fgscoder.cpp

来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,684 行 · 第 1/5 页

CPP
1,684
字号
  
  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 )
{
  UInt uiBlockIndex = (uiMbY * 4 + cIdx.y()) * m_uiWidthInMB * 4 + uiMbX * 4 + cIdx.x();

  for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
  {
    pucSigMap[g_aucFrameScan[uiScanIndex]] = 
      SIGNIFICANT & m_apaucLumaCoefMap[uiScanIndex][uiBlockIndex];
  }
}


// get 8x8 significance map for luma
Void FGSCoder::getCoeffSigMap( UInt uiMbX, UInt uiMbY, B8x8Idx c8x8Idx, UChar *pucSigMap )
{
  UInt  auiBlockIdx[4]  = { ( 4*uiMbY + c8x8Idx.y()     ) * 4 * m_uiWidthInMB + ( 4*uiMbX + c8x8Idx.x()     ),
    ( 4*uiMbY + c8x8Idx.y()     ) * 4 * m_uiWidthInMB + ( 4*uiMbX + c8x8Idx.x() + 1 ),
    ( 4*uiMbY + c8x8Idx.y() + 1 ) * 4 * m_uiWidthInMB + ( 4*uiMbX + c8x8Idx.x()     ),
    ( 4*uiMbY + c8x8Idx.y() + 1 ) * 4 * m_uiWidthInMB + ( 4*uiMbX + c8x8Idx.x() + 1 ) };

  for( UInt ui8x8ScanIndex = 0; ui8x8ScanIndex < 64; ui8x8ScanIndex ++ )
  {
    UInt  uiS = ui8x8ScanIndex/4;
    UInt  uiB = auiBlockIdx[ui8x8ScanIndex % 4];

    pucSigMap[g_aucFrameScan64[ui8x8ScanIndex]] = 
      SIGNIFICANT & m_apaucLumaCoefMap[uiS][uiB];
  }
}


// get 4x4 significance map for chroma
Void FGSCoder::getCoeffSigMap( UInt uiMbX, UInt uiMbY, CIdx cIdx, UChar *pucSigMap )
{
  UInt uiPlane      = cIdx.plane();
  UInt uiMbIndex    = uiMbY * m_uiWidthInMB + uiMbX;
  UInt uiBlockIndex = (uiMbY * 2 + cIdx.y()) * m_uiWidthInMB * 2 + uiMbX * 2 + cIdx.x();

  for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
  {
    pucSigMap[g_aucFrameScan[uiScanIndex]] = 
      SIGNIFICANT & ((uiScanIndex == 0) ?
      m_aapaucChromaDCCoefMap[uiPlane][cIdx.y() * 2 + cIdx.x()][uiMbIndex]
      : m_aapaucChromaACCoefMap[cIdx.plane()][uiScanIndex][uiBlockIndex]);
  }
}


// get entire 8x8 significance map for chroma
Void FGSCoder::getCoeffSigMapChroma8x8( UInt uiMbX, UInt uiMbY, UInt uiPlane, UChar *pucSigMap )
{
  UInt uiMbIndex    = uiMbY * m_uiWidthInMB + uiMbX;
  UInt uiBeginIdx, uiEndIdx;

  uiBeginIdx = (uiPlane == 0) ? 0 : 4;
  uiEndIdx   = uiBeginIdx + 4;

  for( CIdx cIdx(uiBeginIdx); cIdx.isLegal(uiEndIdx); cIdx ++ )
  {
    UInt uiBlockIndex     = (uiMbY * 2 + cIdx.y()) * m_uiWidthInMB * 2 + uiMbX * 2 + cIdx.x();
    UInt uiBlockIdxWithMb = cIdx.y() * 2 + cIdx.x();

    for( UInt uiScanIndex = 0; uiScanIndex < 16; uiScanIndex ++ )
    {
      pucSigMap[uiBlockIdxWithMb * 16 + g_aucFrameScan[uiScanIndex]] = 
        SIGNIFICANT & ((uiScanIndex == 0) ?
        m_aapaucChromaDCCoefMap[uiPlane][uiBlockIdxWithMb][uiMbIndex]
        : m_aapaucChromaACCoefMap[cIdx.plane()][uiScanIndex][uiBlockIndex]);
    }
  }
}


ErrVal
FGSCoder::xClearBaseCoeffs( MbDataAccess& rcMbDataAccess, 
                            MbDataAccess* pcMbDataAccessBase )
{
  UInt uiMbY     = pcMbDataAccessBase->getMbY();
  UInt uiMbX     = pcMbDataAccessBase->getMbX();
  UInt uiMbIndex = uiMbY * m_uiWidthInMB + uiMbX;

  m_pauiMacroblockMap[uiMbIndex] = rcMbDataAccess.getSH().getPPS().getTransform8x8ModeFlag() && rcMbDataAccess.getMbData().is8x8TrafoFlagPresent() ? CLEAR : TRANSFORM_SPECIFIED;

  //--- LUMA ---
  for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
  {
    UInt uiSubMbIndex = ( 2*uiMbY + c8x8Idx.y()/2 ) * 2 * m_uiWidthInMB + ( 2*uiMbX + c8x8Idx.x() / 2 );

    //===== set sub-macroblock mode =====
    m_paucSubMbMap[uiSubMbIndex] = CLEAR;

    for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ )
    {
      UInt    uiScanIndex;
      UInt    uiBlockIdx  = ( 4*uiMbY + cIdx.y() ) * 4 * m_uiWidthInMB + ( 4*uiMbX + cIdx.x() );

      //===== set transform coefficients =====
      for( uiScanIndex = 0; uiScanIndex < 16; uiScanIndex++ )
      {
        m_apaucLumaCoefMap[uiScanIndex][uiBlockIdx] = CLEAR;
      }
      m_apaucScanPosMap[0][uiBlockIdx] = 16;
      for( uiScanIndex = 0; uiScanIndex < 16; uiScanIndex++ )
      {
        if( !( m_apaucLumaCoefMap[uiScanIndex][uiBlockIdx] & (SIGNIFICANT|CODED) ) && m_apaucScanPosMap[0][uiBlockIdx] == 16 )
        {
          m_apaucScanPosMap[0][uiBlockIdx] = uiScanIndex;
        }
      }

      //===== set block mode =====
      m_paucBlockMap[uiBlockIdx] = CLEAR;
    }
  }

  //--- CHROMA DC ---
  for( UInt uiPlane = 0; uiPlane < 2; uiPlane++ )
  {
    UInt ui;
    for( ui = 0; ui < 4; ui++ )
    {
      m_aapaucChromaDCCoefMap[uiPlane][ui][uiMbIndex] = CLEAR;
    }
    m_apaucScanPosMap[uiPlane + 1][uiMbIndex] = 4;
    for( ui = 0; ui < 4; ui++ )
    {
      if( !( m_aapaucChromaDCCoefMap[uiPlane][ui][uiMbIndex] & (SIGNIFICANT|CODED) ) && m_apaucScanPosMap[uiPlane + 1][uiMbIndex] == 4 )
      {
        m_apaucScanPosMap[uiPlane + 1][uiMbIndex] = ui;
      }
    }
    m_apaucChromaDCBlockMap[uiPlane][uiMbIndex] = CLEAR;
  }

  //--- CHROMA AC ---
  for( CIdx cCIdx; cCIdx.isLegal(); cCIdx++ )
  {
    UInt    ui;
    UInt    ui8x8Idx    = ( 2*uiMbY + cCIdx.y() ) * 2 * m_uiWidthInMB + ( 2 * uiMbX + cCIdx.x() );

    for( ui = 1; ui < 16; ui++ )
    {
      m_aapaucChromaACCoefMap[cCIdx.plane()][ui][ui8x8Idx]  = CLEAR;
    }
    m_apaucScanPosMap[cCIdx.plane() + 3][ui8x8Idx] = 16;
    for( ui = 1; ui < 16; ui++ )
    {
      if( !( m_aapaucChromaACCoefMap[cCIdx.plane()][ui][ui8x8Idx] & (SIGNIFICANT|CODED) ) && m_apaucScanPosMap[cCIdx.plane() + 3][ui8x8Idx] == 16 )
      {
        m_apaucScanPosMap[cCIdx.plane() + 3][ui8x8Idx] = ui;
      }
    }
    m_apaucChromaACBlockMap[cCIdx.plane()][ui8x8Idx] = CLEAR;
  }

  //pcMbDataAccessBase->getMbData().setMbCbp( 0 );
  pcMbDataAccessBase->getMbTCoeffs().clear();
  pcMbDataAccessBase->getMbData().setTransformSize8x8( false );

  IntYuvMbBuffer cZeroBuffer;
  cZeroBuffer.setAllSamplesToZero();
  RNOK( m_pcBaseLayerSbb->getFullPelYuvBuffer()->loadBuffer( &cZeroBuffer ) );

  return Err::m_nOK;
}


H264AVC_NAMESPACE_END


⌨️ 快捷键说明

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