Combined Inter and Intra prediction (CIIP) : in HEVC, a CU can use either intra-frame prediction or inter-frame prediction, but only one or the other. The CIIP technology in VVC, as its name suggests, can use both intra-frame prediction and inter-frame prediction.

CIIP uses both intra-frame prediction and inter-frame prediction to get two prediction blocks for a CU, and the final prediction block is weighted by the two prediction blocks.

In VTM5, when CU is encoded in merge mode, and CU contains at least 64 brightness pixels (W*H≧64), and W<128,H<128, a flag bit is required to indicate whether the CU is in CIIP mode.

In VTM5, when CU uses CIIP mode, inter prediction block P_inter is first obtained by inter-frame merge mode, then intra-frame Planar mode is applied to P_intra, and finally the two blocks are weighted to get the final prediction block.

The weight is determined by the modes of adjacent blocks above and to the left of the current CU, as shown in the figure below. The weight calculation process is as follows:

  1. If the adjacent block above is available and uses the intra-frame encoding mode, isIntraTop =1, otherwise isIntraTop =0;
  2. IsIntraLeft =1 if the adjacent block to the left is available and it uses intra-frame encoding mode, otherwise isIntraLeft =0;
  3. If (isIntraTop + isIntraLeft) = 2, wt=3;
  4. If (isIntraTop + isIntraLeft) = 1, wt=2;
  5. Otherwise the wt = 1.

void IntraPrediction::geneWeightedPred(const ComponentID compId, PelBuf &pred, const PredictionUnit &pu, Pel *srcBuf)
{
  const int            width = pred.width;
  const int            height = pred.height;
  const int            srcStride = width;
  const int            dstStride = pred.stride;

  Pel*                 dstBuf = pred.buf;
  int wIntra, wMerge;

  const Position posBL = pu.Y().bottomLeft(a);const Position posTR = pu.Y().topRight(a);const PredictionUnit *neigh0 = pu.cs->getPURestricted(posBL.offset(- 1.0), pu, CHANNEL_TYPE_LUMA);
  const PredictionUnit *neigh1 = pu.cs->getPURestricted(posTR.offset(0.- 1), pu, CHANNEL_TYPE_LUMA);
  bool isNeigh0Intra = neigh0 && (CU::isIntra(*neigh0->cu));
  bool isNeigh1Intra = neigh1 && (CU::isIntra(*neigh1->cu));
  / /! < Weight calculation of inter-frame and intra-frame weights
  if (isNeigh0Intra && isNeigh1Intra)
  {
    wIntra = 3; wMerge = 1;
  }
  else
  {
    if(! isNeigh0Intra && ! isNeigh1Intra) { wIntra =1; wMerge = 3;
    }
    else
    {
      wIntra = 2; wMerge = 2; }}for (int y = 0; y < height; y++)
  {
    for (int x = 0; x < width; x++)
    {/ /! < Inter-frame and intra-frame weights obtain the final predicted value
      dstBuf[y*dstStride + x] = (wMerge * dstBuf[y*dstStride + x] + wIntra * srcBuf[y*srcStride + x] + 2) > >2; }}}Copy the code

reference

JVET-N1002

JVET-N0302

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