📄 transform.cpp
字号:
Int iStride3=3*iStride;
for( x = 0; x < 4; x++, piCoeff+=4 )
{
tmp1 = piCoeff[0] + piCoeff[2];
tmp2 = (piCoeff[3]>>1) + piCoeff[1];
aai[0][x] = tmp1 + tmp2;
aai[3][x] = tmp1 - tmp2;
tmp1 = piCoeff[0] - piCoeff[2];
tmp2 = (piCoeff[1]>>1) - piCoeff[3];
aai[1][x] = tmp1 + tmp2;
aai[2][x] = tmp1 - tmp2;
}
for( y = 0; y < 4; y++, puc ++ )
{
tmp1 = aai[y][0] + aai[y][2];
tmp2 = (aai[y][3]>>1) + aai[y][1];
puc[0] = xClip( xRound( tmp1 + tmp2) + puc[0] );
puc[iStride3] = xClip( xRound( tmp1 - tmp2) + puc[iStride3] );
tmp1 = aai[y][0] - aai[y][2];
tmp2 = (aai[y][1]>>1) - aai[y][3];
puc[iStride] = xClip( xRound( tmp1 + tmp2) + puc[iStride] );
puc[iStride2] = xClip( xRound( tmp1 - tmp2) + puc[iStride2] );
}
}
ErrVal Transform::transformMb16x16( YuvMbBuffer* pcOrgData, YuvMbBuffer* pcPelData, TCoeff* piCoeff, const UChar* pucScale, UInt& ruiDcAbs, UInt& ruiAcAbs )
{
XPel* pucOrg = pcOrgData->getMbLumAddr();
XPel* pucRec = pcPelData->getMbLumAddr();
Int iStride = pcPelData->getLStride();
TCoeff aiCoeff[256];
Int x, n;
Int iOffset = 0;
for( n = 0; n < 16; n+=4 )
{
for( x = 0; x < 4; x++ )
{
UInt uiBlk = x+n;
Int iOffsetBlk = iOffset + (x << 2);
xForTransform4x4Blk( pucOrg + iOffsetBlk, pucRec + iOffsetBlk, iStride, &aiCoeff[uiBlk<<4] );
}
iOffset += iStride << 2;
}
xForTransformLumaDc( aiCoeff );
for( n = 0; n < 16; n ++ )
{
xQuantDequantNonUniformLuma( &piCoeff[n<<4], &aiCoeff[n<<4], m_cLumaQp, pucScale, ruiDcAbs, ruiAcAbs );
}
for( n = 0; n < 16; n ++ )
{
aiCoeff[n<<4] = piCoeff[n<<4];
}
Int iQpScale = ( g_aaiDequantCoef[m_cLumaQp.rem()][0] << m_cLumaQp.per() );
if( pucScale )
{
iQpScale = ( iQpScale * pucScale[0] ) >> 4;
}
invTransformDcCoeff( aiCoeff, iQpScale );
iOffset = 0;
for( n = 0; n < 16; n += 4 )
{
for( x = 0; x < 4; x++ )
{
UInt uiBlk = x+n;
Int iOffsetBlk = iOffset + (x << 2);
xInvTransform4x4Blk( pucRec + iOffsetBlk, iStride, &aiCoeff[uiBlk<<4] );
}
iOffset += iStride << 2;
}
for( x = 0; x < 256; x++ )
{
piCoeff[x].setLevel( aiCoeff[x].getCoeff() );
}
return Err::m_nOK;
}
ErrVal Transform::transformChromaBlocks( XPel* pucOrg,
XPel* pucRec,
const CIdx cCIdx,
Int iStride,
TCoeff* piCoeff,
TCoeff* piQuantCoeff,
const UChar* pucScale,
UInt& ruiDcAbs,
UInt& ruiAcAbs )
{
Int iOffset = 0;
xForTransform4x4Blk( pucOrg + iOffset, pucRec + iOffset, iStride, piQuantCoeff + 0x00);
iOffset += 4;
xForTransform4x4Blk( pucOrg + iOffset, pucRec + iOffset, iStride, piQuantCoeff + 0x10);
iOffset = 4*iStride;
xForTransform4x4Blk( pucOrg + iOffset, pucRec + iOffset, iStride, piQuantCoeff + 0x20);
iOffset += 4;
xForTransform4x4Blk( pucOrg + iOffset, pucRec + iOffset, iStride, piQuantCoeff + 0x30);
xForTransformChromaDc( piQuantCoeff );
xQuantDequantNonUniformChroma( piCoeff + 0x00, piQuantCoeff + 0x00, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x10, piQuantCoeff + 0x10, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x20, piQuantCoeff + 0x20, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x30, piQuantCoeff + 0x30, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
if (m_storeCoeffFlag)
{
for( UInt ui=0; ui<64; ui++ )
{
piCoeff[ui].setLevel( piQuantCoeff[ui].getCoeff() ); // store the dequantized coeffs in TCoeff.level
}
}
return Err::m_nOK;
}
ErrVal Transform::transformChromaBlocksCGS( XPel* pucOrg,
XPel* pucRec,
const CIdx cCIdx,
Int iStride,
TCoeff* piCoeff,
TCoeff* piQuantCoeff,
TCoeff* piCoeffBase,
const UChar* pucScale,
UInt& ruiDcAbs,
UInt& ruiAcAbs )
{
Int iOffset = 0;
Int normAdjust[] = { 4, 5, 4, 5};
xForTransform4x4Blk( pucOrg + iOffset, pucRec + iOffset, iStride, piQuantCoeff + 0x00);
iOffset += 4;
xForTransform4x4Blk( pucOrg + iOffset, pucRec + iOffset, iStride, piQuantCoeff + 0x10);
iOffset = 4*iStride;
xForTransform4x4Blk( pucOrg + iOffset, pucRec + iOffset, iStride, piQuantCoeff + 0x20);
iOffset += 4;
xForTransform4x4Blk( pucOrg + iOffset, pucRec + iOffset, iStride, piQuantCoeff + 0x30);
xForTransformChromaDc( piQuantCoeff );
// substract the baselayer coefficients
for( UInt uiOffset = 0; uiOffset<0x40; uiOffset+=0x10 )
{
piQuantCoeff[uiOffset+0] = ( piQuantCoeff[uiOffset+0].getCoeff() - ( ( piCoeffBase[uiOffset+0].getLevel() + 1) >> 1 ) );
for( UInt ui=1; ui<16; ui++ )
piQuantCoeff[uiOffset+ui] = ( piQuantCoeff[uiOffset+ui].getCoeff() - ( ( normAdjust[ui/4] * normAdjust[ui%4] * piCoeffBase[uiOffset+ui].getLevel() + (1<<5) ) >> 6 ) );
}
xQuantDequantNonUniformChroma( piCoeff + 0x00, piQuantCoeff + 0x00, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x10, piQuantCoeff + 0x10, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x20, piQuantCoeff + 0x20, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x30, piQuantCoeff + 0x30, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
// add the base layer coeff back and also store the dequantized coeffs
for( UInt ui=0; ui<64; ui++ )
{
piQuantCoeff[ui] = piCoeffBase[ui].getLevel() + piQuantCoeff[ui].getCoeff();
if (m_storeCoeffFlag)
piCoeff[ui].setLevel( piQuantCoeff[ui].getCoeff() );
}
return Err::m_nOK;
}
ErrVal Transform::invTransformChromaBlocks( XPel* 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::invTransform4x4Blk( XPel* puc, Int iStride, TCoeff* piCoeff )
{
xInvTransform4x4Blk( puc, iStride, piCoeff );
return Err::m_nOK;
}
ErrVal
Transform::transform8x8Blk( 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();
xForTransform8x8Blk ( pOrg, pRec, iStride, aiTemp );
xQuantDequantUniform8x8 ( piCoeff, aiTemp, m_cLumaQp, pucScale, ruiAbsSum );
if (m_storeCoeffFlag)
{
for( UInt ui=0; ui<64; ui++ )
piCoeff[ui].setLevel( aiTemp[ui].getCoeff() ); // store the dequantized coeffs are stored in TCoeff.level
}
invTransform8x8Blk ( pRec, iStride, aiTemp );
return Err::m_nOK;
}
ErrVal
Transform::invTransform8x8Blk( XPel* puc,
Int iStride,
TCoeff* piCoeff )
{
Int aai[8][8];
Int n;
for( n = 0; n < 8; n++ )
{
TCoeff* pi = piCoeff + n*8;
Int ai1[8];
Int ai2[8];
ai1[0] = pi[0] + pi[4];
ai1[2] = pi[0] - pi[4];
ai1[4] = (pi[2]>>1) - pi[6];
ai1[6] = pi[2] + (pi[6]>>1);
ai1[1] = pi[5] - pi[3] - pi[7] - (pi[7]>>1);
ai1[3] = pi[1] + pi[7] - pi[3] - (pi[3]>>1);;
ai1[5] = pi[7] - pi[1] + pi[5] + (pi[5]>>1);
ai1[7] = pi[3] + pi[5] + pi[1] + (pi[1]>>1);
ai2[0] = ai1[0] + ai1[6];
ai2[6] = ai1[0] - ai1[6];
ai2[2] = ai1[2] + ai1[4];
ai2[4] = ai1[2] - ai1[4];
ai2[1] = ai1[1] + (ai1[7]>>2);
ai2[7] = ai1[7] - (ai1[1]>>2);
ai2[3] = ai1[3] + (ai1[5]>>2);
ai2[5] = (ai1[3]>>2) - ai1[5];
aai[n][0] = ai2[0] + ai2[7];
aai[n][1] = ai2[2] + ai2[5];
aai[n][2] = ai2[4] + ai2[3];
aai[n][3] = ai2[6] + ai2[1];
aai[n][4] = ai2[6] - ai2[1];
aai[n][5] = ai2[4] - ai2[3];
aai[n][6] = ai2[2] - ai2[5];
aai[n][7] = ai2[0] - ai2[7];
}
for( n = 0; n < 8; n++, puc++ )
{
Int ai1[8];
Int ai2[8];
ai1[0] = aai[0][n] + aai[4][n];
ai1[1] = aai[5][n] - aai[3][n] - aai[7][n] - (aai[7][n]>>1);
ai1[2] = aai[0][n] - aai[4][n];
ai1[3] = aai[1][n] + aai[7][n] - aai[3][n] - (aai[3][n]>>1);
ai1[4] = (aai[2][n]>>1) - aai[6][n];
ai1[5] = aai[7][n] - aai[1][n] + aai[5][n] + (aai[5][n]>>1);
ai1[6] = aai[2][n] + (aai[6][n]>>1);
ai1[7] = aai[3][n] + aai[5][n] + aai[1][n] + (aai[1][n]>>1);
ai2[2] = ai1[2] + ai1[4];
ai2[4] = ai1[2] - ai1[4];
ai2[0] = ai1[0] + ai1[6];
ai2[6] = ai1[0] - ai1[6];
ai2[1] = ai1[1] + (ai1[7]>>2);
ai2[7] = ai1[7] - (ai1[1]>>2);
ai2[3] = ai1[3] + (ai1[5]>>2);
ai2[5] = (ai1[3]>>2) - ai1[5];
puc[0*iStride] = xClip( xRound( ai2[0] + ai2[7] ) + puc[0*iStride] );
puc[1*iStride] = xClip( xRound( ai2[2] + ai2[5] ) + puc[1*iStride] );
puc[2*iStride] = xClip( xRound( ai2[4] + ai2[3] ) + puc[2*iStride] );
puc[3*iStride] = xClip( xRound( ai2[6] + ai2[1] ) + puc[3*iStride] );
puc[4*iStride] = xClip( xRound( ai2[6] - ai2[1] ) + puc[4*iStride] );
puc[5*iStride] = xClip( xRound( ai2[4] - ai2[3] ) + puc[5*iStride] );
puc[6*iStride] = xClip( xRound( ai2[2] - ai2[5] ) + puc[6*iStride] );
puc[7*iStride] = xClip( xRound( ai2[0] - ai2[7] ) + puc[7*iStride] );
}
return Err::m_nOK;
}
Void
Transform::x4x4Quant( TCoeff* piQCoeff,
TCoeff* piCoeff,
const QpParameter& rcQp )
{
for( Int n = 0; n < 16; n++ )
{
Int iLevel = ( abs( (Int)piCoeff[n] ) * g_aaiQuantCoef[ rcQp.rem() ][n] + rcQp.add() ) >> rcQp.bits();
Int iSign = ( 0 < piCoeff[n] ? 1 : -1 );
if( 0 != iLevel )
{
piQCoeff[n] = iLevel * iSign;
}
else
{
piQCoeff[n] = 0;
}
}
}
Void
Transform::x4x4Dequant( TCoeff* piQCoeff,
TCoeff* piCoeff,
const QpParameter& rcQp )
{
for( Int n = 0; n < 16; n++ )
{
if( piQCoeff[n] != 0 )
{
Int iScale = g_aaiDequantCoef[rcQp.rem()][n];
piCoeff[n] = ( piQCoeff[n] * iScale ) << rcQp.per();
}
else
{
piCoeff[n] = 0;
}
}
}
Void
Transform::xForTransform8x8Blk( XPel* pucOrg, XPel* pucRec, Int iStride, TCoeff* piPredCoeff )
{
Int aai[8][8];
for( Int i = 0; i < 8; i++, pucOrg += iStride, pucRec += iStride)
{
Int ai [8];
Int ai1 [8];
Int ai2 [8];
ai[0] = pucOrg[0] - pucRec[0];
ai[1] = pucOrg[1] - pucRec[1];
ai[2] = pucOrg[2] - pucRec[2];
ai[3] = pucOrg[3] - pucRec[3];
ai[4] = pucOrg[4] - pucRec[4];
ai[5] = pucOrg[5] - pucRec[5];
ai[6] = pucOrg[6] - pucRec[6];
ai[7] = pucOrg[7] - pucRec[7];
ai1[0] = ai[0] + ai[7];
ai1[1] = ai[1] + ai[6];
ai1[2] = ai[2] + ai[5];
ai1[3] = ai[3] + ai[4];
ai1[4] = ai[0] - ai[7];
ai1[5] = ai[1] - ai[6];
ai1[6] = ai[2] - ai[5];
ai1[7] = ai[3] - ai[4];
ai2[0] = ai1[0] + ai1[3];
ai2[1] = ai1[1] + ai1[2];
ai2[2] = ai1[0] - ai1[3];
ai2[3] = ai1[1] - ai1[2];
ai2[4] = ai1[5] + ai1[6] + ((ai1[4]>>1) + ai1[4]);
ai2[5] = ai1[4] - ai1[7] - ((ai1[6]>>1) + ai1[6]);
ai2[6] = ai1[4] + ai1[7] - ((ai1[5]>>1) + ai1[5]);
ai2[7] = ai1[5] - ai1[6] + ((ai1[7]>>1) + ai1[7]);
aai[0][i] = ai2[0] + ai2[1];
aai[2][i] = ai2[2] + (ai2[3]>>1);
aai[4][i] = ai2[0] - ai2[1];
aai[6][i] = (ai2[2]>>1) - ai2[3];
aai[1][i] = ai2[4] + (ai2[7]>>2);
aai[3][i] = ai2[5] + (ai2[6]>>2);
aai[5][i] = ai2[6] - (ai2[5]>>2);
aai[7][i] = (ai2[4]>>2) - ai2[7];
}
// vertical transform
for( Int n = 0; n < 8; n++, piPredCoeff++)
{
Int ai1[8];
Int ai2[8];
ai1[0] = aai[n][0] + aai[n][7];
ai1[1] = aai[n][1] + aai[n][6];
ai1[2] = aai[n][2] + aai[n][5];
ai1[3] = aai[n][3] + aai[n][4];
ai1[4] = aai[n][0] - aai[n][7];
ai1[5] = aai[n][1] - aai[n][6];
ai1[6] = aai[n][2] - aai[n][5];
ai1[7] = aai[n][3] - aai[n][4];
ai2[0] = ai1[0] + ai1[3];
ai2[1] = ai1[1] + ai1[2];
ai2[2] = ai1[0] - ai1[3];
ai2[3] = ai1[1] - ai1[2];
ai2[4] = ai1[5] + ai1[6] + ((ai1[4]>>1) + ai1[4]);
ai2[5] = ai1[4] - ai1[7] - ((ai1[6]>>1) + ai1[6]);
ai2[6] = ai1[4] + ai1[7] - ((ai1[5]>>1) + ai1[5]);
ai2[7] = ai1[5] - ai1[6] + ((ai1[7]>>1) + ai1[7]);
piPredCoeff[ 0] = ai2[0] + ai2[1];
piPredCoeff[16] = ai2[2] + (ai2[3]>>1);
piPredCoeff[32] = ai2[0] - ai2[1];
piPredCoeff[48] = (ai2[2]>>1) - ai2[3];
piPredCoeff[ 8] = ai2[4] + (ai2[7]>>2);
piPredCoeff[24] = ai2[5] + (ai2[6]>>2);
piPredCoeff[40] = ai2[6] - (ai2[5]>>2);
piPredCoeff[56] = (ai2[4]>>2) - ai2[7];
}
}
Void
Transform::xQuantDequantUniform8x8( TCoeff* piQCoeff,
TCoeff* piCoeff,
const QpParameter& rcQp,
const UChar* pucScale,
UInt& ruiAbsSum )
{
UInt uiAbsSum = 0;
Int iAdd = ( 1 << 5 ) >> rcQp.per();
for( Int n = 0; n < 64; n++ )
{
Int iLevel = piCoeff[n];
Int iSign = iLevel;
iLevel = abs( iLevel ) * g_aaiQuantCoef64[ rcQp.rem() ][ n ];
if( pucScale )
{
iLevel = ( iLevel << 4 ) / pucScale[ n ];
}
iLevel = ( iLevel + 2*rcQp.add() ) >> ( rcQp.bits() + 1 );
if( 0 != iLevel )
{
iSign >>= 31;
Int iDeScale = g_aaiDequantCoef64[ rcQp.rem() ][ n ];
uiAbsSum += iLevel;
iLevel ^= iSign;
iLevel -= iSign;
piQCoeff[n] = iLevel;
if( pucScale )
{
piCoeff[n] = ( (iLevel*iDeScale*pucScale[n] + iAdd) << rcQp.per() ) >> 6;
}
else
{
piCoeff[n] = ( (iLevel*iDeScale*16 + iAdd) << rcQp.per() ) >> 6;
}
}
else
{
piQCoeff[n] = 0;
piCoeff [n] = 0;
}
}
ruiAbsSum = uiAbsSum;
}
// h264 namepace end
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -