📄 mbdecoder.cpp
字号:
ErrVal MbDecoder::xDecodeMbIntra8x8( MbDataAccess& rcMbDataAccess,
IntYuvMbBuffer& cYuvMbBuffer,
IntYuvMbBuffer& rcPredBuffer )
{
Int iStride = cYuvMbBuffer.getLStride();
MbTransformCoeffs& rcCoeffs = m_cTCoeffs;
for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
{
if( !rcMbDataAccess.getMbData().getBLSkipFlag() || !rcMbDataAccess.getSH().getAVCRewriteFlag() )
{
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;
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 ) );
const UChar* pucScaleY = rcMbDataAccess.getSH().getScalingMatrix( uiYScalId );
const Int aaiDequantDcCoef[6] = { 10, 11, 13, 14, 16, 18 };
const Int iQp = rcMbDataAccess.getMbData().getQp();
Int iQpScale = aaiDequantDcCoef[iQp%6];
if( pucScaleY )
{
iQpScale *= pucScaleY[0];
}
else
{
iQpScale *= 16;
}
RNOK( m_pcTransform->invTransformDcCoeff( rcCoeffs.get( B4x4Idx(0) ), iQpScale, iQp/6) );
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 );
}
// ChromaCbp value is not correct when AVCRewriteFlag is true
ROTRS( 0 == uiChromaCbp && !rcMbDataAccess.getSH().getAVCRewriteFlag(), 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 );
//===== store coefficient level values ==
if (!rcMbDataAccess.getMbData().isPCM() )
rcMbDataAccess.getMbTCoeffs().storeLevelData();
//===== copy all coefficients =====
MbTransformCoeffs& rcTCoeffs = m_cTCoeffs;
rcTCoeffs.copyFrom( rcMbDataAccess.getMbTCoeffs() );
//===== luma =====
if( b16x16 )
{
//===== INTRA_16x16 =====
const Int aaiDequantDcCoef[6] = { 10, 11, 13, 14, 16, 18 };
Int iScaleY = aaiDequantDcCoef[cLQp.rem()] << cLQp.per();
if( pucScaleY )
{
iScaleY *= pucScaleY[0];
iScaleY >>= 4;
}
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;
}
// for SVC to AVC rewrite
ErrVal
MbDecoder::xAddTCoeffs2( MbDataAccess& rcMbDataAccess, MbDataAccess& rcMbDataAccessBase )
{
UInt uiBCBP = 0;
UInt uiCoded = 0;
Bool bCoded = false;
Bool bChromaAC = false;
Bool bChromaDC = false;
rcMbDataAccessBase.getMbTCoeffs().switchLevelCoeffData();
// Add the luma coefficients and track the new BCBP
if( rcMbDataAccess.getMbData().isTransformSize8x8() )
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
bCoded = false;
m_pcTransform->addPrediction8x8Blk( rcMbDataAccess.getMbTCoeffs().get8x8( c8x8Idx ),
rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx ),
rcMbDataAccess.getMbData().getQp(),
rcMbDataAccessBase.getMbData().getQp(), bCoded );
if( rcMbDataAccess.getMbData().isIntra16x16() )
AOT(1);
if( bCoded )
uiBCBP |= (0x33 << c8x8Idx.b4x4());
}
}
else
{
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
uiCoded = 0;
m_pcTransform->addPrediction4x4Blk( rcMbDataAccess.getMbTCoeffs().get( cIdx ),
rcMbDataAccessBase.getMbTCoeffs().get( cIdx ),
rcMbDataAccess.getMbData().getQp(),
rcMbDataAccessBase.getMbData().getQp(), uiCoded );
if( rcMbDataAccess.getMbData().isIntra16x16() )
{
if( *(rcMbDataAccess.getMbTCoeffs().get( cIdx )) )
uiCoded--;
}
if( uiCoded )
uiBCBP |= (1<<cIdx);
}
if( rcMbDataAccess.getMbData().isIntra16x16() )
{
uiBCBP = uiBCBP?((1<<16)-1):0;
}
}
// Add the chroma coefficients and update the BCBP
m_pcTransform->addPredictionChromaBlocks( rcMbDataAccess.getMbTCoeffs().get( CIdx(0) ),
rcMbDataAccessBase.getMbTCoeffs().get( CIdx(0) ),
rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbData().getQp() ),
rcMbDataAccessBase.getSH().getChromaQp( rcMbDataAccessBase.getMbData().getQp() ),
bChromaDC, bChromaAC );
m_pcTransform->addPredictionChromaBlocks( rcMbDataAccess.getMbTCoeffs().get( CIdx(4) ),
rcMbDataAccessBase.getMbTCoeffs().get( CIdx(4) ),
rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbData().getQp() ),
rcMbDataAccessBase.getSH().getChromaQp( rcMbDataAccessBase.getMbData().getQp() ),
bChromaDC, bChromaAC );
uiBCBP |= (bChromaAC?2:(bChromaDC?1:0))<<16;
// Update the CBP
rcMbDataAccess.getMbData().setAndConvertMbExtCbp( uiBCBP );
// Update the Intra16x16 mode
if( rcMbDataAccess.getMbData().isIntra16x16() )
{
UInt uiMbType = INTRA_4X4 + 1;
UInt uiPredMode = rcMbDataAccess.getMbData().intraPredMode();
UInt uiChromaCbp = uiBCBP>>16;
Bool bACcoded = (uiBCBP && ((1<<16)-1));
uiMbType += uiPredMode;
uiMbType += ( bACcoded ) ? 12 : 0;
uiMbType += uiChromaCbp << 2;
rcMbDataAccess.getMbData().setMbMode( MbMode(uiMbType) );
// Sanity checks
if( rcMbDataAccess.getMbData().intraPredMode() != uiPredMode )
AOT(1);
if( rcMbDataAccess.getMbData().getCbpChroma16x16() != uiChromaCbp )
AOT(1);
if( rcMbDataAccess.getMbData().isAcCoded() != bACcoded )
AOT(1);
}
rcMbDataAccessBase.getMbTCoeffs().switchLevelCoeffData();
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -