数据压缩11 | 实验7 | MP4及H.264码流分析

一、实验准备

声明:
由于程序H264Visa.exe无法打开我自己的mp4视频CCTV大楼.mp4(闪退),老师所给的材料demo.mp4中没有B帧,而只有I帧和P帧,所以我只能用此程序分析demo.264文件格式,同时利用程序eseye_u.exe输出包含IPB帧的GOP的帧类型、编码比特数、QP值(其实找不到导出的地方,只能看看……),太坎坷了,抹泪,等我学会了h.264编码。。。

二、分析过程

0. h.264&mp4区别

H.264是一种高性能的视频编解码技术。MPEG-4 AVC、MPEG-4 Part 10,还是ISO/IEC 14496-10,都是指H.264。H.264最大的优势是具有很高的数据压缩比率,在同等图像质量的条件下,H.264的压缩比是MPEG-2的2倍以上,是MPEG-4的1.5~2倍。优势:低码率、高质量的图象、容错能力强、网络适应性强。

根据上课所学,h.264和mpeg-2预测、变换、量化、编码模块顺序上并无大的区别,主要不同在于,h.264用了些新技术:

  1. 帧内编码。在空域内进行帧内预测,提高帧内编码精确度。
  2. 运动估计和补偿。采用不同尺寸不同形状的块进行划分,有着高分辨率的子像素运动估计(选择多个参考帧进行估计)。
  3. DCT变换,采用整数DCT变换。
  4. 增加自适应消块滤波器去除块效应。
  5. 熵编码技术。采用通用变长编码、基于上下文的自适应变长码编码、基于上下文的自适应二进制算术编码。

1. h.264文件格式

初始化H.264解码器所需要的信息参数,包括编码所用的profile,level,图像的宽和高,deblock滤波器。这些都可以在header info获得。
两个重要的NALU

1.1. SPS(即Sequence Paramater Set,序列参数集)

SPS中保存了一组编码视频序列(Coded video sequence)的全局参数。
在这里插入图片描述
格式详解
(1) profile_idc:(66)
标识当前H.264码流的profile。H.264中定义了三种常用的档次profile:
基准档次:baseline profile;
主要档次:main profile;
扩展档次:extended profile;

(2) level_idc:(31)
标识当前码流的Level。编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数,码流所遵从的level由level_idc指定。

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

(4) log2_max_frame_num_minus4:(4)
用于计算MaxFrameNum的值。计算公式为
M a x F r a m e N u m = 2 l o g 2 _ m a x _ f r a m e _ n u m _ m i n u s 4 + 4 MaxFrameNum = 2^{log2\_max\_frame\_num\_minus4 + 4} MaxFrameNum=2log2_max_frame_num_minus4+4
MaxFrameNum是frame_num的上限值,frame_num是图像序号的一种表示方法,在帧间编码中常用作一种参考帧标记的手段。

(5) log2_max_pic_order_cnt_lsb_minus4:(2)
用于计算MaxPicOrderCntLsb的值,该值表示POC的上限。计算方法为
M a x P i c O r d e r C n t L s b = 2 l o g 2 _ m a x _ p i c _ o r d e r _ c n t _ l s b _ m i n u s 4 + 4 MaxPicOrderCntLsb = 2^{log2\_max\_pic\_order\_cnt\_lsb\_minus4 + 4} MaxPicOrderCntLsb=2log2_max_pic_order_cnt_lsb_minus4+4

(6)pic_order_cnt_type:(2)
表示解码picture order count(POC)的方法。POC是另一种计量图像序号的方式,与frame_num有着不同的计算方法。该语法元素的取值为0、1或2。

(7) num_ref_frames:(2)
用于表示参考帧的最大数目。

(8) gaps_in_frame_num_value_allowed_flag:(0)
标识位,说明frame_num中是否允许不连续的值。

(9) pic_width_in_mbs_minus1:(53)
用于计算图像的宽度。单位为宏块个数,因此图像的实际宽度为:
f r a m e _ w i d t h = 16 × ( p i c _ w i d t h _ i n _ m b s _ m i n u s 1 + 1 ) frame\_width = 16 × (pic\_width\_in\_mbs\_minus1 + 1) frame_width=16×(pic_width_in_mbs_minus1+1)
可以得出图像宽为:frame_width=16×(53+1)=864

(10) pic_height_in_map_units_minus1:(29)
使用PicHeightInMapUnits来度量视频中一帧图像的高度。
PicHeightInMapUnits并非图像明确的以像素或宏块为单位的高度,而需要考虑该宏块是帧编码或场编码,其计算方式为:
P i c H e i g h t I n M a p U n i t s = 16 ∗ ( p i c _ h e i g h t _ i n _ m a p _ u n i t s _ m i n u s 1 + 1 ) PicHeightInMapUnits =16*( pic\_height\_in\_map\_units\_minus1 + 1) PicHeightInMapUnits=16(pic_height_in_map_units_minus1+1)
计算得图像高为:picheightmapunits=480

(11) frame_mbs_only_flag:(1)
标识位,说明宏块的编码方式。当该标识位为0时,宏块可能为帧编码或场编码;该标识位为1时,所有宏块都采用帧编码。根据该标识位取值不同,PicHeightInMapUnits的含义也不同,为0时表示一场数据按宏块计算的高度,为1时表示一帧数据按宏块计算的高度。
按照宏块计算的图像实际高度FrameHeightInMbs的计算方法为:
F r a m e H e i g h t I n M b s = ( 2 − f r a m e _ m b s _ o n l y _ f l a g ) × P i c H e i g h t I n M a p U n i t s FrameHeightInMbs = ( 2 − frame\_mbs\_only\_flag ) ×PicHeightInMapUnits FrameHeightInMbs=(2frame_mbs_only_flag)×PicHeightInMapUnits
图像实际高度frame_height=1×30=30

(12) mb_adaptive_frame_field_flag
标识位,说明是否采用了宏块级的帧场自适应编码。当该标识位为0时,不存在帧编码和场编码之间的切换;当标识位为1时,宏块可能在帧编码和场编码模式之间进行选择。

(13) direct_8x8_inference_flag:(1)
标识位,用于B_Skip、B_Direct模式运动矢量的推导计算。

(14) frame_cropping_flag:(1)
标识位,说明是否需要对输出的图像帧进行裁剪。

(15) vui_parameters_present_flag:(1)
标识位,说明SPS中是否存在VUI信息。只有这里有帧率!!!找了好久
在这里插入图片描述
帧率 = t i m e _ s c a l e / n u m _ u n i t s _ i n _ t i c k 帧率=time\_scale/num\_units\_in\_tick 帧率=time_scale/num_units_in_tick
60000 / 1001 = 59.94 H z 60000/1001=59.94Hz 60000/1001=59.94Hz
在这里插入图片描述

1.2. PPS(即图像参数集Picture Parameter Set)

在这里插入图片描述
(1) pic_parameter_set_id:(0)
表示当前PPS的id。某个PPS在码流中会被相应的slice引用,slice引用PPS的方式就是在Slice header中保存PPS的id值。该值的取值范围为[0,255]。

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

(3) entropy_coding_mode_flag:(0)
熵编码模式标识,该标识位表示码流中熵编码/解码选择的算法。对于部分语法元素,在不同的编码配置下,选择的熵编码方式不同。例如在一个宏块语法元素中,宏块类型mb_type的语法元素描述符为“ue(v) | ae(v)”,在baseline profile等设置下采用指数哥伦布编码,在main profile等设置下采用CABAC编码。

标识位entropy_coding_mode_flag的作用就是控制这种算法选择。当该值为0时,选择左边的算法,通常为指数哥伦布编码或者CAVLC;当该值为1时,选择右边的算法,通常为CABAC。

(4) bottom_field_pic_order_in_frame_present_flag:(0)
标识位,用于表示另外条带头中的两个语法元素delta_pic_order_cnt_bottom和delta_pic_order_cn是否存在的标识。这两个语法元素表示了某一帧的底场的POC的计算方法。

(5) num_slice_groups_minus1:(0)
表示某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice group。

(6) num_ref_idx_l0_default_active_minus1、num_ref_idx_l0_default_active_minus1:(1、0)
表示当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的默认值。

(7) weighted_pred_flag:(0)
标识位,表示在P/SP slice中是否开启加权预测。

(8) weighted_bipred_idc:(0)
表示在B Slice中加权预测的方法,取值范围为[0,2]。0表示默认加权预测,1表示显式加权预测,2表示隐式加权预测。

(9) pic_init_qp_minus26和pic_init_qs_minus26:(0、0)
表示初始的量化参数。实际的量化参数由该参数、slice header中的slice_qp_delta/slice_qs_delta计算得到。

(10) chroma_qp_index_offset:(0)
用于计算色度分量的量化参数,取值范围为[-12,12]。

(11) deblocking_filter_control_present_flag:(1)
标识位,用于表示Slice header中是否存在用于去块滤波器控制的信息。**当该标志位为1时,slice header中包含去块滤波相应的信息;**当该标识位为0时,slice header中没有相应的信息。

(12) constrained_intra_pred_flag:(0)
若该标识为1,表示I宏块在进行帧内预测时只能使用来自I和SI类型宏块的信息;若该标识位0,表示I宏块可以使用来自Inter类型宏块的信息。

(13) redundant_pic_cnt_present_flag:(0)
标识位,用于表示Slice header中是否存在redundant_pic_cnt语法元素。当该标志位为1时,slice header中包含redundant_pic_cnt;当该标识位为0时,slice header中没有相应的信息

2. h.264的I帧和P帧宏块分布

宏块类型表示的是宏块不同的分割和编码方式,在h.264的语法结构中,宏块类型在宏块层(macroblock_layer)中用mb_type表示(请参考h.264语法结构分析中的macroblock_layer)。而mb_type是与当前宏块所在的slice相关的,相同数值的mb_type在不同类型的slice中表示的类型会不一样。

2.1. 第一个I帧

在这里插入图片描述
在这里插入图片描述

2.2. P帧

在这里插入图片描述
在这里插入图片描述
可以看到,I帧所有的块都是I类型,P少部分块用的是I类型,大部分是P类型,但是I类型所用比特数占总比特数绝大部分。

3. mp4文件某GOP

eseye_u.exe打开CCTV大楼.mp4文件观察第一个GOP:
I帧
在这里插入图片描述
I帧
在这里插入图片描述

B帧1
在这里插入图片描述
B帧2
在这里插入图片描述
可以看出解码顺序和显示顺序并不同步,IPB帧的大小size也差距很大,符合IPB帧编码特点。
用tool输出statistic.csv文件,其中包含type、size、offset、num,并不能输出 QP(量化参数),虽然能在页面上看到。

  1. 以第一个GOP为例,其IPB帧的size均值作图为:
    在这里插入图片描述
  2. IPB帧数统计条形图
    在这里插入图片描述
  3. 以图像帧号为横坐标、每帧所用比特数为纵坐标曲线图
    在这里插入图片描述

4. MP4文件IPB帧宏块分布

4.1. I帧

在这里插入图片描述
在这里插入图片描述
可以从上方看到I帧的最大、最小QP(但就是输出不了),这里宏块类型主要有全红、红十六两种(我自己命名的名字),小格子越多,量化程度越高,红十六在细节多的地方就非常多,全红在平滑处较多,其具体数据如下:

全红红十六
在这里插入图片描述在这里插入图片描述

4.2. 第一个P帧

在这里插入图片描述
出现的宏块有:全黄、全红、红十六、全蓝、蓝二(蓝横、蓝竖)、蓝四,重复的我就不列在表格中了。全黄就是我们所说的P_skip(即跳过不编码宏块,解码时可以直接复制参考宏块)
全黄其详细信息:
在这里插入图片描述
其他的宏块:

全蓝蓝横蓝竖蓝四
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

4.3. 某个B帧

在这里插入图片描述
出现了黄四和绿四,黄四仍然是B_Skip,绿四是新出现的B类型宏块

黄四绿四
在这里插入图片描述在这里插入图片描述

三、总结反思

虽然复习时间有限,数据压缩也很难,考试可能 考得非常不好,但是好在每次实验都有先在onenote做记录,延迟写报告的时候总不至于从头开始,还有最后一个实验,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月婵婵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值