H.264编码分析

一、H.264格式解析

1.H.264概述

H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式,它即保留了以往压缩技术的优点和精华又具有其他压缩技术无法比拟的许多优点。

(1)低码流(Low Bit Rate)

和MPEG2和MPEG4 ASP等压缩技术相比,在同等图像质量下,采用H.264技术压缩后的数据量只有MPEG2的1/8,MPEG4的1/3。显然,H.264压缩技术的采用将大大节省用户的下载时间和数据流量收费。

(2)高质量的图象

H.264能提供连续、流畅的高质量图象(DVD质量)。

(3)容错能力强

H.264提供了解决在不稳定网络环境下容易发生的丢包等错误的必要工具。

(4)网络适应性强

H.264提供了网络适应层(Network Adaptation Layer), 使得H.264的文件能容易地在不同网络上传输(例如互联网,CDMA,GPRS,WCDMA,CDMA2000等)。
在这里插入图片描述

2.NAL

NAL全称Network Abstract Layer, 即网络抽象层。在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。因此我们平时的每帧数据就是一个NAL单元(SPS与PPS除外)。
在这里插入图片描述

3.SPS

在H.264标准协议中规定了多种不同的NAL Unit类型,其中类型7表示该NAL Unit内保存的数据为Sequence Paramater Set。在H.264的各种语法元素中,SPS中的信息至关重要。如果其中的数据丢失或出现错误,那么解码过程很可能会失败。SPS及后续将要讲述的图像参数集PPS在某些平台的视频处理框架(比如iOS的VideoToolBox等)还通常作为解码器实例的初始化信息使用。
SPS中保存了一组编码视频序列(Coded video sequence)的全局参数。所谓的编码视频序列即原始视频的一帧一帧的像素数据经过编码之后的结构组成的序列。而每一帧的编码后数据所依赖的参数保存于图像参数集中。一般情况SPS和PPS的NAL Unit通常位于整个码流的起始位置。
在这里插入图片描述
本实验SPS数据:
在这里插入图片描述

元素含义如下:

(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表示。
另外,constraint_set0_flag ~ constraint_set5_flag是在编码的档次方面对码流增加的其他一些额外限制性条件。
在我们实验码流中,profile_idc = 0x42 = 66,因此码流的档次为baseline profile。

(2) level_idc

标识当前码流的Level。编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数,码流所遵从的level由level_idc指定。
当前码流中,level_idc = 31,因此码流的级别为3。

(3) seq_parameter_set_id

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

(4) log2_max_frame_num_minus4

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

(5) pic_order_cnt_type

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

(6) log2_max_pic_order_cnt_lsb_minus4

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

(7) max_num_ref_frames

用于表示参考帧的最大数目。

(8) gaps_in_frame_num_value_allowed_flag

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

(9) pic_width_in_mbs_minus1

用于计算图像的宽度。单位为宏块个数,因此图像的实际宽度为:

frame_width = 16 × (pic_width_in_mbs_minus1 + 1);
本文件实际宽度为(53 + 1)*16 = 864

(10) pic_height_in_map_units_minus1

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

PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1;

(11) frame_mbs_only_flag

标识位,说明宏块的编码方式。当该标识位为0时,宏块可能为帧编码或场编码;该标识位为1时,所有宏块都采用帧编码。根据该标识位取值不同,PicHeightInMapUnits的含义也不同,为0时表示一场数据按宏块计算的高度,为1时表示一帧数据按宏块计算的高度。
本文件为1

按照宏块计算的图像实际高度FrameHeightInMbs的计算方法为:

FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits
本文件高度为(29 + 1)*16 = 480

(12) mb_adaptive_frame_field_flag

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

(13) direct_8x8_inference_flag

标识位,用于B_Skip、B_Direct模式运动矢量的推导计算。

(14) frame_cropping_flag

标识位,说明是否需要对输出的图像帧进行裁剪。

(15) vui_parameters_present_flag

标识位,说明SPS中是否存在VUI信息。

4.PPS

H.264中另一重要的参数集合为图像参数集Picture Paramater Set(PPS)。通常情况下,PPS类似于SPS,在H.264的裸码流中单独保存在一个NAL Unit中,只是PPS NAL Unit的nal_unit_type值为8;而在封装格式中,PPS通常与SPS一起,保存在视频文件的文件头中。
在这里插入图片描述
本实验数据为:
在这里插入图片描述
元素含义如下:

(1) pic_parameter_set_id

表示当前PPS的id。某个PPS在码流中会被相应的slice引用,slice引用PPS的方式就是在Slice header中保存PPS的id值。该值的取值范围为[0,255]。

(2) seq_parameter_set_id

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

(3) entropy_coding_mode_flag

熵编码模式标识,该标识位表示码流中熵编码/解码选择的算法。对于部分语法元素,在不同的编码配置下,选择的熵编码方式不同。例如在一个宏块语法元素中,宏块类型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

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

(5) num_slice_groups_minus1

表示某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice group。slice group是一帧中宏块的组合方式,定义在协议文档的3.141部分。
本文件该值为0,即一帧中所有的slice都属于一个slice group。

(6) num_ref_idx_l0_default_active_minus1、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的默认值。

(7) weighted_pred_flag

标识位,表示在P/SP slice中是否开启加权预测。

(8) weighted_bipred_idc

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

(9) pic_init_qp_minus26和pic_init_qs_minus26

表示初始的量化参数。实际的量化参数由该参数、slice header中的slice_qp_delta/slice_qs_delta计算得到。

(10) chroma_qp_index_offset

用于计算色度分量的量化参数,取值范围为[-12,12]。

(11) deblocking_filter_control_present_flag

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

(12) constrained_intra_pred_flag

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

(13) redundant_pic_cnt_present_flag

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

5.GOP

(1)编码比特数统计

导出数据到csv文件
在这里插入图片描述
使用excel画图
在这里插入图片描述
可以看出I帧编码所需bit数远远高于B/P帧,其次是P帧。

6.I帧

以视频第一个I帧为例,对其编码进行分析。
在这里插入图片描述
红点为intra44;橙点为intra88。
可以看出,I帧编码全部为帧内预测,无帧间编码。
在这里插入图片描述
由此图可以看出,在图像平坦处,编码所使用bit数较少,也多为16*16宏块。在图像陡峭处,反之。
在这里插入图片描述

7.P帧

在这里插入图片描述
黄点为Inter P_skip
蓝点为Inter P_L0_16*16(前向预测)
P帧为前向预测帧,可以看到此帧中绝大部分宏块均为P_skip,即无需占用bit编码,只有少量前向预测宏块。
黄点:
在这里插入图片描述
蓝点:
在这里插入图片描述
因此,P帧所占空间极小
在这里插入图片描述
在这里插入图片描述

8.B帧

在这里插入图片描述
黄点为Inter P_skip
蓝点为Inter P_L1_16*16(后向预测)
P帧为双向预测帧,但由于此片开头为静态镜头,无法看出其运动矢量。
在这里插入图片描述
此帧所占bit数也极小。
在这里插入图片描述
选取了一段典型的下摇镜头中的一帧。
在这里插入图片描述
通过此运动向量可以直观看出其运动方向。

二、H.264编码实验

1.H.264解码

在这里插入图片描述
将提供的.264文件解码,得到YUV文件。
在这里插入图片描述
查找源代码,发现
在这里插入图片描述
该编解码器只支持100KB以下的文件。(后来发现并不是…)
更改文件后再次尝试
在这里插入图片描述
查找源代码
在这里插入图片描述
缺少NALU部分

NALU是一种封装的模组,并拥有NAL-unit 标头(Header),此Header内又有许多资讯,包括 Type。一个完整的NALU是标头(Header)加上位元流(bitstream)。多个NAL-units组成一个存储单元(access unit)。

最终解码
在这里插入图片描述
在这里插入图片描述
在输出的log.dec文件中查看分辨率
在这里插入图片描述
使用YUVviewplus打开生成的YUV文件
在这里插入图片描述
看起来好像不太对…
检查参数确认无误后,使用vooya打开。
在这里插入图片描述
。。。原来是播放器的问题。

2.H.264编码

(1)固定码率

固定码率为1000kbps

InputFile             = "test_rec.yuv"       # Input sequence
FramesToBeEncoded     = 60      # Number of frames to be coded
FrameRate             = 30.0   # Frame Rate per second 
SourceWidth           = 854    # Source frame width
SourceHeight          = 480    # Source frame height
OutputWidth           = 864    # Output frame width
OutputHeight          = 480    # Output frame height
IntraPeriod           = 15   # Period of I-pictures   (0=only first)
NumberBFrames          = 2  # Number of B coded frames 
HierarchicalCoding      =  0  # B hierarchical coding (0= off, 1= 2 layers, 2= 2 full hierarchy, 3 = explicit)
RateControlEnable       = 1     # 0 Disable, 1 Enable
Bitrate                 = 100000 # Bitrate(bps)

生成GOP=15, 2B帧的.264文件。
在这里插入图片描述
再依次生成GOP=12,2B帧;GOP=9,2B帧;GOP=4,1B帧;GOP=12,无B帧;GOP=1,全I帧。
并记录Y的PSNR

码率\规格GOP15_2BGOP9_2BGOP4_1BGOP12_0BGOP1_全I
100kbps34.82134.98435.25434.95530.465

(2)固定GOP

固定GOP长度为12,2B帧
分别生成码率为400kbps,800kbps,1000kbps,1200kbps

规格\码率400kbps800kbps1000kbps1200kbps
12GOP_2B37.26839.80240.76342.065

3.质量分析

(1)主观评测

固定码率
相同码率下,GOP越长,B帧数目越小,图像质量越好。全I帧图像质量较差,由于无帧间预测编码,存在较多冗余数据。
固定GOP
相同GOP结构下,码率越高,图像质量越好。

(2)率失真曲线

在这里插入图片描述
在这里插入图片描述
psnr客观评价与主观评测基本一致。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值