📄 fgssubbanddecoder.cpp
字号:
RQFGSDecoder::xResidualBlock ( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase,
ChromaIdx cIdx,
ResidualMode eResidualMode,
Int* piMaxPos,
UInt& ruiNumFrags,
MbFGSCoefMap & rcMbFGSCoefMap,
UInt& ruiCoeffsDecoded )
{
UInt uiBcbp, uiBaseBcbp;
Bool bDecodeBcbpInside;
ErrVal eStatus;
RefCtx* pcRefCtx;
RefCtx cRefCtxTemp[4];
bDecodeBcbpInside = false;
uiBcbp = 0;
if( eResidualMode == CHROMA_DC ) {
if( ( rcMbDataAccess.getMbData().getMbCbp() >> 4 ) > 0 )
bDecodeBcbpInside = true;
uiBaseBcbp = rcMbDataAccessBase.getMbData().getBCBP( 24 + cIdx.plane() );
CPlaneIdx cCPlaneIdx ( cIdx.plane() );
for(UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx ++ )
{
CIdx cCIdx = CIdx( cCPlaneIdx ) + uiDCIdx;
cRefCtxTemp[uiDCIdx] = rcMbFGSCoefMap.getRefCtx( cCIdx )[0] ;
}
pcRefCtx = cRefCtxTemp;
}
else {
if( ( rcMbDataAccess.getMbData().getMbCbp() >> 4 ) > 1 )
bDecodeBcbpInside = true;
uiBaseBcbp = rcMbDataAccessBase.getMbData().getBCBP( 16 + cIdx );
pcRefCtx = rcMbFGSCoefMap.getRefCtx ( cIdx );
}
// ROTRS( uiBaseBcbp == 0 && ! bDecodeBcbpInside, Err::m_nOK );
eStatus = xResidualBlock( rcMbDataAccess, rcMbDataAccessBase, eResidualMode, 1, cIdx,
uiBcbp, bDecodeBcbpInside, piMaxPos, pcRefCtx, ruiNumFrags, ruiCoeffsDecoded );
if( eResidualMode == CHROMA_DC ) {
rcMbDataAccess .getMbData().setBCBP( 24 + cIdx.plane(), uiBcbp );
rcMbDataAccessBase.getMbData().setBCBP( 24 + cIdx.plane(), uiBcbp);
CPlaneIdx cCPlaneIdx ( cIdx.plane() );
for(UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx ++ )
{
CIdx cCIdx = CIdx( cCPlaneIdx ) + uiDCIdx;
rcMbFGSCoefMap.getRefCtx( cCIdx )[0] = cRefCtxTemp[uiDCIdx];
}
}
else {
rcMbDataAccess .getMbData().setBCBP( 16 + cIdx, uiBcbp );
rcMbDataAccessBase.getMbData().setBCBP( 16 + cIdx, uiBcbp );
}
return eStatus;
}
ErrVal
RQFGSDecoder::xDecodingFGSBlock( SliceHeader* pcSliceHeader )
{
RNOK( m_cMbDataCtrlEL .reset () );
RNOK( m_cMbDataCtrlEL .clear () );
RNOK( m_cMbDataCtrlEL .initSlice ( *m_pcSliceHeader, PARSE_PROCESS, true, NULL ) );
RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS, true, NULL ) );
RNOK( xInitializeMacroblockQPs() );
RNOK( m_cMbDataCtrlEL .initSlice ( *m_pcSliceHeader, PRE_PROCESS, true, NULL ) );
Int iLastQP = m_pcSliceHeader->getPicQp();
UInt uiFirstMbInSlice = m_pcSliceHeader->getFirstMbInSlice ();
UInt uiNumMbsInSlice = m_pcSliceHeader->getNumMbsInSlice ();
m_bFgsComponentSep = m_pcSliceHeader->getFgsComponentSep();
UInt ui;
if(m_pcSliceHeader->getFGSCodingMode() == false) {
//grouping size mode
UInt uiGroupingSize = m_pcSliceHeader->getGroupingSize();
ui = 0;
m_auiScanPosVectLuma[ui] = uiGroupingSize-1;
while( m_auiScanPosVectLuma[ui] < 15) {
ui++;
m_auiScanPosVectLuma[ui] = m_auiScanPosVectLuma[ui-1]+uiGroupingSize;
}
}
else {
//vector specified
ui = 0;
m_auiScanPosVectLuma[ui] = m_pcSliceHeader->getPosVect(ui) - 1;
while( m_auiScanPosVectLuma[ui] < 15) {
ui++;
m_auiScanPosVectLuma[ui] = m_auiScanPosVectLuma[ui-1] + m_pcSliceHeader->getPosVect(ui);
}
}
AOT( m_pcSymbolReader == 0 );
RNOK( m_pcSymbolReader ->startSlice( *m_pcSliceHeader ) );
UInt iStartCycle = 0;
Bool bChromaCbpFlag;
UInt uiMbX, uiMbY;
UInt uiFirstMbY = (UInt) ( uiFirstMbInSlice / m_uiWidthInMB );
UInt uiFirstMbX = uiFirstMbInSlice % m_uiWidthInMB;
UInt uiLastMbY = (UInt) ( ( uiFirstMbInSlice + uiNumMbsInSlice ) / m_uiWidthInMB );
UInt uiLastMbX = ( uiFirstMbInSlice + uiNumMbsInSlice ) % m_uiWidthInMB;
UInt uiNumFrags;
Int aiMaxPosLuma[16], aiMaxPosChromaAC[16], aiMaxPosChromaDC[16];
try
{
AOT( m_pcSymbolReader == 0 );
RNOK( m_pcSymbolReader->RQdecodeEobOffsets_Luma () );
RNOK( m_pcSymbolReader->RQdecodeEobOffsets_Chroma() );
RNOK( m_pcSymbolReader->RQdecodeBestCodeTableMap ( 16 ) );
m_uiLumaCbpRun = 0;
m_uiChromaCbpRun = 0;
if( ! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() )
{
((UvlcReader *) m_pcSymbolReader)->getFlag(m_bLastLumaCbpFlag, "Luma_CBP_first_flag");
((UvlcReader *) m_pcSymbolReader)->getFlag(bChromaCbpFlag, "Chroma_CBP_first");
m_uiLastChromaCbp = bChromaCbpFlag ? 1 : 0;
}
// initialize the parallel bitstream buffers
m_pcSymbolReader->RQinitFragments( *m_pcSliceHeader, uiNumFrags, true );
m_pcSymbolReader->RQsetTruncatedFlag( false );
// when m_bFgsComponentSep is needed
if( m_bFgsComponentSep == 0 )
m_pcSymbolReader->RQdecodeCycleSymbol( iStartCycle );
xDeriveComponentPosVectors( m_auiScanPosVectLuma,
aiMaxPosLuma, aiMaxPosChromaAC, aiMaxPosChromaDC, iStartCycle );
for( uiMbY = uiFirstMbY; uiMbY < uiLastMbY && uiNumFrags > 0; uiMbY ++ ) {
for( uiMbX = ( uiMbY == uiFirstMbY ? uiFirstMbX : 0 );
uiMbX < ( uiMbY == uiLastMbY ? uiLastMbX : m_uiWidthInMB ) && uiNumFrags > 0; uiMbX ++ ) {
MbDataAccess* pcMbDataAccessEL = 0;
MbDataAccess* pcMbDataAccessBL = 0;
UInt uiMbCoeffsDecoded = 0;
UInt uiMbAddress = uiMbY * m_uiWidthInMB + uiMbX ;
MbFGSCoefMap &rcMbFGSCoefMap = m_pcCoefMap[uiMbAddress];
RNOK( m_pcCurrMbDataCtrl ->initMb( pcMbDataAccessBL, uiMbY, uiMbX ) );
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
// Read the MB header
if( xDecodeMbHeader( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, iLastQP ) != Err::m_nOK )
uiNumFrags = 0;
if( uiNumFrags > 0 ) {
//===== LUMA =====
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal() && uiNumFrags > 0; c8x8Idx ++ ) {
if( pcMbDataAccessBL->getMbData().isTransformSize8x8() &&
pcMbDataAccessBL->getSH().getPPS().getEntropyCodingModeFlag() ) {
xResidualBlock( *pcMbDataAccessEL, *pcMbDataAccessBL,
c8x8Idx, LUMA_8X8, 1, aiMaxPosLuma, uiNumFrags, rcMbFGSCoefMap, uiMbCoeffsDecoded );
}
else {
// determine if this is actual 4x4, or deinterleaved 4x4
UInt uiStride = pcMbDataAccessBL->getMbData().isTransformSize8x8() ? 4 : 1;
for( S4x4Idx cIdx(c8x8Idx); cIdx.isLegal( c8x8Idx ) && uiNumFrags > 0; cIdx ++ ) {
xResidualBlock( *pcMbDataAccessEL, *pcMbDataAccessBL,
cIdx, LUMA_SCAN, uiStride, aiMaxPosLuma, uiNumFrags, rcMbFGSCoefMap, uiMbCoeffsDecoded );
}
}
}
//===== CHROMA DC =====
if( uiNumFrags > 0 ) {
xResidualBlock( *pcMbDataAccessEL, *pcMbDataAccessBL,
CIdx(0), CHROMA_DC, aiMaxPosChromaDC, uiNumFrags, rcMbFGSCoefMap, uiMbCoeffsDecoded );
}
if( uiNumFrags > 0 ) {
xResidualBlock( *pcMbDataAccessEL, *pcMbDataAccessBL,
CIdx(4), CHROMA_DC, aiMaxPosChromaDC, uiNumFrags, rcMbFGSCoefMap, uiMbCoeffsDecoded );
}
//===== CHROMA AC =====
for( CIdx cCIdx; cCIdx.isLegal() && uiNumFrags > 0; cCIdx ++ ) {
xResidualBlock( *pcMbDataAccessEL, *pcMbDataAccessBL,
cCIdx, CHROMA_AC, aiMaxPosChromaAC, uiNumFrags, rcMbFGSCoefMap, uiMbCoeffsDecoded );
}
RNOK( m_pcSymbolReader->RQupdateVlcTable( uiNumFrags ) );
RNOK( xSetNumCoefficients( uiMbX, uiMbY, rcMbFGSCoefMap, uiMbCoeffsDecoded ) );
}
}
}
RNOK( m_pcSymbolReader->RQvlcFlush() );
UInt uiTermBit = 0;
RNOK( m_pcSymbolReader->RQdecodeTermBit( uiTermBit ) );
}
catch( BitReadBuffer::ReadStop )
{
m_bPicFinished = true;
m_pcSymbolReader->RQsetTruncatedFlag( true );
}
RNOK( m_pcSymbolReader->finishSlice( ) );
// initialize the parallel bitstream buffers
m_pcSymbolReader->RQreleaseFragments();
if( ! m_bPicFinished )
{
m_pcSliceHeader->setQualityLevel( m_pcSliceHeader->getQualityLevel() + 1 );
}
m_bUpdateWithoutMap = true;
RNOK( xUpdateCodingPath( pcSliceHeader ) );
RNOK( xClearCodingPath() );
return Err::m_nOK;
}
// all functions below, except xDecodeMotionData and
// xInitializeMacroblockQPs are not needed for block-based decoding
ErrVal
RQFGSDecoder::xDecodingFGS( SliceHeader* pcSliceHeader )
{
RNOK( m_cMbDataCtrlEL .reset () );
RNOK( m_cMbDataCtrlEL .clear () );
RNOK( m_cMbDataCtrlEL .initSlice ( *m_pcSliceHeader, PARSE_PROCESS, true, NULL ) );
RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS, true, NULL ) );
RNOK( xInitializeMacroblockQPs() );
RNOK( m_cMbDataCtrlEL .initSlice ( *m_pcSliceHeader, PRE_PROCESS, true, NULL ) );
Int iLastQP = m_pcSliceHeader->getPicQp();
UInt uiFirstMbInSlice = m_pcSliceHeader->getFirstMbInSlice ();
// JVT-S054 (2) (ADD)
UInt uiLastMbInSlice = m_pcSliceHeader->getLastMbInSlice();
m_bFgsComponentSep = m_pcSliceHeader->getFgsComponentSep();
Bool isTruncated =false;
//positions vector for luma (and chromaAC) and chroma DC
UInt ui;
for(ui = 0; ui < 4; ui++)
{
m_auiScanPosVectChromaDC[ui] = ui;
}
if(m_pcSliceHeader->getFGSCodingMode() == false)
{
//grouping size mode
UInt uiGroupingSize = m_pcSliceHeader->getGroupingSize();
ui = 0;
m_auiScanPosVectLuma[ui] = uiGroupingSize-1;
while( m_auiScanPosVectLuma[ui] < 15)
{
ui++;
m_auiScanPosVectLuma[ui] = m_auiScanPosVectLuma[ui-1]+uiGroupingSize;
}
}
else
{
//vector specified
ui = 0;
m_auiScanPosVectLuma[ui] = m_pcSliceHeader->getPosVect(ui) - 1;
while( m_auiScanPosVectLuma[ui] < 15)
{
ui++;
m_auiScanPosVectLuma[ui] = m_auiScanPosVectLuma[ui-1] + m_pcSliceHeader->getPosVect(ui);
}
}
try
{
AOT( m_pcSymbolReader == 0 );
RNOK( m_pcSymbolReader ->startSlice( *m_pcSliceHeader ) );
//===== SIGNIFICANCE PATH =====
{
UInt iStartCycle = 0, iCycle = 0;
UInt iLumaScanIdx = 0;
UInt iChromaDCScanIdx = 0;
UInt iChromaACScanIdx = 1;
RNOK( m_pcSymbolReader->RQdecodeEobOffsets_Luma () );
RNOK( m_pcSymbolReader->RQdecodeEobOffsets_Chroma() );
RNOK( m_pcSymbolReader->RQdecodeBestCodeTableMap ( 16 ) );
m_uiLumaCbpRun = 0;
m_uiChromaCbpRun = 0;
Bool bChromaCbpFlag;
if( ! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() )
{
m_pcUvlcReader->getFlag(m_bLastLumaCbpFlag, "Luma_CBP_first_flag");
m_pcUvlcReader->getFlag(bChromaCbpFlag, "Chroma_CBP_first");
m_uiLastChromaCbp = bChromaCbpFlag ? 1 : 0;
}
UInt uiNumFrags, uiFragIdx;
Int aiMaxPosLuma[16], aiMaxPosChromaAC[16], aiMaxPosChromaDC[16];
// initialize the parallel bitstream buffers
m_pcSymbolReader->RQinitFragments( *m_pcSliceHeader, uiNumFrags, false );
if( m_bFgsComponentSep == 0 )
m_pcSymbolReader->RQdecodeCycleSymbol(iStartCycle);
uiFragIdx = 0;
uiNumFrags = xDeriveComponentPosVectors( m_auiScanPosVectLuma,
aiMaxPosLuma, aiMaxPosChromaAC, aiMaxPosChromaDC, iStartCycle );
while (iLumaScanIdx < 16 || iChromaDCScanIdx < 4 || iChromaACScanIdx < 16) {
UInt bAllowChromaDC, bAllowChromaAC;
UInt uiMaxPosLuma;
UInt uiMaxPosChromaAC;
UInt uiMaxPosChromaDC;
uiMaxPosLuma = aiMaxPosLuma [uiFragIdx];
uiMaxPosChromaAC = aiMaxPosChromaAC[uiFragIdx];
uiMaxPosChromaDC = aiMaxPosChromaDC[uiFragIdx];
if( uiFragIdx == 0 )
{
bAllowChromaDC = true;
bAllowChromaAC = aiMaxPosChromaAC[0] > 0;
}
else
{
bAllowChromaDC = (Int) uiMaxPosChromaDC > aiMaxPosChromaDC[uiFragIdx - 1];
bAllowChromaAC = (Int) uiMaxPosChromaAC > aiMaxPosChromaAC[uiFragIdx - 1];
}
uiFragIdx ++;
if( iLumaScanIdx >= 16 && !bAllowChromaDC && !bAllowChromaAC )
{
iCycle++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -