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

📄 fgssubbandencoder.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

// FGS FMO ICU/ETRI
ErrVal
RQFGSEncoder::setSliceGroup(Int iSliceGroupID)
{
  FMO* pcFMO = m_pcSliceHeader->getFMO();
  m_pcSliceHeader->setFirstMbInSlice(pcFMO->getFirstMacroblockInSlice(iSliceGroupID));
  m_pcSliceHeader->setLastMbInSlice(pcFMO->getLastMBInSliceGroup(iSliceGroupID));
  // JVT-S054 (2) (ADD)
  m_pcSliceHeader->setNumMbsInSlice(pcFMO->getNumMbsInSlice(m_pcSliceHeader->getFirstMbInSlice(), m_pcSliceHeader->getLastMbInSlice()));
  return Err::m_nOK;
}


// FGS FMO ICU/ETRI
ErrVal
RQFGSEncoder::prepareEncode(UInt uiFrac, UInt uiFracNb)
{
	if( ! uiFrac )
	{
		RNOK ( xMotionEstimation() );
		RNOK ( xResidualTransform() );
	}
	
	if( uiFracNb )
	{
		RNOK( xRestoreCodingPath() );
	}
	return Err::m_nOK;
}


ErrVal
RQFGSEncoder::reconstruct( IntFrame* pcRecResidual )
{
  ROF( m_bInit );
  ROF( m_bPicInit );
  ROF( pcRecResidual );

  UInt            uiLayer         = m_pcSliceHeader->getSPS().getLayerId();
  YuvBufferCtrl*  pcYuvBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
  IntYuvMbBuffer  cMbBuffer;

  RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );

  for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
  for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB;  uiMbX++ )
  {
    MbDataAccess* pcMbDataAccess = 0;

    RNOK( m_pcCurrMbDataCtrl->initMb(  pcMbDataAccess, uiMbY, uiMbX ) );
    RNOK( pcYuvBufferCtrl   ->initMb(                  uiMbY, uiMbX ) );
    RNOK( xReconstructMacroblock    ( *pcMbDataAccess, cMbBuffer    ) );

    RNOK( pcRecResidual->getFullPelYuvBuffer()->loadBuffer( &cMbBuffer ) );
  }

  return Err::m_nOK;
}



const UChar COEFF_COST[16] =
{
  3, 2,2,1, 1,1,0,0,0,0,0,0,0,0,0,0
};

const UChar COEFF_COST8x8[64] =
{
  3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,
  1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};

const UChar MAX_VALUE = 100;



ErrVal
RQFGSEncoder::xSetSymbolsChroma( TCoeff*             piCoeff,
                                 UInt                uiMbX,
                                 UInt                uiMbY,
                                 UInt&               uiCoeffCostDC,
                                 UInt&               uiCoeffCostAC,
                                 Bool&               bSigDC,
                                 Bool&               bSigAC,
                                 ChromaIdx           cIdx )
{
  Int iRun  = 0;
  UInt    uiPlane             = cIdx.plane();
  UChar** ppucChromaDCCoefMap = m_aapaucChromaDCCoefMap[uiPlane];
  UChar** ppucChromaACCoefMap = m_aapaucChromaACCoefMap[uiPlane];
  UInt    uiMbIndex           = uiMbY * m_uiWidthInMB + uiMbX;
  UInt    ui8x8Idx = ( 2 * uiMbY + cIdx.y() ) * 2 * m_uiWidthInMB + ( 2 * uiMbX + cIdx.x() );

  for( Int iPos = 0; iPos < 16; iPos++ )
  {
    Int iIndex      = g_aucFrameScan[iPos];
    Int iLevel      = piCoeff       [iIndex];
    UChar ucSigMap = ( iPos == 0 ) ? 
      ppucChromaDCCoefMap[cIdx.y()* 2 + cIdx.x()][uiMbIndex] : ppucChromaACCoefMap[iPos][ui8x8Idx];

    if( ucSigMap & SIGNIFICANT )
    {
      if( abs(iLevel) > 1 )
      {
        iLevel = max( -1, min( 1, iLevel ) );
      }

      piCoeff[iIndex] = iLevel;
    }
    else
    {
      if( iPos == 0 )
      {
        if( iLevel )
        {
          if( abs( iLevel) == 1 )   uiCoeffCostDC += COEFF_COST[iRun];
          else                      uiCoeffCostDC += MAX_VALUE;
        
          bSigDC  = true;
        }
      }
      else
      {
        if( iLevel )
        {
          if( abs( iLevel) == 1 )   uiCoeffCostAC += COEFF_COST[iRun];
          else                      uiCoeffCostAC += MAX_VALUE;

          iRun   = 0;
          bSigAC = true;
        }
        else
        {
          iRun++;
        }
      }
    }
  }

  return Err::m_nOK;
}





