📄 mbdecoder.cpp
字号:
RNOK( m_pcTransform->invTransform4x4Blk( cYuvMbBuffer.getYBlk( cIdx ),
cYuvMbBuffer.getLStride(),
rcCoeffs.get(cIdx) ) );
}
}
UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, false, bAddBaseCoeffs ) );
// Note that the following also copies pred buffer inside of MbTransformCoeffs
rcMbDataAccess.getMbTCoeffs().copyFrom( rcCoeffs );
rcMbDataAccess.getMbTCoeffs().copyPredictionFrom( rcPredBuffer );
pcRecYuvBuffer->loadBuffer( &cYuvMbBuffer );
return Err::m_nOK;
}
ErrVal
MbDecoder::xDecodeMbIntra16x16( MbDataAccess& rcMbDataAccess,
YuvMbBuffer& cYuvMbBuffer,
YuvMbBuffer& rcPredBuffer )
{
#ifdef SHARP_AVC_REWRITE_OUTPUT
return Err::m_nOK;
#endif
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,
YuvMbBuffer& rcRecYuvBuffer,
YuvMbBuffer& rcPredMbBuffer,
UInt uiChromaCbp,
Bool bPredChroma,
Bool bAddBaseCoeffsChroma )
{
#ifdef SHARP_AVC_REWRITE_OUTPUT
return Err::m_nOK;
#endif
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 );
}
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 );
if( bAddBaseCoeffsChroma )
{
rcCoeffs.add( &rcMbDataAccess.getMbDataAccessBase()->getMbTCoeffs(), false, true );
}
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:
(It 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;
}
// store the coefficient for non intra 16x16 block
if (!rcMbDataAccess.getMbData().isIntra16x16() && (!rcMbDataAccess.getMbData().isPCM() ))
rcMbDataAccess.getMbTCoeffs().copyFrom(rcTCoeffs);
return Err::m_nOK;
}
ErrVal
MbDecoder::xAddTCoeffs( 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 + -