⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mc.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					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 + -