📄 fgssubbanddecoder.cpp
字号:
pcMbDataAccessEL->getMbData().setMbCbp( (uiMbCbp & 0x0F) | (m_uiLastChromaCbp << 4) );
m_uiChromaCbpRun --;
return Err::m_nOK;
}
ErrVal
RQFGSDecoder::xDecodeMbHeader( MbDataAccess* pcMbDataAccessBL,
MbDataAccess* pcMbDataAccessEL,
MbFGSCoefMap &rcMbFGSCoefMap,
Int& riLastQp )
{
UInt uiMbX = pcMbDataAccessBL->getMbX();
UInt uiMbY = pcMbDataAccessBL->getMbY();
UInt uiCbpBit;
MbSymbolReadIf* pcMbHeaderReader;
pcMbHeaderReader = m_pcSymbolReader->RQactivateFragment( 0 );
const Bool bMbAff = m_pcSliceHeader->isMbAff ();// TMM_INTERLACE
if( m_pcSliceHeader->getAdaptivePredictionFlag() &&
! pcMbDataAccessBL->getMbData().isIntra() )
{
// the error is not handled if it is termnated early
RNOKS( m_pcMbParser ->readMotion( *pcMbDataAccessEL, pcMbDataAccessBL ) );
RNOK ( m_pcMbDecoder->calcMv ( *pcMbDataAccessEL, pcMbDataAccessBL ) );
if( ! pcMbDataAccessEL->getMbData().getBLSkipFlag() && ! pcMbDataAccessEL->getMbData().getResidualPredFlag( PART_16x16 ) )
{
//----- motion refinement without residual prediction ===> clear base layer coeffs -----
UInt uiLayer = m_pcSliceHeader->getLayerId();
YuvBufferCtrl* pcYuvBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
RNOK( pcYuvBufferCtrl->initMb( uiMbY, uiMbX, bMbAff ) );
RNOK( xClearBaseCoeffs( *pcMbDataAccessEL, pcMbDataAccessBL ) );
}
}
//===== CBP =====
if( ! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() ) {
RNOKS( xDecodeLumaCbpVlc ( uiMbX, uiMbY ) );
RNOKS( xDecodeChromaCbpVlc ( uiMbX, uiMbY ) );
// restore pcMbDataAccessBL and pcMbDataAccessEL, may not be necessary
RNOK( m_pcCurrMbDataCtrl ->initMb( pcMbDataAccessBL, uiMbY, uiMbX ) );
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
}
// Luma CBP in CABAC, need also for CAVLC to update the CBP in buffer
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx ++ )
RNOKS( pcMbHeaderReader->RQdecodeCBP_8x8( *pcMbDataAccessEL, *pcMbDataAccessBL, c8x8Idx ) );
}
// CHROMA CBP in CABAC, need also for CAVLC to update the CBP in buffer
RNOKS( pcMbHeaderReader->RQdecodeCBP_Chroma( *pcMbDataAccessEL, *pcMbDataAccessBL, uiCbpBit ) );
if( uiCbpBit )
RNOKS( pcMbHeaderReader->RQdecodeCBP_ChromaAC( *pcMbDataAccessEL, *pcMbDataAccessBL, uiCbpBit ) );
// transform size
if( ( pcMbDataAccessBL->getMbData().getMbCbp() & 15 ) &&
! ( rcMbFGSCoefMap.getMbMap() & TRANSFORM_SPECIFIED ) ) {
RNOKS( pcMbHeaderReader->RQdecode8x8Flag( *pcMbDataAccessEL, *pcMbDataAccessBL ) );
rcMbFGSCoefMap.getMbMap() |= TRANSFORM_SPECIFIED;
}
// delta QP and transform flag
if( pcMbDataAccessBL->getMbData().getMbCbp() != 0 ) {
if( ! ( rcMbFGSCoefMap.getMbMap() & SIGNIFICANT ) ) {
pcMbDataAccessEL->setLastQp( riLastQp );
RNOKS( pcMbHeaderReader->RQdecodeDeltaQp( *pcMbDataAccessEL ) );
riLastQp = pcMbDataAccessEL->getMbData().getQp();
rcMbFGSCoefMap.getMbMap() |= SIGNIFICANT;
}
}
// Luma BCBP
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx ++ ) {
Bool bSigBCBP = ( ( pcMbDataAccessEL->getMbData().getMbCbp() >> c8x8Idx.b8x8Index() ) & 1 ? 1 : 0 );
Bool b8x8 = pcMbDataAccessBL->getMbData().isTransformSize8x8();
// 8x8 in VLC mode is de-interleaved into 4 4x4 blocks
// 8x8 in CABAC mode is encoded in native 8x8 zigzag order, and no BCBP is needed
if( bSigBCBP && (! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() || ! b8x8 ) ) {
for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx ++ )
RNOKS( pcMbHeaderReader->RQdecodeBCBP_4x4( *pcMbDataAccessEL, *pcMbDataAccessBL, b8x8, cIdx, uiCbpBit ) );
}
else
{
S4x4Idx cIdx (c8x8Idx);
rcMbFGSCoefMap.getLumaScanPos( cIdx+1 ) = 64;
}
}
}
// do not track the number of coefficients in the decoder
xUpdateMbMaps( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, 0 );
return Err::m_nOK;
}
const UChar g_aucLinearScan[16] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15
};
ErrVal
RQFGSDecoder::xResidualBlock ( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ResidualMode eResidualMode,
UInt uiStride,
UInt uiBlkIdx,
UInt& uiBcbp,
Bool bDecodeBcbpInside,
Int* piMaxPos,
RefCtx* pcRefCtx,
UInt& ruiNumFrags,
UInt& ruiCoeffsDecoded )
{
UInt uiStart, uiStop, uiCycle, uiFragIdx, uiNumCoeffs;
Bool bFirstSigRunCode, bEndOfBlock;
UInt uiRun;
TCoeff iCoeff;
TCoeff* piCoeff;
TCoeff* piCoeffBase;
UInt uiLastScanIdx;
ErrVal eStatus;
MbSymbolReadIf* pcFragmentReader;
const UChar* pucScan;
TCoeff aiCoeffTemp[16];
TCoeff aiCoeffBaseTemp[16];
UInt uiBlkX, uiBlkY, uiB8x8, uiB4x4IdxInB8x8;
Par8x8 ePar8x8 = Par8x8(0);
uiB4x4IdxInB8x8 = 0;
if( eResidualMode == LUMA_SCAN && uiStride == 1 ) {
// the normal 4x4 block
piCoeff = rcMbDataAccess .getMbTCoeffs().get( B4x4Idx( uiBlkIdx ) );
piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( B4x4Idx( uiBlkIdx ) );
pucScan = g_aucFrameScan;
}
else if ( eResidualMode == LUMA_8X8 || uiStride == 4 ) {
uiBlkX = uiBlkIdx % 4;
uiBlkY = uiBlkIdx / 4;
uiB8x8 = (uiBlkY / 2) * 2 + uiBlkX / 2;
ePar8x8 = Par8x8(uiB8x8);
uiB4x4IdxInB8x8 = (uiBlkY % 2) * 2 + (uiBlkX % 2);
piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get8x8( B8x8Idx( ePar8x8 ) );
if( uiStride == 4) {
// 4x4 block within 8x8 block, deinteleave piCoeffBase to aiCoeffBaseTemp
for( uiCycle = 0; uiCycle < 16; uiCycle ++ )
aiCoeffBaseTemp[ uiCycle ] = piCoeffBase[ g_aucFrameScan64[uiCycle * 4 + uiB4x4IdxInB8x8] ];
piCoeffBase = aiCoeffBaseTemp;
memset( aiCoeffTemp, 0, 16 * sizeof(TCoeff) );
piCoeff = aiCoeffTemp;
pucScan = g_aucLinearScan;
}
else {
// cabac uses native 8x8 zigzag scan
piCoeff = rcMbDataAccess .getMbTCoeffs().get8x8( B8x8Idx( ePar8x8 ) );
pucScan = g_aucFrameScan64;
// a dirty fix
// in "-pd 0" path, it is set in RQdecodeNewTCoeff_8x8, should be in higher level
if( uiBcbp ) {
B8x8Idx c8x8Idx( ePar8x8 );
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 );
}
}
}
else {
piCoeff = rcMbDataAccess .getMbTCoeffs().get( CIdx( uiBlkIdx ) );
piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( CIdx( uiBlkIdx ) );
pucScan = eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : g_aucFrameScan;
}
uiStart = ( eResidualMode == CHROMA_AC ) ? 1 : 0;
uiStop = ( eResidualMode == CHROMA_DC ) ? 4 : ( ( eResidualMode == LUMA_8X8 ) ? 64 : 16 );
bFirstSigRunCode = true;
bEndOfBlock = ( uiBcbp == 0 ) ? 1 : 0;
pcFragmentReader = m_pcSymbolReader->RQactivateFragment( 0 );
uiNumCoeffs = 0;
uiRun = 0;
eStatus = Err::m_nOK;
// last possible coefficient in the block
for( uiLastScanIdx = uiStop - 1; uiLastScanIdx >= uiStart; uiLastScanIdx -- ) {
if( ! piCoeffBase[pucScan[uiLastScanIdx]] )
break;
}
for( uiFragIdx = 0, uiCycle = uiStart; uiCycle < uiStop; uiCycle ++ ) {
UInt uiMaxPos;
uiMaxPos = ( eResidualMode == LUMA_8X8 ) ? ( piMaxPos[uiFragIdx] * 4 +3 ) : piMaxPos[uiFragIdx];
while( uiCycle > uiMaxPos ) {
if( uiFragIdx == ruiNumFrags - 1 ) {
pcFragmentReader = 0;
break;
}
else {
uiFragIdx ++;
pcFragmentReader = m_pcSymbolReader->RQactivateFragment( uiFragIdx );
uiMaxPos = ( eResidualMode == LUMA_8X8 ) ? ( piMaxPos[uiFragIdx] * 4 +3 ) : piMaxPos[uiFragIdx];
}
}
// no more data for this block
if( pcFragmentReader == 0 && uiRun == 0 )
break;
if( piCoeffBase[pucScan[uiCycle]] ) {
if( pcFragmentReader ) {
eStatus = pcFragmentReader->RQdecodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiCycle, pcRefCtx[uiCycle] );
if( eStatus != Err::m_nOK )
break;
Int iXCoeff;
//if( eResidualMode == LUMA_SCAN && uiStride == 1 )
{
iXCoeff = piCoeff[pucScan[uiCycle]];
if( piCoeffBase[pucScan[uiCycle]] < 0 )
iXCoeff = -iXCoeff;
}
#if 0
else if(eRedisualMode == LUMA_8x8 || uiStride == 4)
{
iCoeff = pcMbDataAccessEL->getMbTCoeffs().get8x8( c8x8Idx )[g_aucFrameScan64[uiCycle]];
if( pcMbDataAccessBL->getMbTCoeffs().get8x8( c8x8Idx )[g_aucFrameScan64[uiCycle]] < 0 )
iCoeff = -iCoeff;
}
#endif
pcRefCtx[uiCycle] <<= 2;
if( iXCoeff < 0 )
pcRefCtx[uiCycle]+= 2;
else if( iXCoeff > 0 )
pcRefCtx[uiCycle]++;
uiNumCoeffs ++;
}
}
else {
if( bDecodeBcbpInside && pcFragmentReader ) {
// luma BCBP is currently decoded outside
if( eResidualMode == CHROMA_AC )
eStatus = pcFragmentReader->RQdecodeBCBP_ChromaAC( rcMbDataAccess, rcMbDataAccessBase, CIdx( uiBlkIdx ), uiBcbp );
else
eStatus = pcFragmentReader->RQdecodeBCBP_ChromaDC( rcMbDataAccess, rcMbDataAccessBase, CIdx( uiBlkIdx ), uiBcbp );
if( eStatus != Err::m_nOK )
break;
bDecodeBcbpInside = false;
bEndOfBlock = ( uiBcbp == 0 ) ? 1 : 0;
}
if( uiRun > 0 )
uiRun --;
else if( ! bEndOfBlock && pcFragmentReader ) {
iCoeff = 0;
eStatus = pcFragmentReader->RQdecodeSigCoeff
( piCoeff, piCoeffBase, eResidualMode, pucScan, bFirstSigRunCode, uiCycle, uiStart, uiLastScanIdx, bEndOfBlock, iCoeff, uiRun );
if( eStatus != Err::m_nOK )
break;
if( iCoeff != 0 )
{
uiNumCoeffs += uiRun + 1;
}
bFirstSigRunCode = false;
}
// bEndOfBlock indicates there is no significant coefficients
// but there may be refinement coefficients to be decoded
if( uiRun == 0 && ! bEndOfBlock )
{
piCoeff[pucScan[uiCycle]] = iCoeff;
if(iCoeff)
pcRefCtx[uiCycle] = 1;
}
}
}
if( uiStride == 4) {
// de-interleaved 4x4 block, put decoded coefficients in the interleaved order
piCoeff = rcMbDataAccess .getMbTCoeffs().get8x8( B8x8Idx( ePar8x8 ) );
for( uiCycle = 0; uiCycle < 16; uiCycle ++ )
piCoeff[ g_aucFrameScan64[uiCycle * 4 + uiB4x4IdxInB8x8] ] = aiCoeffTemp[ uiCycle ];
}
if( eStatus == Err::m_nEndOfStream ) {
ruiNumFrags = uiFragIdx;
}
else {
if( bEndOfBlock )
uiNumCoeffs = uiStop - uiStart;
}
ruiCoeffsDecoded += uiNumCoeffs;
return Err::m_nOK;
}
ErrVal
RQFGSDecoder::xResidualBlock ( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
LumaIdx cIdx,
ResidualMode eResidualMode,
UInt uiStride,
Int* piMaxPos,
UInt& ruiNumFrags,
MbFGSCoefMap & rcMbFGSCoefMap,
UInt& ruiCoeffsDecoded )
{
UInt uiBcbp;
RefCtx *pcRefCtx;
B8x8Idx c8x8Idx( cIdx );
if( eResidualMode == LUMA_8X8 )
{
uiBcbp = ( rcMbDataAccess .getMbData().getMbCbp() >> ( (cIdx.y()/2)*2 + cIdx.x()/2 ) ) & 1;
pcRefCtx = rcMbFGSCoefMap.getRefCtx( c8x8Idx );
}
else
{
UInt uiOffset = (cIdx.x()%2) + (cIdx.y()%2) * 2;
S4x4Idx c4x4Idx ( c8x8Idx );
c4x4Idx = c4x4Idx + uiOffset;
uiBcbp = rcMbDataAccess .getMbData().getBCBP( cIdx.b4x4() );
pcRefCtx = rcMbFGSCoefMap.getRefCtx( c4x4Idx );
}
RNOKS( xResidualBlock( rcMbDataAccess, rcMbDataAccessBase, eResidualMode, uiStride, cIdx,
uiBcbp, false, piMaxPos, pcRefCtx, ruiNumFrags, ruiCoeffsDecoded ) );
return Err::m_nOK;
}
ErrVal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -