(音视频学习笔记):H264基本概念

H264基本概念学习笔记

  • NALU(Network Abstract Layer Unit)
  • GOP (图像组)主要⽤作形容⼀个IDR帧 到下⼀个IDR帧之间的间隔了多少个帧。
  • H264将其组织成为 序列(GOP)、图⽚(pictrue)、⽚(Slice)、宏块(Macroblock)、⼦块(subblock)五个层次。
  • H264将视频分为连续的帧进⾏传输,在连续的帧之间使⽤I帧、P帧和B帧。同时对于帧内⽽ ⾔,将图像分块为⽚、宏块和字块进⾏分⽚传输;通过这个过程实现对视频⽂件的压缩包装。
  • IDRInstantaneous Decoding Refresh,即时解码刷新
    • ⼀个序列的第⼀个图像叫做 IDR 图像(⽴即刷新图像),IDR 图像都是 I 帧图像
  • 其核⼼作⽤是,是为了解码的重同步,当解码器解码到 IDR 图像时,⽴即将参考帧队列清 空,将已解码的数据全部输出或抛弃,重新查找参数集,开始⼀个新的序列。
  • B帧不能被当做参考帧。

NALU

  • SPS序列参数集,SPS中保存了⼀组编码视频序列(Coded video sequence)的全局参数。
  • PPS图像参数集,对应的是⼀个序列中某⼀幅图像或者某⼏幅图像的参数。
  • I帧帧内编码帧,可独⽴解码⽣成完整的图⽚。
  • P帧: 前向预测编码帧,需要参考其前⾯的⼀个I 或者B 来⽣成⼀张完整的图⽚。
  • B帧: 双向预测内插编码帧,则要参考其前⼀个I或者P帧及其后⾯的⼀个P帧来⽣成⼀张完整的 图⽚
  • 发I帧之前,⾄少要发⼀次SPS和PPS

NALU结构

  • H.264原始码流(裸流)是由⼀个接⼀个NALU组成,它的功能分为两层
    • VCL(视频编码层):包括核⼼压缩引擎和块,宏块和⽚的语法级别定义,设计⽬标是尽可能地独⽴于⽹ 络进⾏⾼效的编码
    • NAL(⽹络提取层):负责将VCL产⽣的⽐特字符串适配到各种各样的⽹络和多元环境中,覆盖了所有⽚级 以上的语法级别
  • 在VCL进⾏数据传输或存储之前,这些编码的VCL数据,被映射或封装进NAL单元。
  • 1个NALU = 1组对应于视频编码的NALU头部信息 + 1个原始字节序列负荷(RBSP,Raw Byte Sequence Payload)
  • NALU结构单元的主体结构如下所示:

  • ⼀个原始的H.264 NALU单元通常由[StartCode] [NALU Header] [NALU Payload]三部分组成
    • 其中 Start Code ⽤于标示这是⼀个NALU 单元的开 始,必须是"00 00 00 01" 或"00 00 01"
    • 除此之外基本相当于⼀个NAL header + RBSP;
  • 对于FFmpeg解复⽤后,MP4⽂件读取出来的packet是不带startcode,但TS⽂件读取出来 的packet带了startcode。

解析NALU

  • 每个NAL单元是⼀个⼀定语法元素的可变⻓字节字符串,包括包含⼀个字节的头信息(⽤来表 示数据类型),以及若⼲整数字节的负荷数据
  • NALU头信息(⼀个字节):

(注:图片参考:https://www.jianshu.com/p/31ed32fd7b6b

  • T为负荷数据类型,占5bit
    • nal_unit_type:这个NALU单元的类型,112H.264使⽤,2431H.264以外的应⽤ 使⽤
  • R为重要性指示位,占2个bit
    • nal_ref_idc.:取00~11,似乎指示这个NALU的重要性
    • 00NALU解码器可以丢弃它⽽不 影响图像的回放,03,取值越⼤,表示当前NAL越重要,需要优先受到保护。
    • 如果当前 NAL是属于参考帧的⽚,或是序列参数集,或是图像参数集这些重要的单位时,本句法元 素必需⼤于0
  • F为禁⽌位,占1bit
    • forbidden_zero_bit: 在 H.264 规范中规定了这⼀位必须为 0
  • H.264标准指出,当数据流是储存在介质上时,在每个NALU 前添加起始码:0x000001 0x00000001,⽤来指示⼀个NALU 的起始和终⽌位置:
    • 在这样的机制下,在码流中检测起始码,作为⼀个NALU得起始标识,当检测到下⼀个起始 码时,当前NALU结束
    • 3字节的0x000001只有⼀种场合下使⽤,就是⼀个完整的帧被编为多个slice(⽚)的时 候,包含这些sliceNALU 使⽤3字节起始码。
    • 其余场合都是4字节0x00000001的

H264 annexb模式

  • H264有两种封装:
    • annexb模式,传统模式,有startcode,SPS和PPS是在ES中(可参考:《H264 ES PS TS 流的区别》https://blog.csdn.net/coloriy/article/details/80623192)
    • mp4模式,⼀般mp4 mkv都是mp4模式,没有startcode,SPS和PPS以及其它信息 被封装在container中每⼀个frame前⾯4个字节是这个frame的⻓度
  • 很多解码器只⽀持annexb这种模式,因此需要将mp4做转换:ffmpeg中⽤ h264_mp4toannexb_filter可以做转换
const AVBitStreamFilter *bsfilter = av_bsf_get_by_name("h264_mp4toannexb"); 
AVBSFContext *bsf_ctx = NULL; 
// 2 初始化过滤器上下⽂ 
av_bsf_alloc(bsfilter, &bsf_ctx); //AVBSFContext; 
// 3 添加解码器属性 
6avcodec_parameters_copy(bsf_ctx->par_in, ifmt_ctx->streams[videoindex]->cod ecpar); 
av_bsf_init(bsf_ctx);

GOP group of pictures

  • 在视频编码序列中,GOP即Group of picture(图像组),指两个I帧之间的距离
  • Reference(参考周期)指两个P帧之间的距离
  • ⼀个I帧所占⽤的字节数⼤于⼀个P帧,⼀个P 帧所占⽤的字节数⼤于⼀个B帧。
  • 所以在码率不变的前提下,GOP值越⼤,PB帧的数量会越多,平均每个IPB帧所占⽤的 字节数就越多,也就更容易获取较好的图像质量;Reference越⼤,B帧的数量越多,同理也 更容易获得较好的图像质量。
  • 通过提⾼GOP值来提⾼图像质量是有限度的,在遇到场景切换的情况时, H.264编码器会⾃动强制插⼊⼀个I帧,此时实际的GOP值被缩短了。
  • 在⼀个GOP 中,P、B帧是由I帧预测得到的,当I帧的图像质量⽐较差时,会影响到⼀个GOP中后续P、B 帧的图像质量,直到下⼀个GOP开始才有可能得以恢复,所以GOP值也不宜设置过⼤
  • 由于PB帧的复杂度⼤于I帧,所以过多的PB帧会影响编码效率,使编码效率降低。
  • 另外,过⻓的GOP还会影响Seek操作的响应速度,由于PB帧是由前⾯的IP帧预测得到 的,所以Seek操作需要直接定位,解码某⼀个PB帧时,需要先解码得到本GOP内的I帧及之 前的N个预测帧才可以,GOP值越⻓,需要解码的预测帧就越多,seek响应的时间也越⻓。
  • 拓展:可参考 https://www.jianshu.com/p/31ed32fd7b6b

猜你喜欢

转载自blog.csdn.net/baidu_41388533/article/details/114756342