遵循RTP
打包格式就是判断包大小是否超过RTP SINK
大小,超过的话则用RTP
分片模式进行打包,通常使用FU-A
模式,未超过RTP SINK
大小的时候则用RTP
单一打包模式。一般RTP
负载是通过UDP
协议传输的,所以根据UDP
协议的特性,RTP SINK
大小是小于MTU
值的,例如MTU
为1500
的时候,RTP SINK
一般为1448
。
含SPS
和PPS
的帧是需要分开打包的,这里所指的分开打包是指SPS
单独打包,PPS
单独打包,剩下的又单独打包,他们3
部分是共享同一个时间戳的。通俗的说就是把含SPS
,PPS
的帧看作是3
个共享同一时间戳的独立的帧,分别是SPS
部分,PPS
部分和剩下的一个部分。不含SPS
和PPS
的帧直接打包即可。
SPS/PPS
的判断
H264
帧格式以00 00 00 01
作为起始码,01
后面的一个字节用来判断是否含SPS/PPS
。当这个字节&0x1f
的值为7
时就说明从此刻的00 00 00 01
开始到下一个00 00 00 01
之间的数据都为SPS
。当00 00 00 01
后面一个字节&0x1f
的值为8
时就说明此刻的起始码到下一个起始码之间为PPS
。
FU-A
打包过程
当包的大小超过了RPT SINK
大小时需要分片打包,FU-A
打包通常分为3
大部分即FU-A
包头,FU-A
包身,FU-A
包尾,当包大小不超过2
个RTP SINK
大小时则只有FU-A
包头,FU-A
包尾2
部分(注意:包头和包尾不能出现在同一包中)。
举例说明:
00 00 00 01 65 32 33 44 55 66 77 88 99.........55 22 33
去掉起始码长度为FrameLength
的数据存入FrameBuffer
中。
0x65 32 33 44 55 66 77 88 99.........55 22 33
FU-A
包头:
BufferFuA[0] = (FrameBuffer[0] & 0xE0) | 28;
BufferFuaA[1] = 0x80 | (FrameBuffer[0] & 0x1f);
memcpy(BufferFuA + 2, FrameBuffer + 1, RTP_SINK_SIZE);
FU-A
包身(包身若干个包):
BufferFuA[0] = FrameBuffer[0];
BufferFuaA[1] = FrameBuffer[0] & ~0x80
memcpy(BufferFuA + 2, FrameBuffer + 1 + RTP_SINK_SIZE, RTP_SINK_SIZE);
FU-A
包尾:
BufferFuA[0] = FrameBuffer[0];
BufferFuaA[1] = FrameBuffer[0] | 0x40;
memcpy(BufferFuA + 2, FrameBuffer + 1 + RTP_SINK_SIZE*N, 余下长度);
参考文章
RTP 打包流程
Rtsp交互流程
基于RTP的H264视频数据打包解包类
RFC-2326 RTSP协议中文版
RFC3984中文版
RFC 3550 中文版
H264 编码+打包+解码相关知识
摄像头采集,264编码,live555直播(1)
摄像头采集,264编码,live555直播(2)
通过live555实现H264 RTSP直播
rtmp流媒体编程相关整理2013(crtmpserver,rtmpdump,x264,faac)
使用librtmp库发布直播流
RaspberrIPCam – Full HD IP Camera based on Raspberry Pi
使用 live555 直播来自 v4l2 的摄像头图像
rtsp_audio
EasyAACEncoder
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。