HM编码器代码阅读(13)——帧间预测之AMVP模式(一)总体流程

帧间预测的原理


AMVP的原理

    帧间预测的实质就是为当前的PU在参考帧中寻找一块最相似块(相似度的判断准则有SAD等方法)。但是参考图像通常都比较大,我们直接去搜索的话就太费时了,应该使用某种方法在参考图像中确定一个搜索起始点,然后再该搜索起始点的周围进行搜索,那么就能降低搜索的时间了。
    AMVP模式就提供了这样一种方法,在开始搜索之前,先为当前PU预测出一个MV,这个预测的MV就被称为MVP,预测的MV可以直接从空域或者时域上的相邻块直接得到,因为相邻块有多个,因此MVP也会有多个,这些MVP组成了MVP候选列表,我们需要从中选择最优的一个来作为实际的MVP,得到MVP之后,我们根MVP(MVP实际也是一个MV)来确定搜索的起始点,然后在搜索起始点的附近按照某种方法做搜索,最后得到一个最优的MV,这个MV就是实际MV,MV确定了参考块的位置,参考块与当前PU相减得到残差,达到了数据压缩的目的;
同时MV与MVP相减得到MV残差也就是MVD,也能够达到数据压缩的目的。
    它的大致工作流程是:
    1、根据某种方法获取MVP候选列表
    2、从候选列表中选出最优的一个MVP
    3、根据MVP确定运动估计的起始点
    4、在起始点附近,按照某种方法进行搜索
    5、搜索完毕之后得到最优的MV
    6、由MV确定参考块在参考图像中的位置
    7、参考块减去当前块(PU)得到残差块
    8、MV减去MVP得到MVD
    9、通过7和8两个步骤就能达到数据压缩的目的

merge模式的原理

    帧间预测的目的就是要得到一个MV(运动向量),然后根据该MV确定参考块在参考图像中的位置,
但是由于临近块的相似性(比如当前块和临近块都属于同一个物体,在镜头移动的时候,它们移动的距离和方向当然是相同的),因此很多时候我们并不需要去计算MV,我们把相邻块的MV直接当作当前块的MV。和AMVP相似,我们通过相邻块得到一个MVP候选列表,从中选出最优的一个MVP作为当前块的MV,然后根据该MV直接确定参考块的位置,确定了参考块之后就能计算残差了。因为MVP和MV相同,因此不存在MVD,因此编码的时候只需要编码MV(MVP)在候选列表中索引即可,不再需要编码MVD,解码可以按照类似的方法构造MVP候选列表,然后依据传送过来的索引就能得到MV了。
    工作流程是:
    1、根据某种方法获取MVP候选列表
    2、从候选列表中选出最优的一个MVP,同时得到该MVP在候选列表中的索引
    3、把该MVP作为当前块的MV
    4、根据MV确定参考块在参考图像中的位置
    5、参考块减去当前块得到残差块
    6、因为MVP和MV相同,因此没有MVD,只需把残差系数和MVP的索引传给解码器就行了



skip模式的原理

    skip模式是merge模式的一种特例。按照merge模式得到MV之后,如果编码器根据某种方法判断了当前块和参考块基本一样,那么不需要传输残差数据,只需要传送MV的索引和一个标志,来表明当前块可以直接从参考块得到。

AMVP模式的入口函数xCheckRDCostInter

主要流程如下:
(1)得到当前的深度。
(2)调用predInterSearch,进行ME(运动估计)和MC(运动补偿)。
(3)调用encodeResAndCalcRdInterCU,根据预测值,求出残差,然后进行TU的划分,然后进行变换、量化等操作以及RD代价的计算。
(4)调用xCheckBestMode选择最好的模式。

#if AMP_MRG
Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize, Bool bUseMRG)
#else
Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize )
#endif
{
	// 深度
	UChar uhDepth = rpcTempCU->getDepth( 0 );

	rpcTempCU->setDepthSubParts( uhDepth, 0 );

	rpcTempCU->setSkipFlagSubParts( false, 0, uhDepth );

	rpcTempCU->setPartSizeSubParts  ( ePartSize,  0, uhDepth );
	rpcTempCU->setPredModeSubParts  ( MODE_INTER, 0, uhDepth );

    // 对于帧间预测,需要在参考帧选择一个最合适的位置给它,进行预测编码
    // 并计算出了残差以及其他信息
#if AMP_MRG
	rpcTempCU->setMergeAMP (true);
	m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth], false, bUseMRG );
#else  
	m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] );
#endif

#if AMP_MRG
	if ( !rpcTempCU->getMergeAMP() )
	{
		return;
	}
#endif

    // 下一步的计算
	m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false );
	rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );

	xCheckDQP( rpcTempCU );
	xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值