一.PS流传输格式
1.1、PS流常用封装格式
1)、视频关键帧的封装 RTP + PS header + PS system header + PS system Map + PES header +h264 data
2)、视频非关键帧的封装 RTP +PS header + PES header + h264 data
3)、音频帧的封装: RTP + PES header + G711
基于 RTP 的 PS 封装首先按照 ISO/IEC13818-1:2000 将 视 音 频 流 封 装 成 PS 包, 再 将 PS 包 以 负载的方式封装成 RTP 包。
https://ecee.colorado.edu/~ecen5653/ecen5653/papers/iso13818-1.pdf
每个视频帧分为若干NAL单元(NALU)。
视频PS格式码流以NALU为单位进行打包。若当前为I帧或P帧的第一个NALU则需加PSH头部。若当前为I帧的第一个NALU还需要加PSM头部。每个NALU分为若干段,每段前需加PES头部,每段数据与PES头部组成PES包。
音频PS格式码流以帧为单位进行打包。音频PS格式码流PSH头部可选。音频关键帧包含PSM头部。每个音频帧可分为若干段,每段前需加PES头部,每段数据与PES头部组成PES包。一般情况下音频流只包含PES包。
私有数据PS格式码流以帧为单位进行打包。私有数据PS格式码流不包含PSH头部。私有数据关键帧包含PSM头部。每个私有数据帧可分为若干段,每段前需加PES头部,每段数据与PES头部组成PES包。一般情况下私有数据流只包含PES包。
1.2、GB28181要求的RTP流格式
首先,我们来看看I帧的PS流格式,这里需要注意的是SPS、PPS之前要加上PES头部。如下图所示,其中绿色部分就是我们拿到的H.264裸流数据,须将它拆分成三段并在前面加上PES头部。这一点在GB28181标准中没有细说,需要通过分析海康IPC流才能看出。
一般情况下IDR帧很大,超过了RTP的负载长度限制(1400字节),所以上面这一个I帧要拆分成若干包RTP分多次发送。第一包的结构如上图所示,第二包以后RTP的结构就简单多了,它是这样的:
上面提到的是I帧的情况,相比它,P/B帧的帧格式真是太简单了,因为它既没有SYS、PSM,也没有SPS、PPS:
/B帧大小一般不超过1400字节,如果超过1400字节,也需分成多包RTP数据进行传输,超出1400部分的第二包RTP结构:
针对H264 做如下PS封装:每个IDR NALU 前一般都会包含SPS、PPS等NALU,因此将SPS、PPS、IDR 的NALU封装为一个PS 包,包括ps 头,然后加上PSsystem header,PS systemmap,PES header+h264 raw data。所以一个IDR NALU PS 包由外到内顺序是:PSheader|PS system header | PS system Map | PES header | h264 raw data。对于其它非关键帧的PS 包,就简单多了,直接加上PS头和PES头就可以了。顺序为:PS header | PES header | h264rawdata。以上是对只有视频video 的情况,如果要把音频Audio也打包进PS封装,也可以。当有音频数据时,将数据加上PES header 放到视频PES 后就可以了。顺序如下:PS 包=PS头|PES(video)|PES(audio),再用RTP 封装发送就可以了。
GB28181 对RTP 传输的数据负载类型有规定(参考GB28181 附录B),负载类型中96-127
RFC2250 建议96 表示PS封装,建议97 为MPEG-4,建议98为H264
即我们接收到的RTP 包首先需要判断负载类型,若负载类型为96,则采用PS解复用,将音视频分开解码。若负载类型为98,直接按照H264 的解码类型解码。
注:此方法不一定准确,取决于打包格式是否标准
PS 包中的流类型(stream type)的取值如下:
1) MPEG-4视频流: 0x10;2) H.264视频流: 0x1B;3) SVAC视频流: 0x80;4) G.711音频流: 0x90;5) G.722.1音频流: 0x92;6) G.723.1音频流: 0x93;7) G.729音频流: 0x99;8) SVAC音频流: 0x9B。
前12位是RTP Header。
1.3、PS包头
[0..3] Pack startcode:包起始码字段,值为0x000001BA的位串,用来标志一个包的开始。
接下来的9位包括了SCR,SCRE,MUXRate,
[4..12] Systemclock reference base,system clockreference extenstion:系统时钟参考字段。
最后一位reserved是保留位(0xf8),以及是否有填充字节
[13] Packstuffing length :包填充长度字段,3位整数,规定该字段后填充字节的个数
系统标题
接下来的00 00 01 bb是系统标题起始码;
接下来的00 0c说明了系统标题的长度(不包括起始码和长度字节本身);
接下来的12个字节是系统标题的具体内容,这里不做解析;
节目映射流
继续看到00 00 01 bc,这是节目映射流起始码;
紧接着的00 1e同样代表长度;
跳过e1 ff,基本没用;
接下来是00 18,代表基本流长度,说明了后面还有24个字节;
接下来的1b,意思是H264编码格式;
下一个字节e0,意思是视频流;
接下里00 0c,同样代表接下的长度12个字节;
跳过这12个字节,看到90,这是G.711音频格式;
下一个字节是c0,代表音频流;
接下来的00 00同样代表长度,这里是0;
接下来4个字节是CRC,循环冗余校验。
二. PSH头部分析
PSH:Program Stream pack Header ,是PS包的包头,主要包含系统时间信息。
若当前码流类型为音频流则可选择是否包含PSH头部。若当前码流类型为视频流,且为当前帧的第1个NALU,则包含PSH头部。若为I帧,PSH头部长度为44个字节。若为P帧,PSH头部长度为20个字节。PSH头部主要包含时间戳,最大比特率,帧号信息。
0X 00 00 01 BA PSH头部标志。0X 00 00 01 BB I帧附加信息头部。
表1 PSH头部说明
字节号
含义
0~3
为0x 00 00 01 ba,表示当前为PSH头部
4~8
含有当前帧45K时间戳
10~12
当前设置的最大比特率
16~19
若set_frame_end_flg置为1,则16~19中存放当前帧帧号
I帧附加信息
20~23
为0x 00 00 01 bb,表示当前为I帧附件信息
24~25
为18,等于I帧附加信息长度-2,I帧附加信息长度为20
26~28
表示当前设置的最大比特率
三. PSM头部分析
PS system Map 节目映射流(PSM)
当前为音频流/私有数据流的关键帧需要加PSM头部。当前为视频流且为I帧的第一个NALU时需要加PSM头部。
主要包含BASIC信息、DEVICE信息、加密信息、视频流信息、音频流信息、私有数据信息。
视频流信息分为VIDEO信息、VIDEO_CLIP信息、TIMING_HRD信息长度。
音频流信息分为AUDIO信息。
0x 00 00 01 BC PSM头部标志:
表2 PSM头部
字节号
含义
0~3
为0x 00 00 01 bc,表示当前为PSM头部
8~9
BASIC信息长度+DEVICE信息长度+加密信息长度
BASIC信息
AA
为0x40,表示当前为BASIC信息
AA+1
为14,等于BASIC信息长度-2,BASIC信息长度为16
AA+2~AA+3
公司描述符
AA+6~AA+11
当前时间年月日时分秒及加密类型
AA+12
含义
字节号
相机类型
DEVICE信息
BB
为0x41,表示当前为DEVICE信息
BB+1
为18,DEVICE信息长度-2,DEVICE信息长度为20
字节号
含义
BB+4~BB+19
为设备ID号
字节号
为设备ID号
加密信息
CC
为0x80,表示当前为加密信息
CC+1
为6,加密信息长度-2,加密信息长度为8
CC+4
打包方式,加密算法
CC+5
加密轮数,秘钥长度含义
CC+6
加密类型
DD
视频流信息长度+音频流信息长度+私有数据信息长度
视频流信息
EE
视频编码类型,如H264、H265等
EE+1
码流类型, 此处为0xe0,表示视频码流
EE+2~EE+3
VIDEO信息长度+VIDEO_CLIP信息长度+TIMING_HRD信息长度
VIDEO信息
aa
为0x42,表示当前为VIDEO信息
aa+1
为14,VIDEO长度-2,VIDEO长度为16
aa+2~aa+3
编码器版本
aa+4~aa+5
编码年月日
字节号
含义
aa+6~aa+9
原始图片宽高
aa+10
是否隔行扫描,b帧数目,是否为SVC码流,是否使用e帧,最大参考帧数目
aa+11
水印类型,显示时是否需要反隔行
aa+12
JPEG的Q值
aa+13~aa+15
以1/90000s为单位的两帧间时间间隔,是否使用固定帧率
VIDEO_CLIP信息
bb
为0x44,表示当前为VIDEO_CLIP信息
bb+1
为10,VIDEO_CLIP信息长度-2,VIDEO_CLIP长度为12
bb+2~bb+3
裁剪起始x坐标
bb+4~bb+5
裁剪起始y坐标
bb+6~bb+7
裁剪宽度
bb+8~bb+9
裁剪高度
TIMING_HRD信息
cc
为0x2A,表示当前为TIMING_HRD信息
cc+1
为10,TIMING_HRD信息的长度-2,TIMING_HRD的长度为12
cc+4~cc+7
以1/45000s为单位的两帧间的时间间隔
cc+10
图片宽度
cc+11
图片高度
音频流信息
FF
音频编码类型,如AAC等
FF+1
码流类型,此处为0xc0表示音频码流类型
FF+2~FF+3
AUDIO信息长度
AUDIO信息
dd
为0x43,表示当前为AUDIO信息
dd+1
为10,AUDIO信息长度-2,AUDIO信息长度为12
dd+2~dd+3
音频帧长度
dd+4
音频声道数
dd+5~dd+7
音频采样率/td>
dd+8~dd+10
音频比特率
私有数据信息
GG
私有数据类型
GG+1
码流类型,此处为0xbd表示私有数据码流
GG+2~GG+3
0
HH
CRC校验
四. PES包分析
视频流/音频流/私有数据流都包含若干PES包。每个PES包由PES头部和码流数据两部分组成。PES头部第4个字节用于判断码流类型,视频流为0xe0,音频流为0xc0,私有数据流为0xbd。
对于视频流,每帧视频流分为若干NALU,每个NALU分为若干个段,每个段需加一个PES头部。第一个NALU的第一段的PES头部中可包含pts信息和user_data信息。
对于音频流/私有数据流,每帧数据分为若干段,每段需加一个PES头部。第一段的PES头部中可包含pts信息和user_data信息。
00 00 01 E0 PES头部标志,表示当前码流为视频流。 00 00 01 C0 PES头部标志,表示当前码流为音频流。 00 00 01 BD PES头部标志,表示当前码流为私有数据。
表3 PES头部说明
字节号
含义
基本信息
3
码流类型,视频流或音频流或私有数据流
4~5
基本信息长度+附加信息长度+媒体数据长度-6,基本信息长度为9
6
是否加密,PES优先级
7
用于判断PES头部中是否包含时间戳信息和用户数据信息
8
附加信息长度
附加信息
9~13
时间戳信息
15~30
用户数据信息