📄 uvlcreader.cpp
字号:
{
UInt uiTemp;
UInt uiLength;
UInt uiCode;
UInt uiLevAbs;
UInt uiSb;
UInt uiSign;
UInt uiAddBit;
UInt uiOffset;
UInt uiNumPrefix = 0;
UInt uiShift = uiVlcLength - 1;
UInt uiEscape = (15<<uiShift)+1;
// read pre zeros
do
{
RNOK( m_pcBitReadBuffer->get( uiTemp, 1 ) );
uiNumPrefix++;
} while ( uiTemp == 0 );
uiLength = uiNumPrefix;
uiCode = 1;
uiNumPrefix--;
if (uiNumPrefix < 15)
{
uiLevAbs = (uiNumPrefix<<uiShift) + 1;
if ( uiVlcLength-1 )
{
RNOK( m_pcBitReadBuffer->get( uiSb, uiVlcLength-1 ) );
uiCode = (uiCode << (uiVlcLength-1) )| uiSb;
uiLevAbs += uiSb;
uiLength += (uiVlcLength-1);
}
// read 1 bit -> sign
RNOK( m_pcBitReadBuffer->get( uiSign, 1 ) );
uiCode = (uiCode << 1)| uiSign;
uiLength++;
}
else // escape
{
uiAddBit = uiNumPrefix - 15;
RNOK( m_pcBitReadBuffer->get( uiSb, (11+uiAddBit) ) );
uiCode = (uiCode << (11+uiAddBit) )| uiSb;
uiLength += (11+uiAddBit);
uiOffset = (2048<<uiAddBit)+uiEscape-2048;
uiLevAbs = uiSb + uiOffset;
// read 1 bit -> sign
RNOK( m_pcBitReadBuffer->get( uiSign, 1 ) );
uiCode = (uiCode << 1)| uiSign;
uiLength++;
}
iLevel = (uiSign) ? -(Int)uiLevAbs : (Int)uiLevAbs;
DTRACE_POS;
DTRACE_T( " VLCN lev: " );
DTRACE_CODE( iLevel );
DTRACE_N;
DTRACE_COUNT( uiLength );
return Err::m_nOK;
}
Bool UvlcReader::isEndOfSlice()
{
UInt uiEOS = ( m_uiRun > 1 ) ? 0 : !( moreRBSPData() );
return (uiEOS == 1);
}
ErrVal UvlcReader::finishSlice( )
{
if( m_bRunLengthCoding && m_uiRun )
{
DTRACE_T( "Run" );
RNOK( xGetUvlcCode( m_uiRun ) );
DTRACE_N;
}
return Err::m_nOK;
}
ErrVal UvlcReader::residualBlock8x8( MbDataAccess& rcMbDataAccess,
B8x8Idx c8x8Idx )
{
const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
const UChar* pucScan = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;
TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get8x8( c8x8Idx );
UInt uiBlk;
UInt uiPos;
Int aaiLevelRun [4][32];
UInt auiTrailingOnes [4] = { 0, 0, 0, 0 };
UInt auiTotalRun [4] = { 0, 0, 0, 0 };
UInt auiCoeffCnt [4] = { 0, 0, 0, 0 };
//Heiner Kirchhoffer fix
for ( uiBlk = 0; uiBlk < 4; uiBlk++ )
for ( uiPos = 0; uiPos < 32; uiPos++ )
aaiLevelRun[uiBlk][uiPos] = 0;
//
{
UInt uiBitPos = c8x8Idx;
rcMbDataAccess.getMbData().setBCBP( uiBitPos, 1);
rcMbDataAccess.getMbData().setBCBP( uiBitPos+1, 1);
rcMbDataAccess.getMbData().setBCBP( uiBitPos+4, 1);
rcMbDataAccess.getMbData().setBCBP( uiBitPos+5, 1);
}
//===== loop over 4x4 blocks =====
for( uiBlk = 0; uiBlk < 4; uiBlk++ )
{
B4x4Idx cIdx( c8x8Idx.b4x4() + 4*(uiBlk/2) + (uiBlk%2) );
xPredictNonZeroCnt( rcMbDataAccess, cIdx, auiCoeffCnt[uiBlk], auiTrailingOnes[uiBlk] );
xGetRunLevel ( aaiLevelRun[uiBlk], auiCoeffCnt[uiBlk], auiTrailingOnes[uiBlk], 16, auiTotalRun[uiBlk] );
uiPos = ((auiTotalRun[uiBlk] + auiCoeffCnt[uiBlk] - 1) << 2) + uiBlk;
for ( Int i = (Int)auiCoeffCnt[uiBlk]; i > 0; i-- )
{
piCoeff[ pucScan [uiPos] ] = aaiLevelRun[uiBlk][i-1];
uiPos -= 4;
for ( Int j = 0; j < aaiLevelRun[uiBlk][i-1+0x10]; j++ )
{
piCoeff[ pucScan [uiPos] ] = 0;
uiPos -= 4;
}
}
}
return Err::m_nOK;
}
Bool
UvlcReader::RQpeekCbp4x4( MbDataAccess& rcMbDataAccessBase,
LumaIdx cIdx )
{
UInt uiSymbol = 0;
uiSymbol = rcMbDataAccessBase.getMbData().getBCBP( cIdx );
return ( uiSymbol == 1 );
}
ErrVal
UvlcReader::RQdecodeNewTCoeff_8x8( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
B8x8Idx c8x8Idx,
UInt uiScanIndex,
Bool& rbLast,
UInt& ruiNumCoefRead )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get8x8( c8x8Idx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx );
const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
const UChar* pucScan = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;
ROT( piCoeffBase[pucScan[uiScanIndex]] );
DTRACE_T( "LUMA_8x8_NEW" );
DTRACE_V( c8x8Idx.b8x8Index() );
DTRACE_V( uiScanIndex );
DTRACE_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( xRQdecodeNewTCoeffs( piCoeff, piCoeffBase, uiScanIndex%4, 64, 4, pucScan, uiScanIndex, auiEobShift, rbLast, ruiNumCoefRead ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::RQdecodeTCoeffRef_8x8( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
B8x8Idx c8x8Idx,
UInt uiScanIndex,
UInt uiCtx )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get8x8( c8x8Idx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx );
const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
const UChar* pucScan = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;
DTRACE_T( "LUMA_8x8_REF" );
DTRACE_V( c8x8Idx.b8x8Index() );
DTRACE_V( uiScanIndex );
DTRACE_N;
RNOKS( xRQdecodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::RQdecodeNewTCoeff_Luma ( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ResidualMode eResidualMode,
Bool b8x8,
LumaIdx cIdx,
UInt uiScanIndex,
Bool& rbLast,
UInt& ruiNumCoefRead )
{
TCoeff* piCoeff;
TCoeff* piCoeffBase;
const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
const UChar* pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
UInt uiStart;
UInt uiStop;
UInt uiStride;
if( b8x8 )
{
UInt uiOffset8x8 = (cIdx.y() % 2) * 2 + (cIdx.x() % 2);
B8x8Idx c8x8Idx(cIdx);
piCoeff = rcMbDataAccess .getMbTCoeffs().get8x8( c8x8Idx );
piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx );
pucScan = g_aucFrameScan64;
uiStart = uiOffset8x8;
uiStop = 64;
uiStride = 4;
uiScanIndex = uiScanIndex * 4 + uiOffset8x8;
}
else
{
piCoeff = rcMbDataAccess .getMbTCoeffs().get( cIdx );
piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
pucScan = g_aucFrameScan;
uiStart = 0;
uiStop = 16;
uiStride = 1;
}
DTRACE_T( "LUMA_4x4_NEW" );
DTRACE_V( cIdx.b4x4() );
DTRACE_V( uiScanIndex );
DTRACE_N;
RNOKS( xRQdecodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, uiStride, pucScan, uiScanIndex, m_auiShiftLuma, rbLast, ruiNumCoefRead ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::RQdecodeTCoeffRef_Luma ( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
LumaIdx cIdx,
UInt uiScanIndex,
UInt uiCtx )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get( cIdx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
const UChar* pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
DTRACE_T( "LUMA_4x4_REF" );
DTRACE_V( cIdx.b4x4() );
DTRACE_V( uiScanIndex );
DTRACE_N;
RNOKS( xRQdecodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::RQdecodeNewTCoeff_Chroma( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ResidualMode eResidualMode,
ChromaIdx cIdx,
UInt uiScanIndex,
Bool& rbLast,
UInt& ruiNumCoefRead )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get( cIdx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
const UChar* pucScan = ( eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : (bFrame) ? g_aucFrameScan : g_aucFieldScan );
UInt uiStart = ( eResidualMode == CHROMA_AC ? 1 : 0 );
UInt uiStop = ( eResidualMode == CHROMA_DC ? 4 : 16 );
ROT( piCoeffBase[pucScan[uiScanIndex]] );
DTRACE_T( "CHROMA_4x4_NEW" );
DTRACE_V( cIdx );
DTRACE_V( uiScanIndex );
DTRACE_N;
RNOKS( xRQdecodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, 1, pucScan, uiScanIndex, m_auiShiftChroma, rbLast, ruiNumCoefRead ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::RQdecodeTCoeffRef_Chroma ( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ResidualMode eResidualMode,
ChromaIdx cIdx,
UInt uiScanIndex,
UInt uiCtx )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get( cIdx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
const UChar* pucScan = ( eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : (bFrame) ? g_aucFrameScan : g_aucFieldScan );
DTRACE_T( "CHROMA_4x4_REF" );
DTRACE_V( cIdx );
DTRACE_V( uiScanIndex );
DTRACE_N;
RNOKS( xRQdecodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::xRQdecodeNewTCoeffs( TCoeff* piCoeff,
TCoeff* piCoeffBase,
UInt uiStart,
UInt uiStop,
UInt uiStride,
const UChar* pucScan,
UInt uiScanIndex,
UInt* pauiEobShift,
Bool& rbLast,
UInt& ruiNumCoefRead )
{
UInt ui=0;
UInt uiCycle = uiStart/uiStride;
for (ui=uiStart; ui<uiScanIndex; ui+=uiStride )
{
if ( piCoeffBase[pucScan[ui]] || piCoeff[pucScan[ui]] )
uiCycle = ui/uiStride + 1;
}
AOF( uiCycle < uiStop );
DTRACE_T("NewTCoeffs-uiCycle: ");
DTRACE_V(uiCycle);
DTRACE_N;
ruiNumCoefRead = 0;
Bool bSkipEob = !rbLast;
UInt uiSymbol;
RNOKS( xGetSigRunCode( uiSymbol, m_auiBestCodeTab[uiCycle] ) );
if( rbLast )
{
// Determine "overshoot" symbol
UInt uiOvershoot = 1;
for( ui = uiStart; ui < uiStop; ui+=uiStride )
{
if ( ! piCoeffBase[pucScan[ui]] )
uiOvershoot++;
if( ui < uiScanIndex && piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
{
uiOvershoot = 0;
}
}
if ( uiSymbol > uiOvershoot )
{
RNOKS( xRQdecodeSigMagGreater1( piCoeff, piCoeffBase, pucScan, uiSymbol-uiOvershoot-1, uiStart, uiStop, uiStride ) );
rbLast = true;
} else {
rbLast = uiSymbol == min( pauiEobShift[uiCycle], uiOvershoot );
}
ROTRS(rbLast, Err::m_nOK);
} else
rbLast = false;
//===== SIGNIFICANCE BIT ======
UInt uiNumCoef = uiSymbol + ((bSkipEob || uiSymbol <= pauiEobShift[uiCycle]) ? 1 : 0);
AOT( uiNumCoef > uiStop );
do
{
ruiNumCoefRead++;
if ( --uiNumCoef == 0 )
{
break;
}
uiScanIndex += uiStride;
while (uiScanIndex < uiStop && piCoeffBase[pucScan[uiScanIndex]])
uiScanIndex += uiStride;
}
while ( true );
RNOKS( xGetFlag( uiSymbol ) );
piCoeff[pucScan[uiScanIndex]] = uiSymbol ? -1 : 1;
// Check whether any more nonzero values
Bool bFinished = true;
for( ui=uiScanIndex+uiStride; ui<uiStop; ui+=uiStride )
{
bFinished &= ( piCoeffBase[pucScan[ui]] != 0 );
if( !bFinished )
break;
}
if( bFinished )
{
uiSymbol = 0;
RNOKS( xGetSigRunCode( uiSymbol, m_auiBestCodeTab[uiCycle] ) );
if( uiSymbol > 0 )
{
RNOKS( xRQdecodeSigMagGreater1( piCoeff, piCoeffBase, pucScan, uiSymbol-1, uiStart, uiStop, uiStride ) );
}
}
return Err::m_nOK;
}
ErrVal
UvlcReader::xRQdecodeSigMagGreater1( TCoeff* piCoeff,
TCoeff* piCoeffBase,
const UChar* pucScan,
UInt uiTermSym,
UInt uiStart,
UInt uiStop,
UInt uiStride )
{
// Find optimal terminating code
UInt ui;
UInt uiCountMag1 = 0;
for (ui=uiStart; ui<uiStop; ui+=uiStride )
{
if ( !piCoeffBase[pucScan[ui]] && piCoeff[pucScan[ui]] )
{
uiCountMag1++;
}
}
UInt uiMaxMag;
UInt uiCountMag2;
if ( uiTermSym < uiCountMag1*2 )
{
uiMaxMag = (uiTermSym % 2) + 2;
uiCountMag2 = (uiTermSym / 2) + 1;
} else {
uiMaxMag = (uiTermSym / uiCountMag1) + 2;
uiCountMag2 = (uiTermSym % uiCountMag1) + 1;
}
UInt auiRemMag[16];
::memset(auiRemMag, 0x0, 16*sizeof(UInt));
UInt uiFlip = 0;
UInt uiRemaining = uiCountMag2;
UInt uiEnd = uiCountMag1;
UInt uiCount = 0;
for (ui=uiStart; ui<uiStop; ui+=uiStride )
{
if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
{
if( uiRemaining+uiCount == uiEnd )
{
auiRemMag[ui/uiStride] = 1-uiFlip;
uiRemaining--;
} else {
RNOKS( xGetFlag( auiRemMag[ui/uiStride] ) );
uiRemaining -= auiRemMag[ui/uiStride] ? 1-uiFlip : uiFlip;
}
if( uiRemaining == 0 )
break;
uiCount++;
}
}
UInt uiOutstanding = uiCountMag2;
Bool bSeenMaxMag = false;
for(ui = uiStart; ui < uiStop; ui+=uiStride )
{
if( !bSeenMaxMag && uiOutstanding == 1 )
break;
if( auiRemMag[ui/uiStride] )
{
UInt uiBit;
UInt uiSymbol = 0;
for ( UInt uiCutoff=1; uiCutoff<uiMaxMag; uiCutoff++ )
{
auiRemMag[ui/uiStride] = 0;
RNOKS( xGetFlag( uiBit ) );
if( uiBit )
uiSymbol++;
else
break;
}
uiSymbol += 2;
piCoeff[pucScan[ui]] = (piCoeff[pucScan[ui]] > 0) ? (Int)uiSymbol : -(Int)uiSymbol;
bSeenMaxMag |= ( uiSymbol == uiMaxMag );
uiOutstanding--;
if( uiOutstanding == 0 )
break;
}
}
for (ui=uiStart; ui<uiStop; ui+=uiStride )
{
if ( auiRemMag[ui/uiStride] )
{
piCoeff[pucScan[ui]] = ( piCoeff[pucScan[ui]] > 0 ) ? (Int)uiMaxMag : -(Int)uiMaxMag;
}
}
return Err::m_nOK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -