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

📄 errdec.cpp

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 CPP
📖 第 1 页 / 共 4 页
字号:
				} else {
					bRightBndry = !((pmbmd - m_iNumMBX + 1) -> m_iVideoPacketNumber == pmbmd -> m_iVideoPacketNumber);
				}
			decodeMV (pmbmd, pmv, bLeftBndry, bRightBndry, bTopBndry, FALSE, iMBX, iMBY);

			if(bMBBackup){
				if (pmbmdBackup->m_dctMd == INTER || pmbmdBackup->m_dctMd == INTERQ) {
					motionCompMB (
						m_ppxlcPredMBY, m_pvopcRefQ0->pixelsY (),
						pmvBackup, pmbmdBackup, 
						iMBXBackup, iMBYBackup, 
						x, y,
						pmbmdBackup->m_bSkip, FALSE,
						&m_rctRefVOPY0
					);
					if (!pmbmdBackup->m_bSkip) {
						CoordI iXRefUV, iYRefUV, iXRefUV1, iYRefUV1;
						mvLookupUV (pmbmdBackup, pmvBackup, iXRefUV, iYRefUV, iXRefUV1, iYRefUV1);
						motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, iXRefUV, iYRefUV, m_vopmd.iRoundingControl, &m_rctRefVOPY0);
						addErrorAndPredToCurrQ (ppxlcCurrQMBYBackup, ppxlcCurrQMBUBackup, ppxlcCurrQMBVBackup);
					}
					else {
						if (m_volmd.bAdvPredDisable)
	
							copyFromRefToCurrQ (m_pvopcRefQ0, x, y, ppxlcCurrQMBYBackup, ppxlcCurrQMBUBackup, ppxlcCurrQMBVBackup, NULL);
						else
							copyFromPredForYAndRefForCToCurrQ (x, y, ppxlcCurrQMBYBackup, ppxlcCurrQMBUBackup, ppxlcCurrQMBVBackup, NULL);
					}
				}
				bMBBackup = FALSE;
			}

			pmbmd++;
			pmv += PVOP_MV_PER_REF_PER_MB;
			mbn++;
			piMCBPC++;
			assert(mbn<=(m_iNumMBX*m_iNumMBY));
		} while( !checkMotionMarker() );
		m_pbitstrmIn -> getBits (NUMBITS_DP_MOTION_MARKER);

		pmbmd = pmbmdFirst;
		piMCBPC = piMCBPCFirst;
		piIntraDC = piIntraDCFirst;
		for(i=mbnFirst;i<mbn;i++) {
			decodeMBTextureHeadOfPVOP_DataPartitioning (pmbmd, iCurrentQP, piMCBPC, piIntraDC, bRestartDelayedQP);
			pmbmd++;
			piMCBPC++;
			piIntraDC += V_BLOCK;
		}

		pmbmd = pmbmdFirst;
		pmv = pmvFirst;
		piIntraDC = piIntraDCFirst;

		for(i=mbnFirst;i<mbn;i++) {
			iMBX = i % m_iNumMBX;
			iMBY = i / m_iNumMBX;
			if(iMBX == 0 ) {
				ppxlcCurrQMBY = ppxlcCurrQY;
				ppxlcCurrQMBU = ppxlcCurrQU;
				ppxlcCurrQMBV = ppxlcCurrQV;
				x = 0;
				if(iMBY != 0)	y += MB_SIZE;
			} else {
				x += MB_SIZE;
			}

			if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)
				decodeTextureIntraMB_DataPartitioning (pmbmd, iMBX, iMBY, ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV, piIntraDC);
			else {
				if (!pmbmd->m_bSkip)
					decodeTextureInterMB (pmbmd);
			}

			if(i==mbn-1){
				bMBBackup = TRUE;
				pmbmdBackup = pmbmd;
				pmvBackup = pmv;
				iMBXBackup = iMBX;
				iMBYBackup = iMBY;
				ppxlcCurrQMBYBackup = ppxlcCurrQMBY;
				ppxlcCurrQMBUBackup = ppxlcCurrQMBU;
				ppxlcCurrQMBVBackup = ppxlcCurrQMBV;
			}

			if (pmbmd->m_dctMd == INTER || pmbmd->m_dctMd == INTERQ) {
				motionCompMB (
					m_ppxlcPredMBY, m_pvopcRefQ0->pixelsY (),
					pmv, pmbmd, 
					iMBX, iMBY, 
					x, y,
					pmbmd->m_bSkip, FALSE,
					&m_rctRefVOPY0
				);
				if (!pmbmd->m_bSkip) {
					CoordI iXRefUV, iYRefUV, iXRefUV1, iYRefUV1;
					mvLookupUV (pmbmd, pmv, iXRefUV, iYRefUV, iXRefUV1, iYRefUV1);
					motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, iXRefUV, iYRefUV, m_vopmd.iRoundingControl, &m_rctRefVOPY0);
					addErrorAndPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
				}
				else {
					if (m_volmd.bAdvPredDisable)

						copyFromRefToCurrQ (m_pvopcRefQ0, x, y, ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV, NULL);
					else
						copyFromPredForYAndRefForCToCurrQ (x, y, ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV, NULL);
				}
			}

			pmbmd++;
			pmv += PVOP_MV_PER_REF_PER_MB;
			piIntraDC += V_BLOCK;
			ppxlcCurrQMBY += MB_SIZE;
			ppxlcCurrQMBU += BLOCK_SIZE;
			ppxlcCurrQMBV += BLOCK_SIZE;

			if(iMBX == m_iNumMBX - 1) {
				MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
				m_rgpmbmAbove = m_rgpmbmCurr;
				m_rgpmbmCurr  = ppmbmTemp;
				ppxlcCurrQY += m_iFrameWidthYxMBSize;
				ppxlcCurrQU += m_iFrameWidthUVxBlkSize;
				ppxlcCurrQV += m_iFrameWidthUVxBlkSize;
			}
		}
	} while( checkResyncMarker() );
	delete m_piIntraDC;
	delete m_piMCBPC;
}

Void CVideoObjectDecoder::decodeMBTextureHeadOfPVOP_DataPartitioning (CMBMode* pmbmd, Int& iCurrentQP, Int* piMCBPC,
																	  Int* piIntraDC, Bool &bUseNewQPForVlcThr)
{
	assert (pmbmd->m_rgTranspStatus [0] != ALL);
	Int iBlk = 0, cNonTrnspBlk = 0;
	for (iBlk = (Int) Y_BLOCK1; iBlk <= (Int) Y_BLOCK4; iBlk++) {
		if (pmbmd->m_rgTranspStatus [iBlk] != ALL)	
			cNonTrnspBlk++;
	}
	Int iCBPC = 0;
	Int iCBPY = 0;
	if (!pmbmd->m_bSkip) {
	  //Int iMBtype = *piMCBPC / 4;					//per H.263's MBtype
		iCBPC = *piMCBPC % 4;
		if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)	{
			pmbmd->m_bACPrediction = m_pbitstrmIn->getBits (1);
			switch (cNonTrnspBlk) {
			case 1:
				iCBPY = m_pentrdecSet->m_pentrdecCBPY1->decodeSymbol ();
				break;
			case 2:
				iCBPY = m_pentrdecSet->m_pentrdecCBPY2->decodeSymbol ();
				break;
			case 3:
				iCBPY = m_pentrdecSet->m_pentrdecCBPY3->decodeSymbol ();
				break;
			case 4:
				iCBPY = m_pentrdecSet->m_pentrdecCBPY->decodeSymbol ();
				break;
			default:
				assert (FALSE);
			}
		}
		else {
			switch (cNonTrnspBlk) {
			case 1:
				iCBPY = 1 - m_pentrdecSet->m_pentrdecCBPY1->decodeSymbol ();
				break;
			case 2:
				iCBPY = 3 - m_pentrdecSet->m_pentrdecCBPY2->decodeSymbol ();
				break;
			case 3:
				iCBPY = 7 - m_pentrdecSet->m_pentrdecCBPY3->decodeSymbol ();
				break;
			case 4:
				iCBPY = 15 - m_pentrdecSet->m_pentrdecCBPY->decodeSymbol ();
				break;
			default:
				assert (FALSE);
			}
		}

		assert (iCBPY >= 0 && iCBPY <= 15);			
	}
	else	{									//skipped
		pmbmd->m_dctMd = INTER;
		pmbmd -> m_bhas4MVForward = FALSE;
	}
	setCBPYandC (pmbmd, iCBPC, iCBPY, cNonTrnspBlk);
	pmbmd->m_stepSize = iCurrentQP;
	pmbmd->m_stepSizeDelayed = iCurrentQP;
	if (pmbmd->m_dctMd == INTERQ || pmbmd->m_dctMd == INTRAQ) {
		assert (!pmbmd->m_bSkip);
		Int iDQUANT = m_pbitstrmIn->getBits (2);
		switch (iDQUANT) {
		case 0:
			pmbmd->m_intStepDelta = -1;
			break;
		case 1:
			pmbmd->m_intStepDelta = -2;
			break;
		case 2:
			pmbmd->m_intStepDelta = 1;
			break;
		case 3:
			pmbmd->m_intStepDelta = 2;
			break;
		default:
			assert (FALSE);
		}
		pmbmd->m_stepSize += pmbmd->m_intStepDelta;
		if(bUseNewQPForVlcThr)
			pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
		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;
		iCurrentQP = pmbmd->m_stepSize;
	}

	if (!pmbmd->m_bSkip)
		bUseNewQPForVlcThr = FALSE;

	if(pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)	{
		Int iQP = pmbmd->m_stepSize;
		for (Int i = 0; i <= 31; i++)	{
			if (iQP <= 4)	{
				m_rgiDcScalerY [i] = 8;
				m_rgiDcScalerC [i] = 8;
			}
			else if (iQP >= 5 && iQP <= 8)	{
				m_rgiDcScalerY [i] = 2 * iQP;
				m_rgiDcScalerC [i] = (iQP + 13) / 2;
			}
			else if (iQP >= 9 && iQP <= 24)	{
				m_rgiDcScalerY [i] = iQP + 8;
				m_rgiDcScalerC [i] = (iQP + 13) / 2;
			}
			else	{
				m_rgiDcScalerY [i] = 2 * iQP - 16;
				m_rgiDcScalerC [i] = iQP - 6;
			}
		}

		assert (iQP > 0);
		assert (pmbmd -> m_stepSizeDelayed > 0);
		if (pmbmd -> m_stepSizeDelayed >= grgiDCSwitchingThreshold [m_vopmd.iIntraDcSwitchThr])
			pmbmd->m_bCodeDcAsAc = TRUE;
		else
			pmbmd->m_bCodeDcAsAc = FALSE;

		for (iBlk = Y_BLOCK1; iBlk < U_BLOCK; iBlk++) {
			if (pmbmd->m_rgTranspStatus [iBlk] != ALL)
				decodeIntraBlockTexture_DataPartitioning (iBlk, pmbmd, piIntraDC);	
		}
		for (iBlk = U_BLOCK; iBlk <= V_BLOCK; iBlk++) {
			decodeIntraBlockTexture_DataPartitioning (iBlk, pmbmd, piIntraDC);	
		}
	}
}

Void CVideoObjectDecoder::decodeIVOP_WithShape_DataPartitioning ()	
{
	//assert (m_volmd.nBits==8);
	assert (m_volmd.fAUsage!=EIGHT_BIT);
	//in case the IVOP is used as an ref for direct mode
	memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));

	Int iMBX, iMBY;
	CMBMode* pmbmd = m_rgmbmd;

	PixelC* ppxlcRefY  = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
	PixelC* ppxlcRefU  = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV;
	PixelC* ppxlcRefV  = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV;
	PixelC* ppxlcRefBY = (PixelC*) m_pvopcRefQ1->pixelsBY () + m_iStartInRefToCurrRctY;
	PixelC* ppxlcRefA  = (PixelC*) m_pvopcRefQ1->pixelsA () + m_iStartInRefToCurrRctY;
	PixelC* ppxlcRefBUV = (PixelC*) m_pvopcRefQ1->pixelsBUV () + m_iStartInRefToCurrRctUV;

	Int iCurrentQP  = m_vopmd.intStepI;	
	Int	iVideoPacketNumber = 0;
	m_iVPMBnum = 0;
	m_piMCBPC = new Int[m_iNumMBX*m_iNumMBY];
	Int*	piMCBPC = m_piMCBPC;
	m_piIntraDC = new Int[m_iNumMBX*m_iNumMBY*V_BLOCK];
	Int*	piIntraDC = m_piIntraDC;

	Bool bRestartDelayedQP = TRUE;
	Int	i;
	Int mbn = 0, mbnFirst = 0;

	PixelC* ppxlcRefMBBY = NULL;
	PixelC* ppxlcRefMBBUV;
	PixelC* ppxlcRefMBY = NULL;
	PixelC* ppxlcRefMBU = NULL;
	PixelC* ppxlcRefMBV = NULL;
	PixelC* ppxlcRefMBA = NULL;
	do	{
		if( checkResyncMarker() )	{
			decodeVideoPacketHeader(iCurrentQP);
			iVideoPacketNumber++;
			bRestartDelayedQP = TRUE;
		}

		CMBMode* pmbmdFirst = pmbmd;
		Int* piMCBPCFirst = piMCBPC;
		Int* piIntraDCFirst = piIntraDC;
		mbnFirst = mbn;

		do{
			iMBX = mbn % m_iNumMBX;
			iMBY = mbn / m_iNumMBX;
			if(iMBX == 0 ) {
				ppxlcRefMBBY = ppxlcRefBY;
				ppxlcRefMBBUV = ppxlcRefBUV;
			}

			pmbmd->m_iVideoPacketNumber = iVideoPacketNumber;

			decodeIntraShape (pmbmd, iMBX, iMBY, m_ppxlcCurrMBBY, ppxlcRefMBBY);
			downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV); // downsample original BY now for LPE padding (using original shape)
			if(m_volmd.bShapeOnly==FALSE)
			{
				pmbmd->m_bPadded=FALSE;
				if (pmbmd->m_rgTranspStatus [0] != ALL) {
					*piMCBPC = m_pentrdecSet->m_pentrdecMCBPCintra->decodeSymbol ();
					assert (*piMCBPC >= 0 && *piMCBPC <= 7);			
					pmbmd->m_dctMd = INTRA;
					if (*piMCBPC > 3)
						pmbmd->m_dctMd = INTRAQ;
					decodeMBTextureDCOfIVOP_DataPartitioning (pmbmd, iCurrentQP,
						piIntraDC, bRestartDelayedQP);
				}
			}
			else	{
				assert(FALSE);
			}
			pmbmd++;
			mbn++;
			piMCBPC++;
			piIntraDC+=V_BLOCK;
			ppxlcRefMBBY += MB_SIZE;
			ppxlcRefMBBUV += BLOCK_SIZE;
			if(iMBX == m_iNumMBX - 1) {
				ppxlcRefBY += m_iFrameWidthYxMBSize;
				ppxlcRefBUV += m_iFrameWidthUVxBlkSize;
			}
		} while( !checkDCMarker() );
		m_pbitstrmIn -> getBits (NUMBITS_DP_DC_MARKER);

		pmbmd = pmbmdFirst;
		piMCBPC = piMCBPCFirst;
		for(i=mbnFirst;i<mbn;i++) {
			if (pmbmd->m_rgTranspStatus [0] != ALL)
				decodeMBTextureHeadOfIVOP_DataPartitioning (pmbmd, piMCBPC);
			pmbmd++;
			piMCBPC++;
		}

		pmbmd = pmbmdFirst;
		piIntraDC = piIntraDCFirst;
		ppxlcRefBY = (PixelC*) m_pvopcRefQ1->pixelsBY () + m_iStartInRefToCurrRctY + (mbnFirst/m_iNumMBX)*m_iFrameWidthYxMBSize;
		ppxlcRefBUV = (PixelC*) m_pvopcRefQ1->pixelsBUV () + m_iStartInRefToCurrRctUV + (mbnFirst/m_iNumMBX)*m_iFrameWidthUVxBlkSize;
		ppxlcRefMBBY = ppxlcRefBY + (mbnFirst%m_iNumMBX)*MB_SIZE;
		ppxlcRefMBBUV = ppxlcRefBUV + (mbnFirst%m_iNumMBX)*BLOCK_SIZE;
		for(i=mbnFirst;i<mbn;i++) {
			pmbmd->m_bPadded = FALSE;
			iMBX = i % m_iNumMBX;
			iMBY = i / m_iNumMBX;
			if(iMBX == 0 ) {
				ppxlcRefMBY = ppxlcRefY;
				ppxlcRefMBU = ppxlcRefU;
				ppxlcRefMBV = ppxlcRefV;
				ppxlcRefMBA  = ppxlcRefA;
				ppxlcRefMBBY = ppxlcRefBY;
				ppxlcRefMBBUV = ppxlcRefBUV;
			}

			copyRefShapeToMb(m_ppxlcCurrMBBY, ppxlcRefMBBY);
			downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV); // downsample original BY now for LPE padding (using original shape)

			if (pmbmd->m_rgTranspStatus [0] != ALL) {
				decodeTextureIntraMB_DataPartitioning (pmbmd, iMBX, iMBY, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, piIntraDC);

⌨️ 快捷键说明

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