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

📄 mctf.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                                              *pcOrigFrame, *m_pcFrameTemp,
                                              false, 4, 8, false, rcControlData.getLambda() ) );
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xMotionCompensation( IntFrame*        pcMCFrame,
                           RefFrameList*    pcRefFrameList0,
                           RefFrameList*    pcRefFrameList1,
                           MbDataCtrl*      pcMbDataCtrl,
                           SliceHeader&     rcSH )
{
  RNOK( pcMbDataCtrl        ->initSlice( rcSH, PRE_PROCESS, false, NULL ) );
  RNOK( m_pcMotionEstimation->initSlice( rcSH ) );

  for( UInt uiMbIndex = 0; uiMbIndex < m_uiMbNumber; uiMbIndex++ )
  {
    UInt          uiMbY           = uiMbIndex / m_uiFrameWidthInMb;
    UInt          uiMbX           = uiMbIndex % m_uiFrameWidthInMb;
    MbDataAccess* pcMbDataAccess  = 0;

    RNOK( pcMbDataCtrl            ->initMb    ( pcMbDataAccess, uiMbY, uiMbX ) );
    RNOK( m_pcYuvFullPelBufferCtrl->initMb    (                 uiMbY, uiMbX ) );
    RNOK( m_pcYuvHalfPelBufferCtrl->initMb    (                 uiMbY, uiMbX ) );
    RNOK( m_pcMotionEstimation    ->initMb    (                 uiMbY, uiMbX, *pcMbDataAccess ) );

    RNOK( m_pcMbEncoder->compensatePrediction ( *pcMbDataAccess, pcMCFrame,
                                                *pcRefFrameList0, *pcRefFrameList1,
                                                false, false ) );
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xGetConnections( Double&  rdL0Rate,
                       Double&  rdL1Rate,
                       Double&  rdBiRate )
{
  //=== just a guess ===
  rdL0Rate = 0.2;
  rdL1Rate = 0.2;
  rdBiRate = 0.6;
  return Err::m_nOK;
}


ErrVal
MCTF::xZeroIntraMacroblocks( IntFrame*    pcFrame,
                             ControlData& rcCtrlData )
{
  MbDataCtrl*       pcMbDataCtrl  = rcCtrlData.getMbDataCtrl       ();
  SliceHeader*      pcSliceHeader = rcCtrlData.getSliceHeader      ();
  IntYuvPicBuffer*  pcPicBuffer   = pcFrame  ->getFullPelYuvBuffer ();

  RNOK( pcMbDataCtrl->initSlice( *pcSliceHeader, PRE_PROCESS, false, NULL ) );

  IntYuvMbBuffer cZeroMbBuffer;
  cZeroMbBuffer.setAllSamplesToZero();

  for( UInt uiMbIndex = 0; uiMbIndex < m_uiMbNumber; uiMbIndex++ )
  {
    UInt          uiMbY           = uiMbIndex / m_uiFrameWidthInMb;
    UInt          uiMbX           = uiMbIndex % m_uiFrameWidthInMb;
    MbDataAccess* pcMbDataAccess  = 0;

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

    if( pcMbDataAccess->getMbData().isIntra() )
    {
      pcPicBuffer->loadBuffer( &cZeroMbBuffer );
    }
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xInitGOP( PicBufferList&  rcPicBufferInputList )
{
  //========== INITIALIZE DECOMPOSITION STRUCTURES ==========
  PicBufferList::iterator cInputIter    = rcPicBufferInputList.begin();
  UInt                    uiFrame       = 0;
  UInt                    uiOldGOPSize  = m_uiGOPSize;
  m_uiGOPSize                           = rcPicBufferInputList.size () - ( m_bFirstGOPCoded ? 0 : 1 );
  if( m_bFirstGOPCoded )
  {
    m_papcFrame[ uiFrame++ ]->copyAll( m_papcFrame[ uiOldGOPSize ] );
  }
  for( ; uiFrame <= m_uiGOPSize; uiFrame++, cInputIter++ )
  {
    m_papcFrame[ uiFrame   ]->load   ( *cInputIter );
  }

  //========== INITIALIZE SLICE HEADERS (the decomposition structure is determined at this point) ==========
  if( ! m_bFirstGOPCoded )
  {
    RNOK  ( xInitSliceHeader( 0, 0 ) );
  }
  UInt uiTemporalLevel;
  for( uiTemporalLevel = 0; uiTemporalLevel <= m_uiDecompositionStages; uiTemporalLevel++ )
  {
    UInt      uiStep    = ( 1 << ( m_uiDecompositionStages - uiTemporalLevel ) );
    for( UInt uiFrameId = uiStep; uiFrameId <= m_uiGOPSize; uiFrameId += ( uiStep << 1 ) )
    {
      RNOK( xInitSliceHeader( uiTemporalLevel, uiFrameId ) );
    }
  }

  //========== INITIALIZE SCALING FACTORS ==========
  for( uiFrame = 0; uiFrame <= m_uiGOPSize; uiFrame++ )
  {
    m_pacControlData      [ uiFrame ].clear();
    m_pacControlData      [ uiFrame ].setScalingFactor( 1.0 );
    RNOK( m_pacControlData[ uiFrame ].getMbDataCtrl()->reset () );
    RNOK( m_pacControlData[ uiFrame ].getMbDataCtrl()->clear () );
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xGetListSizes( UInt  uiTemporalLevel,
                     UInt  uiFrameIdInGOP,
                     UInt  auiPredListSize[2],
                     UInt  aauiUpdListSize[MAX_DSTAGES][2] )
{
  //----- clear update list sizes -----
  ::memset( aauiUpdListSize, 0x00, 2 * MAX_DSTAGES * sizeof( UInt ) );

  //----- loop over prediction and update steps -----
  for( UInt uiLevel = uiTemporalLevel; uiLevel <= m_uiDecompositionStages; uiLevel++ )
  {
    //----- get parameters base GOP size and cut-off frame id -----
    UInt  uiBaseLevel       = m_uiDecompositionStages - uiLevel;
    UInt  uiFrameIdLevel    = uiFrameIdInGOP >> uiBaseLevel;
    UInt  uiBaseGOPSize     = ( 1 << m_uiDecompositionStages ) >> uiBaseLevel;

    if( uiLevel == uiTemporalLevel )
    {
      //=========== PREDICTION LIST SIZES ==========
      auiPredListSize[0]    = ( uiFrameIdLevel + 1 ) >> 1;
      UInt  uiFrameIdWrap   = ( uiFrameIdLevel % uiBaseGOPSize );
      if( uiFrameIdWrap > 0 )
      {
        auiPredListSize[1]  = ( uiBaseGOPSize - uiFrameIdWrap + 1 ) >> 1;
      }
      else
      {
        auiPredListSize[1]  = ( uiFrameIdWrap + 1 ) >> 1;
      }
      auiPredListSize[0]    = min( 1, auiPredListSize[0] );
      auiPredListSize[1]    = min( 1, auiPredListSize[1] );
      UInt  uiMaxL1Size     = ( ( m_uiGOPSize >> uiBaseLevel ) + 1 - uiFrameIdLevel ) >> 1;
      auiPredListSize[1]    = min( uiMaxL1Size, auiPredListSize[1] );
    }
    else
    {
      //========== UPDATE LIST SIZES ==========
      UInt* pauiUpdListSize = aauiUpdListSize[uiLevel-1];
      UInt  uiFrameIdWrap   = ( uiFrameIdLevel == 0 ? 0 : ( ( uiFrameIdLevel - 1 ) % uiBaseGOPSize ) + 1 );
      if( uiFrameIdWrap > 0 )
      {
        pauiUpdListSize[0]  = uiFrameIdWrap >> 1;
        pauiUpdListSize[1]  = ( uiBaseGOPSize - uiFrameIdWrap ) >> 1;
      }
      else
      {
        pauiUpdListSize[0]  = uiFrameIdWrap >> 1;
        pauiUpdListSize[1]  = ( uiFrameIdLevel == 0 ? 0 : ( 1 - uiFrameIdWrap ) >> 1 );
      }
      pauiUpdListSize[0]    = min( 1, pauiUpdListSize[0] );
      pauiUpdListSize[1]    = min( 1, pauiUpdListSize[1] );
      UInt  uiMaxL1Size     = ( ( m_uiGOPSize >> uiBaseLevel ) + 1 - uiFrameIdLevel ) >> 1;
      pauiUpdListSize[1]    = min( uiMaxL1Size, pauiUpdListSize[1] );
    }
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xInitSliceHeader( UInt uiTemporalLevel,
                        UInt uiFrameIdInGOP )
{
  SliceHeader*  pcSliceHeader = m_pacControlData[ uiFrameIdInGOP ].getSliceHeader();
  ROF( pcSliceHeader );

  //===== get maximum sizes of prediction and update lists ( decomposition structure ) =====
  UInt  auiPredListSize             [2];
  UInt  aauiUpdListSize[MAX_DSTAGES][2];
  RNOK( xGetListSizes( uiTemporalLevel, uiFrameIdInGOP, auiPredListSize, aauiUpdListSize ) );

  //===== get slice header parameters =====
  SliceType     eSliceType      = ( auiPredListSize[1] ? B_SLICE : auiPredListSize[0] ? P_SLICE : I_SLICE );

  //===== set simple slice header parameters =====
  pcSliceHeader->setNalUnitType                 ( NAL_UNIT_CODED_SLICE_SCALABLE );
  pcSliceHeader->setFirstMbInSlice              ( 0                     );
  pcSliceHeader->setLastMbInSlice               ( m_uiMbNumber - 1      );
  pcSliceHeader->setNumMbsInSlice               ( m_uiMbNumber          );
  pcSliceHeader->setSliceType                   ( eSliceType            );
  pcSliceHeader->setDirectSpatialMvPredFlag     ( true                  );

  //===== set prediction and update list sizes =====
  pcSliceHeader->setNumRefIdxActive( LIST_0, 0 );
  pcSliceHeader->setNumRefIdxActive( LIST_1, 0 );

  UInt  uiMaxLists = ( eSliceType == B_SLICE ? 2 : eSliceType == P_SLICE ? 1 : 0 );
  for( UInt uiList = 0; uiList < uiMaxLists; uiList++ )
  {
    ListIdx eListIdx  = ListIdx( uiList );
    ROF( auiPredListSize[ uiList ] );

    pcSliceHeader->setNumRefIdxActive( eListIdx, auiPredListSize[ uiList ] );
    if( pcSliceHeader->getPPS().getNumRefIdxActive( eListIdx ) != auiPredListSize[ uiList ] )
    {
      pcSliceHeader->setNumRefIdxActiveOverrideFlag( true );
    }
  }
  for( UInt uiLevel = uiTemporalLevel; uiLevel < m_uiDecompositionStages; uiLevel++ )
  {
    pcSliceHeader->setNumRefIdxUpdate( uiLevel, LIST_0, aauiUpdListSize[uiLevel][0] );
    pcSliceHeader->setNumRefIdxUpdate( uiLevel, LIST_1, aauiUpdListSize[uiLevel][1] );
  }

  //===== pred weights =====
  RNOK( pcSliceHeader->getPredWeightTable(LIST_0).uninit() );
  RNOK( pcSliceHeader->getPredWeightTable(LIST_1).uninit() );
  RNOK( pcSliceHeader->getPredWeightTable(LIST_0).init( pcSliceHeader->getNumRefIdxActive( LIST_0) ) );
  RNOK( pcSliceHeader->getPredWeightTable(LIST_1).init( pcSliceHeader->getNumRefIdxActive( LIST_1) ) );
  RNOK( pcSliceHeader->getPredWeightTable(LIST_1).initDefaults( pcSliceHeader->getLumaLog2WeightDenom(), pcSliceHeader->getChromaLog2WeightDenom() ) );
  RNOK( pcSliceHeader->getPredWeightTable(LIST_0).initDefaults( pcSliceHeader->getLumaLog2WeightDenom(), pcSliceHeader->getChromaLog2WeightDenom() ) );

  return Err::m_nOK;
}


ErrVal
MCTF::xSetScalingFactors( UInt uiBaseLevel )
{
  Double  adRateL0 [( 1 << MAX_DSTAGES )];
  Double  adRateL1 [( 1 << MAX_DSTAGES )];
  Double  adRateBi [( 1 << MAX_DSTAGES )];

  Double  dScalingBase    = m_pacControlData[0].getScalingFactor();
  Double  dScalingLowPass = 0.0;
  Int     iLowPassSize    = ( m_uiGOPSize >> uiBaseLevel );
  Int     iFrame;

  //===== get connection data =====
  for( iFrame = 1; iFrame <= iLowPassSize; iFrame += 2 )
  {
    RNOK( xGetConnections( adRateL0[iFrame], adRateL1[iFrame], adRateBi[iFrame] ) );
  }

  //===== get low-pass scaling =====
  for( iFrame = 0; iFrame <= iLowPassSize; iFrame += 2 )
  {
    Double  dScalLPCurr = 1.0;

    if( iFrame > 0 )
    {
      if( ( iFrame + 1 ) < iLowPassSize )
      {
        dScalLPCurr = ( adRateBi[iFrame-1] + adRateBi[iFrame+1] ) * ( FACTOR_53_LP - 1.0 ) / 2.0 +
                      ( adRateL1[iFrame-1] + adRateL0[iFrame+1] ) * ( FACTOR_22_LP - 1.0 ) / 2.0 + 1.0;
      }
      else
      {
        dScalLPCurr = ( adRateBi[iFrame-1] / 2.0 ) * ( FACTOR_53_LP - 1.0 ) +
                      ( adRateL1[iFrame-1]       ) * ( FACTOR_22_LP - 1.0 ) + 1.0;
      }
    }
    else
    {
      if( iLowPassSize )
      {
        dScalLPCurr = ( adRateBi[iFrame+1] / 2.0 ) * ( FACTOR_53_LP - 1.0 ) +
                      ( adRateL0[iFrame+1]       ) * ( FACTOR_22_LP - 1.0 ) + 1.0;
      }
    }

    dScalingLowPass += dScalLPCurr;
  }
  dScalingLowPass /= (Double)( 1 + ( iLowPassSize >> 1 ) );

  Double dFactor53 = FACTOR_53_HP;
  Double dFactor22 = FACTOR_22_HP;

  //===== get high-pass scaling and set scaling factors =====
  for( iFrame = 0; iFrame <= iLowPassSize; iFrame++ )
  {
    Double dScal = dScalingBase;

    if( iFrame % 2 )
    {
      dScal *= ( adRateBi[iFrame]                    ) * ( dFactor53 - 1.0 ) +
               ( adRateL0[iFrame] + adRateL1[iFrame] ) * ( dFactor22 - 1.0 ) + 1.0;
    }
    else
    {
      dScal *= dScalingLowPass;
    }
    m_pacControlData[ iFrame << uiBaseLevel ].setScalingFactor( dScal );
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xClearBufferExtensions()
{
  for( UInt uiFrame = 0; uiFrame <= m_uiGOPSize; uiFrame++ )
  {
    RNOK( m_papcFrame   [uiFrame]->uninitHalfPel() );
    RNOK( m_papcResidual[uiFrame]->uninitHalfPel() );
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xGetPredictionLists( RefFrameList& rcRefList0,
                           RefFrameList& rcRefList1,
                           UInt          uiBaseLevel,
                           UInt          uiFrame,
                           Bool          bHalfPel )
{
  rcRefList0.reset();
  rcRefList1.reset();

  UInt          uiFrameIdInGOP  = ( uiFrame << uiBaseLevel );
  SliceHeader*  pcSliceHeader   = m_pacControlData[uiFrameIdInGOP].getSliceHeader();
  UInt          uiList0Size     = pcSliceHeader->getNumRefIdxActive( LIST_0 );
  UInt          uiList1Size     = pcSliceHeader->getNumRefIdxActive( LIST_1 );

  //===== list 0 =====
  {
    Int iFrameId;
    for( iFrameId = Int( uiFrame - 1 ); iFrameId >= 0 && uiList0Size; iFrameId -= 2 )
    {
      IntFrame* pcFrame = m_papcFrame[ iFrameId << uiBaseLevel ];
      if( ! pcFrame->isExtended() )
      {

⌨️ 快捷键说明

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