📄 uvlcreader.cpp
字号:
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 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]] );
DTRACE_T( "CHROMA_4x4_NEW" );
DTRACE_V( cIdx );
DTRACE_V( uiScanIndex );
DTRACE_N;
RNOK( 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 )
{
TCoeff* piCoeff = rcMbDataAccess .getMbTCoeffs().get( cIdx );
TCoeff* piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
const UChar* pucScan = ( eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : g_aucFrameScan );
DTRACE_T( "CHROMA_4x4_REF" );
DTRACE_V( cIdx );
DTRACE_V( uiScanIndex );
DTRACE_N;
RNOK( 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 = 0;
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;
RNOK( 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 = 1;
}
}
if ( uiSymbol > uiOvershoot )
{
RNOK( xRQdecodeSigMagGreater1( piCoeff, piCoeffBase, pucScan, uiSymbol-uiOvershoot-1, uiStart, uiStop, uiStride ) );
rbLast = true;
} else {
rbLast = ( uiSymbol == pauiEobShift[uiCycle]) || ( uiSymbol == 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 );
RNOK( 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;
RNOK( xGetSigRunCode( uiSymbol, m_auiBestCodeTab[uiCycle] ) );
if( uiSymbol > 0 )
{
RNOK( 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 {
RNOK( 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;
RNOK( 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;
}
ErrVal
UvlcReader::xRQdecodeTCoeffsRef( TCoeff* piCoeff,
TCoeff* piCoeffBase,
const UChar* pucScan,
UInt uiScanIndex )
{
if(m_uiRefSymCounter == CAVLC_SYMGRP_SIZE)
{
UInt uiDenom = 9;
RNOK( m_pSymGrp->xFetchSymbol( CAVLC_SYMGRP_SIZE ) );
UInt uiCode = m_pSymGrp->GetCode();
for(UInt ui = 0; ui < CAVLC_SYMGRP_SIZE; ui++)
{
UChar ucSym;
ucSym = uiCode/uiDenom;
m_auiSymbolBuf[ui] = ucSym;
uiCode = (uiCode % uiDenom);
uiDenom /= 3;
}
m_uiRefSymCounter = 0;
}
if (m_auiSymbolBuf[m_uiRefSymCounter] > 0) {
UInt uiSymbol = m_auiSymbolBuf[m_uiRefSymCounter] - 1;
UInt uiSignBL = ( piCoeffBase[pucScan[uiScanIndex]] < 0 ? 1 : 0 );
UInt uiSignEL = ( uiSignBL ^ uiSymbol );
piCoeff[pucScan[uiScanIndex]] = ( uiSignEL ? -1 : 1 );
}
m_uiRefSymCounter++;
return Err::m_nOK;
}
ErrVal
UvlcReader::xGetGolomb(UInt& uiSymbol, UInt uiK)
{
UInt uiCode;
UInt uiR;
UInt uiQ = 0;
UInt uiC = 0;
UInt uiT = uiK >> 1;
while ( uiT > 0 )
{
uiC++;
uiT >>= 1;
}
// Unary part
do {
RNOK( xGetFlag( uiCode ) );
uiQ++;
} while ( uiCode != 0 );
uiQ--;
uiSymbol = uiQ * uiK;
if ( uiC == 0 )
{
return Err::m_nOK;
}
// Binary part
RNOK( xGetFlag( uiCode ) );
if ( uiCode == 0 )
{
if ( uiC > 1 )
{
RNOK( xGetCode( uiR, uiC-1 ) );
} else {
uiR = 0;
}
} else {
RNOK( xGetCode( uiCode, uiC ) );
uiR = uiCode + uiC;
}
DTRACE_N;
uiSymbol += uiR;
return Err::m_nOK;
}
ErrVal
UvlcReader::RQdecodeEobOffsets_Luma()
{
RNOK( m_pSymGrp->Init() );
m_uiCbpStat4x4[0] = m_uiCbpStat4x4[1] = 0;
m_uiCbpStats[0][0] = m_uiCbpStats[0][1] = m_uiCbpStats[1][0] = m_uiCbpStats[1][1] = 0;
RNOK( xRQdecodeEobOffsets( m_auiShiftLuma, 16 ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::RQdecodeEobOffsets_Chroma()
{
m_auiShiftChroma[0] = 15;
RNOK( xRQdecodeEobOffsets( m_auiShiftChroma+1, 15 ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::xRQdecodeEobOffsets( UInt* pauiShift, UInt uiMax )
{
UInt uiNumEnd = 1;
for (UInt uiEc=0; uiEc<3; uiEc++)
{
UInt uiCode;
RNOK( xGetFlag( uiCode ) );
if (uiCode)
{
uiNumEnd++;
} else {
break;
}
}
if (uiNumEnd == 4)
{
uiNumEnd = 0;
}
for (UInt ui=0; ui<uiNumEnd; ui++)
{
pauiShift[ui] = uiMax - 1;
}
UInt uiLevel;
RNOK( xGetGolomb( uiLevel, 2 ) );
pauiShift[uiNumEnd] = uiLevel;
RNOK( xDecodeMonSeq( pauiShift+uiNumEnd+1, uiLevel, uiMax-uiNumEnd-1 ) );
return Err::m_nOK;
}
ErrVal
UvlcReader::RQdecodeBestCodeTableMap( UInt uiMaxH )
{
UInt uiW = uiMaxH-1;
memset(m_auiBestCodeTab, 0, sizeof(UInt)*uiMaxH);
RNOK( xGetCode(uiW, 4) );
for(UInt uiH = 0; uiH <= uiW; uiH++)
{
RNOK(xGetSigRunTabCode(m_auiBestCodeTab[uiH]));
}
return Err::m_nOK;
}
ErrVal
UvlcReader::RQvlcFlush()
{
return Err::m_nOK;
}
ErrVal
UvlcReader::RQupdateVlcTable()
{
m_pSymGrp->UpdateVlc();
m_uiRefSymCounter = CAVLC_SYMGRP_SIZE;
return Err::m_nOK;
}
ErrVal
UvlcReader::xDecodeMonSeq ( UInt* auiSeq, UInt uiStart, UInt uiLen )
{
UInt uiPos = 0;
UInt uiLevel = uiStart;
while ( uiLevel > 0 && uiPos < uiLen )
{
UInt uiRun;
RNOK( xGetGolomb( uiRun, 1 ) );
for (UInt ui=0; ui<uiRun; ui++,uiPos++)
auiSeq[uiPos] = uiLevel;
uiLevel--;
}
for (; uiPos < uiLen; uiPos++)
{
auiSeq[uiPos] = 0;
}
DTRACE_N;
return Err::m_nOK;
}
ErrVal
UvlcReader::xGetSigRunCode( UInt& uiVal, UInt uiCodeTab )
{
if( uiCodeTab == 0)
{
RNOK(xGetUnaryCode( uiVal ));
}
else if( uiCodeTab == 1)
{
RNOK(xGetCodeCB1( uiVal ));
}
else if( uiCodeTab == 2)
{
RNOK(xGetCodeCB2( uiVal ));
}
else if( uiCodeTab == 3)
{
UInt uiCode;
RNOK( xGetFlag( uiCode ) );
if(uiCode == 1)
{
uiVal = 0;
}
else
{
RNOK( xGetCodeCB2( uiCode ) );
uiVal = uiCode+1;
}
}
else
{
UInt uiCode;
RNOK( xGetFlag( uiCode ) );
if(uiCode == 1)
{
uiVal = 0;
}
else
{
RNOK( xGetCodeCB1( uiCode ) );
uiVal = uiCode+1;
}
}
return Err::m_nOK;
}
ErrVal
UvlcReader::xGetCodeCB1 ( UInt& uiVal )
{
UInt uiPrefixLen = 0;
UInt uiFlag;
do
{
RNOK(xGetFlag(uiFlag));
uiPrefixLen++;
}
while (uiFlag == 0);
RNOK( xGetFlag( uiFlag) );
uiVal = (2*(uiPrefixLen-1))+(1-uiFlag);
return Err::m_nOK;
}
ErrVal
UvlcReader::xGetCodeCB2( UInt& uiVal )
{
UInt uiPrefixLen = 0;
UInt uiCode;
do
{
RNOK( xGetCode( uiCode, 2) );
uiPrefixLen++;
}
while (uiCode == 0);
uiVal = (3*(uiPrefixLen-1))+(3-uiCode);
return Err::m_nOK;
}
ErrVal
UvlcReader::xGetUnaryCode( UInt& uiVal )
{
UInt uiCode;
UInt uiSymbol = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -