H264编码 SPS & PPS

一基础介绍

在H264各种语法元素中,SPS和PPS中的信息非常重要。数据丢失或者错误,就会导致解码失败。在一些解码器中甚至起到了初始化信息的作用。

SPS

SPS即Sequence Paramater Set,序列参数集。即原始视频的一帧一帧的像素数据经过编码之后的结构组成的序列。而每一帧的编码后数据所依赖的参数保存于图像参数集中。

PPS

Picture Paramater Set,图像参数集。即图像的一些参数,宽高等。

二、SPS数据结构

标准文档如下:

github
github

其中每一个语法元素说明如下:

profile_idc

识别当前H264码流的档次(这里的值为10进制):

  • 基准档次:baseline profile,值66
  • 主要档次:main profile,值77
  • 扩展档次:extended profile,值88

新版的标准中,还包括HighHigh10High422High444High10IntraHigh422IntraHigh444IntraCAVLC444Intra等。
另外,constraint_set0_flag ~ constraint_set5_flag是在编码的档次方面对码流增加的其他一些额外限制性条件。

level_idc

标识当前码流的Level。定义了某些条件下的最大视频分辨率、最大视频帧率等参数。

seq_parameter_set_id

表示当前的序列参数集的id。通过该id值,图像参数集pps可以引用其代表的sps中的参数。

log2_max_frame_num_minus4

用于计算MaxFrameNum的值。
计算公式为MaxFrameNum = 2^(log2_max_frame_num_minus4 + 4)MaxFrameNumframe_num的上限值,frame_num是图像序号的一种表示方法,在帧间编码中常用作一种参考帧标记的手段。

pic_order_cnt_type

表示解码picture order count(POC)的方法。POC是另一种计量图像序号的方式,与frame_num有着不同的计算方法。

log2_max_pic_order_cnt_lsb_minux4

用于计算MaxPicOrderCntLsb的值,该值表示POC的上限。
计算方法为MaxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4)

max_num_ref_frames

用于表示参考帧的最大数目。

gaps_in_frame_num_value_allowed_flag

标识位,说明frame_num中是否允许不连续的值。

pic_width_in_mbs_minus1

用于计算图像的宽度,单位为宏块个数

pic_height_in_map_units_minus1

使用PicHeightInMapUnits来度量视频中一帧图像的高度。
PicHeightInMapUnits并非图像明确的以像素或宏块为单位的高度,而需要考虑该宏块是帧编码或场编码。PicHeightInMapUnits的计算方式为:
PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1

frame_mbs_only_flag

标识位,说明宏块的编码方式。

  • 0:宏块可能为帧编码或场编码
  • 1:所有宏块都采用帧编码
    根据该标识位取值不同,PicHeightInMapUnits的含义也不同,为0时表示一场数据按宏块计算的高度,为1时表示一帧数据按宏块计算的高度。
    其计算方式:
    FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits

mb_adaptive_frame_field_flag

标识位,说明是否采用了宏块级的帧场自适应编码。

  • 0:不存在帧编码和场编码之间的切换
  • 1:宏块可能在帧编码和场编码模式之间进行选择

direct_8x8_inference_flag

标识位,用于B_Skip、B_Direct模式运动矢量的推导计算。

frame_cropping_flag

标识位,说明是否需要对输出的图像帧进行裁剪。

vui_parameters_present_flag

标识位,说明SPS中是否存在VUI信息。

三、PPS数据结构

标准文档如下:

github
github

其中每一个语法元素说明如下:

pic_parameter_set_id

当前PPS的id。
某个PPS在码流中会被相应的slice引用,slice引用PPS的方式就是在Slice header中保存PPS的id值。该值的取值范围为[0,255]。

seq_parameter_set_id

当前PPS所引用的激活的SPS的id。
通过这种方式,PPS中也可以取到对应SPS中的参数。该值的取值范围为[0,31]。

entropy_coding_mode_flag

熵编码模式标识,该标识位表示码流中熵编码/解码选择的算法。标识位entropy_coding_mode_flag的作用就是控制这种算法选择。mb_type的语法元素描述符为”ue(v) | ae(v)”*,在baseline profile等设置下采用指数哥伦布编码,在main profile等设置下采用CABAC编码。

  • 0:选择左边的算法,通常为指数哥伦布编码或者CAVLC
  • 1:选择右边的算法,通常为CABAC

bottom_field_pic_order_in_frame_present_flag

标识位,用于表示另外条带头中的两个语法元素delta_pic_order_cnt_bottomdelta_pic_order_cn是否存在的标识。这两个语法元素表示了某一帧的底场的POC的计算方法。

num_slice_groups_minus1

某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice group。slice group是一帧中宏块的组合方式

num_ref_idx_I0_default_active_minus1、num_ref_idx_I1_default_active_minus1

当Slice Header中的num_ref_idx_active_override_flag标识位为0时,P/SP/B slice的语法元素num_ref_idx_l0_active_minus1和num_ref_idx_l1_active_minus1的默认值。

weighted_pred_flag

标识位,表示在P/SP slice中是否开启加权预测。

weighted_bipred_idc

表示在B Slice中加权预测的方法,取值范围为[0,2]。

  • 0:默认加权预测
  • 1:显式加权预测
  • 2:隐式加权预测

pic_init_qp_minus26、pic_init_qs_minus26

初始的量化参数。实际的量化参数由该参数、slice header中的slice_qp_delta/slice_qs_delta计算得到。

chroma_qp_index_offset

用于计算色度分量的量化参数,取值范围为[-12,12]。

deblocking_filter_control_present_flag

标识位,用于表示Slice header中是否存在用于去块滤波器控制的信息。

  • 0:slice header中没有相应的信息
  • 1:slice header中包含去块滤波相应的信息

constrained_intra_pred_flag

标识位

  • 0:表示I宏块可以使用来自Inter类型宏块的信息
  • 1:表示I宏块在进行帧内预测时只能使用来自I和SI类型宏块的信息

redundant_pic_cnt_present_flag

标识位,用于表示Slice header中是否存在redundant_pic_cnt语法元素。

  • 0:slice header中没有相应的信息
  • 1:slice header中包含redundant_pic_cnt