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

📄 blkenc.cpp

📁 此源码是在VC平台下,实现MPEG4编解码的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			|| blkn >=A_BLOCK1 && pmbmd->m_bACPredictionAlpha)
		{
			Int i, j;
			//do AC prediction
			if (pmbmd->m_preddir [blkn - 1] == HORIZONTAL)	{
				for (i = 8, j = 8; j < 2 * BLOCK_SIZE - 1; i += 8, j++)	{
					rgiCoefQ [i] -= (blkmPred == NULL) ? 0 : (iQPcurr == iQPpred) ?
									 blkmPred [j] : divroundnearest(blkmPred [j] * iQPpred, iQPcurr);
					assert (rgiCoefQ [i] >= -iMaxAC && rgiCoefQ [i]  <= iMaxAC);
				}

			}
			else if  (pmbmd->m_preddir [blkn - 1] == VERTICAL)	{
				//horizontal zigzag scan
				for (i = 1; i < BLOCK_SIZE; i++)	{
					rgiCoefQ [i] -= (blkmPred == NULL) ? 0 : (iQPcurr == iQPpred) ?
									 blkmPred [i] : divroundnearest(blkmPred [i] * iQPpred, iQPcurr);
					assert (rgiCoefQ [i] >= -iMaxAC && rgiCoefQ [i] <= iMaxAC);
				}
			}
			else
				assert (FALSE);
		}
	}
}

Void CVideoObjectEncoder::quantizeTextureInterBlock (PixelI* ppxliCurrQBlock, 
													 Int iWidthCurrQ,
													 Int* rgiCoefQ, 
													 Int iQP,
													 Bool bAlphaBlock)	
{
//	m_pentrencSet->m_pentrencDCT->bitstream()->trace (rgiCoefQ, "BLK_TEXTURE");
	m_pfdct->apply  (ppxliCurrQBlock, iWidthCurrQ, m_rgiDCTcoef, BLOCK_SIZE);
	if (m_volmd.fQuantizer == Q_H263)	{
		quantizeInterDCTcoefH263 (rgiCoefQ, 0, iQP);	
		inverseQuantizeDCTcoefH263 (rgiCoefQ, 0, iQP);
	}
	else	{
		quantizeInterDCTcoefMPEG (rgiCoefQ, 0, iQP, bAlphaBlock);	
		inverseQuantizeInterDCTcoefMPEG (rgiCoefQ, 0, iQP, bAlphaBlock);
	}

	m_pidct->apply (m_rgiDCTcoef, BLOCK_SIZE, ppxliCurrQBlock, iWidthCurrQ);
//	m_pentrencSet->m_pentrencDCT->bitstream()->trace (ppxliCurrQBlock, "BLK_TEXTURE_Q");
}

UInt CVideoObjectEncoder::sendIntraDC (const Int* rgiCoefQ, BlockNum blkn)
{
	UInt nBits = 0;
	UInt nBitsPerPixel = m_volmd.nBits; // NBIT
	Int iMaxVal = 1<<nBitsPerPixel; // NBIT

	assert (rgiCoefQ [0] >= -iMaxVal && rgiCoefQ [0] < iMaxVal);
	Int iAbsDiffIntraDC = abs (rgiCoefQ [0]);
	Long lSzDiffIntraDC = 0;
	for (Int i = nBitsPerPixel; i > 0; i--)
		if (iAbsDiffIntraDC & (1 << (i - 1)))	{
			lSzDiffIntraDC	= i;
			break;
		}

	COutBitStream* pobstrmIntraDC;
	if (blkn == U_BLOCK || blkn == V_BLOCK)	{
		nBits = m_pentrencSet->m_pentrencIntraDCc->encodeSymbol(lSzDiffIntraDC, "IntraDClen");		// huffman encode 
		pobstrmIntraDC = m_pentrencSet->m_pentrencIntraDCc -> bitstream ();
	}
	else	{
		nBits = m_pentrencSet->m_pentrencIntraDCy->encodeSymbol(lSzDiffIntraDC, "IntraDClen");		// huffman encode 
		pobstrmIntraDC = m_pentrencSet->m_pentrencIntraDCy -> bitstream ();
	}
	if (lSzDiffIntraDC<=8) { // NBIT
		    if (rgiCoefQ [0] > 0)
				pobstrmIntraDC->putBits ((Char) rgiCoefQ [0], lSzDiffIntraDC, "IntraDC");	//fix length code
		    else if (rgiCoefQ [0] < 0)
				pobstrmIntraDC->putBits (~iAbsDiffIntraDC, lSzDiffIntraDC, "IntraDC");		//fix length code
		    nBits += lSzDiffIntraDC;
	} else { // NBIT: MARKER bit inserted after first 8 bits
		 //   UInt uiOffset = lSzDiffIntraDC-8;
		    UInt uiValue = iAbsDiffIntraDC;
		    if (rgiCoefQ [0] < 0) {
				uiValue = ~iAbsDiffIntraDC;
		    }
/*
		    uiValue = ( (uiValue>>uiOffset)<<(uiOffset+1) )
				+ ( 1<<uiOffset )
			   + ( uiValue&((1<<uiOffset)-1) );
		    pobstrmIntraDC->putBits (uiValue, lSzDiffIntraDC+1, "IntraDC");
*/
		    pobstrmIntraDC->putBits (uiValue, lSzDiffIntraDC, "IntraDC");
		    pobstrmIntraDC->putBits (1, 1, "Marker");
		    nBits += lSzDiffIntraDC+1;
	}
	return nBits;
}

UInt CVideoObjectEncoder::sendTCOEFIntra (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag)
{
	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 += putBitsOfTCOEFIntra (uiPrevRun, iPrevLevel, bIsLastRun);
			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 += putBitsOfTCOEFIntra (uiPrevRun, iPrevLevel, bIsLastRun);
	return numBits;
}


UInt CVideoObjectEncoder::sendTCOEFInter (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag)
{
	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 += putBitsOfTCOEFInter (uiPrevRun, iPrevLevel, bIsLastRun);
			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 += putBitsOfTCOEFInter (uiPrevRun, iPrevLevel, bIsLastRun);
	return numBits;
}

UInt CVideoObjectEncoder::putBitsOfTCOEFInter (UInt uiRun, Int iLevel, Bool bIsLastRun)
{
	UInt nBits = 0;
	Long lVLCtableIndex;
	if (bIsLastRun == FALSE) {
		lVLCtableIndex = findVLCtableIndexOfNonLastEvent (bIsLastRun, uiRun, abs(iLevel));
		if (lVLCtableIndex != NOT_IN_TABLE)  {
			nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF");	// huffman encode 
			m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");			
			nBits++;
		}
		else
			nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXinter, g_rgiRMAXinter, &CVideoObjectEncoder::findVLCtableIndexOfNonLastEvent);
	}
	else	{
		lVLCtableIndex = findVLCtableIndexOfLastEvent (bIsLastRun, uiRun, abs(iLevel));
		if (lVLCtableIndex != NOT_IN_TABLE)  {
			nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF");	// huffman encode 
			m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");			
			nBits++;
		}
		else
			nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXinter, g_rgiRMAXinter, &CVideoObjectEncoder::findVLCtableIndexOfLastEvent);
	}
	return nBits;
}



UInt CVideoObjectEncoder::putBitsOfTCOEFIntra (UInt uiRun, Int iLevel, Bool bIsLastRun)
{
	//fprintf(stderr,"%d %d %d\n", iLevel,uiRun,bIsLastRun);

	Int nBits = 0;
	Long lVLCtableIndex;
	lVLCtableIndex = findVLCtableIndexOfIntra (bIsLastRun, uiRun, abs(iLevel));

	if (lVLCtableIndex != NOT_IN_TABLE)  {
		nBits += m_pentrencSet->m_pentrencDCTIntra->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF");	// huffman encode 
		m_pentrencSet->m_pentrencDCTIntra->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");			
		nBits++;
	}
	else
		nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXintra, g_rgiRMAXintra, &CVideoObjectEncoder::findVLCtableIndexOfIntra);

	return nBits;
}

UInt CVideoObjectEncoder::escapeEncode (UInt uiRun, Int iLevel, Bool bIsLastRun, Int* rgiLMAX, Int* rgiRMAX, 
										FIND_TABLE_INDEX findVLCtableIndex)
{
	UInt nBits = 0;
	nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(TCOEF_ESCAPE, "Esc_TCOEF");
	Int iLevelAbs = abs (iLevel);
	Int iLevelPlus = iLevelAbs - rgiLMAX [(uiRun & 0x0000003F) + (bIsLastRun << 6)];		//hashing the table
	Int iVLCtableIndex = (this->*findVLCtableIndex) (bIsLastRun, uiRun, abs (iLevelPlus));
	if (iVLCtableIndex != NOT_IN_TABLE)  {
		m_pbitstrmOut->putBits (0, 1, "Esc_0");			
		nBits++;
		nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(iVLCtableIndex, "Esc_1_Vlc_TCOEF");	// huffman encode 
		m_pbitstrmOut->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");
		nBits++;
	}
	else	{
		Int iRunPlus = uiRun - rgiRMAX [(iLevelAbs & 0x0000001F) + (bIsLastRun << 5)];  //RMAX table includes + 1 already
		iVLCtableIndex = (this->*findVLCtableIndex) (bIsLastRun, (UInt) iRunPlus, iLevelAbs);
		if (iVLCtableIndex != NOT_IN_TABLE)  {
			m_pbitstrmOut->putBits (2, 2, "Esc_10");			
			nBits += 2;
			nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(iVLCtableIndex, "Esc_01_Vlc_TCOEF");	// huffman encode 
			m_pbitstrmOut->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");			
			nBits++;
		}
		else	{
			m_pbitstrmOut->putBits (3, 2, "Esc_11");
			nBits += 2;
			nBits += fixLengthCode (uiRun, iLevel, bIsLastRun);
		}
	}
	return nBits;
}

UInt CVideoObjectEncoder::fixLengthCode (UInt uiRun, Int iLevel, Bool bIsLastRun)
{
	UInt nBits = 0;
	m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) bIsLastRun, 1, "Last_Run_TCOEF");
	nBits++;

	assert (uiRun < BLOCK_SQUARE_SIZE);
	m_pentrencSet->m_pentrencDCT->bitstream()->putBits (uiRun, NUMBITS_ESC_RUN, "Run_Esc_TCOEF");
	nBits+=NUMBITS_ESC_RUN;

	Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?)
	Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT
	assert (iLevel >= -iMaxAC && iLevel <= iMaxAC && iLevel != 0);
	if (iLevel < 0)
		iLevel = (1<<iLevelBits) - abs(iLevel);
	m_pentrencSet->m_pentrencDCT->bitstream()->putBits (1, 1, "Marker");
	m_pentrencSet->m_pentrencDCT->bitstream()->putBits (iLevel, iLevelBits, "Level_Esc_TCOEF");	
	m_pentrencSet->m_pentrencDCT->bitstream()->putBits (1, 1, "Marker");
	nBits += iLevelBits + 2;
	
	return nBits;
}

Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEvent (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{

	assert (uiRun >= 0);
	if (uiRun > 26 || (uiLevel > grgIfNotLastNumOfLevelAtRun [uiRun]))
		return NOT_IN_TABLE;
	else	{
		UInt uiTableIndex = 0;	
		for (UInt i = 0; i < uiRun; i++)
			uiTableIndex += grgIfNotLastNumOfLevelAtRun [i];
		uiTableIndex += uiLevel;
		uiTableIndex--;												// make it zero-based; see Table H13/H.263
		return uiTableIndex;
	}
}

Int CVideoObjectEncoder::findVLCtableIndexOfLastEvent (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
	assert (uiRun >= 0);
	if (uiRun > 40 || (uiLevel > grgIfLastNumOfLevelAtRun [uiRun]))
		return NOT_IN_TABLE;
	else	{
		UInt uiTableIndex = 0;	
		for (UInt i = 0; i < uiRun; i++)
			uiTableIndex += grgIfLastNumOfLevelAtRun [i];
		uiTableIndex += uiLevel;		
		uiTableIndex += 57;									// make it zero-based and 
		return uiTableIndex;								//correction of offset; see Table H13/H.263
	}
}

Int CVideoObjectEncoder::findVLCtableIndexOfIntra (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
	UInt i;
	assert (uiRun >= 0);
	if (uiRun > 20 || uiLevel > 27)
		return NOT_IN_TABLE;
	else	{
		UInt uiTableIndex = 0;	
		for (i = 0; i < TCOEF_ESCAPE; i++) {
			UInt iHashing = (bIsLastRun << 10) | (uiRun << 5) | uiLevel;
			if (iHashing == grgiIntraYAVCLHashingTable [i])	
				return i;
		}
		return NOT_IN_TABLE;
	}
}

⌨️ 快捷键说明

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