一、实验要求
1.选择一个.mp4或者.264文件。
在码流分析仪软件中打开该文件,从几个层次进行分析:
2. (1)分析SPS和PPS里都包含哪些主要的信息,给出参数值。(例如分辨率、帧率、GOP结构等等)
(2)以一个GOP为例,分析如下信息:
每个图像帧的类型及所用的编码比特数、QP值;并以图像帧号为横坐标、每帧所用比特数为纵坐标画出曲线图;以图像帧号为横坐标、每帧所用QP为纵坐标画出曲线图。
以第一个I帧作为分析对象,基于该帧图像的空间特性,分析每个宏块所采用的编码类型及其比例。
以第一个P帧作为分析对象,基于该帧图像的空间和时间特性,分析每个宏块所采用的编码类型及其比例。
以某一个B帧作为分析对象,基于该帧图像的空间和时间特性,分析每个宏块所采用的编码类型及其比例。
二、实验过程
使用demo.mp4文件
(1) profile_idc
标识当前H.264码流的profile。H.264中定义了三种常用的档次profile:
基准档次:baseline profile;
主要档次:main profile;
扩展档次:extended profile;
在H.264的SPS中,第一个字节表示profile_idc,根据profile_idc的值可以确定码流符合哪一种档次。判断规律为:
profile_idc = 66 → baseline profile;
profile_idc = 77 → main profile;
profile_idc = 88 → extended profile;
在新版的标准中,还包括了High、High 10、High 4:2:2、High 4:4:4、High 10 Intra、High
4:2:2 Intra、High 4:4:4 Intra、CAVLC 4:4:4 Intra等,每一种都由不同的profile_idc表示。
此文件中profile_idc = 0x42 = 66,码流的档次为baseline profile。
constraint_set0_flag ~ constraint_set5_flag是在编码的档次方面对码流增加的其他一些额外限制性条件。
(2) level_idc
标识当前码流的Level。编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数,码流所遵从的level由level_idc指定。
此文件中level_idc = 0x1e = 31,码流的级别为3.1。
(3) seq_parameter_set_id
表示当前的序列参数集的id。通过该id值,图像参数集pps可以引用其代表的sps中的参数。
此文件中seq_parameter_set_id = 0,序列参数集的id = 0。
(4) log2_max_frame_num_minus4
用于计算MaxFrameNum的值。计算公式为MaxFrameNum = 2^(log2_max_frame_num_minus4 +4)。MaxFrameNum是frame_num的上限值,frame_num是图像序号的一种表示方法,在帧间编码中常用作一种参考帧标记的手段。
此文件中log2_max_frame_num_minus4 = 4,MaxFrameNum = 256。
(5) pic_order_cnt_type
表示解码picture order count(POC)的方法。POC是另一种计量图像序号的方式,与frame_num有着不同的计算方法。该语法元素的取值为0、1或2。
此文件中pic_order_cnt_type = 2。
(6) num_ref_frames
用于表示参考帧的数目。
此文件中num_ref_frames = 2。
(7) gaps_in_frame_num_value_allowed_flag
标识位,说明frame_num中是否允许不连续的值。
此文件中gaps_in_frame_num_value_allowed_flag = 0,不允许不连续的值。
(8) pic_width_in_mbs_minus1
用于计算图像的宽度。单位为宏块个数,因此图像的实际宽度为:
frame_width = 16 × (pic_width_in_mbs_minus1 + 1);
此文件中pic_width_in_mbs_minus1 = 53,故frame_width = 16 × (53 + 1) = 864。
(9) pic_height_in_map_units_minus1
使用PicHeightInMapUnits来度量视频中一帧图像的高度。PicHeightInMapUnits并非图像明确的以像素或宏块为单位的高度,而需要考虑该宏块是帧编码或场编码。PicHeightInMapUnits的计算方式为:
PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1;
当前码流中,pic_height_in_map_units_minus1 = 29,故PicHeightInMapUnits = 29 + 1 = 30。
(10) frame_mbs_only_flag
标识位,说明宏块的编码方式。当该标识位为0时,宏块可能为帧编码或场编码;该标识位为1时,所有宏块都采用帧编码。根据该标识位取值不同,PicHeightInMapUnits的含义也不同,为0时表示一场数据按宏块计算的高度,为1时表示一帧数据按宏块计算的高度。
按照宏块计算的图像实际高度FrameHeightInMbs的计算方法为:
FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits
因此图像的实际高度frame_height的计算方法为:
frame_height = 16 × FrameHeightInMbs
当前码流中,frame_mbs_only_flag = 1,PicHeightInMapUnits = 30,故FrameHeightInMbs = ( 2 − 1 ) * 30 = 30。
因此图像的实际高度为:frame_height = 16 × 30 =480
(11) direct_8x8_inference_flag
标识位,用于B_Skip、B_Direct模式运动矢量的推导计算。
当前码流中,direct_8x8_inference_flag = 1
(12) frame_cropping_flag
标识位,说明是否需要对输出的图像帧进行裁剪。
当前码流中,frame_cropping_flag = 1即需要对输出的图像帧进行裁剪。
(13) vui_parameters_present_flag
标识位,说明SPS中是否存在VUI信息。
当前码流中,vui_parameters_present_flag = 1即SPS中存在VUI信息。