您的位置:首页 > 其它

HEVC函数入门(18)——帧间预测的原理

2017-08-21 14:45 211 查看
首先推荐大家看一下:http://blog.csdn.net/qq_21747841/article/details/75671087

http://blog.csdn.net/qq_21747841/article/details/76560245

当前的文章主要参考并整理自:http://blog.csdn.net/nb_vol_1/article/details/51152785

只修改很少的一部分,所以推荐大家跳转去看一下原创。

帧间预测的原理

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而是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 DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseMRG)
#else
Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize )
#endif
{
DEBUG_STRING_NEW(sTest)

// prior to this, rpcTempCU will have just been reset using rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );
// 深度
UChar uhDepth = rpcTempCU->getDepth( 0 );

rpcTempCU->setPartSizeSubParts  ( ePartSize,  0, uhDepth );
rpcTempCU->setPredModeSubParts  ( MODE_INTER, 0, uhDepth );
rpcTempCU->setChromaQpAdjSubParts( rpcTempCU->getCUTransquantBypass(0) ? 0 : m_ChromaQpAdjIdc, 0, uhDepth );
// 对于帧间预测,需要在参考帧选择一个最合适的位置给它,进行预测编码 ,并计算出了残差以及其他信息

#if AMP_MRG
rpcTempCU->setMergeAMP (true);
m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] DEBUG_STRING_PASS_INTO(sTest), 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 DEBUG_STRING_PASS_INTO(sTest) );
rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );

#ifdef DEBUG_STRING
DebugInterPredResiReco(sTest, *(m_ppcPredYuvTemp[uhDepth]), *(m_ppcResiYuvBest[uhDepth]), *(m_ppcRecoYuvTemp[uhDepth]), DebugStringGetPredModeMask(rpcTempCU->getPredictionMode(0)));
#endif

xCheckDQP( rpcTempCU );
xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTest));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hevc HM 预测