Skip to content
Snippets Groups Projects
IntraSearch.cpp 483 KiB
Newer Older
  • Learn to ignore specific revisions
  •   else
      {
        if ( compID == COMPONENT_Cb )
    
          m_CABACEstimator->cbf_comp( cs, TU::getCbf( currTU, compID ), currTU.blocks[ compID ], currTU.depth, false );
    
        {
          const bool cbCbf    = TU::getCbf( currTU, COMPONENT_Cb );
          const bool crCbf    = TU::getCbf( currTU, compID );
          const int  cbfMask  = ( cbCbf ? 2 : 0 ) + ( crCbf ? 1 : 0 );
          m_CABACEstimator->cbf_comp( cs, crCbf, currTU.blocks[ compID ], currTU.depth, cbCbf );
          m_CABACEstimator->joint_cb_cr( currTU, cbfMask );
        }
    
      if( !currTU.jointCbCr && TU::getCbf( currTU, compID ) )
    
      {
        m_CABACEstimator->residual_coding( currTU, compID );
      }
    
      uint64_t fracBits = m_CABACEstimator->getEstFracBits();
      return fracBits;
    }
    
    #if JVET_W0103_INTRA_MTS
    
    void IntraSearch::xSelectAMTForFullRD(TransformUnit &tu
    #if JVET_AG0136_INTRA_TMP_LIC
                                          , InterPrediction* pcInterPred
    #endif
    )
    
    {
      if (!tu.blocks[COMPONENT_Y].valid())
      {
        return;
      }
    
      if (!tu.cu->mtsFlag)
      {
        return;
      }
    
      CodingStructure &cs = *tu.cs;
      m_pcRdCost->setChromaFormat(cs.sps->getChromaFormatIdc());
    
      const CompArea      &area = tu.blocks[COMPONENT_Y];
    
      const ChannelType    chType = toChannelType(COMPONENT_Y);
    
    
      PelBuf         piOrg = cs.getOrgBuf(area);
      PelBuf         piPred = cs.getPredBuf(area);
      PelBuf         piResi = cs.getResiBuf(area);
    
    
    #if JVET_AC0115_INTRA_TMP_DIMD_MTS_LFNST
      PredictionUnit& pu = *cs.getPU(area.pos(), chType);
    #else
      const PredictionUnit& pu = *cs.getPU(area.pos(), chType);
    #endif
    
    
      //===== init availability pattern =====
    
      PelBuf sharedPredTS(m_pSharedPredTransformSkip[COMPONENT_Y], area);
      initIntraPatternChType(*tu.cu, area);
    
      //===== get prediction signal =====
    
    #if JVET_V0130_INTRA_TMP && JVET_AC0115_INTRA_TMP_DIMD_MTS_LFNST
      if (PU::isTmp(pu, chType))
      {
        int foundCandiNum;
    #if JVET_W0069_TMP_BOUNDARY
        RefTemplateType tempType = getRefTemplateType(*(tu.cu), tu.cu->blocks[COMPONENT_Y]);
        if (tempType != NO_TEMPLATE)
        {
    
    #if JVET_AD0086_ENHANCED_INTRA_TMP
    
          if (pu.cu->tmpIsSubPel)
          {
            xPadForInterpolation(tu.cu);
          }
    
          generateTMPrediction(piPred.buf, piPred.stride, foundCandiNum, pu
    #if JVET_AG0136_INTRA_TMP_LIC
                               , (tu.cu)->tmpLicFlag
                               , !(tu.cu)->tmpFlmFlag
    #endif
                               );
    #if JVET_AG0136_INTRA_TMP_LIC
          if ((tu.cu)->tmpLicFlag)
          {
            if (!(tu.cu)->tmpFusionFlag)
            {
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
              PelBuf bufDumb;
              pcInterPred->LicItmp(pu, bufDumb, false);
              const auto& arrayLicParams = pcInterPred->getArrayLicParams();
    #else
    
              const auto& arrayLicParams = getMemLicParams((tu.cu)->ibcLicIdx, (tu.cu)->tmpIdx);
    
              if ((tu.cu)->ibcLicIdx == IBC_LIC_IDX_M)
              {
                piPred.linearTransforms(arrayLicParams[1], arrayLicParams[0], arrayLicParams[2], arrayLicParams[4], arrayLicParams[3], arrayLicParams[5], arrayLicParams[6], true, (tu.cu)->cs->slice->clpRng(COMPONENT_Y));
              }
              else
              {
                piPred.linearTransform(arrayLicParams[1], arrayLicParams[0], arrayLicParams[2], true, (tu.cu)->cs->slice->clpRng(COMPONENT_Y));
              }
            }
          }
    #endif
    
          xGenerateTmpFlmPred(piPred, pu.lwidth(), pu.lheight(), tempType, tu.cu);
    
          xTMPFusionApplyModel(piPred, pu.lwidth(), pu.lheight(), tempType, tu.cu
    #if JVET_AG0136_INTRA_TMP_LIC
                               , (tu.cu)->tmpLicFlag
    #endif
                               );
    
          generateTMPrediction(piPred.buf, piPred.stride, pu.Y(), foundCandiNum, tu.cu);
    #else
          getTargetTemplate(tu.cu, pu.lwidth(), pu.lheight(), tempType);
          candidateSearchIntra(tu.cu, pu.lwidth(), pu.lheight(), tempType);
          generateTMPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum);
    #endif
    #if JVET_AB0061_ITMP_BV_FOR_IBC
          pu.interDir = 1;              // use list 0 for IBC mode
          pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF;   // last idx in the list
    
    #if JVET_AD0086_ENHANCED_INTRA_TMP
          CodingUnit *cu         = pu.cu;
          int         pX, pY;
    
    #if JVET_AG0136_INTRA_TMP_LIC
          const int tmpIdx = cu->tmpFusionFlag ? (cu->tmpLicFlag ? m_tmpFusionInfoUseMR : m_tmpFusionInfo)[cu->tmpIdx].tmpFusionIdx : cu->tmpIdx;
          pX = (cu->tmpLicFlag ? m_tmpXdispUseMR : m_tmpXdisp)[tmpIdx];
          pY = (cu->tmpLicFlag ? m_tmpYdispUseMR : m_tmpYdisp)[tmpIdx];
    #else
    
          int tmpIdx = cu->tmpFusionFlag ? m_tmpFusionInfo[cu->tmpIdx].tmpFusionIdx : cu->tmpIdx;
          pX = m_tmpXdisp[tmpIdx];
          pY = m_tmpYdisp[tmpIdx];
    
    #if JVET_AF0079_STORING_INTRATMP
    
    #if JVET_AG0136_INTRA_TMP_LIC
          if (cu->tmpFusionFlag && (((cu->tmpLicFlag ? m_tmpFusionInfoUseMR : m_tmpFusionInfo)[cu->tmpIdx].tmpFusionNumber < 1) || (cu->tmpLicFlag ? m_tmpFusionInfoUseMR : m_tmpFusionInfo)[cu->tmpIdx].bFilter))
    #else
    
          if (cu->tmpFusionFlag
              && ((m_tmpFusionInfo[cu->tmpIdx].tmpFusionNumber < 1) || m_tmpFusionInfo[cu->tmpIdx].bFilter))
    
          {
            pu.mv[0].set(pX << MV_FRACTIONAL_BITS_INTERNAL, pY << MV_FRACTIONAL_BITS_INTERNAL);
            pu.bv.set(pX, pY);
          }
    #else
    
          pu.mv->set(pX << MV_FRACTIONAL_BITS_INTERNAL, pY << MV_FRACTIONAL_BITS_INTERNAL);
          pu.bv.set(pX, pY);
    
          pu.mv->set(m_tempLibFast.getX() << MV_FRACTIONAL_BITS_INTERNAL, m_tempLibFast.getY() << MV_FRACTIONAL_BITS_INTERNAL);
          pu.bv.set(m_tempLibFast.getX(), m_tempLibFast.getY());
    
    #endif
        }
        else
        {
          foundCandiNum = 1;
    #if JVET_AC0115_INTRA_TMP_DIMD_MTS_LFNST 
          generateTmDcPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), 1 << (tu.cu->cs->sps->getBitDepth(CHANNEL_TYPE_LUMA) - 1), pu.cu);
    #else
          generateTmDcPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), 1 << (tu.cu->cs->sps->getBitDepth(CHANNEL_TYPE_LUMA) - 1));
    #endif 
    
    #if JVET_AB0061_ITMP_BV_FOR_IBC
          pu.interDir = 1;             // use list 0 for IBC mode
          pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF;   // last idx in the list
          pu.mv->set(0, 0);
          pu.bv.set(0, 0);
    #endif
        }
    #else
        getTargetTemplate(tu.cu, pu.lwidth(), pu.lheight());
        candidateSearchIntra(tu.cu, pu.lwidth(), pu.lheight());
        generateTMPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum);
    #endif
        CHECK(foundCandiNum < 1, "");
      
      }
      else if (PU::isMIP(pu, chType))
    
      {
        initIntraMip(pu, area);
    
    #if JVET_AH0076_OBIC
        predIntraMip(COMPONENT_Y, piPred, pu, true);
    #else
    
        predIntraMip(COMPONENT_Y, piPred, pu);
    
    #if JVET_AG0058_EIP
      else if (PU::isEIP(pu, chType))
      {
        const CPelBuf eipSaveBuf(pu.cu->eipMerge ? m_eipMergePredBuf[pu.intraDir[0]] : m_eipPredBuf[pu.intraDir[0]], pu.Y());
        piPred.copyFrom(eipSaveBuf);
      }
    
    #endif
    #if JVET_AH0076_OBIC
      else if (pu.cu->dimd && chType == CHANNEL_TYPE_LUMA && pu.cu->ispMode == NOT_INTRA_SUBPARTITIONS)
      {
        const CPelBuf dimdSaveBuf(pu.cu->obicFlag ? m_obicPredBuf : m_dimdPredBuf, pu.Y());
        piPred.copyFrom(dimdSaveBuf);
      }
    
    fan wang's avatar
    fan wang committed
    #if JVET_AB0155_SGPM
        if (pu.cu->sgpm)
        {
          CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
          PelBuf predBuf(m_sgpmPredBuf[pu.cu->sgpmIdx], tmpArea);
          piPred.copyFrom(predBuf);
        }
        else
    #endif
    
      if (PU::isMIP(pu, chType))
      {
        initIntraMip(pu, area);
        predIntraMip(COMPONENT_Y, piPred, pu);
      }
    
    #if JVET_AG0058_EIP
      else if (PU::isEIP(pu, chType))
      {
        const CPelBuf eipSaveBuf(pu.cu->eipMerge ? m_eipMergePredBuf[pu.intraDir[0]] : m_eipPredBuf[pu.intraDir[0]], pu.Y());
        piPred.copyFrom(eipSaveBuf);
      }
    #endif
    
      else
      {
    #if JVET_AB0155_SGPM
        if (pu.cu->sgpm)
        {
          CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
          PelBuf predBuf(m_sgpmPredBuf[pu.cu->sgpmIdx], tmpArea);
          piPred.copyFrom(predBuf);
        }
        else
    #endif
        {
          predIntraAng(COMPONENT_Y, piPred, pu);
        }
      }
    
    #endif
    
      // save prediction
      sharedPredTS.copyFrom(piPred);
    
      const Slice           &slice = *cs.slice;
      //===== get residual signal =====
      piResi.copyFrom(piOrg);
      if (slice.getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
      {
        piResi.rspSignal(m_pcReshape->getFwdLUT());
        piResi.subtract(piPred);
      }
      else
      {
        piResi.subtract(piPred);
      }
      // do transform and calculate Coeff AbsSum for all MTS candidates
    
    #if JVET_Y0142_ADAPT_INTRA_MTS
      int nCands = MTS_NCANDS[2];
      if (m_coeffAbsSumDCT2 >= 0 && m_coeffAbsSumDCT2 <= MTS_TH_COEFF[0])
      {
        nCands = MTS_NCANDS[0];
      }
      else if(m_coeffAbsSumDCT2 > MTS_TH_COEFF[0] && m_coeffAbsSumDCT2 <= MTS_TH_COEFF[1])
      {
        nCands = MTS_NCANDS[1];
      }
      std::vector<std::pair<int, uint64_t>> coeffAbsSum(nCands);
      for (int i = 0; i < nCands; i++)
    #else
      std::vector<std::pair<int, uint64_t>> coeffAbsSum(4);
    
      for (int i = 0; i < 4; i++)
    
      {
        tu.mtsIdx[0] = i + MTS_DST7_DST7;
        uint64_t AbsSum = m_pcTrQuant->transformNxN(tu);
    
        coeffAbsSum[i] = { i, AbsSum };
    
      std::stable_sort(coeffAbsSum.begin(), coeffAbsSum.end(), [](const std::pair<int, uint64_t> & l, const std::pair<int, uint64_t> & r) {return l.second < r.second; });
    #if JVET_Y0142_ADAPT_INTRA_MTS
      for (int i = 0; i < nCands; i++)
    #else
    
      for (int i = 0; i < 4; i++)
    
        m_testAMTForFullRD[i] = coeffAbsSum[i].first;
    
    #if JVET_Y0142_ADAPT_INTRA_MTS
      m_numCandAMTForFullRD = nCands;
    #else
    
      m_numCandAMTForFullRD = 4;
    
    #endif
    #if !JVET_Y0142_ADAPT_INTRA_MTS
    
      if (m_pcEncCfg->getUseFastLFNST())
      {
        double skipThreshold = 1.0 + 1.0 / sqrt((double)(area.width*area.height));
        skipThreshold = std::max(skipThreshold, 1.03);
        for (int i = 1; i < m_numCandAMTForFullRD; i++)
        {
    
          if (coeffAbsSum[i].second > skipThreshold * coeffAbsSum[0].second)
    
          {
            m_numCandAMTForFullRD = i;
            break;
          }
        }
      }
    
    void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &compID, Distortion& ruiDist, const int &default0Save1Load2, uint32_t* numSig, std::vector<TrMode>* trModes, const bool loadTr
    #if JVET_AG0136_INTRA_TMP_LIC
                                          , InterPrediction* pcInterPred
    #endif
    )
    
    {
      if (!tu.blocks[compID].valid())
      {
        return;
      }
    
      CodingStructure &cs                       = *tu.cs;
    
      m_pcRdCost->setChromaFormat(cs.sps->getChromaFormatIdc());
    
    
      const CompArea      &area                 = tu.blocks[compID];
      const SPS           &sps                  = *cs.sps;
    
    #if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
    
    Vadim Seregin's avatar
    Vadim Seregin committed
      const PPS           &pps                  = *cs.pps;
    #endif
    
    
      const ChannelType    chType               = toChannelType(compID);
      const int            bitDepth             = sps.getBitDepth(chType);
    
      PelBuf         piOrg                      = cs.getOrgBuf    (area);
      PelBuf         piPred                     = cs.getPredBuf   (area);
      PelBuf         piResi                     = cs.getResiBuf   (area);
      PelBuf         piReco                     = cs.getRecoBuf   (area);
    
    
    #if JVET_AB0061_ITMP_BV_FOR_IBC
      PredictionUnit &pu = *cs.getPU(area.pos(), chType);
    #else
    
      const PredictionUnit &pu                  = *cs.getPU(area.pos(), chType);
    
      const uint32_t           uiChFinalMode        = PU::getFinalIntraMode(pu, chType);
    
      //===== init availability pattern =====
    
      CHECK( tu.jointCbCr && compID == COMPONENT_Cr, "wrong combination of compID and jointCbCr" );
    
      bool jointCbCr = tu.jointCbCr && compID == COMPONENT_Cb;
    
        PelBuf sharedPredTS( m_pSharedPredTransformSkip[compID], area );
        if( default0Save1Load2 != 2 )
    
          bool predRegDiffFromTB = CU::isPredRegDiffFromTB(*tu.cu, compID);
          bool firstTBInPredReg = CU::isFirstTBInPredReg(*tu.cu, compID, area);
          CompArea areaPredReg(COMPONENT_Y, tu.chromaFormat, area);
          if (tu.cu->ispMode && isLuma(compID))
    
              if (firstTBInPredReg)
              {
                CU::adjustPredArea(areaPredReg);
                initIntraPatternChTypeISP(*tu.cu, areaPredReg, piReco);
              }
    
              initIntraPatternChTypeISP(*tu.cu, area, piReco);
    
    
          //===== get prediction signal =====
          if(compID != COMPONENT_Y && !tu.cu->bdpcmModeChroma && PU::isLMCMode(uiChFinalMode))
    
            xGetLumaRecPixels( pu, area );
            predIntraChromaLM( compID, piPred, pu, area, uiChFinalMode );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if JVET_V0130_INTRA_TMP
            if( PU::isTmp( pu, chType ) )
            {
              int foundCandiNum;
    
    #if JVET_W0069_TMP_BOUNDARY
    
              RefTemplateType tempType = getRefTemplateType( *(tu.cu), tu.cu->blocks[COMPONENT_Y] );
              if( tempType != NO_TEMPLATE )
    
    Vadim Seregin's avatar
    Vadim Seregin committed
              {
    
    #if JVET_AD0086_ENHANCED_INTRA_TMP
    
                if (pu.cu->tmpIsSubPel)
                {
                  xPadForInterpolation(tu.cu);
                }
    
                generateTMPrediction(piPred.buf, piPred.stride, placeHolder, pu
    #if JVET_AG0136_INTRA_TMP_LIC
                                     , (tu.cu)->tmpLicFlag
                                     , !(tu.cu)->tmpFlmFlag
    #endif
                                     );
    #if JVET_AG0136_INTRA_TMP_LIC
                if ((tu.cu)->tmpLicFlag)
                {
                  if (!(tu.cu)->tmpFusionFlag)
                  {
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
                    PelBuf bufDumb;
                    pcInterPred->LicItmp(pu, bufDumb, false);
                    const auto& arrayLicParams = pcInterPred->getArrayLicParams();
    #else
    
                    const auto& arrayLicParams = getMemLicParams((tu.cu)->ibcLicIdx, (tu.cu)->tmpIdx);
    
                    if ((tu.cu)->ibcLicIdx == IBC_LIC_IDX_M)
                    {
                      piPred.linearTransforms(arrayLicParams[1], arrayLicParams[0], arrayLicParams[2], arrayLicParams[4], arrayLicParams[3], arrayLicParams[5], arrayLicParams[6], true, (tu.cu)->cs->slice->clpRng(COMPONENT_Y));
                    }
                    else
                    {
                      piPred.linearTransform(arrayLicParams[1], arrayLicParams[0], arrayLicParams[2], true, (tu.cu)->cs->slice->clpRng(COMPONENT_Y));
                    }
                  }
                }
    #endif
    
                xGenerateTmpFlmPred(piPred, pu.lwidth(), pu.lheight(), tempType, pu.cu);
    
                xTMPFusionApplyModel(piPred, pu.lwidth(), pu.lheight(), tempType, pu.cu
    #if JVET_AG0136_INTRA_TMP_LIC
                                     , (tu.cu)->tmpLicFlag
    #endif
                                     );
    
                foundCandiNum = 1;
    #elif TMP_FAST_ENC
    
                generateTMPrediction(piPred.buf, piPred.stride, pu.Y(), foundCandiNum, tu.cu);
    #else
    
                getTargetTemplate( tu.cu, pu.lwidth(), pu.lheight(), tempType );
                candidateSearchIntra( tu.cu, pu.lwidth(), pu.lheight(), tempType );
                generateTMPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
    #if JVET_AB0061_ITMP_BV_FOR_IBC
                pu.interDir               = 1;             // use list 0 for IBC mode
                pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF;   // last idx in the list
    
    #if JVET_AD0086_ENHANCED_INTRA_TMP
                CodingUnit *cu = pu.cu;
                int pX, pY;
    
    #if JVET_AG0136_INTRA_TMP_LIC
                const int tmpIdx = cu->tmpFusionFlag ? ((tu.cu)->tmpLicFlag ? m_tmpFusionInfoUseMR : m_tmpFusionInfo)[cu->tmpIdx].tmpFusionIdx : cu->tmpIdx;
                pX = (cu->tmpLicFlag ? m_tmpXdispUseMR : m_tmpXdisp)[tmpIdx];
                pY = (cu->tmpLicFlag ? m_tmpYdispUseMR : m_tmpYdisp)[tmpIdx];
    #else
    
                int tmpIdx = cu->tmpFusionFlag ? m_tmpFusionInfo[cu->tmpIdx].tmpFusionIdx : cu->tmpIdx;
                pX = m_tmpXdisp[tmpIdx];
                pY = m_tmpYdisp[tmpIdx];
    
    #if JVET_AF0079_STORING_INTRATMP
    
    #if JVET_AG0136_INTRA_TMP_LIC
                if (cu->tmpFusionFlag && ((((tu.cu)->tmpLicFlag ? m_tmpFusionInfoUseMR : m_tmpFusionInfo)[cu->tmpIdx].tmpFusionNumber < 1) || ((tu.cu)->tmpLicFlag ? m_tmpFusionInfoUseMR : m_tmpFusionInfo)[cu->tmpIdx].bFilter))
    #else
    
                if (cu->tmpFusionFlag
                    && ((m_tmpFusionInfo[cu->tmpIdx].tmpFusionNumber < 1) || m_tmpFusionInfo[cu->tmpIdx].bFilter))
    
                {
                  pu.mv[0].set(pX << MV_FRACTIONAL_BITS_INTERNAL, pY << MV_FRACTIONAL_BITS_INTERNAL);
                  pu.bv.set(pX, pY);
                }
    #else
    
    
                pu.mv->set(pX << MV_FRACTIONAL_BITS_INTERNAL, pY << MV_FRACTIONAL_BITS_INTERNAL);
                pu.bv.set(pX, pY);
    
                pu.mv->set(m_tempLibFast.getX() << MV_FRACTIONAL_BITS_INTERNAL, m_tempLibFast.getY() << MV_FRACTIONAL_BITS_INTERNAL);
                pu.bv.set(m_tempLibFast.getX(), m_tempLibFast.getY());
    
    Vadim Seregin's avatar
    Vadim Seregin committed
              }
              else
              {
                foundCandiNum = 1;
    
    #if JVET_AC0115_INTRA_TMP_DIMD_MTS_LFNST 
                generateTmDcPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), 1 << (tu.cu->cs->sps->getBitDepth(CHANNEL_TYPE_LUMA) - 1), pu.cu);
    #else
    
                generateTmDcPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), 1 << (tu.cu->cs->sps->getBitDepth( CHANNEL_TYPE_LUMA ) - 1) );
    
    #if JVET_AB0061_ITMP_BV_FOR_IBC
                pu.interDir               = 1;             // use list 0 for IBC mode
                pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF;   // last idx in the list
                pu.mv->set(0, 0);
                pu.bv.set(0, 0);
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
              }
    
              getTargetTemplate( tu.cu, pu.lwidth(), pu.lheight() );
              candidateSearchIntra( tu.cu, pu.lwidth(), pu.lheight() );
              generateTMPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum );
    
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
              CHECK( foundCandiNum < 1, "" );
            }
            else if( PU::isMIP( pu, chType ) )
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #else
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
    #if JVET_AB0067_MIP_DIMD_LFNST
    
    #if JVET_AH0076_OBIC
              predIntraMip( compID, piPred, pu, true);
    #else
    
              predIntraMip( compID, piPred, pu, pu.cu->lfnstIdx > 0 ? true : false);
    
    #if JVET_AG0058_EIP
            else if (PU::isEIP(pu, chType))
            {
              const CPelBuf eipSaveBuf(pu.cu->eipMerge ? m_eipMergePredBuf[pu.intraDir[0]] : m_eipPredBuf[pu.intraDir[0]], pu.Y());
              piPred.copyFrom(eipSaveBuf);
            }
    
    #endif
    #if JVET_AH0076_OBIC
            else if (pu.cu->dimd && compID == COMPONENT_Y && pu.cu->ispMode == NOT_INTRA_SUBPARTITIONS)
            {
              const CPelBuf dimdSaveBuf(pu.cu->obicFlag ? m_obicPredBuf : m_dimdPredBuf, pu.Y());
              piPred.copyFrom(dimdSaveBuf);
            }
    
            else
            {
              if (predRegDiffFromTB)
              {
                if (firstTBInPredReg)
                {
                  PelBuf piPredReg = cs.getPredBuf(areaPredReg);
                  predIntraAng(compID, piPredReg, pu);
                }
              }
              else
    
    fan wang's avatar
    fan wang committed
    #if JVET_AB0155_SGPM
                if (pu.cu->sgpm &&compID == COMPONENT_Y)
                {
                  CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
                  PelBuf   predBuf(m_sgpmPredBuf[pu.cu->sgpmIdx], tmpArea);
                  piPred.copyFrom(predBuf);
                }
                else
    #endif
    
    
    #if JVET_Z0050_DIMD_CHROMA_FUSION
              if (compID != COMPONENT_Y && pu.isChromaFusion)
              {
                geneChromaFusionPred(compID, piPred, pu);
              }
    #endif
    
          // save prediction
          if( default0Save1Load2 == 1 )
          {
            sharedPredTS.copyFrom( piPred );
          }
        }
        else
    
          // load prediction
          piPred.copyFrom( sharedPredTS );
    
        }
      }
    
    
      DTRACE( g_trace_ctx, D_PRED, "@(%4d,%4d) [%2dx%2d] IMode=%d\n", tu.lx(), tu.ly(), tu.lwidth(), tu.lheight(), uiChFinalMode );
      //DTRACE_PEL_BUF( D_PRED, piPred, tu, tu.cu->predMode, COMPONENT_Y );
    
    
    Taoran Lu's avatar
    Taoran Lu committed
      const Slice           &slice = *cs.slice;
    
      bool flag = slice.getLmcsEnabledFlag() && (slice.isIntra() || (!slice.isIntra() && m_pcReshape->getCTUFlag()));
    
    #if JVET_W0103_INTRA_MTS
      if (!tu.cu->mtsFlag && isLuma(compID))
    #else
    
        //===== get residual signal =====
        piResi.copyFrom( piOrg  );
    
        if (slice.getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          piResi.rspSignal( m_pcReshape->getFwdLUT() );
          piResi.subtract( piPred );
    
    
      //===== transform and quantization =====
      //--- init rate estimation arrays for RDOQ ---
      //--- transform and quantization           ---
      TCoeff uiAbsSum = 0;
    
      const QpParam cQP(tu, compID);
    
    #if RDOQ_CHROMA_LAMBDA
      m_pcTrQuant->selectLambda(compID);
    #endif
    
    
      flag =flag && (tu.blocks[compID].width*tu.blocks[compID].height > 4);
    
    Brian Heng's avatar
    Brian Heng committed
      if (flag && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() )
    
    Taoran Lu's avatar
    Taoran Lu committed
        int cResScaleInv = tu.getChromaAdj();
    
        double cResScale = (double)(1 << CSCALE_FP_PREC) / (double)cResScaleInv;
    
    Taoran Lu's avatar
    Taoran Lu committed
        m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cResScale*cResScale));
    
      PelBuf          crOrg;
      PelBuf          crPred;
      PelBuf          crResi;
      PelBuf          crReco;
    
      if (isChroma(compID))
      {
        const CompArea &crArea = tu.blocks[ COMPONENT_Cr ];
        crOrg  = cs.getOrgBuf  ( crArea );
        crPred = cs.getPredBuf ( crArea );
        crResi = cs.getResiBuf ( crArea );
        crReco = cs.getRecoBuf ( crArea );
      }
    
      if ( jointCbCr )
      {
        // Lambda is loosened for the joint mode with respect to single modes as the same residual is used for both chroma blocks
    
        const int    absIct = abs( TU::getICTMode(tu) );
        const double lfact  = ( absIct == 1 || absIct == 3 ? 0.8 : 0.5 );
        m_pcTrQuant->setLambda( lfact * m_pcTrQuant->getLambda() );
    
      if ( sps.getJointCbCrEnabledFlag() && isChroma(compID) && (tu.cu->cs->slice->getSliceQp() > 18) )
    
    Fangdong Chen's avatar
    Fangdong Chen committed
      {
        m_pcTrQuant->setLambda( 1.3 * m_pcTrQuant->getLambda() );
      }
    
    #if JVET_Y0142_ADAPT_INTRA_MTS
          m_pcTrQuant->transformNxN(tu, compID, cQP, trModes, 8);
    #else
    
          m_pcTrQuant->transformNxN(tu, compID, cQP, trModes, m_pcEncCfg->getMTSIntraMaxCand());
    
          tu.mtsIdx[compID] = trModes->at(0).first;
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    
    
        if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) || tu.cu->bdpcmMode != 0)
    
        {
          m_pcTrQuant->transformNxN(tu, compID, cQP, uiAbsSum, m_CABACEstimator->getCtx(), loadTr);
        }
    
        DTRACE(g_trace_ctx, D_TU_ABS_SUM, "%d: comp=%d, abssum=%d\n", DTRACE_GET_COUNTER(g_trace_ctx, D_TU_ABS_SUM), compID,
               uiAbsSum);
    
        if (tu.cu->ispMode && isLuma(compID) && CU::isISPLast(*tu.cu, area, area.compID) && CU::allLumaCBFsAreZero(*tu.cu))
        {
          // ISP has to have at least one non-zero CBF
          ruiDist = MAX_INT;
          return;
        }
    
    #if JVET_Y0142_ADAPT_INTRA_MTS
        if (isLuma(compID) && tu.mtsIdx[compID] >= MTS_DST7_DST7)
        {
          bool signHiding = cs.slice->getSignDataHidingEnabledFlag();
          CoeffCodingContext  cctx(tu, compID, signHiding);
          const TCoeff*       coeff = tu.getCoeffs(compID).buf;
          int          scanPosLast = -1;
          uint64_t     coeffAbsSum = 0;
    
          for (int scanPos = 0; scanPos < cctx.maxNumCoeff(); scanPos++)
          {
            unsigned blkPos = cctx.blockPos(scanPos);
            if (coeff[blkPos])
            {
              scanPosLast = scanPos;
              coeffAbsSum += abs(coeff[blkPos]);
            }
          }
          int nCands = (coeffAbsSum > MTS_TH_COEFF[1]) ? MTS_NCANDS[2] : (coeffAbsSum > MTS_TH_COEFF[0]) ? MTS_NCANDS[1] : MTS_NCANDS[0];
          bool isInvalid = (scanPosLast <= 0) || ((tu.mtsIdx[COMPONENT_Y] - MTS_DST7_DST7) >= nCands);
          if (isInvalid)
          {
            m_validMTSReturn = false;
            ruiDist = MAX_INT;
            return;
          }
        }
    #endif
    
        if ((m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0)
            && 0 == tu.cu->bdpcmMode)
        {
          uiAbsSum = 0;
          tu.getCoeffs(compID).fill(0);
          TU::setCbfAtDepth(tu, compID, tu.depth, 0);
        }
    
        //--- inverse transform ---
        if (uiAbsSum > 0)
        {
          m_pcTrQuant->invTransformNxN(tu, compID, piResi, cQP);
        }
        else
        {
          piResi.fill(0);
        }
    
        ComponentID codeCompId    = (tu.jointCbCr ? (tu.jointCbCr >> 1 ? COMPONENT_Cb : COMPONENT_Cr) : compID);
        const QpParam qpCbCr(tu, codeCompId);
    
    
        if( tu.jointCbCr )
        {
          ComponentID otherCompId = ( codeCompId==COMPONENT_Cr ? COMPONENT_Cb : COMPONENT_Cr );
          tu.getCoeffs( otherCompId ).fill(0); // do we need that?
          TU::setCbfAtDepth (tu, otherCompId, tu.depth, false );
        }
        PelBuf& codeResi = ( codeCompId == COMPONENT_Cr ? crResi : piResi );
        uiAbsSum = 0;
    
          m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, trModes, m_pcEncCfg->getMTSIntraMaxCand());
          tu.mtsIdx[codeCompId] = trModes->at(0).first;
          if (tu.jointCbCr)
          {
            tu.mtsIdx[(codeCompId == COMPONENT_Cr) ? COMPONENT_Cb : COMPONENT_Cr] = MTS_DCT2_DCT2;
          }
    
        }
        // encoder bugfix: Set loadTr to aovid redundant transform process
    
        if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) || tu.cu->bdpcmModeChroma != 0)
    
        {
            m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, uiAbsSum, m_CABACEstimator->getCtx(), loadTr);
        }
    
        if ((m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) && 0 == tu.cu->bdpcmModeChroma)
    
        {
            uiAbsSum = 0;
            tu.getCoeffs(compID).fill(0);
            TU::setCbfAtDepth(tu, compID, tu.depth, 0);
        }
    
    
        DTRACE( g_trace_ctx, D_TU_ABS_SUM, "%d: comp=%d, abssum=%d\n", DTRACE_GET_COUNTER( g_trace_ctx, D_TU_ABS_SUM ), codeCompId, uiAbsSum );
        if( uiAbsSum > 0 )
        {
    
          m_pcTrQuant->invTransformNxN(tu, codeCompId, codeResi, qpCbCr);
    
          codedCbfMask += ( codeCompId == COMPONENT_Cb ? 2 : 1 );
        }
        else
        {
          codeResi.fill(0);
        }
    
        if( tu.jointCbCr )
        {
          if( tu.jointCbCr == 3 && codedCbfMask == 2 )
          {
            codedCbfMask = 3;
            TU::setCbfAtDepth (tu, COMPONENT_Cr, tu.depth, true );
          }
          if( tu.jointCbCr != codedCbfMask )
          {
            ruiDist = std::numeric_limits<Distortion>::max();
            return;
          }
          m_pcTrQuant->invTransformICT( tu, piResi, crResi );
          uiAbsSum = codedCbfMask;
        }
      }
    
    Brian Heng's avatar
    Brian Heng committed
      if ( flag && uiAbsSum > 0 && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() )
    
        piResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(compID));
    
        if( jointCbCr )
        {
          crResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cr));
        }
    
      if (slice.getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
    
    Taoran Lu's avatar
    Taoran Lu committed
      {
        CompArea      tmpArea(COMPONENT_Y, area.chromaFormat, Position(0,0), area.size());
        PelBuf tmpPred = m_tmpStorageLCU.getBuf(tmpArea);
        tmpPred.copyFrom(piPred);
    
    #if JVET_AG0145_ADAPTIVE_CLIPPING
        ClpRng clpRng = cs.slice->clpRng(compID);
        if (pu.cu->cs->sps->getUseLmcs() && pu.cu->cs->picHeader->getLmcsEnabledFlag())
        {
          std::vector<Pel>& fwdLUT = m_pcReshape->getFwdLUT();
          clpRng.min = fwdLUT[cs.slice->getLumaPelMin()];
          clpRng.max = fwdLUT[cs.slice->getLumaPelMax()];
        }
        else
        {
          clpRng.min = cs.slice->getLumaPelMin();
          clpRng.max = cs.slice->getLumaPelMax();
        }
        piReco.reconstruct(tmpPred, piResi, clpRng);
    #else
    
    Taoran Lu's avatar
    Taoran Lu committed
        piReco.reconstruct(tmpPred, piResi, cs.slice->clpRng(compID));
    
    #if JVET_AG0145_ADAPTIVE_CLIPPING
        ClpRng clpRng = cs.slice->clpRng(compID);
        if (compID == COMPONENT_Y)
        {
          if (pu.cu->cs->sps->getUseLmcs() && pu.cu->cs->picHeader->getLmcsEnabledFlag())
          {
            std::vector<Pel>& fwdLUT = m_pcReshape->getFwdLUT();
            clpRng.min = fwdLUT[cs.slice->getLumaPelMin()];
            clpRng.max = fwdLUT[cs.slice->getLumaPelMax()];
          }
          else
          {
            clpRng.min = cs.slice->getLumaPelMin();
            clpRng.max = cs.slice->getLumaPelMax();
          }
        }
        piReco.reconstruct(piPred, piResi, clpRng);
    #else
    
        piReco.reconstruct(piPred, piResi, cs.slice->clpRng( compID ));
    
        if( jointCbCr )
        {
          crReco.reconstruct(crPred, crResi, cs.slice->clpRng( COMPONENT_Cr ));
        }
      }
    
    #if JVET_AC0071_DBV && JVET_AA0070_RRIBC
    
    #if JVET_AH0136_CHROMA_REORDERING
      if (compID != COMPONENT_Y && PU::isDbvMode(uiChFinalMode) && pu.cu->rribcFlipType)
    #else
    
      if (compID != COMPONENT_Y && uiChFinalMode == DBV_CHROMA_IDX && pu.cu->rribcFlipType)
    
      {
        cs.getRecoBuf(area).flipSignal(pu.cu->rribcFlipType == 1);
        if (jointCbCr)
        {
          const CompArea &crArea = tu.blocks[COMPONENT_Cr];
          cs.getRecoBuf(crArea).flipSignal(pu.cu->rribcFlipType == 1);
        }
      }
    #endif
    
    #if INTRA_TRANS_ENC_OPT 
      bool doSignPrediction = true;
      if (isLuma(compID) && ((tu.mtsIdx[COMPONENT_Y] > MTS_SKIP) || (CS::isDualITree(cs) && tu.cu->lfnstIdx && !tu.cu->ispMode)))
      {
        bool signHiding = cs.slice->getSignDataHidingEnabledFlag();
        CoeffCodingContext  cctx(tu, COMPONENT_Y, signHiding);
        int scanPosLast = -1;
        TCoeff* coeff = tu.getCoeffs(compID).buf;
        for (int scanPos = cctx.maxNumCoeff() - 1; scanPos >= 0; scanPos--)
        {
          unsigned blkPos = cctx.blockPos(scanPos);
          if (coeff[blkPos])
          {
            scanPosLast = scanPos;
            break;
          }
        }
        if (scanPosLast < 1)
        {
          doSignPrediction = false;
        }
      }
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
      if ( sps.getNumPredSigns() > 0)
      {
    
    #if INTRA_TRANS_ENC_OPT
        if (doSignPrediction)
        {
    #endif
          bool bJccrWithCr = tu.jointCbCr && !(tu.jointCbCr >> 1);
          bool bIsJccr = tu.jointCbCr && isChroma(compID);
          ComponentID signPredCompID = bIsJccr ? (bJccrWithCr ? COMPONENT_Cr : COMPONENT_Cb) : compID;
          bool reshapeChroma = flag && (TU::getCbf(tu, signPredCompID) || tu.jointCbCr) && isChroma(signPredCompID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag();
          m_pcTrQuant->predCoeffSigns(tu, compID, reshapeChroma);
    #if INTRA_TRANS_ENC_OPT
        }
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
      }
    
    #if INTRA_TRANS_ENC_OPT 
      if (doSignPrediction)
    
    Vadim Seregin's avatar
    Vadim Seregin committed
      {
    
    #if JVET_V0094_BILATERAL_FILTER
        CompArea      tmpArea1(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
        PelBuf tmpRecLuma;
        if(isLuma(compID))
        {
          tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
          tmpRecLuma.copyFrom(piReco);
        }
    
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
    
        CompArea tmpArea2(compID, area.chromaFormat, Position(0, 0), area.size());
        PelBuf tmpRecChroma;
        if(isChroma(compID))
        {
          tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2);
          tmpRecChroma.copyFrom(piReco);
        }
    
    Vadim Seregin's avatar
    Vadim Seregin committed
      //===== update distortion =====
    #if WCG_EXT
      
    
        if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcEncCfg->getLmcs()
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          && slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD()))))
        {
    
        
          const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
    
          if( isLuma( compID) )
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          {
            if(!(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
            {
    
              tmpRecLuma.rspSignal(m_pcReshape->getInvLUT());
    
    Vadim Seregin's avatar
    Vadim Seregin committed
            }
    
    #if JVET_AF0112_BIF_DYNAMIC_SCALING
            bool applyBIF = pps.getUseBIF() && m_bilateralFilter->getApplyBIF(tu, compID);
    #else
            bool applyBIF = pps.getUseBIF() /*&& (uiAbsSum > 0)*/ && tu.cu->qp > 17 && 128 > std::max(tu.lumaSize().width, tu.lumaSize().height);
    #endif
            if(applyBIF)
    
    Vadim Seregin's avatar
    Vadim Seregin committed
            {
    
              CompArea compArea = tu.blocks[compID];
              PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
              if(!(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
              {
    
                m_bilateralFilter->bilateralFilterRDOdiamond5x5( compID, tmpRecLuma, tmpRecLuma, tmpRecLuma, tu.cu->qp, recIPredBuf, cs.slice->clpRng( compID ), tu, true, true, &m_pcReshape->getInvLUT() );
    
                std::vector<Pel> invLUT;
    
                m_bilateralFilter->bilateralFilterRDOdiamond5x5( compID, tmpRecLuma, tmpRecLuma, tmpRecLuma, tu.cu->qp, recIPredBuf, cs.slice->clpRng( compID ), tu, true, false, &invLUT );
    
            ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          {
    
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
    
    #if JVET_AF0112_BIF_DYNAMIC_SCALING
            bool applyChromaBIF = pps.getUseChromaBIF() && m_bilateralFilter->getApplyBIF(tu, compID);
    #else
            bool applyChromaBIF = pps.getUseChromaBIF() && tu.cu->qp > 17;
    #endif
            if(applyChromaBIF)
    
              CompArea compArea = tu.blocks[compID];
              PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
    
              m_bilateralFilter->bilateralFilterRDOdiamond5x5( compID, tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true );
    
            ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecChroma, bitDepth, compID, DF_SSE_WTD, &orgLuma);
    #else
            ruiDist += m_pcRdCost->getDistPart(piOrg, piReco, bitDepth, compID, DF_SSE_WTD, &orgLuma);
    #endif
            if( jointCbCr )
    
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
              if(compID == COMPONENT_Cr)
              {
                ruiDist += m_pcRdCost->getDistPart(crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
              }
              else