遵循RTP打包格式就是判断包大小是否超过RTP SINK大小,超过的话则用RTP分片模式进行打包,通常使用FU-A模式,未超过RTP SINK大小的时候则用RTP单一打包模式。一般RTP负载是通过UDP协议传输的,所以根据UDP协议的特性,RTP SINK大小是小于MTU值的,例如MTU1500的时候,RTP SINK一般为1448

SPSPPS的帧是需要分开打包的,这里所指的分开打包是指SPS单独打包,PPS单独打包,剩下的又单独打包,他们3部分是共享同一个时间戳的。通俗的说就是把含SPS,PPS的帧看作是3个共享同一时间戳的独立的帧,分别是SPS部分,PPS部分和剩下的一个部分。不含SPSPPS的帧直接打包即可。

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包尾,当包大小不超过2RTP 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


txgcwm
764 声望71 粉丝

Linux C/C++


« 上一篇
jrtplib库使用
下一篇 »
实时传输协议