推荐阅读
http://blog.csdn.net/nb_vol_1/article/details/51163625
http://blog.csdn.net/guoyaoyao1990/article/details/35339717
今天来学习HM中merge部分的代码,其入口函数为xCheckRDCostMerge2Nx2N。
这里需要注意的是,merge是借用空间邻近块的MV作为当前块的MV直接进行预测,不再进行运动估计。也就是说,对于merge是没有MVP的,直接得到的即为MV,不存在MVD。因此在merge模式下是没有运动估计的。
而这个被merge选到的MV由已编码的空间邻近块得到,不需要再进行传输了,只需要传输最优MV的候选列表索引即可。
xCheckRDCostMerge2Nx2N功能即为构造Merge候选列表,遍历列表进行运动补偿,通过比较RD cost,最终得到最优MV和最优模式信息。
工作流程如下:
1. 调用getInterMergeCandidates构造候选列表。
2. 遍历候选列表:
(1) 调用motionCompensation进行运动补偿。
(2) 调用encodeResAndCalcRdInterCU计算残差和RD cost
并进行编码。
(3) 比较选出最优MV和最优模式信息。
其中使用到的重要函数为getInterMergeCandidates(http://blog.csdn.net/lin453701006/article/details/78573347),motionCompensation(http://blog.csdn.net/lin453701006/article/details/72677630),encodeResAndCalcRdInterCU(http://blog.csdn.net/lin453701006/article/details/77249344)。
代码分析:
/** check RD costs for a CU block encoded with merge
* \param rpcBestCU
* \param rpcTempCU
* \param earlyDetectionSkipMode
*/
//计算2Nx2N块Merge下的RD代价
Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU DEBUG_STRING_FN_DECLARE(sDebug), Bool *earlyDetectionSkipMode )
{
assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE ); //检测非I帧
if(getFastDeltaQp()) //快速deltaQP,默认关闭
{