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

📄 fgscoder.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  }
  else
  {
    for( UInt ui = 0; ui < 64; ui++ )
    {
      piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef64[rcQP.rem()][ui] * 16 + iAdd ) << rcQP.per() ) >> 6;
    }
  }

  return Err::m_nOK;
}


ErrVal
FGSCoder::xScaleTCoeffs( MbDataAccess& rcMbDataAccess,
                         Bool          bBaseLayer )
{
  const Int aaiDequantDcCoef[6] = {  10, 11, 13, 14, 16, 18 };
  Quantizer cQuantizer;
  cQuantizer.setQp( rcMbDataAccess, false );
  
  const QpParameter&  cLQp      = cQuantizer.getLumaQp  ();
  const QpParameter&  cCQp      = cQuantizer.getChromaQp();
  Bool                bIntra    = rcMbDataAccess.getMbData().isIntra();
  Bool                b8x8      = rcMbDataAccess.getMbData().isTransformSize8x8();
  Bool                b16x16    = rcMbDataAccess.getMbData().isIntra16x16();
  UInt                uiYScalId = ( bIntra ? ( b8x8 && !b16x16 ? 6 : 0 ) : ( b8x8 ? 7 : 3 ) );
  UInt                uiUScalId = ( bIntra ? 1 : 4 );
  UInt                uiVScalId = ( bIntra ? 2 : 5 );
  const UChar*        pucScaleY = rcMbDataAccess.getSH().getScalingMatrix( uiYScalId );
  const UChar*        pucScaleU = rcMbDataAccess.getSH().getScalingMatrix( uiUScalId );
  const UChar*        pucScaleV = rcMbDataAccess.getSH().getScalingMatrix( uiVScalId );
  Int                 iScale    = 1;

  if (!rcMbDataAccess.getMbData().isPCM() )
      rcMbDataAccess.getMbTCoeffs().storeLevelData();  // for SVC to AVC rewrite

  //===== luma =====
  if( b16x16 )
  {
    //===== INTRA_16x16 =====
    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( xScale4x4Block( rcMbDataAccess.getMbTCoeffs().get   ( cIdx ), pucScaleY, 1, cLQp ) );
    }

    iScale  = aaiDequantDcCoef[cLQp.rem()] << cLQp.per();
    if( pucScaleY )
    {
      iScale  *= pucScaleY[0];
      iScale >>= 4;
    }
    // perform scaling only
    TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( B4x4Idx(0) );

    for( Int uiDCIdx = 0; uiDCIdx < 16; uiDCIdx++ )
    {
      TCoeff a = piCoeff[16*uiDCIdx] * iScale;
      Int    b = piCoeff[16*uiDCIdx] * iScale;
      if( a != b )
      {
        printf("Short overflow in FGS Intra16x16 DC-coeffs.\n");
        // not good
        piCoeff[16*uiDCIdx] = max( (Int)MSYS_SHORT_MIN, min( (Int)MSYS_SHORT_MAX, b ) );
      }
      else
      {
      piCoeff[16*uiDCIdx] *= iScale;
      }
    }
    //===== correct CBP =====
    rcMbDataAccess.getMbData().setMbCbp( rcMbDataAccess.getAutoCbp() );
  }
  else if( b8x8 )
  {
    //===== 8x8 BLOCKS =====
    for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( xScale8x8Block( rcMbDataAccess.getMbTCoeffs().get8x8( cIdx ), pucScaleY, cLQp ) );
    }
  }
  else
  {
    //===== 4x4 BLOCKS =====
    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( xScale4x4Block( rcMbDataAccess.getMbTCoeffs().get   ( cIdx ), pucScaleY, 0, cLQp ) );
    }
  }

  //===== chroma =====
  for( CIdx cIdx; cIdx.isLegal(); cIdx++ )
  {
    RNOK( xScale4x4Block( rcMbDataAccess.getMbTCoeffs().get( cIdx ), ( cIdx.plane() ? pucScaleV : pucScaleU ), 1, cCQp ) );
  }

  // only performs scaling, not inverse transform
  UInt  uiMbIndex = rcMbDataAccess.getMbY()*m_uiWidthInMB+rcMbDataAccess.getMbX();

    iScale = g_aaiDequantCoef[cCQp.rem()][0] << cCQp.per();
    /* HS: old scaling modified:
       (I did not work for scaling matrices, when QpPer became less than 5 in an FGS enhancement) */

  for( CIdx cCIdx; cCIdx.isLegal(); cCIdx++ )
    {
    if(! bBaseLayer && ! ( m_pcCoefMap[uiMbIndex].getCoefMap( cCIdx )[0] & CODED ) && !m_bUpdateWithoutMap )
        // condition "! bBaseLayer" is needed. When "xScaleTCoeffs is called 
        // before first FGS layer, m_aapaucChromaDCCoefMap is not initialized
      rcMbDataAccess.getMbTCoeffs().get( cCIdx )[0] = 0;
      else
      rcMbDataAccess.getMbTCoeffs().get( cCIdx )[0] *= iScale;
    }
  return Err::m_nOK;
}


ErrVal
FGSCoder::xReconstructMacroblock( MbDataAccess&   rcMbDataAccess,
                                  IntYuvMbBuffer& rcMbBuffer )
{
  m_pcTransform->setClipMode( false );

  Int                 iLStride  = rcMbBuffer.getLStride();
  Int                 iCStride  = rcMbBuffer.getCStride();
  Bool                b8x8      = rcMbDataAccess.getMbData().isTransformSize8x8();
  MbTransformCoeffs&  rcCoeffs  = rcMbDataAccess.getMbTCoeffs();

  rcMbBuffer.loadBuffer( m_pcBaseLayerSbb->getPic(rcMbDataAccess.getMbPicType())->getFullPelYuvBuffer() );//TMM_INTERLACE

  TCoeff lumaDcCoeffs[16];
  if ( rcMbDataAccess.getMbData().isIntra16x16() )
  {
    // backup luma DC
    TCoeff *piCoeffs;
    UInt   uiDCIdx;

    piCoeffs = rcCoeffs.get( B4x4Idx(0) );
    for( uiDCIdx = 0; uiDCIdx < 16; uiDCIdx++ )
      lumaDcCoeffs[uiDCIdx] = piCoeffs[16*uiDCIdx] ;

    // inverse transform on luma DC
    RNOK( m_pcTransform->invTransformDcCoeff( piCoeffs, 1 ) );

    // inverse transform on entire MB
    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( m_pcTransform->invTransform4x4Blk( rcMbBuffer.getYBlk( cIdx ), iLStride, rcCoeffs.get( cIdx ) ) );
    }

    // restore luma DC
    for( uiDCIdx = 0; uiDCIdx < 16; uiDCIdx++ )
      piCoeffs[16*uiDCIdx] = lumaDcCoeffs[uiDCIdx];
  }
  else if( b8x8 )
  {
    for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( m_pcTransform->invTransform8x8Blk( rcMbBuffer.getYBlk( cIdx ), iLStride, rcCoeffs.get8x8( cIdx ) ) );
    }
  }
  else
  {
    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( m_pcTransform->invTransform4x4Blk( rcMbBuffer.getYBlk( cIdx ), iLStride, rcCoeffs.get( cIdx ) ) );
    }
  }

  TCoeff              chromaDcCoeffs[2][4];
  UInt                uiPlane;
  Int                 iScale;
  Bool                bIntra    = rcMbDataAccess.getMbData().isIntra();
  UInt                uiUScalId = ( bIntra ? 1 : 4 );
  UInt                uiVScalId = ( bIntra ? 2 : 5 );
  const UChar*        pucScaleU = rcMbDataAccess.getSH().getScalingMatrix( uiUScalId );
  const UChar*        pucScaleV = rcMbDataAccess.getSH().getScalingMatrix( uiVScalId );

  // backup chroma DC coefficients
  for( uiPlane = 0; uiPlane < 2; uiPlane++ )
  {
    TCoeff*   piCoeff = rcCoeffs.get( CIdx(4*uiPlane) );
    for( UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
      chromaDcCoeffs[uiPlane][uiDCIdx] = piCoeff[16*uiDCIdx];
  }

  // scaling has already been performed on DC coefficients
  iScale = ( pucScaleU ? pucScaleU[0] : 16 );
  m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(0) ), iScale );     
  iScale = ( pucScaleV ? pucScaleV[0] : 16 );
  m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(4) ), iScale );

  RNOK( m_pcTransform->invTransformChromaBlocks( rcMbBuffer.getMbCbAddr(), iCStride, rcCoeffs.get( CIdx(0) ) ) );
  RNOK( m_pcTransform->invTransformChromaBlocks( rcMbBuffer.getMbCrAddr(), iCStride, rcCoeffs.get( CIdx(4) ) ) );

  // restore chroma DC coefficients
  for( uiPlane = 0; uiPlane < 2; uiPlane++ )
  {
    TCoeff*   piCoeff = rcCoeffs.get( CIdx(4*uiPlane) );
    for( UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
      piCoeff[16*uiDCIdx] = chromaDcCoeffs[uiPlane][uiDCIdx];
  }
  m_pcTransform->setClipMode( true );

  return Err::m_nOK;
}


Int
FGSCoder::xScaleLevel4x4( Int                 iLevel,
                          Int                 iIndex,
                          const QpParameter&  cQP,
                          const QpParameter&  cBaseQP )
{
  Int iSign       = ( iLevel < 0 ? -1 : 1 );
  Int iBaseScale  = g_aaiDequantCoef[cBaseQP.rem()][iIndex] << cBaseQP.per();
  Int iScale      = g_aaiDequantCoef[cQP    .rem()][iIndex] << cQP    .per();

  return iSign * ( ( abs(iLevel) * iBaseScale ) + ( iScale >> 1 ) ) / iScale;
}

