fgscoder.cpp
来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,684 行 · 第 1/5 页
CPP
1,684 行
TCoeff lumaDcCoeffs[16];
if ( rcMbDataAccess.getMbData().isIntra16x16() )
{
// backup luma DC
TCoeff *piCoeffs;
UInt uiDCIdx;
piCoeffs = rcCoeffs.get( B4x4Idx(0) );
for( uiDCIdx = 0; uiDCIdx < 16; uiDCIdx++ )
lumaDcCoeffs[uiDCIdx] = piCoeffs[16*uiDCIdx] ;
// inverse transform on luma DC
RNOK( m_pcTransform->invTransformDcCoeff( piCoeffs, 1 ) );
// inverse transform on entire MB
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( m_pcTransform->invTransform4x4Blk( rcMbBuffer.getYBlk( cIdx ), iLStride, rcCoeffs.get( cIdx ) ) );
}
// restore luma DC
for( uiDCIdx = 0; uiDCIdx < 16; uiDCIdx++ )
piCoeffs[16*uiDCIdx] = lumaDcCoeffs[uiDCIdx];
}
else if( b8x8 )
{
for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( m_pcTransform->invTransform8x8Blk( rcMbBuffer.getYBlk( cIdx ), iLStride, rcCoeffs.get8x8( cIdx ) ) );
}
}
else
{
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
RNOK( m_pcTransform->invTransform4x4Blk( rcMbBuffer.getYBlk( cIdx ), iLStride, rcCoeffs.get( cIdx ) ) );
}
}
TCoeff chromaDcCoeffs[2][4];
UInt uiPlane;
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 );
// backup chroma DC coefficients
for( uiPlane = 0; uiPlane < 2; uiPlane++ )
{
TCoeff* piCoeff = rcCoeffs.get( CIdx(4*uiPlane) );
for( UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
chromaDcCoeffs[uiPlane][uiDCIdx] = piCoeff[16*uiDCIdx];
}
// 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( rcMbBuffer.getMbCbAddr(), iCStride, rcCoeffs.get( CIdx(0) ) ) );
RNOK( m_pcTransform->invTransformChromaBlocks( rcMbBuffer.getMbCrAddr(), iCStride, rcCoeffs.get( CIdx(4) ) ) );
// restore chroma DC coefficients
for( uiPlane = 0; uiPlane < 2; uiPlane++ )
{
TCoeff* piCoeff = rcCoeffs.get( CIdx(4*uiPlane) );
for( UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
piCoeff[16*uiDCIdx] = chromaDcCoeffs[uiPlane][uiDCIdx];
}
m_pcTransform->setClipMode( true );
return Err::m_nOK;
}
Int
FGSCoder::xScaleLevel4x4( Int iLevel,
Int iIndex,
const QpParameter& cQP,
const QpParameter& cBaseQP )
{
Int iSign = ( iLevel < 0 ? -1 : 1 );
Int iBaseScale = g_aaiDequantCoef[cBaseQP.rem()][iIndex] << cBaseQP.per();
Int iScale = g_aaiDequantCoef[cQP .rem()][iIndex] << cQP .per();
return iSign * ( ( abs(iLevel) * iBaseScale ) + ( iScale >> 1 ) ) / iScale;
}
Int
FGSCoder::xScaleLevel8x8( Int iLevel,
Int iIndex,
const QpParameter& cQP,
const QpParameter& cBaseQP )
{
Int iSign = ( iLevel < 0 ? -1 : 1 );
Int iBaseScale = g_aaiDequantCoef64[cBaseQP.rem()][iIndex] << cBaseQP.per();
Int iScale = g_aaiDequantCoef64[cQP .rem()][iIndex] << cQP .per();
return iSign * ( ( abs(iLevel) * iBaseScale ) + ( iScale >> 1 ) ) / iScale;
}
ErrVal
FGSCoder::xScaleSymbols4x4( TCoeff* piCoeff,
const QpParameter& cQP,
const QpParameter& cBaseQP )
{
for( Int iIndex = 0; iIndex < 16; iIndex++ )
{
if( piCoeff[iIndex] )
{
piCoeff[iIndex] = xScaleLevel4x4( piCoeff[iIndex], iIndex, cQP, cBaseQP );
}
}
return Err::m_nOK;
}
ErrVal
FGSCoder::xScaleSymbols8x8( TCoeff* piCoeff,
const QpParameter& cQP,
const QpParameter& cBaseQP )
{
for( Int iIndex = 0; iIndex < 64; iIndex++ )
{
if( piCoeff[iIndex] )
{
piCoeff[iIndex] = xScaleLevel8x8( piCoeff[iIndex], iIndex, cQP, cBaseQP );
}
}
return Err::m_nOK;
}
ErrVal
FGSCoder::xUpdateSymbols( TCoeff* piCoeff,
TCoeff* piCoeffEL,
Bool& bSigDC,
Bool& bSigAC,
Int iNumCoeff )
{
piCoeff [0] += piCoeffEL[0];
if( piCoeff [0] )
{
bSigDC = true;
}
for( Int iIndex = 1; iIndex < iNumCoeff; iIndex++ )
{
piCoeff [iIndex] += piCoeffEL[iIndex];
if( piCoeff[iIndex] )
{
bSigAC = true;
}
}
return Err::m_nOK;
}
// get 4x4 significance map for luma
Void FGSCoder::getCoeffSigMap( UInt uiMbX, UInt uiMbY, S4x4Idx cIdx, UChar *pucSigMap )
{
UInt uiBlockIndex = (uiMbY * 4 + cIdx.y()) * m_uiWidthInMB * 4 + uiMbX * 4 + cIdx.x();
for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
{
pucSigMap[g_aucFrameScan[uiScanIndex]] =
SIGNIFICANT & m_apaucLumaCoefMap[uiScanIndex][uiBlockIndex];
}
}
// get 8x8 significance map for luma
Void FGSCoder::getCoeffSigMap( UInt uiMbX, UInt uiMbY, B8x8Idx c8x8Idx, UChar *pucSigMap )
{
UInt auiBlockIdx[4] = { ( 4*uiMbY + c8x8Idx.y() ) * 4 * m_uiWidthInMB + ( 4*uiMbX + c8x8Idx.x() ),
( 4*uiMbY + c8x8Idx.y() ) * 4 * m_uiWidthInMB + ( 4*uiMbX + c8x8Idx.x() + 1 ),
( 4*uiMbY + c8x8Idx.y() + 1 ) * 4 * m_uiWidthInMB + ( 4*uiMbX + c8x8Idx.x() ),
( 4*uiMbY + c8x8Idx.y() + 1 ) * 4 * m_uiWidthInMB + ( 4*uiMbX + c8x8Idx.x() + 1 ) };
for( UInt ui8x8ScanIndex = 0; ui8x8ScanIndex < 64; ui8x8ScanIndex ++ )
{
UInt uiS = ui8x8ScanIndex/4;
UInt uiB = auiBlockIdx[ui8x8ScanIndex % 4];
pucSigMap[g_aucFrameScan64[ui8x8ScanIndex]] =
SIGNIFICANT & m_apaucLumaCoefMap[uiS][uiB];
}
}
// get 4x4 significance map for chroma
Void FGSCoder::getCoeffSigMap( UInt uiMbX, UInt uiMbY, CIdx cIdx, UChar *pucSigMap )
{
UInt uiPlane = cIdx.plane();
UInt uiMbIndex = uiMbY * m_uiWidthInMB + uiMbX;
UInt uiBlockIndex = (uiMbY * 2 + cIdx.y()) * m_uiWidthInMB * 2 + uiMbX * 2 + cIdx.x();
for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
{
pucSigMap[g_aucFrameScan[uiScanIndex]] =
SIGNIFICANT & ((uiScanIndex == 0) ?
m_aapaucChromaDCCoefMap[uiPlane][cIdx.y() * 2 + cIdx.x()][uiMbIndex]
: m_aapaucChromaACCoefMap[cIdx.plane()][uiScanIndex][uiBlockIndex]);
}
}
// get entire 8x8 significance map for chroma
Void FGSCoder::getCoeffSigMapChroma8x8( UInt uiMbX, UInt uiMbY, UInt uiPlane, UChar *pucSigMap )
{
UInt uiMbIndex = uiMbY * m_uiWidthInMB + uiMbX;
UInt uiBeginIdx, uiEndIdx;
uiBeginIdx = (uiPlane == 0) ? 0 : 4;
uiEndIdx = uiBeginIdx + 4;
for( CIdx cIdx(uiBeginIdx); cIdx.isLegal(uiEndIdx); cIdx ++ )
{
UInt uiBlockIndex = (uiMbY * 2 + cIdx.y()) * m_uiWidthInMB * 2 + uiMbX * 2 + cIdx.x();
UInt uiBlockIdxWithMb = cIdx.y() * 2 + cIdx.x();
for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
{
pucSigMap[uiBlockIdxWithMb * 16 + g_aucFrameScan[uiScanIndex]] =
SIGNIFICANT & ((uiScanIndex == 0) ?
m_aapaucChromaDCCoefMap[uiPlane][uiBlockIdxWithMb][uiMbIndex]
: m_aapaucChromaACCoefMap[cIdx.plane()][uiScanIndex][uiBlockIndex]);
}
}
}
ErrVal
FGSCoder::xClearBaseCoeffs( MbDataAccess& rcMbDataAccess,
MbDataAccess* pcMbDataAccessBase )
{
UInt uiMbY = pcMbDataAccessBase->getMbY();
UInt uiMbX = pcMbDataAccessBase->getMbX();
UInt uiMbIndex = uiMbY * m_uiWidthInMB + uiMbX;
m_pauiMacroblockMap[uiMbIndex] = rcMbDataAccess.getSH().getPPS().getTransform8x8ModeFlag() && rcMbDataAccess.getMbData().is8x8TrafoFlagPresent() ? CLEAR : TRANSFORM_SPECIFIED;
//--- LUMA ---
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
UInt uiSubMbIndex = ( 2*uiMbY + c8x8Idx.y()/2 ) * 2 * m_uiWidthInMB + ( 2*uiMbX + c8x8Idx.x() / 2 );
//===== set sub-macroblock mode =====
m_paucSubMbMap[uiSubMbIndex] = CLEAR;
for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ )
{
UInt uiScanIndex;
UInt uiBlockIdx = ( 4*uiMbY + cIdx.y() ) * 4 * m_uiWidthInMB + ( 4*uiMbX + cIdx.x() );
//===== set transform coefficients =====
for( uiScanIndex = 0; uiScanIndex < 16; uiScanIndex++ )
{
m_apaucLumaCoefMap[uiScanIndex][uiBlockIdx] = CLEAR;
}
m_apaucScanPosMap[0][uiBlockIdx] = 16;
for( uiScanIndex = 0; uiScanIndex < 16; uiScanIndex++ )
{
if( !( m_apaucLumaCoefMap[uiScanIndex][uiBlockIdx] & (SIGNIFICANT|CODED) ) && m_apaucScanPosMap[0][uiBlockIdx] == 16 )
{
m_apaucScanPosMap[0][uiBlockIdx] = uiScanIndex;
}
}
//===== set block mode =====
m_paucBlockMap[uiBlockIdx] = CLEAR;
}
}
//--- CHROMA DC ---
for( UInt uiPlane = 0; uiPlane < 2; uiPlane++ )
{
UInt ui;
for( ui = 0; ui < 4; ui++ )
{
m_aapaucChromaDCCoefMap[uiPlane][ui][uiMbIndex] = CLEAR;
}
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] = CLEAR;
}
//--- 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] = CLEAR;
}
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] = CLEAR;
}
//pcMbDataAccessBase->getMbData().setMbCbp( 0 );
pcMbDataAccessBase->getMbTCoeffs().clear();
pcMbDataAccessBase->getMbData().setTransformSize8x8( false );
IntYuvMbBuffer cZeroBuffer;
cZeroBuffer.setAllSamplesToZero();
RNOK( m_pcBaseLayerSbb->getFullPelYuvBuffer()->loadBuffer( &cZeroBuffer ) );
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?