H.264文件解析与码流分析


概述

 目前,H.264视频压缩编码方式仍在视频压缩领域有一席之地,所熟知的MPEG-4 AVC与MPEG-4 Part 10方式,均指H.264。其主要编码过程以去除各种冗余信息为目的,包含数据变换、基于运动补偿的帧间预测、熵编码和量化过程。

 本实验通过使用软件对一个mp4文件进行码流信息查看,并分析其基本信息、帧信息等参数,并对其比例与概率等参数进行绘制分析,以熟悉文件的结构与编码方式。

 所用软件:H264VisaElecard StreamEye Tools


实验步骤

一、打开文件

 使用H264Visa软件,打开一个h264编码的mp4文件后,可看到软件出现了四个信息窗口:

  • Summary
     显示文件整体的信息。
    在这里插入图片描述
     图中即为对整个文件的码流进行信息读取,可以看到此码流的profile类型(与之后SPS中的信息对应,可见后文)、视频格式等信息。

  • Header Info
     显示当前文件信息的数值。其中提取的重要信息包含SPS、PPS等信息。
    在这里插入图片描述

  • MB Info 和 Pixel Info
     两窗口分别显示当前选取的宏块的信息以及宏块内所有像素的信息。
    在这里插入图片描述
    在这里插入图片描述
     因目前刚刚打开文件,其所在位置为mp4的文件信息头,未读取任何帧信息,故对画面内的相关数据还为空。

二、文件信息分析

1、SPS信息

 SPS信息即SPS即Sequence Paramater Set,又称作序列参数集。SPS中保存了一组编码视频序列(Coded Video Sequence)的全局参数。
在这里插入图片描述

 通过其中的参数可求得文件图像序列的信息。重要参数包括:

  • profile_idc
     标识当前码流的profile。H264的profile参数定义包含Baseline、Main、Extended 和 High 等档次,直观影响的是GOP内IPB帧的比例关系。profile_idc 所对应的档次如下:
    在这里插入图片描述
     此实验中可看到对应值为100,即本视频所用的 profile 为 High。

  • constraint_set[%d]_flag
     此字段一般有多个,是对视频序列的码流编码档次方面增加限制性条件的参数。

  • level_idc
     标识当前码流的level。其level参数的真值为level_idc/10,对应下表。
    在这里插入图片描述
     可见此实验文件中level的值为3.1。

  • log2_max_frame_num_minus4
     用于计算MaxFrameNum的值。计算公式为MaxFrameNum = 2(log2_max_frame_num_minus4 +4)。MaxFrameNum的物理含义是frame_num的上限值,frame_num是图像序号的一种表示方法,在帧间编码中常用作一种参考帧标记的手段。
     此文件中的 MaxFrameNum 值为 26 = 64。

  • pic_order_cnt_type
     表示解码picture order count(POC)的方法,取值空间为 0、1 或 2。

  • gaps_in_frame_num_value_allowed_flag
     标识位,说明frame_num中是否允许不连续的值。

  • pic_width_in_mbs_minus1
     用于计算图像的宽度,单位为宏块个数。
     因序列使用宏块为16×16,故其图像宽度公式为
    frame_width = 16 × (pic_width_in_mbs_minus1 + 1)

  • pic_height_in_map_units_minus1
     用于计算图像的高度,单位为宏块个数,公式为
    frame_height = 16 × (pic_height_in_map_units_minus1 + 1)

 至此,使用 pic_width_in_mbs_minus1和 pic_height_in_map_units_minus1可直接得到图像分辨率:
frame_width = 16 × (pic_width_in_mbs_minus1 + 1) = 640
frame_height = 16 × (pic_height_in_map_units_minus1 + 1) = 368
 故图像分辨率为640×368。
 使用VLC打开文件,发现确实为此分辨率。

在这里插入图片描述

  • frame_mbs_only_flag
     标识位,说明宏块的编码方式。等于0时表示本序列中所有图像的编码模式都是帧,等于1时表示本序列中的编码模式可能是帧或场或帧场自适应。
  • direct_8x8_inference_flag
     标识运动向量的预测方法,frame_mbs_only_flag为0时此处则应为1。
  • frame_cropping_flag
     标识是否需要对输出图像进行裁剪,要裁剪(=1)时需要再声明裁剪的边缘位置frame_cropping_rect_left_offset,frame_cropping_rect_right_offset,frame_cropping_rect_top_offset,frame_cropping_rect_bottom_offset。
  • vui_parameters
     标识码流中是否有vui子结构。同时,其中 time_scale 与num_unis_in_tick 可以对视频的帧率进行计算。公式为
    frame = time_scale / num_unis_in_tick
     本实验中的 time_scale 与 num_unis_in_tick 分别为96和4,故其帧率为24,与VLC中读取信息相同。

