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

📄 fgssubbandencoder.cpp

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

    if ( bIntra16x16 )
    {
      UInt    uiAbsDc;
      TCoeff  *piCoeff, *piCoeffBase;

      // put DC coefficients into buffer
      piCoeff     = rcMbDataAccess    .getMbTCoeffs().get( B4x4Idx(0) );
      piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( B4x4Idx(0) );

      // transform and quantization on intra16x16 DC coefficients
      m_pcTransform->requantLumaDcCoeffs( piCoeff, piCoeffBase, pucScaleY, uiAbsDc );

      for ( UInt uiDcIdx = 0; uiDcIdx < 16; uiDcIdx ++ )
      {
        Int iLevel      = piCoeff    [16 * uiDcIdx];
        Int uiBlockIndex = (uiMbY * 4 + uiDcIdx/4)* m_uiWidthInMB * 4 + uiMbX * 4 + (uiDcIdx % 4);
        if( m_apaucLumaCoefMap[0][uiBlockIndex] & SIGNIFICANT )

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

          piCoeff[16 * uiDcIdx] = iLevel;
        }
        else
        // WARNING, should have "else" here because CBP is only for new-significant coefficients

        // since the DC coefficients are merged with the AC coefficients
        // update the cbp information
        uiExtCbp |= (iLevel != 0) << uiDcIdx;
      }
    }

#if COEF_SKIP
    if( ! bIntra16x16 )
    if( uiExtCbp && uiCoeffCostMb <= 5 && ! bIntra && ! bLowPass )
    {
      rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels( rcMbDataAccessBase.getMbTCoeffs() );
      uiExtCbp = 0;
    }
#endif
  }

  //===== chroma =====
  UInt  uiDcAbs       = 0;
  UInt  uiAcAbs       = 0;
  UInt  uiCoeffCostDC = 0;
  UInt  uiCoeffCostAC = 0;
  Bool  bSigDC        = false;
  Bool  bSigAC_U      = false;
  Bool  bSigAC_V      = false;

  RNOK( m_pcTransform->requantChroma( cMbBuffer,
                                      rcMbDataAccess    .getMbTCoeffs().get( CIdx(0) ),
                                      rcMbDataAccessBase.getMbTCoeffs().get( CIdx(0) ),
                                      pucScaleU, pucScaleV, uiDcAbs, uiAcAbs ) );
  
  //===== chrominance U =====
  {
    UInt  uiCoeffCostAC_U = 0;
    
    for( CIdx cIdxU(0); cIdxU.isLegal(4); cIdxU++ )
    {
      RNOK( xSetSymbolsChroma( rcMbDataAccess    .getMbTCoeffs().get( cIdxU ),
                               uiMbX, uiMbY, 
                               uiCoeffCostDC, uiCoeffCostAC_U, bSigDC, bSigAC_U, cIdxU ) );
    }
#if COEF_SKIP
    if( uiCoeffCostAC_U < 4 )
    {
      for( CIdx cIdxU(0); cIdxU.isLegal(4); cIdxU++ )
      {
        rcMbDataAccess.getMbTCoeffs().clearNewAcBlk( cIdxU, rcMbDataAccessBase.getMbTCoeffs() );
      }
      bSigAC_U = false;
    }
    else
#endif
    {
      uiCoeffCostAC += uiCoeffCostAC_U;
    }
  }

  //===== chrominance V =====
  {
    UInt  uiCoeffCostAC_V = 0;
    
    for( CIdx cIdxV(4); cIdxV.isLegal(8); cIdxV++ )
    {
      RNOK( xSetSymbolsChroma( rcMbDataAccess    .getMbTCoeffs().get( cIdxV ),
                               uiMbX, uiMbY, 
                               uiCoeffCostDC, uiCoeffCostAC_V, bSigDC, bSigAC_V, cIdxV ) );
    }
#if COEF_SKIP
    if( uiCoeffCostAC_V < 4 )
    {
      for( CIdx cIdxV(4); cIdxV.isLegal(8); cIdxV++ )
      {
        rcMbDataAccess.getMbTCoeffs().clearNewAcBlk( cIdxV, rcMbDataAccessBase.getMbTCoeffs() );
      }
      bSigAC_V = false;
    }
    else
#endif
    {
      uiCoeffCostAC += uiCoeffCostAC_V;
    }
  }

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


  return Err::m_nOK;
#undef COEF_SKIP
}


ErrVal
RQFGSEncoder::xMotionEstimation()
{
  RNOK( m_cMbDataCtrlEL    .clear     () );
  RNOK( m_cMbDataCtrlEL    .reset     () );
  RNOK( m_cMbDataCtrlEL    .initSlice ( *m_pcSliceHeader, ENCODE_PROCESS, false, NULL ) );
  RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS,    false, NULL ) );
  ROTRS( m_eSliceType == I_SLICE, Err::m_nOK );

  UInt            uiLayer             = m_pcSliceHeader->getSPS().getLayerId();
  YuvBufferCtrl*  pcYuvFullBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
  YuvBufferCtrl*  pcYuvHalfBufferCtrl = m_papcYuvHalfPelBufferCtrl[uiLayer];

  m_pcSliceHeader->setSliceType( m_eSliceType );
  for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
  for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB;  uiMbX++ )
  {
    MbDataAccess* pcMbDataAccessCurr  = 0;
    MbDataAccess* pcMbDataAccessEL    = 0;

    RNOK( m_pcCurrMbDataCtrl  ->initMb( pcMbDataAccessCurr, uiMbY, uiMbX ) );
    RNOK( m_cMbDataCtrlEL      .initMb( pcMbDataAccessEL,   uiMbY, uiMbX ) );
    RNOK( pcYuvFullBufferCtrl ->initMb(                     uiMbY, uiMbX ) );
    RNOK( pcYuvHalfBufferCtrl ->initMb(                     uiMbY, uiMbX ) );
    RNOK( m_pcMotionEstimation->initMb( uiMbY, uiMbX, *pcMbDataAccessEL  ) );

    if( pcMbDataAccessCurr->getMbData().isIntra() || ! m_pcSliceHeader->getAdaptivePredictionFlag() )
    {
            pcMbDataAccessEL->getMbData().copyFrom  ( pcMbDataAccessCurr->getMbData() );
      RNOK( pcMbDataAccessEL->getMbData().copyMotion( pcMbDataAccessCurr->getMbData() ) );
      if( ! pcMbDataAccessCurr->getMbData().isIntra() )
        pcMbDataAccessEL->getMbData().setBLSkipFlag( true );
    }
    else
    {
      //----- reconstruct base layer -----
      IntYuvMbBuffer cBLRecBuffer;
      RNOK( xReconstructMacroblock( *pcMbDataAccessCurr, cBLRecBuffer ) );
      //----- get new motion data -----
      RNOK( m_pcMbEncoder->encodeFGS( *pcMbDataAccessEL,
                                      pcMbDataAccessCurr,
                                      *m_pcRefFrameList0,
                                      *m_pcRefFrameList1,
                                      *m_pcOrgFrame,
                                      m_pcPredSignal,
                                      m_pcFGSPredFrame,
                                      m_pcRefFrameListDiff,
                                      this,
                                      cBLRecBuffer,
                                      m_uiNumMaxIter,
                                      m_uiIterSearchRange,
                                      m_dLambda,
                                      m_iMaxQpDelta ) );

      if( ! pcMbDataAccessEL->getMbData().getResidualPredFlag( PART_16x16 ) )
      {
        ROT( pcMbDataAccessEL->getMbData().getBLSkipFlag() );
        //----- motion refinement without residual prediction ===> clear base layer coeffs -----
        RNOK( xClearBaseCoeffs( *pcMbDataAccessEL, pcMbDataAccessCurr ) );
      }
    }
  }
  m_pcSliceHeader->setSliceType( F_SLICE );

  return Err::m_nOK;
}


ErrVal
RQFGSEncoder::xEncodeMotionData( UInt uiMbYIdx, UInt uiMbXIdx )
{
  ETRACE_DECLARE( UInt          uiMbIndex         = uiMbYIdx * m_uiWidthInMB + uiMbXIdx );
  MbDataAccess* pcMbDataAccessEL  = 0;
  MbDataAccess* pcMbDataAccessBL  = 0;

  RNOK( m_cMbDataCtrlEL     .initMb( pcMbDataAccessEL, uiMbYIdx, uiMbXIdx ) );
  RNOK( m_pcCurrMbDataCtrl ->initMb( pcMbDataAccessBL, uiMbYIdx, uiMbXIdx ) );
  ROT ( pcMbDataAccessBL->getMbData().isIntra() );

  ETRACE_NEWMB( uiMbIndex );
  m_pcSliceHeader  ->setSliceType( m_eSliceType );
  RNOK( m_pcMbCoder->encodeMotion( *pcMbDataAccessEL, pcMbDataAccessBL ) );
  m_pcSliceHeader  ->setSliceType( F_SLICE );

  return Err::m_nOK;
}


