Subblock-based TMVP (SbTMVP)

Subblock-based Temporal Motion Vector Prediction (SbTMVP) proposed in VTM is similar to TMVP in HEVC. TMVP calculation method can refer to the construction of time domain candidate list in Section 1.2 of the extended Merge pattern.

SbTMVP differs from TMVP in the following two aspects:

  • TMVP predicts motion at CU level while SbTMVP predicts motion at sub-Cu level.
  • TMVP directly calculates the time domain MV using the same block of the same image, while SbTMVP performs a motion offset before calculating the same block, which comes from the MV of the adjacent block of the current CU in the airspace.

SbTMVP calculates the MV of the current CU’s child CU in two steps:

1. As shown in the figure below, check the adjacent block A1 in CU’s current airspace. If the reference image of A1 happens to be the same image as the current image, use A1’s MV as the motion offset; otherwise, the motion offset is set to (0,0).

2. Use the motion offset obtained in step 1 (add the coordinates of the current block to the motion offset) to obtain the motion information (MV and reference image index) of the child CU from the isoimage. As shown in the figure below, it is assumed that the MV of A1 is used as the motion offset, and then the motion information of the corresponding block in the isoposition image is obtained for each sub-Cu, and then the MV obtained is scaled according to the processing method of TMVP to obtain the MV of the sub-Cu.

In VTM5, the subblock-based Merge list contains both SbTMVP candidates and Affine Merge candidates. There are flag bits in the Sequence Parameter set (SPS) to indicate whether the SbTMVP pattern is used or not. If the SbTMVP pattern is allowed, SbTMVP candidates precede Affine Merge candidates in the subblock-based Merge list. The number of candidates in this list is specified in SPS and VTM5 specifies a maximum of 5 candidates.

In SbTMVP, the size of neutron CU is fixed at 8×8, and like affine Merge mode, SbTMVP mode is used only when CU width and height are greater than or equal to 8.

Adaptive motion vector resolution (AMVR)

In HEVC, when use_integer_mv_flag=0 in the slice header, MVD (the difference between CU MV and MVP) is transmitted at 1/4 brightness pixel accuracy. VVC proposed cu-level AMVR, AMVR allows THE MVD of CU to be encoded with different precision.

The optional precision is as follows:

  • Normal AMVP mode: 1/4 brightness pixel precision, full brightness pixel precision, 4 brightness pixel precision.
  • Affine AMVP mode: 1/4 brightness pixel accuracy, full brightness pixel accuracy, 1/16 brightness pixel accuracy. .

At the CU level, the accuracy of the MVD needs to be transmitted only if it has at least one non-zero component. If all MVD components (horizontal and vertical) are 0, MVD defaults to 1/4 brightness pixel accuracy.

When a CU has at least one non-zero MVD component, there is a flag bit indicating whether the CU’s MVD uses 1/4 brightness pixel precision. If this flag bit is 0, it means that the USE of 1/4 brightness pixel precision does not need to pass other flag bits. Otherwise, a second flag bit is required for CU in Normal AMVP mode to indicate whether full brightness pixel precision or 4x brightness pixel precision is used. CU in Affine AMVP mode requires a second flag bit to indicate whether full brightness pixel precision or 1/16 brightness pixel precision is used. To ensure that the reconstructed MV has the same accuracy, the MVP is rounded to the same accuracy as the MVD. MVP is rounded to 0 (i.e., minus MVP goes to infinity, plus MVP goes to minus infinity).

The pixel precision of the two modes in VTM5 is defined as follows:

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
Copy the code

The precision conversion code is as follows:

  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);
  }
Copy the code

reference

JVET-N1002

JVET-M0246

JVET-M0165

If you are interested, please pay attention to wechat public account Video Coding