sliceencoder.cpp

来自「SVC最新更新代码」· C++ 代码 · 共 1,588 行 · 第 1/5 页

CPP
1,588
字号
    Double adCost[2]  = {0,0};

    YuvMbBuffer cTempBuffer;

    UInt auiLastQpTest[2] = {uiLastQp, uiLastQp};
    Int eP;
    for( eP = 0; eP < 4; eP++ )
    {
      MbDataAccess* pcMbDataAccess     = NULL;
      MbDataAccess* pcMbDataAccessBase = NULL;
      Double        dCost              = 0;
      UInt          uiMbY, uiMbX;

      const Bool    bField = (eP < 2);
      const UInt    uiMbAddressMbAff   = uiMbAddress+(eP%2);

      rcSliceHeader.getMbPositionFromAddress         ( uiMbY, uiMbX, uiMbAddressMbAff      );

      RNOK( pcMbDataCtrl      ->initMb               (  pcMbDataAccess,     uiMbY, uiMbX ) );

      if  (eP < 2 && pcBaseLayerCtrlField)  // field case
      {
        RNOK( pcBaseLayerCtrlField         ->initMb( pcMbDataAccessBase, uiMbY, uiMbX ) );
      }
      else if  (eP >= 2 && pcBaseLayerCtrl )  //frame case
      {
        RNOK( pcBaseLayerCtrl         ->initMb( pcMbDataAccessBase, uiMbY, uiMbX ) );
      }

      RNOK( m_pcControlMng    ->initMbForCoding ( *pcMbDataAccess,    uiMbY, uiMbX, true, bField ) );
			pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );

      if( ! rcSliceHeader.getNoInterLayerPredFlag() )
      {
        Int iField = ( bField ? 1 : 0 );
        m_pcMbEncoder->setBaseModeAllowedFlag( m_apabBaseModeFlagAllowedArrays[iField][uiMbAddressMbAff] );
      }

      pcMbDataAccess->setLastQp( auiLastQpTest[bField] );
      RNOK( m_pcMbEncoder     ->encodeIntra     ( *pcMbDataAccess,
                                                   pcMbDataAccessBase,
                                                   apcOrgFrame  [eP],
                                                   apcFrame     [eP],
                                                   apcRecSubband[eP],
                                                   apcBaseLayer [eP],
                                                   apcPredSignal[eP],
                                                   dLambda,
                                                   dCost ) );
      auiLastQpTest[bField] = pcMbDataAccess->getMbData().getQp();

      if( adCost[eP>>1] != DOUBLE_MAX )
      {
        adCost [eP>>1] += dCost;
      }
      if( bField )
      {
        acMbData[eP].copy( pcMbDataAccess->getMbData() );
        acIntYuvMbBufferPredSignal[eP].loadBuffer( apcPredSignal[eP]->getFullPelYuvBuffer() );
        acIntYuvMbBufferRecSubBand[eP].loadBuffer( apcRecSubband[eP]->getFullPelYuvBuffer() );
        acIntYuvMbBufferFrame     [eP].loadBuffer( apcFrame     [eP]->getFullPelYuvBuffer() );
      }
    }

    const Bool bFieldMode = ( adCost[0] < adCost[1] );
#ifdef RANDOM_MBAFF
    bFieldMode = gBoolRandom();
