📄 mbdecoder.cpp
字号:
ErrVal MbDecoder::process( MbDataAccess& rcMbDataAccess,
Bool bReconstructAll,
UInt uiMbAddress )
{
ROF( m_bInitDone );
RNOK( xScaleTCoeffs( rcMbDataAccess ) );
YuvPicBuffer *pcRecYuvBuffer;
RNOK( m_pcFrameMng->getRecYuvBuffer( pcRecYuvBuffer, rcMbDataAccess.getMbPicType() ) );
IntYuvMbBuffer cPredIntYuvMbBuffer;
IntYuvMbBuffer cResIntYuvMbBuffer;
YuvMbBuffer cYuvMbBuffer;
if( rcMbDataAccess.getMbData().isPCM() )
{
RNOK( xDecodeMbPCM( rcMbDataAccess, cYuvMbBuffer ) );
cResIntYuvMbBuffer .setAllSamplesToZero();
cPredIntYuvMbBuffer.loadBuffer( &cYuvMbBuffer );
}
else
{
if( rcMbDataAccess.getMbData().isIntra() )
{
m_pcIntraPrediction->setAvailableMaskMb( rcMbDataAccess.getAvailableMask() );
cResIntYuvMbBuffer.loadIntraPredictors( pcRecYuvBuffer );
if( rcMbDataAccess.getMbData().isIntra4x4() )
{
if( rcMbDataAccess.getMbData().isTransformSize8x8() )
{
RNOK( xDecodeMbIntra8x8( rcMbDataAccess, cResIntYuvMbBuffer, cPredIntYuvMbBuffer ) );
}
else
{
RNOK( xDecodeMbIntra4x4( rcMbDataAccess, cResIntYuvMbBuffer, cPredIntYuvMbBuffer ) );
}
}
else
{
RNOK( xDecodeMbIntra16x16( rcMbDataAccess, cResIntYuvMbBuffer, cPredIntYuvMbBuffer ) );
}
cYuvMbBuffer.loadBuffer( &cResIntYuvMbBuffer );
}
else
{
RNOK( xDecodeMbInter( rcMbDataAccess,
cYuvMbBuffer, cPredIntYuvMbBuffer, cResIntYuvMbBuffer, bReconstructAll ) );
}
}
pcRecYuvBuffer->loadBuffer( &cYuvMbBuffer );
const PicType eMbPicType = rcMbDataAccess.getMbPicType();
RNOK( m_pcFrameMng->getCurrentFrameUnit()->getResidual() ->getPic( eMbPicType )->getFullPelYuvBuffer()->loadBuffer( &cResIntYuvMbBuffer ) );
RNOK( m_pcFrameMng->getCurrentFrameUnit()->getFGSIntFrame()->getPic( eMbPicType )->getFullPelYuvBuffer()->loadBuffer( &cPredIntYuvMbBuffer ) );
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeMbPCM( MbDataAccess& rcMbDataAccess, YuvMbBuffer& rcRecYuvBuffer )
{
Pel* pucSrc = rcMbDataAccess.getMbTCoeffs().getPelBuffer();
Pel* pucDest = rcRecYuvBuffer.getMbLumAddr();
Int iStride = rcRecYuvBuffer.getLStride();
Int n;
for( n = 0; n < 16; n++ )
{
::memcpy( pucDest, pucSrc, 16 );
pucSrc += 16;
pucDest += iStride;
}
pucDest = rcRecYuvBuffer.getMbCbAddr();
iStride = rcRecYuvBuffer.getCStride();
for( n = 0; n < 8; n++ )
{
::memcpy( pucDest, pucSrc, 8 );
pucSrc += 8;
pucDest += iStride;
}
pucDest = rcRecYuvBuffer.getMbCrAddr();
for( n = 0; n < 8; n++ )
{
::memcpy( pucDest, pucSrc, 8 );
pucSrc += 8;
pucDest += iStride;
}
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeMbPCM( MbDataAccess& rcMbDataAccess, IntYuvPicBuffer *pcRecYuvBuffer )
{
Pel* pucSrc = rcMbDataAccess.getMbTCoeffs().getPelBuffer();
XPel* pucDest = pcRecYuvBuffer->getMbLumAddr();
Int iStride = pcRecYuvBuffer->getLStride();
Int iDelta = 1;
Int n, m, n1, m1, dest;
for( n = 0; n < 16; n+=iDelta )
{
for( m = 0; m < 16; m+=iDelta )
{
dest = *pucSrc++;
for( n1=0; n1< +iDelta; n1++ )
for( m1=m; m1<m+iDelta; m1++ )
{
pucDest[m1+n1*iStride] = dest;
}
}
pucDest += iDelta*iStride;
}
pucDest = pcRecYuvBuffer->getMbCbAddr();
iStride = pcRecYuvBuffer->getCStride();
for( n = 0; n < 8; n+=iDelta )
{
for( m = 0; m < 8; m+=iDelta )
{
dest = *pucSrc++;
for( n1=0; n1< +iDelta; n1++ )
for( m1=m; m1<m+iDelta; m1++ )
{
pucDest[m1+n1*iStride] = dest;
}
}
pucDest += iDelta*iStride;
}
pucDest = pcRecYuvBuffer->getMbCrAddr();
for( n = 0; n < 8; n+=iDelta )
{
for( m = 0; m < 8; m+=iDelta )
{
dest = *pucSrc++;
for( n1=0; n1< +iDelta; n1++ )
for( m1=m; m1<m+iDelta; m1++ )
{
pucDest[m1+n1*iStride] = dest;
}
}
pucDest += iDelta*iStride;
}
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeMbInter( MbDataAccess& rcMbDataAccess,
YuvMbBuffer& rcRecYuvBuffer,
IntYuvMbBuffer& rcPredIntYuvMbBuffer,
IntYuvMbBuffer& rcResIntYuvMbBuffer,
Bool bReconstruct )
{
rcResIntYuvMbBuffer.setAllSamplesToZero();
if( ! bReconstruct )
{
RNOK( m_pcMotionCompensation->calculateMb ( rcMbDataAccess, true ) );
rcRecYuvBuffer.setZero();
}
else
{
RNOK( m_pcMotionCompensation->compensateMb( rcMbDataAccess, &rcRecYuvBuffer, true ) );
}
rcPredIntYuvMbBuffer.loadBuffer( &rcRecYuvBuffer );
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
m_pcTransform->setClipMode( false );
if( rcMbDataAccess.getMbData().isTransformSize8x8() )
{
for( B8x8Idx cIdx8x8; cIdx8x8.isLegal(); cIdx8x8++ )
{
if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx8x8 ) )
{
RNOK( m_pcTransform->invTransform8x8Blk( rcResIntYuvMbBuffer.getYBlk( cIdx8x8 ),
rcResIntYuvMbBuffer.getLStride(),
rcCoeffs.get8x8(cIdx8x8) ) );
}
}
}
else
{
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
{
RNOK( m_pcTransform->invTransform4x4Blk( rcResIntYuvMbBuffer.getYBlk( cIdx ),
rcResIntYuvMbBuffer.getLStride(),
rcCoeffs.get(cIdx) ) );
}
}
}
UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
IntYuvMbBuffer cPredBuffer;
RNOK( xDecodeChroma( rcMbDataAccess, rcResIntYuvMbBuffer, cPredBuffer, uiChromaCbp, false ) );
m_pcTransform->setClipMode( true );
IntYuvMbBuffer cIntYuvMbBuffer;
cIntYuvMbBuffer. loadLuma ( rcPredIntYuvMbBuffer );
cIntYuvMbBuffer. loadChroma ( rcPredIntYuvMbBuffer );
cIntYuvMbBuffer. add ( rcResIntYuvMbBuffer );
rcRecYuvBuffer. loadBufferClip( &cIntYuvMbBuffer );
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeMbInter( MbDataAccess& rcMbDataAccess,
MbDataAccess* pcMbDataAccessBase,
IntYuvMbBuffer& rcPredBuffer,
IntYuvPicBuffer* pcRecYuvBuffer,
IntFrame* pcResidual,
IntFrame* pcBaseResidual,
RefFrameList& rcRefFrameList0,
RefFrameList& rcRefFrameList1,
Bool bReconstruct,
IntFrame* pcBaseLayerRec )
{
IntYuvMbBuffer cYuvMbBuffer; cYuvMbBuffer .setAllSamplesToZero();
IntYuvMbBuffer cYuvMbBufferResidual; cYuvMbBufferResidual.setAllSamplesToZero();
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
Bool bCalcMv = false;
Bool bFaultTolerant = true;
//===== derive motion vectors =====
calcMv( rcMbDataAccess, pcMbDataAccessBase );
//===== get prediction signal when full reconstruction is requested =====
if( bReconstruct )
{
if( rcMbDataAccess.getMbData().getMbMode() == MODE_8x8 || rcMbDataAccess.getMbData().getMbMode() == MODE_8x8ref0 )
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
//----- motion compensated prediction -----
RNOK( m_pcMotionCompensation->compensateSubMb ( c8x8Idx,
rcMbDataAccess, rcRefFrameList0, rcRefFrameList1,
&cYuvMbBuffer, bCalcMv, bFaultTolerant,
rcMbDataAccess.getMbData().getSmoothedRefFlag() ) );
}
}
else
{
//----- motion compensated prediction -----
RNOK( m_pcMotionCompensation->compensateMb ( rcMbDataAccess,
rcRefFrameList0,
rcRefFrameList1,
&cYuvMbBuffer,
bCalcMv,
rcMbDataAccess.getMbData().getSmoothedRefFlag() ) );
}
if(pcBaseLayerRec)
{
RNOK(m_pcMotionCompensation->compensateMbBLSkipIntra(rcMbDataAccess, &cYuvMbBuffer, pcBaseLayerRec));
}
rcPredBuffer.loadLuma ( cYuvMbBuffer );
rcPredBuffer.loadChroma ( cYuvMbBuffer );
}
//===== reconstruct residual signal by using transform coefficients ======
m_pcTransform->setClipMode( false );
if( rcMbDataAccess.getMbData().isTransformSize8x8() )
{
for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
{
if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
{
RNOK( m_pcTransform->invTransform8x8Blk( cYuvMbBufferResidual.getYBlk( cIdx ),
cYuvMbBufferResidual.getLStride(),
rcCoeffs.get8x8(cIdx) ) );
}
}
}
else
{
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
{
RNOK( m_pcTransform->invTransform4x4Blk( cYuvMbBufferResidual.getYBlk( cIdx ),
cYuvMbBufferResidual.getLStride(),
rcCoeffs.get(cIdx) ) );
}
}
}
UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBufferResidual, rcPredBuffer, uiChromaCbp, false ) );
m_pcTransform->setClipMode( true );
//===== add base layer residual =====
if( rcMbDataAccess.getMbData().getResidualPredFlag( PART_16x16 )
&& !rcMbDataAccess.getSH().getAVCRewriteFlag() )
{
IntYuvMbBuffer cBaseLayerBuffer;
cBaseLayerBuffer.loadBuffer( pcBaseResidual->getFullPelYuvBuffer() );
cYuvMbBufferResidual.add( cBaseLayerBuffer );
//--- set CBP ---
rcMbDataAccess.getMbData().setMbExtCbp( rcMbDataAccess.getMbData().getMbExtCbp() | pcMbDataAccessBase->getMbData().getMbExtCbp() );
}
//===== reconstruct signal =====
if( bReconstruct )
{
cYuvMbBuffer.add( cYuvMbBufferResidual );
cYuvMbBuffer.clip();
}
//===== store reconstructed residual =====
if( pcResidual )
{
RNOK( pcResidual->getFullPelYuvBuffer()->loadBuffer( &cYuvMbBufferResidual ) );
}
//===== store reconstructed signal =====
if( pcRecYuvBuffer )
{
RNOK( pcRecYuvBuffer->loadBuffer( &cYuvMbBuffer ) );
}
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeChroma( MbDataAccess& rcMbDataAccess, YuvMbBuffer& rcRecYuvBuffer, UInt uiChromaCbp, Bool bPredChroma )
{
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
Pel* pucCb = rcRecYuvBuffer.getMbCbAddr();
Pel* pucCr = rcRecYuvBuffer.getMbCrAddr();
Int iStride = rcRecYuvBuffer.getCStride();
if( bPredChroma )
{
RNOK( m_pcIntraPrediction->predictChromaBlock( pucCb, pucCr, iStride, rcMbDataAccess.getMbData().getChromaPredMode() ) );
}
ROTRS( 0 == uiChromaCbp, Err::m_nOK );
Int iScale;
Bool bIntra = rcMbDataAccess.getMbData().isIntra();
UInt uiUScalId = ( bIntra ? 1 : 4 );
UInt uiVScalId = ( bIntra ? 2 : 5 );
const UChar* pucScaleU = rcMbDataAccess.getSH().getScalingMatrix( uiUScalId );
const UChar* pucScaleV = rcMbDataAccess.getSH().getScalingMatrix( uiVScalId );
// scaling has already been performed on DC coefficients
iScale = ( pucScaleU ? pucScaleU[0] : 16 );
m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(0) ), iScale );
iScale = ( pucScaleV ? pucScaleV[0] : 16 );
m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(4) ), iScale );
RNOK( m_pcTransform->invTransformChromaBlocks( pucCb, iStride, rcCoeffs.get( CIdx(0) ) ) );
RNOK( m_pcTransform->invTransformChromaBlocks( pucCr, iStride, rcCoeffs.get( CIdx(4) ) ) );
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeMbIntra4x4( MbDataAccess& rcMbDataAccess,
IntYuvMbBuffer& cYuvMbBuffer,
IntYuvMbBuffer& rcPredBuffer )
{
Int iStride = cYuvMbBuffer.getLStride();
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
if( !rcMbDataAccess.getMbData().getBLSkipFlag() || !rcMbDataAccess.getSH().getAVCRewriteFlag() )
rcMbDataAccess.getMbData().intraPredMode( cIdx ) = rcMbDataAccess.decodeIntraPredMode( cIdx );
XPel* puc = cYuvMbBuffer.getYBlk( cIdx );
UInt uiPredMode = rcMbDataAccess.getMbData().intraPredMode( cIdx );
RNOK( m_pcIntraPrediction->predictLumaBlock( puc, iStride, uiPredMode, cIdx ) );
rcPredBuffer.loadLuma( cYuvMbBuffer, cIdx );
if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
{
RNOK( m_pcTransform->invTransform4x4Blk( puc, iStride, rcCoeffs.get( cIdx ) ) );
}
}
UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, true ) );
return Err::m_nOK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -