fgscoder.cpp

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

CPP
1,684
字号
      {
        UInt ui;
        for( ui = 0; ui < 4; ui++ )
          m_aapaucChromaDCCoefMap[uiPlane][ui][uiMbIndex] &= ~CODED;
        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] &= ~CODED;
      }

      //--- 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] &= ~CODED;
        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] &= ~CODED;
      }
    }
  }

  return Err::m_nOK;
}


ErrVal
FGSCoder::xUpdateMacroblock( MbDataAccess&  rcMbDataAccessBL,
                             MbDataAccess&  rcMbDataAccessEL,
                             UInt           uiMbY,
                             UInt           uiMbX )
{
  UInt  uiExtCbp  = 0;
  Bool  b8x8      = rcMbDataAccessBL.getMbData().isTransformSize8x8();
  UInt  uiMbIndex = uiMbY*m_uiWidthInMB + uiMbX;

  if( ! rcMbDataAccessBL.getMbData().isIntra() && ! rcMbDataAccessEL.getMbData().getBLSkipFlag() )
  {
    //----- update motion parameters -----
    rcMbDataAccessBL.getMbData().copyFrom  ( rcMbDataAccessEL.getMbData() );
    rcMbDataAccessBL.getMbData().copyMotion( rcMbDataAccessEL.getMbData() );
  }
  //===== luma =====
  if( b8x8 )
  {
    for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
    {
      Bool    bSig      = false;
      TCoeff* piCoeffBL = rcMbDataAccessBL.getMbTCoeffs().get8x8( c8x8Idx );
      TCoeff* piCoeffEL = rcMbDataAccessEL.getMbTCoeffs().get8x8( c8x8Idx );

      for( UInt ui8x8ScanIdx = 0; ui8x8ScanIdx < 64; ui8x8ScanIdx++ )
      {
        UInt  uiPos         = g_aucFrameScan64[ui8x8ScanIdx];
        UInt  ui4x4ScanIdx  = ui8x8ScanIdx / 4;
        UInt  uiBlk4x4Idx   = ui8x8ScanIdx % 4;
        UInt  uiBlockIndex  = (4*uiMbY+c8x8Idx.y()+(uiBlk4x4Idx/2))*4*m_uiWidthInMB + (4*uiMbX+c8x8Idx.x()+(uiBlk4x4Idx%2));

        if( m_apaucLumaCoefMap[ui4x4ScanIdx][uiBlockIndex] & CODED )
        {
          xUpdateCoeffMap(piCoeffBL[uiPos], piCoeffEL[uiPos], m_apaucLumaCoefMap[ui4x4ScanIdx][uiBlockIndex]);
        }
        if( piCoeffBL[uiPos] )
        {
          bSig = true;
        }
      }
      if( bSig )
      {
        uiExtCbp |= ( 0x33 << c8x8Idx.b4x4() );
      }
    }
  }
  else
  {
    for( B4x4Idx c4x4Idx; c4x4Idx.isLegal(); c4x4Idx++ )
    {
      Bool    bSig      = false;
      TCoeff* piCoeffBL = rcMbDataAccessBL.getMbTCoeffs().get( c4x4Idx );
      TCoeff* piCoeffEL = rcMbDataAccessEL.getMbTCoeffs().get( c4x4Idx );

      for( UInt uiScanIdx = 0; uiScanIdx < 16; uiScanIdx++ )
      {
        UInt  uiPos         = g_aucFrameScan[uiScanIdx];
        UInt  uiBlockIndex  = (4*uiMbY+c4x4Idx.y())*4*m_uiWidthInMB + (4*uiMbX+c4x4Idx.x());

        if( m_apaucLumaCoefMap[uiScanIdx][uiBlockIndex] & CODED )
        {
          xUpdateCoeffMap(piCoeffBL[uiPos], piCoeffEL[uiPos], m_apaucLumaCoefMap[uiScanIdx][uiBlockIndex]);
        }
        if( piCoeffBL[uiPos] )
        {
          bSig = true;
        }
      }
      if( bSig )
      {
        uiExtCbp |= ( 1 << c4x4Idx );
      }
    }
  }


  //===== chroma DC =====
  Bool  bSigDC = false;
  for( UInt uiPlane = 0; uiPlane < 2; uiPlane++ )
  {
    TCoeff* piCoeffBL = rcMbDataAccessBL.getMbTCoeffs().get( CIdx(4*uiPlane) );
    TCoeff* piCoeffEL = rcMbDataAccessEL.getMbTCoeffs().get( CIdx(4*uiPlane) );

    for( UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
    {
      UInt uiPos = g_aucIndexChromaDCScan[uiDCIdx];

      if( m_aapaucChromaDCCoefMap[uiPlane][uiDCIdx][uiMbIndex] & CODED)
      {
        xUpdateCoeffMap(piCoeffBL[uiPos], piCoeffEL[uiPos], m_aapaucChromaDCCoefMap[uiPlane][uiDCIdx][uiMbIndex]);
      }

      if( piCoeffBL[uiPos] )
      {
        bSigDC = true;
      }
    }
  }

  //===== chroma AC =====
  Bool  bSigAC = false;
  for( CIdx cCIdx; cCIdx.isLegal(); cCIdx++ )
  {
    TCoeff* piCoeffBL = rcMbDataAccessBL.getMbTCoeffs().get( cCIdx );
    TCoeff* piCoeffEL = rcMbDataAccessEL.getMbTCoeffs().get( cCIdx );

    for( UInt uiScanIdx = 1; uiScanIdx < 16; uiScanIdx++ )
    {
      UInt  uiPos     = g_aucFrameScan[uiScanIdx];
      UInt  ui8x8Idx  = (2*uiMbY+cCIdx.y())*2*m_uiWidthInMB + (2*uiMbX+cCIdx.x());

      if( m_aapaucChromaACCoefMap[cCIdx.plane()][uiScanIdx][ui8x8Idx] & CODED )
      {
        xUpdateCoeffMap(piCoeffBL[uiPos], piCoeffEL[uiPos], m_aapaucChromaACCoefMap[cCIdx.plane()][uiScanIdx][ui8x8Idx]);
      }
      if( piCoeffBL[uiPos] )
      {
        bSigAC = true;
      }
    }
  }

  
  //===== set CBP =====
  UInt  uiChromaCBP = ( bSigAC ? 2 : bSigDC ? 1 : 0 );
  uiExtCbp         |= ( uiChromaCBP << 16 );
  rcMbDataAccessBL.getMbData().setAndConvertMbExtCbp( uiExtCbp );


  //===== set QP =====
  Int iELQP     = rcMbDataAccessEL.getMbData().getQp();
  Int iNumCoded = ( m_pauiMacroblockMap[uiMbIndex] >> NUM_COEFF_SHIFT );
  Int iQPDelta  = ( 384 - iNumCoded ) / 64;
  Int iQP       = min( 51, iELQP + iQPDelta );
  if( ! ( m_pauiMacroblockMap[uiMbIndex] & SIGNIFICANT ) )
  {
    iQP = rcMbDataAccessEL.getSH().getPicQp();
  }
  rcMbDataAccessBL.getMbData().setQp( iQP );

  return Err::m_nOK;
}


ErrVal
FGSCoder::xScale4x4Block( TCoeff*            piCoeff,
                          const UChar*       pucScale,
                          UInt               uiStart,
                          const QpParameter& rcQP )
{
  if( pucScale )
  {
    Int iAdd = ( rcQP.per() <= 3 ? ( 1 << ( 3 - rcQP.per() ) ) : 0 );
    
    for( UInt ui = uiStart; ui < 16; ui++ )
    {
      piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef[rcQP.rem()][ui] * pucScale[ui] + iAdd ) << rcQP.per() ) >> 4;
    }
  }
  else
  {
    for( UInt ui = uiStart; ui < 16; ui++ )
    {
      piCoeff[ui] *= ( g_aaiDequantCoef[rcQP.rem()][ui] << rcQP.per() );
    }
  }

  return Err::m_nOK;
}


ErrVal
FGSCoder::xScale8x8Block( TCoeff*            piCoeff,
                          const UChar*       pucScale,
                          const QpParameter& rcQP )
{
  Int iAdd = ( rcQP.per() <= 5 ? ( 1 << ( 5 - rcQP.per() ) ) : 0 );

  if( pucScale )
  {
    for( UInt ui = 0; ui < 64; ui++ )
    {
      piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef64[rcQP.rem()][ui] * pucScale[ui] + iAdd ) << rcQP.per() ) >> 6;
    }
  }
  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;

  //===== 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++ )
      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();
  for( UInt uiPlane = 0; uiPlane < 2; uiPlane++ )
  {
    TCoeff*      piCoeff = rcMbDataAccess.getMbTCoeffs().get( CIdx(4*uiPlane) );

    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( UInt uiDCIdx = 0; uiDCIdx < 4; uiDCIdx++ )
    {
      if(! bBaseLayer && ! ( m_aapaucChromaDCCoefMap[uiPlane][uiDCIdx][uiMbIndex] & CODED ) )
        // condition "! bBaseLayer" is needed. When "xScaleTCoeffs is called 
        // before first FGS layer, m_aapaucChromaDCCoefMap is not initialized
        piCoeff[16*uiDCIdx]  = 0;
      else
        piCoeff[16*uiDCIdx] *= 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->getFullPelYuvBuffer() );

⌨️ 快捷键说明

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