#endif

    // coding part

    for( eP = 0; eP < 2; eP++ )
    {
      MbDataAccess* pcMbDataAccess     = NULL;
      MbDataAccess* pcMbDataAccessBase = NULL;
      UInt          uiMbY, uiMbX;
      const UInt    uiMbAddressMbAff   = uiMbAddress+eP;

      ETRACE_NEWMB( uiMbAddressMbAff );

      rcSliceHeader.getMbPositionFromAddress    ( uiMbY, uiMbX, uiMbAddressMbAff );

      RNOK( pcMbDataCtrl      ->initMb          ( pcMbDataAccess,     uiMbY, uiMbX ) );

      if( bFieldMode && pcBaseLayerCtrlField )
      {
        RNOK( pcBaseLayerCtrlField ->initMb    ( pcMbDataAccessBase, uiMbY, uiMbX ) );
      }
      else if( !bFieldMode && pcBaseLayerCtrl )
      {
        RNOK( pcBaseLayerCtrl ->initMb          ( pcMbDataAccessBase, uiMbY, uiMbX ) );
      }

      RNOK( m_pcControlMng    ->initMbForCoding ( *pcMbDataAccess,    uiMbY, uiMbX, true, bFieldMode ) );

      if( bFieldMode )
      {
        pcMbDataAccess->getMbData().copy( acMbData[eP] );
        apcRecSubband [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferRecSubBand[eP] );
        apcPredSignal [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferPredSignal[eP] );
        apcFrame      [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferFrame     [eP] );
      }
      pcMbDataAccess->setLastQp( uiLastQp );
      uiLastQp = pcMbDataAccess->getMbData().getQp();
			pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );

      RNOK( m_pcMbCoder       ->encode          ( *pcMbDataAccess,
                                                   pcMbDataAccessBase,
                                                   ( uiMbAddressMbAff == uiLastMbAddress ),
                                                   (eP == 1) ) );
    }
  }

  ruiBits += m_pcMbCoder ->getBitCount() - uiBits;
	return Err::m_nOK;
}

// TMM_INTERLACE}


ErrVal SliceEncoder::encodeHighPassPicture( UInt&         ruiMbCoded,
                                            UInt&         ruiBits,
                                            SliceHeader&  rcSH,
                                            Frame*     pcOrgFrame,
                                            Frame*     pcFrame,
                                            Frame*     pcResidual,
                                            Frame*     pcPredSignal,
 																						Frame*     pcBaseSubband,
                                            Frame*     pcBaseLayer,
                                            MbDataCtrl*   pcMbDataCtrl,
                                            MbDataCtrl*   pcMbDataCtrlBaseMotion,
                                            UInt          uiMbInRow,
                                            Double        dLambda,
                                            Int           iMaxDeltaQp,
																						PicType      ePicType )
{
  ROF( m_bInitDone );

  RNOK( pcMbDataCtrl  ->initSlice         ( rcSH, PRE_PROCESS, false, NULL ) );
  RNOK( m_pcControlMng->initSliceForCoding( rcSH              ) );

  //====== initialization ======
  UInt            uiMbAddress       = rcSH.getFirstMbInSlice();
  UInt            uiLastMbAddress   = rcSH.getLastMbInSlice ();
  UInt            uiBits            = m_pcMbCoder->getBitCount();
  Int             iQPRes            = rcSH.getSliceQp();
  Int             iQPIntra          = rcSH.getSliceQp(); //- 2;

  YuvMbBuffer  cZeroBuffer;
  cZeroBuffer.setAllSamplesToZero();

	if( ePicType!=FRAME )
	{
    if( pcOrgFrame )    RNOK( pcOrgFrame   ->addFieldBuffer( ePicType ) ); //TMM
		if( pcFrame )       RNOK( pcFrame      ->addFieldBuffer( ePicType ) );
		if( pcResidual )    RNOK( pcResidual   ->addFieldBuffer( ePicType ) );
		if( pcBaseSubband ) RNOK( pcBaseSubband->addFieldBuffer( ePicType ) );
		if( pcBaseLayer )   RNOK( pcBaseLayer  ->addFieldBuffer( ePicType ) );
		if( pcPredSignal )  RNOK( pcPredSignal ->addFieldBuffer( ePicType ) );
	}

  //===== loop over macroblocks =====
  for(  ruiMbCoded = 0; uiMbAddress <= uiLastMbAddress;  ) //--ICU/ETRI FMO Implementation
  {
    // JVT-W043 {
    if ( bRateControlEnable && !pcJSVMParams->m_uiLayerId )
    {
      pcGenericRC->m_pcJSVMParams->number = pcGenericRC->m_pcJSVMParams->current_frame_number;      
      pcJSVMParams->CurrGopLevel = pcGenericRC->getCurrGopLevel( pcGenericRC->m_pcJSVMParams->number );
      pcGenericRC->m_pcJSVMParams->nal_reference_idc = (pcJSVMParams->CurrGopLevel == 0) ? 0 : 1;
      pcGenericRC->m_pcJSVMParams->current_mb_nr = uiMbAddress;

      if( pcGenericRC->m_pcJSVMParams->basicunit == pcGenericRC->m_pcJSVMParams->FrameSizeInMbs ) {
        // qp remains unchanged
      }
      // basic unit layer rate control
      else if ( pcGenericRC->m_pcJSVMParams->type == P_SLICE ) {
        if( pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks > 0 
          && (pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks % pcGenericRC->m_pcJSVMParams->BasicUnit) == 0 ) {
            // frame coding
            if( pcGenericRC->m_pcJSVMParams->frame_mbs_only_flag ) {
              pcQuadraticRC->updateRCModel();
              pcGenericRC->m_pcJSVMParams->qp = pcQuadraticRC->updateQPRC2( pcGenericRC->m_iTopFieldFlag );
              iQPRes = pcGenericRC->m_pcJSVMParams->qp;
            }
          }
      }
    }
    // JVT-W043 }
    ETRACE_NEWMB( uiMbAddress );

    MbDataAccess* pcMbDataAccess = NULL;
    Bool          bCoded;
    UInt          uiMbY, uiMbX;

    rcSH.getMbPositionFromAddress           ( uiMbY, uiMbX, uiMbAddress );

    RNOK( pcMbDataCtrl    ->initMb          (  pcMbDataAccess,    uiMbY, uiMbX ) );
    RNOK( m_pcControlMng  ->initMbForCoding ( *pcMbDataAccess,    uiMbY, uiMbX, false, false ) );

    MbDataAccess* pcMbDataAccessBase  = 0;

    if( pcMbDataCtrlBaseMotion)
    {
      RNOK( pcMbDataCtrlBaseMotion->initMb  ( pcMbDataAccessBase, uiMbY, uiMbX ) );
    }
    pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );

    if( pcMbDataAccess->getMbData().isIntra() )
    {
      Double dCost = 0;

      if( ! rcSH.getNoInterLayerPredFlag() )
      {
        m_pcMbEncoder->setBaseModeAllowedFlag( m_apabBaseModeFlagAllowedArrays[0][uiMbAddress] );
      }

      pcMbDataAccess->getMbData().setQp( iQPIntra );

      UInt  uiIPCMRate  = m_pcMbEncoder->getIPCMRate();
      Bool  bIPCM       = pcMbDataAccess->getMbData().isPCM();
      m_pcMbEncoder->setIPCMRate( bIPCM ? 100 : 0 ); // keep ICPM decision

      RNOK( m_pcMbEncoder ->encodeIntra   ( *pcMbDataAccess,
                                             pcMbDataAccessBase,
                                             pcFrame                  ->getPic( ePicType ),
                                             pcFrame                  ->getPic( ePicType ),
                                             pcResidual               ->getPic( ePicType ),
																						 pcBaseLayer ? pcBaseLayer->getPic( ePicType ) : NULL,
																						 pcPredSignal             ->getPic( ePicType ),
                                             dLambda,
                                             dCost ) );
      m_pcMbEncoder->setIPCMRate( uiIPCMRate );

      RNOK( m_pcMbCoder   ->encode        ( *pcMbDataAccess,
                                             pcMbDataAccessBase,
                                             (uiMbAddress == uiLastMbAddress ),
                                             true ) );
			ruiMbCoded++;
    }
    else
    {
      pcMbDataAccess->getMbData().setQp( iQPRes );

      m_pcTransform->setClipMode( false );
      RNOK( m_pcMbEncoder ->encodeResidual  ( *pcMbDataAccess,
                                               pcOrgFrame->getPic( ePicType ),
                                               pcFrame   ->getPic( ePicType ),
                                               pcResidual->getPic( ePicType ),
                                               pcBaseSubband ? pcBaseSubband->getPic( ePicType ) : NULL,
                                               bCoded,
                                               dLambda,
                                               iMaxDeltaQp ) );

      if( ! pcMbDataAccess->getSH().getNoInterLayerPredFlag() && ! pcMbDataAccess->getSH().getAdaptiveBaseModeFlag() && pcMbDataAccessBase->getMbData().getInCropWindowFlag() )
      {
        ROF( pcMbDataAccess->getMbData().getResidualPredFlag() );
        pcMbDataAccess->getMbData().setBLSkipFlag( true );
      }

      m_pcTransform->setClipMode( true );

      RNOK( m_pcMbCoder->encode( *pcMbDataAccess, pcMbDataAccessBase, (uiMbAddress == uiLastMbAddress ), true ) );

      if( bCoded )
      {
        ruiMbCoded++;
      }
      // JVT-W043 {
      if ( bRateControlEnable && !pcJSVMParams->m_uiLayerId )
      {
        pcGenericRC->m_iNumberofHeaderBits           += pcGenericRC->m_iRCHeaderBits;
        pcGenericRC->m_iNumberofBasicUnitHeaderBits  += pcGenericRC->m_iRCHeaderBits;
        pcGenericRC->m_iNumberofTextureBits          += pcGenericRC->m_iRCTextureBits;
        pcGenericRC->m_iNumberofBasicUnitTextureBits += pcGenericRC->m_iRCTextureBits;
        pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks++;
      }
      // JVT-W043 }
      // Update the state of the baselayer residual data -- it may be reused in subsequent layers - ASEGALL@SHARPLABS.COM
      if( pcBaseSubband && ( pcMbDataAccess->getMbData().isIntra() || ! pcMbDataAccess->getMbData().getResidualPredFlag() ) )	
      {
        YuvPicBuffer* pcBaseResidual = pcBaseSubband->getPic( ePicType )->getFullPelYuvBuffer();
        pcBaseResidual->clearCurrMb();
      }

	    RNOK( pcPredSignal->getFullPelYuvBuffer()->loadBuffer( &cZeroBuffer ) );
    }

    uiMbAddress = rcSH.getFMO()->getNextMBNr(uiMbAddress);
  }

  if( ePicType!=FRAME )
	{
		if( pcFrame )       RNOK( pcFrame      ->removeFieldBuffer( ePicType ) );
		if( pcResidual )    RNOK( pcResidual   ->removeFieldBuffer( ePicType ) );
		if( pcBaseSubband ) RNOK( pcBaseSubband->removeFieldBuffer( ePicType ) );
		if( pcBaseLayer )   RNOK( pcBaseLayer  ->removeFieldBuffer( ePicType ) );
		if( pcPredSignal )  RNOK( pcPredSignal ->removeFieldBuffer( ePicType ) );
	}

  ruiBits += m_pcMbCoder->getBitCount() - uiBits;

  return Err::m_nOK;
}

// TMM_INTERLACE{
ErrVal SliceEncoder::encodeHighPassPictureMbAff( UInt&				ruiMbCoded,
                                                 UInt&				ruiBits,
                                                 SliceHeader&	rcSH,
                                                 Frame*    pcOrgFrame,
                                                 Frame*    pcFrame,
                                                 Frame*    pcResidual,
                                                 Frame*    pcPredSignal,
     																						 Frame*    pcBaseSubband,
                                                 Frame*    pcBaseLayer,
                                                 MbDataCtrl*	pcMbDataCtrl,
                                                 MbDataCtrl*  pcMbDataCtrlBaseMotion,
                                                 MbDataCtrl*   pcMbDataCtrlInterlBaseMotion,
                                                 UInt					uiMbInRow,

⌨️ 快捷键说明

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