Skip to content
Snippets Groups Projects
IntraSearch.cpp 316 KiB
Newer Older
  • Learn to ignore specific revisions
  • bool IntraSearch::updateISPStatusFromRelCU( double bestNonISPCostCurrCu, ModeInfo bestNonISPModeCurrCu, int& bestISPModeInRelCU )
    {
      //It compares the data of a related CU with the current CU to cancel or reduce the ISP tests
      bestISPModeInRelCU = -1;
      if (m_modeCtrl->getRelatedCuIsValid())
      {
        double bestNonISPCostRelCU = m_modeCtrl->getBestDCT2NonISPCostRelCU();
        double costRatio           = bestNonISPCostCurrCu / bestNonISPCostRelCU;
        bool   bestModeRelCuIsMip  = (m_modeCtrl->getIspPredModeValRelCU() >> 5) & 0x1;
        bool   bestModeCurrCuIsMip = bestNonISPModeCurrCu.mipFlg;
        int    relatedCuIntraMode  = m_modeCtrl->getIspPredModeValRelCU() >> 9;
        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));
        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();
          }
        }
      }
    }