1.什么是SPS
一个H264码流序列中,每个slice都会有各自的编码参数,其中有些参数在整个码流序列中不会改变,为节省码流,把这类参数提取出来放入SPS单独编码。这些参数就是SPS。
SPS是 nalu 单元的一种,它的nalu type是7。以一个h264码流为例,蓝色数据就是SPS。
2.SPS的语法结构
SPS语法结构如下:
profile_idc/level_idc:
h264通过 profile_idc 和 level_idc 来确定该码流支持哪些特性。
我们的测试码流中 profile_idc 对应第6个字节 0x42=66,level_idc对应第8个字节 0x1e=30.
seq_parameter_set_id:
表示当前SPS的唯一id,一个码流中可能存在多个SPS,由PPS根据seq_parameter_set_id 选择要使用的SPS。seq_parameter_set_id的数值范围是0-31.
chroma_format_idc:
表示YUV格式类型,
- chroma_format_idc=0,为YUV400,也就是没有UV分量
- chroma_format_idc=1,为YUV420
- chroma_format_idc=2,为YUV422
- chroma_format_idc=3,为YUV444
bit_depth_luma_minus8/bit_depth_chroma_minus8 :
表示亮度、色度分量数据位深,即一个像素分量由几个bit表示。
常见的位深是8bit,此时bit_depth_luma_minus8/bit_depth_chroma_minus8都为0.
seq_scaling_matrix_present_flag
表示量化矩阵是否存在,如果seq_scaling_matrix_present_flag=0,表示不存在,使用系数全为16的默认量化矩阵。
log2_max_frame_num_minus4:
用于计算MaxFrameNum的值。计算公式为MaxFrameNum = 2^(log2_max_frame_num_minus4 + 4)。
MaxFrameNum是frame_num的上限值,frame_num是图像解码序号。
pic_order_cnt_type
表示picture of count(POC)的计算方式,共由三种方式(0、1、2)。计算过程可看这篇 POC计算
POC表示图像的显示顺序,当存在B slice时,解码顺序和显示顺序不一样。
max_num_ref_frames
表示参考帧最大个数
pic_width_in_mbs_minus1
用于计算图像宽度,width=16*(pic_width_in_mbs_minus1+1)
pic_height_in_map_units_minus1
用于计算图像高度,计算过程需结合 frame_mbs_only_flag。
height = ( 2 − frame_mbs_only_flag ) *(pic_height_in_map_units_minus1+1)*16
frame_mbs_only_flag
表示码流中是否只存在帧宏块,如果frame_mbs_only_flag =1,表示码流中图像为帧格式,否则可能时场格式和MBAFF
mb_adaptive_frame_field_flag
表示是否使用宏块级帧场自适应编码,如果mb_adaptive_frame_field_flag=1,则宏块可能帧宏块,也可能是场宏块,具体由宏块头中的mb_field_decoding_flag决定。
direct_8x8_inference_flag
用于B slice中 B_Skip\B_Direct宏块 direct 预测 mv。
frame_mbs_only_flag= 0时,direct_8x8_inference_flag 需为 1.
frame_cropping_flag
表示解码后的图像需要根据crop信息进行裁剪,如下图所示。真实图像数据为黄色区域,而解码输出数据为蓝色区域(包括黄色区域)。通过4个crop信息可以得到真实数据区域。
通常crop信息出现在图像宽高不是16整数倍的码流中,因为H264解码以16x16大小宏块为单位,图像真实宽高需要16byte对齐。
vui_parameters_present_flag
表示SPS中是否存在VUI信息。