📄 fgssubbanddecoder.cpp
字号:
continue;
}
UInt uiMbAddress = 0;
for(uiMbAddress=uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice ;)
{
const UInt uiMbYIdx = uiMbAddress / m_uiWidthInMB;
const UInt uiMbXIdx = uiMbAddress % m_uiWidthInMB;
MbDataAccess* pcMbDataAccessEL = NULL, *pcMbDataAccessBL = NULL;
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbYIdx, uiMbXIdx ) );
RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccessBL, uiMbYIdx, uiMbXIdx ) );
const Bool bFrame = (FRAME == pcMbDataAccessBL->getMbPicType());
MbFGSCoefMap &rcMbFGSCoefMap = m_pcCoefMap[uiMbAddress];
if( iLumaScanIdx == 0 && rcMbFGSCoefMap.getNumCoded() == 0 ) {
xDecodeMbHeader( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, iLastQP );
}
if( xDecodeNewCoefficientLumaMb( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, uiMbYIdx, uiMbXIdx, iLastQP, iLumaScanIdx, uiMaxPosLuma, bFrame ) != Err::m_nOK )
throw BitReadBuffer::ReadStop();
//===== CHROMA DC =====
if( bAllowChromaDC && ( m_bFgsComponentSep == 0 || iLumaScanIdx == 16 ) )
{
for( CPlaneIdx cCPlaneIdx; cCPlaneIdx.isLegal(); ++cCPlaneIdx )
{
for( ui=iChromaDCScanIdx; ui<=uiMaxPosChromaDC && ui<4; ui++ )
{
if( ui == 0 || ui == rcMbFGSCoefMap.getChromaDCScanPos( cCPlaneIdx ) )
{
if( xDecodeNewCoefficientChromaDC( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, cCPlaneIdx, iLastQP, ui ) != Err::m_nOK )
throw BitReadBuffer::ReadStop();
}
CoefMap cCoefMap = m_pcCoefMap[uiMbAddress].getCoefMap( CIdx( cCPlaneIdx ) + ui )[0];
if( (cCoefMap & SIGNIFICANT) && !(cCoefMap & CODED) )
if( xDecodeCoefficientChromaDCRef( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, cCPlaneIdx, ui ) != Err::m_nOK )
throw BitReadBuffer::ReadStop();
}
} // for
} // if
//===== CHROMA AC =====
if( bAllowChromaAC && ( m_bFgsComponentSep == 0 || iLumaScanIdx == 16 ) )
{
for( CPlaneIdx cCPlaneIdx; cCPlaneIdx.isLegal(); ++cCPlaneIdx )
{
for( UInt uiB8YIdx = 2 * uiMbYIdx; uiB8YIdx < 2 * uiMbYIdx + 2; uiB8YIdx++ )
{
for( UInt uiB8XIdx = 2 * uiMbXIdx; uiB8XIdx < 2 * uiMbXIdx + 2; uiB8XIdx++ )
{
CIdx cCIdx = CIdx( cCPlaneIdx ) + ((2*(uiB8YIdx%2) + (uiB8XIdx%2)));
CoefMap *pcCoefMap = rcMbFGSCoefMap.getCoefMap( cCIdx );
for( ui=iChromaACScanIdx; ui<=uiMaxPosChromaAC && ui<16; ui++ )
{
if( ui == 1 || ui == rcMbFGSCoefMap.getChromaACScanPos( cCIdx ) )
{
if( xDecodeNewCoefficientChromaAC( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, cCIdx, iLastQP, ui, bFrame ) != Err::m_nOK )
throw BitReadBuffer::ReadStop();
}
if( (pcCoefMap[ui] & SIGNIFICANT) && !(pcCoefMap[ui] & CODED) )
{
if( xDecodeCoefficientChromaACRef( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, cCIdx, ui ) != Err::m_nOK )
throw BitReadBuffer::ReadStop();
}
}
} // for
}
}
} // if
RNOK( m_pcSymbolReader->RQupdateVlcTable() );
//--ICU/ETRI FMO Implementation
uiMbAddress = m_pcSliceHeader->getFMO()->getNextMBNr( uiMbAddress );
} // macroblock iteration
RNOK( m_pcSymbolReader->RQvlcFlush() );
iLumaScanIdx = min(uiMaxPosLuma+1, 16);
if( m_bFgsComponentSep && iLumaScanIdx == 16 )
{
RNOK( m_pcSymbolReader->RQcompSepAlign() );
}
if (bAllowChromaDC)
iChromaDCScanIdx = min(uiMaxPosChromaDC+1, 4);
if (bAllowChromaAC)
iChromaACScanIdx = min(uiMaxPosChromaAC+1, 16);
iCycle++;
} // while
}
// ==
UInt uiTermBit = 0;
RNOK( m_pcSymbolReader->RQdecodeTermBit( uiTermBit ) );
// heiko.schwarz@hhi.fhg.de: decoder could assert when nearly complete FGS slices are decoded
//ROF ( uiTermBit );
if( !uiTermBit )
{
throw BitReadBuffer::ReadStop();
}
}
catch( BitReadBuffer::ReadStop )
{
// FGS ROI DECODE ICU/ETRI
isTruncated =true;
}
if(m_pcSymbolReader == m_pcUvlcReader)
{
// FGS ROI DECODE ICU/ETRI
m_pcSymbolReader->RQsetTruncatedFlag( true );
}
RNOK( m_pcSymbolReader->finishSlice( ) );
// initialize the parallel bitstream buffers
m_pcSymbolReader->RQreleaseFragments(); //TMM_INTERLACE
if( ! m_bPicFinished )
{
m_pcSliceHeader->setQualityLevel( pcSliceHeader->getQualityLevel());
}
//--ICU/ETRI 1206
RNOK( xUpdateCodingPath(pcSliceHeader) );
RNOK( xClearCodingPath() );
return Err::m_nOK;
}
ErrVal
RQFGSDecoder::xDecodeMotionData( UInt uiMbYIdx, UInt uiMbXIdx )
{
DTRACE_DO( UInt uiMbIndex = uiMbYIdx * m_uiWidthInMB + uiMbXIdx );
MbDataAccess* pcMbDataAccessEL = 0;
MbDataAccess* pcMbDataAccessBL = 0;
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbYIdx, uiMbXIdx ) );
RNOK( m_pcCurrMbDataCtrl ->initMb( pcMbDataAccessBL, uiMbYIdx, uiMbXIdx ) );
ROT ( pcMbDataAccessBL->getMbData().isIntra() );
DTRACE_NEWMB( uiMbIndex );
RNOK( 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];
const Bool bMbAff = m_pcSliceHeader->isMbAff (); // TMM_INTERLACE
RNOK( pcYuvBufferCtrl->initMb( uiMbYIdx, uiMbXIdx, bMbAff ) );
RNOK( xClearBaseCoeffs( *pcMbDataAccessEL, pcMbDataAccessBL ) );
}
return Err::m_nOK;
}
ErrVal
RQFGSDecoder::xInitializeMacroblockQPs()
{
for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB; uiMbX++ )
{
MbDataAccess* pcMbDataAccess = 0;
RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccess, uiMbY, uiMbX ) );
MbDataAccess* pcMbDataAccessEL = 0;
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
//===== set QP for enhancement layer =====
Int iQpEL = max( 0, pcMbDataAccess->getMbData().getQp() - RQ_QP_DELTA );
pcMbDataAccessEL->getMbData().setQp( iQpEL );
RNOK( pcMbDataAccessEL->getMbData().copyMotion( pcMbDataAccess->getMbData() ) );
if( ! m_pcSliceHeader->getAdaptivePredictionFlag() && ! pcMbDataAccess->getMbData().isIntra() )
pcMbDataAccessEL->getMbData().setBLSkipFlag( true );
}
return Err::m_nOK;
}
ErrVal
RQFGSDecoder::xDecodeNewCoefficientLumaMb( MbDataAccess *pcMbDataAccessBL,
MbDataAccess *pcMbDataAccessEL,
MbFGSCoefMap &rcMbFGSCoefMap,
UInt uiMbYIdx,
UInt uiMbXIdx,
Int& riLastQp,
Int iLumaScanIdx,
UInt uiMaxPosLuma,
Bool bFrame )
{
ROFRS( iLumaScanIdx < 16, Err::m_nOK );
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
S4x4Idx cIdx2 = S4x4Idx( c8x8Idx );
Bool b8x8 = (rcMbFGSCoefMap.getLumaScanPos( cIdx2+1 ) == 64);
if( b8x8 )
{
for( UInt ui=iLumaScanIdx; ui<=uiMaxPosLuma && ui<16; ui++ )
{
for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ )
{
UInt uiOffset = ( cIdx.y() % 2 ) * 2 + ( cIdx.x() % 2);
if( rcMbFGSCoefMap.getLumaScanPos( cIdx2 ) == ui * 4 + uiOffset )
{
RNOKS( xDecodeNewCoefficientLuma( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, cIdx, bFrame ) );
}
RNOKS( xDecodeCoefficientLumaRef( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, cIdx, ui ) );
}
} // 4x4 block iteration
}
else
{
for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ )
{
for( UInt ui=iLumaScanIdx; ui<=uiMaxPosLuma && ui<16; ui++ )
{
if( rcMbFGSCoefMap.getLumaScanPos( cIdx ) == ui )
{
RNOK( xDecodeNewCoefficientLuma( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, cIdx, bFrame ) );
}
RNOKS( xDecodeCoefficientLumaRef( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, cIdx, ui ) );
}
} // 4x4 block iteration
}
} // 8x8 block iteration
return Err::m_nOK;
}
ErrVal
RQFGSDecoder::xDecodeNewCoefficientLuma( MbDataAccess* pcMbDataAccessBL,
MbDataAccess* pcMbDataAccessEL,
MbFGSCoefMap &rcMbFGSCoefMap,
const S4x4Idx &rcIdx,
Bool bFrame )
{
B8x8Idx c8x8Idx( rcIdx.getContainingPar8x8() );
Bool b8x8 = pcMbDataAccessBL->getMbData().isTransformSize8x8();
if( b8x8 && m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() )
{
UInt uiStop = 64;
UInt ui8x8ScanIndex = uiStop;
UInt ui8x8StartIndex = uiStop;
UInt ui8x8Index;
CoefMap* pcCoefMap = rcMbFGSCoefMap.getCoefMap( c8x8Idx );
for( ui8x8Index = 0; ui8x8Index < uiStop; ui8x8Index++ )
{
if( ! (pcCoefMap[ ui8x8Index ] & SIGNIFICANT ) || (pcCoefMap [ ui8x8Index ] & NEWSIG ) )
{
ui8x8StartIndex = ui8x8Index;
break;
}
}
S4x4Idx cIdx2 = S4x4Idx ( c8x8Idx );
ui8x8ScanIndex = rcMbFGSCoefMap.getLumaScanPos( cIdx2 ) ;
ROTRS ( ui8x8ScanIndex == uiStop, Err::m_nOK );
Bool bNeedEob = (ui8x8ScanIndex > ui8x8StartIndex );
while ( ui8x8ScanIndex < 64 )
{
UInt uiNumCoefRead;
RNOKS( m_pcSymbolReader->RQdecodeNewTCoeff_8x8( *pcMbDataAccessEL, *pcMbDataAccessBL,
c8x8Idx, ui8x8ScanIndex, bNeedEob, uiNumCoefRead ) );
if( bNeedEob )
{
//===== end of block =====
rcMbFGSCoefMap.getLumaScanPos( cIdx2 ) = 64;
for( UInt ui8x8 = ui8x8ScanIndex; ui8x8 < 64; ui8x8++ )
{
if( ! (pcCoefMap [ ui8x8 ] & SIGNIFICANT) )
{
pcCoefMap[ ui8x8 ] |= CODED;
RNOK( rcMbFGSCoefMap.increaseAndCheckNumCoded( 1 ) );
}
}
break;
}
else
{
//===== coefficient =====
bNeedEob = false;
pcCoefMap[ ui8x8ScanIndex ] |= CODED;
RNOK( rcMbFGSCoefMap.increaseAndCheckNumCoded( 1 ) );
if( pcMbDataAccessEL->getMbTCoeffs().get8x8( c8x8Idx )[g_aucFrameScan64[ui8x8ScanIndex]] )
{
rcMbFGSCoefMap.getRefCtx( c8x8Idx )[ui8x8ScanIndex] = 1;
pcCoefMap[ ui8x8ScanIndex ] |= SIGNIFICANT | NEWSIG;
break;
}
ui8x8ScanIndex++;
while( ( ui8x8ScanIndex < 64 ) && (pcCoefMap[ ui8x8ScanIndex ] & SIGNIFICANT) )
{
ui8x8ScanIndex++;
}
}
}
if( rcMbFGSCoefMap.getLumaScanPos( cIdx2 ) < ui8x8ScanIndex )
rcMbFGSCoefMap.getLumaScanPos( cIdx2 ) = ui8x8ScanIndex;
while( ui8x8ScanIndex < 64 && ( pcCoefMap[ ui8x8ScanIndex ] & SIGNIFICANT ) )
rcMbFGSCoefMap.getLumaScanPos( cIdx2 ) = ++ui8x8ScanIndex;
}
else
{
if (! m_pcSymbolReader->RQpeekCbp4x4( *pcMbDataAccessBL, rcIdx ) )
{
return Err::m_nOK;
}
UInt uiStop = b8x8 ? 64:16;
UInt uiScanIndex = uiStop;
UInt uiStartIndex = uiStop;
UInt uiIndex;
CoefMap* pcCoefMap = b8x8 ? rcMbFGSCoefMap.getCoefMap(c8x8Idx) : rcMbFGSCoefMap.getCoefMap( rcIdx );
if( b8x8 )
{
UInt ui8x8Index;
UInt uiOffset = (rcIdx.x() % 2) + (rcIdx.y() % 2) *2;
for( ui8x8Index = uiOffset; ui8x8Index < uiStop; ui8x8Index+=4 )
{
if( ! ( pcCoefMap[ui8x8Index] & SIGNIFICANT ) || ( pcCoefMap[ui8x8Index] & NEWSIG ) )
{
uiStartIndex = ui8x8Index;
break;
}
}
uiStartIndex >>= 2;
}
else
{
for( uiIndex = 0; uiIndex < uiStop; uiIndex++ )
{
if( ! ( pcCoefMap[uiIndex] & SIGNIFICANT ) || ( pcCoefMap[uiIndex] & NEWSIG ) )
{
uiStartIndex = uiIndex;
break;
}
}
}
uiScanIndex = rcMbFGSCoefMap.getLumaScanPos( rcIdx );
ROTRS(uiScanIndex == uiStop, Err::m_nOK);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -