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

📄 errenc.cpp

📁 此源码是在VC平台下,实现MPEG4编解码的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

		ppxlcRefY += m_iFrameWidthYxMBSize;
		ppxlcRefU += m_iFrameWidthUVxBlkSize;
		ppxlcRefV += m_iFrameWidthUVxBlkSize;
		
		ppxlcOrigY += m_iFrameWidthYxMBSize;
		ppxlcOrigU += m_iFrameWidthUVxBlkSize;
		ppxlcOrigV += m_iFrameWidthUVxBlkSize;
	}

	// delete CoefQ_DP
	for( Int iMB = 0; iMB < m_iNumMB; iMB++ )  {
		for (Int iBlk = 0; iBlk < 6; iBlk++) {
			delete [] iCoefQ_DP [iMB] [iBlk];
		}
		delete [] iCoefQ_DP[iMB];
	}
	delete [] iCoefQ_DP;

	// Set to output bitstream
	m_pbitstrmOut->SetDontSendBits(FALSE);
}

Void CVideoObjectEncoder::encodeNSForIVOP_DP ()	
{
	assert( m_volmd.bDataPartitioning );
	assert( m_vopmd.vopPredType==IVOP );
	//assert(m_volmd.nBits==8);
// bug fix by toshiba 98-9-24 start
	//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));
// bug fix by toshiba 98-9-24 end

	CMBMode* pmbmd = m_rgmbmd;
	Int iQPPrev = m_vopmd.intStepI;	//initialization
	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* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY ();
	PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU ();
	PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV ();

	// MB rate control
	Int iIndexofQ = 0;
	Int rgiQ [4] = {-1, -2, 1, 2};
	// -----

	Int iMBX, iMBY;

	Int iVPCounter = m_statsVOP.total();
	Int iVPtotal;
	m_iVPMBnum = 0;
	CStatistics m_statsVP;
	// DCT coefficient buffer for Data Partitioning mode
	Int*** iCoefQ_DP = new Int** [m_iNumMB];

	// Set not to output but count bitstream
	m_pbitstrmOut->SetDontSendBits(TRUE);

	Bool bRestartDelayedQP = TRUE;

	for (iMBY = 0; iMBY < m_iNumMBY; iMBY++) {
		PixelC* ppxlcRefMBY  = ppxlcRefY;
		PixelC* ppxlcRefMBU  = ppxlcRefU;
		PixelC* ppxlcRefMBV  = ppxlcRefV;
		PixelC* ppxlcOrigMBY = ppxlcOrigY;
		PixelC* ppxlcOrigMBU = ppxlcOrigU;
		PixelC* ppxlcOrigMBV = ppxlcOrigV;
		for (iMBX = 0; iMBX < m_iNumMBX; iMBX++) {
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");
#endif // __TRACE_AND_STATS_

			m_statsMB.reset ();

			// MB rate control
			//pmbmd->m_intStepDelta = 0;
			//iIndexofQ = (iIndexofQ + 1) % 4;
			//pmbmd->m_intStepDelta = rgiQ [iIndexofQ];
			// -----

// bug fix by toshiba 98-9-24 start
			pmbmd->m_bSkip = FALSE;			//reset for direct mode
// bug fix by toshiba 98-9-24 end
			pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;

			if(bRestartDelayedQP)
			{
				pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
				bRestartDelayedQP = FALSE;
			}
			else
				pmbmd->m_stepSizeDelayed = iQPPrev;

			iQPPrev = pmbmd->m_stepSize;
			if (pmbmd->m_intStepDelta == 0)
				pmbmd->m_dctMd = INTRA;
			else
				pmbmd->m_dctMd = INTRAQ;

			copyToCurrBuff (ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, m_iFrameWidthY, m_iFrameWidthUV); 
			quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, NULL);
			codeMBTextureHeadOfIVOP (pmbmd);
			sendDCTCoefOfIntraMBTexture (pmbmd);

			Int iVPlastMBnum = iMBY * m_iNumMBX + iMBX;

			// copy DCT coefficient to buffer
			iCoefQ_DP[iVPlastMBnum] = new Int* [6];
			Int iBlk;
			for (iBlk = 0; iBlk < 6; iBlk++) {
				iCoefQ_DP [iVPlastMBnum] [iBlk] = new Int [BLOCK_SQUARE_SIZE];

				for( Int t = 0; t < BLOCK_SQUARE_SIZE; t++ )
					iCoefQ_DP[iVPlastMBnum][iBlk][t] = m_rgpiCoefQ[iBlk][t];
			}

			pmbmd++;
#ifdef __TRACE_AND_STATS_
			m_statsVOP   += m_statsMB;
#endif // __TRACE_AND_STATS_
			ppxlcRefMBY  += MB_SIZE;
			ppxlcRefMBU  += BLOCK_SIZE;
			ppxlcRefMBV  += BLOCK_SIZE;
			ppxlcOrigMBY += MB_SIZE;
			ppxlcOrigMBU += BLOCK_SIZE;
			ppxlcOrigMBV += BLOCK_SIZE;

			iVPtotal = (int) m_statsVOP.total() - iVPCounter;
			if( iVPtotal > m_volmd.bVPBitTh || iVPlastMBnum == m_iNumMB-1 /* last MB in a VOP */) {
				// Set to output bitstream
				m_pbitstrmOut->SetDontSendBits(FALSE);
				// encode video packet
				iVPCounter = m_statsVOP.total();
				m_statsVP.reset();
				if( m_iVPMBnum > 0 )
				{
					m_statsVP.nBitsHead = codeVideoPacketHeader (m_rgmbmd[m_iVPMBnum].m_stepSize);
					bRestartDelayedQP = TRUE;
				}

				DataPartitioningMotionCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);

				m_pbitstrmOut -> putBits (DC_MARKER, NUMBITS_DP_DC_MARKER, "DC_marker");
				m_statsVP.nBitsHead += NUMBITS_DP_DC_MARKER;

				DataPartitioningTextureCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);

				//assert( iVPtotal + m_statsVP.nBitsHead == (int) m_statsVP.total() );

				m_iVPMBnum = iVPlastMBnum + 1;

				// Set not to output but count bitstream
				m_pbitstrmOut->SetDontSendBits(TRUE);
			}

		}
		
		MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
		m_rgpmbmAbove = m_rgpmbmCurr;
		m_rgpmbmCurr  = ppmbmTemp;
		ppxlcRefY  += m_iFrameWidthYxMBSize;
		ppxlcRefU  += m_iFrameWidthUVxBlkSize;
		ppxlcRefV  += m_iFrameWidthUVxBlkSize;
		
		ppxlcOrigY += m_iFrameWidthYxMBSize;
		ppxlcOrigU += m_iFrameWidthUVxBlkSize;
		ppxlcOrigV += m_iFrameWidthUVxBlkSize;
	}

	// delete CoefQ_DP
	for( Int iMB = 0; iMB < m_iNumMB; iMB++ )  {
		for (Int iBlk = 0; iBlk < 6; iBlk++) {
			delete [] iCoefQ_DP [iMB] [iBlk];
		}
		delete [] iCoefQ_DP[iMB];
	}
	delete [] iCoefQ_DP;

	// Set to output bitstream
	m_pbitstrmOut->SetDontSendBits(FALSE);
}


Void CVideoObjectEncoder::DataPartitioningMotionCoding(Int iVPMBnum, Int iVPlastMBnum, CStatistics* m_statsVP, Int*** iCoefQ_DP)
{
	assert( m_volmd.bDataPartitioning );

	Int	iMBnum;
	CMBMode* pmbmd;
	CMotionVector* pmv = m_rgmv;
	Int iMBX, iMBY;

	for(iMBnum = iVPMBnum, pmbmd = m_rgmbmd+iVPMBnum, pmv = m_rgmv+iVPMBnum*PVOP_MV_PER_REF_PER_MB;
		iMBnum <= iVPlastMBnum; iMBnum++, pmbmd++, pmv+=PVOP_MV_PER_REF_PER_MB) {
		iMBX = iMBnum % m_iNumMBX;
		iMBY = iMBnum / m_iNumMBX;
#ifdef __TRACE_AND_STATS_
		m_pbitstrmOut->trace (CSite (iMBX, iMBY), "Motion_MB_X_Y");
#endif // __TRACE_AND_STATS_
		if( m_volmd.fAUsage != RECTANGLE ) {
			m_statsVP->nBitsShape += dumpCachedShapeBits_DP(iMBnum);
		}
		
		if (pmbmd -> m_rgTranspStatus [0] != ALL) {
			if( m_vopmd.vopPredType==PVOP ) {
				m_pbitstrmOut->putBits (pmbmd->m_bSkip, 1, "MB_Skip");
				m_statsVP->nBitsCOD++;
			}

			if (!pmbmd->m_bSkip) {
				UInt CBPC = (pmbmd->getCodedBlockPattern (U_BLOCK) << 1)
							| pmbmd->getCodedBlockPattern (V_BLOCK);	
														//per defintion of H.263's CBPC 
				assert (CBPC >= 0 && CBPC <= 3);

				Int iMBtype;								//per H.263's MBtype
				Int iSymbol;
				switch( m_vopmd.vopPredType ) {
				case PVOP:
					if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)
						iMBtype = pmbmd->m_dctMd + 3;
					else
						iMBtype = (pmbmd -> m_dctMd - 2) | pmbmd -> m_bhas4MVForward << 1;
					assert (iMBtype >= 0 && iMBtype <= 4);
#ifdef __TRACE_AND_STATS_
					m_pbitstrmOut->trace (iMBtype, "MB_MBtype");
					m_pbitstrmOut->trace (CBPC, "MB_CBPC");
#endif // __TRACE_AND_STATS_
					m_statsVP->nBitsMCBPC += m_pentrencSet->m_pentrencMCBPCinter->encodeSymbol (iMBtype * 4 + CBPC, "MCBPC");
					break;
				case IVOP:
					iSymbol = 4 * pmbmd->m_dctMd + CBPC;
					assert (iSymbol >= 0 && iSymbol <= 7);			//send MCBPC
#ifdef __TRACE_AND_STATS_
					m_pbitstrmOut->trace (CBPC, "MB_CBPC");
#endif // __TRACE_AND_STATS_
					m_statsVP->nBitsMCBPC += m_pentrencSet->m_pentrencMCBPCintra->encodeSymbol (iSymbol, "MB_MCBPC");
					break;
				default:
					assert(FALSE);
				}

				if ( m_vopmd.vopPredType == IVOP ) {
					if( pmbmd->m_dctMd == INTRAQ) {
						Int DQUANT = pmbmd->m_intStepDelta;			//send DQUANT
						assert (DQUANT >= -2 && DQUANT <= 2);
						if (DQUANT != 0) {	
							if (sign (DQUANT) == 1)
								m_pbitstrmOut->putBits (DQUANT + 1, 2, "MB_DQUANT");
							else
								m_pbitstrmOut->putBits (-1 - DQUANT, 2, "MB_DQUANT");
							m_statsVP->nBitsDQUANT += 2;
						}
					}				 
		
					UInt iBlk = 0;
					for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
						UInt nBits = 0;
#ifdef __TRACE_AND_STATS_
						m_pbitstrmOut->trace (iBlk, "BLK_NO");
#endif // __TRACE_AND_STATS_
						if (iBlk < U_BLOCK)
							if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
						Int* rgiCoefQ = iCoefQ_DP [iMBnum][iBlk - 1];
#ifdef __TRACE_AND_STATS_
						m_pbitstrmOut->trace (rgiCoefQ[0], "IntraDC");
#endif // __TRACE_AND_STATS_
						if (pmbmd->m_bCodeDcAsAc != TRUE)	{
							nBits = sendIntraDC (rgiCoefQ, (BlockNum) iBlk);
						}
						switch (iBlk) {
						case U_BLOCK: 
							m_statsVP->nBitsCr += nBits;
							break;
						case V_BLOCK: 
							m_statsVP->nBitsCb += nBits;
							break;
						default:
							m_statsVP->nBitsY += nBits;
						}
					}
				}

				if (pmbmd->m_dctMd != INTRA && pmbmd->m_dctMd != INTRAQ) {
					if( m_volmd.fAUsage == RECTANGLE )
						m_statsVP->nBitsMV += encodeMVVP (pmv, pmbmd, iMBX, iMBY);
					else
						m_statsVP->nBitsMV += encodeMVWithShape (pmv, pmbmd, iMBX, iMBY);
				}
			}
		}
	}
}

Void CVideoObjectEncoder::DataPartitioningTextureCoding(Int iVPMBnum, Int iVPlastMBnum, CStatistics* m_statsVP, Int*** iCoefQ_DP)
{
	assert( m_volmd.bDataPartitioning );

	Int	iMBnum;
	CMBMode* pmbmd;
	CMotionVector* pmv = m_rgmv;
	Int iMBX, iMBY;

	for(iMBnum = iVPMBnum, pmbmd = m_rgmbmd+iVPMBnum, pmv = m_rgmv+iVPMBnum*PVOP_MV_PER_REF_PER_MB;
			iMBnum <= iVPlastMBnum; iMBnum++, pmbmd++, pmv+=PVOP_MV_PER_REF_PER_MB) {
		if (pmbmd->m_bSkip || pmbmd -> m_rgTranspStatus [0] == ALL)
			continue;

		iMBX = iMBnum % m_iNumMBX;
		iMBY = iMBnum / m_iNumMBX;
#ifdef __TRACE_AND_STATS_
		m_pbitstrmOut->trace (CSite (iMBX, iMBY), "TextureHeader_MB_X_Y");
#endif // __TRACE_AND_STATS_
		Int CBPY = 0;
		UInt cNonTrnspBlk = 0, iBlk;
		for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
			if (pmbmd->m_rgTranspStatus [iBlk] != ALL)	
				cNonTrnspBlk++;
		}
		UInt iBitPos = 1;
		for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++)	{
			if (pmbmd->m_rgTranspStatus [iBlk] != ALL)	{
				CBPY |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (cNonTrnspBlk - iBitPos);
				iBitPos++;
			}
		}
		assert (CBPY >= 0 && CBPY <= 15);								//per defintion of H.263's CBPY 
		if (m_volmd.fAUsage == RECTANGLE)
			assert (cNonTrnspBlk==4); // Only all opaque is only supportedin DP mode at present

		if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)	{
			m_pbitstrmOut->putBits (pmbmd->m_bACPrediction, 1, "MB_ACPRED");
			m_statsVP->nBitsIntraPred++;
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
			m_pbitstrmOut->trace (CBPY, "MB_CBPY (I-style)");
#endif // __TRACE_AND_STATS_
			switch (cNonTrnspBlk) {
			case 1:
				m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (CBPY, "MB_CBPY1");
				break;
			case 2:
				m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (CBPY, "MB_CBPY2");
				break;
			case 3:
				m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (CBPY, "MB_CBPY3");
				break;
			case 4:
				m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (CBPY, "MB_CBPY");
				break;
			default:
				assert (FALSE);
			}
			m_statsVP->nIntraMB++;
		}
		else {
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
			m_pbitstrmOut->trace (CBPY, "MB_CBPY (P-style)");
#endif // __TRACE_AND_STATS_
			switch (cNonTrnspBlk) {
			case 1:
				m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (1 - CBPY, "MB_CBPY1");
				break;
			case 2:
				m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (3 - CBPY, "MB_CBPY2");
				break;
			case 3:
				m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (7 - CBPY, "MB_CBPY3");
				break;
			case 4:
				m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (15 - CBPY, "MB_CBPY");
				break;
			default:
				assert (FALSE);
			}
		}

		if ( m_vopmd.vopPredType != IVOP &&
				(pmbmd->m_dctMd == INTERQ || pmbmd->m_dctMd == INTRAQ)) {
			Int DQUANT = pmbmd->m_intStepDelta;			//send DQUANT
			assert (DQUANT >= -2 && DQUANT <= 2);
			if (DQUANT != 0) {	
				if (sign (DQUANT) == 1)
					m_pbitstrmOut->putBits (DQUANT + 1, 2, "MB_DQUANT");
				else
					m_pbitstrmOut->putBits (-1 - DQUANT, 2, "MB_DQUANT");
				m_statsVP->nBitsDQUANT += 2;
			}
		}				 
		
		if (m_vopmd.vopPredType	!= IVOP &&
				(pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ))	{
			UInt iBlk = 0;
			for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
				UInt nBits = 0;
#ifdef __TRACE_AND_STATS_
				m_pbitstrmOut->trace (iBlk, "BLK_NO");
#endif // __TRACE_AND_STATS_
				if (iBlk < U_BLOCK)
					if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
////				Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
				Int* rgiCoefQ = iCoefQ_DP [iMBnum][iBlk - 1];
#ifdef __TRACE_AND_STATS_
////				m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
				m_pbitstrmOut->trace (rgiCoefQ[0], "IntraDC");
#endif // __TRACE_AND_STATS_
////				Int iCoefStart = 0;
				if (pmbmd->m_bCodeDcAsAc != TRUE)	{
////					iCoefStart = 1;
					nBits = sendIntraDC (rgiCoefQ, (BlockNum) iBlk);
				}
				switch (iBlk) {
				case U_BLOCK: 
					m_statsVP->nBitsCr += nBits;
					break;
				case V_BLOCK: 
					m_statsVP->nBitsCb += nBits;
					break;
				default:
					m_statsVP->nBitsY += nBits;

⌨️ 快捷键说明

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