📄 mc.cpp
字号:
ppxlcRefBot = ppxlcRef + m_iFrameWidthY; //UPln -> pixels (xInt,yInt+1); for (ix = 0; ix < iSize; ix++) ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRefBot [ix] + 1 - iRoundingControl) >> 1; ppxlcRef = ppxlcRefBot; ppxlcPred += MB_SIZE; } } else { // bXSubPxl && bYSubPxl for (iy = 0; iy < iSize; iy++) { ppxlcRefBot = ppxlcRef + m_iFrameWidthY; //UPln -> pixels (xInt,yInt+1); for (ix = 0; ix < iSize; ix++){ ppxlcPred [ix] = ( ppxlcRef [ix + 1] + ppxlcRef [ix] + ppxlcRefBot [ix + 1] + ppxlcRefBot [ix] + 2 - iRoundingControl ) >> 2; } ppxlcRef = ppxlcRefBot; ppxlcPred += MB_SIZE; } } } }}Void CVideoObject::motionCompDirectMode( // Interlaced direct mode CoordI x, CoordI y, CMBMode *pmbmd, const CMotionVector *pmvRef, CRct *prctMVLimitFwd, CRct *prctMVLimitBak, Int plane // plane=1 for grey scale, plane=0 for texture, 02-17-99){ Int* rgiMvRound = NULL; UInt uiDivisor = 0; Int xRefUVF,yRefUVF,xRefUVB,yRefUVB;// begin of new changes 10/21/98 Int iMBX,iMBY; const CMBMode *pmbmdRef; if(m_volmd.fAUsage != RECTANGLE) { iMBX=(x-m_rctCurrVOPY.left)/MB_SIZE; iMBY=(y-m_rctCurrVOPY.top)/MB_SIZE; pmbmdRef= m_rgmbmdRef + (iMBX+iMBY*m_iNumMBXRef); } else { iMBX=x/MB_SIZE; iMBY=y/MB_SIZE; pmbmdRef= m_rgmbmdRef + iMBX+iMBY*m_iNumMBXRef; }// end of new changes 10/21/98 if (pmbmdRef->m_rgTranspStatus[0]==ALL) { static CMotionVector mvZero[5]; pmvRef = mvZero; } if ((iMBX<m_iNumMBXRef && iMBX>=0 && iMBY<m_iNumMBYRef && iMBY>=0)&& // new change 10/21/98 (pmbmdRef->m_bFieldMV&&pmbmdRef->m_rgTranspStatus[0]!=ALL)) { static I8 iTROffsetTop[] = { 0, 0, 1, 1, 0, 0, -1, -1 }; static I8 iTROffsetBot[] = { -1, 0, -1, 0, 1, 0, 1, 0 }; CoordI iXFwdTop, iXFwdBot, iXBakTop, iXBakBot; CoordI iYFwdTop, iYFwdBot, iYBakTop, iYBakBot; const CMotionVector *pmvRefTop, *pmvRefBot; Int iTopRefFldOffset = 0, iBotRefFldOffset = 0; Int iCode = (Int)(vopmd().bTopFieldFirst) << 2; pmbmd->m_bFieldMV = 1; // set field direct mode for grey scale // new change 02-19-99 assert((pmbmdRef->m_dctMd != INTRA) && (pmbmdRef->m_dctMd != INTRAQ)); if (pmbmdRef->m_bForwardTop) { iCode |= 2; iTopRefFldOffset = 1; pmvRefTop = pmvRef + 6; } else pmvRefTop = pmvRef + 5; if (pmbmdRef->m_bForwardBottom) { iCode |= 1; iBotRefFldOffset = 1; pmvRefBot = pmvRef + 8; } else pmvRefBot = pmvRef + 7; Int iTempRefDTop = 2*(m_tFutureRef - m_tPastRef) + iTROffsetTop[iCode]; Int iTempRefDBot = 2*(m_tFutureRef - m_tPastRef) + iTROffsetBot[iCode]; Int iTempRefBTop = 2*(m_t - m_tPastRef) + iTROffsetTop[iCode]; Int iTempRefBBot = 2*(m_t - m_tPastRef) + iTROffsetBot[iCode]; assert(iTempRefDTop > 0); assert(iTempRefDBot > 0); assert(iTempRefBTop > 0); assert(iTempRefBBot > 0); // Find MVs for the top field iXFwdTop = (pmvRefTop->m_vctTrueHalfPel.x * iTempRefBTop) / iTempRefDTop + pmbmd->m_vctDirectDeltaMV.x; iYFwdTop = (pmvRefTop->m_vctTrueHalfPel.y * iTempRefBTop) / iTempRefDTop + pmbmd->m_vctDirectDeltaMV.y; iXBakTop = pmbmd->m_vctDirectDeltaMV.x ? (iXFwdTop - pmvRefTop->m_vctTrueHalfPel.x) : ((pmvRefTop->m_vctTrueHalfPel.x * (iTempRefBTop - iTempRefDTop)) / iTempRefDTop); iYBakTop = pmbmd->m_vctDirectDeltaMV.y ? (iYFwdTop - pmvRefTop->m_vctTrueHalfPel.y) : ((pmvRefTop->m_vctTrueHalfPel.y * (iTempRefBTop - iTempRefDTop)) / iTempRefDTop); // Find MVs for the bottom field iXFwdBot = (pmvRefBot->m_vctTrueHalfPel.x * iTempRefBBot) / iTempRefDBot + pmbmd->m_vctDirectDeltaMV.x; iYFwdBot = (pmvRefBot->m_vctTrueHalfPel.y * iTempRefBBot) / iTempRefDBot + pmbmd->m_vctDirectDeltaMV.y; iXBakBot = pmbmd->m_vctDirectDeltaMV.x ? (iXFwdBot - pmvRefBot->m_vctTrueHalfPel.x) : ((pmvRefBot->m_vctTrueHalfPel.x * (iTempRefBBot - iTempRefDBot)) / iTempRefDBot); iYBakBot = pmbmd->m_vctDirectDeltaMV.y ? (iYFwdBot - pmvRefBot->m_vctTrueHalfPel.y) : ((pmvRefBot->m_vctTrueHalfPel.y * (iTempRefBBot - iTempRefDBot)) / iTempRefDBot); // Motion compensate the top field forward iXFwdTop += 2*x; iYFwdTop += 2*y; limitMVRangeToExtendedBBHalfPel(iXFwdTop, iYFwdTop, prctMVLimitFwd, MB_SIZE); if (plane==0) { // texture MC // new change 02-19-99 motionCompYField(m_ppxlcPredMBY, m_pvopcRefQ0->pixelsY() + iTopRefFldOffset * m_iFrameWidthY, iXFwdTop, iYFwdTop); iXFwdTop -= 2*x; iYFwdTop -= 2*y; motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, (iXFwdTop & 3) ? ((iXFwdTop >> 1) | 1) : (iXFwdTop >> 1), (iYFwdTop & 6) ? ((iYFwdTop >> 1) | 2) : (iYFwdTop >> 1), iTopRefFldOffset); } else { // plane=1, grey scale MC // begin of new change 02-19-99 motionCompYField(m_ppxlcPredMBA, m_pvopcRefQ0->pixelsA() + iTopRefFldOffset * m_iFrameWidthY, iXFwdTop, iYFwdTop); iXFwdTop -= 2*x; iYFwdTop -= 2*y; } // end of new change 02-19-99 // Motion compensate the top field backward iXBakTop += 2*x; iYBakTop += 2*y; limitMVRangeToExtendedBBHalfPel(iXBakTop, iYBakTop, prctMVLimitBak, MB_SIZE); if (plane==0) { // texture MC // new change 02-19-99 motionCompYField(m_ppxlcPredMBBackY, m_pvopcRefQ1->pixelsY(), iXBakTop, iYBakTop); iXBakTop -= 2*x; iYBakTop -= 2*y; motionCompFieldUV(m_ppxlcPredMBBackU, m_ppxlcPredMBBackV, m_pvopcRefQ1, x, y, (iXBakTop & 3) ? ((iXBakTop >> 1) | 1) : (iXBakTop >> 1), (iYBakTop & 6) ? ((iYBakTop >> 1) | 2) : (iYBakTop >> 1), 0); } else { // plane=1, grey scale MC // begin of new change 02-19-99 motionCompYField(m_ppxlcPredMBBackA, m_pvopcRefQ1->pixelsA(), iXBakTop, iYBakTop); iXBakTop -= 2*x; iYBakTop -= 2*y; } // end of new change 02-19-99 // Motion compensate the bottom field forward iXFwdBot += 2*x; iYFwdBot += 2*y; limitMVRangeToExtendedBBHalfPel(iXFwdBot, iYFwdBot, prctMVLimitFwd, MB_SIZE); if (plane==0) { // texture MC // new change 02-19-99 motionCompYField(m_ppxlcPredMBY + MB_SIZE, m_pvopcRefQ0->pixelsY() + iBotRefFldOffset * m_iFrameWidthY, iXFwdBot, iYFwdBot); iXFwdBot -= 2*x; iYFwdBot -= 2*y; motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE, m_pvopcRefQ0, x, y, (iXFwdBot & 3) ? ((iXFwdBot >> 1) | 1) : (iXFwdBot >> 1), (iYFwdBot & 6) ? ((iYFwdBot >> 1) | 2) : (iYFwdBot >> 1), iBotRefFldOffset); } else { // plane=1, grey scale MC // begin of new change 02-19-99 motionCompYField(m_ppxlcPredMBA + MB_SIZE, m_pvopcRefQ0->pixelsA() + iBotRefFldOffset * m_iFrameWidthY, iXFwdBot, iYFwdBot); iXFwdBot -= 2*x; iYFwdBot -= 2*y; } // end of new change 02-19-99 // Motion compensate the bottom field backward iXBakBot += 2*x; iYBakBot += 2*y; limitMVRangeToExtendedBBHalfPel(iXBakBot, iYBakBot, prctMVLimitBak, MB_SIZE); if (plane==0) { // texture MC // new change 02-19-99 motionCompYField(m_ppxlcPredMBBackY + MB_SIZE, m_pvopcRefQ1->pixelsY() + m_iFrameWidthY, iXBakBot, iYBakBot); iXBakBot -= 2*x; iYBakBot -= 2*y; motionCompFieldUV(m_ppxlcPredMBBackU + BLOCK_SIZE, m_ppxlcPredMBBackV + BLOCK_SIZE, m_pvopcRefQ1, x, y, (iXBakBot & 3) ? ((iXBakBot >> 1) | 1) : (iXBakBot >> 1), (iYBakBot & 6) ? ((iYBakBot >> 1) | 2) : (iYBakBot >> 1), 1); } else { // plane=1, grey scale MC // begin of new change 02-19-99 motionCompYField(m_ppxlcPredMBBackA + MB_SIZE, m_pvopcRefQ1->pixelsA() + m_iFrameWidthY, iXBakBot, iYBakBot); iXBakBot -= 2*x; iYBakBot -= 2*y; } // end of new change 02-19-99 } else { Int iTempRefD = m_tFutureRef - m_tPastRef; Int iTempRefB = m_t - m_tPastRef; assert(iTempRefD > 0); assert(iTempRefB > 0); Int iChromaFwdX = 0, iChromaFwdY = 0, iChromaBakX = 0, iChromaBakY = 0; CVector vctFwd, vctBak; static I8 iBlkXOffset[] = { 0, 2*BLOCK_SIZE, 0, 2*BLOCK_SIZE }; static I8 iBlkYOffset[] = { 0, 0, 2*BLOCK_SIZE, 2*BLOCK_SIZE }; static Int iMBOffset[] = { 0, BLOCK_SIZE, MB_SIZE*BLOCK_SIZE, MB_SIZE*BLOCK_SIZE + BLOCK_SIZE }; if ((pmbmdRef->m_dctMd == INTRA) || (pmbmdRef->m_dctMd == INTRAQ)) { static CMotionVector mvZero[5]; pmvRef = mvZero; } if(iMBX<m_iNumMBXRef && iMBX>=0 && iMBY<m_iNumMBYRef && iMBY>=0) // new changes 10/21/98 { if (pmbmdRef -> m_bhas4MVForward) { for (Int iBlk = 0; iBlk < 4; iBlk++) { if(pmbmd->m_rgTranspStatus[iBlk+1]!=ALL) { vctFwd = (pmvRef[iBlk + 1].m_vctTrueHalfPel * iTempRefB) / iTempRefD + pmbmd->m_vctDirectDeltaMV; vctBak.x = pmbmd->m_vctDirectDeltaMV.x ? (vctFwd.x - pmvRef[iBlk + 1].m_vctTrueHalfPel.x) : ((pmvRef[iBlk + 1].m_vctTrueHalfPel.x * (iTempRefB - iTempRefD)) / iTempRefD); vctBak.y = pmbmd->m_vctDirectDeltaMV.y ? (vctFwd.y - pmvRef[iBlk + 1].m_vctTrueHalfPel.y) : ((pmvRef[iBlk + 1].m_vctTrueHalfPel.y * (iTempRefB - iTempRefD)) / iTempRefD); // rounding control is messed up here motionComp(m_ppxlcPredMBY + iMBOffset[iBlk], m_pvopcRefQ0->pixelsY(), BLOCK_SIZE, x * 2 + iBlkXOffset[iBlk] + vctFwd.x, y * 2 + iBlkYOffset[iBlk] + vctFwd.y, 0, prctMVLimitFwd); motionComp(m_ppxlcPredMBBackY + iMBOffset[iBlk], m_pvopcRefQ1->pixelsY(), BLOCK_SIZE, x * 2 + iBlkXOffset[iBlk] + vctBak.x, y * 2 + iBlkYOffset[iBlk] + vctBak.y, 0, prctMVLimitBak); iChromaFwdX += vctFwd.x; iChromaFwdY += vctFwd.y; iChromaBakX += vctBak.x; iChromaBakY += vctBak.y; uiDivisor += 4; } } switch (uiDivisor) { case 4: rgiMvRound = grgiMvRound4; break; case 8: rgiMvRound = grgiMvRound8; break; case 12: rgiMvRound = grgiMvRound12; break; case 16: rgiMvRound = grgiMvRound16; break; } xRefUVF = sign (iChromaFwdX) * (rgiMvRound [abs (iChromaFwdX) % uiDivisor] + (abs (iChromaFwdX) / uiDivisor) * 2); yRefUVF = sign (iChromaFwdY) * (rgiMvRound [abs (iChromaFwdY) % uiDivisor] + (abs (iChromaFwdY) / uiDivisor) * 2); xRefUVB = sign (iChromaBakX) * (rgiMvRound [abs (iChromaBakX) % uiDivisor] + (abs (iChromaBakX) / uiDivisor) * 2); yRefUVB = sign (iChromaBakY) * (rgiMvRound [abs (iChromaBakY) % uiDivisor] + (abs (iChromaBakY) / uiDivisor) * 2); } else // 16x16 { vctFwd = (pmvRef[0].m_vctTrueHalfPel * iTempRefB) / iTempRefD + pmbmd->m_vctDirectDeltaMV; vctBak.x = pmbmd->m_vctDirectDeltaMV.x ? (vctFwd.x - pmvRef[0].m_vctTrueHalfPel.x) : ((pmvRef[0].m_vctTrueHalfPel.x * (iTempRefB - iTempRefD)) / iTempRefD); vctBak.y = pmbmd->m_vctDirectDeltaMV.y ? (vctFwd.y - pmvRef[0].m_vctTrueHalfPel.y) : ((pmvRef[0].m_vctTrueHalfPel.y * (iTempRefB - iTempRefD)) / iTempRefD); // rounding control is messed up here motionComp(m_ppxlcPredMBY, m_pvopcRefQ0->pixelsY(), MB_SIZE, x * 2 + vctFwd.x, y * 2 + vctFwd.y, 0, prctMVLimitFwd); motionComp(m_ppxlcPredMBBackY , m_pvopcRefQ1->pixelsY(), MB_SIZE, x * 2 + vctBak.x, y * 2 + vctBak.y, 0, prctMVLimitBak); xRefUVF = sign (vctFwd.x) * (grgiMvRound4 [abs (vctFwd.x) % 4] + (abs (vctFwd.x) / 4) * 2); yRefUVF = sign (vctFwd.y) * (grgiMvRound4 [abs (vctFwd.y) % 4] + (abs (vctFwd.y) / 4) * 2); xRefUVB = sign (vctBak.x) * (grgiMvRound4 [abs (vctBak.x) % 4] + (abs (vctBak.x) / 4) * 2); yRefUVB = sign (vctBak.y) * (grgiMvRound4 [abs (vctBak.y) % 4] + (abs (vctBak.y) / 4) * 2); } } // begin of new changes 10/21/98 else { vctFwd = pmbmd->m_vctDirectDeltaMV; vctBak.x = pmbmd->m_vctDirectDeltaMV.x ? vctFwd.x :0; vctBak.y = pmbmd->m_vctDirectDeltaMV.y ? vctFwd.y :0; // rounding control is messed up here motionComp(m_ppxlcPredMBY, m_pvopcRefQ0->pixelsY(), MB_SIZE, x * 2 + vctFwd.x, y * 2 + vctFwd.y, 0, prctMVLimitFwd); motionComp(m_ppxlcPredMBBackY , m_pvopcRefQ1->pixelsY(), MB_SIZE, x * 2 + vctBak.x, y * 2 + vctBak.y, 0, prctMVLimitBak); xRefUVF = sign (vctFwd.x) * (grgiMvRound4 [abs (vctFwd.x) % 4] + (abs (vctFwd.x) / 4) * 2); yRefUVF = sign (vctFwd.y) * (grgiMvRound4 [abs (vctFwd.y) % 4] + (abs (vctFwd.y) / 4) * 2); xRefUVB = sign (vctBak.x) * (grgiMvRound4 [abs (vctBak.x) % 4] + (abs (vctBak.x) / 4) * 2); yRefUVB = sign (vctBak.y) * (grgiMvRound4 [abs (vctBak.y) % 4] + (abs (vctBak.y) / 4) * 2); } // end of new changes 10/21/98 motionCompUV(m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, xRefUVF, yRefUVF,0, prctMVLimitFwd); motionCompUV(m_ppxlcPredMBBackU, m_ppxlcPredMBBackV, m_pvopcRefQ1, x, y, xRefUVB, yRefUVB,0, prctMVLimitBak); }}Void CVideoObject::motionCompOneBVOPReference( CVOPU8YUVBA *pvopcPred, MBType type, CoordI x, CoordI y, const CMBMode *pmbmd, const CMotionVector *pmv, CRct *prctMVLimit){ CVOPU8YUVBA *pvopcRef; Int topRef, botRef; if (type == BACKWARD) { pvopcRef = m_pvopcRefQ1; topRef = (Int)pmbmd->m_bBackwardTop; botRef = (Int)pmbmd->m_bBackwardBottom; } else { pvopcRef = m_pvopcRefQ0; topRef = (Int)pmbmd->m_bForwardTop; botRef = (Int)pmbmd->m_bForwardBottom; } if (pmbmd->m_bFieldMV) { const CMotionVector *pmvTop = pmv + 1 + topRef; const CMotionVector *pmvBot = pmv + 3 + botRef; assert((topRef & ~1) == 0); assert((botRef & ~1) == 0); CoordI iMVX, iMVY; iMVX = 2*x + pmvTop->m_vctTrueHalfPel.x; iMVY = 2*y + pmvTop->m_vctTrueHalfPel.y; limitMVRangeToExtendedBBHalfPel(iMVX, iMVY, prctMVLimit, MB_SIZE); motionCompYField((PixelC *)pvopcPred->pixelsY(), // Luma top field pvopcRef->pixelsY() + topRef * m_iFrameWidthY, iMVX, iMVY); iMVX -= 2*x; iMVY -= 2*y; motionCompFieldUV((PixelC *)pvopcPred->pixelsU(), // Chroma top field (PixelC *)pvopcPred->pixelsV(), pvopcRef, x, y, (iMVX & 3) ? ((iMVX >> 1) | 1) : (iMVX >> 1), (iMVY & 6) ? ((iMVY >> 1) | 2) : (iMVY >> 1), topRef); iMVX = 2*x + pmvBot->m_vctTrueHalfPel.x; iMVY = 2*y + pmvBot->m_vctTrueHalfPel.y; limitMVRangeToExtendedBBHalfPel(iMVX, iMVY, prctMVLimit, MB_SIZE); motionCompYField((PixelC *)(pvopcPred->pixelsY()) + MB_SIZE, // Luma bottom field pvopcRef->pixelsY() + botRef * m_iFrameWidthY, iMVX, iMVY); iMVX -= 2*x; iMVY -= 2*y; motionCompFieldUV((PixelC *)(pvopcPred->pixelsU()) + BLOCK_SIZE, // Chroma bottom field (PixelC *)(pvopcPred->pixelsV()) + BLOCK_SIZE, pvopcRef, x, y, (iMVX & 3) ? ((iMVX >> 1) | 1) : (iMVX >> 1), (iMVY & 6) ? ((iMVY >> 1) | 2) : (iMVY >> 1), botRef); } else { // rounding control is messed up here motionComp((PixelC *)pvopcPred->pixelsY(), pvopcRef->pixelsY(), MB_SIZE, x * 2 + pmv->trueMVHalfPel().x, y * 2 + pmv->trueMVHalfPel().y, 0, prctMVLimit); motionCompUV((PixelC *)pvopcPred->pixelsU(), (PixelC *)pvopcPred->pixelsV(), pvopcRef, x, y, (pmv->m_vctTrueHalfPel.x & 3) ? ((pmv->m_vctTrueHalfPel.x >> 1) | 1) : (pmv->m_vctTrueHalfPel.x >> 1), (pmv->m_vctTrueHalfPel.y & 3) ? ((pmv->m_vctTrueHalfPel.y >> 1) | 1) : (pmv->m_vctTrueHalfPel.y >> 1), 0, prctMVLimit); }}Void CVideoObject::motionCompYField ( PixelC* ppxlcPred, // can be either Y or A const PixelC* ppxlcRefLeftTop, // point to left-top of the frame CoordI xRef, CoordI yRef // current coordinate system){ CoordI ix, iy; const PixelC* ppxlcRef = ppxlcRefLeftTop +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -