一、H.264概述
H.264是由ITU-T视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT)提出的高度压缩数字视频编解码器标准,这个标准通常被称为H.264/AVC。它是继MPEG-4之后的新一代数字视频压缩格式,具有更高的编码效率,注重对移动和IP网络的适应,并且提供了丰富的错误处理工具以控制或消除丢包和误码。
H.264的功能分为两层:视频编码层(VCL, Video Coding Layer)和网络提取层(NAL, Network Abstraction Layer)。
VCL数据即编码处理的输出,它表示被压缩编码后的视频数据序列。在VCL数据传输或存储之前,编码的VCL数据会先被映射或封装进NAL单元中。
每个NAL单元包括一个原始字节序列负荷(RBSP, Raw Byte Sequence Payload)和一组对应于视频编码的NAL头信息。RBSP由VCL层输出的SODB(SODB, String Of Data Bits)字节对齐处理后封装而成。
二、实验步骤
1、选择视频文件
2、分析sps
sps的参数:
sps所含信息:
(1) profile_idc 标识当前H.264码流的profile
H.264中定义了三种常用的档次profile:
基准档次:baseline profile;
主要档次:main profile;
扩展档次:extended profile;
根据profile_idc的值可以确定码流符合哪一种档次。判断规律为:
profile_idc = 66对应基准档次;
profile_idc = 77对应主要档次;
profile_idc = 88对应扩展档次;
profile_idc = 66,码流档次为baseline profile。
(2) constraint_setn_flag 标识制约条件
等于1时表示必须遵从附录 A.2.n 所指明的所有制约条件;
等于 0 时表示不必遵从所有条件;
当前码流中,constraint_setn_flag均等于0,说明不必遵从所有制约条件。
(3) level_idc 标识当前码流的Level
编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数。码流所遵从的level由level_idc指定,level = level_idc/10.
当前码流中,level_idc = 40,可得码流级别level=4.
(4) seq_parameter_set_id 表示当前的序列参数集的id
seq_parameter_set_id用于识别图像参数集所指的序列参数集,图像参数集PPS可以引用其代表的序列参数集SPS中的参数。该值应在0-31的范围内。
当前码流中,seq_parameter_set_id=0,即当前序列参数集的id = 0.
(5) log2_max_frame_num_minus4 用于计算MaxFrameNum的值
计算公式为:MaxFrameNum = 2^(log2_max_frame_num_minus4 + 4)。
MaxFrameNum是frame_num的上限值,frame_num是图像序号的一种表示方法,在帧间编码中常用作一种参考帧标记的手段。
当前码流中,log2_max_frame_num_minus4 = 0,计算可得MaxFrameNum = 16.
(6) pic_order_cnt_type 表示解码picture order count(POC)的方法
POC是另一种计量图像序号的方式,与frame_num有着不同的计算方法。该语法元素的取值为0、1或2。
当前码流中,pic_order_cnt_type=0.
(7) log2_max_pic_order_cnt_lsb_minus4 用于计算MaxPicOrderCntLsb的值
MaxPicOrderCntLsb表示POC的上限,计算公式为:MaxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4).
log2_max_pic_order_cnt_lsb_minus4=8,MaxPicOrderCntLsb = 4096.
(8) num_ref_frames 用于表示参考帧的最大数目。
当前码流中,num_ref_frames=2,说明参考帧最大数目为2.
(9) gaps_in_frame_num_value_allowed_flag 说明frame_num中是否允许不连续的值
当前码流中,gaps_in_frame_num_value_allowed_flag=0.
(10) pic_width_in_mbs_minus1 用于计算图像宽度
以宏块为单位的图像宽度变量:PicWidthInMbs = pic_width_in_mbs_minus1 + 1
亮度分量的图像宽度变量(以像素为单位):PicWidthInSamplesL = PicWidthInMbs ∗ 16
色度分量的图像宽度变量(以像素为单位):PicWidthInSamplesLC= PicWidthInMbs ∗ MbWidthC
pic_width_in_mbs_minus1=10,PicWidthInMbs=11,图像的宽frame_width = PicWidthInMbs ∗ 16 = 176.
(11) pic_height_in_map_units_minus1 用于计算图像的高度
使用PicHeightInMapUnits来度量视频中一帧图像的高度。PicHeightInMapUnits并非图像明确地以像素或宏块为单位的高度,因为需要考虑该宏块是帧编码或场编码。
PicHeightInMapUnits的计算方式:PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1
pic_height_in_map_units_minus1 = 8,PicHeightInMapUnits=9.
(12) frame_mbs_only_flag 宏块编码方式标识
该标识位为0时,宏块可能为帧编码或场编码;
该标识位为1时,所有宏块都采用帧编码。
根据该标识位取值不同,PicHeightInMapUnits的含义也不同,为0时表示一场数据按宏块计算的高度,为1时表示一帧数据按宏块计算的高度。
按照宏块计算的图像实际高度FrameHeightInMbs的计算方法为:FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits
frame_mbs_only_flag =1,FrameHeightInMbs = 9,图像的实际高度为144 = 9 ∗ 16.
(13) direct_8x8_inference_flag 用于B_Skip、B_Direct模式运动矢量的推导计算。
当前码流中,direct_8x8_inference_flag=1.
(14) frame_cropping_flag 说明是否需要对输出的图像帧进行裁剪。
该标识位为0时,表示不存在帧剪切偏移参数;
该标识位为1时,表示帧剪切偏移参数遵从视频序列参数集中的下一个值;
当前码流中,frame_cropping_flag=0,说明不存在帧剪切偏移参数。
(15) vui_parameters_present_flag 说明SPS中是否存在VUI信息。
该标识位为0时,表示不存在vui_parameters()语法结构;
该标识位为1时,表示存在vui_parameters()语法结构;
当前码流中,vui_parameters_present_flag=0,说明SPS中不存在vui_parameters()语法结构。
3、PPS分析
pps图像参数集:
pps所含信息:
(1)pic_parameter_set_id
表示当前PPS的id。某个PPS在码流中会被相应的slice引用,slice引用PPS的方式就是在Slice header中保存PPS的id值。该值的取值范围为[0,255]。
上图中pic_parameter_set_id=0,当前PPS的id为0
(2)seq_parameter_set_id
表示当前PPS所引用的激活的SPS的id。通过这种方式,PPS中也可以取到对应SPS中的参数。该值的取值范围为[0,31]。
上图中seq_parameter_set_id=0,当前PPS所引用的激活的SPS的id为0
(3)entropy_coding_mode_flag
熵编码模式标识,该标识位表示码流中熵编码/解码选择的算法。对于部分语法元素,在不同的编码配置下,选择的熵编码方式不同。例如在一个宏块语法元素中,宏块类型mb_type的语法元素描述符为“ue(v) | ae(v)”,在baseline profile等设置下采用指数哥伦布编码,在main profile等设置下采用CABAC编码。
标识位entropy_coding_mode_flag的作用就是控制这种算法选择。当该值为0时,选择左边的算法,通常为指数哥伦布编码或者CAVLC;当该值为1时,选择右边的算法,通常为CABAC。
上图中entropy_coding_mode_flag=1,选择右边的算法CABAC
(4)num_slice_groups_minus1
表示某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice group。slice group是一帧中宏块的组合方式,定义在协议文档的3.141部分。(主要用在FMO灵活宏块模式编码时才会用到)
上图中num_slice_groups_minus1=0,一帧中所有的slice都属于一个slice group
(5)num_ref_idx_l0_active_minus1、num_ref_idx_l1_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的默认值。
上图中num_ref_idx_l0_active_minus1=15,num_ref_idx_l1_active_minus1=0
(6)weighted_pred_flag
标识位,表示在P/SP slice中是否开启加权预测。上图中为1.
(7)weighted_bipred_idc
表示在B Slice中加权预测的方法,取值范围为[0,2]。0表示默认加权预测,1表示显式加权预测,2表示隐式加权预测(都应用于B slices)。上图中为2.
(8)pic_init_qp_minus26 和 pic_init_qs_minus26
表示初始的量化参数。实际的量化参数由该参数、slice header中的slice_qp_delta/slice_qs_delta计算得到。上图中两个值均为0。
(9)chroma_qp_index_offset
用于计算色度分量的量化参数,取值范围为[-12,12]。上图中为-2.
(10)deblocking_filter_control_present_flag
标识位,用于表示Slice header中是否存在用于去块滤波器控制的信息。当该标志位为1时,slice header中包含去块滤波相应的信息;当该标识位为0时,slice header中没有相应的信息。
上图中为1.
(11)constrained_intra_pred_flag
若该标识为1,表示宏块在进行帧内预测时只能使用来自和类型宏块的信息;若该标识位0,表示I宏块可以使用来自Inter类型宏块的信息。上图中为0.
(12)redundant_pic_cnt_present_flag
标识位,用于表示Slice header中是否存在redundant_pic_cnt语法元素。当该标志位为1时,slice header中包含redundant_pic_cnt;当该标识位为0时,slice header中没有相应的信息。
上图中为0.
4.GOP分析
由上图可知,当前位置为I帧,是第二个GOP(第一个GOP显示0),第一个GOP的长度为30帧
I帧的编码帧序与显示帧序一致,均为30。
由上图可知,当前位置为P帧,编码帧序与显示帧序不同,是因为B帧先编码后显示。
I帧的比特数最高,其次是P帧,最后是B帧。
量化参数
量化参数QP是量化步长Qstep的序号。
量化参数,反映了空间细节压缩情况。值越小,量化越精细,图像质量越高,产生的码流也越长。如QP小,大部分的细节都会被保留;QP增大,一些细节丢失,码率降低,但图像失真加强和质量下降。
QP取最小值0 时,表示量化最精细;相反,QP取最大值51时,表示量化是最粗糙的。
QP和Qstep具有线性相关性,Qstep随着QP的增加而增加,每当QP值增加6,Qstep便增加一倍。