transform.cpp
来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,550 行 · 第 1/3 页
CPP
1,550 行
Void Transform::xRequantUniform4x4( TCoeff* piCoeff,
TCoeff* piCoeffBase,
const QpParameter& rcQp,
const UChar* pucScale,
UInt& ruiAbsSum )
{
Int normAdjust[] = { 4, 5, 4, 5 };
ruiAbsSum = 0;
for( Int n = 0; n < 16; n++ )
{
Int iLevel = piCoeff[n];
Int iSign = iLevel;
iLevel -= ( normAdjust[n/4] * normAdjust[n%4] * (Int)piCoeffBase[n] + ( 1 << 5 ) ) >> 6;
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;
ruiAbsSum += iLevel;
iLevel ^= iSign;
iLevel -= iSign;
piCoeff [n] = iLevel;
}
else
{
piCoeff [n] = 0;
}
}
}
Void Transform::xRequantNonUniformChroma( TCoeff* piCoeff,
TCoeff* piCoeffBase,
const QpParameter& rcQp,
const UChar* pucScale,
UInt& ruiDcAbs,
UInt& ruiAcAbs )
{
Int normAdjust[] = { 4, 5, 4, 5 };
Int iLevel = piCoeff[0];
UInt uiSign = ((UInt)iLevel)>>31;
iLevel -= ( (Int)piCoeffBase[0] + 1 ) >> 1;
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 );
piCoeff [0] = iLevel;
UInt uiAcAbs = 0;
for( int n = 1; n < 16; n++ )
{
iLevel = piCoeff[n];
Int iSign = iLevel;
iLevel -= ( normAdjust[n/4] * normAdjust[n%4] * (Int)piCoeffBase[n] + ( 1 << 5 ) ) >> 6;
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;
uiAcAbs += iLevel;
iLevel ^= iSign;
iLevel -= iSign;
piCoeff [n] = iLevel;
}
else
{
piCoeff [n] = 0;
}
}
ruiAcAbs += uiAcAbs;
return;
}
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( IntYuvMbBuffer* pcOrgData, IntYuvMbBuffer* 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 );
ROTRS( 0 == ruiAbsSum, Err::m_nOK );
xInvTransform4x4Blk( pRec, iStride, aiTemp );
return Err::m_nOK;
}
ErrVal
Transform::requant4x4Block( IntYuvMbBuffer& rcResData,
TCoeff* piCoeff,
TCoeff* piCoeffBase,
const UChar* pucScale,
Bool bFirstIsDc,
UInt& ruiAbsSum )
{
Int iDcCoeff = 0;
//===== trafo =====
x4x4Trafo( rcResData.getLumBlk (), rcResData.getLStride(), piCoeff );
// backup the first coefficient
if (bFirstIsDc)
{
iDcCoeff = piCoeff[0];
piCoeff[0] = 0;
}
//===== quantization =====
xRequantUniform4x4( piCoeff, piCoeffBase, m_cLumaQp, pucScale, ruiAbsSum );
// restored the first coefficient
if (bFirstIsDc)
piCoeff[0] = iDcCoeff;
return Err::m_nOK;
}
ErrVal
Transform::requantLumaDcCoeffs( TCoeff* piCoeff,
TCoeff* piCoeffBase,
const UChar* pucScale,
UInt& ruiAbsSum )
{
// the transform was already performed
xForTransformLumaDc( piCoeff );
ruiAbsSum = 0;
for( UInt n = 0; n < 16; n ++ )
{
Int iLevel = piCoeff[n<<4];
UInt uiSign = ((UInt)iLevel)>>31;
iLevel -= ( (Int)piCoeffBase[n<<4] + 1 ) >> 1;
uiSign = ((UInt)iLevel)>>31;
iLevel = abs( iLevel ) * g_aaiQuantCoef[ m_cLumaQp.rem() ][0];
if( pucScale )
{
iLevel = ( iLevel << 4 ) / pucScale[0];
}
iLevel = ( iLevel + 2 * m_cLumaQp.add() ) >> ( m_cLumaQp.bits() + 1 );
ruiAbsSum += iLevel;
iLevel = ( uiSign ? -iLevel : iLevel );
piCoeff[n<<4] = iLevel;
}
return Err::m_nOK;
}
ErrVal
Transform::requant8x8Block( IntYuvMbBuffer& rcResData,
TCoeff* piCoeff,
TCoeff* piCoeffBase,
const UChar* pucScale,
UInt& ruiAbsSum )
{
//===== trafo =====
x8x8Trafo( rcResData.getLumBlk (), rcResData.getLStride(), piCoeff );
//===== quantization =====
xRequantUniform8x8( piCoeff, piCoeffBase, m_cLumaQp, pucScale, ruiAbsSum );
return Err::m_nOK;
}
ErrVal
Transform::requantChroma( IntYuvMbBuffer& rcResData,
TCoeff* piCoeff,
TCoeff* piCoeffBase,
const UChar* pucScaleU,
const UChar* pucScaleV,
UInt& ruiDcAbs,
UInt& ruiAcAbs )
{
x4x4Trafo( rcResData.getMbCbAddr(), rcResData.getCStride(), piCoeff + 0x00 );
x4x4Trafo( rcResData.getMbCbAddr() + 4, rcResData.getCStride(), piCoeff + 0x10 );
x4x4Trafo( rcResData.getMbCbAddr() + 4*rcResData.getCStride(), rcResData.getCStride(), piCoeff + 0x20 );
x4x4Trafo( rcResData.getMbCbAddr() + 4 + 4*rcResData.getCStride(), rcResData.getCStride(), piCoeff + 0x30 );
x4x4Trafo( rcResData.getMbCrAddr(), rcResData.getCStride(), piCoeff + 0x40 );
x4x4Trafo( rcResData.getMbCrAddr() + 4, rcResData.getCStride(), piCoeff + 0x50 );
x4x4Trafo( rcResData.getMbCrAddr() + 4*rcResData.getCStride(), rcResData.getCStride(), piCoeff + 0x60 );
x4x4Trafo( rcResData.getMbCrAddr() + 4 + 4*rcResData.getCStride(), rcResData.getCStride(), piCoeff + 0x70 );
xForTransformChromaDc( piCoeff + 0x00 );
xForTransformChromaDc( piCoeff + 0x40 );
xRequantNonUniformChroma( piCoeff+0x00, piCoeffBase+0x00, m_cChromaQp, pucScaleU, ruiDcAbs, ruiAcAbs );
xRequantNonUniformChroma( piCoeff+0x10, piCoeffBase+0x10, m_cChromaQp, pucScaleU, ruiDcAbs, ruiAcAbs );
xRequantNonUniformChroma( piCoeff+0x20, piCoeffBase+0x20, m_cChromaQp, pucScaleU, ruiDcAbs, ruiAcAbs );
xRequantNonUniformChroma( piCoeff+0x30, piCoeffBase+0x30, m_cChromaQp, pucScaleU, ruiDcAbs, ruiAcAbs );
xRequantNonUniformChroma( piCoeff+0x40, piCoeffBase+0x40, m_cChromaQp, pucScaleV, ruiDcAbs, ruiAcAbs );
xRequantNonUniformChroma( piCoeff+0x50, piCoeffBase+0x50, m_cChromaQp, pucScaleV, ruiDcAbs, ruiAcAbs );
xRequantNonUniformChroma( piCoeff+0x60, piCoeffBase+0x60, m_cChromaQp, pucScaleV, ruiDcAbs, ruiAcAbs );
xRequantNonUniformChroma( piCoeff+0x70, piCoeffBase+0x70, m_cChromaQp, pucScaleV, ruiDcAbs, ruiAcAbs );
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;
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( IntYuvMbBuffer* pcOrgData, IntYuvMbBuffer* 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;
}
return Err::m_nOK;
}
ErrVal Transform::transformChromaBlocks( XPel* pucOrg, XPel* pucRec, 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 );
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( IntYuvMbBuffer* pcOrgData,
IntYuvMbBuffer* 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 );
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];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?