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

📄 mvdec.cpp

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	    } 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 + -