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

📄 shpenc.cpp

📁 此源码是在VC平台下,实现MPEG4编解码的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			UInt nBitsMV=0;
			UInt nBitsModeInter = codeShapeModeInter (pmbmd->m_shpmd, shpmdColocatedMB);
			if(pmbmd->m_shpmd==INTER_CAE_MVDNZ)
				nBitsMV = encodeMVDS (mvBYD);
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace ("MB_CAE_INTER_VERTICAL_CODING (TRIAL)");
#endif // __TRACE_AND_STATS_
			UInt nBitsVInter = encodeCAEInter (pmbmd->m_shpmd, VERTICAL);
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace ("MB_CAE_INTER_HORIZONTAL_CODING (TRIAL)");
#endif // __TRACE_AND_STATS_
			UInt nBitsHInter = encodeCAEInter (pmbmd->m_shpmd, HORIZONTAL);
			UInt nBitsInter = nBitsModeInter + nBitsMV + min (nBitsVInter, nBitsHInter);

			m_pbitstrmShapeMBOut->gotoBookmark ();
			
			if (nBitsInter < nBitsIntra)
			{
				// choose inter coding
#ifdef __TRACE_AND_STATS_
				m_pbitstrmOut->trace ("MB_CAE_INTER_CODING (REAL)");
				m_pbitstrmOut->trace (mvShapeMVP, "MB_SHP_MV_PRED (half pel)");
				m_pbitstrmOut->trace (*pmvBY, "MB_SHP_MV (half pel)");
				m_pbitstrmOut->trace (mvBYD, "MB_SHP_MVD (half pel)");
#endif // __TRACE_AND_STATS_
				codeShapeModeInter (pmbmd->m_shpmd, shpmdColocatedMB);
				if(pmbmd->m_shpmd==INTER_CAE_MVDNZ)
					encodeMVDS (mvBYD);
				if(nBitsVInter<nBitsHInter)
					encodeCAEInter (pmbmd->m_shpmd, VERTICAL);
				else
					encodeCAEInter (pmbmd->m_shpmd, HORIZONTAL);
				return nBitsInter;
			}
			else
			{
				// choose intra coding
#ifdef __TRACE_AND_STATS_
				m_pbitstrmOut->trace ("MB_CAE_INTRA_CODING (REAL)");
#endif // __TRACE_AND_STATS_
				pmvBY->iMVX = NOT_MV;
				pmvBY->iMVY = NOT_MV;
				pmbmd->m_shpmd = INTRA_CAE;
				codeShapeModeInter (pmbmd->m_shpmd, shpmdColocatedMB);
				if(nBitsVIntra<nBitsHIntra)
					encodeCAEIntra (pmbmd->m_shpmd, VERTICAL);
				else
					encodeCAEIntra (pmbmd->m_shpmd, HORIZONTAL);
				return nBitsIntra;
			}
		}
	case MVDZ_NOUPDT:
	case MVDNZ_NOUPDT:
		{
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace ("MB_CAE_INTER_CODING_NO_UPDATE");
			m_pbitstrmOut->trace (mvShapeMVP, "MB_SHP_MV_PRED (half pel)");
			m_pbitstrmOut->trace (*pmvBY, "MB_SHP_MV (half pel)");
			m_pbitstrmOut->trace (mvBYD, "MB_SHP_MVD (half pel)");
#endif // __TRACE_AND_STATS_
			copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, m_puciPredBAB->pixels (), MC_BAB_SIZE, MC_BAB_BORDER);
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace ((PixelC *)m_puciPredBAB->pixels(), MC_BAB_SIZE, MC_BAB_SIZE, "MB_MC_PRED_BAB");
#endif // __TRACE_AND_STATS_
			Int nBits = codeShapeModeInter (pmbmd->m_shpmd, shpmdColocatedMB);
			if(pmbmd->m_shpmd==MVDNZ_NOUPDT)
				nBits += encodeMVDS (mvBYD);	
			return nBits;
		}
	default:
		assert(FALSE);
		return 0;
	}
}

UInt CVideoObjectEncoder::codeShapeModeIntra (ShapeMode shpmd, const CMBMode* pmbmd, Int iMBX, Int iMBY)
{	
	UInt nBits = 0;
	assert (shpmd == ALL_TRANSP || shpmd == ALL_OPAQUE || shpmd == INTRA_CAE);

	static Int iLeftTopMostMB = 0;
	Int iRightMostMB = m_iNumMBX - 1;

	//get previous shape codes; 
	Bool bLeftBndry, bRightTopBndry, bTopBndry, bLeftTopBndry;
	Int iMBnum = VPMBnum(iMBX, iMBY);
	bLeftBndry = bVPNoLeft(iMBnum, iMBX);
	bTopBndry = bVPNoTop(iMBnum);
	bRightTopBndry = bVPNoRightTop(iMBnum, iMBX);
	bLeftTopBndry = bVPNoLeftTop(iMBnum, iMBX);

	ShapeMode shpmdTop		= ALL_TRANSP;
	ShapeMode shpmdTopRight = ALL_TRANSP;
	ShapeMode shpmdTopLeft	= ALL_TRANSP;
	ShapeMode shpmdLeft		= ALL_TRANSP;
	// Modified for error resilient mode by Toshiba(1997-11-14)
	if (!bTopBndry)		
		shpmdTop = (pmbmd - m_iNumMBX)->m_shpmd;
	if (!bRightTopBndry)	
		shpmdTopRight = (pmbmd - m_iNumMBX + 1)->m_shpmd;
	if (!bLeftBndry)	
		shpmdLeft = (pmbmd - 1)->m_shpmd;
	if (!bLeftTopBndry)	
		shpmdTopLeft = (pmbmd - m_iNumMBX - 1)->m_shpmd;
	//if (iMBY > iLeftTopMostMB)	{
	//	shpmdTop = (pmbmd - m_iNumMBX)->m_shpmd;
	//	if (iMBX < iRightMostMB)
	//		shpmdTopRight = (pmbmd - m_iNumMBX + 1)->m_shpmd;
	//}
	//if (iMBX > iLeftTopMostMB)	{
	//	shpmdLeft = (pmbmd - 1)->m_shpmd;
	//	if (iMBY > iLeftTopMostMB)
	//		shpmdTopLeft = (pmbmd - m_iNumMBX - 1)->m_shpmd;
	//}
	//	End Toshiba(1997-11-14)
	assert (shpmdTop != UNKNOWN && shpmdTopRight != UNKNOWN && 
			shpmdTopLeft != UNKNOWN && shpmdLeft != UNKNOWN);
	//get code and its size
	UInt uiTblIndex			= shpmdTopLeft * 81 +  shpmdTop * 27 +					
							  shpmdTopRight * 9 + shpmdLeft * 3 + shpmd;
	assert (uiTblIndex >= 0 && uiTblIndex < 243);
	assert (grgchFirstShpCd [uiTblIndex] == 0 || grgchFirstShpCd [uiTblIndex] == 2 || 
			grgchFirstShpCd [uiTblIndex] == 3);
	// Modified for error resilient mode by Toshiba(1997-11-14)
	UInt nCodeSize	= (grgchFirstShpCd [uiTblIndex] == 0) ? 1
			 : grgchFirstShpCd [uiTblIndex];
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace ((Int) shpmd, "MB_Curr_ShpMd");
#endif // __TRACE_AND_STATS_
	m_pbitstrmShapeMBOut->putBits ((Int) 1, nCodeSize, "MB_Shape_Mode");
	//	End Toshiba(1997-11-14)
	nBits += nCodeSize;
	return nBits;
}

UInt CVideoObjectEncoder::codeShapeModeInter (const ShapeMode& shpmd, const ShapeMode& shpmdColocatedMB)
{		
	assert (shpmdColocatedMB != UNKNOWN && shpmd != UNKNOWN);
	UInt nBits = 0;
	CEntropyEncoder* pentrenc = m_pentrencSet->m_ppentrencShapeMode [shpmdColocatedMB];
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace ((Int) shpmdColocatedMB, "MB_Colocated_ShpMd");
	m_pbitstrmOut->trace ((Int) shpmd, "MB_Curr_ShpMd");
#endif // __TRACE_AND_STATS_
	pentrenc->attachStream(*m_pbitstrmShapeMBOut);
	nBits += pentrenc->encodeSymbol (shpmd, "MB_Shape_Mode");
	pentrenc->attachStream(*m_pbitstrmOut);
	return nBits;
}