ErrVal
RQFGSEncoder::xSetSymbols4x4( TCoeff*             piCoeff,
                              UInt                uiMbX,
                              UInt                uiMbY,
                              UInt&               uiCoeffCost,
                              UInt&               ruiCbp,
                              LumaIdx             cIdx,
                              UInt                uiStart )
{
  Int   iRun  = 0;
  Bool  bSig  = false;

  for( Int iPos = uiStart; iPos < 16; iPos++ )
  {
    Int iIndex      = g_aucFrameScan[iPos];
    Int iLevel      = piCoeff       [iIndex];

    UInt uiBlockIndex = ( uiMbY * 4 + cIdx.y() ) * m_uiWidthInMB * 4 + uiMbX * 4 + cIdx.x();
    if( m_apaucLumaCoefMap[iPos][uiBlockIndex] & SIGNIFICANT )
    {
      if( abs(iLevel) > 1 )
      {
        iLevel = max( -1, min( 1, iLevel ) );
      }

      piCoeff[iIndex] = iLevel;
    }
    else
    {
      if( iLevel )
      {
        if( abs( iLevel) == 1 )   uiCoeffCost += COEFF_COST[iRun];
        else                      uiCoeffCost += MAX_VALUE;

        iRun  = 0;
        bSig  = true;
      }
      else
      {
        iRun++;
      }
    }
  }

  if( bSig ) 
  {
    ruiCbp |= ( 1 << cIdx );
  }

  return Err::m_nOK;
}






ErrVal
RQFGSEncoder::xSetSymbols8x8( TCoeff*             piCoeff,
                              UInt                uiMbX,
                              UInt                uiMbY,
                              UInt&               uiCoeffCost,
                              UInt&               ruiCbp,
                              LumaIdx             cIdx )
{
  Int     iRun            = 0;
  Bool    bSig            = false;
  UInt    auiBlockIdx[4]  =
  {
    ( uiMbY*4 + cIdx.y()     ) * 4 * m_uiWidthInMB + ( uiMbX*4 + cIdx.x()     ),
    ( uiMbY*4 + cIdx.y()     ) * 4 * m_uiWidthInMB + ( uiMbX*4 + cIdx.x() + 1 ),
    ( uiMbY*4 + cIdx.y() + 1 ) * 4 * m_uiWidthInMB + ( uiMbX*4 + cIdx.x()     ),
    ( uiMbY*4 + cIdx.y() + 1 ) * 4 * m_uiWidthInMB + ( uiMbX*4 + cIdx.x() + 1 )
  };

  for( Int iPos = 0; iPos < 64; iPos++ )
  {
    Int iIndex = g_aucFrameScan64[iPos];
    Int iLevel = piCoeff         [iIndex];

    if( m_apaucLumaCoefMap[iPos/4][auiBlockIdx[iPos%4]] & SIGNIFICANT )
    {
      if( abs(iLevel) > 1 )
      {
        iLevel = max( -1, min( 1, iLevel ) );
      }

      piCoeff[iIndex] = iLevel;
    }
    else
    {
      if( iLevel )
      {
        if( abs( iLevel) == 1 )   uiCoeffCost += COEFF_COST8x8[iRun];
        else                      uiCoeffCost += MAX_VALUE;

        iRun  = 0;
        bSig  = true;
      }
      else
      {
        iRun++;
      }
    }
  }

  if( bSig )
  {
    ruiCbp |= ( 0x33 << cIdx );
  }

  return Err::m_nOK;
}




ErrVal
RQFGSEncoder::xRequantizeMacroblock( MbDataAccess&    rcMbDataAccess,
                                     MbDataAccess&    rcMbDataAccessBase )
{
#define COEF_SKIP 1

  UInt          uiExtCbp  = 0;
  Int           iQp       = max( 0, rcMbDataAccessBase.getMbData().getQp() - RQ_QP_DELTA );
  Bool          bIntra    = rcMbDataAccessBase.getMbData().isIntra();
  Bool          bIntra16x16 = rcMbDataAccessBase.getMbData().isIntra16x16();
  Bool          b8x8      = rcMbDataAccessBase.getMbData().isTransformSize8x8();
  Bool          bLowPass  = m_pcSliceHeader->getTemporalLevel() == 0;
  const UChar*  pucScaleY = rcMbDataAccessBase.getSH().getScalingMatrix( bIntra ? ( b8x8 ? 6 : 0 ) : ( b8x8 ? 7 : 3 ) );
  const UChar*  pucScaleU = rcMbDataAccessBase.getSH().getScalingMatrix( bIntra ? 1 : 4 );
  const UChar*  pucScaleV = rcMbDataAccessBase.getSH().getScalingMatrix( bIntra ? 2 : 5 );
  UInt          uiMbX     = rcMbDataAccess.getMbX();
  UInt          uiMbY     = rcMbDataAccess.getMbY();

  rcMbDataAccess.getMbData().setQp( iQp );

	//-- JVT-R091
	// use intra offset for smoothed reference MB
	if ( rcMbDataAccessBase.getMbData().getSmoothedRefFlag() )
	{
		m_pcTransform->setQp( rcMbDataAccess, true );
	}
	else
	{
		m_pcTransform->setQp( rcMbDataAccess, bLowPass || bIntra );
	}
	//--

  IntYuvMbBuffer  cMbBuffer;
  cMbBuffer      .loadBuffer( m_pcOrgResidual ->getFullPelYuvBuffer() );

  //===== luma =====
  if( b8x8 )
  {
    UInt  uiAbsSumMb    = 0;
    UInt  uiCoeffCostMb = 0;

    for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
    {
      UInt  uiCoeffCost8x8  = 0;
      UInt  uiAbsSum8x8     = 0;
      UInt  uiCbp           = 0;
      
      cMbBuffer.set4x4Block( c8x8Idx );
      RNOK( m_pcTransform->requant8x8Block( cMbBuffer,
                                            rcMbDataAccess    .getMbTCoeffs().get8x8( c8x8Idx ),
                                            rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx ),
                                            pucScaleY, uiAbsSum8x8 ) );
      uiAbsSumMb += uiAbsSum8x8;

      RNOK( xSetSymbols8x8( rcMbDataAccess    .getMbTCoeffs().get8x8( c8x8Idx ),
                            uiMbX, uiMbY,
                            uiCoeffCost8x8, uiCbp, c8x8Idx ) );

      if( uiCbp )
      {
#if COEF_SKIP
        if( uiCoeffCost8x8 <= 4 && ! bIntra && ! bLowPass )
        {
          rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels8x8Block( c8x8Idx, rcMbDataAccessBase.getMbTCoeffs() );
        }
        else
#endif
        {
          uiCoeffCostMb += uiCoeffCost8x8;
          uiExtCbp      += uiCbp;
        }
      }
    }
#if COEF_SKIP
    if( uiExtCbp && uiCoeffCostMb <= 5 && ! bIntra && ! bLowPass )
    {
      rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels( rcMbDataAccessBase.getMbTCoeffs() );
      uiExtCbp = 0;
    }
#endif
  }
  else
  {
    UInt  uiAbsSumMb    = 0;
    UInt  uiCoeffCostMb = 0;

    for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
    {
      UInt  uiCoeffCost8x8  = 0;
      UInt  uiAbsSum8x8     = 0;
      UInt  uiCbp           = 0;

      for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ )
      {
        UInt  uiAbsSum4x4 = 0;
        cMbBuffer.set4x4Block( cIdx );

        RNOK( m_pcTransform->requant4x4Block( cMbBuffer,
          rcMbDataAccess    .getMbTCoeffs().get( cIdx ),
          rcMbDataAccessBase.getMbTCoeffs().get( cIdx ),
          pucScaleY, 
          bIntra16x16,
          uiAbsSum4x4 ) );

        uiAbsSum8x8 += uiAbsSum4x4;
        if ( bIntra16x16 )
          uiAbsSum8x8 -= abs(rcMbDataAccess.getMbTCoeffs().get( cIdx )[0]);

        RNOK( xSetSymbols4x4( rcMbDataAccess    .getMbTCoeffs().get( cIdx ),
          uiMbX, uiMbY, 
          uiCoeffCost8x8, uiCbp, cIdx, bIntra16x16 ) );
      }
      if( uiCbp )
      {
#if COEF_SKIP
        if( uiCoeffCost8x8 <= 4 && ! bIntra && ! bLowPass && ! bIntra16x16 )
        {
          rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels8x8( c8x8Idx, rcMbDataAccessBase.getMbTCoeffs() );
        }
        else
#endif
        {
          uiCoeffCostMb += uiCoeffCost8x8;

⌨️ 快捷键说明

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