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

📄 motest.cpp

📁 此源码是在VC平台下,实现MPEG4编解码的源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
						m_iMAD += m_vopmd.bInterlace ?
							motionEstMB_BVOP_Interlaced (x, y, pmv, pmvBackward, pmbmd,
                                                     pmbmdRef, pmvRef, ppxlcRef0MBY, 
													 ppxlcRef1MBY,
													 bColocatedMBExist) :
// end of new changes
						motionEstMB_BVOP (
								x, y, 
								pmv, pmvBackward,
								pmbmd, 
								pmbmdRef, pmvRef,
								ppxlcRef0MBY, ppxlcRef1MBY,
								bColocatedMBExist
							);
						}
						else if (pmbmd->m_rgTranspStatus [0] == PARTIAL) {
// new changes
					m_iMAD += m_vopmd.bInterlace ?
                        motionEstMB_BVOP_InterlacedWithShape (x, y, pmv, pmvBackward, pmbmd,
                                                     pmbmdRef, pmvRef, ppxlcRef0MBY, 
													 ppxlcRef1MBY,
													 bColocatedMBExist) :
// end of new changes
					motionEstMB_BVOP_WithShape (
								x, y, 
								pmv, pmvBackward,
								pmbmd, 
								pmbmdRef, pmvRef,
								ppxlcRef0MBY, ppxlcRef1MBY,
								bColocatedMBExist
							);
						}
					}
				}
			}
			ppxlcOrigMBBY += MB_SIZE;
			pmbmd++;
			pmv         += BVOP_MV_PER_REF_PER_MB;
			pmvBackward += BVOP_MV_PER_REF_PER_MB;
			ppxlcOrigMBY += MB_SIZE;
			ppxlcRef0MBY += MB_SIZE;
			ppxlcRef1MBY += MB_SIZE;
		}
		ppxlcOrigY += m_iFrameWidthYxMBSize;
		ppxlcOrigBY += m_iFrameWidthYxMBSize;
		ppxlcRef0Y += m_iFrameWidthYxMBSize;
		ppxlcRef1Y += m_iFrameWidthYxMBSize;
	}
	if (m_iMVFileUsage == 2)
		writeBVOPMVs();
}

Void CVideoObjectEncoder::copyToCurrBuffWithShapeY (const PixelC* ppxlcCurrY, const PixelC* ppxlcCurrBY)
{
	Int iUnit = sizeof(PixelC); // NBIT: for memcpy
	PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY;
	PixelC* ppxlcCurrMBBY = m_ppxlcCurrMBBY;
	Int ic;
	for (ic = 0; ic < MB_SIZE; ic++) {
		memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*iUnit);
		memcpy (ppxlcCurrMBBY, ppxlcCurrBY, MB_SIZE*iUnit);
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += m_iFrameWidthY;
		ppxlcCurrMBBY += MB_SIZE; ppxlcCurrBY += m_iFrameWidthY;
	}
}

Void CVideoObjectEncoder::copyToCurrBuffY (const PixelC* ppxlcCurrY)
{
	Int iUnit = sizeof(PixelC); // NBIT: for memcpy
	PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY;
	Int ic;
	for (ic = 0; ic < MB_SIZE; ic++) {
		memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*iUnit);
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += m_iFrameWidthY;
	}
}

//for spatial sclability: basically set every mv to zero
Void CVideoObjectEncoder::motionEstMB_PVOP (CoordI x, CoordI y, 
											CMotionVector* pmv, CMBMode* pmbmd)
{
	pmbmd -> m_bhas4MVForward = FALSE;
	pmbmd-> m_dctMd = INTER;
	memset (pmv, 0, sizeof (CMotionVector) * PVOP_MV_PER_REF_PER_MB);
	for (UInt i = 0; i < PVOP_MV_PER_REF_PER_MB; i++)  {
		pmv -> computeTrueMV (); 
		pmv++;
	}
}

