H266/VVC 帧间预测中 AMVR 技术

自适应运动精度 AMVR

  1. 最早的视频编码标准采用整数像素精度描述运动矢量,因此运动估计只能利 用位于整数点位置的像素。但实际上物体的真实运动经常是连续的,采用整像素 精度并不能很好的描述运动矢量。H.264 和 HEVC 都对亮度分量的运动矢量采用 1/4 像素精度、色度分量的运动矢量采用 1/8 像素精度。在HEVC中,当切片头中的use_integer_mv_flag等于0时,运动矢量差(MVDs,即运动矢量与预测运动矢量的差值)以四分之一亮度样本为单位进行信号传输。
  2. H.266/VVC 中运动矢量 精度进一步提升,亮度分量的运动矢量采用 1/16 像素精度、色度分量的运动矢量采用 1/32 像素精度。随着像素精度的提升,预测精度增长,但随之会带来编 码所需比特的大幅度提升。 综合考虑预测精度和编码比特消耗,H.266/VVC 提出了 CU 级的自适应运动矢量精度 AMVR(Adaptive motion vector resolution) 技术,在 CU 层面对亮度分量 MVD 采用不同的像素精度进行编码。根据当前 CU 帧间预测模式的差别,亮度分量 MVD 编码精度有不同的选取策略:
    • 如果是普通 AMVP 模式,亮度分量 MVD 编码精度可在 1/4 像素精度、1/2 像素精度、整数像素精度和 4 像素精度中根据率失真大小自适应选择。
    • 如果是仿射 AMVP 模式,亮度分量 MVD 编码精度可在 1/4 像素精度、整数像素精度和 1/16 像素精度中根据率失真大小自适应的选取。
  3. 对于 MVD 全为零的情况,默认使用 1/4 像素精度。编码器通过率失真比较确定当前 CU 的精度,对于正常 AMVP 模式,首先计算并比较 1/4 精度和整数精度的率失真代价,决定 MVD 精度是否有必要进一步检查四精度采样 MVD 精度的 RD cost。 当 1/4 精度的率失真比整型 MVD 精度的率是很小得多时,将跳过四精度的率失真检查。如果整像素精度的率失真明显大于先前测试的 MVD 精度的最佳率失真,则跳过 1/2 精度的检查。
  4. 对于 Affine AMVP 模式,如果在检查 Affine merge/skip 模式,merge/skip 模 式,1/4 精度普通 AMVP 模式和 1/4 精度 Affine AMVP 的率失真后,未选择 Affine inter 模式,则不检查 1/16 精度和整像素精度 Affine inter 模式。此外,在 1/4 精 度 Affine inter 模式下获得的 Affine 参数可以被用作 1/16 亮度采样和 1/4 精度 Affine inter 模式下的起始搜索点。
  5. 在 2020 年 1 月的 JVET-Q2002[Algorithm description for Versatile Video Coding and Test Model 8 (VTM 8)] 提案中对 GPM 技术进行了总结描述。
    在这里插入图片描述H266/VVC 帧间预测中 AMVR 技术_第1张图片H266/VVC 帧间预测中 AMVR 技术_第2张图片
  6. 在 VVenC 编码器中Mv.h 文件中关于 MV 的精度申明:
enum MvPrecision
{
  MV_PRECISION_4PEL     = 0,      // 4-pel
  MV_PRECISION_INT      = 2,      // 1-pel, shift 2 bits from 4-pel
  MV_PRECISION_HALF     = 3,      // 1/2-pel
  MV_PRECISION_QUARTER  = 4,      // 1/4-pel (the precision of regular MV difference signaling), shift 4 bits from 4-pel
  MV_PRECISION_SIXTEENTH = 6,     // 1/16-pel (the precision of internal MV), shift 6 bits from 4-pel
  MV_PRECISION_INTERNAL = 2 + MV_FRACTIONAL_BITS_INTERNAL,
};
  1. 在 VVenC 编码器中Mv.cpp 文件中像素精度定义如下:
const MvPrecision Mv::m_amvrPrecision[4] = { MV_PRECISION_QUARTER, MV_PRECISION_INT, MV_PRECISION_4PEL, MV_PRECISION_HALF }; // for cu.imv=0, 1, 2 and 3
const MvPrecision Mv::m_amvrPrecAffine[3] = { MV_PRECISION_QUARTER, MV_PRECISION_SIXTEENTH, MV_PRECISION_INT }; // for cu.imv=0, 1 and 2
const MvPrecision Mv::m_amvrPrecIbc[3] = { MV_PRECISION_INT, MV_PRECISION_INT, MV_PRECISION_4PEL }; // for cu.imv=0, 1 and 2
  1. 在 VVenC 编码器中 Mv.h 文件中像素精度转换changePrecision 函数定义如下:
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);
      hor = hor >= 0 ? (hor + nOffset - 1) >> rightShift : (hor + nOffset) >> rightShift;
      ver = ver >= 0 ? (ver + nOffset - 1) >> rightShift : (ver + nOffset) >> rightShift;
    }
  }

你可能感兴趣的:(帧间预测,H266,VVC,VVenC,AMVR,运动搜索,视频编解码)