ErrVal
RQFGSEncoder::xResidualTransform( /*UInt uiBasePos*/ )
{
  UInt            uiLayer         = m_pcSliceHeader->getSPS().getLayerId();
  YuvBufferCtrl*  pcYuvBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
  Bool            bLowPass        = m_pcSliceHeader->getTemporalLevel() == 0;

  RNOK( m_pcOrgResidual->subtract( m_pcOrgFrame,    m_pcPredSignal   ) );
  RNOK( m_pcOrgResidual->subtract( m_pcOrgResidual, m_pcBaseLayerSbb ) );
  // Martin.Winken@hhi.fhg.de: clear, reset, initSlice now done in RQFGSEncoder::xMotionEstimation()

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

    RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccessCurr, uiMbY, uiMbX ) );
    RNOK( m_cMbDataCtrlEL    .initMb( pcMbDataAccessEL,   uiMbY, uiMbX ) );
    RNOK( pcYuvBufferCtrl   ->initMb(                     uiMbY, uiMbX ) );

    if( pcMbDataAccessCurr->getMbData().isIntra16x16() ||
      ( m_pauiMacroblockMap[uiMbY * m_uiWidthInMB + uiMbX] & SIGNIFICANT ) != 0 )
    {
      UInt uiMbIndex                = uiMbY * m_uiWidthInMB + uiMbX;
      Bool bUseTransformSizeFromRDO = ! ( m_pauiMacroblockMap[uiMbIndex] & TRANSFORM_SPECIFIED ) && ! pcMbDataAccessCurr->getMbData().isIntra();
      if( bUseTransformSizeFromRDO )
      {
        //----- set transform size from RDO (i.e., MbEncoder::encodeFGS()) if possible -----
        pcMbDataAccessCurr->getMbData().setTransformSize8x8( pcMbDataAccessEL->getMbData().isTransformSize8x8() );
      }
      //===== requantization =====
      RNOK( xRequantizeMacroblock ( *pcMbDataAccessEL, *pcMbDataAccessCurr ) );
      if( bUseTransformSizeFromRDO && ( pcMbDataAccessEL->getMbData().getMbCbp() & 0x0F ) == 0 )
      {
        //----- clear transform size flag if no luma samples coded -----
        pcMbDataAccessCurr->getMbData().setTransformSize8x8( false );
      }
    }
    else
    {
      //===== new encoding =====
      m_pcTransform->setClipMode( false );
      pcMbDataAccessEL->getMbData().setQp( m_pcSliceHeader->getPicQp() );
      Bool bResidualPrediction = pcMbDataAccessEL->getMbData().getResidualPredFlag( PART_16x16 );
      RNOK( m_pcMbEncoder->encodeResidual( *pcMbDataAccessEL,
                                           *pcMbDataAccessCurr,
                                           m_pcOrgResidual,
                                           m_dLambda,
                                           bLowPass,
                                           m_iMaxQpDelta ) );
      pcMbDataAccessEL->getMbData().setResidualPredFlag( bResidualPrediction );
      m_pcTransform->setClipMode( true );
    }
  }

 
  return Err::m_nOK;
}




ErrVal
RQFGSEncoder::xScaleBaseLayerCoeffs()
{
  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( xScaleTCoeffs             ( *pcMbDataAccess, true ) );
  }
  
  return Err::m_nOK;
}

//JVT-P031
ErrVal RQFGSEncoder::xSaveCodingPath()
{
    typedef MbTransformCoeffs* pMbTransformCoeffs;
    m_aMyELTransformCoefs = new pMbTransformCoeffs[m_uiHeightInMB*m_uiWidthInMB];
    m_aMyBLTransformCoefs = new pMbTransformCoeffs[m_uiHeightInMB*m_uiWidthInMB];
    m_auiMbCbpStored = new UInt[m_uiHeightInMB*m_uiWidthInMB];
    m_auiBCBPStored = new UInt[m_uiHeightInMB*m_uiWidthInMB];
    m_aiBLQP = new Int[m_uiHeightInMB*m_uiWidthInMB];
    m_abELtransform8x8 = new Bool[m_uiHeightInMB*m_uiWidthInMB];

    for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
  {
    for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB;  uiMbX++ )
    {
        m_aMyELTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB] = new MbTransformCoeffs();
        m_aMyBLTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB] = new MbTransformCoeffs();

        //--- Get MbData for BL and EL
      MbDataAccess* pcMbDataAccessBL = 0;
      MbDataAccess* pcMbDataAccessEL = 0;

      RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccessBL, uiMbY, uiMbX ) );
      RNOK( m_cMbDataCtrlEL    .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );

      //--------------------------------------------------------
      //--- Perform some backup of BL and EL 
      // coeffs
      m_aMyBLTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB]->copyFrom(pcMbDataAccessBL->getMbData().getMbTCoeffs());
      m_aMyELTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB]->copyFrom(pcMbDataAccessEL->getMbData().getMbTCoeffs());
      // store CBP before update (but it seems not to have any influence)
      m_auiMbCbpStored[uiMbY+uiMbX*m_uiHeightInMB] = pcMbDataAccessBL->getMbData().getMbExtCbp();
      m_auiBCBPStored[uiMbY+uiMbX*m_uiHeightInMB] = pcMbDataAccessBL->getMbData().getBCBP();
      m_aiBLQP[uiMbY+uiMbX*m_uiHeightInMB] = pcMbDataAccessBL->getMbData().getQp();
      m_abELtransform8x8[uiMbY+uiMbX*m_uiHeightInMB] = pcMbDataAccessEL->getMbData().isTransformSize8x8();
    }
  }

    return Err::m_nOK;
}

ErrVal RQFGSEncoder::xRestoreCodingPath()
{
	//--ICU/ETRI FMO
	UInt uiFirstMbInSlice;
	UInt uiLastMbInSlice;
	
	if(m_pcSliceHeader !=NULL)
	{
		uiFirstMbInSlice  = m_pcSliceHeader->getFirstMbInSlice();
		uiLastMbInSlice  = m_pcSliceHeader->getLastMbInSlice();  
	}
	else
	{
		uiFirstMbInSlice =0;
		uiLastMbInSlice  = (m_uiWidthInMB*m_uiHeightInMB) -1;
		
	}

	for(UInt uiMbAddress= uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice ;)
	{
    UInt uiMbY  = uiMbAddress / m_uiWidthInMB;
    UInt uiMbX  = uiMbAddress % m_uiWidthInMB;


  {
    {
      //-------------------------------------------------------
      //--- Get MbData for BL and EL
      MbDataAccess* pcMbDataAccessBL = 0;
      MbDataAccess* pcMbDataAccessEL = 0;

      RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccessBL, uiMbY, uiMbX ) );
      RNOK( m_cMbDataCtrlEL    .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );

      //----- restore informations on BL and EL
      pcMbDataAccessBL->getMbData().setBCBP(m_auiBCBPStored[uiMbY+uiMbX*m_uiHeightInMB]);
      pcMbDataAccessBL->getMbData().setMbExtCbp(m_auiMbCbpStored[uiMbY+uiMbX*m_uiHeightInMB]);
      pcMbDataAccessBL->getMbData().setQp(m_aiBLQP[uiMbY+uiMbX*m_uiHeightInMB]);
      // restore Coeffs
      m_cMbDataCtrlEL.getMbData(uiMbX,uiMbY).getMbTCoeffs().copyFrom(*m_aMyELTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB]);
      m_pcCurrMbDataCtrl->getMbData(uiMbX,uiMbY).getMbTCoeffs().copyFrom(*m_aMyBLTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB]);
      pcMbDataAccessEL->getMbData().setTransformSize8x8( m_abELtransform8x8[uiMbY+uiMbX*m_uiHeightInMB] );

			//--ICU/ETRI FMO Implementation
	  if(m_pcSliceHeader !=NULL)
	    uiMbAddress = m_pcSliceHeader->getFMO()->getNextMBNr(uiMbAddress );
	  else
	   uiMbAddress ++;
    }
  }
	}	
    delete []m_aMyELTransformCoefs;
    delete []m_aMyBLTransformCoefs;

⌨️ 快捷键说明

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