H.264基础概念

常用名词及概念
  1. H.264VCEG(Video Coding Experts Group)和MPEG(Moving Picture Experts Group)共同推进并且目前广泛使用的一种通用视频编码技术;相比于H.265,压缩率较低,但是对于硬件设备的要求也低一些;另外,h.265商用是非免费的;

    H.264中两个重要的概念是NAL(Network Abstract Layer)和VCL(Video Coding Layer);VCL负责表示有效视频数据的内容,NAL负责格式化数据及头信息,使之可以在不同的信道和存储媒介传播;一个H.264文件由多个NALU组成,每个NALU又可以分为VCLnon-VCL。视频数据由编码器处理后然后打包为多个NALU

    针对不同的系统,打包NALU的方式有两种:包传输系统(Packet-Transport System)和字节流格式(Byte-Stream Format);对于类似于RTP的包传输系统,传输系统协议会把编码数据切割成不同的块;系统能够简单地区分NALU边界并且不需要额外的start code
    然而,很多传输系统并没有这样的协议去分割NALU,为了让解码端能够正确区分出NALU边界,通常会在NALU的起始位置添加一个3或4字节的start code;这种类型称为字节流格式

  2. NALU:Network Abstract Layer Unit,网络抽象层;NAL是H.264/AVC视频编码标准的一部分;NAL-unit是视讯编码层(Video Coding Layer, VCL)的运算单元;H.264比特流是由多个NAL-unit组成的;

    NALU Header:是NALU的第一个字节,包含了当前NALU的基本信息,由3部分构成——forbidden_zero_bit(1bit)、 nal_ref_idc(2bits)、nal_unit_type(5bits);

    forbidden_zero_bit用于检测传输过程中是否发生错误;0表示正常,1表示出现错误;

    nal_ref_idc表示该NALU是否是一个参考field/frame/picture,非零表示是一个参考field/frame/picture;并且非零值越大,表示该NALU越重要;

    nal_unit_type用于定义当前NALU的类型,长度5bits;上边提到的VCLnon-VCLNALU可以更具nal_unit_type进行区分——nal_unit_type等于1-5的为VCL,其他的均为non-VCL
    常见的几个nal_unit_type:5-IDR(首个I帧)、6-SEI(辅助增强信息)、7-SPS(Sequence Parameter Set)、8-PPS(Picture Parameter Set)、9-Access unit delimiter、10-End of Sequence、 11-End of Stream、12-Filler data

    nal_unit_typenal_ref_idc的关系:

nal_unit_typenal_ref_idc
1-4如果其中一个NALU是0,type为1-4的NALU都为0
5 Coded Slice of IDR非零
7 Sequence Parameter Set非零
8 Picture parameter set非零
13 Sequence parameter set extension非零
15 Subset Sequence parameter set非零
6,9,10,11,120
  1. start code:为了区分不同的NALU的边界,通常每个NALU都是以0x0000010x00000001作为前缀的;如果当前NALU是一帧的起始,则使用0x00000001,否则使用0x000001

    Start Code + NALU + ... + Start Code + NALU = h.264 Byte Stream
    
  2. SODB:String of Data Bits. 原始数据比特流
    定义:一个包含多个字节的序列,表示在一个RBSP中位于RBSP Stop bit之前的多个字节;在SODB中越靠左的比特越有意义;

  3. RBSP:Raw Byte Sequence Payload,原始数据字节流负载;
    定义:包含多个字节的封装在NALU中的一个语法结构;一个RBSP要么为空,要么为由以下格式组成:一个SODB后面接一个RBSP Stop bit,然后接一个或多个均等于0的比特;RGSP总是字节对齐的(8-bits),通过RBSP Stop bit后添加0的方式;

    SODB + RBSP Stopbit + 0 bit(s) = RBSP
    

    在这里插入图片描述

    RBSP Stop bit:位于RGSP中的SODB之后的值为1且长度为1比特,用于标识SODB的结束;由于它是当前RBSP的最后一个非零比特位,可以方便定位RGSP中的SODB

  4. EBSP: Encapsulated Byte Sequence Payload,封装字节流负载;上面提到了作为NALU分隔符的Start Code,然而在RBSP中可能存在0x00000X的数据格式(X = 1, 2, 3)的数据流与起始码数据结构非常相似;因此为了简化解码过程,在编码的时候遇到0x00000X会在其后插入emulation_prevention_three_byte (0x03),使之转换为0x0000030X;在解码过程中会忽略emulation_prevention_three_byte (0x03),保证解码正确;

    RBSP partA + 0x03 + RBSP partB+ 0x03 + ... + RBSP + 0x03 = EBSP
    
    NALU Header  + EBSP = NALU
    