Int CVideoObjectEncoder::motionEstMB_PVOP (
	CoordI x, CoordI y, 
	CMotionVector* pmv, CMBMode* pmbmd, 
	const PixelC* ppxlcRefMBY
)
{
	Int nBits = m_volmd.nBits; // NBIT
	Int iFavorZero = FAVORZERO; // NBIT
	Int iFavorInter = FAVOR_INTER; // NBIT
	Int iFavor16x16 = FAVOR_16x16; // NBIT
	// NBIT: addjust mode selection thresholds
	if (nBits > 8) {
		iFavorZero <<= (nBits-8);
		iFavorInter <<= (nBits-8);
		iFavor16x16 <<= (nBits-8);
	} else if (nBits < 8) {
		iFavorZero >>= (8-nBits);
		iFavorInter >>= (8-nBits);
		iFavor16x16 >>= (8-nBits);
	}

	Int iInitSAD = sad16x16At0 (ppxlcRefMBY);
	Int iSADInter = blkmatch16 (pmv, x, y, x, y, iInitSAD, ppxlcRefMBY, m_puciRefQZoom0, m_vopmd.iSearchRangeForward);
	Int iSumDev = sumDev ();
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace (iSADInter, "MB_SAD16");
#endif // __TRACE_AND_STATS_

// INTERLACE
/* NBIT: change to a bigger number
	Int iSAD16x8 = 256*256;
*/
	Int iSAD16x8 = 4096*256;
	pmbmd -> m_bFieldMV = FALSE;
	if(m_vopmd.bInterlace) {
		// Field-Based Estimation
		CMotionVector* pmv16x8 = pmv + 5;
		const PixelC *ppxlcHalfPelRef = m_pvopcRefQ0->pixelsY()
			+ EXPANDY_REF_FRAME * m_iFrameWidthY + EXPANDY_REF_FRAME + x + y * m_iFrameWidthY; // 1.31.99 changes

		// top to top
		Int iSAD16x8top = blkmatch16x8 (pmv16x8, x, y, 0, ppxlcRefMBY,
			ppxlcHalfPelRef, m_vopmd.iSearchRangeForward);
		pmv16x8++;
		// bot to top
		Int iSAD16x8bot = blkmatch16x8 (pmv16x8, x, y, 0, ppxlcRefMBY + m_iFrameWidthY,
			ppxlcHalfPelRef + m_iFrameWidthY, m_vopmd.iSearchRangeForward);

		iSAD16x8=(iSAD16x8top<iSAD16x8bot) ? iSAD16x8top : iSAD16x8bot;
		pmbmd->m_bForwardTop = (iSAD16x8top<iSAD16x8bot) ? 0 : 1;
		pmv16x8++;
		// top to bot
		iSAD16x8top = blkmatch16x8 (pmv16x8, x, y, MB_SIZE, ppxlcRefMBY,
			ppxlcHalfPelRef, m_vopmd.iSearchRangeForward);
		pmv16x8++;
		// bot to bot
		iSAD16x8bot = blkmatch16x8 (pmv16x8, x, y, MB_SIZE, ppxlcRefMBY + m_iFrameWidthY,
			ppxlcHalfPelRef + m_iFrameWidthY, m_vopmd.iSearchRangeForward);
		iSAD16x8 += (iSAD16x8top<iSAD16x8bot) ? iSAD16x8top : iSAD16x8bot;
		pmbmd->m_bForwardBottom = (iSAD16x8top<iSAD16x8bot) ? 0 : 1;
	} else {
/* NBIT: change to a bigger number
		iSAD16x8 = 256*256;
*/
		iSAD16x8 = 4096*256;

		for (Int iBlk = 5; iBlk <= 8; iBlk++) {  // 04/28/99 david ruhoff
			pmv [iBlk] = pmv [0];   // fill in field info to make mv file deterministic
		}
	}
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace (iSAD16x8, "MB_SAD16x8");
#endif // __TRACE_AND_STATS_
// ~INTERLACE

	CoordI blkX, blkY;
	Int iSAD8 = 0;
	CMotionVector* pmv8 = pmv + 1;
	blkX = x + BLOCK_SIZE;
	blkY = y + BLOCK_SIZE;
	const PixelC* ppxlcCodedBlkY = m_ppxlcCurrMBY;

#ifdef __DISABLE_4MV_FOR_PVOP_
	iSAD8 = 4096*4096; // big number to disable 8x8 mode
#else

	// 8x8
	iSAD8 += blockmatch8 (ppxlcCodedBlkY, pmv8, x, y, pmv, m_vopmd.iSearchRangeForward);
	pmv8++;
	ppxlcCodedBlkY += BLOCK_SIZE;
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace (iSAD8, "MB_SAD8");
#endif // __TRACE_AND_STATS_

	iSAD8 += blockmatch8 (ppxlcCodedBlkY, pmv8, blkX, y, pmv, m_vopmd.iSearchRangeForward);
	pmv8++;
	ppxlcCodedBlkY += BLOCK_SIZE * MB_SIZE - BLOCK_SIZE;
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace (iSAD8, "MB_SAD8");
#endif // __TRACE_AND_STATS_

	iSAD8 += blockmatch8 (ppxlcCodedBlkY, pmv8, x, blkY, pmv, m_vopmd.iSearchRangeForward);
	pmv8++;
	ppxlcCodedBlkY += BLOCK_SIZE;
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace (iSAD8, "MB_SAD8");
#endif // __TRACE_AND_STATS_

	iSAD8 += blockmatch8 (ppxlcCodedBlkY, pmv8, blkX, blkY, pmv, m_vopmd.iSearchRangeForward);
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace (iSAD8, "MB_SAD8");
#endif // __TRACE_AND_STATS_
	
#endif // DISABLE_4MV_FOR_PVOP

/* NBIT: change
	iSADInter -= FAVOR_16x16;
*/
	iSADInter -= iFavor16x16;
	iSAD16x8 -= FAVOR_FIELD;
	if ((iSADInter <= iSAD8) && (iSADInter <= iSAD16x8)) {
/* NBIT: change
	    iSADInter += FAVOR_16x16;
*/
	    iSADInter += iFavor16x16;
		pmbmd -> m_bhas4MVForward = FALSE;
		pmv -> computeTrueMV (); // compute here instead of blkmatch to save computation
		for (UInt i = 1; i < PVOP_MV_PER_REF_PER_MB; i++) // didn't increment the last pmv
			pmv[i].m_vctTrueHalfPel = pmv->m_vctTrueHalfPel;	// Save (iMVX, iMVY) for MV file
	}
// INTERLACE
	else if (iSAD16x8 <= iSAD8) { // Field-based
		pmbmd -> m_bhas4MVForward = FALSE;
		pmbmd -> m_bFieldMV = TRUE;
		Int iTempX1, iTempY1, iTempX2, iTempY2;
		if(pmbmd->m_bForwardTop) {
			pmv [6].computeTrueMV ();
			iTempX1 = pmv[6].m_vctTrueHalfPel.x;
			iTempY1 = pmv[6].m_vctTrueHalfPel.y;
		}
		else {
			pmv [5].computeTrueMV ();
			iTempX1 = pmv[5].m_vctTrueHalfPel.x;
			iTempY1 = pmv[5].m_vctTrueHalfPel.y;
		}
		if(pmbmd->m_bForwardBottom) {
			pmv [8].computeTrueMV ();
			iTempX2 = pmv[8].m_vctTrueHalfPel.x;
			iTempY2 = pmv[8].m_vctTrueHalfPel.y;
		}
		else {
			pmv [7].computeTrueMV ();
			iTempX2 = pmv[7].m_vctTrueHalfPel.x;
			iTempY2 = pmv[7].m_vctTrueHalfPel.y;
		}
		iSADInter = iSAD16x8 + FAVOR_FIELD;
		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);
		}
	}
