ErrVal
MbEncoder::xEstimateMb16x16( IntMbTempData*& rpcMbTempData,
IntMbTempData*& rpcMbBestData,
RefListStruct& rcRefListStruct,
UInt uiMinQP,
UInt uiMaxQP,
UInt uiMaxNumMv,
UInt uiNumMaxIter,
UInt uiIterSearchRange,
MbDataAccess* pcMbDataAccessBase,
Bool bResidualPred )
//运动估计队列用的是MEList
//如果允许MotionPred
iBLRefIdx [0] = pcMbDataAccessBase->getMbMotionData( LIST_0 ).getRefIdx (); //ref_idx
cBLMvPred [0] = pcMbDataAccessBase->getMbMotionData( LIST_0 ).getMv (); // BL的mv 作为EL运动估计的MVP
rpcMbTempData->clear(); // 清空
//设置几个参数
rpcMbTempData->setMbMode( MODE_16x16 );
rpcMbTempData->setBLSkipFlag( false );
rpcMbTempData->setResidualPredFlag( bResidualPred );
//对List0、List1中每个ref_idx,进行ME
pcRefFrame = rcRefFrameList0[iRefIdxTest]; //读取参考帧
// 根据当前块的ABC块得到MVP 存入cMvPred[0][iRefIdxTest] rpcMbTempData->getMbDataAccess().getMvPredictor ( cMvPred[0][iRefIdxTest], iRefIdxTest, LIST_0 );
m_pcMotionEstimation->estimateBlockWithStart(…) // 运动估计出mv //注意:这里MVP一定是周围块得到的MVP,搜索起点可能是MVP,也可能是BL的mv(当BL的ref_idx与当前的ref_idx相等时就以BL的Mv为搜索起点,但是MVP仍是周围块得到的)
//如果这个ref_idx与BL的相同,则 MotionPrediction m_pcMotionEstimation->estimateBlockWithStart(…) // 运动估计出mv //注意:这里MVP是BL的mv,搜索起点可能是BL的mv
//如果cost比前面的最小cost(org-ref的失真 和Mv与ref_idx的比特数) 选用该ref_idx和mv
//如果是List1预测,还要补偿出双向预测用的块 m_pcMotionEstimation->compensateBlock ( &cYuvMbBuffer[1], PART_16x16, MODE_16x16 ) |
//如果是B帧,还要进行迭代的Bi-Pred,步骤与上面相同
//注意:MVP用对应LIST的MVP,起始MV也用上次对应LIST运动估计出的MV,包括Std的ME和BL的ME
//保存ref_idx、mv和mvd
rpcMbTempData->getMbMotionData( LIST_0 ).setRefIdx ( iRefIdx [0] );
rpcMbTempData->getMbMotionData( LIST_0 ).setAllMv ( cMv [0] );
rpcMbTempData->getMbMvdData ( LIST_0 ).setAllMv ( cMvd [0] );
//设置每个4x4块的MotionPredFlag
rpcMbTempData->getMbMotionData( LIST_0 ).setMotPredFlag( bBLPred [0] );
rpcMbTempData->getMbMotionData( LIST_1 ).setMotPredFlag( bBLPred [1] );
//计算4x4变换的RDCost
xSetRdCostInterMb(*rpcMbTempData, pcMbDataAccessBase, rcRefListStruct, uiMinQP, uiMaxQP, bLowComplexMbEnable ) 后面分析
xCheckBestEstimation( rpcMbTempData, rpcMbBestData )
//如果当前4x4变换的RdCost比BestData的RdCost大,则函数退出
//交换rpcMbTempData和 rpcMbBestData
xCheckInterMbMode8x8( rpcMbTempData, rpcMbBestData, pcMbRefData, rcRefListStruct, uiMinQP, uiMaxQP,
false, pcMbDataAccessBase )
//计算当前8x8变换的RdCost
xSetRdCost8x8InterMb( *rpcMbTempData, pcMbDataAccessBaseMotion, rcRefListStruct,
uiMinQP, uiMaxQP, bBLSkip, 0, pcBaseLayerRec, pcBaseLayerResidual )
xCheckBestEstimation( rpcMbTempData, rpcMbBestData )