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

📄 errenc.cpp

📁 此源码是在VC平台下,实现MPEG4编解码的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
				m_pbitstrmShapeMBOut = m_pbitstrmShape_DP[iMBY * m_iNumMBX + iMBX + 1];
// Added for error resilient mode by Toshiba(1997-11-14)
				// The following operation is needed only for OBMC
				if( bCodeVPHeaderNext ) {
					iTempVPMBnum  = m_iVPMBnum;
					m_iVPMBnum = VPMBnum(iMBX+1, iMBY);
				}
// End Toshiba(1997-11-14)
				// code shape 1mb in advance
				copyToCurrBuffJustShape (ppxlcOrigMBBY+MB_SIZE,m_iFrameWidthY);
				// Modified for error resilient mode by Toshiba(1997-11-14)
				if(m_vopmd.bShapeCodingType) {
					shpmdColocatedMB = m_rgmbmdRef [
						min (max (0, iMBX+1), m_iNumMBXRef-1) + 
 						min (max (0, iMBY), m_iNumMBYRef-1) * m_iNumMBXRef
					].m_shpmd;
					encodePVOPMBJustShape(
						ppxlcRefMBBY+MB_SIZE, pmbmd+1,
						 shpmdColocatedMB,
						 pmv+PVOP_MV_PER_REF_PER_MB,
						 pmvBY+1, x+MB_SIZE, y,
						 iMBX+1, iMBY
					);
				}
				else {
					m_statsMB.nBitsShape
						+= codeIntraShape (
							ppxlcRefMBBY+MB_SIZE,
							pmbmd+1, iMBX+1, iMBY
						);
					decideTransparencyStatus (pmbmd+1,
						 m_ppxlcCurrMBBY); 
				}
			// End Toshiba(1997-11-14)

// Added for error resilient mode by Toshiba(1997-11-14)
				// The following operation is needed only for OBMC
				if( bCodeVPHeaderNext )
					m_iVPMBnum = iTempVPMBnum;
// End Toshiba(1997-11-14)
				if((pmbmd+1)->m_bhas4MVForward)
					padMotionVectors(pmbmd+1, pmv+PVOP_MV_PER_REF_PER_MB);
			}
			
			// Set not to output but count bitstream
			m_pbitstrmOut->SetDontSendBits(TRUE);

			// 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];
			}

			if(m_volmd.bShapeOnly==FALSE)
			{
				if (pmbmd -> m_rgTranspStatus [0] != ALL) {
					// need to copy binary shape too since curr buff is future shape
					copyToCurrBuffWithShape(ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV,
					ppxlcRefMBBY, ppxlcOrigMBA, m_iFrameWidthY, m_iFrameWidthUV);

					downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV);

					encodePVOPMBTextureWithShape(ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA, pmbmd, pmv, iMBX, iMBY, x, y,
						iQPPrev, iQPPrevAlpha, bRestartDelayedQP);

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

					if (pmbmd -> m_rgTranspStatus [0] == PARTIAL)
						mcPadCurrMB (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA);
					padNeighborTranspMBs (
						iMBX, iMBY,
						pmbmd,
						ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA
					);
				}
				else {
					padCurrAndTopTranspMBFromNeighbor (
						iMBX, iMBY,
						pmbmd,
						ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA
					);
				}
			}

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

			pmbmd++;
			pmv += PVOP_MV_PER_REF_PER_MB;
			pmvBY++;
			ppxlcRefMBBY += MB_SIZE;
			ppxlcRefMBA += MB_SIZE;
			ppxlcRefMBBUV += BLOCK_SIZE;
			ppxlcOrigMBBY += MB_SIZE;
			ppxlcOrigMBA += MB_SIZE;
#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( bCodeVPHeaderNext || 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 (MOTION_MARKER, NUMBITS_DP_MOTION_MARKER, "motion_marker");
				m_statsVP.nBitsHead += NUMBITS_DP_MOTION_MARKER;

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

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

				m_iVPMBnum = iVPlastMBnum + 1;
			}
			// The following operation is needed only for OBMC
			iCounter = m_statsVOP.total();
			bCodeVPHeaderNext = iCounter - iVPCounter > m_volmd.bVPBitTh;
		}
		MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
		m_rgpmbmAbove = m_rgpmbmCurr;
		m_rgpmbmCurr  = ppmbmTemp;

		ppxlcRefY += m_iFrameWidthYxMBSize;
		ppxlcRefU += m_iFrameWidthUVxBlkSize;
		ppxlcRefV += m_iFrameWidthUVxBlkSize;
		ppxlcRefBY += m_iFrameWidthYxMBSize;
		ppxlcRefA += m_iFrameWidthYxMBSize;
		ppxlcRefBUV += m_iFrameWidthUVxBlkSize;
		
		ppxlcOrigY += m_iFrameWidthYxMBSize;
		ppxlcOrigBY += m_iFrameWidthYxMBSize;
		ppxlcOrigA += 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;

	// restore normal output stream
	m_pbitstrmShapeMBOut = m_pbitstrmOut;

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

//////////////////////////////////////////////////////////
////  The following functions are for Reversible VLC  ////
//////////////////////////////////////////////////////////

UInt CVideoObjectEncoder::sendTCOEFIntraRVLC (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag, Bool bDontSendBits)
{
	assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );

	Bool bIsFirstRun = TRUE;
	Bool bIsLastRun = FALSE;
	UInt uiCurrRun = 0;
	UInt uiPrevRun = 0;
	Int	 iCurrLevel = 0;
	Int  iPrevLevel = 0;
	UInt uiCoefToStart = 0;
	UInt numBits = 0;

	for (Int j = iStart; j < BLOCK_SQUARE_SIZE; j++) {
		if (rgiCoefQ [rgiZigzag [j]] == 0)								// zigzag here
			uiCurrRun++;											// counting zeros
		else {
			if (!bIsFirstRun)
				numBits += putBitsOfTCOEFIntraRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
			uiPrevRun = uiCurrRun; 									// reset for next run
			iPrevLevel = rgiCoefQ [rgiZigzag [j]]; 
			uiCurrRun = 0;											
			bIsFirstRun = FALSE;										
		}
	}
	assert (uiPrevRun <= (BLOCK_SQUARE_SIZE - 1) - 1);				// Some AC must be non-zero; at least for inter
	bIsLastRun = TRUE;
	numBits += putBitsOfTCOEFIntraRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
	return numBits;
}

UInt CVideoObjectEncoder::putBitsOfTCOEFIntraRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
{
	assert(m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );

	UInt nBits = 0;
	Long lVLCtableIndex;
	if (bIsLastRun == FALSE) {
		lVLCtableIndex = findVLCtableIndexOfNonLastEventIntraRVLC (bIsLastRun, uiRun, abs(iLevel));
		if (lVLCtableIndex != NOT_IN_TABLE)  {
			nBits += m_pentrencSet->m_pentrencDCTIntraRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_RVLC", bDontSendBits);	// huffman encode 
			if( !bDontSendBits )
				m_pentrencSet->m_pentrencDCTIntraRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_RVLC");	
			nBits++;
		}
		else
			escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
	}
	else	{
		lVLCtableIndex = findVLCtableIndexOfLastEventIntraRVLC (bIsLastRun, uiRun, abs(iLevel));
		if (lVLCtableIndex != NOT_IN_TABLE)  {
			nBits += m_pentrencSet->m_pentrencDCTIntraRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_Last_RVLC", bDontSendBits);	// huffman encode 
			if( !bDontSendBits )
				m_pentrencSet->m_pentrencDCTIntraRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_Last_RVLC");	
			nBits++;
		}
		else
			escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
	}
	return nBits;
}

Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEventIntraRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
	assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
	assert (uiRun >= 0);
	if (uiRun > 19 || (uiLevel > grgIfNotLastNumOfLevelAtRunIntraRVLC [uiRun]))
		return NOT_IN_TABLE;
	else	{
		UInt uiTableIndex = 0;	
		for (UInt i = 0; i < uiRun; i++)
			uiTableIndex += grgIfNotLastNumOfLevelAtRunIntraRVLC [i];
		uiTableIndex += uiLevel;
		uiTableIndex--;												// make it zero-based; see Table H13/H.263
		return uiTableIndex;
	}
}

Int CVideoObjectEncoder::findVLCtableIndexOfLastEventIntraRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
	assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
	assert (uiRun >= 0);
	if (uiRun > 44 || (uiLevel > grgIfLastNumOfLevelAtRunIntraRVLC [uiRun]))
		return NOT_IN_TABLE;
	else	{
		UInt uiTableIndex = 0;	
		for (UInt i = 0; i < uiRun; i++)
			uiTableIndex += grgIfLastNumOfLevelAtRunIntraRVLC [i];
		uiTableIndex += uiLevel;		
		uiTableIndex += 102;									// make it zero-based and 
		return uiTableIndex;								//correction of offset; see Table H13/H.263
	}
}

UInt CVideoObjectEncoder::sendTCOEFInterRVLC (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag, Bool bDontSendBits)
{
	assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );

	Bool bIsFirstRun = TRUE;
	Bool bIsLastRun = FALSE;
	UInt uiCurrRun = 0;
	UInt uiPrevRun = 0;
	Int	 iCurrLevel = 0;
	Int  iPrevLevel = 0;
	UInt numBits = 0;

	for (Int j = iStart; j < BLOCK_SQUARE_SIZE; j++) {
		if (rgiCoefQ [rgiZigzag [j]] == 0)								// zigzag here
			uiCurrRun++;											// counting zeros
		else {
			if (!bIsFirstRun)
				numBits += putBitsOfTCOEFInterRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
			uiPrevRun = uiCurrRun; 									// reset for next run
			iPrevLevel = rgiCoefQ [rgiZigzag [j]]; 
			uiCurrRun = 0;											
			bIsFirstRun = FALSE;										
		}
	}
	assert (uiPrevRun <= (BLOCK_SQUARE_SIZE - 1));				// Some AC must be non-zero; at least for inter
	bIsLastRun = TRUE;
	numBits += putBitsOfTCOEFInterRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
	return numBits;
}

UInt CVideoObjectEncoder::putBitsOfTCOEFInterRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
{
	assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );

	UInt nBits = 0;
	Long lVLCtableIndex;
	if (bIsLastRun == FALSE) {
		lVLCtableIndex = findVLCtableIndexOfNonLastEventInterRVLC (bIsLastRun, uiRun, abs(iLevel));
		if (lVLCtableIndex != NOT_IN_TABLE)  {
			nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_RVLC", bDontSendBits);	// huffman encode 
			if( !bDontSendBits )
				m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_RVLC");
			nBits++;
		}
		else
			escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
	}
	else	{
		lVLCtableIndex = findVLCtableIndexOfLastEventInterRVLC (bIsLastRun, uiRun, abs(iLevel));
		if (lVLCtableIndex != NOT_IN_TABLE)  {
			nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_Last_RVLC", bDontSendBits);	// huffman encode 
			if( !bDontSendBits )
				m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_Last_RVLC");			
			nBits++;
		}
		else
			escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
	}
	return nBits;
}

Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEventInterRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
	assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
	assert (uiRun >= 0);
	if (uiRun > 38 || (uiLevel > grgIfNotLastNumOfLevelAtRunInterRVLC [uiRun]))
		return NOT_IN_TABLE;
	else	{
		UInt uiTableIndex = 0;	
		for (UInt i = 0; i < uiRun; i++)
			uiTableIndex += grgIfNotLastNumOfLevelAtRunInterRVLC [i];
		uiTableIndex += uiLevel;
		uiTableIndex--;												// make it zero-based; see Table H13/H.263
		return uiTableIndex;
	}
}

Int CVideoObjectEncoder::findVLCtableIndexOfLastEventInterRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
	assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
	assert (uiRun >= 0);
	if (uiRun > 44 || (uiLevel > grgIfLastNumOfLevelAtRunInterRVLC [uiRun]))
		return NOT_IN_TABLE;
	else	{
		UInt uiTableIndex = 0;	
		for (UInt i = 0; i < uiRun; i++)
			uiTableIndex += grgIfLastNumOfLevelAtRunInterRVLC [i];
		uiTableIndex += uiLevel;		
		uiTableIndex += 102;									// make it zero-based and 
		return uiTableIndex;								//correction of offset; see Table H13/H.263
	}
}

UInt CVideoObjectEncoder::escapeEncodeRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
{
	assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );

	UInt nBits = 0;

	Int iLevelAbs = abs (iLevel);
	Char iLevelSign = (Char) invSignOf (iLevel);

	nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(TCOEF_RVLC_ESCAPE, "FEsc_TCOEF_RVLC", bDontSendBits);
	if( !bDontSendBits )
		m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "FEsc1_TCOEF_RVLC");
	nBits ++;

	if( !bDontSendBits )
		m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) bIsLastRun, 1, "Last_Esc_TCOEF_RVLC");
	nBits ++;

	assert (uiRun < BLOCK_SQUARE_SIZE);
	if( !bDontSendBits )
		m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (uiRun, NUMBITS_RVLC_ESC_RUN, "Run_Esc_TCOEF_RVLC");	
	nBits += NUMBITS_RVLC_ESC_RUN;

	Int iLevelBits = 12; // = m_volmd.nBits;
	Int iMaxAC = (1<<(iLevelBits - 1)) - 1;
	assert (iLevelAbs <= iMaxAC && iLevelAbs > 0);
	if( !bDontSendBits )
	{
		m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "Marker");
		m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (iLevelAbs, iLevelBits - 1, "Level_Esc_TCOEF_RVLC");	
		m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "Marker");
	}
	nBits += iLevelBits - 1 + 2;

	nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(TCOEF_RVLC_ESCAPE, "LEsc_TCOEF_RVLC", bDontSendBits);
	if( !bDontSendBits )
		m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (iLevelSign, 1, "Sign_LEsc_TCOEF_RVLC");
	nBits ++;

	return nBits;
}

Int CVideoObjectEncoder::dumpCachedShapeBits_DP(Int iMBnum)
{
	Int ret;
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace("INSERTING PRE-ENCODED MB SHAPE STREAM HERE\n");
	m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location Before");
#endif // __TRACE_AND_STATS_
	m_pbitstrmOut->putBitStream(*m_pbitstrmShape_DP[iMBnum]);
	ret = m_pbitstrmShape_DP[iMBnum]->getCounter();
#ifdef __TRACE_AND_STATS_
	m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location After");
#endif // __TRACE_AND_STATS_
	m_pbitstrmShape_DP[iMBnum]->flush();
	m_pbitstrmShape_DP[iMBnum]->resetAll();

	return(ret);
}

⌨️ 快捷键说明

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