H.265视频编码与技术全析(上)
一. 概述
作为新一代视频编解码格式,H.265得到越来越广泛的应用。不久之前,苹果公司在翘首期盼中发布了iPhone6,该款手机较之以往的iPhone,不仅仅只是简单地增大了屏幕,其采用了H.265视频编码解码技术,可达到在有限带宽下传输更高质量的网络视频。虽然对于大部分人来讲,H.265还有点陌生,然而早在两年前,爱立信就已经推出了首款H.265编解码器。使用H.265编解码的一个巨大优势是仅需目前主流编码视频H.264一半的比特率,就可提供同等质量的视频。
接下来,为大家详细介绍H.265视频编码技术究竟有什么样的优势。
新一代视频压缩标准:H.265
视频编解码标准主要来源于国际电联ITU-T和国际标准化组织ISO,ITU的H.26×系列视频压缩标准经过了H.261、H.263,H.263+这样一个演进过程。而ISO的视频压缩标准是MPEG系列,从MPEG1、MEPG2到MPEG4,之后两个标准化组合走向合作,成立了JVT,推出了在当前最有效的视频压缩标准:H.264/AVC。
随后,H.264的应用范围不断扩展,成熟度也不断提高,于2013年定稿发布了下一代视频压缩标准,命名为HEVC(High EfficiencyVideoCoding),分别被ITU-T和ISO/IEC采纳成为国际标准,即H.265视频压缩标准。H.265在现有的视频编码标准H.264基础上,进一步提高压缩效率、提高鲁棒性(Robustness抗变换性)和错误恢复能力、减少实时的时延、减少信道获取时间和随机接入时延、降低复杂度,以达到最优化设置。
高清晰,低码率
如今,4K超高清技术大行其道,传统的H.264已面临瓶颈限制。以编码单位来说,H.264中每个宏块(marcoblock,MB)大小都是固定的16x16像素。然而,在更高分辨率下,单个宏块所表示的图像内容信息大大减少,H.264所采用的宏块经过整数变换后,低频系数相似程度也大大提高,出现大量冗余,导致H.264编码对高清视频的压缩效率明显降低;其次,H.264算法宏块个数的爆发式增长,会导致每个编码宏块的预测模式、运动矢量、参考帧索引和量化级等宏块级参数信息占用更多码流资源,也降低了编码压缩率。
相比H.264,H.265提供了更多不同的工具来降低码率。H.265的编码单位可以选择从最小的8x8到最大的64x64。信息量不多的区域划分的宏块较大,编码后的码字较少,而细节多的地方划分的宏块就相应的小和多一些,编码后的码字较多,这样就相当于对图像进行了有重点的编码,针对重要的更多关键细节的部分进行增强划块,从而降低了整体的码率,编码效率就相应得到了提高。这个过程在H.265上,可以通过系统自行适应识别实现。
最新H.265标准基本继承了H.264的框架,H264由于算法优化,只能低于1Mbps的速度实现标清数字图像传送;H265则可以实现利用1~2Mbps的传输速度传送720P(分辨率1280*720)普通高清音视频传送。这意味着,旨在有限带宽下H.265能够传输更高质量的网络视频,同时,仅需原先的一半带宽即可播放相同质量的视频。
H.265技术的应用
编码技术主要运用于视频播放设备、软件应用以及拍摄、录制视频的设备。人们最熟悉的莫过于PPS网络视频播放器。在PC屏客户端产品上面,PPS已经于2013年初推出了基于H.265标准的高清视频,并命名“臻高清”为自己的高清品牌。同时 PPS不断加大了在H.265技术应用方面的研究,把H.265推向手机客户端,且在性能上不断优化提升。
在视频播放设备上,4K超清电视的推出,也与H.265编码技术息息相关。索尼于今年9月份发布的国内首台提供高品质4K内容的媒体播放器新品FMP-X10以及索尼在国外已发布的S900B系列和S990B系列,它们都采用了H.265编码格式,在编码技术上更胜从前。对于蓝光来说,H.265的HEVC编码技术足以将巨大的4K电影压缩进一张蓝光光盘,节省更大的内存空间。
在摄像设备上,索尼、海康威视、中兴等厂商陆续发布了该类摄像设备,不仅用于日常的拍照摄影,更用于区域监控安防上。采用了H.265编码技术的超高清监控所能监控的区域更大,不仅减少了安装数量,最主要的是提高了监控的画面质量。避免了一个路口安装多台摄像机而造成庞大的冗余数据的情况。
当然,H.265的应用不仅仅局限于此,据悉,马上入华的索尼PS4也将支持H.265编解码技术。另外,伴随着4G网络的到来,H.265将可能逐渐大规模投入移动客户端,让高清无处不在,使得更多的人们感受并享受这一技术所带来的影响。
这里需要指出的是,虽然H.265带来了远高于H.264的压缩效率,但同时也带来了高于H.264数倍的解码难度,运算量飙升到400~500GOPS,目前还没有广泛的H.265硬解支持。而且,在面对硬件支持度欠缺、标准确立太晚等问题的同时,谷歌VP9也是H.265摆在面前的挑战,毕竟和需要缴纳授权费的H.265相比,VP9使用自由的BSD版权协议对业界的吸引力无疑是巨大的。
二、名词
CTU: 编码树单元
CU: 编码单元
PU: 以CU为根,对CU进行划分,一个预测单元PU包含一个亮度预测块PB和两个色度预测块PB.
TU: 以CU为根,变换单元TU是在CU的基础上划分的,跟PU没有关系,采用四叉树划分方式,具体划分有率失真代价决定,下图给出了某个CU划分成TU的结构。
1. H265-NALU-Type介绍
NAL_TRAIL_N
= 0, NAL_TRAIL_R = 1, NAL_TSA_N = 2, NAL_TSA_R = 3, NAL_STSA_N = 4, NAL_STSA_R
= 5, NAL_RADL_N = 6, NAL_RADL_R = 7, NAL_RASL_N = 8, NAL_RASL_R = 9,
NAL_BLA_W_LP = 16, NAL_BLA_W_RADL = 17, NAL_BLA_N_LP = 18, NAL_IDR_W_RADL = 19,
NAL_IDR_N_LP = 20, NAL_CRA_NUT = 21, NAL_VPS = 32, NAL_SPS = 33, NAL_PPS = 34,
NAL_AUD = 35, NAL_EOS_NUT = 36, NAL_EOB_NUT = 37, NAL_FD_NUT = 38,
NAL_SEI_PREFIX = 39, NAL_SEI_SUFFIX = 40,
2. H264和H265获取帧类型/NALU类型的区别
H264获取方式为 code&0x1f 取低5位,如00 00 00 01 65 则65&0x1f=5表示IDR帧
H265获取方式为 (code & 0x7E)>>1 , 如00 00 00 01
40 则(40&0x7e)>>1 = 32--vps
3. H265中帧类型的介绍GOP等
H265和H264的不同有H265引入了多种方式的帧编码方式,其次H265的GOP不像H264那种为封闭式,H265是封闭和开放式都支持;H264封闭式GOP: H264中单个GOP内部帧解码不会依赖其它GOP,即每个GOP都可独立解码,关键点就是IDR帧的强制刷新起了阻隔作用,避免错误帧相互影响,所以H264中GOP开始的第一帧必须为IDR关键帧,IDR为I帧的一种采用帧内编码无参考方式,但I帧不一定是IDR帧,普通I帧会参考前边的IDR,在RTC中,用的最多的就是IDR关键帧。
关于GOP。
这是图像组(Group of Pictures)的意思,表示编码的视频序列分成了一组一组的有序的帧的集合进行编码。每个GOP一定是以一个I帧开始的,但是却不一定指代的是两个I帧之间的距离。因为一个GOP内可能包含几个I帧,只有第一个I帧(也就是第一帧)才是关键帧。在程序cfg中,GOP的长度和两个I帧的距离也是两个不同参数指定的(如IntraPeriod和GOP Size或者类似的参数)。所以,两个I帧的间距不可能大于GOP的长度,一般情况是更小的。
关于IDR。
这个词儿的全称是Instantaneous Decoding Refresh,是在H.264中定义的结构。在H.264中,IDR帧一定是I帧,而且一定是GOP的开始,也是H.264 GOP的关键帧。但是反过来却不成立,I帧不一定是IDR帧。GOP的长度不是定死不变的,在H.264的编码器中,如果判定场景发生变化,那么及时不到原定GOP的末尾,也会在这个位置加入一个IDR,作为新一个GOP的开始。此时这个GOP的长度就被缩小了。
闭合GOP和开放GOP(closed GOP/open GOP),CRA
闭合GOP是H.264中GOP的格式。在H.264的GOP中,所有的GOP都是独立解码的,与其他GOP无关,即它们都是“封闭”的。但是在HEVC中,GOP的结构发生了变化,采用了“开放”的结构,在解码过程过可能会参考其他GOP的数据。这时,一个GOP的起始帧命名为CRA, clean random access,同样采用帧内编码,但是这个GOP内的帧间编码帧可以越过CRA参考前一个GOP的数据,这便是GOP的open。
关于BLA
BLA只是CRA在视频流切换情况下的一种特例。视频流在某个RAP上要求切换到另一个视频流继续解码,则直接将该CRA同另一个视频流中的接入CRA连接,后者便是BLA。由于BLA之前解码到缓存的视频流与当前视频流无关,因此其特性类似于直接从该点进行随机存取后的CRA。
RASL和RADL
这是两种GOP间的图像类型。如果解码器从某个CRA随机接入,则按照显示顺序的后面几帧数据由于缺少参考帧而不能解码,这些图像将被解码器抛弃,即skip leading。而对于没有从当前CRA接入的数据,这些图像可以被正常解码显示,因此称为decodable leading。由于这些数据是有可能舍弃的,因此其他图像(trailing
pictures)不能参考这些数据,否则万一这些图像被舍弃,将会有更多的图像受其影响而不能正常解码。
HEVC Encoder整体框架:
CU是用作帧间和帧内编码的基础模块,它的特点是方块,它的大小从8×8到最小64×64,LCU是64x64,可以使用递归分割的四分树的方法来得到,大的CU适用于图像中比较平滑部分,而小的部分则适用于边缘和纹理较丰富的区域。CU采用四叉树的分割方式,具体的分割过程通过两个变量来标记:分割深度(Depth)和分割标记符(Split_flag)。
在设置CTU大小为64X64的情况下,一个亮度CB最大为64X64即一个CTB直接作为一个CB,最小为8X8,则色度CB最大为32X32,最小为4X4。每个CU包含着与之相关联的预测单元(PU)和我变换单元(TU).
Z扫描顺序:
Z扫描
PU是预测的最基本的单元,是从CU中分割出来的,HEVC中对于skip模式、帧内模式和帧间模式。
帧内预测有2种划分模式,只有在CU尺寸为8x8时,才能用PART_NxN。
帧间有8种划分模式,PU可以使方形也可以使矩形,但是其分割不是递归的,与CU的分割还是有区别的。尺寸最大为64×64到最小4×4。
TU也是采用四叉树划分,以CU为根,TU可以大于PU,但是却不可以大于CU的大小。
在帧内编码过程中,TU 的尺寸严格小于
PU 的尺寸;
在帧间编码过程中,TU 的尺寸不一定小于PU
的尺寸,但一定小于其对应 CU 的尺寸。
Slice可以包含一个独立的Slice Segment(SS)和多个非独立的SS,一个Slice中的SS可以互相依赖,但不能依赖其它Slice。图中,虚线是SS分隔线,实线是Slice分隔线。
Tile是一个矩形块,Slice是一个条带。
Tile、Slice需要满足以下两个条件之一:
1. 任一Slice中的所有CTU属于同一个Tile:
2. 任一Tile中的所有CTU属于同一个Slice:
举例说明:
假设视频序列的显示顺序为①,这是一个完整的GOP,解码顺序为②
①I
B B P B B P B B P
②I
P B B P B B P B B
在H.264中,第一个I帧为IDR,GOP为闭合结构,因此两个GOP组成视频的结构为
I B B
P B B P B B PI B B P B B P B B P(显示顺序)
I P B
B P B B P B BI P B B P B B P B B(解码顺序)
而在HEVC中,两个I帧为CRA,GOP为开放结构,因此GOP的结构为:
I B B
P B B P B B PB B I B B P B B P B(显示顺序)
I P B
B P B B P B B I B B P B B P B B…(解码顺序)
两个红色的B帧表示的是按照解码顺序在CRA之后,该GOP内参考的前一个GOP进行编码的图像。这样便很容易得知,如果选择在第二个CRA进行随机接入,这两个红色的B帧将会由于没有参考帧无法解码而被舍弃。这两个红色的B帧即RASP。如果没有选择这个CRA进行随机接入,这两个红色B帧将可以顺利解码,即成为RADP。
对于BLA,情况也是类似的。由于出现码流拼接,第二段码流的CRA之后的B也会因为没有参考帧无法解码而丢弃。很容易理解,此时缓存中的参考帧数据还来自上一段码流,跟当前码流没关系,当然不能用作B的参考了。
至于HEVC这么设计的目的,应该是为了编码效率考虑的。因为B帧的压缩比相对是最高的,引入这种设计可以在不影响随机存取性能的前提下,尽可能增大B帧的比重,提高整体压缩编码的性能。
H265中引入的新结构:
Random
access point picture
IDR(instantaneous decoder refresh)
BLA(broken link access)
CRA(clean random access)
Leading
picture RASL和RADL的总称
RADL(random access decodable leading)在随机接入点后,可以按顺序解码的图像
RASL(random access skipped leading)因为包含帧间信息而不能解码的图像--会被丢弃
Temporal sub-layer
access picture随机接入点后按解码和输出顺序的图像。
TSA(temporal sublayer access)
STSA(stepwise temporal sublayer access)
因此可以说随机接入点的图像一定是I帧,则H265中I帧的类型有以下几种IDR/BLA/CRA,也就是NALU中的16~21均为I帧,代码可参考ffmpeg相关判断代码:
switch (type) {
case
NAL_VPS:
vps++;
break;
case
NAL_SPS:
sps++;
break;
case
NAL_PPS:
pps++;
break;
case
NAL_BLA_N_LP:
case
NAL_BLA_W_LP:
case
NAL_BLA_W_RADL:
case
NAL_CRA_NUT:
case
NAL_IDR_N_LP:
case
NAL_IDR_W_RADL: irap++; break;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章