VVC帧间预测(五)SbTMVP和AMVR

基于子块的TMVP (SbTMVP)

VTM中提出的基于子块的TMVP(subblock-based temporal motion vector prediction ,SbTMVP)和HEVC中的TMVP类似。TMVP计算方法可以参考扩展的merge模式中1.2节时域候选列表构建。

SbTMVP和TMVP主要有以下两点不同:

  • TMVP在CU级预测运动而SbTMVP在sub-CU级预测运动。

  • TMVP直接使用同位图像的同位块计算时域MV,而SbTMVP在计算同位块前先进行一个运动偏移,这个运动偏移来自当前CU的空域相邻块的MV。

SbTMVP计算当前CU的子CU的MV分为两步:

1、如下图所示,检查当前CU的空域相邻块A1,如果A1的参考图像正好是当前图像的同位图像则用A1的MV作为运动偏移,否则运动偏移设为(0,0)。

2、使用第1步得到的运动偏移(将当前块的坐标加上运动偏移)从同位图像获得子CU的运动信息(MV和参考图像索引)。如下图所示,图中假设使用A1的MV作为运动偏移,然后对每个子CU获取其在同位图像中对应块的运动信息,然后按照TMVP的处理方法将获得的MV进行缩放得到子CU的MV。

在VTM5中,基于子块的merge list内既包含SbTMVP候选项也包含affine merge候选项。在序列参数集(sequence parameter set ,SPS)中有标志位表明是否使用SbTMVP模式,如果允许使用SbTMVP模式那么在基于子块的merge list中SbTMVP候选项在affine merge候选项前面。该list中候选项数量在SPS中指定,VTM5规定最多候选数量为5。

在SbTMVP中子CU的大小固定为8x8,且和affine merge模式一样只有当CU宽高都大于等于8时才使用SbTMVP模式。

Adaptive motion vector resolution (AMVR)

在HEVC中当slice header中use_integer_mv_flag=0时,MVD(CU的MV和MVP的差值)按照1/4亮度像素精度传输。VVC提出了CU级的AMVR,AMVR允许CU的MVD使用不同精度编码。

其中可选精度如下:

  • Normal AMVP模式:1/4亮度像素精度,整亮度像素精度,4倍亮度像素精度。

  • Affine AMVP模式:1/4亮度像素精度,整亮度像素精度,1/16亮度像素精度。.

在CU级,只有当MVD至少有一个非零分量时才需要传输其精度。如果所有MVD分量(水平分量和垂直分量)都是0,则MVD默认使用1/4亮度像素精度。

当一个CU至少有一个非零MVD分量时,有一个标志位表示该CU的MVD是否使用1/4亮度像素精度,如果该标志位为0则表示使用1/4亮度像素精度不需要再传其他标志位。否则,对于Normal AMVP模式的CU需要第二个标志位表示是否使用整亮度像素精度或4倍亮度像素精度。对于Affine AMVP模式的CU需要第二个标志位表示是否使用整亮度像素精度或1/16亮度像素精度。为了确保重建的MV有同样的精度MVP会四舍五入到和MVD同样的精度。MVP朝0进行四舍五入(也就是负MVP朝正无穷方向,正MVP朝负无穷方向)。

在VTM5中两种模式的像素精度定义如下:

const MvPrecision Mv::m_amvrPrecision[3] = { MV_PRECISION_QUARTER, MV_PRECISION_INT, MV_PRECISION_4PEL }; // for cu.imv=0, 1 and 2
const MvPrecision Mv::m_amvrPrecAffine[3] = { MV_PRECISION_QUARTER, MV_PRECISION_SIXTEENTH, MV_PRECISION_INT }; // for cu.imv=0, 1 and 2

精度转换代码如下:

  void changePrecision(const MvPrecision& src, const MvPrecision& dst)
  {
    const int shift = (int)dst - (int)src;
    if (shift >= 0)
    {
      *this <<= shift;
    }
    else
    {
      const int rightShift = -shift;
      const int nOffset = 1 << (rightShift - 1);
#if JVET_N0335_N0085_MV_ROUNDING
      hor = hor >= 0 ? (hor + nOffset - 1) >> rightShift : (hor + nOffset) >> rightShift;
      ver = ver >= 0 ? (ver + nOffset - 1) >> rightShift : (ver + nOffset) >> rightShift;
#else
      hor = hor >= 0 ? (hor + nOffset) >> rightShift : -((-hor + nOffset) >> rightShift);
      ver = ver >= 0 ? (ver + nOffset) >> rightShift : -((-ver + nOffset) >> rightShift);
#endif
    }
  }
​
  void roundToPrecision(const MvPrecision& src, const MvPrecision& dst)
  {
    changePrecision(src, dst);
    changePrecision(dst, src);
  }

参考

JVET-N1002

JVET-M0246

JVET-M0165

感兴趣的请关注微信公众号Video Coding

发布了87 篇原创文章 · 获赞 108 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Dillon2015/article/details/103864926
今日推荐