// ~INTERLACE
	else {
		pmv [1].computeTrueMV ();
		pmv [2].computeTrueMV ();
		pmv [3].computeTrueMV ();
		pmv [4].computeTrueMV ();
		pmbmd -> m_bhas4MVForward = TRUE;
		iSADInter = iSAD8;
	}
/* NBIT: change
	if (iSumDev < (iSADInter - FAVOR_INTER)) {
*/
	if (iSumDev < (iSADInter - iFavorInter)) {
		pmbmd -> m_bSkip = FALSE;
		pmbmd -> m_dctMd = INTRA;
		pmbmd -> m_bFieldMV = FALSE;
		memset (pmv, 0, PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
		return ((m_uiRateControl==RC_MPEG4) ? sumAbsCurrMB () : 0);
	}
	else {
		pmbmd -> m_dctMd = INTER;
		if (pmbmd->m_bhas4MVForward == FALSE
			&& pmbmd -> m_bFieldMV == FALSE
			&& pmv->m_vctTrueHalfPel.x == 0 && pmv->m_vctTrueHalfPel.y == 0)
/* NBIT: change
			return (iSADInter + FAVORZERO);
*/
			return (iSADInter + iFavorZero);
		else 
			return iSADInter;
	}
}

Int CVideoObjectEncoder::motionEstMB_PVOP_WithShape (
	CoordI x, CoordI y, 
	CMotionVector* pmv, CMBMode* pmbmd, 
	const PixelC* ppxlcRefMBY
)
{
	assert (pmbmd->m_rgTranspStatus [0] == PARTIAL);
	UInt nBits = m_volmd.nBits; // NBIT
	Int iFavorZero = FAVORZERO;
	Int iFavor16x16 = (pmbmd->m_rgNumNonTranspPixels [0] >> 1) + 1; // NBIT
	Int iFavorInter = pmbmd->m_rgNumNonTranspPixels [0] << 1; // NBIT
	// NBIT: addjust mode selection thresholds
	if (nBits > 8) {
		iFavor16x16 <<= (nBits-8);
		iFavorInter <<= (nBits-8);
		iFavorZero <<= (nBits-8);
	} else if (nBits < 8) {
		iFavor16x16 >>= (8-nBits);
		iFavorInter >>= (8-nBits);
		iFavorZero >>= (8-nBits);
	}

	Int iInitSAD = sad16x16At0WithShape (ppxlcRefMBY, pmbmd);
	Int iSADInter = blkmatch16WithShape (pmv, x, y, x, y, iInitSAD, ppxlcRefMBY, m_puciRefQZoom0, pmbmd, m_vopmd.iSearchRangeForward,0);
	Int iSumDev = sumDevWithShape (pmbmd -> m_rgNumNonTranspPixels [0]);
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace (iSADInter, "MB_SAD16");
#endif // __TRACE_AND_STATS_
// INTERLACE
// New Changes
	Int iSAD16x8 = 4096*256;
	pmbmd -> m_bFieldMV = FALSE;
	if(m_vopmd.bInterlace) {
		// Field-Based Estimation
		CMotionVector* pmv16x8 = pmv + 5;
		const PixelC *ppxlcHalfPelRef = m_pvopcRefQ0->pixelsY()
			+ EXPANDY_REF_FRAME * m_iFrameWidthY + EXPANDY_REF_FRAME + x + y * m_iFrameWidthY; // 1.31.99 changes

		// top to top
		Int iSAD16x8top = blkmatch16x8WithShape (pmv16x8, x, y, 0, ppxlcRefMBY,
			ppxlcHalfPelRef, m_vopmd.iSearchRangeForward,0);
		pmv16x8++;
		// bot to top
		Int iSAD16x8bot = blkmatch16x8WithShape (pmv16x8, x, y, 0, ppxlcRefMBY + m_iFrameWidthY,
			ppxlcHalfPelRef + m_iFrameWidthY, m_vopmd.iSearchRangeForward,0);

		iSAD16x8=(iSAD16x8top<iSAD16x8bot) ? iSAD16x8top : iSAD16x8bot;
		pmbmd->m_bForwardTop = (iSAD16x8top<iSAD16x8bot) ? 0 : 1;
		pmv16x8++;
		// top to bot
		iSAD16x8top = blkmatch16x8WithShape (pmv16x8, x, y, MB_SIZE, ppxlcRefMBY,
			ppxlcHalfPelRef, m_vopmd.iSearchRangeForward,0);
		pmv16x8++;
		// bot to bot
		iSAD16x8bot = blkmatch16x8WithShape (pmv16x8, x, y, MB_SIZE, ppxlcRefMBY + m_iFrameWidthY,
			ppxlcHalfPelRef + m_iFrameWidthY, m_vopmd.iSearchRangeForward,0);
		iSAD16x8 += (iSAD16x8top<iSAD16x8bot) ? iSAD16x8top : iSAD16x8bot;
		pmbmd->m_bForwardBottom = (iSAD16x8top<iSAD16x8bot) ? 0 : 1;
	} else {
		iSAD16x8 = 4096*256;

		for (Int iBlk = 5; iBlk <= 8; iBlk++) {  // 04/28/99 david ruhoff
			pmv [iBlk] = pmv [0];   // fill in field info to make mv file deterministic
		}
	}
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace (iSAD16x8, "MB_SAD16x8");
#endif // __TRACE_AND_STATS_
// end of New changes
// ~INTERLACE

	CoordI blkX, blkY;
	Int iSAD8 = 0;
	CMotionVector* pmv8 = pmv + 1;
	blkX = x + BLOCK_SIZE;
	blkY = y + BLOCK_SIZE;
	const PixelC* ppxlcCodedBlkY = m_ppxlcCurrMBY;
	const PixelC* ppxlcCodedBlkBY = m_ppxlcCurrMBBY;

	// 8 x 8
	iSAD8 += 
		(pmbmd->m_rgTranspStatus [1] == PARTIAL) ? blockmatch8WithShape (ppxlcCodedBlkY, ppxlcCodedBlkBY, pmv8, x, y, pmv, m_vopmd.iSearchRangeForward,0) :
		(pmbmd->m_rgTranspStatus [1] == NONE) ? blockmatch8 (ppxlcCodedBlkY, pmv8, x, y, pmv, m_vopmd.iSearchRangeForward) : 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -