📄 uvlcwriter.cpp
字号:
pucScan = g_aucFrameScan;
break;
}
default:
return Err::m_nERR;
}
Int aiLevelRun[32];
UInt uiTrailingOnes = 0;
UInt uiTotalRun = 0;
UInt uiCoeffCnt = 0;
while( uiPos < uiMaxPos )
{
if( ( iLevel = piCoeff[ pucScan [ uiPos++ ] ]) )
{
if( abs(iLevel) == 1 )
{
m_uiCoeffCost += COEFF_COST[iRun];
uiTrailingOnes++;
}
else
{
m_uiCoeffCost += MAX_VALUE; // set high cost, shall not be discarded
uiTrailingOnes = 0;
}
aiLevelRun[uiCoeffCnt] = iLevel;
aiLevelRun[uiCoeffCnt+0x10] = iRun;
uiTotalRun += iRun;
uiCoeffCnt++;
iRun = 0;
}
else
{
iRun++;
}
}
if( uiTrailingOnes > 3 )
{
uiTrailingOnes = 3;
}
switch( eResidualMode )
{
case LUMA_I16_DC:
{
ETRACE_T( "Luma:" );
ETRACE_V( cIdx );
ETRACE_N;
xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes );
xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 16, uiTotalRun );
break;
}
case LUMA_I16_AC:
{
ETRACE_T( "Luma:" );
ETRACE_V( cIdx );
ETRACE_N;
xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes );
xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 15, uiTotalRun );
break;
}
case LUMA_SCAN:
{
ETRACE_T( "Luma:" );
ETRACE_V( cIdx );
ETRACE_N;
xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes );
xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 16, uiTotalRun );
break;
}
default:
{
AF();
}
}
return Err::m_nOK;
}
ErrVal UvlcWriter::residualBlock( MbDataAccess& rcMbDataAccess,
ChromaIdx cIdx,
ResidualMode eResidualMode )
{
const TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( cIdx );
const UChar* pucScan;
Int iRun = 0, iLevel;
UInt uiPos, uiMaxPos;
switch( eResidualMode )
{
case CHROMA_DC:
{
pucScan = g_aucIndexChromaDCScan;
uiPos=0; uiMaxPos= 4;
break;
}
case CHROMA_AC:
{
pucScan = g_aucFrameScan;
uiPos=1; uiMaxPos=16;
break;
}
default:
return Err::m_nERR;
}
Int aiLevelRun[32];
UInt uiTrailingOnes = 0;
UInt uiTotalRun = 0;
UInt uiCoeffCnt = 0;
while( uiPos < uiMaxPos )
{
if( ( iLevel = piCoeff[ pucScan [ uiPos++ ] ]) )
{
if( abs(iLevel) == 1 )
{
m_uiCoeffCost += COEFF_COST[iRun];
uiTrailingOnes++;
}
else
{
m_uiCoeffCost += MAX_VALUE; // set high cost, shall not be discarded
uiTrailingOnes = 0;
}
aiLevelRun[uiCoeffCnt] = iLevel;
aiLevelRun[uiCoeffCnt+0x10] = iRun;
uiTotalRun += iRun;
uiCoeffCnt++;
iRun = 0;
}
else
{
iRun++;
}
}
if( uiTrailingOnes > 3 )
{
uiTrailingOnes = 3;
}
switch( eResidualMode )
{
case CHROMA_AC:
{
ETRACE_T( "CHROMA_AC:" );
ETRACE_V( cIdx );
ETRACE_N;
xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes );
xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 15, uiTotalRun );
break;
}
case CHROMA_DC:
{
ETRACE_T( "CHROMA_DC:" );
ETRACE_V( cIdx );
ETRACE_N;
xWriteTrailingOnes4( uiCoeffCnt, uiTrailingOnes );
xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 4, uiTotalRun );
break;
}
default:
{
AF();
}
}
return Err::m_nOK;
}
ErrVal UvlcWriter::deltaQp( MbDataAccess& rcMbDataAccess )
{
ETRACE_T ("DQp");
RNOK( xWriteSvlcCode( rcMbDataAccess.getDeltaQp() ) );
ETRACE_TY ("se(v)");
ETRACE_N;
return Err::m_nOK;
}
ErrVal UvlcWriter::finishSlice()
{
if( m_bRunLengthCoding && m_uiRun )
{
ETRACE_T( "Run" );
RNOK( xWriteUvlcCode( m_uiRun ) );
ETRACE_N;
}
return Err::m_nOK;
}
ErrVal UvlcWriter::xPredictNonZeroCnt( MbDataAccess& rcMbDataAccess, ChromaIdx cIdx, UInt uiCoeffCount, UInt uiTrailingOnes )
{
UInt uiCoeffCountCtx = rcMbDataAccess.getCtxCoeffCount( cIdx );
xWriteTrailingOnes16( uiCoeffCountCtx, uiCoeffCount, uiTrailingOnes );
rcMbDataAccess.getMbTCoeffs().setCoeffCount( cIdx, uiCoeffCount );
return Err::m_nOK;
}
ErrVal UvlcWriter::xPredictNonZeroCnt( MbDataAccess& rcMbDataAccess, LumaIdx cIdx, UInt uiCoeffCount, UInt uiTrailingOnes )
{
UInt uiCoeffCountCtx = rcMbDataAccess.getCtxCoeffCount( cIdx );
xWriteTrailingOnes16( uiCoeffCountCtx, uiCoeffCount, uiTrailingOnes );
rcMbDataAccess.getMbTCoeffs().setCoeffCount( cIdx, uiCoeffCount );
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteRunLevel( Int* aiLevelRun, UInt uiCoeffCnt, UInt uiTrailingOnes, UInt uiMaxCoeffs, UInt uiTotalRun )
{
ROTRS( 0 == uiCoeffCnt, Err::m_nOK );
if( uiTrailingOnes )
{
UInt uiBits = 0;
Int n = uiTrailingOnes-1;
for( UInt k = uiCoeffCnt; k > uiCoeffCnt-uiTrailingOnes; k--, n--)
{
if( aiLevelRun[k-1] < 0)
{
uiBits |= 1<<n;
}
}
RNOK( m_pcBitWriteBufferIf->write( uiBits, uiTrailingOnes ))
ETRACE_POS;
ETRACE_T( " TrailingOnesSigns: " );
ETRACE_V( uiBits );
ETRACE_N;
ETRACE_COUNT(uiTrailingOnes);
}
Int iHighLevel = ( uiCoeffCnt > 3 && uiTrailingOnes == 3) ? 0 : 1;
Int iVlcTable = ( uiCoeffCnt > 10 && uiTrailingOnes < 3) ? 1 : 0;
for( Int k = uiCoeffCnt - 1 - uiTrailingOnes; k >= 0; k--)
{
Int iLevel;
iLevel = aiLevelRun[k];
UInt uiAbsLevel = (UInt)abs(iLevel);
if( iHighLevel )
{
iLevel -= ( iLevel > 0 ) ? 1 : -1;
iHighLevel = 0;
}
if( iVlcTable == 0 )
{
xWriteLevelVLC0( iLevel );
}
else
{
xWriteLevelVLCN( iLevel, iVlcTable );
}
// update VLC table
if( uiAbsLevel > g_auiIncVlc[ iVlcTable ] )
{
iVlcTable++;
}
if( k == Int(uiCoeffCnt - 1 - uiTrailingOnes) && uiAbsLevel > 3)
{
iVlcTable = 2;
}
}
ROFRS( uiCoeffCnt < uiMaxCoeffs, Err::m_nOK );
iVlcTable = uiCoeffCnt-1;
if( uiMaxCoeffs <= 4 )
{
xWriteTotalRun4( iVlcTable, uiTotalRun );
}
else
{
xWriteTotalRun16( iVlcTable, uiTotalRun );
}
// decode run before each coefficient
uiCoeffCnt--;
if( uiTotalRun > 0 && uiCoeffCnt > 0)
{
do
{
iVlcTable = (( uiTotalRun > RUNBEFORE_NUM) ? RUNBEFORE_NUM : uiTotalRun) - 1;
UInt uiRun = aiLevelRun[uiCoeffCnt+0x10];
xWriteRun( iVlcTable, uiRun );
uiTotalRun -= uiRun;
uiCoeffCnt--;
} while( uiTotalRun != 0 && uiCoeffCnt != 0);
}
return Err::m_nOK;
}
ErrVal UvlcWriter::xWriteTrailingOnes16( UInt uiLastCoeffCount, UInt uiCoeffCount, UInt uiTrailingOnes )
{
UInt uiVal;
UInt uiSize;
ETRACE_POS;
if( 3 == uiLastCoeffCount )
{
UInt uiBits = 3;
if( uiCoeffCount )
{
uiBits = (uiCoeffCount-1)<<2 | uiTrailingOnes;
}
RNOK( m_pcBitWriteBufferIf->write( uiBits, 6) );
ETRACE_DO( m_uiBitCounter = 6 );
uiVal = uiBits;
uiSize = 6;
}
else
{
RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount],
g_aucLenTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount] ) );
ETRACE_DO( m_uiBitCounter = g_aucLenTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount] );
uiVal = g_aucCodeTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount];
uiSize = g_aucLenTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount];
}
ETRACE_T( " TrailingOnes16: Vlc: " );
ETRACE_V( uiLastCoeffCount );
ETRACE_T( " CoeffCnt: " );
ETRACE_V( uiCoeffCount );
ETRACE_T( " TraiOnes: " );
ETRACE_V( uiTrailingOnes );
ETRACE_N;
ETRACE_COUNT(m_uiBitCounter);
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::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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -