uvlcwriter.cpp
来自「JVT-S203 contains the JSVM 6 reference s」· C++ 代码 · 共 2,605 行 · 第 1/5 页
CPP
2,605 行
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::RQencodeNewTCoeff_8x8( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
B8x8Idx c8x8Idx,
UInt uiScanIndex,
UInt& ruiLast )
{
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 );
//===== end-of-block =====
if( ruiLast )
{
for( UInt ui = uiScanIndex; ui < 64; ui++ )
{
if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]] )
{
ruiLast = 0;
break;
}
}
RNOK( xWriteFlag( ruiLast ) );
ROTRS( ruiLast, Err::m_nOK );
}
else
{
ruiLast = 0;
}
//===== SIGNIFICANCE BIT =====
UInt uiSig = ( piCoeff[pucScan[uiScanIndex]] ? 1 : 0 );
RNOK( xWriteFlag( uiSig ) );
if( uiSig )
{
xWriteLevelVLC0( piCoeff[pucScan[uiScanIndex]] );
}
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, eResidualMode, 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, eResidualMode, pucScan, uiScanIndex, m_auiShiftChroma, rbLast, ruiNumCoefWritten ) );
return Err::m_nOK;
}
ErrVal
UvlcWriter::xRQencodeNewTCoeffs( TCoeff* piCoeff,
TCoeff* piCoeffBase,
UInt uiStart,
UInt uiStop,
ResidualMode eResidualMode,
const UChar* pucScan,
UInt uiScanIndex,
UInt* pauiEobShift,
Bool& rbLast,
UInt& ruiNumCoefWritten )
{
UInt ui;
UInt uiCycle = 0;
for ( ui=uiStart; ui<uiScanIndex; ui++ )
{
if ( !piCoeffBase[pucScan[ui]] && piCoeff[pucScan[ui]] )
{
uiCycle = ui + 1;
}
}
AOF( uiCycle < uiStop );
Bool bSkipEob = !rbLast;
ruiNumCoefWritten = 0;
if( rbLast )
{
rbLast = true;
for( ui = uiScanIndex; ui < uiStop; ui++ )
{
if( piCoeff[pucScan[ui]] && !piCoeffBase[pucScan[ui]] )
{
rbLast = false;
break;
}
}
if (rbLast) {
UInt uiCountMag2;
UInt uiLastPos = 0;
for( ui = uiStart; ui < uiStop; ui++ )
{
if ( ! piCoeffBase[pucScan[ui]] )
uiLastPos++;
if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
{
uiLastPos = 1;
}
}
RNOK( xRQencodeSigMagGreater1( piCoeff, piCoeffBase, uiLastPos, uiStart, uiStop, uiCycle, pucScan, uiCountMag2 ) );
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 + 1;
while (uiLastScanPosition < uiStop && piCoeffBase[pucScan[uiLastScanPosition]])
uiLastScanPosition ++;
if (uiLastScanPosition < uiStop)
{
uiSig = piCoeff[pucScan[uiScanIndex] ] ? 1 : 0;
} else {
uiSig = 1;
}
if( uiSig )
{
break;
}
uiScanIndex++;
while (uiScanIndex < uiStop && piCoeffBase[pucScan[uiScanIndex]])
uiScanIndex++;
}
while ( true );
UInt uiSymbol = ruiNumCoefWritten - ((bSkipEob || ruiNumCoefWritten <= pauiEobShift[uiCycle]) ? 1 : 0);
RNOK( xWriteSigRunCode( uiSymbol, m_auiBestCodeTabMap[uiCycle] ) );
RNOK( xWriteFlag( piCoeff[pucScan[uiScanIndex]] < 0 ? 1 : 0 ) );
// Check whether any more nonzero values
Bool bFinished = true;
for( ui=uiScanIndex+1; ui<uiStop; ui++ )
{
bFinished &= ( piCoeffBase[pucScan[ui]] != 0 );
if( !bFinished )
break;
}
if( bFinished )
{
UInt uiCountMag2;
RNOK( xRQencodeSigMagGreater1( piCoeff, piCoeffBase, 0, uiStart, uiStop, uiCycle, pucScan, uiCountMag2 ) );
if( uiCountMag2 == 0 )
{
RNOK( xWriteSigRunCode( 0, m_auiBestCodeTabMap[uiCycle] ) );
}
}
return Err::m_nOK;
}
ErrVal
UvlcWriter::xRQencodeSigMagGreater1( TCoeff* piCoeff,
TCoeff* piCoeffBase,
UInt uiBaseCode,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?