⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transform.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  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 + -