VTM3.0代碼學習:predIntraAng函數

今天來學習一下幀內預測函數predIntraAng,用於生成幀內預測圖像。

輸入參數:

 const ComponentID compId //In 顏色分量
 PelBuf &piPred 			  //In/Out 預測圖像
 const PredictionUnit &pu      //In 當前PU 
 const bool useFilteredPredSamples  //In 是否進行濾波

相比HEVC新加入的技術:
1.幀內多參考行
2.PDPC

主要流程
1.初始化。
2.根據傳入角度值調用對應預測函數:xPredIntraPlanar(PLANAR模式)、xPredIntraDc(DC模式)、xPredIntraAng(角度模式)。
3.PLANAR、DC、HOR、VER角度和參考行索引爲0時,進行PDPC。

代碼:

//角度預測
void IntraPrediction::predIntraAng( const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu, const bool useFilteredPredSamples )
{
  const ComponentID    compID       = MAP_CHROMA( compId );	
  const ChannelType    channelType  = toChannelType( compID );
  const int            iWidth       = piPred.width;
  const int            iHeight      = piPred.height;
  const uint32_t           uiDirMode    = PU::getFinalIntraMode( pu, channelType );


  CHECK( g_aucLog2[iWidth] < 2 && pu.cs->pcv->noChroma2x2, "Size not allowed" );
  CHECK( g_aucLog2[iWidth] > 7, "Size not allowed" );
  CHECK( iWidth != iHeight && !pu.cs->pcv->rectCUs, "Rectangular block are only allowed with QTBT" );

#if JVET_L0283_MULTI_REF_LINE
  const int  multiRefIdx = (compID == COMPONENT_Y) ? pu.multiRefIdx : 0;	//多參考行,只在亮度分量啓用
#if JVET_L0279_WAIP_CLEANUP
  int whRatio           = std::max(1, iWidth / iHeight);
  int hwRatio           = std::max(1, iHeight / iWidth);
  const int  srcStride  = m_topRefLength  + 1 + (whRatio + 1) * multiRefIdx;
  const int  srcHStride = m_leftRefLength + 1 + (hwRatio + 1) * multiRefIdx;
#else
  const int  srcStride   = m_topRefLength  + 1 + 5 * multiRefIdx;
  const int  srcHStride  = m_leftRefLength + 1 + 5 * multiRefIdx;
#endif
#else
  const int  srcStride  = m_topRefLength  + 1;
  const int  srcHStride = m_leftRefLength + 1;
#endif

  Pel *ptrSrc = getPredictorPtr(compID, useFilteredPredSamples);	//參考樣本,單獨開闢buf,在預測之前提前存入
  const ClpRng& clpRng(pu.cu->cs->slice->clpRng(compID));
  
/*****************************************************************************************************************/
  switch (uiDirMode)	//角度預測,此時沒有進行寬角度擴展
  {
	//PLANAR
    case(PLANAR_IDX): xPredIntraPlanar(CPelBuf(ptrSrc, srcStride, srcHStride), piPred, *pu.cs->sps); break;
    //DC
	case(DC_IDX):     xPredIntraDc(CPelBuf(ptrSrc, srcStride, srcHStride), piPred, channelType, false); break;
#if JVET_L0628_4TAP_INTRA
	//對角模式2、34、66
    case(2): 
    case(DIA_IDX):
    case(VDIA_IDX):
      if (getWideAngle(iWidth, iHeight, uiDirMode) == static_cast<int>(uiDirMode)) // check if uiDirMode is not wide-angle
      {
        xPredIntraAng(CPelBuf(ptrSrc, srcStride, srcHStride), piPred, channelType, uiDirMode, clpRng, *pu.cs->sps
#if JVET_L0283_MULTI_REF_LINE
          , multiRefIdx
#endif
          , useFilteredPredSamples); 
        break;
      }
	//其他角度
    default:          xPredIntraAng(CPelBuf(getPredictorPtr(compID, false), srcStride, srcHStride), piPred, channelType, uiDirMode, clpRng, *pu.cs->sps
#if JVET_L0283_MULTI_REF_LINE
      , multiRefIdx
#endif
      , useFilteredPredSamples); break;
#else //JVET_L0628_4TAP_INTRA
    default:          xPredIntraAng(CPelBuf(ptrSrc, srcStride, srcHStride), piPred, channelType, uiDirMode, clpRng, *pu.cs->sps
#if JVET_L0283_MULTI_REF_LINE
      , multiRefIdx
#endif
      , false); break;
#endif //JVET_L0628_4TAP_INTRA
  }

/*****************************************************************************************************************/
  //PLANAR、DC、HOR、VER,且參考行索引爲0,進行PDPC
  bool pdpcCondition = (uiDirMode == PLANAR_IDX || uiDirMode == DC_IDX || uiDirMode == HOR_IDX || uiDirMode == VER_IDX);
#if JVET_L0283_MULTI_REF_LINE
  if (pdpcCondition && multiRefIdx == 0)
#else
  if (pdpcCondition)
#endif
  {
    const CPelBuf srcBuf = CPelBuf(ptrSrc, srcStride, srcStride);
    PelBuf dstBuf = piPred;
    const int scale = ((g_aucLog2[iWidth] - 2 + g_aucLog2[iHeight] - 2 + 2) >> 2);
    CHECK(scale < 0 || scale > 31, "PDPC: scale < 0 || scale > 31");

    if (uiDirMode == PLANAR_IDX)
    {
      //省略具體處理
    }
    else if (uiDirMode == DC_IDX)
    {
      //省略具體處理
    }
    else if (uiDirMode == HOR_IDX)
    {
     //省略具體處理
    }
    else if (uiDirMode == VER_IDX)
    {
     //省略具體處理
    }
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章