Skip to content
Snippets Groups Projects
IntraSearch.cpp 309 KiB
Newer Older
  • Learn to ignore specific revisions
  •   //===== get prediction signal =====
      if (PU::isMIP(pu, chType))
      {
        initIntraMip(pu, area);
        predIntraMip(COMPONENT_Y, piPred, pu);
      }
      else
      {
    
    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
    
    
        predIntraAng(COMPONENT_Y, piPred, pu);
      }
    
    
      // 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 (!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 TMP_FAST_ENC
                generateTMPrediction(piPred.buf, piPred.stride, pu.Y(), foundCandiNum, tu.cu);
    #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(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
    
                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 );
    
    #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(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;
    
                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
              predIntraMip( compID, piPred, pu, pu.cu->lfnstIdx > 0 ? true : false);
    #else
    
            }
            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);
        piReco.reconstruct(tmpPred, piResi, cs.slice->clpRng(compID));
      }
    
      {
        piReco.reconstruct(piPred, piResi, cs.slice->clpRng( compID ));
        if( jointCbCr )
        {
          crReco.reconstruct(crPred, crResi, cs.slice->clpRng( COMPONENT_Cr ));
        }
      }
    
    #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 (compID == COMPONENT_Y)
    
    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 (pps.getUseBIF() /*&& (uiAbsSum > 0)*/ && isLuma(compID) && (tu.cu->qp > 17) && (128 > std::max(tu.lumaSize().width, tu.lumaSize().height)))
    
    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(tmpRecLuma, tmpRecLuma, tmpRecLuma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, true, m_pcReshape->getInvLUT());
              }
              else
              {
    
                std::vector<Pel> invLUT;
                m_bilateralFilter->bilateralFilterRDOdiamond5x5(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(pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17))
    
              CompArea compArea = tu.blocks[compID];
              PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
              bool isCb = compID == COMPONENT_Cb ? true : false;
              m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb);
    
            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
              {
                ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
              }
    
              ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          }
        }
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
        {
    
          if(isLuma(compID))
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          {
    
            if (pps.getUseBIF() /*&& (uiAbsSum > 0)*/ && isLuma(compID) && (tu.cu->qp > 17) && (128 > std::max(tu.lumaSize().width, tu.lumaSize().height)))
            {
              CompArea compArea = tu.blocks[compID];
              PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
    
              std::vector<Pel> invLUT;
              m_bilateralFilter->bilateralFilterRDOdiamond5x5(tmpRecLuma, tmpRecLuma, tmpRecLuma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, false, invLUT);
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          
    
            ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecLuma, bitDepth, compID, DF_SSE );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          {
    
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
    
            if (pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17))
    
              CompArea compArea = tu.blocks[compID];
              PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
              bool isCb = compID == COMPONENT_Cb ? true : false;
              m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb);
    
            ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecChroma, bitDepth, compID, DF_SSE );
    #else
            ruiDist += m_pcRdCost->getDistPart( piOrg, piReco, bitDepth, compID, DF_SSE );
    #endif
            if( jointCbCr )
    
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
              if(compID == COMPONENT_Cr)
              {
                ruiDist += m_pcRdCost->getDistPart( crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE );
              }
              else
              {
                ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE );
              }
    
              ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          }
        }
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #else
    
    #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);
    
        }
    #if WCG_EXT
        if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcEncCfg->getLmcs() && slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD()))))
        {
    
          const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
          if(isLuma(compID))
          {
            if (compID == COMPONENT_Y  && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
    
              CompArea      tmpArea1(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
              PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
              tmpRecLuma.rspSignal( piReco, m_pcReshape->getInvLUT() );
              ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
    
              ruiDist += m_pcRdCost->getDistPart(piOrg, piReco, bitDepth, compID, DF_SSE_WTD, &orgLuma);
              if( jointCbCr )
              {
                ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
              }
            }
          }
          else
          {
            if(pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17))
            {
              CompArea compArea = tu.blocks[compID];
              PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
              bool isCb = compID == COMPONENT_Cb ? true : false;
              m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb);
    
            ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecChroma, bitDepth, compID, DF_SSE_WTD, &orgLuma);
            if( jointCbCr )
            {
              if(compID == COMPONENT_Cr)
              {
                ruiDist += m_pcRdCost->getDistPart(crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
              }
              else
              {
                ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
              }
            }
          }
    
          if(isLuma(compID))
          {
            ruiDist += m_pcRdCost->getDistPart( piOrg, piReco, bitDepth, compID, DF_SSE );
          }
          else
          {
            if (pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17))
    
              CompArea compArea = tu.blocks[compID];
              PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
              bool isCb = compID == COMPONENT_Cb ? true : false;
              m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb);
    
            ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecChroma, bitDepth, compID, DF_SSE );
          }
          if( jointCbCr )
          {
            if(compID == COMPONENT_Cr)
            {
              ruiDist += m_pcRdCost->getDistPart( crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE );
    
              ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE );
    
        if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcEncCfg->getLmcs()
          && slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD()))))
    
          const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
          if (compID == COMPONENT_Y  && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
          {
            CompArea      tmpArea1(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
            PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
            tmpRecLuma.rspSignal( piReco, m_pcReshape->getInvLUT() );
            ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
          }
          else
          {
            ruiDist += m_pcRdCost->getDistPart(piOrg, piReco, bitDepth, compID, DF_SSE_WTD, &orgLuma);
            if( jointCbCr )
            {
              ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
            }
          }
    
          ruiDist += m_pcRdCost->getDistPart( piOrg, piReco, bitDepth, compID, DF_SSE );
    
            ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
    #if INTRA_TRANS_ENC_OPT && SIGN_PREDICTION
    
    void IntraSearch::xIntraCodingACTTUBlock(TransformUnit &tu, const ComponentID &compID, Distortion& ruiDist, std::vector<TrMode>* trModes, const bool loadTr)
    {
      if (!tu.blocks[compID].valid())
      {
        CHECK(1, "tu does not exist");
      }
    
      CodingStructure     &cs = *tu.cs;
      const SPS           &sps = *cs.sps;
      const Slice         &slice = *cs.slice;
      const CompArea      &area = tu.blocks[compID];
      const CompArea &crArea = tu.blocks[COMPONENT_Cr];
    
      PelBuf              piOrgResi = cs.getOrgResiBuf(area);
      PelBuf              piResi = cs.getResiBuf(area);
      PelBuf              crOrgResi = cs.getOrgResiBuf(crArea);
      PelBuf              crResi = cs.getResiBuf(crArea);
      TCoeff              uiAbsSum = 0;
    
      CHECK(tu.jointCbCr && compID == COMPONENT_Cr, "wrong combination of compID and jointCbCr");
      bool jointCbCr = tu.jointCbCr && compID == COMPONENT_Cb;
    
      m_pcRdCost->setChromaFormat(cs.sps->getChromaFormatIdc());
    
      if (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless())
    
      m_pcTrQuant->lambdaAdjustColorTrans(true);
    
      if (jointCbCr)
      {
        ComponentID compIdCode = (tu.jointCbCr >> 1 ? COMPONENT_Cb : COMPONENT_Cr);
        m_pcTrQuant->selectLambda(compIdCode);
      }
      else
      {
        m_pcTrQuant->selectLambda(compID);
      }
    
    
      bool flag = slice.getLmcsEnabledFlag() && (slice.isIntra() || (!slice.isIntra() && m_pcReshape->getCTUFlag())) && (tu.blocks[compID].width*tu.blocks[compID].height > 4);
    
      if (flag && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag())
    
      {
        int    cResScaleInv = tu.getChromaAdj();
        double cResScale = (double)(1 << CSCALE_FP_PREC) / (double)cResScaleInv;
        m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cResScale*cResScale));
      }
    
      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) && (slice.getSliceQp() > 18))
      {
        m_pcTrQuant->setLambda(1.3 * m_pcTrQuant->getLambda());
      }
    
      if (isLuma(compID))
      {
        QpParam cQP(tu, compID);
    
        if (trModes)
        {
          m_pcTrQuant->transformNxN(tu, compID, cQP, trModes, m_pcEncCfg->getMTSIntraMaxCand());
          tu.mtsIdx[compID] = trModes->at(0).first;
        }
    
        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);
        }
    
        if ((m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) && tu.cu->bdpcmMode == 0)
    
        {
          uiAbsSum = 0;
          tu.getCoeffs(compID).fill(0);
          TU::setCbfAtDepth(tu, compID, tu.depth, 0);
        }
    
    
        if (uiAbsSum > 0)
        {
          m_pcTrQuant->invTransformNxN(tu, compID, piResi, cQP);
        }
        else
        {
          piResi.fill(0);
        }
      }
      else
      {
        int         codedCbfMask = 0;
        ComponentID codeCompId = (tu.jointCbCr ? (tu.jointCbCr >> 1 ? COMPONENT_Cb : COMPONENT_Cr) : compID);
        QpParam qpCbCr(tu, codeCompId);
    
        if (tu.jointCbCr)
        {
          ComponentID otherCompId = (codeCompId == COMPONENT_Cr ? COMPONENT_Cb : COMPONENT_Cr);
          tu.getCoeffs(otherCompId).fill(0);
          TU::setCbfAtDepth(tu, otherCompId, tu.depth, false);
        }
    
        PelBuf& codeResi = (codeCompId == COMPONENT_Cr ? crResi : piResi);
        uiAbsSum = 0;
    
        if (trModes)
        {
          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;
          }
        }
    
        if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[codeCompId] == 0) || tu.cu->bdpcmModeChroma != 0)
    
        {
          m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, uiAbsSum, m_CABACEstimator->getCtx(), loadTr);
        }
    
        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();
    
            if (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless())
    
            m_pcTrQuant->lambdaAdjustColorTrans(false);
            return;
          }
          m_pcTrQuant->invTransformICT(tu, piResi, crResi);
          uiAbsSum = codedCbfMask;
        }
      }
    
    
      if (flag && uiAbsSum > 0 && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag())
    
      {
        piResi.scaleSignal(tu.getChromaAdj(), 0, slice.clpRng(compID));
        if (jointCbCr)
        {
          crResi.scaleSignal(tu.getChromaAdj(), 0, slice.clpRng(COMPONENT_Cr));
        }
      }
    
      if (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless())
    
      m_pcTrQuant->lambdaAdjustColorTrans(false);
    
      ruiDist += m_pcRdCost->getDistPart(piOrgResi, piResi, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE);
      if (jointCbCr)
      {
        ruiDist += m_pcRdCost->getDistPart(crOrgResi, crResi, sps.getBitDepth(toChannelType(COMPONENT_Cr)), COMPONENT_Cr, DF_SSE);
      }
    }
    
    
    bool IntraSearch::xIntraCodingLumaISP(CodingStructure& cs, Partitioner& partitioner, const double bestCostSoFar)
    {
      int               subTuCounter = 0;
      const CodingUnit& cu = *cs.getCU(partitioner.currArea().lumaPos(), partitioner.chType);
      bool              earlySkipISP = false;
    
    Santiago de Luxán Hernández's avatar
    Santiago de Luxán Hernández committed
      bool              splitCbfLuma = false;
    
      const PartSplit   ispType = CU::getISPType(cu, COMPONENT_Y);
    
      cs.cost = 0;
    
      partitioner.splitCurrArea(ispType, cs);
    
    
      CUCtx cuCtx;
      cuCtx.isDQPCoded = true;
      cuCtx.isChromaQpAdjCoded = true;
    
    
      do   // subpartitions loop
      {
        uint32_t   numSig = 0;
        Distortion singleDistTmpLuma = 0;
        uint64_t   singleTmpFracBits = 0;
        double     singleCostTmp = 0;
    
        TransformUnit& tu = cs.addTU(CS::getArea(cs, partitioner.currArea(), partitioner.chType), partitioner.chType);
        tu.depth = partitioner.currTrDepth;
    
        // Encode TU
    
        xIntraCodingTUBlock(tu, COMPONENT_Y, singleDistTmpLuma, 0, &numSig);
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    
    #if SIGN_PREDICTION
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #if JVET_Z0118_GDR
        cs.updateReconMotIPM(partitioner.currArea());
    #else
    
    Vadim Seregin's avatar
    Vadim Seregin committed
        cs.picture->getRecoBuf( partitioner.currArea() ).copyFrom( cs.getRecoBuf( partitioner.currArea() ) );
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
    
        if (singleDistTmpLuma == MAX_INT)   // all zero CBF skip
        {
          earlySkipISP = true;
          partitioner.exitCurrSplit();
          cs.cost = MAX_DOUBLE;
          return false;
        }
    
    
        if (m_pcRdCost->calcRdCost(cs.fracBits, cs.dist + singleDistTmpLuma) > bestCostSoFar)