一、实验目的
认识并理解H.264标准的码流结构,深刻理解各种帧类型的结构并进行分析,深刻理解各种编码模式和运动矢量。
二、实验原理
序列参数集和图像参数集
-
序列参数集SPS(Sequence parameter set)
在H.264标准协议中规定了多种不同的NAL Unit类型,其中类型7表示该NAL Unit内保存的数据为Sequence Paramater Set。一般情况下SPS和PPS位于NAL单元的起始部分。
字段 | 说明 |
---|---|
profile_idc | 该码流的编码规格。 |
level_idc | 标识当前码流的level。编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数,码流所遵从的level由level_idc指定。 |
seq_parameter_set_id | 表示当前的序列参数集的id。通过该id值,图像参数集pps可以引用其代表的sps中的参数。 |
pic_order_cnt_type | 表示解码picture order count(POC)的方法。 |
log2_max_pic_order_cnt_lsb_minus4 | 用于计算MaxPicOrderCntLsb的值,该值表示POC的上限。 计算方法为 MaxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4)
|
num_ref_frames | 规定了可能在视频序列中任何图像帧间预测的解码过程中用到的短期参考帧和长期参考帧、互补参考场对以及不成对的参考场的最大数量。 |
pic_width_in_mbs_minus1 | 加 1 是指以宏块为单元的每个解码图像的宽度。 |
pic_height_in_map_units_minus1 | 加 1 是指以宏块为单元的每个解码图像的高度。 |
frame_mbs_only_flag | 标识位,说明宏块的编码方式。当该标识位为0时,宏块可能为帧编码或场编码;该标识位为1时,所有宏块都采用帧编码。 |
direct_8x8_inference_flag | 标识位,用于B_Skip、B_Direct模式运动矢量的推导计算。 |
gaps_in_frame_num_value_allowed_flag | 标识位,说明frame_num中是否允许不连续的值。 |
frame_cropping_flag | 标识位,说明是否需要对输出的图像帧进行裁剪。 |
vui_parameters_present_flag | 标识位,说明SPS中是否存在VUI信息。 |
- 图像参数集PPS(Picture parameter set)
字段 | 说明 |
---|---|
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 | 熵编码模式标识,该标识位表示码流中熵编码/解码选择的算法。对于部分语法元素,在不同的编码配置下,选择的熵编码方式不同。 |
num_slice_groups_minus1 | 表示某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice group。slice group是一帧中宏块的组合方式,定义在协议文档的3.141部分。 |
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中是否存在用于去块滤波器控制的信息。当该标志位为1时,slice header中包含去块滤波相应的信息;当该标识位为0时,slice header中没有相应的信息。 |
constrained_intra_pred_flag | 若该标识为1,表示I宏块在进行帧内预测时只能使用来自I和SI类型宏块的信息;若该标识位0,表示I宏块可以使用来自Inter类型宏块的信息。 |
redundant_pic_cnt_present_flag | 标识位,用于表示Slice header中是否存在redundant_pic_cnt语法元素。当该标志位为1时,slice header中包含redundant_pic_cnt;当该标识位为0时,slice header中没有相应的信息。 |
三、实验步骤
(一)用码流分析仪从几个层次分析.mp4文件。
1.分析SPS和PPS里都包含哪些主要的信息,给出参数值。(例如分辨率、帧率、GOP结构等等)
1.1 查看Movie.mp4第一帧的SPS信息:
- profile_idc:100,标识high profile。
- level_idc:31,对应level3.1,每秒最多处理的宏块数为108000个,每帧最多的宏块数3600个,high profile下最高比特率为17.5Mbps。
- seq_parameter_set_id:0,当前序列参数集id为0.。
-
log2_max_pic_order_cnt_lsb_minus4:2,据此计算出POC上限为
2^(2+4)=64
。 - pic_order_cnt_type:0。
- num_ref_frames:16,参考帧最大数量为16。
- pic_width_in_mbs_minus1:39,每个宏块宽度为40。
- pic_height_in_map_minus1:22,一帧图像的高度为23。
- gaps_in_frame_num_value_allowed_flag:0,frame_num中不允许不连续的值。
- frame_mbs_only_flag:1,所有宏块采用帧编码。
- frame_cropping_flag:0,输出图像帧不进行裁剪。
- vui_parameters_present_flag:1,SPS中存在VUI信息。
1.2 查看Movie.mp4第一帧的PPS信息:
- pic_parameter_set_id:0,当前PPS的id为0。
- seq_parameter_set_id:0,当前PPS所引用的激活SPS的id为0,即上述SPS。
- entropy_coding_mode_flag:1,熵编码模式标识为1。
- num_slice_groups_minus1:0,一帧中所有的slice都属于一个slice group。
- weighted_pred_flag:1,开启加权预测。
- weighted_bipred_idc:2,B slice中采用隐式加权预测。
- pic_init_qp_minus26:0,初始量化参数。
- pic_init_qs_minus26:0,初始量化参数。
- chroma_qp_index_offset:-2,用于计算色度分量。
- deblocking_filter_control_present_flag:1,slice header中包含去块滤波相应的信息。
- constrained_intra_pred_flag:0,I宏块可以使用来自Inter类型宏块的信息。
- redundant_pic_cnt_present_flag:0,slice header中没有redundant_pic_cnt语法元素相应的信息。
1.3 结论
-
分辨率
图像宽度包含宏块数40,图像高度包含宏块数23,帧高度23*16=368,帧宽度40*16=640,分辨率640*368。
验证:
-
帧率
vui_parameters_present_flag=1,表示带有帧率信息。
根据fps=time_scale/num_units_in_tick
计算得出fps=96/1=96kbps。
验证:
虽然根据SPS算得的帧率为96帧每秒,但该视频的实际帧率为24帧每秒,说明该SPS不准确。
- GOP结构
由num_slice_groups_minus1=0得知一帧中所有的slice都属于一个slice group。
2.以一个GOP为例,分析如下信息:
2.1 每个图像帧的类型及所用的编码比特数、QP值;并以图像帧号为横坐标、每帧所用比特数为纵坐标画出曲线图;以图像帧号为横坐标、每帧所用QP为纵坐标画出曲线图。
-
图像帧号-每帧比特数
取第二个GOP,GOP格式为IBBBPBBBPBPBPBP...从图中可以发现,I帧的比特数最多,B帧所用比特数最少。这是因为I帧仅利用帧内编码,压缩比较低;B帧是双向预测帧,压缩比最高,P帧则介于二者之间。
-
图像帧号-每帧QP
QP表示量化步长,量化步长越小,说明量化越精细,图像质量越高,反之则相反。从图中可以看出,编号为30的I帧量化步长最小,质量越高,这与其所用比特数最多相对应。B帧和P帧的量化步长都较大,质量较低,这与其所用比特数较少相对应。
2.2 以第一个I帧作为分析对象,基于该帧图像的空间特性,分析每个宏块所采用的编码类型及其比例。
所有宏块的颜色相同,它们都属于帧内编码。可以看到该帧共有920个宏块,宏块类型与宏块当前所处位置的图像复杂度有关,图像复杂度比较低的位置,宏块较大,复杂度比较高的位置宏块较小。
2.3 以第一个P帧作为分析对象,基于该帧图像的空间和时间特性,分析每个宏块所采用的编码类型及其比例。
该P帧中帧内编码类型的宏块有91个,前向预测类型的宏块有829个。在P帧中出现帧内编码类型宏块说明在该帧中找到的匹配块比在前一帧找到的匹配块的误差更小。
2.4 以某一个B帧作为分析对象,基于该帧图像的空间和时间特性,分析每个宏块所采用的编码类型及其比例。
从统计信息看,920个宏块中,B_skip块有737个,占了绝大部分,这种类型的宏块直接复制上一帧的对应宏块,极大地降低了数据率,这也是B帧所用比特数少的原因。
3.用码流分析软件检查所生成的码流中各种编码模式和运动矢量等信息
分析不同统计特性的视频图像对应的编码模式和运动矢量的特点。
可以看到在第四帧人物面部的运动向量是向右下的,这是因为从第一帧(I帧)到第四帧(P帧),画面中的人物向左上方移动,P帧在I帧中找到的匹配块位于当前位置的右下方。
四、软件介绍
1.H264Visa
- 主界面
-
Summary
存放媒体的总体信息。
Profile指的是编码器的配置,由标准规定。例如,Low Profile可能不使用B帧,这样做会使编码效率降低(B帧可以双向预测),但同步的要求更低。
- Header Info
H.264以NAL为一个数据单元,每个NAL以一个Header和一个Payload构成。不再像MPEG一样使用树状结构,Picture信息和Sequence信息单独存储在PPS和SPS包中。接收到SPS和PPS包就可以进行码流的传输了。
- MB Info
宏块级别的信息。包含了预测类型、运动向量等信息。
H264Visa将MB分为四类:
1.一般信息、MB类型、位置、位号、流数据等。
2.Pred Info,获取详细的帧间/帧内预测信息。
3.Reflist Info,获取当前切片的详细参考列表。
4.BS Info(如果有),用于当前MB的边界强度列表。
- Pixel Info
像素级别的信息。当前样本最终解码的数据信息。
H264Visa为每个宏块提供非常详细的像素信息。目前支持七类:
1.最终解码像素信息;
2.解块滤波器前的像素信息;
3.预测像素信息;
4.剩余像素信息;
5.DCT系数信息;
6.原始参考YUV像素信息;
7.最终解码像素与原始参考YUV像素信息之间的差值。