Skip to content
Snippets Groups Projects
IntraSearch.cpp 565 KiB
Newer Older
  • Learn to ignore specific revisions
  •     bool   modesAreComparable = isSameTypeOfMode && (bestModeCurrCuIsMip || bestModeCurrCuIsAeip ||
          bestNonISPModeCurrCu.modeId == relatedCuIntraMode || (bothModesAreAngular && abs(relatedCuIntraMode - (int)bestNonISPModeCurrCu.modeId) <= 5));
    #else
        bool   isSameTypeOfMode = (bestModeRelCuIsMip && bestModeCurrCuIsMip) || (!bestModeRelCuIsMip && !bestModeCurrCuIsMip);
    
        bool   bothModesAreAngular = bestNonISPModeCurrCu.modeId > DC_IDX && relatedCuIntraMode > DC_IDX;
    
        bool   modesAreComparable = isSameTypeOfMode && (bestModeCurrCuIsMip || bestNonISPModeCurrCu.modeId == relatedCuIntraMode || (bothModesAreAngular && abs(relatedCuIntraMode - (int)bestNonISPModeCurrCu.modeId) <= 5));
    #endif
    
        int    status              = m_modeCtrl->getIspPredModeValRelCU();
    
        if ((status & 0x3) == 0x3) //ISP was not selected in the relCU
        {
          double bestNonDCT2Cost = m_modeCtrl->getBestNonDCT2Cost();
          double ratioWithNonDCT2 = bestNonDCT2Cost / bestNonISPCostRelCU;
          double margin = ratioWithNonDCT2 < 0.95 ? 0.2 : 0.1;
    
          if (costRatio > 1 - margin && costRatio < 1 + margin && modesAreComparable)
          {
            for (int lfnstVal = 0; lfnstVal < NUM_LFNST_NUM_PER_SET; lfnstVal++)
            {
              m_ispTestedModes[lfnstVal].splitIsFinished[HOR_INTRA_SUBPARTITIONS - 1] = true;
              m_ispTestedModes[lfnstVal].splitIsFinished[VER_INTRA_SUBPARTITIONS - 1] = true;
            }
            return false;
          }
        }
        else if ((status & 0x3) == 0x1) //ISP was selected in the relCU
        {
          double margin = 0.05;
    
          if (costRatio > 1 - margin && costRatio < 1 + margin && modesAreComparable)
          {
            int  ispSplitIdx = (m_modeCtrl->getIspPredModeValRelCU() >> 2) & 0x1;
            bool lfnstIdxIsNot0 = (bool)((m_modeCtrl->getIspPredModeValRelCU() >> 3) & 0x1);
            bool lfnstIdxIs2 = (bool)((m_modeCtrl->getIspPredModeValRelCU() >> 4) & 0x1);
            int  lfnstIdx = !lfnstIdxIsNot0 ? 0 : lfnstIdxIs2 ? 2 : 1;
            bestISPModeInRelCU = (int)m_modeCtrl->getBestISPIntraModeRelCU();
    
            for (int splitIdx = 0; splitIdx < NUM_INTRA_SUBPARTITIONS_MODES - 1; splitIdx++)
            {
              for (int lfnstVal = 0; lfnstVal < NUM_LFNST_NUM_PER_SET; lfnstVal++)
              {
                if (lfnstVal == lfnstIdx && splitIdx == ispSplitIdx)
                {
                  continue;
                }
                m_ispTestedModes[lfnstVal].splitIsFinished[splitIdx] = true;
              }
            }
    
            bool stopNonDCT2Transforms = (bool)((m_modeCtrl->getIspPredModeValRelCU() >> 6) & 0x1);
            m_modeCtrl->setStopNonDCT2Transforms(stopNonDCT2Transforms);
          }
        }
        else
        {
          THROW("Wrong ISP relCU status");
        }
      }
    
      return true;
    }
    
    void IntraSearch::xFinishISPModes()
    {
    
      //Continue to the next lfnst index
    
      m_curIspLfnstIdx++;
    
      if (m_curIspLfnstIdx < NUM_LFNST_NUM_PER_SET)
      {
        //Check if LFNST is applicable
        if (m_curIspLfnstIdx == 1)
        {
          bool canTestLFNST = false;
          for (int lfnstIdx = 1; lfnstIdx < NUM_LFNST_NUM_PER_SET; lfnstIdx++)
          {
            canTestLFNST |= !m_ispTestedModes[lfnstIdx].splitIsFinished[HOR_INTRA_SUBPARTITIONS - 1] || !m_ispTestedModes[lfnstIdx].splitIsFinished[VER_INTRA_SUBPARTITIONS - 1];
          }
          if (canTestLFNST)
          {
            //Construct the intra modes candidates list for the lfnst > 0 cases
            xSortISPCandListLFNST();
          }
        }
      }
    }
    
    void IntraSearch::setLumaIntraPredIdx(PredictionUnit& pu)
    {
    #if SECONDARY_MPM
      const int numMPMs = NUM_PRIMARY_MOST_PROBABLE_MODES + NUM_SECONDARY_MOST_PROBABLE_MODES;
    #else
      const int numMPMs = NUM_MOST_PROBABLE_MODES;
    #endif
      int pred_idx = numMPMs;
      for (int idx = 0; idx < numMPMs; idx++)
      {
        if (pu.intraDir[0] == m_intraMPM[idx])
        {
          pred_idx = idx;
          break;
        }
      }
    #if SECONDARY_MPM
      if (pred_idx < NUM_PRIMARY_MOST_PROBABLE_MODES)
      {
        pu.mpmFlag = true;
        pu.secondMpmFlag = false;
      }
      else if (pred_idx < numMPMs)
      {
        pu.mpmFlag = false;
        pu.secondMpmFlag = true;
      }
      else
      {
        pu.mpmFlag = false;
        pu.secondMpmFlag = false;
        pred_idx = NUM_NON_MPM_MODES;
        for (int idx = 0; idx < NUM_NON_MPM_MODES; idx++)
        {
          if (pu.intraDir[0] == m_intraNonMPM[idx])
          {
            pred_idx = idx;
            break;
          }
        }
    
      }
    #else
      if (mpm_idx < NUM_MOST_PROBABLE_MODES)
      {
        pu.mpmFlag = true;
      }
      else
      {
        std::sort(mpmPred, mpmPred + numMPMs);
        int pred_idx = pu.intraDir[0];
        for (int idx = numMPMs - 1; idx >= 0; idx--)
        {
          if (pred_idx > mpmPred[idx])
          {
            pred_idx--;
          }
        }
        CHECK(pred_idx >= 64, "Incorrect mode");
      }
    #endif
      pu.ipredIdx = pred_idx;
    }