transform.cpp
来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,550 行 · 第 1/3 页
CPP
1,550 行
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;
}
ErrVal
Transform::transformMb( TCoeff* piCoeff, // -> array of 16*16+2*4*16 = 384 entries
IntYuvMbBuffer& rcYuvMbBuffer, // <- current macroblock buffer
Int iQpLuma, // <- luma QP
Int iQpChroma, // <- chroma QP
Int iQuantOffsetDiv ) // <- determines quantization offset
{
ROF( piCoeff );
TCoeff aiOrgCoeff[16];
QpParameter cLumaQp, cChromaQp;
Int iLStride = rcYuvMbBuffer.getLStride();
Int iCStride = rcYuvMbBuffer.getCStride();
//===== set quantization parameters =====
cLumaQp .setQp( iQpLuma, iQuantOffsetDiv );
cChromaQp .setQp( iQpChroma, iQuantOffsetDiv );
//===== luma =====
for( B4x4Idx cYIdx; cYIdx.isLegal(); cYIdx++, piCoeff+=16 )
{
x4x4Trafo( rcYuvMbBuffer.getYBlk( cYIdx ), iLStride, aiOrgCoeff );
x4x4Quant( piCoeff, aiOrgCoeff, cLumaQp );
}
//===== chroma =====
for( CIdx cCIdx; cCIdx.isLegal(); cCIdx++, piCoeff+=16 )
{
x4x4Trafo( rcYuvMbBuffer.getCBlk( cCIdx ), iCStride, aiOrgCoeff );
x4x4Quant( piCoeff, aiOrgCoeff, cChromaQp );
}
return Err::m_nOK;
}
ErrVal
Transform::inverseTransformMb( IntYuvMbBuffer& rcYuvMbBuffer, // -> current macroblock buffer
TCoeff* piCoeff, // <- array of 16*16+2*4*16 = 384 entries
Int iQpLuma, // <- luma QP
Int iQpChroma ) // <- chroma QP
{
ROF( piCoeff );
TCoeff aiRecCoeff[16];
QpParameter cLumaQp, cChromaQp;
Int iLStride = rcYuvMbBuffer.getLStride();
Int iCStride = rcYuvMbBuffer.getCStride();
//===== set quantization parameters =====
cLumaQp .setQp( iQpLuma );
cChromaQp .setQp( iQpChroma );
//===== luma =====
for( B4x4Idx cYIdx; cYIdx.isLegal(); cYIdx++, piCoeff+=16 )
{
x4x4Dequant( piCoeff, aiRecCoeff, cLumaQp );
x4x4InverseTrafo( rcYuvMbBuffer.getYBlk( cYIdx ), iLStride, aiRecCoeff );
}
//===== chroma =====
for( CIdx cCIdx; cCIdx.isLegal(); cCIdx++, piCoeff+=16 )
{
x4x4Dequant( piCoeff, aiRecCoeff, cChromaQp );
x4x4InverseTrafo( rcYuvMbBuffer.getCBlk( cCIdx ), iCStride, aiRecCoeff );
}
return Err::m_nOK;
}
Void
Transform::x4x4Trafo( XPel* pOrg,
Int iStride,
TCoeff* piCoeff )
{
Int aai[4][4];
Int tmp1, tmp2;
for( Int y = 0; y < 4; y++ )
{
tmp1 = pOrg[0] + pOrg[3];
tmp2 = pOrg[1] + pOrg[2];
aai[0][y] = tmp1 + tmp2;
aai[2][y] = tmp1 - tmp2;
tmp1 = pOrg[0] - pOrg[3];
tmp2 = pOrg[1] - pOrg[2];
aai[1][y] = tmp1 * 2 + tmp2 ;
aai[3][y] = tmp1 - tmp2 * 2;
pOrg += iStride;
}
for( Int x = 0; x < 4; x++, piCoeff++ )
{
tmp1 = aai[x][0] + aai[x][3];
tmp2 = aai[x][1] + aai[x][2];
piCoeff[0] = tmp1 + tmp2;
piCoeff[8] = tmp1 - tmp2;
tmp1 = aai[x][0] - aai[x][3];
tmp2 = aai[x][1] - aai[x][2];
piCoeff[4] = tmp1 * 2 + tmp2;
piCoeff[12] = tmp1 - tmp2 * 2;
}
}
Void
Transform::x4x4InverseTrafo( XPel* pRec,
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++, pRec++ )
{
tmp1 = aai[y][0] + aai[y][2];
tmp2 = (aai[y][3]>>1) + aai[y][1];
pRec[0] = /*gClip*/( xRound( tmp1 + tmp2) );
pRec[iStride3] = /*gClip*/( xRound( tmp1 - tmp2) );
tmp1 = aai[y][0] - aai[y][2];
tmp2 = (aai[y][1]>>1) - aai[y][3];
pRec[iStride] = /*gClip*/( xRound( tmp1 + tmp2) );
pRec[iStride2] = /*gClip*/( xRound( tmp1 - tmp2) );
}
}
Void
Transform::x4x4Quant( TCoeff* piQCoeff,
TCoeff* piCoeff,
const QpParameter& rcQp )
{
for( Int n = 0; n < 16; n++ )
{
Int iLevel = ( abs( 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::x8x8Trafo( XPel* pOrg,
Int iStride,
TCoeff* piCoeff )
{
Int aai[8][8];
for( Int i = 0; i < 8; i++, pOrg += iStride )
{
Int ai1 [8];
Int ai2 [8];
ai1[0] = pOrg[0] + pOrg[7];
ai1[1] = pOrg[1] + pOrg[6];
ai1[2] = pOrg[2] + pOrg[5];
ai1[3] = pOrg[3] + pOrg[4];
ai1[4] = pOrg[0] - pOrg[7];
ai1[5] = pOrg[1] - pOrg[6];
ai1[6] = pOrg[2] - pOrg[5];
ai1[7] = pOrg[3] - pOrg[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++, piCoeff++ )
{
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]);
piCoeff[ 0] = ai2[0] + ai2[1];
piCoeff[16] = ai2[2] + (ai2[3]>>1);
piCoeff[32] = ai2[0] - ai2[1];
piCoeff[48] = (ai2[2]>>1) - ai2[3];
piCoeff[ 8] = ai2[4] + (ai2[7]>>2);
piCoeff[24] = ai2[5] + (ai2[6]>>2);
piCoeff[40] = ai2[6] - (ai2[5]>>2);
piCoeff[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;
}
Void
Transform::xRequantUniform8x8( TCoeff* piCoeff,
TCoeff* piCoeffBase,
const QpParameter& rcQp,
const UChar* pucScale,
UInt& ruiAbsSum )
{
Int normAdjust[] = { 8, 9, 5, 9, 8, 9, 5, 9 };
ruiAbsSum = 0;
for( Int n = 0; n < 64; n++ )
{
Int iLevel = piCoeff[n];
Int iSign = iLevel;
iLevel -= ( normAdjust[n/8] * normAdjust[n%8] * (Int)piCoeffBase[n] + ( 1 << 5 ) ) >> 6;
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;
ruiAbsSum += iLevel;
iLevel ^= iSign;
iLevel -= iSign;
piCoeff [n] = iLevel;
}
else
{
piCoeff [n] = 0;
}
}
}
// h264 namepace end
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?