标签:
#if AMP_MRG Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes, Bool bUseMRG ) #else Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes ) #endif { m_acYuvPred[0].clear(); m_acYuvPred[1].clear(); m_cYuvPredTemp.clear(); rpcPredYuv->clear(); if ( !bUseRes ) { rpcResiYuv->clear(); } rpcRecoYuv->clear(); // 这两个mv表示搜索范围(左上角和右下角),但是没有用到 TComMv cMvSrchRngLT; TComMv cMvSrchRngRB; TComMv cMvZero; TComMv TempMv; //kolya TComMv cMv[2]; TComMv cMvBi[2]; TComMv cMvTemp[2][33]; // 当前CU可以被分成多少部分 // 根据partitionSize来确定,如果partitionSize是2Nx2N那么就是一个,如果是NxN就是4个 Int iNumPart = pcCU->getNumPartitions(); // 预测的方向的个数(B帧有两个,前向和后向;P帧有一个,前向) Int iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2; // 记录了每一个前向参考帧的MV TComMv cMvPred[2][33]; // 记录了每一个后向参考帧的MV TComMv cMvPredBi[2][33]; // 记录了每一个后向参考帧的MVP的索引 Int aaiMvpIdxBi[2][33]; // 记录了每一个前向参考帧的MVP的索引 Int aaiMvpIdx[2][33]; // 记录了每一个帧的MVP的数量 Int aaiMvpNum[2][33]; // 记录每一个帧的MVP的信息 AMVPInfo aacAMVPInfo[2][33]; Int iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage. Int iRefIdxBi[2]; UInt uiPartAddr; Int iRoiWidth, iRoiHeight; UInt uiMbBits[3] = {1, 1, 0}; UInt uiLastMode = 0; Int iRefStart, iRefEnd; PartSize ePartSize = pcCU->getPartitionSize( 0 ); Int bestBiPRefIdxL1 = 0; Int bestBiPMvpL1 = 0; UInt biPDistTemp = MAX_INT; #if ZERO_MVD_EST Int aiZeroMvdMvpIdx[2] = {-1, -1}; Int aiZeroMvdRefIdx[2] = {0, 0}; Int iZeroMvdDir = -1; #endif TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS]; Int numValidMergeCand = 0 ; // 遍历当前帧被分成的各个分部 for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ ) { UInt uiCost[2] = { MAX_UINT, MAX_UINT }; UInt uiCostBi = MAX_UINT; UInt uiCostTemp; UInt uiBits[3]; UInt uiBitsTemp; #if ZERO_MVD_EST UInt uiZeroMvdCost = MAX_UINT; UInt uiZeroMvdCostTemp; UInt uiZeroMvdBitsTemp; UInt uiZeroMvdDistTemp = MAX_UINT; UInt auiZeroMvdBits[3]; #endif UInt bestBiPDist = MAX_INT; UInt uiCostTempL0[MAX_NUM_REF]; for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) { uiCostTempL0[iNumRef] = MAX_UINT; } UInt uiBitsTempL0[MAX_NUM_REF]; TComMv mvValidList1; Int refIdxValidList1 = 0; UInt bitsValidList1 = MAX_UINT; UInt costValidList1 = MAX_UINT; // 得到某种模式下CU块的比特数 xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits); // 得到当前部分的索引和大小 pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight ); #if AMP_MRG Bool bTestNormalMC = true; if ( bUseMRG && pcCU->getWidth( 0 ) > 8 && iNumPart == 2 ) { bTestNormalMC = false; } if (bTestNormalMC) { #endif // Uni-directional prediction // 遍历两个参考图像列表(如果是P帧,只参考一个列表;如果是B帧,会参考两个列表) for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ ) { // 选出参考列表 RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); // 遍历这个参考列表的所有参考帧 for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ ) { uiBitsTemp = uiMbBits[iRefList]; if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 ) { uiBitsTemp += iRefIdxTemp+1; if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--; } #if ZERO_MVD_EST xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp, &uiZeroMvdDistTemp); #else // MV预测和AMVP // 针对每一个参考帧进行处理(主要是MVP的计算) xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp); #endif // 记录该帧MVP的索引 aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr); // 记录该帧MVP的数量 aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr); // 更新最优的参数 if(pcCU->getSlice()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist) { bestBiPDist = biPDistTemp; bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp]; bestBiPRefIdxL1 = iRefIdxTemp; } uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS]; #if ZERO_MVD_EST if ( iRefList == 0 || pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) < 0 ) { uiZeroMvdBitsTemp = uiBitsTemp; uiZeroMvdBitsTemp += 2; //zero mvd bits m_pcRdCost->getMotionCost( 1, 0 ); uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost(uiZeroMvdBitsTemp); if (uiZeroMvdCostTemp < uiZeroMvdCost) { uiZeroMvdCost = uiZeroMvdCostTemp; iZeroMvdDir = iRefList + 1; aiZeroMvdRefIdx[iRefList] = iRefIdxTemp; aiZeroMvdMvpIdx[iRefList] = aaiMvpIdx[iRefList][iRefIdxTemp]; auiZeroMvdBits[iRefList] = uiZeroMvdBitsTemp; } } #endif #if GPB_SIMPLE_UNI // 如果是参考列表1(B帧使用) if ( iRefList == 1 ) // list 1 { // 如果list0到list1之间有映射,说明该帧即出现在list0中也出现在list1中 if ( pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) >= 0 ) { cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )]; uiCostTemp = uiCostTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )]; /*first subtract the bit-rate part of the cost of the other list*/ uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )] ); /*correct the bit-rate part of the current ref*/ m_pcRdCost->setPredictor ( cMvPred[iRefList][iRefIdxTemp] ); uiBitsTemp += m_pcRdCost->getBits( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() ); /*calculate the correct cost*/ uiCostTemp += m_pcRdCost->getCost( uiBitsTemp ); } else { // 运动估计 xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp ); } } // 如果是P帧 else { // 直接进行运动估计 xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp ); } #else xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp ); #endif xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE ) // 选择最优的MVP xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp); if ( iRefList == 0 ) { uiCostTempL0[iRefIdxTemp] = uiCostTemp; uiBitsTempL0[iRefIdxTemp] = uiBitsTemp; } if ( uiCostTemp < uiCost[iRefList] ) { uiCost[iRefList] = uiCostTemp; uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction // set motion cMv[iRefList] = cMvTemp[iRefList][iRefIdxTemp]; iRefIdx[iRefList] = iRefIdxTemp; } if ( iRefList == 1 && uiCostTemp < costValidList1 && pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) < 0 ) { costValidList1 = uiCostTemp; bitsValidList1 = uiBitsTemp; // set motion mvValidList1 = cMvTemp[iRefList][iRefIdxTemp]; refIdxValidList1 = iRefIdxTemp; } } } // Bi-directional prediction // 如果是B帧 if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) ) { cMvBi[0] = cMv[0]; cMvBi[1] = cMv[1]; iRefIdxBi[0] = iRefIdx[0]; iRefIdxBi[1] = iRefIdx[1]; ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred)); ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx)); UInt uiMotBits[2]; if(pcCU->getSlice()->getMvdL1ZeroFlag()) { xCopyAMVPInfo(&aacAMVPInfo[1][bestBiPRefIdxL1], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo()); pcCU->setMVPIdxSubParts( bestBiPMvpL1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1; cMvPredBi[1][bestBiPRefIdxL1] = pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo()->m_acMvCand[bestBiPMvpL1]; cMvBi[1] = cMvPredBi[1][bestBiPRefIdxL1]; iRefIdxBi[1] = bestBiPRefIdxL1; pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx ); TComYuv* pcYuvPred = &m_acYuvPred[1]; // 运动补偿 motionCompensation( pcCU, pcYuvPred, REF_PIC_LIST_1, iPartIdx ); uiMotBits[0] = uiBits[0] - uiMbBits[0]; uiMotBits[1] = uiMbBits[1]; if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 ) { uiMotBits[1] += bestBiPRefIdxL1+1; if ( bestBiPRefIdxL1 == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiMotBits[1]--; } uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][AMVP_MAX_NUM_CANDS]; uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1]; cMvTemp[1][bestBiPRefIdxL1] = cMvBi[1]; } else { uiMotBits[0] = uiBits[0] - uiMbBits[0]; uiMotBits[1] = uiBits[1] - uiMbBits[1]; uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1]; } // 4-times iteration (default) Int iNumIter = 4; // fast encoder setting: only one iteration if ( m_pcEncCfg->getUseFastEnc() || pcCU->getSlice()->getMvdL1ZeroFlag()) { iNumIter = 1; } // 遍历4次的原因是什么 for ( Int iIter = 0; iIter < iNumIter; iIter++ ) { Int iRefList = iIter % 2; if ( m_pcEncCfg->getUseFastEnc() ) { if( uiCost[0] <= uiCost[1] ) { iRefList = 1; } else { iRefList = 0; } } else if ( iIter == 0 ) { iRefList = 0; } if ( iIter == 0 && !pcCU->getSlice()->getMvdL1ZeroFlag()) { pcCU->getCUMvField(RefPicList(1-iRefList))->setAllMv( cMv[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(RefPicList(1-iRefList))->setAllRefIdx( iRefIdx[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx ); TComYuv* pcYuvPred = &m_acYuvPred[1-iRefList]; motionCompensation ( pcCU, pcYuvPred, RefPicList(1-iRefList), iPartIdx ); } RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); if(pcCU->getSlice()->getMvdL1ZeroFlag()) { iRefList = 0; eRefPicList = REF_PIC_LIST_0; } Bool bChanged = false; iRefStart = 0; iRefEnd = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1; for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ ) { uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList]; if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 ) { uiBitsTemp += iRefIdxTemp+1; if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--; } uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS]; // call ME // 运动估计 xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true ); xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo()); // 检查最好的MVP xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp); // 如果找到了一个代价更小的方式,那么更新 if ( uiCostTemp < uiCostBi ) { bChanged = true; cMvBi[iRefList] = cMvTemp[iRefList][iRefIdxTemp]; iRefIdxBi[iRefList] = iRefIdxTemp; uiCostBi = uiCostTemp; uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList]; uiBits[2] = uiBitsTemp; if(iNumIter!=1) { // Set motion pcCU->getCUMvField( eRefPicList )->setAllMv( cMvBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField( eRefPicList )->setAllRefIdx( iRefIdxBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx ); TComYuv* pcYuvPred = &m_acYuvPred[iRefList]; motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx ); } } } // for loop-iRefIdxTemp // 最小代价没有更新 if ( !bChanged ) { if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] ) { xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo()); xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi); if(!pcCU->getSlice()->getMvdL1ZeroFlag()) { xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo()); xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi); } } break; } } // for loop-iter } // if (B_SLICE) #if ZERO_MVD_EST if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) ) { m_pcRdCost->getMotionCost( 1, 0 ); for ( Int iL0RefIdxTemp = 0; iL0RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1; iL0RefIdxTemp++ ) for ( Int iL1RefIdxTemp = 0; iL1RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1; iL1RefIdxTemp++ ) { UInt uiRefIdxBitsTemp = 0; if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 1 ) { uiRefIdxBitsTemp += iL0RefIdxTemp+1; if ( iL0RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1 ) uiRefIdxBitsTemp--; } if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 ) { uiRefIdxBitsTemp += iL1RefIdxTemp+1; if ( iL1RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiRefIdxBitsTemp--; } Int iL0MVPIdx = 0; Int iL1MVPIdx = 0; for (iL0MVPIdx = 0; iL0MVPIdx < aaiMvpNum[0][iL0RefIdxTemp]; iL0MVPIdx++) { for (iL1MVPIdx = 0; iL1MVPIdx < aaiMvpNum[1][iL1RefIdxTemp]; iL1MVPIdx++) { uiZeroMvdBitsTemp = uiRefIdxBitsTemp; uiZeroMvdBitsTemp += uiMbBits[2]; uiZeroMvdBitsTemp += m_auiMVPIdxCost[iL0MVPIdx][aaiMvpNum[0][iL0RefIdxTemp]] + m_auiMVPIdxCost[iL1MVPIdx][aaiMvpNum[1][iL1RefIdxTemp]]; uiZeroMvdBitsTemp += 4; //zero mvd for both directions pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( aacAMVPInfo[0][iL0RefIdxTemp].m_acMvCand[iL0MVPIdx], iL0RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 ); pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( aacAMVPInfo[1][iL1RefIdxTemp].m_acMvCand[iL1MVPIdx], iL1RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 ); xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiZeroMvdDistTemp, m_pcEncCfg->getUseHADME() ); uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost( uiZeroMvdBitsTemp ); if (uiZeroMvdCostTemp < uiZeroMvdCost) { uiZeroMvdCost = uiZeroMvdCostTemp; iZeroMvdDir = 3; aiZeroMvdMvpIdx[0] = iL0MVPIdx; aiZeroMvdMvpIdx[1] = iL1MVPIdx; aiZeroMvdRefIdx[0] = iL0RefIdxTemp; aiZeroMvdRefIdx[1] = iL1RefIdxTemp; auiZeroMvdBits[2] = uiZeroMvdBitsTemp; } } } } } #endif #if AMP_MRG } //end if bTestNormalMC #endif // Clear Motion Field pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd ( cMvZero, ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd ( cMvZero, ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); UInt uiMEBits = 0; // Set Motion Field_ cMv[1] = mvValidList1; iRefIdx[1] = refIdxValidList1; uiBits[1] = bitsValidList1; uiCost[1] = costValidList1; #if AMP_MRG if (bTestNormalMC) { #endif #if ZERO_MVD_EST if (uiZeroMvdCost <= uiCostBi && uiZeroMvdCost <= uiCost[0] && uiZeroMvdCost <= uiCost[1]) { if (iZeroMvdDir == 3) { uiLastMode = 2; pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 ); pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 ); pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) ); pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); uiMEBits = auiZeroMvdBits[2]; } else if (iZeroMvdDir == 1) { uiLastMode = 0; pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 ); pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) ); pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); uiMEBits = auiZeroMvdBits[0]; } else if (iZeroMvdDir == 2) { uiLastMode = 1; pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 ); pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) ); pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); uiMEBits = auiZeroMvdBits[1]; } else { assert(0); } } else #endif if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) { uiLastMode = 2; pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMvBi[0], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdxBi[0], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx ); TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]]; pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd ( TempMv, ePartSize, uiPartAddr, 0, iPartIdx ); TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]]; pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd ( TempMv, ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) ); pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); uiMEBits = uiBits[2]; } else if ( uiCost[0] <= uiCost[1] ) { uiLastMode = 0; pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx ); TempMv = cMv[0] - cMvPred[0][iRefIdx[0]]; pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd ( TempMv, ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) ); pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); uiMEBits = uiBits[0]; } else { uiLastMode = 1; pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx ); TempMv = cMv[1] - cMvPred[1][iRefIdx[1]]; pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd ( TempMv, ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) ); pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); uiMEBits = uiBits[1]; } #if AMP_MRG } // end if bTestNormalMC #endif // 如果分割类型不是2Nx2N if ( pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N ) { UInt uiMRGInterDir = 0; TComMvField cMRGMvField[2]; UInt uiMRGIndex = 0; UInt uiMEInterDir = 0; TComMvField cMEMvField[2]; m_pcRdCost->getMotionCost( 1, 0 ); #if AMP_MRG // calculate ME cost UInt uiMEError = MAX_UINT; UInt uiMECost = MAX_UINT; if (bTestNormalMC) { xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() ); uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits ); } #else // calculate ME cost UInt uiMEError = MAX_UINT; xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() ); UInt uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits ); #endif // save ME result. uiMEInterDir = pcCU->getInterDir( uiPartAddr ); pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] ); pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] ); // find Merge result UInt uiMRGCost = MAX_UINT; // 合并估计信息 xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand); if ( uiMRGCost < uiMECost ) { // set Merge result pcCU->setMergeFlagSubParts ( true, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) ); pcCU->setMergeIndexSubParts( uiMRGIndex, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) ); pcCU->setInterDirSubParts ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) ); pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd ( cMvZero, ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd ( cMvZero, ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); } else { // set ME result pcCU->setMergeFlagSubParts( false, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) ); pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) ); pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0], ePartSize, uiPartAddr, 0, iPartIdx ); pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1], ePartSize, uiPartAddr, 0, iPartIdx ); } } // MC // 运动补偿 motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx ); } // end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ ) setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X ); return; }
HM编码器代码阅读(14)——帧间预测之二predInterSearch(inter模式)
标签:
原文地址:http://blog.csdn.net/nb_vol_1/article/details/51162391