📄 transform.cpp
字号:
TCoeff* piCoeff,
const QpParameter& rcQp,
const UChar* pucScale,
UInt& ruiDcAbs,
UInt& ruiAcAbs )
{
Int iAdd = ( 1 << 3 ) >> rcQp.per();
{
Int iLevel = piCoeff[0];
UInt uiSign = ((UInt)iLevel)>>31;
iLevel = ( abs( iLevel ) * g_aaiQuantCoef[ rcQp.rem() ][0] );
if( pucScale )
{
iLevel = ( iLevel << 4 ) / pucScale[0];
}
iLevel = ( iLevel + 2*rcQp.add() ) >> ( rcQp.bits() + 1 );
ruiDcAbs += iLevel;
iLevel = ( uiSign ? -iLevel : iLevel );
piQCoeff[0] = iLevel;
// dequantize DC also
piCoeff [0] = iLevel * g_aaiDequantCoef[rcQp.rem()][0] << rcQp.per();
}
UInt uiAcAbs = 0;
for( int n = 1; n < 16; n++ )
{
Int iLevel = piCoeff[n];
Int iSign = iLevel;
iLevel = ( abs( iLevel ) * g_aaiQuantCoef[rcQp.rem()][n] );
if( pucScale )
{
iLevel = ( iLevel << 4 ) / pucScale[n];
}
iLevel = ( iLevel + rcQp.add() ) >> rcQp.bits();
if( 0 != iLevel )
{
iSign >>= 31;
Int iDeScale = g_aaiDequantCoef[rcQp.rem()][n];
uiAcAbs += iLevel;
iLevel ^= iSign;
iLevel -= iSign;
piQCoeff[n] = iLevel;
if( pucScale )
{
piCoeff[n] = ( ( iLevel*iDeScale*pucScale[n] + iAdd ) << rcQp.per() ) >> 4;
}
else
{
piCoeff[n] = iLevel*iDeScale << rcQp.per();
}
}
else
{
piQCoeff[n] = 0;
piCoeff[n] = 0;
}
}
ruiAcAbs += uiAcAbs;
return;
}
Void Transform::xQuantDequantUniform4x4( TCoeff* piQCoeff,
TCoeff* piCoeff,
const QpParameter& rcQp,
const UChar* pucScale,
UInt& ruiAbsSum )
{
Int n = 0;
ruiAbsSum = 0;
Int iAdd = ( 1 << 3 ) >> rcQp.per();
for( ; n < 16; n++ )
{
Int iLevel = piCoeff[n];
Int iSign = iLevel;
iLevel = abs( iLevel ) * g_aaiQuantCoef[rcQp.rem()][n];
if( pucScale )
{
iLevel = ( iLevel << 4 ) / pucScale[n];
}
iLevel = ( iLevel + rcQp.add() ) >> rcQp.bits();
if( 0 != iLevel )
{
iSign >>= 31;
Int iDeScale = g_aaiDequantCoef[ rcQp.rem() ][ n ];
ruiAbsSum += iLevel;
iLevel ^= iSign;
iLevel -= iSign;
piQCoeff[n] = iLevel;
if( pucScale )
{
piCoeff[n] = ( ( iLevel*iDeScale*pucScale[n] + iAdd ) << rcQp.per() ) >> 4;
}
else
{
piCoeff[n] = iLevel*iDeScale << rcQp.per();
}
}
else
{
piQCoeff[n] = 0;
piCoeff [n] = 0;
}
}
}
// for SVC to AVC rewrite
ErrVal Transform::predict4x4Blk( TCoeff* piCoeff, TCoeff* piRefCoeff, UInt uiRefQp, UInt& ruiAbsSum )
{
// DECLARATIONS
TCoeff cPredCoeff[16];
// PREDICT THE COEFFICIENTS
ScaleCoeffLevels( cPredCoeff, piRefCoeff, getLumaQp().value(), uiRefQp, 16 );
// ADJUST THE TRANSMITTED COEFFICIENTS
for( Int n=0; n<16; n++ )
{
ruiAbsSum -= (piCoeff[n] >0) ? piCoeff[n].getCoeff() : (-1*piCoeff[n].getCoeff());
piCoeff[n] -= cPredCoeff[n];
ruiAbsSum += (piCoeff[n]>0) ? piCoeff[n].getCoeff() : (-1*piCoeff[n].getCoeff());
}
return Err::m_nOK;
}
ErrVal Transform::predict8x8Blk( TCoeff* piCoeff, TCoeff* piRefCoeff, UInt uiRefQp, UInt& ruiAbsSum )
{
// DECLARATIONS
TCoeff cPredCoeff[64];
// PREDICT THE COEFFICIENTS
ScaleCoeffLevels( cPredCoeff, piRefCoeff, getLumaQp().value(), uiRefQp, 64 );
// ADJUST THE TRANSMITTED COEFFICIENTS
for( Int n=0; n<64; n++ )
{
ruiAbsSum -= (piCoeff[n] >0) ? piCoeff[n].getCoeff() : -1*piCoeff[n].getCoeff();
piCoeff[n] -= cPredCoeff[n];
ruiAbsSum += (piCoeff[n]>0) ? piCoeff[n].getCoeff() : -1*piCoeff[n].getCoeff();
}
return Err::m_nOK;
}
ErrVal Transform::predictMb16x16( TCoeff* piCoeff, TCoeff* piRef, UInt uiRefQp, UInt& ruiDcAbs, UInt& ruiAcAbs )
{
UInt uiAbs = 0;
for( UInt n=0; n<16; n++ )
predict4x4Blk( &piCoeff[n<<4], &piRef[n<<4], uiRefQp, uiAbs );
return Err::m_nOK;
}
ErrVal Transform::predictChromaBlocks( TCoeff* piCoeff, TCoeff* piRef, UInt uiRefQp, UInt& ruiDcAbs, UInt& ruiAcAbs )
{
// DECLARATIONS
TCoeff cScaledRef[64];
int i;
for( UInt x=0; x<0x40; x+=0x10 )
{
ScaleCoeffLevels( &cScaledRef[x], &piRef[x], getChromaQp().value(), uiRefQp, 16 );
for( UInt n=0; n<16; n++ )
{
piCoeff[x+n] -= cScaledRef[x+n];
}
}
// RECOMPUTE THE COEFFICIENT COUNTS
ruiAcAbs = 0;
ruiDcAbs = 0;
for(i=0; i<64; i++ )
ruiAcAbs += abs( (Int)piCoeff[i] );
for( i=0; i<64; i+=16 )
ruiDcAbs += abs( (Int)piCoeff[i] );
ruiAcAbs -= ruiDcAbs;
return Err::m_nOK;
}
ErrVal
Transform::predictScaledACCoeffs( TCoeff *piCoeff,
TCoeff *piRef,
UInt uiRefQp )
{
// DECLARATIONS
TCoeff cPredCoeff[64] = {0};
UInt uiDcAbs=0, uiAcAbs=0;
// Predict the chroma coefficients
predictChromaBlocks( cPredCoeff, piRef, uiRefQp, uiDcAbs, uiAcAbs );
for( UInt i=0; i<64; i++ )
cPredCoeff[i] = -cPredCoeff[i];
// Scale the coefficients
x4x4Dequant( &cPredCoeff[0x00], &cPredCoeff[0x00], m_cChromaQp );
x4x4Dequant( &cPredCoeff[0x10], &cPredCoeff[0x10], m_cChromaQp );
x4x4Dequant( &cPredCoeff[0x20], &cPredCoeff[0x20], m_cChromaQp );
x4x4Dequant( &cPredCoeff[0x30], &cPredCoeff[0x30], m_cChromaQp );
// Substitute
for( UInt x=0x00; x<0x40; x+=0x10 )
for( UInt n=1; n<16; n++ )
piCoeff[x+n] = cPredCoeff[x+n];
return Err::m_nOK;
}
ErrVal
Transform::predictScaledChromaCoeffs( TCoeff *piCoeff, TCoeff *piRef, UInt uiRefQp )
{
// DECLARATIONS
TCoeff cPredCoeff[0x80] = {0};
UInt uiDcAbs=0, uiAcAbs=0;
// Predict the chroma coefficients
predictChromaBlocks( cPredCoeff+0x00, piRef+0x00, uiRefQp, uiDcAbs, uiAcAbs );
predictChromaBlocks( cPredCoeff+0x40, piRef+0x40, uiRefQp, uiDcAbs, uiAcAbs );
for( UInt uiBlkOff = 0x00; uiBlkOff < 0x80; uiBlkOff += 0x10 )
{
TCoeff* piPredBlk = cPredCoeff + uiBlkOff;
TCoeff* piCoefBlk = piCoeff + uiBlkOff;
for( UInt i0 = 0; i0 < 16; i0++ )
{
piPredBlk[i0] = -piPredBlk[i0];
}
x4x4Dequant( piPredBlk, piPredBlk, m_cChromaQp );
for( UInt i1 = 0; i1 < 16; i1++ )
{
piCoefBlk[i1] = piPredBlk[i1];
}
}
return Err::m_nOK;
}
ErrVal Transform::addPrediction4x4Blk( TCoeff* piCoeff, TCoeff* piRefCoeff, UInt uiQp, UInt uiRefQp, UInt &uiCoded )
{
// DECLARATIONS
TCoeff cPredCoeff[16];
// PREDICT THE COEFFICIENTS
ScaleCoeffLevels( cPredCoeff, piRefCoeff, uiQp, uiRefQp, 16 );
// ADJUST THE TRANSMITTED COEFFICIENTS
for( Int n=0; n<16; n++ )
{
piCoeff[n] += cPredCoeff[n];
if( piCoeff[n] )
uiCoded++;
}
return Err::m_nOK;
}
ErrVal Transform::addPrediction8x8Blk( TCoeff* piCoeff, TCoeff* piRefCoeff, UInt uiQp, UInt uiRefQp, Bool& bCoded )
{
// DECLARATIONS
TCoeff cPredCoeff[64];
// PREDICT THE COEFFICIENTS
ScaleCoeffLevels( cPredCoeff, piRefCoeff, uiQp, uiRefQp, 64 );
// ADJUST THE TRANSMITTED COEFFICIENTS
for( Int n=0; n<64; n++ )
{
piCoeff[n] += cPredCoeff[n];
if( piCoeff[n] )
bCoded = true;
}
return Err::m_nOK;
}
ErrVal Transform::addPredictionChromaBlocks( TCoeff* piCoeff, TCoeff* piRef, UInt uiQp, UInt uiRefQp, Bool& bDCflag, Bool& bACflag )
{
// DECLARATIONS
TCoeff cScaledRef[64];
for( UInt x=0; x<0x40; x+=0x10 )
{
ScaleCoeffLevels( &cScaledRef[x], &piRef[x], uiQp, uiRefQp, 16 );
for( UInt n=0; n<16; n++ )
{
piCoeff[x+n] += cScaledRef[x+n];
if( piCoeff[x+n] )
{
if( n%16 )
bACflag = true;
else
bDCflag = true;
}
}
}
return Err::m_nOK;
}
ErrVal Transform::invTransformChromaBlocks( Pel* puc, Int iStride, TCoeff* piCoeff )
{
xInvTransform4x4Blk( puc, iStride, piCoeff + 0x00 );
xInvTransform4x4Blk( puc + 4, iStride, piCoeff + 0x10 );
puc += iStride << 2;
xInvTransform4x4Blk( puc, iStride, piCoeff + 0x20 );
xInvTransform4x4Blk( puc + 4, iStride, piCoeff + 0x30 );
return Err::m_nOK;
}
ErrVal Transform::transform4x4Blk( YuvMbBuffer* pcOrgData,
YuvMbBuffer* pcPelData,
TCoeff* piCoeff,
const UChar* pucScale,
UInt& ruiAbsSum )
{
TCoeff aiTemp[64];
XPel* pOrg = pcOrgData->getLumBlk();
XPel* pRec = pcPelData->getLumBlk();
Int iStride = pcPelData->getLStride();
xForTransform4x4Blk( pOrg, pRec, iStride, aiTemp );
xQuantDequantUniform4x4( piCoeff, aiTemp, m_cLumaQp, pucScale, ruiAbsSum );
if (m_storeCoeffFlag) // store the coefficients
{
for( UInt ui=0; ui<16; ui++ )
piCoeff[ui].setLevel( piCoeff[ui].getCoeff() * (g_aaiDequantCoef[m_cLumaQp.rem()][ui] << m_cLumaQp.per()) );
}
ROTRS( 0 == ruiAbsSum, Err::m_nOK );
xInvTransform4x4Blk( pRec, iStride, aiTemp );
return Err::m_nOK;
}
ErrVal
Transform::transform8x8BlkCGS( YuvMbBuffer* pcOrgData,
YuvMbBuffer* pcPelData,
TCoeff* piCoeff,
TCoeff* piCoeffBase,
const UChar* pucScale,
UInt& ruiAbsSum )
{
TCoeff aiTemp[64];
Int normAdjust[] = { 8, 9, 5, 9, 8, 9, 5, 9 };
XPel* pOrg = pcOrgData->getLumBlk();
XPel* pRec = pcPelData->getLumBlk();
Int iStride = pcPelData->getLStride();
xForTransform8x8Blk ( pOrg, pRec, iStride, aiTemp );
UInt ui=0;
// get the baselayer coefficients
for( ui=0; ui<64; ui++ )
aiTemp[ui] = ( aiTemp[ui].getCoeff() - ( ( normAdjust[ui/8]*normAdjust[ui%8]*(Int)piCoeffBase[ui].getLevel() + (1<<5) ) >> 6 ) );
xQuantDequantUniform8x8 ( piCoeff, aiTemp, m_cLumaQp, pucScale, ruiAbsSum );
// add the base layer coeff back
for( ui=0; ui<64; ui++ )
{
aiTemp[ui] = piCoeffBase[ui].getLevel() + aiTemp[ui].getCoeff();
// store the coefficients
if (m_storeCoeffFlag)
piCoeff[ui].setLevel( aiTemp[ui].getCoeff() );
}
invTransform8x8Blk ( pRec, iStride, aiTemp );
return Err::m_nOK;
}
ErrVal Transform::transform4x4BlkCGS( YuvMbBuffer* pcOrgData,
YuvMbBuffer* pcPelData,
TCoeff* piCoeff,
TCoeff* piCoeffBase,
const UChar* pucScale,
UInt& ruiAbsSum )
{
TCoeff aiTemp[64];
Int normAdjust[] = { 4, 5, 4, 5 };
XPel* pOrg = pcOrgData->getLumBlk();
XPel* pRec = pcPelData->getLumBlk();
Int iStride = pcPelData->getLStride();
xForTransform4x4Blk( pOrg, pRec, iStride, aiTemp );
UInt ui=0;
// get the baselayer coefficients
for( ui=0; ui<16; ui++ )
aiTemp[ui] = ( aiTemp[ui].getCoeff() - ( ( normAdjust[ui/4]*normAdjust[ui%4]*(Int)piCoeffBase[ui].getLevel() + (1<<5) ) >> 6 ) );
xQuantDequantUniform4x4( piCoeff, aiTemp, m_cLumaQp, pucScale, ruiAbsSum );
// add the base layer coeff back
for( ui=0; ui<16; ui++ )
{
aiTemp[ui] = piCoeffBase[ui].getLevel() + aiTemp[ui].getCoeff();
// store the coefficients
if (m_storeCoeffFlag)
piCoeff[ui].setLevel( aiTemp[ui].getCoeff() );
}
xInvTransform4x4Blk( pRec, iStride, aiTemp );
return Err::m_nOK;
}
Void Transform::xForTransform4x4Blk( XPel* pucOrg, XPel* pucRec, Int iStride, TCoeff* piPredCoeff )
{
Int aai[4][4];
Int tmp1, tmp2;
for( Int y = 0; y < 4; y++ )
{
Int ai[4];
ai[0] = pucOrg[0] - pucRec[0];
ai[1] = pucOrg[1] - pucRec[1];
ai[2] = pucOrg[2] - pucRec[2];
ai[3] = pucOrg[3] - pucRec[3];
tmp1 = ai[0] + ai[3];
tmp2 = ai[1] + ai[2];
aai[0][y] = tmp1 + tmp2;
aai[2][y] = tmp1 - tmp2;
tmp1 = ai[0] - ai[3];
tmp2 = ai[1] - ai[2];
aai[1][y] = tmp1 * 2 + tmp2 ;
aai[3][y] = tmp1 - tmp2 * 2;
pucRec += iStride;
pucOrg += iStride;
}
for( Int x = 0; x < 4; x++, piPredCoeff++ )
{
tmp1 = aai[x][0] + aai[x][3];
tmp2 = aai[x][1] + aai[x][2];
piPredCoeff[0] = tmp1 + tmp2;
piPredCoeff[8] = tmp1 - tmp2;
tmp1 = aai[x][0] - aai[x][3];
tmp2 = aai[x][1] - aai[x][2];
piPredCoeff[4] = tmp1 * 2 + tmp2;
piPredCoeff[12] = tmp1 - tmp2 * 2;
}
}
Void Transform::xInvTransform4x4Blk( XPel* puc, Int iStride, TCoeff* piCoeff )
{
Int aai[4][4];
Int tmp1, tmp2;
Int x, y;
Int iStride2=2*iStride;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -