📄 uvlcwriter.cpp
字号:
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteTrailingOnes4( UInt uiCoeffCount, UInt uiTrailingOnes )
{
RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTO4[uiTrailingOnes][uiCoeffCount],
g_aucLenTableTO4[uiTrailingOnes][uiCoeffCount] ) );
ETRACE_POS;
ETRACE_T( " TrailingOnes4: CoeffCnt: " );
ETRACE_V( uiCoeffCount );
ETRACE_T( " TraiOnes: " );
ETRACE_V( uiTrailingOnes );
ETRACE_N;
ETRACE_COUNT(g_aucLenTableTO4[uiTrailingOnes][uiCoeffCount]);
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteTotalRun4( UInt uiVlcPos, UInt uiTotalRun )
{
RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTZ4[uiVlcPos][uiTotalRun],
g_aucLenTableTZ4[uiVlcPos][uiTotalRun] ) );
ETRACE_POS;
ETRACE_T( " TotalZeros4 vlc: " );
ETRACE_V( uiVlcPos );
ETRACE_T( " TotalRun: " );
ETRACE_V( uiTotalRun );
ETRACE_N;
ETRACE_COUNT(g_aucLenTableTZ4[uiVlcPos][uiTotalRun]);
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteTotalRun8( UInt uiVlcPos, UInt uiTotalRun )
{
RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTZ8[uiVlcPos][uiTotalRun],
g_aucLenTableTZ8[uiVlcPos][uiTotalRun] ) );
ETRACE_POS;
ETRACE_T( " TotalZeros8 vlc: " );
ETRACE_V( uiVlcPos );
ETRACE_T( " TotalRun: " );
ETRACE_V( uiTotalRun );
ETRACE_N;
ETRACE_COUNT(g_aucLenTableTZ8[uiVlcPos][uiTotalRun]);
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteTotalRun16( UInt uiVlcPos, UInt uiTotalRun )
{
RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTZ16[uiVlcPos][uiTotalRun],
g_aucLenTableTZ16[uiVlcPos][uiTotalRun] ) );
ETRACE_POS;
ETRACE_T( " TotalRun16 vlc: " );
ETRACE_V( uiVlcPos );
ETRACE_T( " TotalRun: " );
ETRACE_V( uiTotalRun );
ETRACE_N;
ETRACE_COUNT(g_aucLenTableTZ16[uiVlcPos][uiTotalRun]);
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteRun( UInt uiVlcPos, UInt uiRun )
{
RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTable3[uiVlcPos][uiRun],
g_aucLenTable3[uiVlcPos][uiRun] ) );
ETRACE_POS;
ETRACE_T( " Run" );
ETRACE_CODE( uiRun );
ETRACE_COUNT (g_aucLenTable3[uiVlcPos][uiRun]);
ETRACE_N;
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteLevelVLC0( Int iLevel )
{
UInt uiLength;
UInt uiLevel = abs( iLevel );
UInt uiSign = ((UInt)iLevel)>>31;
UInt uiBits;
if( 8 > uiLevel )
{
uiBits = 1;
uiLength = 2 * uiLevel - 1 + uiSign;
}
else if( 16 > uiLevel )
{
uiBits = 2*uiLevel + uiSign;
uiLength = 15 + 4;
}
else
{
uiBits = 0x1000-32 + (uiLevel<<1) + uiSign;
uiLength = 16 + 12;
}
RNOK( m_pcBitWriteBufferIf->write( uiBits, uiLength ) );
ETRACE_POS;
ETRACE_T( " VLC0 lev " );
ETRACE_CODE( iLevel );
ETRACE_N;
ETRACE_COUNT( uiLength );
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteLevelVLCN( Int iLevel, UInt uiVlcLength )
{
UInt uiLength;
UInt uiLevel = abs( iLevel );
UInt uiSign = ((UInt)iLevel)>>31;
UInt uiBits;
UInt uiShift = uiVlcLength-1;
UInt uiEscapeCode = (0xf<<uiShift)+1;
if( uiLevel < uiEscapeCode )
{
uiLevel--;
uiLength = (uiLevel>>uiShift) + uiVlcLength + 1;
uiLevel &= ~((0xffffffff)<<uiShift);
uiBits = (2<<uiShift) | 2*uiLevel | uiSign;
}
else
{
uiLength = 28;
uiBits = 0x1000 + 2*(uiLevel-uiEscapeCode) + uiSign;
}
RNOK( m_pcBitWriteBufferIf->write( uiBits, uiLength ) );
ETRACE_POS;
ETRACE_T( " VLCN lev: " );
ETRACE_CODE( iLevel );
ETRACE_N;
ETRACE_COUNT( uiLength );
return Err::m_nOK;
}
ErrVal UvlcWriter::samplesPCM( MbDataAccess& rcMbDataAccess )
{
ETRACE_POS;
ETRACE_T( " PCM SAMPLES: " );
RNOK( m_pcBitWriteBufferIf->writeAlignZero() );
AOF_DBG( rcMbDataAccess.getMbData().isPCM() );
rcMbDataAccess.getMbTCoeffs().setAllCoeffCount( 16 );
Pel* pSrc = rcMbDataAccess.getMbTCoeffs().getPelBuffer();
const UInt uiFactor = 8*8;
const UInt uiSize = uiFactor*2*3;
RNOK( m_pcBitWriteBufferIf->samples( pSrc, uiSize ) );
ETRACE_N;
ETRACE_COUNT( uiFactor*6 );
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteRefFrame( Bool bWriteBit, UInt uiRefFrame )
{
ETRACE_T( "RefFrame" );
if( bWriteBit )
{
RNOK( xWriteFlag( 1-uiRefFrame ) );
}
else
{
RNOK( xWriteUvlcCode( uiRefFrame ) );
}
ETRACE_V( uiRefFrame+1 );
ETRACE_N;
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteMotionPredFlag( Bool bFlag )
{
ETRACE_T( "MotionPredFlag" );
UInt uiCode = ( bFlag ? 1 : 0 );
RNOK( xWriteFlag( uiCode) );
ETRACE_V( uiCode );
ETRACE_N;
return Err::m_nOK;
}
ErrVal UvlcWriter::transformSize8x8Flag( MbDataAccess& rcMbDataAccess, UInt uiStart, UInt uiStop )
{
ETRACE_T( "transformSize8x8Flag:" );
UInt uiCode = rcMbDataAccess.getMbData().isTransformSize8x8() ? 1 : 0;
RNOK( xWriteFlag( uiCode) );
ETRACE_V( uiCode );
ETRACE_N;
return Err::m_nOK;
}
ErrVal UvlcWriter::residualBlock8x8( MbDataAccess& rcMbDataAccess,
B8x8Idx c8x8Idx,
ResidualMode eResidualMode,
UInt uiStart,
UInt uiStop )
{
ROF( eResidualMode == LUMA_SCAN );
const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
const UChar* pucScan = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;
TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get8x8( c8x8Idx );
UInt uiBlk;
Int iLevel;
Int iOverallRun = 0;
UInt uiPos = uiStart << 2;
UInt uiMaxPos = uiStop << 2;
Int aaiLevelRun [4][32];
Int aiRun [4] = { 0, 0, 0, 0 };
UInt auiTrailingOnes [4] = { 0, 0, 0, 0 };
UInt auiTotalRun [4] = { 0, 0, 0, 0 };
UInt auiCoeffCnt [4] = { 0, 0, 0, 0 };
while( uiPos < uiMaxPos )
{
uiBlk = ( uiPos % 4 );
if( ( iLevel = piCoeff[ pucScan[ uiPos++ ] ] ) )
{
if( abs(iLevel) == 1 )
{
m_uiCoeffCost += COEFF_COST8x8[ iOverallRun ];
auiTrailingOnes[uiBlk]++;
}
else
{
m_uiCoeffCost += MAX_VALUE;
auiTrailingOnes[uiBlk] = 0;
}
aaiLevelRun[uiBlk][auiCoeffCnt[uiBlk]] = iLevel;
aaiLevelRun[uiBlk][auiCoeffCnt[uiBlk]+0x10] = aiRun[uiBlk];
auiTotalRun[uiBlk] += aiRun[uiBlk];
auiCoeffCnt[uiBlk] ++;
aiRun [uiBlk] = 0;
iOverallRun = 0;
}
else
{
aiRun[uiBlk]++;
iOverallRun ++;
}
}
//===== loop over 4x4 blocks =====
Bool bDefaultScanIdx = ( uiStart == 0 && uiStop == 16 );
for( uiBlk = 0; uiBlk < 4; uiBlk++ )
{
if( auiTrailingOnes[uiBlk] > 3 )
{
auiTrailingOnes[uiBlk] = 3;
}
B4x4Idx cIdx( c8x8Idx.b4x4() + 4*(uiBlk/2) + (uiBlk%2) );
RNOK( xPredictNonZeroCnt( rcMbDataAccess, cIdx, auiCoeffCnt[uiBlk], auiTrailingOnes[uiBlk], uiStart, uiStop ) );
RNOK( xWriteRunLevel( aaiLevelRun[uiBlk],
auiCoeffCnt[uiBlk],
auiTrailingOnes[uiBlk],
uiStop-uiStart,
auiTotalRun[uiBlk],
rcMbDataAccess, bDefaultScanIdx ) );
}
return Err::m_nOK;
}
ErrVal
UvlcWriter::xWriteGolomb(UInt uiSymbol, UInt uiK)
{
UInt uiQ = uiSymbol / uiK;
UInt uiR = uiSymbol - uiQ * uiK;
UInt uiC = 0;
UInt uiT = uiK >> 1;
while ( uiT > 0 )
{
uiC++;
uiT >>= 1;
}
// Unary part
for ( UInt ui = 0; ui < uiQ; ui++ )
{
RNOK( xWriteFlag( 1 ) );
}
RNOK( xWriteFlag( 0 ) );
// Binary part
if ( uiR < uiC )
{
RNOK( xWriteCode( uiR, uiC ) );
} else if ( uiC > 0 ) {
RNOK( xWriteFlag( 1 ) );
RNOK( xWriteCode( uiR - uiC, uiC ) );
}
ETRACE_N;
return Err::m_nOK;
}
UInt g_auiSigRunTabCode[] = {0x01, 0x01, 0x01, 0x01, 0x00};
UInt g_auiSigRunTabCodeLen[] = {1, 2, 3, 4, 4};
ErrVal
UvlcWriter::xEncodeMonSeq ( UInt* auiSeq, UInt uiStartVal, UInt uiLen )
{
UInt uiRun = 0;
UInt uiLevel = uiStartVal;
for (UInt uiPos=0; uiPos<uiLen && uiLevel > 0; uiPos++)
{
if (auiSeq[uiPos] == uiLevel)
{
uiRun++;
} else {
ETRACE_T("eob_run");
RNOK( xWriteGolomb( uiRun, 1 ) );
uiRun = 1;
uiLevel--;
while ( uiLevel > auiSeq[uiPos] )
{
ETRACE_T("eob_run");
RNOK( xWriteGolomb( 0, 1 ) );
uiLevel--;
}
}
}
if (uiLevel > 0)
{
ETRACE_T("eob_run");
RNOK( xWriteGolomb( uiRun, 1 ) );
}
return Err::m_nOK;
}
ErrVal
UvlcWriter::xWriteSigRunCode ( UInt uiSymbol, UInt uiTableIdx )
{
assert( uiTableIdx >= 0 && uiTableIdx <= 4 );
if(uiTableIdx == 0)
{
// unary code
RNOK ( xWriteUnaryCode (uiSymbol) );
}
else if (uiTableIdx == 1)
{
RNOK ( xWriteCodeCB1 (uiSymbol) );
}
else if (uiTableIdx == 2)
{
RNOK ( xWriteCodeCB2 (uiSymbol) );
}
else if (uiTableIdx == 3)
{
if ( uiSymbol == 0 )
{
RNOK( xWriteFlag( 1 ) );
}
else
{
RNOK( xWriteFlag( 0 ) );
RNOK( xWriteCodeCB2 (uiSymbol-1) );
}
}
else // uiTableIdx == 4
{
if(uiSymbol == 0)
{
RNOK (xWriteFlag ( 1 ));
}
else
{
RNOK (xWriteCodeCB1(uiSymbol+1));
}
}
return Err::m_nOK;
}
ErrVal
UvlcWriter::xWriteUnaryCode ( UInt uiSymbol )
{
UInt uiStart = 0;
do
{
if(uiSymbol == uiStart)
{
RNOK( xWriteFlag (1) );
break;
}
else
{
RNOK( xWriteFlag (0) );
uiStart++;
}
}
while (true);
return Err::m_nOK;
}
ErrVal
UvlcWriter::xWriteCodeCB1 ( UInt uiSymbol )
{
// this function writes codeword for the input symbol according to the {2, 2, 3, 3, 4, 4...} codebook
for(UInt ui = 0; ui < uiSymbol/2; ui ++)
{
RNOK (xWriteFlag (0));
}
RNOK (xWriteCode((3-(uiSymbol%2)), 2)) ;
return Err::m_nOK;
}
ErrVal
UvlcWriter::xWriteCodeCB2 ( UInt uiSymbol )
{
// this function writes codeword for the input symbol according to the {2, 2, 2, 4, 4, 4...} codebook
for(UInt ui = 0; ui < uiSymbol/3; ui ++)
{
RNOK(xWriteCode (0, 2));
}
RNOK (xWriteCode((3-(uiSymbol%3)), 2));
return Err::m_nOK;
}
//JVT-X046 {
void
UvlcWriter::loadUvlcWrite(MbSymbolWriteIf *pcMbSymbolWriteIf)
{
UvlcWriter* pcUvlcWriter = (UvlcWriter*) (pcMbSymbolWriteIf);
m_uiBitCounter = pcUvlcWriter->getBitCounter();
m_uiPosCounter = pcUvlcWriter->getPosCounter();
m_uiCoeffCost = pcUvlcWriter->getCoeffCost();
m_bTraceEnable = pcUvlcWriter->getTraceEnable();
m_bRunLengthCoding = pcUvlcWriter->getRunLengthCoding();
m_uiRun = pcUvlcWriter->getRun();
if ( m_pcBitWriteBufferIf == NULL )
{
BitWriteBuffer *pcBitWriteBuffer;
BitWriteBuffer::create(pcBitWriteBuffer);
m_pcBitWriteBufferIf = pcBitWriteBuffer;
}
m_pcBitWriteBufferIf->loadBitWriteBuffer(pcUvlcWriter->getBitWriteBufferIf());
}
//JVT-X046 }
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -