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

📄 mbenc.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
{
	PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY;
	PixelC* ppxlcCurrMBU = m_ppxlcCurrMBU;
	PixelC* ppxlcCurrMBV = m_ppxlcCurrMBV;
	Int ic;
	for (ic = 0; ic < BLOCK_SIZE; ic++) {
		memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*sizeof(PixelC));
		memcpy (ppxlcCurrMBU, ppxlcCurrU, BLOCK_SIZE*sizeof(PixelC));
		memcpy (ppxlcCurrMBV, ppxlcCurrV, BLOCK_SIZE*sizeof(PixelC));
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += iWidthY;
		ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrU += iWidthUV;
		ppxlcCurrMBV += BLOCK_SIZE;	ppxlcCurrV += iWidthUV;
		
		memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*sizeof(PixelC)); // two rows for Y
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += iWidthY;
	}
}

// compute error signal

Void CVideoObjectEncoder::computeTextureError ()
{
	CoordI ix;
	// Y
	for (ix = 0; ix < MB_SQUARE_SIZE; ix++)
		m_ppxliErrorMBY [ix] = m_ppxlcCurrMBY [ix] - m_ppxlcPredMBY [ix];

	// UV
	for (ix = 0; ix < BLOCK_SQUARE_SIZE; ix++) {
		m_ppxliErrorMBU [ix] = m_ppxlcCurrMBU [ix] - m_ppxlcPredMBU [ix];
		m_ppxliErrorMBV [ix] = m_ppxlcCurrMBV [ix] - m_ppxlcPredMBV [ix];
	}

	// Alpha
	if(m_volmd.fAUsage==EIGHT_BIT)
		for (ix = 0; ix < MB_SQUARE_SIZE; ix++)
			m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix];
}

Void CVideoObjectEncoder::computeTextureErrorWithShape ()
{
	CoordI ix;
	// Y
	for (ix = 0; ix < MB_SQUARE_SIZE; ix++) {
		if (m_ppxlcCurrMBBY [ix] == transpValue)
			m_ppxliErrorMBY [ix] = 0; // zero padding
		else
			m_ppxliErrorMBY [ix] = m_ppxlcCurrMBY [ix] - m_ppxlcPredMBY [ix];
	}

	// UV
	for (ix = 0; ix < BLOCK_SQUARE_SIZE; ix++) {
		if (m_ppxlcCurrMBBUV [ix] == transpValue)
			m_ppxliErrorMBU [ix] = m_ppxliErrorMBV [ix] = 0;
		else {
			m_ppxliErrorMBU [ix] = m_ppxlcCurrMBU [ix] - m_ppxlcPredMBU [ix];
			m_ppxliErrorMBV [ix] = m_ppxlcCurrMBV [ix] - m_ppxlcPredMBV [ix];
		}
	}

	if(m_volmd.fAUsage==EIGHT_BIT)
		for (ix = 0; ix < MB_SQUARE_SIZE; ix++) {
			if (m_ppxlcCurrMBBY [ix] == transpValue)
				m_ppxliErrorMBA [ix] = 0; // zero padding
			else
				m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix];
		}
}

Void CVideoObjectEncoder::computeAlphaError ()
{
	CoordI ix;

	for (ix = 0; ix < MB_SQUARE_SIZE; ix++) {
		if (m_ppxlcCurrMBBY [ix] == transpValue)
			m_ppxliErrorMBA [ix] = 0; // zero padding
		else
			m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix];
	}
}

