📄 uvlcwriter.cpp
字号:
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 )
{
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 )
{
ROF( eResidualMode == LUMA_SCAN );
const UChar* pucScan = g_aucFrameScan64;
const TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get8x8( c8x8Idx );
UInt uiBlk;
Int iLevel;
Int iOverallRun = 0;
UInt uiPos = 0;
UInt uiMaxPos = 64;
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 =====
for( uiBlk = 0; uiBlk < 4; uiBlk++ )
{
if( auiTrailingOnes[uiBlk] > 3 )
{
auiTrailingOnes[uiBlk] = 3;
}
B4x4Idx cIdx( c8x8Idx.b4x4() + 4*(uiBlk/2) + (uiBlk%2) );
xPredictNonZeroCnt( rcMbDataAccess, cIdx, auiCoeffCnt[uiBlk], auiTrailingOnes[uiBlk] );
xWriteRunLevel ( aaiLevelRun[uiBlk], auiCoeffCnt[uiBlk], auiTrailingOnes[uiBlk], 16, auiTotalRun[uiBlk] );
}
return Err::m_nOK;
}
Bool
UvlcWriter::RQencodeCBP_8x8( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
B8x8Idx c8x8Idx )
{
UInt uiSymbol = ( ( rcMbDataAccess.getMbData().getMbCbp() >> c8x8Idx.b8x8Index() ) & 1 ? 1 : 0 );
if( uiSymbol )
{
rcMbDataAccessBase.getMbData().setMbCbp( rcMbDataAccessBase.getMbData().getMbCbp() | ( 1 << c8x8Idx.b8x8Index() ) );
}
return ( uiSymbol == 1 );
}
Bool
UvlcWriter::RQpeekCbp4x4( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
LumaIdx cIdx )
{
UInt uiSymbol = 0;
TCoeff* piCoeff = rcMbDataAccess. getMbTCoeffs().get( cIdx );
TCoeff* piBCoeff = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
for( UInt ui = 0; ui < 16; ui++ )
{
if( piCoeff[ g_aucFrameScan[ui] ] && !piBCoeff[ g_aucFrameScan[ui] ] )
{
uiSymbol = 1;
break;
}
}
return ( uiSymbol == 1 );
}
Bool
UvlcWriter::RQencodeBCBP_4x4( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
LumaIdx cIdx )
{
if ( (cIdx.x() %2) == 0 && (cIdx.y() %2) == 0)
{
// Write
UInt uiCode = 0;
UInt uiLen = 0;
UInt uiFlip = (m_uiCbpStat4x4[1] > m_uiCbpStat4x4[0]) ? 1 : 0;
UInt uiVlc = (m_uiCbpStat4x4[uiFlip] < 2*m_uiCbpStat4x4[1-uiFlip]) ? 0 : 2;
for( Int iY=cIdx.y(); iY<cIdx.y()+2; iY++)
for ( Int iX=cIdx.x(); iX<cIdx.x()+2; iX++)
{
UInt uiSymbol = 0;
B4x4Idx cTmp(iY*4+iX);
uiSymbol = RQpeekCbp4x4(rcMbDataAccess, rcMbDataAccessBase, cTmp);
rcMbDataAccessBase.getMbData().setBCBP( cTmp, uiSymbol );
uiCode <<= 1;
uiCode |= uiSymbol;
uiLen++;
m_uiCbpStat4x4[uiSymbol]++;
}
if (uiFlip)
uiCode = uiCode ^ ((1<<uiLen)-1);
if (uiVlc == 0)
{
ANOK( xWriteCode( uiCode, uiLen ) );
} else {
ANOK( xWriteCode( g_auiISymCode[2][uiCode], g_auiISymLen[2][uiCode] ) );
}
// Scaling
if (m_uiCbpStat4x4[0]+m_uiCbpStat4x4[1] > 512)
{
m_uiCbpStat4x4[0] >>= 1;
m_uiCbpStat4x4[1] >>= 1;
}
ETRACE_T( "BCBP_4x4" );
ETRACE_V( uiCode );
ETRACE_N;
}
return RQpeekCbp4x4(rcMbDataAccess, rcMbDataAccessBase, cIdx);
}
Bool
UvlcWriter::RQencodeCBP_Chroma( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase )
{
UInt uiSymbol = ( ( rcMbDataAccess.getMbData().getMbCbp() >> 4 ) ? 1 : 0 );
ETRACE_T( "CBP_Chroma" );
ETRACE_V( uiSymbol );
ETRACE_N;
if( uiSymbol )
{
rcMbDataAccessBase.getMbData().setMbCbp( rcMbDataAccessBase.getMbData().getMbCbp() | 0x10 );
}
return ( uiSymbol == 1 );
}
Bool
UvlcWriter::RQencodeBCBP_ChromaDC( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ChromaIdx cIdx )
{
UInt uiSymbol = 0;
TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( cIdx );
TCoeff* piBCoeff = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
for( UInt ui = 0; ui < 4; ui++ )
{
if( piCoeff[ g_aucIndexChromaDCScan[ui] ] && !piBCoeff[ g_aucIndexChromaDCScan[ui] ] )
{
uiSymbol = 1;
break;
}
}
ANOK( xWriteFlag( uiSymbol ) );
ETRACE_T( "BCBP_ChromaDC" );
ETRACE_V( uiSymbol );
ETRACE_N;
rcMbDataAccessBase.getMbData().setBCBP( 24 + cIdx.plane(), uiSymbol );
return ( uiSymbol == 1 );
}
Bool
UvlcWriter::RQencodeBCBP_ChromaAC( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ChromaIdx cIdx )
{
UInt uiSymbol = 0;
TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( cIdx );
TCoeff* piBCoeff = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
for( UInt ui = 1; ui < 16; ui++ )
{
if( piCoeff[ g_aucFrameScan[ui] ] && !piBCoeff[ g_aucFrameScan[ui] ] )
{
uiSymbol = 1;
break;
}
}
ANOK( xWriteFlag( uiSymbol ) );
ETRACE_T( "BCBP_ChromaAC" );
ETRACE_V( uiSymbol );
ETRACE_N;
rcMbDataAccessBase.getMbData().setBCBP( 16 + cIdx, uiSymbol );
return ( uiSymbol == 1 );
}
Bool
UvlcWriter::RQencodeCBP_ChromaAC( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase )
{
UInt uiSymbol = ( ( rcMbDataAccess.getMbData().getMbCbp() >> 5 ) ? 1 : 0 );
ETRACE_T( "CBP_ChromaAC" );
ETRACE_V( uiSymbol );
ETRACE_N;
if( uiSymbol )
{
rcMbDataAccessBase.getMbData().setMbCbp( ( rcMbDataAccessBase.getMbData().getMbCbp() & 0xF ) | 0x20 );
}
return ( uiSymbol == 1 );
}
ErrVal
UvlcWriter::RQencodeDeltaQp( MbDataAccess& rcMbDataAccess )
{
ETRACE_T ("DQp");
RNOK( xWriteSvlcCode( rcMbDataAccess.getDeltaQp() ) );
ETRACE_TY ("se(v)");
ETRACE_N;
return Err::m_nOK;
}
ErrVal
UvlcWriter::RQencode8x8Flag( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase )
{
UInt uiSymbol = rcMbDataAccess.getMbData().isTransformSize8x8() ? 1 : 0;
RNOK( xWriteFlag( uiSymbol ) );
ETRACE_T( "TRAFO_8x8" );
ETRACE_V( uiSymbol );
ETRACE_N;
rcMbDataAccessBase.getMbData().setTransformSize8x8( rcMbDataAccess.getMbData().isTransformSize8x8() );
return Err::m_nOK;
}
ErrVal
UvlcWriter::RQeo8b( Bool& bEob )
{
RNOK( xWriteFlag( bEob ? 1 : 0 ) );
return Err::m_nOK;
}
ErrVal
UvlcWriter::RQencodeNewTCoeff_8x8( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
B8x8Idx c8x8Idx,
UInt uiScanIndex,
Bool& rbLast,
UInt& ruiNumCoefWritten )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get8x8( c8x8Idx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx );
const UChar* pucScan = g_aucFrameScan64;
ROT( piCoeffBase[pucScan[uiScanIndex]] );
ETRACE_T( "LUMA_8x8_NEW" );
ETRACE_V( c8x8Idx.b8x8Index() );
ETRACE_V( uiScanIndex );
ETRACE_N;
rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4(), 1 );
rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+1, 1 );
rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+4, 1 );
rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+5, 1 );
UInt auiEobShift[16];
memset(auiEobShift, 0, sizeof(UInt)*16);
RNOK( xRQencodeNewTCoeffs( piCoeff, piCoeffBase, uiScanIndex%4, 64, 4, pucScan, uiScanIndex, auiEobShift, rbLast, ruiNumCoefWritten ) );
return Err::m_nOK;
}
ErrVal
UvlcWriter::RQencodeNewTCoeff_Luma ( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ResidualMode eResidualMode,
LumaIdx cIdx,
UInt uiScanIndex,
Bool& rbLast,
UInt& ruiNumCoefWritten )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get( cIdx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
const UChar* pucScan = g_aucFrameScan;
UInt uiStart = 0;
UInt uiStop = 16;
ROT( piCoeffBase[pucScan[uiScanIndex]] );
ETRACE_T( "LUMA_4x4_NEW" );
ETRACE_V( cIdx.b4x4() );
ETRACE_V( uiScanIndex );
ETRACE_N;
RNOK( xRQencodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, 1, pucScan, uiScanIndex, m_auiShiftLuma, rbLast, ruiNumCoefWritten ) );
return Err::m_nOK;
}
ErrVal
UvlcWriter::RQencodeNewTCoeff_Chroma ( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ResidualMode eResidualMode,
ChromaIdx cIdx,
UInt uiScanIndex,
Bool& rbLast,
UInt& ruiNumCoefWritten )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get( cIdx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
const UChar* pucScan = ( eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : g_aucFrameScan );
UInt uiStart = ( eResidualMode == CHROMA_AC ? 1 : 0 );
UInt uiStop = ( eResidualMode == CHROMA_DC ? 4 : 16 );
ROT( piCoeffBase[pucScan[uiScanIndex]] );
ETRACE_T( "CHROMA_4x4_NEW" );
ETRACE_V( cIdx );
ETRACE_V( uiScanIndex );
ETRACE_N;
RNOK( xRQencodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, 1, pucScan, uiScanIndex, m_auiShiftChroma, rbLast, ruiNumCoefWritten ) );
return Err::m_nOK;
}
ErrVal
UvlcWriter::xRQencodeNewTCoeffs( TCoeff* piCoeff,
TCoeff* piCoeffBase,
UInt uiStart,
UInt uiStop,
UInt uiStride,
const UChar* pucScan,
UInt uiScanIndex,
UInt* pauiEobShift,
Bool& rbLast,
UInt& ruiNumCoefWritten )
{
UInt ui;
UInt uiCycle = 0;
for ( ui=uiStart; ui<uiScanIndex; ui+=uiStride )
{
if ( !piCoeffBase[pucScan[ui]] && piCoeff[pucScan[ui]] )
{
uiCycle = ui/uiStride + 1;
}
}
AOF( uiCycle < uiStop );
Bool bSkipEob = !rbLast;
ruiNumCoefWritten = 0;
if( rbLast )
{
rbLast = true;
for( ui = uiScanIndex; ui < uiStop; ui+=uiStride )
{
if( piCoeff[pucScan[ui]] && !piCoeffBase[pucScan[ui]] )
{
rbLast = false;
break;
}
}
if (rbLast) {
UInt uiCountMag2;
UInt uiLastPos = 1;
for( ui = uiStart; ui < uiStop; ui+=uiStride )
{
if ( ! piCoeffBase[pucScan[ui]] )
uiLastPos++;
if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
{
uiLastPos = 1;
}
}
RNOK( xRQencodeSigMagGreater1( piCoeff, piCoeffBase, uiLastPos, uiStart, uiStop, uiCycle, pucScan, uiCountMag2, uiStride ) );
if ( uiCountMag2 == 0 )
{
RNOK( xWriteSigRunCode( min(pauiEobShift[uiCycle], uiLastPos), m_auiBestCodeTabMap[uiCycle] ) );
}
}
ROTRS(rbLast, Err::m_nOK);
} else
rbLast = false;
//===== SIGNIFICANCE BIT ======
UInt uiSig;
do
{
ruiNumCoefWritten++;
UInt uiLastScanPosition = uiScanIndex + uiStride;
while (uiLastScanPosition < uiStop && piCoeffBase[pucScan[uiLastScanPosition]])
uiLastScanPosition += uiStride;
if (uiLastScanPosition < uiStop)
{
uiSig = piCoeff[pucScan[uiScanIndex] ] ? 1 : 0;
} else {
uiSig = 1;
}
if( uiSig )
{
break;
}
uiScanIndex+=uiStride;
while (uiScanIndex < uiStop && piCoeffBase[pucScan[uiScanIndex]])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -