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

📄 sliceencoder.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
ErrVal
SliceEncoder::encodeInterPicturePMbAff( UInt&         ruiBits,
                                        IntFrame*     pcOrgFrame,
                                        IntFrame*     pcFrame,
                                        IntFrame*     pcRecSubband,
                                        IntFrame*     pcPredSignal,
                                        ControlData&  rcControlData,
                                        UInt          uiMbInRow,
                                        RefFrameList& rcRefFrameList,
                                        RefFrameList& rcRefFrameListBase )
{
  ROF( m_bInitDone );

  SliceHeader&  rcSliceHeader						= *rcControlData.getSliceHeader          ( FRAME );
  MbDataCtrl*   pcMbDataCtrl						= rcControlData.getMbDataCtrl            ();
	IntFrame*     pcBaseLayerFrame        = rcControlData.getBaseLayerRec          ();
	IntFrame*     pcBaseLayerResidual     = rcControlData.getBaseLayerSbb          ();
  MbDataCtrl*   pcBaseLayerCtrl					= rcControlData.getBaseLayerCtrl         ();
  MbDataCtrl*   pcBaseLayerCtrlField  =  rcControlData.getBaseLayerCtrlField    ();
  Double        dLambda									= rcControlData.getLambda                ();
  Int           iSpatialScalabilityType = rcControlData.getSpatialScalabilityType(); // TMM_ESS
  UInt          uiBits									= m_pcMbCoder ->getBitCount              ();

  //====== initialization ======
  RNOK( pcMbDataCtrl      ->initSlice         ( rcSliceHeader, ENCODE_PROCESS, false, NULL ) );
  if( pcBaseLayerCtrl )
  {
    RNOK( pcBaseLayerCtrl ->initSlice         ( rcSliceHeader, PRE_PROCESS,    false, NULL ) );
  }
  if( pcBaseLayerCtrlField )
  {
    RNOK( pcBaseLayerCtrlField ->initSlice   ( rcSliceHeader, PRE_PROCESS,    false, NULL ) );
  }
  RNOK( m_pcControlMng    ->initSliceForCoding( rcSliceHeader ) );

  RefFrameList acRefFrameList    [2];
  RefFrameList acRefFrameListBase[2];

  IntYuvMbBuffer acIntYuvMbBufferPredSignal[2];
  IntYuvMbBuffer acIntYuvMbBufferRecSubBand[2];
  IntYuvMbBuffer acIntYuvMbBufferFrame     [2];

  RNOK( gSetFrameFieldLists( acRefFrameList    [0], acRefFrameList    [1], rcRefFrameList     ) );
  RNOK( gSetFrameFieldLists( acRefFrameListBase[0], acRefFrameListBase[1], rcRefFrameListBase ) );

  IntFrame* apcOrgFrame  [4] = { NULL, NULL, NULL, NULL };
  IntFrame* apcFrame     [4] = { NULL, NULL, NULL, NULL };
  IntFrame* apcRecSubband[4] = { NULL, NULL, NULL, NULL };
  IntFrame* apcPredSignal[4] = { NULL, NULL, NULL, NULL };
  IntFrame* apcBaseLayerF[4] = { NULL, NULL, NULL, NULL };
  IntFrame* apcBaseLayerR[4] = { NULL, NULL, NULL, NULL };

	RNOK( gSetFrameFieldArrays( apcFrame,      pcFrame             ) );
  RNOK( gSetFrameFieldArrays( apcOrgFrame,   pcOrgFrame          ) );
  RNOK( gSetFrameFieldArrays( apcRecSubband, pcRecSubband        ) );
  RNOK( gSetFrameFieldArrays( apcPredSignal, pcPredSignal        ) );
  RNOK( gSetFrameFieldArrays( apcBaseLayerF, pcBaseLayerFrame    ) );
  RNOK( gSetFrameFieldArrays( apcBaseLayerR, pcBaseLayerResidual ) );

//  const Bool bInheritFieldMode = ! rcSliceHeader.getSPS().getFieldFlagCoded() && (SCALABLE_PROFILE == rcSliceHeader.getSPS().getProfileIdc());
  MbDataBuffer acMbData[2];
  Bool   abSkipModeAllowed[4] = {true,true,true,true};
  UInt uiLastQp = rcSliceHeader.getPicQp();

  //===== loop over macroblocks =====
  UInt       uiMbAddress			= rcSliceHeader.getFirstMbInSlice();
  const UInt uiLastMbAddress	= rcSliceHeader.getLastMbInSlice  ();
  for( ; uiMbAddress <= uiLastMbAddress; uiMbAddress+=2 )
  {
    UInt auiLastQpTest[2] = {uiLastQp, uiLastQp};
    Double adCost[2] = {0,0};
	  Int eP;

    for( eP = 0; eP < 4; eP++ )
    {
      RefFrameList* pcRefFrameList;
      RefFrameList* pcRefFrameListBase;
      MbDataAccess* pcMbDataAccess     = NULL;
      MbDataAccess* pcMbDataAccessBase = NULL;
      Double        dCost = 0;
      UInt          uiMbY, uiMbX;

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

      if( bField )
      {
        pcRefFrameList     = acRefFrameList     + eP;
        pcRefFrameListBase = acRefFrameListBase + eP;
      }
      else
      {
        pcRefFrameList     = &rcRefFrameList;
        pcRefFrameListBase = &rcRefFrameListBase;
      }

      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->getMbData().deactivateMotionRefinement();

      pcMbDataAccess->setLastQp( auiLastQpTest[bField] );

      if( 0 == eP )
      {
        abSkipModeAllowed[1] = pcMbDataAccess->getDefaultFieldFlag(); // do not move
        abSkipModeAllowed[3] = ! abSkipModeAllowed[1];
      }

      pcRefFrameListBase = pcRefFrameListBase->getSize()? pcRefFrameListBase : NULL;

      RNOK( m_pcMbEncoder     ->encodeInterP    ( *pcMbDataAccess,
                                                   pcMbDataAccessBase,
                                                   iSpatialScalabilityType,
                                                   apcOrgFrame  [eP],
                                                   apcFrame     [eP],
                                                   apcRecSubband[eP],
                                                   apcPredSignal[eP],
                                                   apcBaseLayerF[eP],
                                                   apcBaseLayerR[eP],
                                                  *pcRefFrameList,
                                                   pcRefFrameListBase,
                                                   dLambda,
                                                   dCost,
                                                   abSkipModeAllowed[eP] ) );

      if( ! pcMbDataAccess->getMbData().isIntra() && pcMbDataAccess->getMbData().getResidualPredFlag( PART_16x16 ) )
      {
        pcMbDataAccess->getMbData().setMbExtCbp( pcMbDataAccess->getMbData().getMbExtCbp() | pcMbDataAccessBase->getMbData().getMbExtCbp() );
      }

      auiLastQpTest[bField] = pcMbDataAccess->getMbData().getQp();
      adCost [eP>>1] += dCost;

      if( bField )
      {
        acMbData[eP].copy( pcMbDataAccess->getMbData() );
        if( apcPredSignal [eP] ) acIntYuvMbBufferPredSignal[eP].loadBuffer( apcPredSignal [eP]->getFullPelYuvBuffer() );
        if( apcRecSubband [eP] ) acIntYuvMbBufferRecSubBand[eP].loadBuffer( apcRecSubband [eP]->getFullPelYuvBuffer() );
        if( apcFrame      [eP] ) acIntYuvMbBufferFrame     [eP].loadBuffer( apcFrame      [eP]->getFullPelYuvBuffer() );
      }
    }

    const Bool bFieldMode = ( adCost[0] < adCost[1] );
#ifdef RANDOM_MBAFF
    bFieldMode = gBoolRandom();
#endif
    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 ) );

      pcMbDataAccess->getMbData().deactivateMotionRefinement();

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

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

    }
  }

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

ErrVal
SliceEncoder::encodeSlice( SliceHeader&  rcSliceHeader,
                           IntFrame*     pcFrame,
                           MbDataCtrl*   pcMbDataCtrl,
                           RefFrameList& rcList0,
                           RefFrameList& rcList1,
                           UInt          uiMbInRow,
                           Double        dlambda )
{
  ROF( pcFrame );
  ROF( pcMbDataCtrl );

  //===== get co-located picture =====
  MbDataCtrl* pcMbDataCtrlL1 = NULL;
  if( rcList1.getActive() && rcList1.getEntry( 0 )->getRecPicBufUnit() )
  {
    pcMbDataCtrlL1 = rcList1.getEntry( 0 )->getRecPicBufUnit()->getMbDataCtrl();
  }
  ROT( rcSliceHeader.isInterB() && ! pcMbDataCtrlL1 );

  //===== initialization =====
  RNOK( pcMbDataCtrl  ->initSlice         ( rcSliceHeader, ENCODE_PROCESS, false, pcMbDataCtrlL1 ) );
  RNOK( m_pcControlMng->initSliceForCoding( rcSliceHeader ) );



  //===== loop over macroblocks =====
  for( UInt uiMbAddress = rcSliceHeader.getFirstMbInSlice(); uiMbAddress <= rcSliceHeader.getLastMbInSlice(); uiMbAddress = rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress ) )
  {
    ETRACE_NEWMB( uiMbAddress );

    UInt          uiMbY           = uiMbAddress / uiMbInRow;
    UInt          uiMbX           = uiMbAddress % uiMbInRow;
    MbDataAccess* pcMbDataAccess  = 0;

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

    RNOK( m_pcMbEncoder ->encodeMacroblock( *pcMbDataAccess,
                                             pcFrame,
                                             rcList0,
                                             rcList1,
                                             m_pcCodingParameter->getMotionVectorSearchParams().getNumMaxIter(),
                                             m_pcCodingParameter->getMotionVectorSearchParams().getIterSearchRange(),
                                             dlambda ) );
    RNOK( m_pcMbCoder   ->encode          ( *pcMbDataAccess,
                                              NULL,
                                              SST_RATIO_1,
                                             ( uiMbAddress == rcSliceHeader.getLastMbInSlice() )
                                             ,true ) );
  }

  return Err::m_nOK;
}

//TMM_WP
ErrVal SliceEncoder::xInitDefaultWeights(Double *pdWeights, UInt uiLumaWeightDenom,
                                         UInt uiChromaWeightDenom)
{
    const Int iLumaWeight = 1 << uiLumaWeightDenom;
    const Int iChromaWeight = 1 << uiChromaWeightDenom;

    pdWeights[0] = iLumaWeight;
    pdWeights[1] = pdWeights[2] = iChromaWeight;

    return Err::m_nOK;
}


ErrVal SliceEncoder::xSetPredWeights( SliceHeader& rcSH,
                                      IntFrame* pOrgFrame,
                                      RefFrameList& rcRefFrameList0,
                                      RefFrameList& rcRefFrameList1)

{
  RNOK( rcSH.getPredWeightTable(LIST_0).uninit() );
  RNOK( rcSH.getPredWeightTable(LIST_1).uninit() );
  RNOK( rcSH.getPredWeightTable(LIST_0).init( rcSH.getNumRefIdxActive( LIST_0) ) );
  RNOK( rcSH.getPredWeightTable(LIST_1).init( rcSH.getNumRefIdxActive( LIST_1) ) );

  ROTRS( rcSH.isIntra(), Err::m_nOK );

  const SampleWeightingParams& rcSWP = m_pcCodingParameter->getSampleWeightingParams(rcSH.getLayerId());

  { // determine denoms
    const UInt uiLumaDenom = rcSWP.getLumaDenom();
    rcSH.setLumaLog2WeightDenom  ( ( uiLumaDenom == MSYS_UINT_MAX ) ? gIntRandom(0,7) : uiLumaDenom );

    const UInt uiChromaDenom = rcSWP.getChromaDenom();
    rcSH.setChromaLog2WeightDenom( ( uiChromaDenom == MSYS_UINT_MAX ) ? gIntRandom(0,7) : uiChromaDenom );
  }

  const Int iChromaScale = 1<<rcSH.getChromaLog2WeightDenom();
  const Int iLumaScale   = 1<<rcSH.getLumaLog2WeightDenom();

   m_pcControlMng->initSliceForWeighting(rcSH);

⌨️ 快捷键说明

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