参考文献:见《High Efficiency Video Coding (HEVC)》Inter-Picture Prediction in HEVC章节
《HEVC标准介绍、HEVC帧间预测论文笔记》系列博客,目录见:http://www.cnblogs.com/DwyaneTalk/p/5711333.html
DPB
在HEVC的编码端,会维护一个DPB存放解码的图像。对于每个CVS里的图片,都有一个唯一的POC(不同CVS里的图片,POC可以相同),POC的范围是-2^31~2^31-1,POC的值(PicOrderCntVal)LSB部分在slice header里通过slice_pic_order_cnt_lsb,MSB部分通过先前图片推断出来。PDB里面的图片可能是会被参考或者还没有输出的。解码端需要维护同样一个PDB,需要的PDB size是通过SPS里的sps_max_dec_pic_buffering_minus1传输的。
PDB中图像,如果不会再被参考的,则成为non-reference pictures,non-reference pictures存储在PDB里,是因为按照output order还没有被输出。对于需要被参考的图像,根据下面叙述的规则分为short-term reference pictures和long-term reference pictutres。
There is a rule determining how long a short-term picture can stay in the DPB. It says that the POC span of the set of pictures consisting of (1) the current picture, (2) revTid0Pic, (3) the short-term reference pictures in the DPB, and (4) the pictures in the DPB that are waiting for output, must be within half of the POC span covered by POC LSB. This rule guarantees the correctness of POC MSB derivation and improves error robustness by enabling the decoder to identify lost short-term pictures.
上述规则也确保了,对于POC的MSB部分,可以根据先前图像的PrevTid0Pic推断出。所以PDB的里面的图像分为short-term reference、long-term reference和non-reference三类,图像进入PDB后最初以short-term reference存在,最终以non-reference状态被从PDB中丢弃。状态变化如下图:
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727154811700-1848698985.png)
图1
另外SPS中有sps_max_num_reorder_pics和sps_max_latency_increase_plus1两个参数和PDB相关。相关定义如下:
sps_max_num_reorder_pics, here denoted as NumReorderPics, indicates the maximum number of pictures that can precede
any picture in decoding order and follow it in output order.
sps_max_latency_increase_plus1 is used to signal MaxLatencyPictures, which indicates the maximum number of pictures that can precede any picture in output order and follow that picture in decoding order.
NumReorderPics表示output order在当前图像后面但decoding order在当前图像前面的图像最大数目,这个参数也确定了最小的PDB存数图像数目。
MaxLatencyPicture表示decoding order在当前图像后面但是output order在当前图像前面的最大数目,这个数确定了以图像为单位的最小的编码延时。
RPS
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727155042669-328488530.png)
图5
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727155057997-1151095153.png)
图6
![]()
RPS:reference picture set,参考图像集。是在每个图像的slice header里,有一系列指示short-term reference和long-term reference的标志组成。RPS里包含的是一组POC(指示在PDB中的位置)和相应的参考类型标识(指示短期还是长期)。
PDB中的short-term reference,如果在RPS中指示为short-term,则为短期参考帧。所以PDB中的short-term reference根据RPS可以归为三类:RefPicSetStCurrAfter(POC大于当前图像)、RefPicSetStCurrBefore(POC小于当前图像)、RefPicSetStFoll。
PDB中的short-term reference和long-term reference,如果在RPS中指示为long-term,则为长期参考帧。所以PDB中的long-term reference根据RPS可以归为两类:RefPicSetLtCurr、RefPicSetLtFoll。
RPL:Reference Pictures Lists,对于P帧(单向预测)只有L0;对于B帧(双向预测),有L0和L1。
对于L0的构建:RefPicSetStCurrBefore中图像按照POC降序,然后接着是RefPicSetStCurrAfter按照POC升序,最后把RefPicSetStCurrBefore加入。
对于L0的构建:RefPicSetStCurrAfter按照POC升序,然后接着是RefPicSetStCurrBefore中图像按照POC降序,最后把RefPicSetStCurrBefore加入。
所以对于下图的帧编码结构,编码每一帧时PDB和RPS的变化如表:
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727154838091-1671491412.png)
图2和表1
然后L0为{P1, B2, B6, P5, I0},L1为{B6, P5, P1, B2, I0},由于L0和L1中内容是一样的(顺序不同),所以对于B帧,就存在双向预测的参考帧相同。此外,对于L0和L1的长度,在PPS中通过参数传递,并可以在slice header中重写(最大长度为15)。
Motion Data
帧间预测的Motion Data是针对一个帧间预测块,通过四叉树结构确定了CU划分结构后,对于每个CU确定帧内、帧间预测(包括特殊的Merge和Skip),然后对于Inter CU,确定PU划分模式之后。对于每个PU,需要进行ME(运动估计)和MC(运动补偿),最终确定的motion data包括参考帧索引、运动矢量和运动残差,解码端由参考帧索引和运动矢量确定预测像素值,然后根据预测像素值和预测残差得到解码像素值。
Inter-Prediction Block Merge And Skip
HEVC定义了三种帧间预测的方式:Inter、Merge和Skip。其中Merge和Skip模式中,运动矢量残差MVD为0,所以是根据相邻的已编码块直接得到运动参数。不同之处在于:
1、Skip模式下,预测残差也为0或者通过策略可以舍去,所以Skip模式下也不需要编码预测残差,只需要编码运动矢量参考块位置;
2、Skip模式只针对2Nx2N的PU划分模式,所以Skip是面向CU,而Merge是面向PU,相当于将具有相同运动参数的PU块进行合并,且保证合并后的PU不能组成2Nx2N的CU(后面解释)。
而Inter模式则是根据相邻块得到运动矢量测预测值MVP,然后得到运动矢量残差MVD,需要编码帧间编码的预测方向(前向、后向或双向)、参考帧索引值、运动矢量预测器索引值、运动矢量预测残差MVD和像素值预测残差。通过
运动矢量预测器索引值、运动矢量预测残差MVD可以得到MV,通过MV、参考帧索引、像素值预测残差根据预测方向可以得到补偿后像素值。
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727154930966-378738175.png)
图3
标准的帧间模式决策过程如上图,编码时:
首先通过cu_skip_flag标记当前CU的预测模式是否为Skip;
若是:则编码一个merge_index指示运动参数的参考块(在merge candidate list中);
若否:则编码一个标记符表示是帧内还是帧间预测模式;
如果是帧间编码,编码PU的划分划分模式part_mode,然后对于一个PU,编码merge_flag表示是否是Merge模式;
若是Merge:编码merge_index
指示运动参数的参考块(在merge candidate list中),还要编码参考帧索引;
若不是Merge:编码预测方向(前向、后向或双向)、参考帧索引值、运动矢量预测器索引值(AMVP中的candidate list中)、运动矢量预测残差MVD和像素值预测残差。
Merge和Skip的运动参数预测,如下图:
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727154959731-2143309611.png)
图4
运动参数预测候选列表分为四类:空间相邻已编码块、时间相邻已编码块、生成的候选运动参数和0。最大的候选列表数目MaxNumMergeCand在slice header中传输,传输值是最大数目与5的插值(如0表示最大数目为5,5表示最大数目为1)。当通过空间和时间选择的候选运动参数(去除重复和不符合要求的之后)数目小于MaxNumMergeCand,则通过生成候选运动参数(依次是双向和非尺度变换)增加候选列表。如果数目还达不到MaxNumMergeCand,则通过补0的方式使得候选运动参数列表数目达到规定数目,这样有利于解码端处理。
空域候选块运动参数:如下图
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727155042669-328488530.png)
图5
对于最左边,空间候选块选择顺序依次是:a1,b1,b0,a0,(b2),b2只有前面4个有任意一个不可用时,才会考虑b2。对于空间候选块确定,需要进行下面三方面的检查:
1、是否可用:是否编码已完成、是否是帧间;
2、避免不同参考块运动数据的重复冗余,但是标准规定不需要对任意两个临近块都进行检查,选择b0时只需要检测b1,选择a0时只需要检查a1,选择b2时只需要检查a1和b1;
3、避免候选PU和当前PU形成一个2Nx2N的CU,如上图右边,对于Nx2N和2NxN的当前PU,a1和b1则分别不可用。
时域候选块运动参数:如下图
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727155057997-1151095153.png)
图6
如上图,当前帧为Curr_pic,当前预测块为Curr_pic。参考帧列表(RPL)中POC距离当前帧最近的帧为Col_pic,对应位置的PU为Col_PU,对于Col_PU选择,如上左图,首选C1,若C1不可用则选C0。Curr_PU和Col_PU的参考帧分别是Curr_ref和Col_ref,to和td表示两个帧之间的POC距离,如图。 通过根据to和td的比例关系,对Col_PU的运动矢量MV进行缩放,即可得到Curr_PU的运动矢量空间预测值。由于预测时,需要存储参考帧中所有块的MV,为了节省内存开销,HEVC中将存储MV的PU块最小限制在16x16,当16x16的块中存在多个MV不同的PU,那么则选择第一个PU的MV存储。
当通过空间和时间,得到的候选运动参数达不到MaxNumMergeCand时,就要求通过生成(生成方式没看懂,参考HM)和补0的方式填充最终归并候选列表。
AMVP AMVP:Advanced Motion Vector Prediction,是一种通过竞争机制实现运动矢量预测的工具。如上面所述,帧间分为Inter、Merge个Skip三种方式,Merge和Skip得到MV的方式和Inter得到MV的方式不同,Merge和Skip的MVD为0,所以直接通过上面“
Merge和Skip的运动参数预测”所述的方法预测得到MV,编码时只需要输出合并候选列表的索引值,就可以得到MV(=MVP)。而对于Inter,则通过AMVP得到MVP,然后编码时除了传输MV预测候选列表(运动矢量预测器)的索引值,还需要传输MVD。
不同之处是,AMVP中:(细节见HEVC书P188)
先从5个空间相邻块选择:如图5,先从{a0,a1}和{b0,b1,b2}分别按顺序选择第一个(共2个)可用的加到候选列表中;
如果2个空间候选运动参数预测值有一个不可用,那么则需要从时域对应位置产生一个候选运动参数预测值;
如果时域运动参数预测值也不可用,那么补0,保证最终候选数目为2。
Fractional Sample Interpolation
![](https://images2015.cnblogs.com/blog/515354/201607/515354-20160727155132778-1495462914.png)
HEVC插值滤波器如上:
对于H.264(YUV=420的情况):
插值亮度时:1/2像素采用6抽头滤波器,1/4像素采用双线性插值法,对1/2像素进行二次插值;
插值色度时:采用1/8精度的双线性插值。
对于HEVC:
插值亮度时:使用表5的7抽头和8抽头滤波器分别对1/4和1/2像素进行插值;
插值色度时:使用表6的7个4抽头滤波器对7个1/8像素进行插值。
所以相对于H.264,HEVC的插值有如下优点:
1、插值1/4像素时,直接进行插值,不需要根据1/2插值结果进行二次插值,去除了因1/2插值结果取整舍去导致1/4像素的插值精度下降;
2、HEVC的插值滤波器是基于DCT的更精确的插值滤波器。