VTM1.0代码阅读:getIntraMPMs函数

getIntraMPMs在estIntraPredLumaQT函数中被调用,用来获取亮度帧内预测模式的MPM候选模式,MPM模式存储在mpm中。
流程大致为:获取左侧和上侧的pu帧内预测模式,然后按照left和above模式的情况,给mpm列表赋值:

int PU::getIntraMPMs( const PredictionUnit &pu, unsigned* mpm, const ChannelType &channelType /*= CHANNEL_TYPE_LUMA*/ )
{
  const unsigned numMPMs = pu.cs->pcv->numMPMs;		//mpm候选模式的数目
  {
    Int numCand = -1;
    Int leftIntraDir = DC_IDX, aboveIntraDir = DC_IDX;

    const CompArea& area = pu.block( getFirstComponentOfChannel( channelType ) );
    const Position& pos  = area.pos();				//当前亮度pu的位置

    // Get intra direction of left PU	左侧pu
    const PredictionUnit *puLeft = pu.cs->getPURestricted( pos.offset( -1, 0 ), pu, channelType );

    if( puLeft && CU::isIntra( *puLeft->cu ) )
    {
      leftIntraDir = puLeft->intraDir[channelType];		//左侧pu的亮度帧内模式

      if( isChroma( channelType ) && leftIntraDir == DM_CHROMA_IDX )
      {
        leftIntraDir = puLeft->intraDir[0];
      }
    }

    // Get intra direction of above PU	上侧pu
    const PredictionUnit* puAbove = pu.cs->getPURestricted( pos.offset( 0, -1 ), pu, channelType );

    if( puAbove && CU::isIntra( *puAbove->cu ) && CU::isSameCtu( *pu.cu, *puAbove->cu ) )	//上侧pu必须与当前pu在同一个ctu之内
    {
      aboveIntraDir = puAbove->intraDir[channelType];	//上侧pu的亮度帧内模式

      if( isChroma( channelType ) && aboveIntraDir == DM_CHROMA_IDX )
      {
        aboveIntraDir = puAbove->intraDir[0];
      }
    }

    CHECK( 2 >= numMPMs, "Invalid number of most probable modes" );

    const Int offset = 29;

    const Int mod    = offset + 3;
										///然后根据左侧和上侧pu的亮度帧内模式,构建mpm列表
    if( leftIntraDir == aboveIntraDir )
    {									//左侧和上侧pu的模式相同
      numCand = 1;

      if( leftIntraDir > DC_IDX ) // angular modes		//左侧和上侧pu的模式大于DC模式,即leftIntraDir为65种角度模式
      {
        mpm[0] =   g_intraMode65to33AngMapping[leftIntraDir];
        mpm[1] = ((g_intraMode65to33AngMapping[leftIntraDir] + offset) % mod) + 2;
        mpm[2] = ((g_intraMode65to33AngMapping[leftIntraDir] - 1)      % mod) + 2;
      }
      else //non-angular			//如果left和above的模式为DC或planar
      {
        mpm[0] = g_intraMode65to33AngMapping[PLANAR_IDX];
        mpm[1] = g_intraMode65to33AngMapping[DC_IDX];
        mpm[2] = g_intraMode65to33AngMapping[VER_IDX];
      }
    }
    else							//左侧和上侧pu的模式不同
    {
      numCand = 2;

      mpm[0] = g_intraMode65to33AngMapping[leftIntraDir];
      mpm[1] = g_intraMode65to33AngMapping[aboveIntraDir];

      if( leftIntraDir && aboveIntraDir ) //both modes are non-planar
      {
        mpm[2] = g_intraMode65to33AngMapping[PLANAR_IDX];		//均不为planar模式时,添加planar
      }
      else
      {
        mpm[2] = g_intraMode65to33AngMapping[(leftIntraDir + aboveIntraDir) < 2 ? VER_IDX : DC_IDX];
      }
    }
    for( UInt i = 0; i < numMPMs; i++ )
    {
      mpm[i] = g_intraMode33to65AngMapping[mpm[i]];
      CHECK( mpm[i] >= NUM_LUMA_MODE, "Invalid MPM" );
    }
    CHECK( numCand == 0, "No candidates found" );
    return numCand;					//返回mpm候选模式的数目
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值