Skip to content
Snippets Groups Projects
InterPrediction.cpp 46.2 KiB
Newer Older
  • Learn to ignore specific revisions
  •   return (dist >= m_bioDistThres);
    }
    
    
    void InterPrediction::xAddBIOAvg4(const Pel* src0, int src0Stride, const Pel* src1, int src1Stride, Pel *dst, int dstStride, const Pel *gradX0, const Pel *gradX1, const Pel *gradY0, const Pel*gradY1, int gradStride, int width, int height, int tmpx, int tmpy, int shift, int offset, const ClpRng& clpRng)
    {
      g_pelBufOP.addBIOAvg4(src0, src0Stride, src1, src1Stride, dst, dstStride, gradX0, gradX1, gradY0, gradY1, gradStride, width, height, tmpx, tmpy, shift, offset, clpRng);
    }
    
    void InterPrediction::xBioGradFilter(Pel* pSrc, int srcStride, int width, int height, int gradStride, Pel* gradX, Pel* gradY)
    {
      g_pelBufOP.bioGradFilter(pSrc, srcStride, width, height, gradStride, gradX, gradY);
    }
    
    void InterPrediction::xCalcBIOPar(const Pel* srcY0Temp, const Pel* srcY1Temp, const Pel* gradX0, const Pel* gradX1, const Pel* gradY0, const Pel* gradY1, int* dotProductTemp1, int* dotProductTemp2, int* dotProductTemp3, int* dotProductTemp5, int* dotProductTemp6, const int src0Stride, const int src1Stride, const int gradStride, const int widthG, const int heightG)
    {
      g_pelBufOP.calcBIOPar(srcY0Temp, srcY1Temp, gradX0, gradX1, gradY0, gradY1, dotProductTemp1, dotProductTemp2, dotProductTemp3, dotProductTemp5, dotProductTemp6, src0Stride, src1Stride, gradStride, widthG, heightG);
    }
    
    void InterPrediction::xCalcBlkGradient(int sx, int sy, int    *arraysGx2, int     *arraysGxGy, int     *arraysGxdI, int     *arraysGy2, int     *arraysGydI, int     &sGx2, int     &sGy2, int     &sGxGy, int     &sGxdI, int     &sGydI, int width, int height, int unitSize)
    {
      g_pelBufOP.calcBlkGradient(sx, sy, arraysGx2, arraysGxGy, arraysGxdI, arraysGy2, arraysGydI, sGx2, sGy2, sGxGy, sGxdI, sGydI, width, height, unitSize);
    }
    
    void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitBuf& pcYuvSrc0, const CPelUnitBuf& pcYuvSrc1, PelUnitBuf& pcYuvDst, const BitDepths& clipBitDepths, const ClpRngs& clpRngs, const bool& bioApplied )
    
    {
      const int iRefIdx0 = pu.refIdx[0];
      const int iRefIdx1 = pu.refIdx[1];
    
      if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
      {
    
        if( pu.cu->GBiIdx != GBI_DEFAULT )
        {
    
          CHECK(bioApplied, "GBi is disallowed with BIO");
    
          pcYuvDst.addWeightedAvg(pcYuvSrc0, pcYuvSrc1, clpRngs, pu.cu->GBiIdx);
          return;
        }
    
          const int  src0Stride = pu.lwidth() + 2 * BIO_EXTEND_SIZE + 2;
          const int  src1Stride = pu.lwidth() + 2 * BIO_EXTEND_SIZE + 2;
    
          const Pel* pSrcY0 = m_filteredBlockTmp[2][COMPONENT_Y] + 2 * src0Stride + 2;
          const Pel* pSrcY1 = m_filteredBlockTmp[3][COMPONENT_Y] + 2 * src1Stride + 2;
    
          bool bioEnabled = xCalcBiPredSubBlkDist(pu, pSrcY0, src0Stride, pSrcY1, src1Stride, clipBitDepths);
          if (bioEnabled)
          {
            applyBiOptFlow(pu, pcYuvSrc0, pcYuvSrc1, iRefIdx0, iRefIdx1, pcYuvDst, clipBitDepths);
          }
          else
          {
            pcYuvDst.bufs[0].addAvg(CPelBuf(pSrcY0, src0Stride, pu.lumaSize()), CPelBuf(pSrcY1, src1Stride, pu.lumaSize()), clpRngs.comp[0]);
          }
        }
    
        pcYuvDst.addAvg(pcYuvSrc0, pcYuvSrc1, clpRngs, bioApplied);
    
        if( pu.cu->triangle )
        {
          pcYuvDst.copyFrom( pcYuvSrc0 );
        }
        else
    
        pcYuvDst.copyClip( pcYuvSrc0, clpRngs );
      }
      else if( iRefIdx0 < 0 && iRefIdx1 >= 0 )
      {
    
        if( pu.cu->triangle )
        {
          pcYuvDst.copyFrom( pcYuvSrc1 );
        }
        else
    
    void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBuf, const RefPicList &eRefPicList 
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      , const bool luma, const bool chroma
    
    Yu Han's avatar
    Yu Han committed
      // dual tree handling for IBC as the only ref
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      if (!luma || !chroma)
      {
        if (!luma && chroma)
        {
          xChromaMC(pu, predBuf);
          return;
        }
        else // (luma && !chroma)
        {
          xPredInterUni(pu, eRefPicList, predBuf, false
            , false
            , luma, chroma);
          return;
        }
      }
      // else, go with regular MC below
    
            CodingStructure &cs = *pu.cs;
      const PPS &pps            = *cs.pps;
      const SliceType sliceType =  cs.slice->getSliceType();
    
      if( eRefPicList != REF_PIC_LIST_X )
      {
        if( ( ( sliceType == P_SLICE && pps.getUseWP() ) || ( sliceType == B_SLICE && pps.getWPBiPred() ) ) )
        {
    
          xPredInterUni         ( pu,          eRefPicList, predBuf, true 
            , false
            , true, true
          );
    
          xWeightedPredictionUni( pu, predBuf, eRefPicList, predBuf, -1, m_maxCompIDToPred );
        }
        else
        {
    
          xPredInterUni( pu, eRefPicList, predBuf, false 
            , false
            , true, true
          );
    
    Yu Han's avatar
    Yu Han committed
        if (pu.mergeType != MRG_TYPE_DEFAULT_N && pu.mergeType != MRG_TYPE_IBC)
    
        {
          xSubPuMC( pu, predBuf, eRefPicList );
        }
        else if( xCheckIdenticalMotion( pu ) )
        {
    
          xPredInterUni( pu, REF_PIC_LIST_0, predBuf, false 
            , false
            , true, true
          );
    
    void InterPrediction::motionCompensation( CodingUnit &cu, const RefPicList &eRefPicList 
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      , const bool luma, const bool chroma
    
    {
      for( auto &pu : CU::traversePUs( cu ) )
      {
        PelUnitBuf predBuf = cu.cs->getPredBuf( pu );
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
        motionCompensation( pu, predBuf, eRefPicList 
          , luma, chroma
        );
    
    void InterPrediction::motionCompensation( PredictionUnit &pu, const RefPicList &eRefPicList /*= REF_PIC_LIST_X*/ 
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      , const bool luma, const bool chroma
    
      motionCompensation( pu, predBuf, eRefPicList 
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
        , luma, chroma
    
    int InterPrediction::rightShiftMSB(int numer, int denom)
    {
      int     d;
      int msbIdx = 0;
      for (msbIdx = 0; msbIdx<32; msbIdx++)
      {
        if (denom < ((int)1 << msbIdx))
        {
          break;
        }
      }
    
      int shiftIdx = msbIdx - 1;
      d = (numer >> shiftIdx);
    
    rlliao's avatar
    rlliao committed
    void InterPrediction::motionCompensation4Triangle( CodingUnit &cu, MergeCtx &triangleMrgCtx, const bool splitDir, const uint8_t candIdx0, const uint8_t candIdx1 )
    
    {
      for( auto &pu : CU::traversePUs( cu ) )
      {
        const UnitArea localUnitArea( cu.cs->area.chromaFormat, Area( 0, 0, pu.lwidth(), pu.lheight() ) );
    
    rlliao's avatar
    rlliao committed
        PelUnitBuf tmpTriangleBuf = m_triangleBuf.getBuf( localUnitArea );
    
        PelUnitBuf predBuf        = cu.cs->getPredBuf( pu );
         
    
    rlliao's avatar
    rlliao committed
        triangleMrgCtx.setMergeInfo( pu, candIdx0 );
    
        PU::spanMotionInfo( pu );
        motionCompensation( pu, tmpTriangleBuf );
       
    
    rlliao's avatar
    rlliao committed
        triangleMrgCtx.setMergeInfo( pu, candIdx1 );
    
        PU::spanMotionInfo( pu );
        motionCompensation( pu, predBuf );
    
    
    rlliao's avatar
    rlliao committed
        weightedTriangleBlk( pu, PU::getTriangleWeights(pu, triangleMrgCtx, candIdx0, candIdx1), splitDir, MAX_NUM_CHANNEL_TYPE, predBuf, tmpTriangleBuf, predBuf );
    
    rlliao's avatar
    rlliao committed
    void InterPrediction::weightedTriangleBlk( PredictionUnit &pu, bool weights, const bool splitDir, int32_t channel, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 )
    
    rlliao's avatar
    rlliao committed
      if( channel == CHANNEL_TYPE_LUMA )
    
    rlliao's avatar
    rlliao committed
        xWeightedTriangleBlk( pu, pu.lumaSize().width, pu.lumaSize().height, COMPONENT_Y, splitDir, weights, predDst, predSrc0, predSrc1 );
    
    rlliao's avatar
    rlliao committed
      else if( channel == CHANNEL_TYPE_CHROMA )
      {
        xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cb, splitDir, weights, predDst, predSrc0, predSrc1 );
        xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cr, splitDir, weights, predDst, predSrc0, predSrc1 );
      }
      else
      {
        xWeightedTriangleBlk( pu, pu.lumaSize().width,   pu.lumaSize().height,   COMPONENT_Y,  splitDir, weights, predDst, predSrc0, predSrc1 );
        xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cb, splitDir, weights, predDst, predSrc0, predSrc1 );
        xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cr, splitDir, weights, predDst, predSrc0, predSrc1 );
      }
    }
    
    rlliao's avatar
    rlliao committed
    void InterPrediction::xWeightedTriangleBlk( const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const bool splitDir, const bool weights, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 )
    {
      Pel*    dst        = predDst .get(compIdx).buf;
      Pel*    src0       = predSrc0.get(compIdx).buf;
      Pel*    src1       = predSrc1.get(compIdx).buf;
      int32_t strideDst  = predDst .get(compIdx).stride  - width;
      int32_t strideSrc0 = predSrc0.get(compIdx).stride  - width;
      int32_t strideSrc1 = predSrc1.get(compIdx).stride  - width;
    
      const char    log2WeightBase    = 3;
      const ClpRng  clipRng           = pu.cu->slice->clpRngs().comp[compIdx];
      const int32_t clipbd            = clipRng.bd;
      const int32_t shiftDefault      = std::max<int>(2, (IF_INTERNAL_PREC - clipbd));
      const int32_t offsetDefault     = (1<<(shiftDefault-1)) + IF_INTERNAL_OFFS;
      const int32_t shiftWeighted     = std::max<int>(2, (IF_INTERNAL_PREC - clipbd)) + log2WeightBase;
      const int32_t offsetWeighted    = (1 << (shiftWeighted - 1)) + (IF_INTERNAL_OFFS << log2WeightBase);
                                      
      const int32_t ratioWH           = (width > height) ? (width / height) : 1;
      const int32_t ratioHW           = (width > height) ? 1 : (height / width);
      const Pel*    pelWeighted       = (compIdx == COMPONENT_Y) ? g_trianglePelWeightedLuma[splitDir][weights] : g_trianglePelWeightedChroma[predDst.chromaFormat == CHROMA_444 ? 0 : 1][splitDir][weights];
      const int32_t weightedLength    = (compIdx == COMPONENT_Y) ? g_triangleWeightLengthLuma[weights] : g_triangleWeightLengthChroma[predDst.chromaFormat == CHROMA_444 ? 0 : 1][weights];
            int32_t weightedStartPos  = ( splitDir == 0 ) ? ( 0 - (weightedLength >> 1) * ratioWH ) : ( width - ((weightedLength + 1) >> 1) * ratioWH );
            int32_t weightedEndPos    = weightedStartPos + weightedLength * ratioWH - 1;
            int32_t weightedPosoffset =( splitDir == 0 ) ? ratioWH : -ratioWH;
      
      const Pel*    tmpPelWeighted;
            int32_t x, y, tmpX, tmpY, tmpWeightedStart, tmpWeightedEnd;
      
      for( y = 0; y < height; y+= ratioHW )
    
    rlliao's avatar
    rlliao committed
        for( tmpY = ratioHW; tmpY > 0; tmpY-- )
    
    rlliao's avatar
    rlliao committed
          for( x = 0; x < weightedStartPos; x++ )
    
    rlliao's avatar
    rlliao committed
            *dst++ = ClipPel( rightShift( (splitDir == 0 ? *src1 : *src0) + offsetDefault, shiftDefault), clipRng );
            src0++;
            src1++;
    
    rlliao's avatar
    rlliao committed
          tmpWeightedStart = std::max((int32_t)0, weightedStartPos);
          tmpWeightedEnd   = std::min(weightedEndPos, (int32_t)(width - 1));
          tmpPelWeighted   = pelWeighted;
          if( weightedStartPos < 0 )
    
    rlliao's avatar
    rlliao committed
            tmpPelWeighted += abs(weightedStartPos) / ratioWH;
    
    rlliao's avatar
    rlliao committed
          for( x = tmpWeightedStart; x <= tmpWeightedEnd; x+= ratioWH )
    
    rlliao's avatar
    rlliao committed
            for( tmpX = ratioWH; tmpX > 0; tmpX-- )
    
    rlliao's avatar
    rlliao committed
              *dst++ = ClipPel( rightShift( ((*tmpPelWeighted)*(*src0++) + ((8 - (*tmpPelWeighted)) * (*src1++)) + offsetWeighted), shiftWeighted ), clipRng );
    
    rlliao's avatar
    rlliao committed
            tmpPelWeighted++;
    
    rlliao's avatar
    rlliao committed
          for( x = weightedEndPos + 1; x < width; x++ )
    
    rlliao's avatar
    rlliao committed
            *dst++ = ClipPel( rightShift( (splitDir == 0 ? *src0 : *src1) + offsetDefault, shiftDefault ), clipRng );
            src0++;
            src1++;
    
    rlliao's avatar
    rlliao committed
    
          dst  += strideDst;
          src0 += strideSrc0;
          src1 += strideSrc1;
    
    rlliao's avatar
    rlliao committed
        weightedStartPos += weightedPosoffset;
        weightedEndPos   += weightedPosoffset;
    
    #if JVET_J0090_MEMORY_BANDWITH_MEASURE
    void InterPrediction::cacheAssign( CacheModel *cache )
    {
      m_cacheModel = cache;
      m_if.cacheAssign( cache );
      m_if.initInterpolationFilter( !cache->isCacheEnable() );
    }
    #endif
    
    //! \}