Void CVideoObjectEncoder::quantizeTextureIntraMB (	
	Int imbX, Int imbY,
	CMBMode* pmbmd, 
	PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV,
	PixelC* ppxlcCurrQMBA
)
{
	assert (pmbmd != NULL);
	assert (pmbmd -> m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ);
	assert (pmbmd -> m_rgTranspStatus [0] != ALL);

	Int iQP = pmbmd->m_stepSize;
#ifdef __TRACE_AND_STATS_
	m_statsMB.nQMB++;
	m_statsMB.nQp += iQP;
#endif // __TRACE_AND_STATS_

	Int iDcScalerY, iDcScalerC, iDcScalerA = 0;
	if (iQP <= 4)
	{
		iDcScalerY = 8;
		iDcScalerC = 8;
	}
	else if (iQP >= 5 && iQP <= 8)
	{
		iDcScalerY = 2 * iQP;
		iDcScalerC = (iQP + 13) / 2;
	}
	else if (iQP >= 9 && iQP <= 24)
	{
		iDcScalerY = iQP + 8;
		iDcScalerC = (iQP + 13) / 2;
	}
	else
	{
		iDcScalerY = 2 * iQP - 16;
		iDcScalerC = iQP - 6;
	}

	Int iQPA = 0;
	pmbmd->m_CODAlpha = ALPHA_CODED;
	if(m_volmd.fAUsage == EIGHT_BIT)
	{
		if (pmbmd -> m_stepSizeAlpha < 1)
			pmbmd -> m_stepSizeAlpha = 1;
		iQPA = pmbmd->m_stepSizeAlpha;

		if (iQPA <= 4)
			iDcScalerA = 8;
		else if (iQPA >= 5 && iQPA <= 8)
			iDcScalerA = 2 * iQPA;
		else if (iQPA >= 9 && iQPA <= 24)
			iDcScalerA = iQPA + 8;
		else
			iDcScalerA = 2 * iQPA - 16;

		if(pmbmd->m_rgTranspStatus [0] == NONE)
		{
			// need to test gray alpha vals
			// CODA = 1 if all==255, can't use TranspStatus, has to be 255
			Int i;
			Int iThresh = 256 - iQPA;
			pmbmd->m_CODAlpha = ALPHA_ALL255;
			for(i = 0; i<MB_SQUARE_SIZE; i++)
				if(m_ppxlcCurrMBA[i]<=iThresh)
				{
					pmbmd->m_CODAlpha = ALPHA_CODED;
					break;
				}
			if(pmbmd->m_CODAlpha == ALPHA_ALL255)
			{
				pxlcmemset(m_ppxlcCurrMBA, 255, MB_SQUARE_SIZE);
				PixelC *ppxlc = ppxlcCurrQMBA;
				for(i = 0; i<MB_SIZE; i++, ppxlc += m_iFrameWidthY)
					pxlcmemset(ppxlc, 255, MB_SIZE);
			}
		}	
	}

	Int iCoefToStart;
	assert (pmbmd -> m_stepSizeDelayed > 0);
	if (pmbmd -> m_stepSizeDelayed >= grgiDCSwitchingThreshold [m_vopmd.iIntraDcSwitchThr])
	{
		pmbmd->m_bCodeDcAsAc = TRUE;
		//pmbmd->m_bCodeDcAsAcAlpha = TRUE; // decision should really be based on alpha quantiser
		iCoefToStart = 0;
	}
	else {
		pmbmd->m_bCodeDcAsAc = FALSE;
		//pmbmd->m_bCodeDcAsAcAlpha = FALSE;
		iCoefToStart = 1;
	}
	pmbmd->m_bCodeDcAsAcAlpha = FALSE;

	//for intra pred
	MacroBlockMemory* pmbmLeft = NULL;
	MacroBlockMemory* pmbmTop = NULL;
	MacroBlockMemory* pmbmLeftTop = NULL;
	CMBMode* pmbmdLeft = NULL;
	CMBMode* pmbmdTop = NULL;
	CMBMode* pmbmdLeftTop = NULL;											 
	Int iMBnum = imbY * m_iNumMBX + imbX;
	if (!bVPNoTop(iMBnum))	{
		pmbmTop  = m_rgpmbmAbove [imbX];
		pmbmdTop = pmbmd - m_iNumMBX;
	}
	if (!bVPNoLeft(iMBnum, imbX))	{
		pmbmLeft  = m_rgpmbmCurr [imbX - 1];
		pmbmdLeft = pmbmd -  1;
	}
	if (!bVPNoLeftTop(iMBnum, imbX))	{
		pmbmLeftTop  = m_rgpmbmAbove [imbX - 1];
		pmbmdLeftTop = pmbmd - m_iNumMBX - 1;
	}

// INTERLACE
	if((pmbmd->m_rgTranspStatus [0] == NONE)&&(m_vopmd.bInterlace == TRUE) ) {
		pmbmd->m_bFieldDCT = FrameFieldDCTDecideC(m_ppxlcCurrMBY);
		m_statsMB.nFieldDCTMB += (Int) pmbmd->m_bFieldDCT;
	}
	else
		pmbmd->m_bFieldDCT = 0;

	pmbmd->m_bSkip = FALSE;		// for direct mode reference 
// ~INTERLACE

	PixelC* rgchBlkDst = NULL;
	PixelC* rgchBlkSrc = NULL;
	Int iWidthDst, iWidthSrc;
	Int iDcScaler;
	Int* rgiCoefQ;
	Int iSumErr = 0; //sum of error to determine intra ac prediction
	Int iBlk;
	Int iBlkEnd;
	if(m_volmd.fAUsage == EIGHT_BIT)
		iBlkEnd = A_BLOCK4;
	else
		iBlkEnd = V_BLOCK;

	for (iBlk = (Int) Y_BLOCK1; iBlk <= iBlkEnd; iBlk++) { // + 1 is because of the indexing
		if (iBlk < (Int) U_BLOCK || iBlk > (Int) V_BLOCK) {
			if(iBlk==A_BLOCK1)
				iSumErr = 0; // start again for alpha
			if (pmbmd -> m_rgTranspStatus [iBlk % 6] == ALL) // %6 hack!!
				continue;
			switch (iBlk) 
			{
			case (Y_BLOCK1): 
				rgchBlkDst = ppxlcCurrQMBY;
				rgchBlkSrc = m_ppxlcCurrMBY;
				break;
			case (Y_BLOCK2): 
				rgchBlkDst = ppxlcCurrQMBY + BLOCK_SIZE;
				rgchBlkSrc = m_ppxlcCurrMBY + BLOCK_SIZE;
				break;
			case (Y_BLOCK3): 
				rgchBlkDst = ppxlcCurrQMBY + m_iFrameWidthYxBlkSize;
				rgchBlkSrc = m_ppxlcCurrMBY + MB_SIZE * BLOCK_SIZE;
				break;
			case (Y_BLOCK4): 
				rgchBlkDst = ppxlcCurrQMBY + m_iFrameWidthYxBlkSize + BLOCK_SIZE;
				rgchBlkSrc = m_ppxlcCurrMBY + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE;
				break;
			case (A_BLOCK1):
				rgchBlkDst = ppxlcCurrQMBA;
				rgchBlkSrc = m_ppxlcCurrMBA;
				break;
			case (A_BLOCK2):
				rgchBlkDst = ppxlcCurrQMBA + BLOCK_SIZE;
				rgchBlkSrc = m_ppxlcCurrMBA + BLOCK_SIZE;
				break;
			case (A_BLOCK3):
				rgchBlkDst = ppxlcCurrQMBA + m_iFrameWidthYxBlkSize;
				rgchBlkSrc = m_ppxlcCurrMBA + MB_SIZE * BLOCK_SIZE;
				break;
			case (A_BLOCK4):
				rgchBlkDst = ppxlcCurrQMBA + m_iFrameWidthYxBlkSize + BLOCK_SIZE;
				rgchBlkSrc = m_ppxlcCurrMBA + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE;
				break;
			}
			iWidthDst = m_iFrameWidthY;
			iWidthSrc = MB_SIZE;
			if(iBlk<=V_BLOCK)
				iDcScaler = iDcScalerY; //m_rgiDcScalerY [iQP];
			else
				iDcScaler = iDcScalerA;
		}
		else {
			iWidthDst = m_iFrameWidthUV;
			iWidthSrc = BLOCK_SIZE;
			rgchBlkDst = (iBlk == U_BLOCK) ? ppxlcCurrQMBU: ppxlcCurrQMBV;
			rgchBlkSrc = (iBlk == U_BLOCK) ? m_ppxlcCurrMBU: m_ppxlcCurrMBV;
			iDcScaler = iDcScalerC; //m_rgiDcScalerC [iQP];
		}
		
		if (m_volmd.nBits<=8) { // NBIT: not always valid when nBits>8
			assert(iDcScaler > 0 && iDcScaler < 128);
		}

		rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
		iSumErr += quantizeIntraBlockTexture (
			rgchBlkSrc,
			iWidthSrc,
			rgchBlkDst,
			iWidthDst,
			rgiCoefQ, 
			(iBlk<=V_BLOCK ? iQP : iQPA), 
			iDcScaler,
			iBlk,	//from here til last
			pmbmLeft, 
			pmbmTop, 
			pmbmLeftTop, 
			m_rgpmbmCurr [imbX],
			pmbmdLeft, 
			pmbmdTop, 
			pmbmdLeftTop, 
			pmbmd
		); //all for intra-pred
		if(iBlk>=A_BLOCK1)
			pmbmd->m_bACPredictionAlpha	= (pmbmd->m_CODAlpha == ALPHA_CODED && iSumErr >= 0);
		else
			pmbmd->m_bACPrediction =(iSumErr >= 0);
		/*BBM// Added for Boundary by Hyundai(1998-5-9)
        if (m_vopmd.bInterlace && pmbmd->m_bMerged [0]) {
                Int iDstBlk = 0;
                switch (iBlk) {
                        case (Y_BLOCK1):
                                if (pmbmd->m_bMerged [1])       iDstBlk = (Int) Y_BLOCK2;
                                else if (pmbmd->m_bMerged [3])  iDstBlk = (Int) Y_BLOCK3;
                                else if (pmbmd->m_bMerged [5])  iDstBlk = (Int) Y_BLOCK4;
                                break;
                        case (Y_BLOCK2):
                                if (pmbmd->m_bMerged [4])       iDstBlk = (Int) Y_BLOCK4;
                                else if (pmbmd->m_bMerged [6])  iDstBlk = (Int) Y_BLOCK3;
                                break;
                        case (Y_BLOCK3):
                                if (pmbmd->m_bMerged [2])       iDstBlk = (Int) Y_BLOCK4;
                                break;
                        case (A_BLOCK1):
                                if (pmbmd->m_bMerged [1])       iDstBlk = (Int) A_BLOCK2;
                                else if (pmbmd->m_bMerged [3])  iDstBlk = (Int) A_BLOCK3;
                                else if (pmbmd->m_bMerged [5])  iDstBlk = (Int) A_BLOCK4;
                                break;
                        case (A_BLOCK2):
                                if (pmbmd->m_bMerged [4])       iDstBlk = (Int) A_BLOCK4;
                                else if (pmbmd->m_bMerged [6])  iDstBlk = (Int) A_BLOCK3;
                                break;
                        case (A_BLOCK3):
                                if (pmbmd->m_bMerged [2])       iDstBlk = (Int) A_BLOCK4;
                                break;
                }
                if (iDstBlk) {
                        MacroBlockMemory* pmbmCurr = m_rgpmbmCurr [imbX];
                        pmbmCurr->rgblkm [iDstBlk-1][0] = pmbmCurr->rgblkm [iBlk-1][0];
                        for (UInt x = 1; x < (BLOCK_SIZE<<1)-1; x++)
                                pmbmCurr->rgblkm [iDstBlk-1][x] = 0;
                }
        }
		// End of Hyundai(1998-5-9)*/
	}

// INTERLACE
	if ((pmbmd->m_rgTranspStatus [0] == NONE) && (m_vopmd.bInterlace == TRUE) && (pmbmd->m_bFieldDCT == TRUE))
		fieldDCTtoFrameC(ppxlcCurrQMBY);
// ~INTERLACE

	for (iBlk = (UInt) Y_BLOCK1; iBlk <= iBlkEnd; iBlk++) { // + 1 is because of the indexing
		if (pmbmd->m_rgTranspStatus [iBlk % 6] == ALL) { // hack %6 ok if [6]==[0]
			pmbmd->setCodedBlockPattern ((BlockNum) iBlk, FALSE);
			continue;
		}
		rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
		if (iBlk < (Int) U_BLOCK) 
			iDcScaler = iDcScalerY; //m_rgiDcScalerY [iQP];
		else if(iBlk < (Int) A_BLOCK1)
			iDcScaler = iDcScalerC; //m_rgiDcScalerC [iQP];
		else
			iDcScaler = iDcScalerA;

		intraPred ((BlockNum) iBlk, pmbmd, rgiCoefQ,
			(iBlk<=V_BLOCK ? iQP : iQPA), iDcScaler, m_rgblkmCurrMB [iBlk - 1], m_rgiQPpred [iBlk - 1]);
		Bool bCoded = FALSE;
		UInt i;
		if(iBlk >=(Int) A_BLOCK1)
			iCoefToStart = pmbmd->m_bCodeDcAsAcAlpha==TRUE ? 0 : 1;

		for (i = iCoefToStart; i < BLOCK_SQUARE_SIZE; i++) {
			if (rgiCoefQ [i] != 0)	{
				bCoded = TRUE;
				break;
			}
		}
		pmbmd->setCodedBlockPattern ((BlockNum) iBlk, bCoded);
	}
}

Void CVideoObjectEncoder::quantizeTextureInterMB (CMBMode* pmbmd, 
												  const CMotionVector* pmv, 
												  PixelC *ppxlcCurrQMBA,
												  Bool bSkip)	//bSkip: tested mv is zero
{
	assert (pmbmd != NULL);
	assert (pmbmd -> m_dctMd == INTER || pmbmd -> m_dctMd == INTERQ);

	assert (pmbmd->m_rgTranspStatus [0] != ALL);
	Int iQuantMax = (1<<m_volmd.uiQuantPrecision) - 1;
	if (pmbmd -> m_stepSize < 1)
		pmbmd -> m_stepSize = 1;
	else if (pmbmd -> m_stepSize > iQuantMax)
		pmbmd -> m_stepSize = iQuantMax;
	Int iQP = pmbmd->m_stepSize;
#ifdef __TRACE_AND_STATS_
	m_statsMB.nQMB++;
	m_statsMB.nQp += iQP;
#endif // __TRACE_AND_STATS_

// INTERLACE
	if ((pmbmd->m_rgTranspStatus [0] == NONE) && (m_vopmd.bInterlace == TRUE)) {
		pmbmd->m_bFieldDCT = FrameFieldDCTDecideI(m_ppxliErrorMBY);
		m_statsMB.nFieldDCTMB += (Int) pmbmd->m_bFieldDCT;
	}
	else
		pmbmd->m_bFieldDCT = 0;
	Bool bMBCoded = FALSE;
// ~INTERLACE

	Int iQPA = 0;
	pmbmd->m_CODAlpha = ALPHA_CODED;
	Int iBlkEnd = V_BLOCK;
	if(m_volmd.fAUsage == EIGHT_BIT)
	{
		iBlkEnd = A_BLOCK4;
		if (pmbmd -> m_stepSizeAlpha < 1)
			pmbmd -> m_stepSizeAlpha = 1;
		iQPA = pmbmd->m_stepSizeAlpha;

		Int i, iThresh = 256 - iQPA;
		pmbmd->m_CODAlpha = ALPHA_ALL255;
		for(i = 0; i<MB_SQUARE_SIZE; i++)
			if(m_ppxlcCurrMBA[i] <= iThresh)
			{
				pmbmd->m_CODAlpha = ALPHA_CODED;
				break;
			}
	}

//	Bool bSkip = pmbmd->m_bhas4MVForward ? (bSkipAllowed && pmv [1].isZero () && pmv [2].isZero () && pmv [3].isZero () && pmv [4].isZero ())

⌨️ 快捷键说明

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