在这里插入图片描述

  1. PPS :Picture Parameter Set,序列参数集,nal_unit_type等于8;多个NALU组成一个视频帧,该视频帧相关的元数据(metadata)保存在PPS中;PPS通常独立保存在一个NAL unit中;包含的语法元素及含义
语法元素含义
pic_parameter_set_id当前PPS的id,可用于slice引用PPS,取值0-255
seq_parameter_set_id当前PPS所引用的激活的SPS的id,通过该方式可以PPS中获取到对应SPS的参数,取值0-31
entropy_coding_mode_flag熵编码模式标识;部分语法元素在不同的编码配置中选择不同的熵编码方式,比如一个宏块的语法元素描述符为"ue(v)|ae(v)",则在baseline profile等设置下使用指数哥伦布编码,在main profile等设置下使用CABAC编码;该标识为0,选择左侧算法,通常为指数哥伦布编码CAVLC;该值为1时,选择右边算法,通常为CABAC
num_slice_groups_minus1标识一帧中slice group的个数;该值为0,标识该帧中的所有slice属于统一一个slice group;
weighted_pred_flag是否在P/SP slice中开启加权预测的标识位
```js
在封装格式中,`SPS`、`PPS`、`SEI`等信息也会保存在视频文件的文件头中
```
  1. SPS :Sequence Parameter Set,序列参数集,nal_unit_type等于7;多个PPS组成一个视频学历,该序列相关的原始数据保存在SPS中;一般SPS的第一个字节和第3个字节分别为profile_idclevel_idc
语法元素含义
profile_idc标识当前H.264流的profile,profile用于控制食品的压缩特性(越大压缩特性越高),有3中可选值:baseline profile(66)、main profile(77)、extended profile(88) ,high profile(>=100),通常一个字节表示
level_idc标识当前麻溜的Level。level定义了特定条件下的最大视频分辨率、最大视频帧率等参数,通常一个字节表示;level越大, 一定条件下分辨率、码率、帧率等越高
seq_parameter_set_id当前SPS的id
log2_max_frame_num_minus4MaxFrameNum的对数值
max_num_ref_frames参考帧最大数值
pic_width_in_mbs_minus1单位为宏块个数,可用于计算图像的宽度值;frame_width = (pic_width_in_mbs_minus1 + 1) * 16(16是基于macroblock的大小为1616);
frame_cropping_flag是否对输出图像进行裁剪的标识位
  1. SEI:Supplymental Enhancement Information,辅助增强信息,包含了增强视频的 一些辅助信息;比如直播答题中增加一些与视频信息同步的文本信息,或者字幕信息控制等用户自定义信息均可以放在SEI中;生成SEI中的方式包括编码时生成SEI及容器封装时写入SEI信息等;
  2. 宏块:是运动预测的基本单位,通常一张完整的帧可以分为多个宏块,宏块是选择特定预测类型的基准,整个图像可以使用不同的预测类型;
Demo

通常,在一个H.164的字节流中,第一个NALU为SPS,第二个NALU为PPS,第三个NALU为IDR

如下,是一个H.264的字节流,可以得到印证;可以看到0x67对应的是SPS的NALU Header,0x64profile_idc,对应为十进制的100,表示high profile;0x33level_idc,对应的十进制为51,表示level=5.1,所以该码流的profilelevel可以记为High@L5.1;使用mediaInfo直接查看对应信息可以验证;

具体的profileLevel值的映射表可以参考wikipedia
在这里插入图片描述在这里插入图片描述

参考文献
  1. 网络抽象层
  2. Introduction to H.264: (1) NAL Unit
  3. Introduction to H.264: (2) SODB vs RBSP vs EBSP
  4. 从H.264码流中一眼读出其Profile和Level
  5. Advanced Video Coding
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Neil-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值