📄 mvdec.cpp
字号:
} else { end of new changes 02-19-99 */ // begin of new changes 02-19-99 if (m_vopmd.bInterlace) { if (!pmbmd->m_bSkip) { getDiffMV (pmbmd->m_vctDirectDeltaMV, directInfo); vctDiff.x = pmbmd->m_vctDirectDeltaMV.x; vctDiff.y = pmbmd->m_vctDirectDeltaMV.y; } else vctDiff.x = vctDiff.y = 0; } else { //end of new changes 02-19-99 if (pmbmd->m_bSkip) vctDiff.x = vctDiff.y = 0; else { Long lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol (); vctDiff.x = deScaleMV (lSymbol - 32, 0, 1); lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol (); vctDiff.y = deScaleMV (lSymbol - 32, 0, 1); } } // new change 02-19-99 computeDirectForwardMV (vctDiff, pmvForward, pmvRef, pmbmdRef); //compute forward mv from diff if(pmbmdRef==NULL) { // transparent reference macroblock pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = FALSE; CMotionVector mvRef; // zero motion vector backwardMVFromForwardMV (*pmvBackward, *pmvForward, mvRef, vctDiff); } else { pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = pmbmdRef->m_bhas4MVForward; //reset 4mv mode if (pmbmd->m_bhas4MVBackward) { for (Int i = 0; i < 4; i++) { pmvForward++; pmvBackward++; pmvRef++; backwardMVFromForwardMV (*pmvBackward, *pmvForward, *pmvRef, vctDiff); //compute back mv from forward mv and ref mv for direct mode } } else backwardMVFromForwardMV (*pmvBackward, *pmvForward, *pmvRef, vctDiff); //compute back mv from forward mv and ref mv for direct mode } // } new change 02-19-99 }}Void CVideoObjectDecoder::computeDirectForwardMV (CVector vctDiff, CMotionVector* pmv, const CMotionVector* pmvRef, const CMBMode* pmbmdRef){ if(pmvRef==NULL) { // colocated macroblock is transparent, use zero reference MV *pmv++ = CMotionVector (vctDiff); //convert to full pel now for (Int i = 0; i < 4; i++) { *pmv = *(pmv - 1); pmv++; } } else { Int iPartInterval = m_t - m_tPastRef; Int iFullInterval = m_tFutureRef - m_tPastRef; if (pmbmdRef->m_bhas4MVForward == FALSE) { CVector vctRefScaled = pmvRef->trueMVHalfPel () * iPartInterval; vctRefScaled.x /= iFullInterval; //truncation as per vm vctRefScaled.y /= iFullInterval; //truncation as per vm CVector vctDecode = vctDiff + vctRefScaled; *pmv++ = CMotionVector (vctDecode); //convert to full pel now for (Int i = 0; i < 4; i++) { *pmv = *(pmv - 1); pmv++; } } else { for (Int i = 0; i < 4; i++) { pmv++; pmvRef++; CVector vctRefScaled = pmvRef->trueMVHalfPel () * iPartInterval; vctRefScaled.x /= iFullInterval; //truncation as per vm vctRefScaled.y /= iFullInterval; //truncation as per vm CVector vctDecode = vctDiff + vctRefScaled; *pmv = CMotionVector (vctDecode); //convert to full pel now } } }}Void CVideoObjectDecoder::decodeMVWithShape (const CMBMode* pmbmd, CoordI iMBX, CoordI iMBY, CMotionVector* pmv){ if (pmbmd->m_bSkip || pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ) { memset (pmv, 0, PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector)); return; } CVector vctDiff, vctDecode, vctPred; if (pmbmd->m_bhas4MVForward) { for (Int iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) { if (pmbmd->m_rgTranspStatus [iBlk] == ALL) pmv [iBlk] = CMotionVector (NOT_MV, NOT_MV); else { findMVpredGeneric (vctPred, pmv, pmbmd, iBlk, iMBX, iMBY); getDiffMV (vctDiff, m_vopmd.mvInfoForward); vctDecode = vctDiff + vctPred; //fit in range fitMvInRange (vctDecode, m_vopmd.mvInfoForward); pmv [iBlk] = CMotionVector (vctDecode); } } }// INTERLACE //new changes else if ((m_vopmd.bInterlace)&&(pmbmd->m_bFieldMV)) { Int iTempX1, iTempY1, iTempX2, iTempY2; assert (pmbmd->m_rgTranspStatus [0] != ALL); findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY); getDiffMV (vctDiff, m_vopmd.mvInfoForward); vctDiff.y *= 2; vctPred.y = 2*(vctPred.y / 2); vctDecode = vctDiff + vctPred; //fit in range fitMvInRange (vctDecode, m_vopmd.mvInfoForward); CMotionVector* pmv16x8 = pmv +5; if(pmbmd->m_bForwardTop) { pmv16x8++; *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now iTempX1 = pmv16x8->m_vctTrueHalfPel.x; iTempY1 = pmv16x8->m_vctTrueHalfPel.y; pmv16x8++; } else { *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now iTempX1 = pmv16x8->m_vctTrueHalfPel.x; iTempY1 = pmv16x8->m_vctTrueHalfPel.y; pmv16x8++; pmv16x8++; } getDiffMV (vctDiff, m_vopmd.mvInfoForward); vctDiff.y *= 2; vctPred.y = 2*(vctPred.y / 2); vctDecode = vctDiff + vctPred; //fit in range fitMvInRange (vctDecode, m_vopmd.mvInfoForward); if(pmbmd->m_bForwardBottom) { pmv16x8++; *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now iTempX2 = pmv16x8->m_vctTrueHalfPel.x; iTempY2 = pmv16x8->m_vctTrueHalfPel.y; } else { *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now iTempX2 = pmv16x8->m_vctTrueHalfPel.x; iTempY2 = pmv16x8->m_vctTrueHalfPel.y; } Int iTemp; for (UInt i = 1; i < 5; i++) { iTemp = iTempX1 + iTempX2; pmv [i].m_vctTrueHalfPel.x = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1); iTemp = iTempY1 + iTempY2; pmv [i].m_vctTrueHalfPel.y = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1); } } //end of new changes// ~INTERLACE else { //1 mv assert (pmbmd->m_rgTranspStatus [0] != ALL); findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY); getDiffMV (vctDiff, m_vopmd.mvInfoForward); vctDecode = vctDiff + vctPred; //fit in range fitMvInRange (vctDecode, m_vopmd.mvInfoForward); *pmv++ = CMotionVector (vctDecode); for (Int i = 0; i < 4; i++) { *pmv = *(pmv - 1); pmv++; } }}Void CVideoObjectDecoder::getDiffMV (CVector& vctDiffMV, MVInfo mvinfo) //get half pel{ Int iResidual; Long lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol (); Int iVLC = lSymbol - 32; if (iVLC != 0) iResidual = m_pbitstrmIn->getBits (mvinfo.uiFCode - 1); else iResidual = 0; vctDiffMV.x = deScaleMV (iVLC, iResidual, mvinfo.uiScaleFactor); lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol (); iVLC = lSymbol - 32; if (iVLC != 0) iResidual = m_pbitstrmIn->getBits (mvinfo.uiFCode - 1); else iResidual = 0; vctDiffMV.y = deScaleMV (iVLC, iResidual, mvinfo.uiScaleFactor);}Int CVideoObjectDecoder::deScaleMV (Int iVLC, Int iResidual, Int iScaleFactor){ if (iVLC == 0 && iResidual == 0) return 0; else if (iScaleFactor == 1) return (iVLC); else { Int iAbsDiffMVcomponent = abs (iVLC) * iScaleFactor + iResidual - iScaleFactor + 1; //changed a'c to enc return (sign (iVLC) * iAbsDiffMVcomponent); }}Void CVideoObjectDecoder::fitMvInRange (CVector& vctSrc, MVInfo mvinfo){ Int iMvRange = mvinfo.uiRange; //in half pel unit if (vctSrc.x < -1 * iMvRange) //* 2 to get length of [-range, range] vctSrc.x += 2 * iMvRange; else if (vctSrc.x >= iMvRange) vctSrc.x -= 2 * iMvRange; if (vctSrc.y < -1 * iMvRange) vctSrc.y += 2 * iMvRange; else if (vctSrc.y >= iMvRange) vctSrc.y -= 2 * iMvRange;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -