Skip to content
Snippets Groups Projects
IntraSearch.cpp 565 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 for(int tmpFusionFlag = 0; tmpFusionFlag <= 1; tmpFusionFlag++)
                    {
                      cu.tmpFusionFlag = tmpFusionFlag ? true: false;
    
                      for (int tmpFlmFlag = 0; tmpFlmFlag <= 1; tmpFlmFlag++)
                      {
                        cu.tmpFlmFlag = tmpFlmFlag ? true: false;
                        if(tmpFlmFlag && tmpFusionFlag)
                        {
                          continue;
                        }
    
    
    #if JVET_AG0136_INTRA_TMP_LIC
                        for (int tmpLicFlag = 0; tmpLicFlag <= 1; tmpLicFlag++)
                        {
                          cu.ibcLicFlag = tmpLicFlag ? true : false;
                          cu.tmpLicFlag = tmpLicFlag ? true : false;
                          if (tmpLicFlag && tmpFlmFlag)
                          {
                            continue;
                          }
                          const int ibcLicLoopNum = (cu.slice->getSPS()->getItmpLicExtension() && cu.tmpLicFlag && !cu.tmpFusionFlag) ? 4 : 1;
                          for (int licIdc = 0; licIdc < ibcLicLoopNum; licIdc++)
                          {
                            cu.ibcLicIdx = licIdc;
                          int idxNum = cu.tmpFusionFlag ? TMP_GROUP_IDX << 1 : (cu.tmpLicFlag ? m_tmpNumCandUseMR : m_tmpNumCand);
    #else
    
                        int idxNum = cu.tmpFusionFlag ? TMP_GROUP_IDX << 1 : m_tmpNumCand;
    
                        for (int tmpIdx = 0; tmpIdx < idxNum; tmpIdx++)
                        {
    
    #if JVET_AG0136_INTRA_TMP_LIC
                          if (cu.tmpFusionFlag && !(cu.tmpLicFlag ? m_tmpFusionInfoUseMR : m_tmpFusionInfo)[tmpIdx].bValid)
    #else
    
                          if(cu.tmpFusionFlag && !m_tmpFusionInfo[tmpIdx].bValid)
    
                          generateTMPrediction(piPred.buf, piPred.stride, placeHolder, pu
    #if JVET_AG0136_INTRA_TMP_LIC
                                               , cu.tmpLicFlag
    #endif
                                               , false);
    #if JVET_AG0136_INTRA_TMP_LIC
                            if (cu.tmpLicFlag)
                            {
                              if (!cu.tmpFusionFlag)
                              {
                                const auto& arrayLicParams = getMemLicParams(cu.ibcLicIdx, cu.tmpIdx);
                                if (cu.ibcLicIdx == IBC_LIC_IDX_M)
                                {
                                  piPred.linearTransforms(arrayLicParams[1], arrayLicParams[0], arrayLicParams[2], arrayLicParams[4], arrayLicParams[3], arrayLicParams[5], arrayLicParams[6], true, cu.cs->slice->clpRng(COMPONENT_Y));
                                }
                                else
                                {
                                  piPred.linearTransform(arrayLicParams[1], arrayLicParams[0], arrayLicParams[2], true, cu.cs->slice->clpRng(COMPONENT_Y));
                                }
                              }
                            }
    #endif
    
                          xGenerateTmpFlmPred(piPred, pu.lwidth(), pu.lheight(), templateType, pu.cu, false);
    
                          xTMPFusionApplyModel(piPred, pu.lwidth(), pu.lheight(), templateType, pu.cu
    #if JVET_AG0136_INTRA_TMP_LIC
                                               , cu.tmpLicFlag
    #endif
                                               , false);
    
    
    #if JVET_W0069_TMP_BOUNDARY
    #if TMP_FAST_ENC
                    bsuccessfull = generateTMPrediction(piPred.buf, piPred.stride, pu.Y(), foundCandiNum, pu.cu);
    #else
                    getTargetTemplate(&cuCopy, pu.lwidth(), pu.lheight(), templateType);
                    candidateSearchIntra(&cuCopy, pu.lwidth(), pu.lheight(), templateType);
                    bsuccessfull = generateTMPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum);
    #endif
    #else
    #if TMP_FAST_ENC
                    bsuccessfull = generateTMPrediction(piPred.buf, piPred.stride, pu.Y(), foundCandiNum, pu.cu);
    #else
                    getTargetTemplate(&cuCopy, pu.lwidth(), pu.lheight());
                    candidateSearchIntra(&cuCopy, pu.lwidth(), pu.lheight());
                    bsuccessfull = generateTMPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum);
    #endif
    #endif
                  }
    #if JVET_W0069_TMP_BOUNDARY
                  else
                  {
                    foundCandiNum = 1;
    
    #if JVET_AC0115_INTRA_TMP_DIMD_MTS_LFNST 
                    bsuccessfull = generateTmDcPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), 1 << (cuCopy.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA) - 1), pu.cu);
    #else
    
                    bsuccessfull = generateTmDcPrediction(piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), 1 << (cuCopy.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA) - 1));
    
                  }
    #endif
                  if (bsuccessfull && foundCandiNum >= 1)
                  {
    
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
    
                          Distortion sadCost = distParamSad.distFunc(distParamSad);
                          Distortion minSadHad = std::min(sadCost * 2, distParamHad.distFunc(distParamHad));
    
                          Distortion minSadHad =
                            std::min(distParamSad.distFunc(distParamSad) * 2, distParamHad.distFunc(distParamHad));
    
    #if JVET_AG0136_INTRA_TMP_LIC
                          m_CABACEstimator->getCtx() = SubCtx(Ctx::TmpLic, ctxStartTmpLicFlag);
                          m_CABACEstimator->getCtx() = SubCtx(Ctx::ItmpLicIndex, ctxStartTmpLicIdx);
    #endif
    
                          uint64_t fracModeBits = xFracModeBitsIntra(pu, 0, CHANNEL_TYPE_LUMA);
    
                          double cost = double(minSadHad) + double(fracModeBits) * sqrtLambdaForFirstPass;
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
                          isTmpModeTestd = true;
                          if(!tmpFusionFlag && !tmpFlmFlag)
                          {
                            if(tmpBestSatdCost > cost)
                            {
                              tmpBestSatdCost = cost;
                            }
                          }
    #endif
    
    
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
                          if(tmpFlmFlag || tmpFusionFlag                   
                            || (cu.lwidth() * cu.lheight() > TMP_SKIP_REFINE_THRESHOLD))
                          {
    #endif
                            m_bestIntraSADCost = std::min(m_bestIntraSADCost, cost - double(minSadHad) + (double)sadCost);
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
                          }
    #endif
    
                          DTRACE(g_trace_ctx, D_INTRA_COST, "IntraTPM: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, 0);
    #if JVET_AD0086_ENHANCED_INTRA_TMP
    
    #if JVET_AG0136_INTRA_TMP_LIC
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
                          if(tmpFlmFlag || tmpFusionFlag || (cu.lwidth() * cu.lheight() > TMP_SKIP_REFINE_THRESHOLD))
                          {
                            updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                            updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), 0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
                          }
                          else if (cu.tmpLicFlag)
                          {
                            backupLicMinSadHad[cu.tmpIdx][cu.ibcLicIdx] = minSadHad;
                            backupLicSadCost[cu.tmpIdx][cu.ibcLicIdx] = sadCost;
                            updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), cost, uiRdModeListLicFracTmp, candCostListLicFracTmp, numModesForLicFracIntraTmp);
                          }
                          else
                          {
                            backupMinSadHad[cu.tmpIdx] = minSadHad;
                            backupSadCost[cu.tmpIdx] = sadCost;
                            updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), cost, uiRdModeListFracTmp, candCostListFracTmp, numModesForFracIntraTmp);
                          }
    #else
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx), 0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpIsSubPel, cu.tmpSubPelIdx), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpIsSubPel, cu.tmpSubPelIdx), 0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1), 0.8 * double(minSadHad), uiHadModeList, CandHadList, numHadCand);
    #endif
    #if JVET_AD0086_ENHANCED_INTRA_TMP
                        //record the best full-pel candidates
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
                        if (!tmpFlmFlag && !tmpFusionFlag && tmpLicFlag)
                        {
                          for(int idxInList=0; idxInList < uiRdModeListLicFracTmp.size(); idxInList++)
                          {
                            if(cu.lwidth() * cu.lheight() > TMP_SKIP_REFINE_THRESHOLD)
                            {
                              break;
                            }
                            if(uiRdModeListLicFracTmp[idxInList].tmpFlag)
                            {
                              updateCandList(uiRdModeListLicFracTmp[idxInList], candCostListLicFracTmp[idxInList], uiRdModeListTmpLic, candCostListTmpLic, numModesForLicFracIntraTmp);
                            }
                            if(idxInList >= numModesForFullRD && uiRdModeListTmpLic.size() >= adjustedTmpLicBvNum)
                            {
                              break;
                            }
    
    #if JVET_AI0136_ADAPTIVE_DUAL_TREE
                            if(idxInList >= (numModesForFullRD-1) && relatedCU && relatedCU->skipFracTmp)
    #else
    
                            if(idxInList >= (numModesForFullRD-1) && relatedCU.skipFracTmp)
    
    #if JVET_AG0136_INTRA_TMP_LIC
                        if (!tmpFlmFlag && !tmpFusionFlag && !tmpLicFlag)
    #else
    
                        if(!tmpFlmFlag&&!tmpFusionFlag)
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER			  
                          for(int idxInList=0; idxInList < uiRdModeListFracTmp.size(); idxInList++)
                          {
                            if(cu.lwidth() * cu.lheight() > TMP_SKIP_REFINE_THRESHOLD)
                            {
                              break;
                            }
                            if(uiRdModeListFracTmp[idxInList].tmpFlag)
                            {
                              updateCandList(uiRdModeListFracTmp[idxInList], candCostListFracTmp[idxInList], uiRdModeListTmp, candCostListTmp, numModesForFracIntraTmp);
                            }
                            if(idxInList >= numModesForFullRD && uiRdModeListTmp.size() >= adjustedTMPNonLicBvNum)
                            {
                              break;
                            }
    
    #if JVET_AI0136_ADAPTIVE_DUAL_TREE
                            if(idxInList >= (numModesForFullRD-1) && relatedCU && relatedCU->skipFracTmp)
    #else
    
                            if(idxInList >= (numModesForFullRD-1) && relatedCU.skipFracTmp)
    
                          for(int idxInList=0; idxInList < uiRdModeList.size(); idxInList++)
                          {
                            if(uiRdModeList[idxInList].tmpFlag){
    
                              updateCandList(uiRdModeList[idxInList], candCostList[idxInList], uiRdModeListTmp, candCostListTmp, numModesForFullRD);
    
    #if JVET_AG0136_INTRA_TMP_LIC
                        }
                        }
    #endif
    
                      }
                    }
                    //fractional BV
                    cu.tmpFusionFlag = false;
                    cu.tmpFlmFlag = false;
    
    #if JVET_AG0136_INTRA_TMP_LIC
                    cu.tmpLicFlag = false;
                    cu.ibcLicIdx = 0;
    #endif
    
                    for(int idxInList=0; idxInList < uiRdModeListTmp.size(); idxInList++)
                    {
                      cu.tmpIdx = uiRdModeListTmp[idxInList].tmpIdx;
                      xPadForInterpolation(&cu);
                      for(int tmpIsSubPel = 1; tmpIsSubPel < 4; tmpIsSubPel++)
                      {
                        for (int idx = 0; idx < TMP_MAX_SUBPEL_DIR; idx++)
                        {
                          cu.tmpIsSubPel = tmpIsSubPel;
                          cu.tmpSubPelIdx = idx;
                          int placeHolder;
    
                          generateTMPrediction(piPred.buf, piPred.stride, placeHolder, pu
    #if JVET_AG0136_INTRA_TMP_LIC
                                               , cu.tmpLicFlag
    #endif
                                               , false);
    
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS&&JVET_AE0169_BIPREDICTIVE_IBC
                          Distortion sadCost = distParamSad.distFunc(distParamSad);
                          Distortion minSadHad = std::min(sadCost * 2, distParamHad.distFunc(distParamHad));
    #else
    
                          Distortion minSadHad =
                              std::min(distParamSad.distFunc(distParamSad) * 2, distParamHad.distFunc(distParamHad));
    
                          uint64_t fracModeBits = xFracModeBitsIntra(pu, 0, CHANNEL_TYPE_LUMA);
    
                          double cost = double(minSadHad) + double(fracModeBits) * sqrtLambdaForFirstPass;
    
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS&&JVET_AE0169_BIPREDICTIVE_IBC
                          m_bestIntraSADCost = std::min(m_bestIntraSADCost, cost - double(minSadHad) + (double)sadCost);
    #endif
    
                          DTRACE(g_trace_ctx, D_INTRA_COST, "IntraTPM: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, 0);
    
    #if JVET_AG0136_INTRA_TMP_LIC
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx), 0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpIsSubPel, cu.tmpSubPelIdx), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                          updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpIsSubPel, cu.tmpSubPelIdx), 0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
    #endif
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
                    for(int idxInList=0; idxInList < uiRdModeListTmp.size(); idxInList++)
                    {
                      cu.tmpIdx = uiRdModeListTmp[idxInList].tmpIdx;
                      cu.tmpLicFlag = uiRdModeListTmp[idxInList].tmpLicFlag;
                      CHECK(cu.tmpLicFlag, "cu.tmpLicFlag == 1");
                      cu.ibcLicFlag = cu.tmpLicFlag;
                      cu.ibcLicIdx = uiRdModeListTmp[idxInList].tmpLicIdc;
    
    #if JVET_AI0129_INTRA_TMP_OVERLAPPING_REFINEMENT
                      searchFracCandidate(&cu, getTargetPatch(), templateType);
    #else
    
                      searchFracCandidate(&cu, getTargetPatch(floorLog2(std::max(cu.lwidth(), cu.lheight())) - 2), templateType);
    
                      for (int spIdx = 0; spIdx < std::min(2, (int) m_mtmpFracCandList[cu.tmpIdx].size()); spIdx++)
                      {
                        cu.tmpIsSubPel = m_mtmpFracCandList[cu.tmpIdx][spIdx].m_subpel;
                        cu.tmpSubPelIdx = m_mtmpFracCandList[cu.tmpIdx][spIdx].m_fracDir;
                        CHECK(cu.tmpIsSubPel < 0 || cu.tmpIsSubPel > 2, "cu.tmpIsSubPel < 1 || cu.tmpIsSubPel > 2");
                        cu.tmpFracIdx = spIdx;
    
                        Distortion sadCost;
                        Distortion minSadHad;
                        uint64_t fracModeBits = 0;
                        double cost;
                        if(cu.tmpIsSubPel)
                        {
                          int placeHolder;
                          generateTMPrediction(piPred.buf, piPred.stride, placeHolder, pu, cu.tmpLicFlag, false);
      #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS&&JVET_AE0169_BIPREDICTIVE_IBC
                          sadCost = distParamSad.distFunc(distParamSad);
                          minSadHad = std::min(sadCost * 2, distParamHad.distFunc(distParamHad));
      #else
                          minSadHad =
                              std::min(distParamSad.distFunc(distParamSad) * 2, distParamHad.distFunc(distParamHad));
      #endif
                        }
                        else
                        {
                          sadCost = backupSadCost[cu.tmpIdx];
                          minSadHad = backupMinSadHad[cu.tmpIdx];
                        }
                        if(!cu.tmpIsSubPel && !cu.tmpFracIdx)
                        {
                          cost = candCostListTmp[idxInList];
                        }
                        else
                        {
                          loadStartStates();
    
                          fracModeBits = xFracModeBitsIntra(pu, 0, CHANNEL_TYPE_LUMA);
                          cost = double(minSadHad) + double(fracModeBits) * sqrtLambdaForFirstPass;
                        }
    
                        if(tmpBestSatdCost > cost)
                        {
                          tmpBestSatdCost = cost;
                        }
    
      #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS&&JVET_AE0169_BIPREDICTIVE_IBC
                        m_bestIntraSADCost = std::min(m_bestIntraSADCost, cost - double(minSadHad) + (double)sadCost);
      #endif
                        DTRACE(g_trace_ctx, D_INTRA_COST, "IntraTPM: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, 0);
      #if JVET_AG0136_INTRA_TMP_LIC
                        updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                        updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), 0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
      #else
                        updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                        updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), 0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
      #endif
                      }
                    }
    
                    for(int idxInList=0; idxInList < uiRdModeListTmpLic.size(); idxInList++)
                    {
                      cu.tmpIdx = uiRdModeListTmpLic[idxInList].tmpIdx;
                      cu.tmpLicFlag = uiRdModeListTmpLic[idxInList].tmpLicFlag;
                      CHECK(!cu.tmpLicFlag, "cu.tmpLicFlag != 0");
                      cu.ibcLicFlag = cu.tmpLicFlag;
                      cu.ibcLicIdx = uiRdModeListTmpLic[idxInList].tmpLicIdc;
    
    #if JVET_AI0129_INTRA_TMP_OVERLAPPING_REFINEMENT
                      searchFracCandidate(&cu, getTargetPatch(), templateType);
    #else
    
                      searchFracCandidate(&cu, getTargetPatch(floorLog2(std::max(cu.lwidth(), cu.lheight())) - 2), templateType);
    
                      for (int spIdx = 0; spIdx < std::min(2, (int) m_mtmpFracCandList[cu.tmpIdx].size()); spIdx++)
                      {
                        cu.tmpIsSubPel = m_mtmpFracCandList[cu.tmpIdx][spIdx].m_subpel;
                        cu.tmpSubPelIdx = m_mtmpFracCandList[cu.tmpIdx][spIdx].m_fracDir;
                        CHECK(cu.tmpIsSubPel < 0 || cu.tmpIsSubPel > 2, "cu.tmpIsSubPel < 1 || cu.tmpIsSubPel > 2");
                        cu.tmpFracIdx = spIdx;
    
                        Distortion sadCost;
                        Distortion minSadHad;
                        uint64_t fracModeBits = 0;
                        double cost;
                        if(cu.tmpIsSubPel)
                        {
                          int placeHolder;
                          generateTMPrediction(piPred.buf, piPred.stride, placeHolder, pu, cu.tmpLicFlag, false);
    
                          if (cu.tmpLicFlag)
                          {
                            PelBuf bufDumb;
                            pcInterPred->LicItmp(pu, bufDumb, false);
                            const auto& arrayLicParams = pcInterPred->getArrayLicParams();
                            if (cu.ibcLicIdx == IBC_LIC_IDX_M)
                            {
                              piPred.linearTransforms(arrayLicParams[1], arrayLicParams[0], arrayLicParams[2], arrayLicParams[4], arrayLicParams[3], arrayLicParams[5], arrayLicParams[6], true, cu.cs->slice->clpRng(COMPONENT_Y));
                            }
                            else
                            {
                              piPred.linearTransform(arrayLicParams[1], arrayLicParams[0], arrayLicParams[2], true, cu.cs->slice->clpRng(COMPONENT_Y));
                            }
                          }
    
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS&&JVET_AE0169_BIPREDICTIVE_IBC
                          sadCost = distParamSad.distFunc(distParamSad);
                          minSadHad = std::min(sadCost * 2, distParamHad.distFunc(distParamHad));
    #else
                          minSadHad =
                              std::min(distParamSad.distFunc(distParamSad) * 2, distParamHad.distFunc(distParamHad));
    #endif
                        }
                        else
                        {
                          sadCost = backupLicSadCost[cu.tmpIdx][cu.ibcLicIdx];
                          minSadHad = backupLicMinSadHad[cu.tmpIdx][cu.ibcLicIdx];                  
                        }
                        if(!cu.tmpIsSubPel && !cu.tmpFracIdx)
                        {
                          cost = candCostListTmpLic[idxInList];
                        }
                        else
                        {
                          loadStartStates();
    
                          fracModeBits = xFracModeBitsIntra(pu, 0, CHANNEL_TYPE_LUMA);
                          cost = double(minSadHad) + double(fracModeBits) * sqrtLambdaForFirstPass;
                        }
                        if(tmpBestSatdCost > cost)
                        {
                          tmpBestSatdCost = cost;
                        }
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS&&JVET_AE0169_BIPREDICTIVE_IBC
                        m_bestIntraSADCost = std::min(m_bestIntraSADCost, cost - double(minSadHad) + (double)sadCost);
    #endif
                        DTRACE(g_trace_ctx, D_INTRA_COST, "IntraTPM: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, 0);
                        updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), cost, uiRdModeList, candCostList, numModesForFullRD);
    
                        updateCandList(ModeInfo(0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1, cu.tmpIdx, cu.tmpFusionFlag, cu.tmpFlmFlag, cu.tmpLicFlag, cu.ibcLicIdx, cu.tmpIsSubPel, cu.tmpSubPelIdx, cu.tmpFracIdx), 0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
    #if JVET_AD0086_ENHANCED_INTRA_TMP
                  cu.tmpFlag       = 0;
                  cu.tmpFusionFlag = false;
                  cu.tmpFlmFlag    = false;
    
    #if JVET_AG0136_INTRA_TMP_LIC
                  cu.tmpLicFlag    = false;
                  cu.ibcLicFlag    = false;
                  cu.ibcLicIdx     = 0;
    #endif
    
    #if JVET_AG0136_INTRA_TMP_LIC
                  cu.tmpSubPelIdx  = -1;
    #else
    
    #if JVET_AH0200_INTRA_TMP_BV_REORDER
                  cu.tmpFracIdx    = -1;
    #endif
    
                if (LFNSTSaveFlag && testMip
                    && !allowLfnstWithMip(cu.firstPU->lumaSize()))   // save a different set for the next run
                {
                  // save found best modes
                  m_uiSavedRdModeListLFNST = uiRdModeList;
    
                  m_dSavedModeCostLFNST    = candCostList;
    
                  // PBINTRA fast
                  m_uiSavedHadModeListLFNST = uiHadModeList;
    
                  m_uiSavedNumRdModesLFNST =
                    g_aucIntraModeNumFast_UseMPM_2D[uiWidthBit - MIN_CU_LOG2][uiHeightBit - MIN_CU_LOG2];
                  m_uiSavedRdModeListLFNST.resize(m_uiSavedNumRdModesLFNST);
                  m_dSavedModeCostLFNST.resize(m_uiSavedNumRdModesLFNST);
                  // PBINTRA fast
                  m_uiSavedHadModeListLFNST.resize(3);
                  m_dSavedHadListLFNST.resize(3);
                  LFNSTSaveFlag = false;
                }
    
    #if JVET_V0130_INTRA_TMP && !JVET_AB0130_ITMP_SAMPLING
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                // derive TPM candidate using hadamard
                if( testTpm )
                {
                  cu.tmpFlag = true;
                  cu.mipFlag = false;
                  pu.multiRefIdx = 0;
    
    #if JVET_AB0157_TMRL
                  cu.tmrlFlag = false;
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                  int foundCandiNum = 0;
                  bool bsuccessfull = 0;
                  CodingUnit cu_cpy = cu;
    
    
    #if JVET_W0069_TMP_BOUNDARY
    
                  RefTemplateType templateType = getRefTemplateType( cu_cpy, cu_cpy.blocks[COMPONENT_Y] );
                  if( templateType != NO_TEMPLATE )
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                  if( isRefTemplateAvailable( cu_cpy, cu_cpy.blocks[COMPONENT_Y] ) )
    
    #endif
    
    #if JVET_W0069_TMP_BOUNDARY
    
                    getTargetTemplate( &cu_cpy, pu.lwidth(), pu.lheight(), templateType );
                    candidateSearchIntra( &cu_cpy, pu.lwidth(), pu.lheight(), templateType );
                    bsuccessfull = generateTMPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum );
    
                    getTargetTemplate( &cu_cpy, pu.lwidth(), pu.lheight() );
                    candidateSearchIntra( &cu_cpy, pu.lwidth(), pu.lheight() );
                    bsuccessfull = generateTMPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum );
    
    #endif
    
    #if JVET_W0069_TMP_BOUNDARY
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                  else
                  {
                    foundCandiNum = 1;
    
                    bsuccessfull = generateTmDcPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), 1 << (cu_cpy.cs->sps->getBitDepth( CHANNEL_TYPE_LUMA ) - 1) );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                  }
    
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                  if( bsuccessfull && foundCandiNum >= 1 )
                  {
    
                    Distortion minSadHad =
                      std::min( distParamSad.distFunc( distParamSad ) * 2, distParamHad.distFunc( distParamHad ) );
    
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                    uint64_t fracModeBits = xFracModeBitsIntra( pu, 0, CHANNEL_TYPE_LUMA );
    
                    double cost = double( minSadHad ) + double( fracModeBits ) * sqrtLambdaForFirstPass;
                    DTRACE( g_trace_ctx, D_INTRA_COST, "IntraTPM: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, 0 );
    
    
                    updateCandList( ModeInfo( 0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1 ), cost, uiRdModeList, candCostList, numModesForFullRD );
    
                    updateCandList( ModeInfo( 0, 0, 0, NOT_INTRA_SUBPARTITIONS, 0, 1 ), 0.8 * double( minSadHad ), uiHadModeList, candHadList, numHadCand );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
                //*** Derive MIP candidates using Hadamard
                if (testMip && !supportedMipBlkSize)
                {
                  // avoid estimation for unsupported blk sizes
                  const int transpOff    = getNumModesMip(pu.Y());
                  const int numModesFull = (transpOff << 1);
                  for (uint32_t uiModeFull = 0; uiModeFull < numModesFull; uiModeFull++)
                  {
                    const bool     isTransposed = (uiModeFull >= transpOff ? true : false);
                    const uint32_t uiMode       = (isTransposed ? uiModeFull - transpOff : uiModeFull);
    
                    numModesForFullRD++;
                    uiRdModeList.push_back(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, uiMode));
    
                    candCostList.push_back(0);
    
                  }
                }
                else if (testMip)
                {
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if JVET_V0130_INTRA_TMP
                  cu.tmpFlag = 0;
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
                  cu.mipFlag     = true;
                  pu.multiRefIdx = 0;
    
    #if JVET_AB0157_TMRL
                  cu.tmrlFlag = false;
    #endif
    
                  double mipHadCost[MAX_NUM_MIP_MODE] = { MAX_DOUBLE };
    
    #if JVET_AB0157_INTRA_FUSION && JVET_AB0155_SGPM
    
    #if JVET_AJ0249_NEURAL_NETWORK_BASED
                  initIntraPatternChType(cu, pu.Y(), false, 0, false, false, true);
    #else
    
                  initIntraPatternChType(cu, pu.Y(), false, 0, false);
    
    #elif JVET_AB0157_INTRA_FUSION
                  initIntraPatternChType(cu, pu.Y(), false, false);
    #else
    
                  initIntraPatternChType(cu, pu.Y());
    
                  initIntraMip(pu, pu.Y());
    
                  const int transpOff    = getNumModesMip(pu.Y());
                  const int numModesFull = (transpOff << 1);
                  for (uint32_t uiModeFull = 0; uiModeFull < numModesFull; uiModeFull++)
                  {
                    const bool     isTransposed = (uiModeFull >= transpOff ? true : false);
                    const uint32_t uiMode       = (isTransposed ? uiModeFull - transpOff : uiModeFull);
    
                    pu.mipTransposedFlag           = isTransposed;
                    pu.intraDir[CHANNEL_TYPE_LUMA] = uiMode;
                    predIntraMip(COMPONENT_Y, piPred, pu);
    
                    // Use the min between SAD and HAD as the cost criterion
                    // SAD is scaled by 2 to align with the scaling of HAD
    
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
                    Distortion sadCost = distParamSad.distFunc(distParamSad);
                    Distortion minSadHad = std::min(sadCost * 2, distParamHad.distFunc(distParamHad));
    #else
    
                    Distortion minSadHad =
                      std::min(distParamSad.distFunc(distParamSad) * 2, distParamHad.distFunc(distParamHad));
    
                    uint64_t fracModeBits = xFracModeBitsIntra(pu, uiMode, CHANNEL_TYPE_LUMA);
    
                    double cost            = double(minSadHad) + double(fracModeBits) * sqrtLambdaForFirstPass;
    
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
                    m_bestIntraSADCost = std::min(m_bestIntraSADCost, cost - double(minSadHad) + (double)sadCost);
    #endif
    
                    mipHadCost[uiModeFull] = cost;
                    DTRACE(g_trace_ctx, D_INTRA_COST, "IntraMIP: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost,
                           uiModeFull);
    
                    updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, uiMode), cost, uiRdModeList,
    
                                   candCostList, numModesForFullRD + 1);
    
                    updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, uiMode),
    
                                   0.8 * double(minSadHad), uiHadModeList, candHadList, numHadCand);
    
    #if !JVET_AJ0061_TIMD_MERGE
    
                  const double thresholdHadCost = 1.0 + 1.4 / sqrt((double) (pu.lwidth() * pu.lheight()));
    
                  reduceHadCandList(uiRdModeList, candCostList, numModesForFullRD, thresholdHadCost, mipHadCost, pu,
    
                                    fastMip
    #if JVET_AB0157_TMRL
                    , tmrlCostList
    
    #endif
    #if JVET_AC0105_DIRECTIONAL_PLANAR
                    , dirPlanarCostList
    
    #else
                  std::memcpy(mipHadCostStore, mipHadCost, MAX_NUM_MIP_MODE * sizeof(double));
    #endif
    
    #if JVET_AH0076_OBIC
                if (obicSaveFlag || dimdSaveFlag)
                {
                  cu.dimd = false;
                  cu.timd = false;
                  cu.mipFlag = false;
                  pu.multiRefIdx = 0;
    #if JVET_V0130_INTRA_TMP
                  cu.tmpFlag = false;
    #endif
                  cu.sgpm = false;
    #if JVET_AB0157_INTRA_FUSION
                  initIntraPatternChType(cu, pu.Y(), true, 0, false);
    #else
                  initIntraPatternChType(cu, pu.Y(), true);
    #endif
                  if (obicSaveFlag)
                  {
                    for (int idx = 0; idx < OBIC_FUSION_NUM; idx++)
                    {
                      int iMode = cu.obicMode[idx];
                      if (iMode < 0)
                      {
                        continue;
                      }
                      if (dimdNeededMode[iMode] && !m_intraModeReady[iMode])
                      {
                        pu.intraDir[0] = iMode;
                        initPredIntraParams(pu, pu.Y(), sps);
    #if JVET_AB0157_INTRA_FUSION
    
    #if JVET_AH0209_PDP
                        predIntraAng( COMPONENT_Y, piPred, pu, false, false );
    #else
    
                        predIntraAng(COMPONENT_Y, piPred, pu, false);
    
    #else
                        predIntraAng(COMPONENT_Y, piPred, pu);
    #endif
                        PelBuf predBuf(m_intraPredBuf[iMode], tmpArea);
                        predBuf.copyFrom(piPred);
                        m_intraModeReady[iMode] = 1;
                      }
                    }
                  }
                  if (dimdSaveFlag)
                  {
                    if (dimdNeededMode[PLANAR_IDX] && !m_intraModeReady[PLANAR_IDX])
                    {
                      pu.intraDir[0] = PLANAR_IDX;
                      initPredIntraParams(pu, pu.Y(), sps);
    #if JVET_AB0157_INTRA_FUSION
    
    #if JVET_AH0209_PDP
                      predIntraAng( COMPONENT_Y, piPred, pu, false, false );
    #else
    
                      predIntraAng(COMPONENT_Y, piPred, pu, false);
    
    #else
                      predIntraAng(COMPONENT_Y, piPred, pu);
    #endif
                      PelBuf predBuf(m_intraPredBuf[PLANAR_IDX], tmpArea);
                      predBuf.copyFrom(piPred);
                      m_intraModeReady[PLANAR_IDX] = 1;
                    }
                  }
                  for (int dimdIdx = 0; dimdIdx < DIMD_FUSION_NUM - 1; dimdIdx++)
                  {
    
                    int dimdMode = (dimdIdx == 0 ? cu.dimdMode : cu.dimdBlendMode[dimdIdx-1]);
    
    #if JVET_AH0209_PDP
                    if (dimdNeededMode[dimdMode] && !m_intraModeReady[dimdMode] && !m_pdpIntraPredReady[dimdMode])
    #else
    
                    if (dimdNeededMode[dimdMode] && !m_intraModeReady[dimdMode])
    
                    {
                      pu.intraDir[0] = dimdMode;
                      initPredIntraParams(pu, pu.Y(), sps);
    #if JVET_AB0157_INTRA_FUSION
    
    #if JVET_AH0209_PDP
                      predIntraAng( COMPONENT_Y, piPred, pu, false, false );
    #else
    
                      predIntraAng(COMPONENT_Y, piPred, pu, false);
    
    #else
                      predIntraAng(COMPONENT_Y, piPred, pu);
    #endif
                      PelBuf predBuf(m_intraPredBuf[dimdMode], tmpArea);
                      predBuf.copyFrom(piPred);
                      m_intraModeReady[dimdMode] = 1;
                    }
                  }
                }
    
    #endif
    #if JVET_AJ0061_TIMD_MERGE
                m_skipDimdMode = !testDimd;
                m_skipObicMode = !testObic;
                m_skipDimdLfnstMtsPass = !testDimd;
                m_skipObicLfnstMtsPass = !testObic;
                m_skipTimdMode[Timd]      = !testTimd;
                m_skipTimdMode[TimdMrg]   = !testTimdMerge;
                m_skipTimdMode[TimdMrl1]  = !testTimdMrl;
                m_skipTimdMode[TimdMrl3]  = !testTimdMrl;
                m_skipTimdLfnstMtsPass    = !testTimd;
                m_skipTimdMrgLfnstMtsPass = !testTimdMerge;
    #if JVET_AH0076_OBIC
                if (obicSaveFlag || dimdSaveFlag)
                {
                  cu.dimd = true;
                  cu.obicFlag = false;
                  cu.timd = false;
                  cu.mipFlag = false;
                  cu.tmpFlag = false;
                  cu.tmrlFlag = false;
                  cu.firstPU->multiRefIdx = 0;
                  cu.ispMode = NOT_INTRA_SUBPARTITIONS;
                  int iWidth = cu.lwidth();
                  int iHeight = cu.lheight();
                  if (obicSaveFlag)
                  {
                    cu.obicFlag = true;
                    int obicMode = cu.obicMode[0];
                    pu.intraDir[CHANNEL_TYPE_LUMA] = obicMode;
                    bool blendModes[OBIC_FUSION_NUM - 1] = {false};
                    PelBuf predFusion[OBIC_FUSION_NUM - 1];
    #if JVET_AH0209_PDP
                   CHECK(!m_intraModeReady[obicMode] && !m_pdpIntraPredReady[obicMode], "OBIC mode is not ready!");
    #else
                    CHECK(!m_intraModeReady[obicMode], "OBIC mode is not ready!");
    #endif
                   const UnitArea localUnitArea( pu.chromaFormat, Area( 0, 0, iWidth, iHeight ) );
    #if JVET_AH0209_PDP
                    PelBuf predBuf(m_pdpIntraPredReady[obicMode]? m_pdpIntraPredBuf[obicMode]: m_intraPredBuf[obicMode], pu.Y());
    #else
                   PelBuf predBuf(m_intraPredBuf[obicMode], pu.Y());
    #endif
                    piPred.copyFrom(predBuf);
                    int planarIdx = 0;
                    for (int idx = 0; idx < OBIC_FUSION_NUM - 1; idx++)
                    {
                      blendModes[idx] = false;
                      predFusion[idx] = m_tempBuffer[idx].getBuf( localUnitArea.Y() );
                      int iMode = cu.obicMode[idx + 1];
                      if (iMode >= 0)
                      {
                        blendModes[idx] = true;
                        CHECK(!m_intraModeReady[iMode], "OBIC mode is not ready!");
                        PelBuf predBufTmp(m_intraPredBuf[iMode], pu.Y());
                        predFusion[idx].copyFrom(predBufTmp);
                        if (iMode == PLANAR_IDX)
                        {
                          planarIdx = idx;
                        }
                      }
                      else
                      {
                        PelBuf planarBuf(m_intraPredBuf[PLANAR_IDX], pu.Y());
                        predFusion[idx].copyFrom(planarBuf);
                      }
                    }
                    if (cu.obicIsBlended)
                    {
                      generateObicBlending(piPred, pu, predFusion, blendModes, planarIdx);
                    }
                    else
                    {
                      initIntraPatternChType(cu, pu.Y(), false);
                      predIntraAng(COMPONENT_Y, piPred, pu);
                    }
                    PelBuf obicSaveBuf(m_obicPredBuf, pu.Y());
                    obicSaveBuf.copyFrom(piPred);
    
    #if JVET_AJ0249_NEURAL_NETWORK_BASED
                    m_isObicPredictionSaved = true;
    #endif
    
                    Distortion sadCost = distParamSad.distFunc(distParamSad);
                    Distortion minSadHadObic = std::min(sadCost * 2, distParamHad.distFunc(distParamHad));
                    m_satdCostOBIC = minSadHadObic;
                  }
                  if (dimdSaveFlag)
                  {
                    cu.obicFlag = false;
                    int dimdMode = cu.dimdMode;
                    pu.intraDir[CHANNEL_TYPE_LUMA] = dimdMode;
                    if (cu.dimdBlending)
                    {
    #if JVET_AH0209_PDP
                      PelBuf predBuf(m_pdpIntraPredReady[dimdMode]? m_pdpIntraPredBuf[dimdMode] : m_intraPredBuf[dimdMode], tmpArea);
    #else
                     PelBuf predBuf(m_intraPredBuf[dimdMode], tmpArea);
    #endif
                      piPred.copyFrom(predBuf);
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if JVET_AJ0267_ADAPTIVE_HOG
                      PelBuf predFusion[ DIMD_FUSION_NUM - 2 ];
                      const UnitArea localUnitArea( pu.chromaFormat, Area( 0, 0, iWidth, iHeight ) );
                      for( int i = 0; i < DIMD_FUSION_NUM - 2; i++ )
                      {
                        predFusion[ i ] = m_tempBuffer[ i + 1 ].getBuf( localUnitArea.Y() );
    #if JVET_AH0209_PDP
                        dimdMode = cu.dimdBlendMode[ i ] > 0 ? cu.dimdBlendMode[ i ] : PLANAR_IDX;
                        PelBuf predBufTmp( dimdMode && m_pdpIntraPredReady[ dimdMode ] ? m_pdpIntraPredBuf[ dimdMode ] : m_intraPredBuf[ dimdMode ], tmpArea );
    #else
                        PelBuf predBufTmp( ( m_intraPredBuf[ cu.dimdBlendMode[ i ] > 0 ? cu.dimdBlendMode[ i ] : PLANAR_IDX ] ), tmpArea );
    #endif
                        predFusion[ i ].copyFrom( predBufTmp );
                      }
                      PelBuf planarBuf( m_intraPredBuf[ PLANAR_IDX ], tmpArea );
                      generateDimdBlending( piPred, pu, predFusion, planarBuf );
    #else
    
    #if JVET_AH0209_PDP
                      dimdMode = cu.dimdBlendMode[0] > 0 ? cu.dimdBlendMode[0] : PLANAR_IDX;
                      PelBuf blendBuf0(dimdMode && m_pdpIntraPredReady[dimdMode] ? m_pdpIntraPredBuf[dimdMode] : m_intraPredBuf[dimdMode], tmpArea);
                      dimdMode = cu.dimdBlendMode[1] > 0 ? cu.dimdBlendMode[1] : PLANAR_IDX;
                      PelBuf blendBuf1(dimdMode && m_pdpIntraPredReady[dimdMode] ? m_pdpIntraPredBuf[dimdMode] : m_intraPredBuf[dimdMode], tmpArea);
                      dimdMode = cu.dimdBlendMode[2] > 0 ? cu.dimdBlendMode[2] : PLANAR_IDX;
                      PelBuf blendBuf2(dimdMode && m_pdpIntraPredReady[dimdMode] ? m_pdpIntraPredBuf[dimdMode] : m_intraPredBuf[dimdMode], tmpArea);
                      dimdMode = cu.dimdBlendMode[3] > 0 ? cu.dimdBlendMode[3] : PLANAR_IDX;
                      PelBuf blendBuf3(dimdMode && m_pdpIntraPredReady[dimdMode] ? m_pdpIntraPredBuf[dimdMode] : m_intraPredBuf[dimdMode], tmpArea);
                      PelBuf planarBuf(m_intraPredBuf[PLANAR_IDX], tmpArea);
      #else
                      PelBuf blendBuf0((m_intraPredBuf[cu.dimdBlendMode[0] > 0 ?cu.dimdBlendMode[0] : PLANAR_IDX]), tmpArea);
                      PelBuf blendBuf1((m_intraPredBuf[cu.dimdBlendMode[1] > 0 ?cu.dimdBlendMode[1] : PLANAR_IDX]), tmpArea);
                      PelBuf blendBuf2((m_intraPredBuf[cu.dimdBlendMode[2] > 0 ?cu.dimdBlendMode[2] : PLANAR_IDX]), tmpArea);
                      PelBuf blendBuf3((m_intraPredBuf[cu.dimdBlendMode[3] > 0 ?cu.dimdBlendMode[3] : PLANAR_IDX]), tmpArea);
                      PelBuf planarBuf(m_intraPredBuf[PLANAR_IDX], tmpArea);
      #endif
                      generateDimdBlending(piPred, pu, blendBuf0, blendBuf1, blendBuf2, blendBuf3, planarBuf);
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
                    }
                    else
                    {
                      initIntraPatternChType(cu, pu.Y(), false);
                      predIntraAng(COMPONENT_Y, piPred, pu);
                    }
                    PelBuf dimdSaveBuf(m_dimdPredBuf, pu.Y());
                    dimdSaveBuf.copyFrom(piPred);
    
    #if JVET_AJ0249_NEURAL_NETWORK_BASED
                    m_isDimdPredictionSaved = true;
    #endif
    
                    Distortion sadCost = distParamSad.distFunc(distParamSad);
                    Distortion minSadHadDimd = std::min(sadCost * 2, distParamHad.distFunc(distParamHad));
                    m_satdCostDIMD = minSadHadDimd;
                  }
                }
                cu.dimd = false;
                cu.obicFlag = false;
    #endif
                if (!cu.lfnstIdx && !cu.mtsFlag && testMip)
                {
                  // now reduce the candidates
                  const double thresholdHadCost = 1.0 + 1.4 / sqrt((double) (pu.lwidth() * pu.lheight()));
                  reduceHadCandList(uiRdModeList, candCostList, numModesForFullRD, thresholdHadCost, mipHadCostStore, pu, fastMip
    #if JVET_AB0157_TMRL
                   , tmrlCostList
    #endif
    #if JVET_AC0105_DIRECTIONAL_PLANAR
                    , dirPlanarCostList
    
    #endif
    #if JVET_AJ0146_TIMDSAD
                    , (modList ? 1 : 0)
    
                if (sps.getUseMIP() && LFNSTSaveFlag)
    
                  // save found best modes
                  m_uiSavedNumRdModesLFNST = numModesForFullRD;
                  m_uiSavedRdModeListLFNST = uiRdModeList;
    
                  m_dSavedModeCostLFNST    = candCostList;
    
                  // PBINTRA fast
                  m_uiSavedHadModeListLFNST = uiHadModeList;
    
                  LFNSTSaveFlag             = false;
    
    #if JVET_AJ0061_TIMD_MERGE
                  m_uiSavedRdModeListTimd   = timdModes;
                  m_uiSavedModeCostTimd     = timdCosts;
                  for (int i = numTimdSatd - 1; i >= 0; i--)
                  {
                    if(timdModes[i].mRefId > 0)
                    {
                      m_uiSavedRdModeListTimd.erase(m_uiSavedRdModeListTimd.begin() + i);
                      m_uiSavedModeCostTimd.erase(m_uiSavedModeCostTimd.begin() + i);
                    }
                  }
                  ModeInfo m;
                  for (int i = numModesForFullRD - 1; i >= 0; i--)
                  {
                    m = m_uiSavedRdModeListLFNST.at(i);
                    if (m.modeId == TIMD_IDX && m.mRefId)
                    {
                      m_uiSavedRdModeListLFNST.erase(m_uiSavedRdModeListLFNST.begin() + i);
                      m_dSavedModeCostLFNST.erase(m_dSavedModeCostLFNST.begin() + i);
                      m_uiSavedNumRdModesLFNST--;
                    }
                  }
                  for (int i = (int)(uiHadModeList.size()) - 1; i >= 0; i--)
                  {
                    m = m_uiSavedHadModeListLFNST.at(i);
                    if (m.modeId == TIMD_IDX && m.mRefId)
                    {
                      m_uiSavedHadModeListLFNST.erase(m_uiSavedHadModeListLFNST.begin() + i);
                      m_dSavedHadListLFNST.erase(m_dSavedHadListLFNST.begin() + i);
                    }
                  }
    #endif
    
              else   // if( sps.getUseMIP() && LFNSTLoadFlag)
              {
                // restore saved modes
                numModesForFullRD = m_uiSavedNumRdModesLFNST;
                uiRdModeList      = m_uiSavedRdModeListLFNST;
    
                candCostList      = m_dSavedModeCostLFNST;
    
                // PBINTRA fast
                uiHadModeList = m_uiSavedHadModeListLFNST;
    
    #if JVET_AJ0061_TIMD_MERGE
                timdModes     = m_uiSavedRdModeListTimd;
                timdCosts     = m_uiSavedModeCostTimd;
                if (cu.mtsFlag)
                {
                  for (int i = (int)timdModes.size() - 1; i >= 0; i--)
                  {
                    if (timdModes[i].modeId == TIMDM_IDX)
                    {
                      timdModes.erase(timdModes.begin() + i);
                      timdCosts.erase(timdCosts.begin() + i);
                    }
                  }
                }
    #endif
    
    #if JVET_AH0076_OBIC && !JVET_AJ0061_TIMD_MERGE
    
              if (obicSaveFlag || dimdSaveFlag)
              {
                cu.dimd = true;
                cu.obicFlag = false;
                cu.timd = false;
                cu.mipFlag = false;
                cu.tmpFlag = false;
                cu.tmrlFlag = false;
                cu.firstPU->multiRefIdx = 0;
                cu.ispMode = NOT_INTRA_SUBPARTITIONS;