// find appropriate size for coded babs
ShapeMode CVideoObjectEncoder::round (PixelC* ppxlcSrcFrm, const CMBMode* pmbmd)					//only to partial BABs
{
	ShapeMode shpmd;
	Bool bIsErrorLarge;

	if (m_volmd.bNoCrChange == FALSE)
	{
		// attempt to reduce bab size
		m_bNoShapeChg = FALSE;
		static iThreshD4 = 7 * OPAQUE;
		
		// reduce by factor 4
		downSampleShape (m_ppxlcCurrMBBY, 
						   m_rgiSubBlkIndx16x16,
						   m_ppxlcCurrMBBYDown4, 
						   m_rgiPxlIndx8x8,
						   4, iThreshD4, 16);

		// see if this size is acceptable
		shpmd = INTRA_CAE;
		m_iInverseCR = 4;
		m_iWidthCurrBAB = 8;
		
		// subsample border before upsample to original size
		subsampleLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcCurrMBBYDown4);
		makeRightBottomBorder (m_ppxlcCurrMBBYDown4, 8);
		upSampleShape(ppxlcSrcFrm,m_ppxlcCurrMBBYDown4,m_ppxlcReconCurrBAB);
		
		// check if approximation is acceptable
		bIsErrorLarge = isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16,
			m_ppxlcReconCurrBAB, m_rgiSubBlkIndx20x20, 20, pmbmd);
		if(!bIsErrorLarge)
		{
			// ok, so assign encoding buffer
			m_rgpxlcCaeSymbol = m_ppxlcCurrMBBYDown4; 
			return shpmd;
		}

		static iThreshD2 = OPAQUE;

		// factor 4 failed, so try to reduce by factor 2
		downSampleShape (m_ppxlcCurrMBBY, 
						   m_rgiSSubBlkIndx16x16,
						   m_ppxlcCurrMBBYDown2, 
						   m_rgiPxlIndx12x12,
						   2, iThreshD2, 64);

		// mixed, so see if this size is acceptable
		shpmd = INTRA_CAE;
		m_iInverseCR = 2;
		m_iWidthCurrBAB = 12;

		// subsample border before upsample to original size
		subsampleLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcCurrMBBYDown2);
		makeRightBottomBorder (m_ppxlcCurrMBBYDown2, 12);
		upSampleShape(ppxlcSrcFrm,m_ppxlcCurrMBBYDown2, m_ppxlcReconCurrBAB);

		// check if approximation is acceptable
		bIsErrorLarge = isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16,
			m_ppxlcReconCurrBAB, m_rgiSubBlkIndx20x20, 20, pmbmd);
		if(!bIsErrorLarge)
		{
			// ok, so assign encoding buffer
			m_rgpxlcCaeSymbol = m_ppxlcCurrMBBYDown2; 
			return shpmd;
		}
	}

	// has to be original size
	m_bNoShapeChg = TRUE;
	shpmd = INTRA_CAE;
	m_iInverseCR = 1;
	m_iWidthCurrBAB = BAB_SIZE;

	// copy data to ReconCurrBAB
	PixelC* ppxlcDst = m_ppxlcReconCurrBAB + BAB_BORDER + BAB_BORDER * TOTAL_BAB_SIZE;
	PixelC* ppxlcSrc = m_ppxlcCurrMBBY;
	Int iUnit = sizeof(PixelC); // NBIT: for memcpy
	Int i;
	for (i = 0; i < MB_SIZE; i++) {
		memcpy (ppxlcDst, ppxlcSrc, MB_SIZE*iUnit);
		ppxlcSrc += MB_SIZE;
		ppxlcDst += BAB_SIZE;
	}

	// make borders
	copyLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcReconCurrBAB);
	makeRightBottomBorder (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE);	

	// assign encoding buffer
	m_rgpxlcCaeSymbol = m_ppxlcReconCurrBAB;
	return shpmd;
}


Int CVideoObjectEncoder::downSampleShape (const PixelC* ppxlcSrc, 
								   Int* rgiSrcSubBlk,
								   PixelC* ppxlcDst, 
								   Int* piDstPxl, 
								   Int iRate,
								   Int iThreshold,
								   Int nSubBlk)
{
	Int nOpaquePixel = 0, iSum = 0;
	Int iSubBlk;
	for (iSubBlk = 0; iSubBlk < nSubBlk; iSubBlk++)	{
		Int i = rgiSrcSubBlk [iSubBlk];
		iSum = 0;
		for (CoordI iY = 0; iY < iRate; iY++)	{
			for (CoordI iX = 0; iX < iRate; iX++)  {
				iSum += abs (ppxlcSrc [i++]);  //abs???
			}
			i += MB_SIZE - iRate;
		}
		ppxlcDst [*piDstPxl] = (iSum > iThreshold) ? OPAQUE : TRANSPARENT;
		nOpaquePixel += ppxlcDst [*piDstPxl];
		piDstPxl++;
	}		
	return (nOpaquePixel /= OPAQUE);
}

Bool CVideoObjectEncoder::isErrorLarge (const PixelC* rgppxlcSrc, const Int* rgiSubBlkIndx, Int iWidthSrc, PixelC pxlcRecon, const CMBMode* pmbmd)
{
	if (pmbmd->m_bhas4MVForward == TRUE)	{
		if (!sameBlockTranspStatus (pmbmd, pxlcRecon))	
			return TRUE;
	} 

	//check error in each 4x4 subblock
	Int iSubBlk;
	Int iError = 0;
	for (iSubBlk = 0; iSubBlk < 16; iSubBlk++)	{
		Int i = rgiSubBlkIndx [iSubBlk];
		for (CoordI iY = 0; iY < 4; iY++)	{
			for (CoordI iX = 0; iX < 4; iX++)  {
				iError += abs (rgppxlcSrc [i++] - pxlcRecon);
			}
			if (iError > m_volmd.iBinaryAlphaTH) 
				return TRUE;
			i += iWidthSrc - 4;
		}
	}		
	return FALSE;
}

Bool CVideoObjectEncoder::isErrorLarge (const PixelC* rgppxlcSrc, const Int* rgiSubBlkIndxSrc, const Int iSizeSrc,
								const PixelC* rgppxlcDst, const Int* rgiSubBlkIndxDst, const Int iSizeDst, const CMBMode* pmbmd)
{
	if (pmbmd->m_bhas4MVForward == TRUE)	{
		if (!sameBlockTranspStatus (pmbmd, rgppxlcDst, iSizeDst))	
			return TRUE;
	} 

	//check error in each 4x4 subblock
	Int iSubBlk;
	Int iError = 0;
	for (iSubBlk = 0; iSubBlk < 16; iSubBlk++)	{

⌨️ 快捷键说明

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