mbdecoder.cpp
来自「JVT-S203 contains the JSVM 6 reference s」· C++ 代码 · 共 1,158 行 · 第 1/3 页
CPP
1,158 行
//===== 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++ )
{
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;
}
ErrVal MbDecoder::xDecodeMbIntra8x8( MbDataAccess& rcMbDataAccess,
IntYuvMbBuffer& cYuvMbBuffer,
IntYuvMbBuffer& rcPredBuffer )
{
Int iStride = cYuvMbBuffer.getLStride();
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
{
{
Int iPredMode = rcMbDataAccess.decodeIntraPredMode( cIdx );
for( S4x4Idx cIdx4x4( cIdx ); cIdx4x4.isLegal( cIdx ); cIdx4x4++ )
{
rcMbDataAccess.getMbData().intraPredMode( cIdx4x4 ) = iPredMode;
}
}
XPel* puc = cYuvMbBuffer.getYBlk( cIdx );
const UInt uiPredMode = rcMbDataAccess.getMbData().intraPredMode( cIdx );
RNOK( m_pcIntraPrediction->predictLuma8x8Block( puc, iStride, uiPredMode, cIdx ) );
rcPredBuffer.loadLuma( cYuvMbBuffer, cIdx );
if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
{
RNOK( m_pcTransform->invTransform8x8Blk( puc, iStride, rcCoeffs.get8x8( cIdx ) ) );
}
}
UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, true ) );
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeMbIntraBL( MbDataAccess& rcMbDataAccess,
IntYuvPicBuffer* pcRecYuvBuffer,
IntYuvMbBuffer& rcPredBuffer,
IntYuvPicBuffer* pcBaseYuvBuffer )
{
IntYuvMbBuffer cYuvMbBuffer;
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
cYuvMbBuffer.loadBuffer ( pcBaseYuvBuffer );
rcPredBuffer.loadLuma ( cYuvMbBuffer );
rcPredBuffer.loadChroma ( cYuvMbBuffer );
if( rcMbDataAccess.getMbData().isTransformSize8x8() )
{
for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
{
if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
{
RNOK( m_pcTransform->invTransform8x8Blk( cYuvMbBuffer.getYBlk( cIdx ),
cYuvMbBuffer.getLStride(),
rcCoeffs.get8x8(cIdx) ) );
}
}
}
else
{
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
{
RNOK( m_pcTransform->invTransform4x4Blk( cYuvMbBuffer.getYBlk( cIdx ),
cYuvMbBuffer.getLStride(),
rcCoeffs.get(cIdx) ) );
}
}
}
UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, false ) );
pcRecYuvBuffer->loadBuffer( &cYuvMbBuffer );
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeMbIntra16x16( MbDataAccess& rcMbDataAccess,
IntYuvMbBuffer& cYuvMbBuffer,
IntYuvMbBuffer& rcPredBuffer )
{
Int iStride = cYuvMbBuffer.getLStride();
RNOK( m_pcIntraPrediction->predictLumaMb( cYuvMbBuffer.getMbLumAddr(), iStride, rcMbDataAccess.getMbData().intraPredMode() ) );
rcPredBuffer.loadLuma( cYuvMbBuffer );
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
Quantizer cQuantizer; cQuantizer.setQp ( rcMbDataAccess, false );
const QpParameter rcLQp = cQuantizer.getLumaQp();
Int iScaleY = g_aaiDequantCoef[rcLQp.rem()][0] << rcLQp.per();
const UChar* pucScaleY = rcMbDataAccess.getSH().getScalingMatrix( 0 );
if( pucScaleY )
{
iScaleY *= pucScaleY[0];
iScaleY >>= 4;
}
RNOK( m_pcTransform->invTransformDcCoeff( rcCoeffs.get( B4x4Idx(0) ), iScaleY ) );
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( m_pcTransform->invTransform4x4Blk( cYuvMbBuffer.getYBlk( cIdx ), iStride, rcCoeffs.get( cIdx ) ) );
}
UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma16x16();
RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, true ) );
return Err::m_nOK;
}
ErrVal MbDecoder::xDecodeChroma( MbDataAccess& rcMbDataAccess,
IntYuvMbBuffer& rcRecYuvBuffer,
IntYuvMbBuffer& rcPredMbBuffer,
UInt uiChromaCbp,
Bool bPredChroma )
{
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
XPel* pucCb = rcRecYuvBuffer.getMbCbAddr();
XPel* pucCr = rcRecYuvBuffer.getMbCrAddr();
Int iStride = rcRecYuvBuffer.getCStride();
if( bPredChroma )
{
RNOK( m_pcIntraPrediction->predictChromaBlock( pucCb, pucCr, iStride, rcMbDataAccess.getMbData().getChromaPredMode() ) );
rcPredMbBuffer.loadChroma( rcRecYuvBuffer );
}
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::xScale4x4Block( TCoeff* piCoeff,
const UChar* pucScale,
UInt uiStart,
const QpParameter& rcQP )
{
if( pucScale )
{
Int iAdd = ( rcQP.per() <= 3 ? ( 1 << ( 3 - rcQP.per() ) ) : 0 );
for( UInt ui = uiStart; ui < 16; ui++ )
{
piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef[rcQP.rem()][ui] * pucScale[ui] + iAdd ) << rcQP.per() ) >> 4;
}
}
else
{
for( UInt ui = uiStart; ui < 16; ui++ )
{
piCoeff[ui] *= ( g_aaiDequantCoef[rcQP.rem()][ui] << rcQP.per() );
}
}
return Err::m_nOK;
}
ErrVal
MbDecoder::xScale8x8Block( TCoeff* piCoeff,
const UChar* pucScale,
const QpParameter& rcQP )
{
Int iAdd = ( rcQP.per() <= 5 ? ( 1 << ( 5 - rcQP.per() ) ) : 0 );
if( pucScale )
{
for( UInt ui = 0; ui < 64; ui++ )
{
piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef64[rcQP.rem()][ui] * pucScale[ui] + iAdd ) << rcQP.per() ) >> 6;
}
}
else
{
for( UInt ui = 0; ui < 64; ui++ )
{
piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef64[rcQP.rem()][ui] * 16 + iAdd ) << rcQP.per() ) >> 6;
}
}
return Err::m_nOK;
}
ErrVal
MbDecoder::xScaleTCoeffs( MbDataAccess& rcMbDataAccess )
{
Quantizer cQuantizer;
cQuantizer.setQp( rcMbDataAccess, false );
const QpParameter& cLQp = cQuantizer.getLumaQp ();
const QpParameter& cCQp = cQuantizer.getChromaQp();
Bool bIntra = rcMbDataAccess.getMbData().isIntra();
Bool b8x8 = rcMbDataAccess.getMbData().isTransformSize8x8();
Bool b16x16 = rcMbDataAccess.getMbData().isIntra16x16();
UInt uiYScalId = ( bIntra ? ( b8x8 && !b16x16 ? 6 : 0 ) : ( b8x8 ? 7 : 3 ) );
UInt uiUScalId = ( bIntra ? 1 : 4 );
UInt uiVScalId = ( bIntra ? 2 : 5 );
const UChar* pucScaleY = rcMbDataAccess.getSH().getScalingMatrix( uiYScalId );
const UChar* pucScaleU = rcMbDataAccess.getSH().getScalingMatrix( uiUScalId );
const UChar* pucScaleV = rcMbDataAccess.getSH().getScalingMatrix( uiVScalId );
//===== copy all coefficients =====
MbTransformCoeffs& rcTCoeffs = m_cTCoeffs;
rcTCoeffs.copyFrom( rcMbDataAccess.getMbTCoeffs() );
//===== luma =====
if( b16x16 )
{
//===== INTRA_16x16 =====
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( xScale4x4Block( rcTCoeffs.get( cIdx ), pucScaleY, 1, cLQp ) );
}
}
else if( b8x8 )
{
//===== 8x8 BLOCKS =====
for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( xScale8x8Block( rcTCoeffs.get8x8( cIdx ), pucScaleY, cLQp ) );
}
}
else
{
//===== 4x4 BLOCKS =====
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( xScale4x4Block( rcTCoeffs.get( cIdx ), pucScaleY, 0, cLQp ) );
}
}
//===== chroma =====
Int iScaleU = g_aaiDequantCoef[cCQp.rem()][0] << cCQp.per();
Int iScaleV = g_aaiDequantCoef[cCQp.rem()][0] << cCQp.per();
/* HS: old scaling modified:
(I did not work for scaling matrices, when QpPer became less than 5 in an FGS enhancement) */
for( CIdx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( xScale4x4Block( rcTCoeffs.get( cIdx ), ( cIdx.plane() ? pucScaleV : pucScaleU ), 1, cCQp ) );
}
UInt uiDCIdx;
TCoeff* piCoeff = rcTCoeffs.get( CIdx(0) );
for( uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
{
piCoeff[16*uiDCIdx] *= iScaleU;
}
piCoeff = rcTCoeffs.get( CIdx(4) );
for( uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
{
piCoeff[16*uiDCIdx] *= iScaleV;
}
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?