H264码流结构

         在H.264的视频编码标准中,分为两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。媒体流的每帧数据就是一个NAL单元(SPS和PPS除外)。

视频编码层(VCL)

        VCL()负责对视频的原始数据进行压缩和编码,VCL输出的是压缩和编码之后的纯视频流信息。

网络提取层(NAL)

        NAL(Network Abstraction Layer)主要为了方便媒体流在网络中的传输,适用于各种传输网络。

NAL单元格式

F: 1位

        forbidden_zero_bit。数值为 0 表示 NAL 单元类型字节和数据包不应出现位错误或其他语法违规情况。数值为 1 则表示 NAL 单元类型字节和数据包可以包含位错误或其他语法违规情况。

NRP: 2位

        nal_ref_idc。值 00 以及非零值的含义与 H.264 规范中的规定保持一致。换句话说,值为 00 表示该 NAL 单元的内容不会用于重建用于帧间预测的参考图像。此类 NAL 单元可以被丢弃,而不会危及参考图像的完整性。值大于 00 则表示需要对 NAL 单元进行解码以保持参考图像的完整性。

Type: 5位

       nal_unit_type表示NAL的数据类型,有以下几种,其值为1,2,3,4,5和12的NAL单元称为VCL的NAL单元,其他类型为非ACL的NAL单元。

NAL_UNIT_TYPE描述
0未使用
1非IDR图像中不采用数据划分的片段【VCL】
2非IDR图像中A类数据划分的片段【VCL】
3非IDR图像中B类数据划分的片段【VCL】
4非IDR图像中C类数据划分的片段【VCL】
5IDR图像中的片段【VCL】
6补充增强信息片段(SEI)【NO-VCL】
7序列参数集【NO-VCL】
8图像参数集【NO-VCL】
9分隔符(或分解符)【NO-VCL】
10序列结束符【NO-VCL】
11流结束符【NO-VCL】
12填充数据【NO-VCL】
13~23保留
24~31未使用

NALU 载荷

        SODB(String of Data Bits) 元数据比特流,即最原始的编码、压缩得到的数据。

        RBSP(Raw Byte Sequence Payload),原始字节序列载荷,主要是在SODB基础上增加了补齐字节(RBSP = SODP + RBSP补齐字节)。

        EBSP(Encapsulated Byte Sequence Payload)扩展字节序列载荷,主要是在RBSP基础上插入放竞争字节(0x03)。

         说明:插入0x03的主要原因是,因为NALU的起始码为0x000001或0x00000001,同时H264规定,当检测到0x000000时,也可以表示NALU的结束。所以这样就会产生一个问题,就是在NALU的内部,如果出现了0x000001或0x000000时该怎么办?所以,H264有了插入0x03防止竞争的机制,在编码完成一个NAL时,如果在NALU内部出现序列(0x000000、0x000001、0x000002、0x000003)中的一个存在时,就在最后一个字节前插入一个新的字节0x03(解码时进行逆向操作)。

一帧图片和NALU之间的关联

       一帧图片经过H.264编码之后,会编码(VCL层实现)为一个或者多个切片(slice)。

        编码后的切片(slice)会被装在到NALU中(NAL层实现),如下图所以NALU和切片(slice)的关系。

        说明:实际实现过程中,NAL还需要对切片(slice)进行处理,然后行程NALU。

        切片(slice)装载到NALU之后进行网络传输,但是NALU装载的也不一定是帧图片的切片(slice),因为NALU还可能装载用于描述视频的信息(如SPS、PPS等)。

slice Header结构

       slice Header中主要保存了当前切片(slice)的一些全局信息,silice Body中的宏块(MB)在进行解码时需要依赖这些信息。以下是一些比较常见的信息:

1、first_mb_in_slice: 表示当前slice中包含的第一个宏块在整个帧中的位置。

2、slice_type: 表示当前slice类型。

slice_type名称
0P(P slice)
1B(B slice)
2I(I slice)
3SP(SP slice)
4SI(SI slice)
5P(P slice)
6B(B slice)
7I(I slice)
8SP(SP slice)
9SI(SI slice)

3、pic_parameter_set_id: 当前slice依赖的PPS和id(指定图像参数集)。

4、colour_plane_id: 当separate_colour_plane_flag标识位的值为true时,colour_plane_id表示当前的颜色分量(0、1、2分别表示Y、U、V)。

5、frame_num: 当前帧序号的计量方式(POC)。

6、field_pic_flag: 场编码标识位,该值为1时,表示当前slice按照场进行编码;值为0时表示当前slice按照帧进行编码。

7、bottom_field_flag: 底场标识位,值为1表示当前slice是某一帧的底场;0表示当前slice为某一帧的顶场。

8、idr_pic_id: IDR帧的序号,一个IDR帧所的所有slice,其idr_pid_id应该保持一致,取值范围0~65535。

9、pic_order_cnt_lsb: 当前帧序号的另一种计量方式。

10、delta_pic_order_cnt_bottom:顶场和底场POC差值的计算方法(不存在则默认为0)。

11、slice_qp_delta: 用于计算当前slice内使用的初始qp值。

根据码流中的不同的数据类型,H.264定义了五种slice类型:

类型(名称)含义描述Profile
I(I slice)帧内切片仅包含 I 宏块ALL
P(P slice)前向预测切片可包含 P 宏块和 I 宏块ALL
B(B slice)双向预测切片可包含 B 宏块、P宏块、 I 宏块Extended and Main
SP(SP slice)切换前向预测切片包含 P 宏块或 I 宏块Exteded
SI(SI slice)切换帧内切片仅包含 SI 宏块Exteded
1. I Slice(Intra-coded Slice,帧内切片)
  • 定义:只使用帧内(本切片或本帧)信息进行预测编码,不引用其他帧的数据。

  • 特点:抗误码能力强,是关键帧的基本构成单元。

  • 典型应用:场景切换、编码重同步点。

  • 数据类型:只包含 I 宏块。

2. P Slice(Predictive-coded Slice,前向预测切片)
  • 定义:使用本帧和参考帧的数据进行前向预测压缩编码。

  • 特点:编码效率高,压缩比好,但对参考帧依赖大。

  • 典型应用:大部分连续画面。

  • 数据类型:可包含 P 宏块和 I 宏块。

3. B Slice(Bi-predictive-coded Slice,双向预测切片)
  • 定义:既能参考前面的帧,也能参考后面的帧进行双向预测编码。

  • 特点:压缩率最高,依赖于多个参考帧,对解码器要求较高。

  • 典型应用:高压缩场合,如蓝光或高码率视频。

  • 数据类型:可包含 B、P、I 宏块。

扩展类型:SI Slice 和 SP Slice

这些类型主要在流切换、容错、码流修复等特定应用场景,实际应用较少:

4. SI Slice(Switching Intra Slice,切换帧内切片)
  • 主要用于码流切换场景,便于不同码率、不同内容之间的切换。

5. SP Slice(Switching Predictive Slice,切换前向预测切片)
  • 主要用于码流无损切换场景,以确保内容切换点的视频连续性。

宏块(MB)

mb_type: 确定当前宏块(MB)的编码模式(P或B),确定当前MB的分割尺寸。

mb_pred: 确定帧内预测模式(帧内宏块)。

sub_mb_pred:确定每一个子宏块的子宏块分割。

residual:预测后对饮残差图像取样的编码变换系数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI发光体

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值