Int
FGSCoder::xScaleLevel8x8( Int                 iLevel,
                          Int                 iIndex,
                          const QpParameter&  cQP,
                          const QpParameter&  cBaseQP )
{
  Int iSign       = ( iLevel < 0 ? -1 : 1 );
  Int iBaseScale  = g_aaiDequantCoef64[cBaseQP.rem()][iIndex] << cBaseQP.per();
  Int iScale      = g_aaiDequantCoef64[cQP    .rem()][iIndex] << cQP    .per();

  return iSign * ( ( abs(iLevel) * iBaseScale ) + ( iScale >> 1 ) ) / iScale;
}


ErrVal
FGSCoder::xScaleSymbols4x4( TCoeff*             piCoeff,
                            const QpParameter&  cQP,
                            const QpParameter&  cBaseQP )
{
  for( Int iIndex = 0; iIndex < 16; iIndex++ )
  {
    if( piCoeff[iIndex] )
    {
      piCoeff[iIndex] = xScaleLevel4x4( piCoeff[iIndex], iIndex, cQP, cBaseQP );
    }
  }
  return Err::m_nOK;
}


ErrVal
FGSCoder::xScaleSymbols8x8( TCoeff*             piCoeff,
                            const QpParameter&  cQP,
                            const QpParameter&  cBaseQP )
{
  for( Int iIndex = 0; iIndex < 64; iIndex++ )
  {
    if( piCoeff[iIndex] )
    {
      piCoeff[iIndex] = xScaleLevel8x8( piCoeff[iIndex], iIndex, cQP, cBaseQP );
    }
  }
  return Err::m_nOK;
}


ErrVal
FGSCoder::xUpdateSymbols( TCoeff* piCoeff,
                          TCoeff* piCoeffEL,
                          Bool&   bSigDC,
                          Bool&   bSigAC,
                          Int     iNumCoeff )
{
  piCoeff     [0] += piCoeffEL[0];
  if( piCoeff [0] )
  {
    bSigDC = true;
  }

  for( Int iIndex = 1; iIndex < iNumCoeff; iIndex++ )
  {
    piCoeff    [iIndex] += piCoeffEL[iIndex];
    if( piCoeff[iIndex] )
    {
      bSigAC = true;
    }
  }

  return Err::m_nOK;
}


// get 4x4 significance map for luma
Void FGSCoder::getCoeffSigMap( UInt uiMbX, UInt uiMbY, S4x4Idx cIdx, UChar *pucSigMap, Bool bFrame  )
{
  CoefMap *pcCoefMap = m_pcCoefMap[uiMbY * m_uiWidthInMB + uiMbX ].getCoefMap( cIdx );
  const UChar*  pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
  for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
  {
    pucSigMap[pucScan[uiScanIndex]] = SIGNIFICANT & pcCoefMap[uiScanIndex];
  }
}


// get 8x8 significance map for luma
Void FGSCoder::getCoeffSigMap( UInt uiMbX, UInt uiMbY, B8x8Idx c8x8Idx, UChar *pucSigMap, Bool bFrame )
{
  CoefMap *pcCoefMap = m_pcCoefMap[uiMbY * m_uiWidthInMB + uiMbX].getCoefMap( c8x8Idx );
  const UChar*  pucScan64 = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;
  for( UInt ui8x8ScanIndex = 0; ui8x8ScanIndex < 64; ui8x8ScanIndex ++ )
  {
    pucSigMap[pucScan64[ui8x8ScanIndex]] = SIGNIFICANT & pcCoefMap[ui8x8ScanIndex];
  }
}


// get 4x4 significance map for chroma
Void FGSCoder::getCoeffSigMap( UInt uiMbX, UInt uiMbY, CIdx cIdx, UChar *pucSigMap, Bool bFrame )
{
  UInt uiMbIndex    = uiMbY * m_uiWidthInMB + uiMbX;
  CoefMap* pcCoefMap = m_pcCoefMap[uiMbIndex].getCoefMap( cIdx );
  const UChar*  pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
  for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
    pucSigMap[pucScan[uiScanIndex]] = SIGNIFICANT & pcCoefMap[uiScanIndex];
}


// get entire 8x8 significance map for chroma
Void FGSCoder::getCoeffSigMapChroma8x8( UInt uiMbX, UInt uiMbY, UInt uiPlane, UChar *pucSigMap, Bool bFrame )
{
  UInt uiMbIndex    = uiMbY * m_uiWidthInMB + uiMbX;
  const UChar*  pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;

  for( CIdx cCIdx(( CPlaneIdx(uiPlane) )); cCIdx.isLegal( CPlaneIdx(uiPlane) ); cCIdx++ )
  {
    UInt uiBlockIdxWithMb = cCIdx.y() * 2 + cCIdx.x();
    CoefMap *pcCoefMap = m_pcCoefMap[uiMbIndex].getCoefMap( cCIdx );
    for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
      pucSigMap[uiBlockIdxWithMb * 16 + pucScan[uiScanIndex]] = SIGNIFICANT & pcCoefMap[uiScanIndex];
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -