H264码流封装

H264

单元

  • NAL单元包括对应于视频编码的NAL头信息、原始字节序列负荷。

    image-20210702151944573

    image-20210702151919080

  • SODB:最原始的编码数据,无任何附加数据。

  • RBSP:在SODB的基础上增加了结尾比特(bit值为1)并用0按字节补位对齐。

  • EBSP:在RBSP的基础上增加了防止伪起始码字节(0x03)。在编码的时候每遇到两个字节(连续)的0,就插入一个字节0x03,以便和起始码相区别,解码时,则将相应的0x03删除掉。所以有时候NAL单元有可能是NAL头+EBSP组成

image-20210702152029794

帧名帧头功能
SPS00 00 00 01 67SPS和PPS是用来初始化解码器的,没有,视频数据无法解析
PPS00 00 00 01 68SPS和PPS是用来初始化解码器的,没有,视频数据无法解析
SEI00 00 01 06描述信息
I 帧00 00 00 01 65关键帧:底画
P帧00 00 00 01 61补充帧:在底画上的修修改改

RTP荷载H264

FU-A 单元分片

blob.png

blob.png

  • FU-A头包含1字节NAL头,1字节的分片单元头
  • S: 开始标识位,FU荷载为NAL的起始分片
  • E: 结束标识位,FU荷载为NAL的结束分片
  • R: 保留位,必须设置为0,
  • 打包时,H264帧头(如00 00 00 01 65),前面的00 * 01去掉,最后一字节标识(65),存储在NAL头的前三位(F,NRI)与分片单元头的后5位中(FU header Type)

TCP传输

TCP 为字节流传输,需要添加间隔帧RTSP Interleaved Frame,对包进行分割

img

PS

PS格式

首条数据结构:PS Header + PS System Header + PSM + PESV(Header + Payload)

非首条数据结构:PS Header + PESV(Header + Payload)

image-20210703102226184

包定义

定义太多,没整理,当字典用吧

PS Header:00 00 01 ba

image-20210703105104562

  • program_mux_rate:速率值字段,占位22bit,正整数,表示P-STD接收此字段所在包的PS流的速率;这个值以每秒50字节作为单位;禁止0值;

  • Marker_bit:标记字段,占位1bit,固定为’1’;

  • stuffing_byte:填充字段,长度由pack_stuffing_length确定;

PS System Header:00 00 01 bb

image-20210703105145138

  • header_length:头部长度字段,占位16bit,表示此字段之后的系统首部字节长度;

  • rate_bound:整数值,占位22bit,为一个大于或等于PS流所有PS包中的最大program_mux_rate值的整数;解码器用来判断是否可以对整个流进行解码;

  • audio_bound:占位6bit;取值范围0到32间整数;大于或等于同时进行解码处理的PS流中的音频流的最大数目;

  • fixed_flag:占位1bit;置位1表示固定比特率操作,置位0则为可变比特率操作;

  • CSPS_flag:CSPS标志位,占位1bit;置位1表示此PS流满足标准的限制;

  • system_audio_lock_flag:占位1bit,表示音频采样率和系统目标解码器的system_clock_frequency之间有一特定常数比例关系;

  • system_video_lock_flag:占位1bit,表示视频帧速率和system_clock_frequency之间有一特定常数比例关系;

  • video_bound:整数,占位5bit,取值范围0到16;大于或等于同时进行解码处理的PS流中的视频流的最大数目;

  • stream_id :占位8bit,判断视频流或音频流;

PSM:00 00 01 bc

