📄 transform.cpp
字号:
iLevel = ( abs( iLevel ) * g_aaiQuantCoef[rcQp.rem()][n] );
if( pucScale )
{
iLevel = ( iLevel << 4 ) / pucScale[n];
}
iQLevel = ( iLevel + rcQp.add() ) >> rcQp.bits();
pcRefCtx[m] <<= 2;
if( iQLevel )
{
// Clip refinement symbols
if( piCoeffBase[n] )
iQLevel = 1;
uiAcAbs += iQLevel;
iQLevel ^= iSign;
iQLevel -= iSign;
piCoeff[n] = iQLevel;
pcRefCtx[m] += 1;
if( piCoeffBase[n] )
pcRefCtx[m] += ( iSign ^ iBaseSign ) & 1;
}
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,
RefCtx* pcRefCtx )
{
TCoeff aiTemp[64];
XPel* pOrg = pcOrgData->getLumBlk();
XPel* pRec = pcPelData->getLumBlk();
Int iStride = pcPelData->getLStride();
xForTransform4x4Blk( pOrg, pRec, iStride, aiTemp );
xQuantDequantUniform4x4( piCoeff, aiTemp, pcRefCtx, 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,
RefCtx* pcRefCtx,
const UChar* pucScale,
Bool bFirstIsDc,
UInt& ruiAbsSum )
{
x4x4Trafo( rcResData.getLumBlk (), rcResData.getLStride(), piCoeff );
xRequantUniform4x4( piCoeff, piCoeffBase, pcRefCtx, bFirstIsDc, m_cLumaQp, pucScale, ruiAbsSum );
return Err::m_nOK;
}
ErrVal
Transform::requantLumaDcCoeffs( MbTransformCoeffs& rcMbTCoeff,
MbTransformCoeffs& rcMbTCoeffBase,
MbFGSCoefMap& rcMbFGSCoefMap,
const UChar* pucScale,
UInt& ruiAbsSum )
{
// the transform was already performed
xForTransformLumaDc( rcMbTCoeff.get( B4x4Idx(0) ) );
ruiAbsSum = 0;
for( S4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
TCoeff& riCoeff = rcMbTCoeff.get ( cIdx )[0];
TCoeff& iCoeffBase = rcMbTCoeffBase.get( cIdx )[0];
Int iLevel = riCoeff;
Int iBaseSign = iCoeffBase.getCoeff() >> 15;
iLevel -= ( (Int)iCoeffBase.getCoeff() + 1 ) >> 1;
Int iSign = iLevel >> 31;
iLevel = abs( iLevel ) * g_aaiQuantCoef[ m_cLumaQp.rem() ][0];
if( pucScale )
{
iLevel = ( iLevel << 4 ) / pucScale[0];
}
Int iQLevel = ( iLevel + 2 * m_cLumaQp.add() ) >> ( m_cLumaQp.bits() + 1 );
RefCtx &rcRefCtx = rcMbFGSCoefMap.getRefCtx( cIdx )[0];
rcRefCtx <<= 2;
if( iQLevel )
{
// Clip refinement symbols
if( iCoeffBase )
iQLevel = 1;
ruiAbsSum += iQLevel;
iQLevel ^= iSign;
iQLevel -= iSign;
riCoeff = iQLevel;
rcRefCtx += 1;
if( iCoeffBase )
rcRefCtx += ( iSign ^ iBaseSign ) & 1;
}
else
{
riCoeff = 0;
}
}
return Err::m_nOK;
}
ErrVal
Transform::requant8x8Block( IntYuvMbBuffer& rcResData,
TCoeff* piCoeff,
TCoeff* piCoeffBase,
RefCtx* pcRefCtx,
const UChar* pucScale,
UInt& ruiAbsSum )
{
//===== trafo =====
x8x8Trafo( rcResData.getLumBlk (), rcResData.getLStride(), piCoeff );
//===== quantization =====
xRequantUniform8x8( piCoeff, piCoeffBase, pcRefCtx, m_cLumaQp, pucScale, ruiAbsSum );
return Err::m_nOK;
}
ErrVal
Transform::requantChroma( IntYuvMbBuffer& rcResData,
MbTransformCoeffs& rcTCoeffs,
MbTransformCoeffs& rcTCoeffsBase,
MbFGSCoefMap& rcMbFGSCoefMap,
const UChar* pucScaleU,
const UChar* pucScaleV,
UInt& ruiDcAbs,
UInt& ruiAcAbs )
{
x4x4Trafo( rcResData.getMbCbAddr(), rcResData.getCStride(), rcTCoeffs.get( CIdx( 0 ) ) );
x4x4Trafo( rcResData.getMbCbAddr() + 4, rcResData.getCStride(), rcTCoeffs.get( CIdx( 1 ) ) );
x4x4Trafo( rcResData.getMbCbAddr() + 4*rcResData.getCStride(), rcResData.getCStride(), rcTCoeffs.get( CIdx( 2 ) ) );
x4x4Trafo( rcResData.getMbCbAddr() + 4 + 4*rcResData.getCStride(), rcResData.getCStride(), rcTCoeffs.get( CIdx( 3 ) ) );
x4x4Trafo( rcResData.getMbCrAddr(), rcResData.getCStride(), rcTCoeffs.get( CIdx( 4 ) ) );
x4x4Trafo( rcResData.getMbCrAddr() + 4, rcResData.getCStride(), rcTCoeffs.get( CIdx( 5 ) ) );
x4x4Trafo( rcResData.getMbCrAddr() + 4*rcResData.getCStride(), rcResData.getCStride(), rcTCoeffs.get( CIdx( 6 ) ) );
x4x4Trafo( rcResData.getMbCrAddr() + 4 + 4*rcResData.getCStride(), rcResData.getCStride(), rcTCoeffs.get( CIdx( 7 ) ) );
xForTransformChromaDc( rcTCoeffs.get( CIdx( 0 ) ) );
xForTransformChromaDc( rcTCoeffs.get( CIdx( 4 ) ) );
for( CIdx cCIdx; cCIdx.isLegal(); cCIdx++ )
xRequantNonUniformChroma( rcTCoeffs.get( cCIdx ), rcTCoeffsBase.get( cCIdx ), rcMbFGSCoefMap.getRefCtx( cCIdx ), m_cChromaQp, cCIdx.plane() ? pucScaleV : pucScaleU, 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,
MbFGSCoefMap* pcMbFGSCoefMap,
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 );
if( pcMbFGSCoefMap )
{
xQuantDequantNonUniformChroma( piCoeff + 0x00, piQuantCoeff + 0x00, pcMbFGSCoefMap->getRefCtx( cCIdx ), m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x10, piQuantCoeff + 0x10, pcMbFGSCoefMap->getRefCtx( cCIdx+1 ), m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x20, piQuantCoeff + 0x20, pcMbFGSCoefMap->getRefCtx( cCIdx+2 ), m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x30, piQuantCoeff + 0x30, pcMbFGSCoefMap->getRefCtx( cCIdx+3 ), m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
}
else
{
xQuantDequantNonUniformChroma( piCoeff + 0x00, piQuantCoeff + 0x00, NULL, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x10, piQuantCoeff + 0x10, NULL, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x20, piQuantCoeff + 0x20, NULL, m_cChromaQp, pucScale, ruiDcAbs, ruiAcAbs );
xQuantDequantNonUniformChroma( piCoeff + 0x30, piQuantCoeff + 0x30, NULL, 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,
RefCtx* pcRefCtx )
{
TCoeff aiTemp[64];
XPel* pOrg = pcOrgData->getLumBlk();
XPel* pRec = pcPelData->getLumBlk();
Int iStride = pcPelData->getLStride();
xForTransform8x8Blk ( pOrg, pRec, iStride, aiTemp );
xQuantDequantUniform8x8 ( piCoeff, aiTemp, pcRefCtx, 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -