帧间预测--时域伸缩MV函数分析

感谢前辈HEVC_CJL,附上前辈专栏:http://blog.csdn.net/HEVC_CJL

这个函数在Merge模式下的getInterMergeCandidates中和AMVP模式下的fillMvpCand都被调用了,主要用来获取时域候选列表需要的MVxGetColMVP调用xGetDistScaleFactor()完成比例伸缩部分,结合前面的理论部分和代码注释,理解起来没什么困难。

理论部分:http://blog.csdn.net/m0_37579288/article/details/79244986

1.xGetColMVP

Bool TComDataCU::xGetColMVP( RefPicList eRefPicList, Int uiCUAddr, Int uiPartUnitIdx, TComMv& rcMv, Int& riRefIdx )
{
  UInt uiAbsPartAddr = uiPartUnitIdx;

  RefPicList  eColRefPicList;
  Int iColPOC, iColRefPOC, iCurrPOC, iCurrRefPOC, iScale;
  TComMv cColMv;

  // use coldir.用同位图像的预测方向
  TComPic *pColPic = getSlice()->getRefPic( RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0), getSlice()->getColRefIdx());//!<获取同位帧
  TComDataCU *pColCU = pColPic->getCU( uiCUAddr );//!<同位CU
  if(pColCU->getPic()==0||pColCU->getPartitionSize(uiPartUnitIdx)==SIZE_NONE)
  {//不存在同位CU或同位帧
    return false;
  }
  iCurrPOC = m_pcSlice->getPOC();//!<当前Slice的POC    
  iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();//参考POC
  iColPOC = pColCU->getSlice()->getPOC();//同位Col

  if (pColCU->isIntra(uiAbsPartAddr))//不是帧内预测模式
  {
    return false;
  }
  eColRefPicList = getSlice()->getCheckLDC() ? eRefPicList : RefPicList(getSlice()->getColFromL0Flag());//同位的参考图像

  Int iColRefIdx = pColCU->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);//colref的Idx

  if (iColRefIdx < 0 )
  {
    //同位帧图像列表的选择,
    //REF_PIC_LIST_0 = 0,   reference list 0
    //REF_PIC_LIST_1 = 1,   reference list 1
    //REF_PIC_LIST_C = 2,   combined reference list for uni-prediction in B-Slices
    //REF_PIC_LIST_X = 100,  special mark
    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()->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);

  if ( bIsCurrRefLongTerm != bIsColRefLongTerm ) 
  {
    return false;
  }

  if ( bIsCurrRefLongTerm || bIsColRefLongTerm )
  {
    rcMv = cColMv;
  }
  else
  {
    iScale = xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iColPOC, iColRefPOC);
    if ( iScale == 4096 )//4096为放大后,实际的比值为iScale/4096
    {
      rcMv = cColMv;//距离相同,mv不调整
    }
    else
    {
      rcMv = cColMv.scaleMv( iScale );
    }
  }
  return true;
}
2.xGetDistScaleFactor

Int TComDataCU::xGetDistScaleFactor(Int iCurrPOC, Int iCurrRefPOC, Int iColPOC, Int iColRefPOC)
{
  Int iDiffPocD = iColPOC - iColRefPOC;//距离
  Int iDiffPocB = iCurrPOC - iCurrRefPOC;//距离
  
  if( iDiffPocD == iDiffPocB )
  {
    return 4096;
  }
  else
  {
    Int iTDB      = Clip3( -128, 127, iDiffPocB );//限幅
    Int iTDD      = Clip3( -128, 127, iDiffPocD );//限幅
    Int iX        = (0x4000 + abs(iTDD/2)) / iTDD;
    //这里我觉得4096是个为了提高精度而使用的,其实是把两个的比值扩大了4096倍
    //所以4096其实是1,即相等
    Int iScale    = Clip3( -4096, 4095, (iTDB * iX + 32) >> 6 );
    return iScale;
  }
}




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值