image-20210703114553396

  • program_stream_map_length:占位16bit;表示此字段之后PSM的总长度,最大值为1018(0x3FA);

  • current_next_indicator:标识符,占位1bit;置位1表示当前PSM是可用的,置位0则表示当前PSM不可以;

  • program_stream_map_version:版本字段,占位5bit;表示PSM的版本号,取值范围1到32,随着PSM定义的改变循环累加;若current_next_indicator == 1,表示当前PSM的版本号,若current_next_indicator == 0,表示下一个PSM的版本号;

  • elementary_stream_map_length:长度字段,占位16bit;表示在这个PSM中所有ES流信息的总长度;

  • stream_type:类型字段,占位8bit;表示原始流ES的类型;可以判断PS打包的流编码类型;MPEG-4 视频流: 0x10;H.264 视频流: 0x1B;SVAC 视频流: 0x80;G.711 音频流: 0x90;G.722.1 音频流: 0x92;G.723.1 音频流: 0x93; G.729 音频流: 0x99; SVAC音频流: 0x9B;

  • elementary_stream_id:流ID字段,占位8bit;表示此ES流所在PES分组包头中的stream_id字段的值;其中0x(C0DF)指音频,0x(E0EF)为视频;

PES 包(Header + Body):00 00 01 e0

image-20210703114617776

  • PES_packet_length :PES分组长度字段,16位字段,指出了PES分组中跟在该字段后的字节数目。

  • PES_scrambling_control :PES加扰控制字段,2位字段,表示PES分组有效负载的加扰方式。

  • PES_priority :PES优先级字段,1位字段,指示PES分组中有效负载的优先级。

  • Copyright:版权字段,1位字段。置’1’时表示相关PES分组有效负载的材料受到版权保护。当值为’0’时,没有定义该材料是否受到版权保护。

  • original_or_copy:原始或拷贝字段,1位字段。置’1’时表示相关PES分组有效负载的内容是原始的;值为’0’表示相关PES分组有效负载的内容是一份拷贝。

  • DSM_trick_mode_flag :DSM特技方式标志字段,1位标志。置’1’时表示有8位特技方式字段;值为’0’表示没有该字段。

  • additional_copy_info_flag:附加版权信息标志字段,1位标志。置’1’时表示有附加拷贝信息字段;值为’0’表示没有该字段。

例子

image-20210703114920326

  • 00 00 01 ba 代表 PS 包的开始。第 10 个字节 fe,对应着二进制数据的 1111 1110它的后三位为 110 为十进制的 6,即接下来的六个字节是扩展内容。

  • 00 00 01 bb是PS System Header 部分。System Header 当且仅当数据包为第一个数据包时才存在。之后紧邻的 00 12 两个字节表示 System Header 的长度,即为 18 个字节。在 header_length 后共有 6 个字节的数据,之后就是 stream_id 字段, system_id 值为 e0,可知本 PS 流为视频流。它是 3 个字节一循环,下一个循环 system_id 字节值为 c0,为音频流,之后出现了 bd,这个是海康私有流的标识,bf 也是海康的私有数据。

  • 00 00 01 bc是本段数据的类型 program_stream_map,即 PSM。之后的两个字段为 header 的长度,00 5e 十进制的 94,自 00 5e 后,跳过两个字段的固定内容,就到了两个字节的 program_stream_info_length,其值为 00 24,说明其后跟着的 descriptor 共占 36 字节。跳过 36 字节后,接下来的值 00 30 为 element_stream_map_length(基本流映射长度),也就是 48 字节,它表示接下来的 48 字节都是用来描述原始流信息的。

  • 进入原始流描述的第一次循环,第一个字节 stream_type 值为 1b 。根据 GB28181 的定义可知为 H.264 编码,之后的 e0 表示其为视频流。再之后的 00 1c 代表接下来描述占用 28 字节。接着循环下去,接下来的字段 91 和 c0,代表着其为音频流, 00 0c 代表接下来描述占用 12 字节,最后就是 CRC_32,4个字节。

据 GB28181 的定义可知为 H.264 编码,之后的 e0 表示其为视频流。再之后的 00 1c 代表接下来描述占用 28 字节。接着循环下去,接下来的字段 91 和 c0,代表着其为音频流, 00 0c 代表接下来描述占用 12 字节,最后就是 CRC_32,4个字节。

  • 00 00 01 e0表示是一个视频流,再之后的 FF C6 表示长度,即其后的 65478字节为数据内容长度,PES_header_data_length的位置是PES 包长度跳过两个字节后的位置。它的值为 07,也就是其后字节的长度,通过这个可以分割PES头部内容和数据段,且PES 是可以存在多个的。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值