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

📄 transform.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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 + -