【数据压缩9】H.264码流分析

H.264介绍

H.264,同时也是MPEG-4第十部分,是由ITU-T视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT,Joint Video Team)提出的高度压缩数字视频编解码器标准。这个标准通常被称之为H.264/AVC(或者AVC/H.264或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC).

实验步骤

1、选择一个.mp4或者.264文件

2、在码流分析仪软件中打开该文件,从几个层次进行分析

(1)分析SPS和PPS里都包含哪些主要的信息,给出参数值。(例如分辨率、帧率、GOP结构等等)

(2)以一个GOP为例,分析如下信息:

每个图像帧的类型及所用的编码比特数、QP值;并以图像帧号为横坐标、每帧所用比特数为纵坐标画出曲线图;以图像帧号为横坐标、每帧所用QP为纵坐标画出曲线图。
以第一个I帧作为分析对象,基于该帧图像的空间特性,分析每个宏块所采用的编码类型及其比例。
以第一个P帧作为分析对象,基于该帧图像的空间和时间特性,分析每个宏块所采用的编码类型及其比例。
以某一个B帧作为分析对象,基于该帧图像的空间和时间特性,分析每个宏块所采用的编码类型及其比例。

码流分析

1.在码流分析仪软件中打开一个mp4文件
用eseye_u.exe打开.264文件
在这里插入图片描述

SPS

1.SPS语法图
在这里插入图片描述
2.实例
在这里插入图片描述
(1)profile_idc
标识当前H.264码流的profile。
标识当前H.264码流的profile。H.264中定义了三种常用的档次profile:
基准档次:baseline profile;
主要档次:main profile;
扩展档次:extended profile;

(2)level_idc
标识当前码流的Level。编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数,码流所遵从的level由level_idc指定。
在这里插入图片描述
当前文件level_idc = 13,查表可知,码流级别为1.3

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

(4)chroma_format_idc
与亮度取样对应的色度取样。chroma_format_idc 的值应该在 0到 3 的范围内(包括 0 和 3)。当 chroma_format_idc 不存在时,应推断其值为 1( 4:2:0 的色度格式)。
观察上图可知chroma_format_idc=1,色度格式为4:2: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(4),
计算MaxFrameNum = 2^(log2_max_frame_num_minus4 +4)= 16。

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

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

当前文件log2_max_pic_order_cnt_lsb_minus4 = 2(6),计算MaxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4)=64。

(8)num_ref_frames
用于表示参考帧的最大数目。
当前num_ref_frames=5

(9)pic_width_in_mbs_minus1
用于计算图像的宽度,单位为宏块个数。在H.264中,每个解码宏块都是16*16像素的块。因此图像的实际宽度为:frame_width = 16 × (pic_width_in_mbs_minus1 + 1)
当前文件pic_width_in_mbs_minus1=22,所以图像的宽为frame_width = 16 × (pic_width_in_mbs_minus1 + 1)=368

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

当前文件pic_height_in_map_units_minus1=12,图像的高为PicHeightInMapUnits =208
结合(9)和(10),当前视频文件的分辨率为368*208

(11)frame_mbs_only_fla
标识位,说明宏块的编码方式。等于0时表示本序列中所有图像的编码模式都是帧,等于1时表示本序列中的编码模式可能是帧或场或帧场自适应
当前文件frame_mbs_only_fla=1,本序列中的编码模式可能是帧或场或帧场自适应

(12)direct_8x8_inference_flag
标识运动向量的预测方法
frame_mbs_only_flag=0时此处则应为1。

(13)frame_cropping_flag
标识是否需要对输出图像进行裁剪,要裁剪(=1)时需要再声明裁剪的边缘位置frame_cropping_rect_left_offset,frame_cropping_rect_right_offset,frame_cropping_rect_top_offset,frame_cropping_rect_bottom_offset

(14)vui_parameters
标识码流中是否有vui子结构。同时,其中 time_scale 与num_unis_in_tick 可以对视频的帧率进行计算。公式为frame = time_scale / num_unis_in_tick
当前文件frame = time_scale / num_unis_in_tick=60/1=60Hz

PPS

在这里插入图片描述
pic_parameter_set_id:表示当前PPS的id。某个pps在码流中会被相应的slice引用,引用方式为在slice header中保存pps的id值,当前码流中该值为0

seq_parameter_set_id:表示当前PPS所引用的激活的SPS的id。通过这种方式,PPS中也可以取到对应SPS中的参数,当前码流中该值为0

entropy_coding_mode_flag:熵编码模式标识,该标识位表示码流中熵编码/解码选择的算法.当前码流中,改制为1,则选择CABAC算法

pic_order_present_flag:POC的三种计算方法在片层还各需要用一些句法元素作为参数,本句法元素等于1时表示在片头会有句法元素指明这些参数;当前码流中该元素等于0时,表示片头不会给出这些参数,这些参数使用默认值。

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

GOP分析

I

在这里插入图片描述
I帧(帧内预测帧)
所有宏块全部为 I 类型宏块,且其中有16×16宏块、8×8宏块和4×4宏块

P

在这里插入图片描述
P帧(前向预测帧)
P帧中宏块大部分为 P 类型宏块,且P类型宏块中16×16类型最多。原因应在于前后图像的变化不大,同时存在帧内编码宏块以弥补此帧相对于之前的 I 帧差异较大的细节部分。

B

在这里插入图片描述
B帧(双向预测帧)
I 类型宏块仍然存在,大部分为B帧的宏块

总结

图像的数据量: I>P>B;
增大GOP或提高GOP中P/B帧的占比,能够提高压缩比,降低码率。

猜你喜欢

转载自blog.csdn.net/ppinecone/article/details/125792686