当前位置:编程学习 > C/C++ >>

HEVC帧间预测之二——TComDataCU::xGetColMVP的分析

本文对该函数进行较为详细的分析:
[cpp] 
Bool TComDataCU::xGetColMVP( RefPicList eRefPicList, Int uiCUAddr, Int uiPartUnitIdx, TComMv& rcMv, Int& riRefIdx )  
{//! 这部分的内容可以参考draft 8.5.2.1.7, Derivation process for temporal luma motion vector prediction  
  //! 这个函数的返回条件可以参考该部分的第3小点,The variables mvLXCol and availableFlagLXCol are derived as follows ...  
  UInt uiAbsPartAddr = uiPartUnitIdx;  
  
  RefPicList  eColRefPicList;  
  Int iColPOC, iColRefPOC, iCurrPOC, iCurrRefPOC, iScale;  
  TComMv cColMv;  
  
  // use coldir.   
  //! Colocated Picture  
  TComPic *pColPic = getSlice()->getRefPic( RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0), getSlice()->getColRefIdx());  
  //! Colocated CU  
  TComDataCU *pColCU = pColPic->getCU( uiCUAddr );  
  if(pColCU->getPic()==0||pColCU->getPartitionSize(uiPartUnitIdx)==SIZE_NONE) //!< Colocated Picture or colocated CU不存在  
  {  
    return false;  
  }  
  iCurrPOC = m_pcSlice->getPOC(); //!< 当前slice的POC     
  iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC(); //!< 当前slice参考帧的POC  
  iColPOC = pColCU->getSlice()->getPOC();  //!< 当前slice的colocated picuture的POC  
  
  if (pColCU->isIntra(uiAbsPartAddr)) //!< colocated CU为帧内预测模式,即没有MV,故直接返回false  
  {  
    return false;  
  }  
  eColRefPicList = getSlice()->getCheckLDC() ? eRefPicList : RefPicList(getSlice()->getColFromL0Flag());  
  
  Int iColRefIdx = pColCU->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr); //!< colocated CU对应的参考帧的序号  
  
  if (iColRefIdx < 0 )  
  {  
    eColRefPicList = RefPicList(1 - eColRefPicList);  
    iColRefIdx = pColCU->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);  
  
    if (iColRefIdx < 0 )  
    {  
      return false;  
    }  
  }  
  
  // Scale the vector.  
  iColRefPOC = pColCU->getSlice()->getRefPOC(eColRefPicList, iColRefIdx);  
  cColMv = pColCU->getCUMvField(eColRefPicList)->getMv(uiAbsPartAddr);  
  
  iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();  
  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getIsLongTerm();  
  Bool bIsColRefLongTerm = pColCU->getSlice()->getRefPic(eColRefPicList, iColRefIdx)->getIsUsedAsLongTerm();  
  
  if ( bIsCurrRefLongTerm != bIsColRefLongTerm )   
  {  
    return false;  
  }  
  
  if ( bIsCurrRefLongTerm || bIsColRefLongTerm )  
  {  
    rcMv = cColMv; //!< draft 式子(8-155)  
  }  
  else  
  {  
    iScale = xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iColPOC, iColRefPOC); //!< 接下来分析  
    if ( iScale == 4096 )  
    {  
      rcMv = cColMv;  
    }  
    else  
    {  
      rcMv = cColMv.scaleMv( iScale ); //!< draft 式子(8-158)  
    }  
  }  
  return true;  
}  
[cpp]  
Int TComDataCU::xGetDistScaleFactor(Int iCurrPOC, Int iCurrRefPOC, Int iColPOC, Int iColRefPOC)  
{  
  Int iDiffPocD = iColPOC - iColRefPOC;     //!< draft 式子(8-159)  
  Int iDiffPocB = iCurrPOC - iCurrRefPOC;   //!< draft 式子(8-160)  
    
  if( iDiffPocD == iDiffPocB )  
  {  
    return 4096;  
  }  
  else  
  {   www.zzzyk.com
    Int iTDB      = Clip3( -128, 127, iDiffPocB );  
    Int iTDD      = Clip3( -128, 127, iDiffPocD );  
    Int iX        = (0x4000 + abs(iTDD/2)) / iTDD; //!< draft 式子(8-156)  
    Int iScale    = Clip3( -4096, 4095, (iTDB * iX + 32) >> 6 ); //!< draft 式子(8-157)  
    return iScale;  
  }  
}  
 
[cpp]  
const TComMv scaleMv( Int iScale ) const  
{//! draft 式子(8-158)  
  Int mvx = Clip3( -32768, 32767, (iScale * getHor() + 127 + (iScale * getHor() < 0)) >> 8 );  
  Int mvy = Clip3( -32768, 32767, (iScale * getVer() + 127 + (iScale * getVer() < 0)) >> 8 );  
  return TComMv( mvx, mvy );  
}  
 
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,