2、PPS信息

 PPS信息即Picture Paramater Set,图像参数集,也为表征序列图像信息的数据。其与SPs信息共同封装于文件头中。
在这里插入图片描述

 其重要参数如下:

  • pic_parameter_set_id
     声明当前PPS的id。
  • seq_parameter_set_id
     声明当前PPS所引用的SPS的id。
  • entropy_coding_mode_flag
     熵编码模式标识,表示码流中熵编码/解码选择的算法。等于0时表示熵编码使用CAVLC,等于1时表示熵编码使用CABAC。
  • num_slice_groups_minus1
     表示某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice group。
  • num_ref_idx_l0_default_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的默认值。
  • 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中没有相应的信息。

三、帧内分析

1、帧内编码帧

 将文件读取的指针向后移动一帧,画面即出现,为整个文件的第一帧,也为第一个GOP的 I 帧。可看到所有宏块全部为 I 类型宏块,且其中有16×16宏块、8×8宏块和4×4宏块。其中8×8和4×4的宏块共有539个,16×16的宏块为381个。
在这里插入图片描述

 将宏块显示打开后如图。
在这里插入图片描述
 观察可以发现,在帧内预测帧(I 帧)中,其宏块类型与宏块当前所处位置的图像复杂度有关。更加细分的宏块,其更适用于较复杂的区域。将16×16宏块、8×8宏块和4×4宏块各取一个查看信息。

宏块类型 宏块信息
16×16 在这里插入图片描述
8×8 在这里插入图片描述
4×4 在这里插入图片描述

2、前向预测编码帧

 向后逐帧跳转,到达第一个P帧后,查看此帧图像宏块信息。

在这里插入图片描述
 不难看出P帧中宏块大部分为 P 类型宏块(829/920),且P类型宏块中16×16(349/829)类型和skip宏块(408/829)为最多。原因应在于前后图像的变化不大,同时存在帧内编码宏块以弥补此帧相对于之前的 I 帧差异较大的细节部分。
在这里插入图片描述
 其中与上述 I 帧内部宏块分为16×16、8×8、4×4宏块同理,此帧中还包含16×8的宏块。但此帧中发现了一个贼有意思的宏块,若未显示错误,此宏块是一个含有8×8和8×4的混合宏块。
在这里插入图片描述
 此宏块的信息仍显示为8×8宏块。

3、双向预测内插编码帧

 随机抽取一位幸运的 B 帧进行查看。

在这里插入图片描述
 同样可看到帧内预测宏块 I 类型宏块的存在。同时,大部分为双向预测帧编码类型的宏块(881/920)
在这里插入图片描述
 同时,将此帧的运动向量进行显示。经历了几秒钟的程序未响应之后, 可看到此 B 帧在进行块匹配过程中,运动向量的存在量很多,原因应在于画面的镜头一直摇晃的缘故。
在这里插入图片描述
 若换一个仅有部分区域移动的视频序列,可看到运动向量的排布。(下图中运动向量均为红色,仅在人的区域出现,可以放大图片观看)
在这里插入图片描述

4、图像帧比特分析

 使用 Elecard StreamEye Tools 软件打开mp4文件,可看到其所有的帧及其比特数全部在GUI界面中展示。
在这里插入图片描述
 其中橙色的线为设置显示的帧比特数的平均值,即视频序列的比特率。红色的为 I 帧,蓝色为 P 帧,绿色为 B 帧。从图中就可看出,相对来说 B 帧要比 I 帧和 P 帧占用更小的比特数。而在视频开头,由于视频中开头部分镜头晃动较为明显,故P帧和B帧比特率并未低多少。

在这里插入图片描述

 在上图中也可看到由于帧间预测,帧存在乱序,即显示顺序与其在码流中的顺序不同的情况。

 将此视频序列的帧信息存入csv文件中,可看到码流顺序的帧排序。
在这里插入图片描述

 考虑到第一个GOP开头部分由于镜头原因,比特数对比程度不大,故对第二个GOP中(第251 - 500个帧,下标为250 - 499)帧的比特数进行绘图。
在这里插入图片描述


参考与引用

[1] h264 : 关于level_idc和Profile_IDC的解释
[2] JM-H264参考手册(VIP下载地址)
[3] (知乎) H264码流中SPS PPS详解
[4] 从H264/H265码流SPS中获取宽、高及帧率

猜你喜欢

转载自blog.csdn.net/weixin_48680270/article/details/125095544