fgscoder.cpp
来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,684 行 · 第 1/5 页
CPP
1,684 行
{
UInt ui;
for( ui = 0; ui < 4; ui++ )
m_aapaucChromaDCCoefMap[uiPlane][ui][uiMbIndex] &= ~CODED;
m_apaucScanPosMap[uiPlane + 1][uiMbIndex] = 4;
for( ui = 0; ui < 4; ui++ )
if( !( m_aapaucChromaDCCoefMap[uiPlane][ui][uiMbIndex] & (SIGNIFICANT|CODED) ) && m_apaucScanPosMap[uiPlane + 1][uiMbIndex] == 4 )
m_apaucScanPosMap[uiPlane + 1][uiMbIndex] = ui;
m_apaucChromaDCBlockMap[uiPlane][uiMbIndex] &= ~CODED;
}
//--- CHROMA AC ---
for( CIdx cCIdx; cCIdx.isLegal(); cCIdx++ )
{
UInt ui;
UInt ui8x8Idx = ( 2*uiMbY + cCIdx.y() ) * 2 * m_uiWidthInMB + ( 2 * uiMbX + cCIdx.x() );
for( ui = 1; ui < 16; ui++ )
m_aapaucChromaACCoefMap[cCIdx.plane()][ui][ui8x8Idx] &= ~CODED;
m_apaucScanPosMap[cCIdx.plane() + 3][ui8x8Idx] = 16;
for( ui = 1; ui < 16; ui++ )
if( !( m_aapaucChromaACCoefMap[cCIdx.plane()][ui][ui8x8Idx] & (SIGNIFICANT|CODED) ) && m_apaucScanPosMap[cCIdx.plane() + 3][ui8x8Idx] == 16 )
m_apaucScanPosMap[cCIdx.plane() + 3][ui8x8Idx] = ui;
m_apaucChromaACBlockMap[cCIdx.plane()][ui8x8Idx] &= ~CODED;
}
}
}
return Err::m_nOK;
}
ErrVal
FGSCoder::xUpdateMacroblock( MbDataAccess& rcMbDataAccessBL,
MbDataAccess& rcMbDataAccessEL,
UInt uiMbY,
UInt uiMbX )
{
UInt uiExtCbp = 0;
Bool b8x8 = rcMbDataAccessBL.getMbData().isTransformSize8x8();
UInt uiMbIndex = uiMbY*m_uiWidthInMB + uiMbX;
if( ! rcMbDataAccessBL.getMbData().isIntra() && ! rcMbDataAccessEL.getMbData().getBLSkipFlag() )
{
//----- update motion parameters -----
rcMbDataAccessBL.getMbData().copyFrom ( rcMbDataAccessEL.getMbData() );
rcMbDataAccessBL.getMbData().copyMotion( rcMbDataAccessEL.getMbData() );
}
//===== luma =====
if( b8x8 )
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
Bool bSig = false;
TCoeff* piCoeffBL = rcMbDataAccessBL.getMbTCoeffs().get8x8( c8x8Idx );
TCoeff* piCoeffEL = rcMbDataAccessEL.getMbTCoeffs().get8x8( c8x8Idx );
for( UInt ui8x8ScanIdx = 0; ui8x8ScanIdx < 64; ui8x8ScanIdx++ )
{
UInt uiPos = g_aucFrameScan64[ui8x8ScanIdx];
UInt ui4x4ScanIdx = ui8x8ScanIdx / 4;
UInt uiBlk4x4Idx = ui8x8ScanIdx % 4;
UInt uiBlockIndex = (4*uiMbY+c8x8Idx.y()+(uiBlk4x4Idx/2))*4*m_uiWidthInMB + (4*uiMbX+c8x8Idx.x()+(uiBlk4x4Idx%2));
if( m_apaucLumaCoefMap[ui4x4ScanIdx][uiBlockIndex] & CODED )
{
xUpdateCoeffMap(piCoeffBL[uiPos], piCoeffEL[uiPos], m_apaucLumaCoefMap[ui4x4ScanIdx][uiBlockIndex]);
}
if( piCoeffBL[uiPos] )
{
bSig = true;
}
}
if( bSig )
{
uiExtCbp |= ( 0x33 << c8x8Idx.b4x4() );
}
}
}
else
{
for( B4x4Idx c4x4Idx; c4x4Idx.isLegal(); c4x4Idx++ )
{
Bool bSig = false;
TCoeff* piCoeffBL = rcMbDataAccessBL.getMbTCoeffs().get( c4x4Idx );
TCoeff* piCoeffEL = rcMbDataAccessEL.getMbTCoeffs().get( c4x4Idx );
for( UInt uiScanIdx = 0; uiScanIdx < 16; uiScanIdx++ )
{
UInt uiPos = g_aucFrameScan[uiScanIdx];
UInt uiBlockIndex = (4*uiMbY+c4x4Idx.y())*4*m_uiWidthInMB + (4*uiMbX+c4x4Idx.x());
if( m_apaucLumaCoefMap[uiScanIdx][uiBlockIndex] & CODED )
{
xUpdateCoeffMap(piCoeffBL[uiPos], piCoeffEL[uiPos], m_apaucLumaCoefMap[uiScanIdx][uiBlockIndex]);
}
if( piCoeffBL[uiPos] )
{
bSig = true;
}
}
if( bSig )
{
uiExtCbp |= ( 1 << c4x4Idx );
}
}
}
//===== chroma DC =====
Bool bSigDC = false;
for( UInt uiPlane = 0; uiPlane < 2; uiPlane++ )
{
TCoeff* piCoeffBL = rcMbDataAccessBL.getMbTCoeffs().get( CIdx(4*uiPlane) );
TCoeff* piCoeffEL = rcMbDataAccessEL.getMbTCoeffs().get( CIdx(4*uiPlane) );
for( UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
{
UInt uiPos = g_aucIndexChromaDCScan[uiDCIdx];
if( m_aapaucChromaDCCoefMap[uiPlane][uiDCIdx][uiMbIndex] & CODED)
{
xUpdateCoeffMap(piCoeffBL[uiPos], piCoeffEL[uiPos], m_aapaucChromaDCCoefMap[uiPlane][uiDCIdx][uiMbIndex]);
}
if( piCoeffBL[uiPos] )
{
bSigDC = true;
}
}
}
//===== chroma AC =====
Bool bSigAC = false;
for( CIdx cCIdx; cCIdx.isLegal(); cCIdx++ )
{
TCoeff* piCoeffBL = rcMbDataAccessBL.getMbTCoeffs().get( cCIdx );
TCoeff* piCoeffEL = rcMbDataAccessEL.getMbTCoeffs().get( cCIdx );
for( UInt uiScanIdx = 1; uiScanIdx < 16; uiScanIdx++ )
{
UInt uiPos = g_aucFrameScan[uiScanIdx];
UInt ui8x8Idx = (2*uiMbY+cCIdx.y())*2*m_uiWidthInMB + (2*uiMbX+cCIdx.x());
if( m_aapaucChromaACCoefMap[cCIdx.plane()][uiScanIdx][ui8x8Idx] & CODED )
{
xUpdateCoeffMap(piCoeffBL[uiPos], piCoeffEL[uiPos], m_aapaucChromaACCoefMap[cCIdx.plane()][uiScanIdx][ui8x8Idx]);
}
if( piCoeffBL[uiPos] )
{
bSigAC = true;
}
}
}
//===== set CBP =====
UInt uiChromaCBP = ( bSigAC ? 2 : bSigDC ? 1 : 0 );
uiExtCbp |= ( uiChromaCBP << 16 );
rcMbDataAccessBL.getMbData().setAndConvertMbExtCbp( uiExtCbp );
//===== set QP =====
Int iELQP = rcMbDataAccessEL.getMbData().getQp();
Int iNumCoded = ( m_pauiMacroblockMap[uiMbIndex] >> NUM_COEFF_SHIFT );
Int iQPDelta = ( 384 - iNumCoded ) / 64;
Int iQP = min( 51, iELQP + iQPDelta );
if( ! ( m_pauiMacroblockMap[uiMbIndex] & SIGNIFICANT ) )
{
iQP = rcMbDataAccessEL.getSH().getPicQp();
}
rcMbDataAccessBL.getMbData().setQp( iQP );
return Err::m_nOK;
}
ErrVal
FGSCoder::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
FGSCoder::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
FGSCoder::xScaleTCoeffs( MbDataAccess& rcMbDataAccess,
Bool bBaseLayer )
{
const Int aaiDequantDcCoef[6] = { 10, 11, 13, 14, 16, 18 };
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 );
Int iScale = 1;
//===== luma =====
if( b16x16 )
{
//===== INTRA_16x16 =====
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( xScale4x4Block( rcMbDataAccess.getMbTCoeffs().get ( cIdx ), pucScaleY, 1, cLQp ) );
}
iScale = aaiDequantDcCoef[cLQp.rem()] << cLQp.per();
if( pucScaleY )
{
iScale *= pucScaleY[0];
iScale >>= 4;
}
// perform scaling only
TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( B4x4Idx(0) );
for( Int uiDCIdx = 0; uiDCIdx < 16; uiDCIdx++ )
piCoeff[16*uiDCIdx] *= iScale;
//===== correct CBP =====
rcMbDataAccess.getMbData().setMbCbp( rcMbDataAccess.getAutoCbp() );
}
else if( b8x8 )
{
//===== 8x8 BLOCKS =====
for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( xScale8x8Block( rcMbDataAccess.getMbTCoeffs().get8x8( cIdx ), pucScaleY, cLQp ) );
}
}
else
{
//===== 4x4 BLOCKS =====
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( xScale4x4Block( rcMbDataAccess.getMbTCoeffs().get ( cIdx ), pucScaleY, 0, cLQp ) );
}
}
//===== chroma =====
for( CIdx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( xScale4x4Block( rcMbDataAccess.getMbTCoeffs().get( cIdx ), ( cIdx.plane() ? pucScaleV : pucScaleU ), 1, cCQp ) );
}
// only performs scaling, not inverse transform
UInt uiMbIndex = rcMbDataAccess.getMbY()*m_uiWidthInMB+rcMbDataAccess.getMbX();
for( UInt uiPlane = 0; uiPlane < 2; uiPlane++ )
{
TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( CIdx(4*uiPlane) );
iScale = 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( UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
{
if(! bBaseLayer && ! ( m_aapaucChromaDCCoefMap[uiPlane][uiDCIdx][uiMbIndex] & CODED ) )
// condition "! bBaseLayer" is needed. When "xScaleTCoeffs is called
// before first FGS layer, m_aapaucChromaDCCoefMap is not initialized
piCoeff[16*uiDCIdx] = 0;
else
piCoeff[16*uiDCIdx] *= iScale;
}
}
return Err::m_nOK;
}
ErrVal
FGSCoder::xReconstructMacroblock( MbDataAccess& rcMbDataAccess,
IntYuvMbBuffer& rcMbBuffer )
{
m_pcTransform->setClipMode( false );
Int iLStride = rcMbBuffer.getLStride();
Int iCStride = rcMbBuffer.getCStride();
Bool b8x8 = rcMbDataAccess.getMbData().isTransformSize8x8();
MbTransformCoeffs& rcCoeffs = rcMbDataAccess.getMbTCoeffs();
rcMbBuffer.loadBuffer( m_pcBaseLayerSbb->getFullPelYuvBuffer() );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?