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

📄 mctf.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        if( bHalfPel )
        {
          RNOK( xFillAndUpsampleFrame ( pcFrame ) );
        }
        else
        {
          RNOK( xFillAndExtendFrame   ( pcFrame ) );
        }
      }
      RNOK( rcRefList0.add( pcFrame ) );
      uiList0Size--;
    }
    ROT( uiList0Size );
  }

  //===== list 1 =====
  {
    Int iFrameId;
    for( iFrameId = Int( uiFrame + 1 ); iFrameId <= (Int)( m_uiGOPSize >> uiBaseLevel ) && uiList1Size; iFrameId += 2 )
    {
      IntFrame* pcFrame = m_papcFrame[ iFrameId << uiBaseLevel ];
      if( ! pcFrame->isExtended() )
      {
        if( bHalfPel )
        {
          RNOK( xFillAndUpsampleFrame ( pcFrame ) );
        }
        else
        {
          RNOK( xFillAndExtendFrame   ( pcFrame ) );
        }
      }
      RNOK( rcRefList1.add( pcFrame ) );
      uiList1Size--;
    }
    ROT( uiList1Size );
  }

  return Err::m_nOK;
}


ErrVal  
MCTF::xGetUpdateLists( RefFrameList& rcRefList0,
                       RefFrameList& rcRefList1,
                       CtrlDataList& rcCtrlList0,
                       CtrlDataList& rcCtrlList1,
                       UInt          uiBaseLevel,
                       UInt          uiFrame )
{
  rcRefList0  .reset();
  rcRefList1  .reset();
  rcCtrlList0 .reset();
  rcCtrlList1 .reset();

  UInt          uiFrameIdInGOP  = ( uiFrame << uiBaseLevel );
  SliceHeader*  pcSliceHeader   = m_pacControlData[uiFrameIdInGOP].getSliceHeader();
  UInt          uiUpdateLevel   = m_uiDecompositionStages - uiBaseLevel - 1;
  UInt          uiList0Size     = pcSliceHeader->getNumRefIdxUpdate( uiUpdateLevel, LIST_0 );
  UInt          uiList1Size     = pcSliceHeader->getNumRefIdxUpdate( uiUpdateLevel, LIST_1 );

  //===== list 0 =====
  {
    for( Int iFrameId = Int( uiFrame - 1 ); iFrameId >= 0 && uiList0Size; iFrameId -= 2 )
    {
      IntFrame*     pcFrame       =  m_papcResidual   [ iFrameId << uiBaseLevel ];
      ControlData*  pcControlData = &m_pacControlData [ iFrameId << uiBaseLevel ];
      if( ! pcFrame->isExtended() )
      {
        RNOK( xFillAndExtendFrame( pcFrame ) );
      }
      RNOK( rcRefList0  .add( pcFrame ) );
      RNOK( rcCtrlList0 .add( pcControlData ) );
      uiList0Size--;
    }
    ROT( uiList0Size );
  }

  //===== list 1 =====
  {
    for( Int iFrameId = Int( uiFrame + 1 ); iFrameId <= (Int)( m_uiGOPSize >> uiBaseLevel ) && uiList1Size; iFrameId += 2 )
    {
      IntFrame*     pcFrame       =  m_papcResidual   [ iFrameId << uiBaseLevel ];
      ControlData*  pcControlData = &m_pacControlData [ iFrameId << uiBaseLevel ];
      if( ! pcFrame->isExtended() )
      {
        RNOK( xFillAndExtendFrame( pcFrame ) );
      }
      RNOK( rcRefList1  .add( pcFrame ) );
      RNOK( rcCtrlList1 .add( pcControlData ) );
      uiList1Size--;
    }
    ROT( uiList1Size );
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xInitControlDataMotion( UInt uiBaseLevel,
                              UInt uiFrame,
                              Bool bMotionEstimation )
{
  UInt            uiFrameIdInGOP    = uiFrame << uiBaseLevel;
  ControlData&    rcControlData     = m_pacControlData[uiFrameIdInGOP];
  SliceHeader*    pcSliceHeader     = rcControlData.getSliceHeader  ();
  MbDataCtrl*     pcMbDataCtrl      = rcControlData.getMbDataCtrl   ();
  Double          dScalFactor       = rcControlData.getScalingFactor() * FACTOR_53_HP;
  Double          dQpPredData       = m_adBaseQpLambdaMotion[ uiBaseLevel ] - 6.0 * log10( dScalFactor ) / log10( 2.0 );
  Double          dLambda           = 0.85 * pow( 2.0, min( 52.0, dQpPredData ) / 3.0 - 4.0 );
  Int             iQp               = max( MIN_QP, min( MAX_QP, (Int)floor( dQpPredData + 0.5 ) ) );

  pcSliceHeader->setSliceHeaderQp( iQp );
  rcControlData. setLambda       ( dLambda );

  if( bMotionEstimation )
  {
    RNOK( pcMbDataCtrl->initSlice( *pcSliceHeader, ENCODE_PROCESS, false, NULL ) );
  }

  return Err::m_nOK;
}


ErrVal
MCTF::xMotionEstimationStage( UInt uiBaseLevel )
{
  for( UInt uiFrame = 1; uiFrame <= ( m_uiGOPSize >> uiBaseLevel ); uiFrame += 2 )
  {
    printf(".");
    UInt          uiFrameIdInGOP  = uiFrame << uiBaseLevel;
    ControlData&  rcControlData   = m_pacControlData[uiFrameIdInGOP];
    IntFrame*     pcFrame         = m_papcFrame     [uiFrameIdInGOP];

    //===== get reference frame lists =====
    RefFrameList& rcRefFrameList0 = rcControlData.getPrdFrameList( LIST_0 );
    RefFrameList& rcRefFrameList1 = rcControlData.getPrdFrameList( LIST_1 );
    RNOK( xGetPredictionLists   ( rcRefFrameList0, rcRefFrameList1, uiBaseLevel, uiFrame, true ) );
    RNOK( xInitControlDataMotion( uiBaseLevel, uiFrame, true ) );
    RNOK( xMotionEstimation     ( &rcRefFrameList0, &rcRefFrameList1, pcFrame, rcControlData ) );
  }
  RNOK( xClearBufferExtensions() );

  return Err::m_nOK;
}


ErrVal
MCTF::xDecompositionStage( UInt uiBaseLevel )
{
  //===== PREDICTION =====
  for( UInt uiFramePrd  = 1; uiFramePrd <= ( m_uiGOPSize >> uiBaseLevel ); uiFramePrd += 2 )
  {
    UInt          uiFrameIdInGOP  = uiFramePrd << uiBaseLevel;
    ControlData&  rcControlData   = m_pacControlData[uiFrameIdInGOP];
    IntFrame*     pcFrame         = m_papcFrame     [uiFrameIdInGOP];
    IntFrame*     pcResidual      = m_papcResidual  [uiFrameIdInGOP];
    IntFrame*     pcMCFrame       = m_pcFrameTemp;

    RefFrameList& rcRefFrameList0 = rcControlData.getPrdFrameList( LIST_0 );
    RefFrameList& rcRefFrameList1 = rcControlData.getPrdFrameList( LIST_1 );
    RNOK( xGetPredictionLists   ( rcRefFrameList0, rcRefFrameList1, uiBaseLevel, uiFramePrd, false ) );
    RNOK( xInitControlDataMotion( uiBaseLevel, uiFramePrd, false ) );
    RNOK( xMotionCompensation   ( pcMCFrame, &rcRefFrameList0, &rcRefFrameList1,
                                  rcControlData.getMbDataCtrl(), *rcControlData.getSliceHeader() ) );
    RNOK( pcFrame ->prediction  ( pcMCFrame, pcFrame ) );
    RNOK( pcResidual->copy      ( pcFrame ) );
    RNOK( xZeroIntraMacroblocks ( pcResidual, rcControlData ) );
  }
  RNOK  ( xClearBufferExtensions() );

  //===== UPDATE =====
  for( UInt uiFrameUpd = 2; uiFrameUpd <= ( m_uiGOPSize >> uiBaseLevel ); uiFrameUpd += 2 )
  {
    UInt          uiFrameIdInGOP  = uiFrameUpd << uiBaseLevel;
    IntFrame*     pcFrame         = m_papcFrame     [uiFrameIdInGOP];

    RefFrameList  acRefFrameListUpd[2];
    CtrlDataList  acCtrlDataList[2];
    RNOK( xGetUpdateLists       ( acRefFrameListUpd[0], acRefFrameListUpd[1],
                                  acCtrlDataList[0], acCtrlDataList[1], uiBaseLevel, uiFrameUpd ) );
    RNOK( xUpdateCompensation   ( pcFrame, &acRefFrameListUpd[0], &acCtrlDataList[0], LIST_0 ) );
    RNOK( xUpdateCompensation   ( pcFrame, &acRefFrameListUpd[1], &acCtrlDataList[1], LIST_1 ) );
  }
  RNOK  ( xClearBufferExtensions() );

  return Err::m_nOK;
}


ErrVal
MCTF::xCompositionStage( UInt           uiBaseLevel,
                         PicBufferList& rcPicBufferInputList )
{
  //===== PREDICTION =====
  for( UInt uiFramePrd  = 1; uiFramePrd <= ( m_uiGOPSize >> uiBaseLevel ); uiFramePrd += 2 )
  {
    UInt          uiFrameIdInGOP  = uiFramePrd << uiBaseLevel;
    ControlData&  rcControlData   = m_pacControlData[uiFrameIdInGOP];
    IntFrame*     pcFrame         = m_papcFrame     [uiFrameIdInGOP];
    IntFrame*     pcMCFrame       = m_pcFrameTemp;

    RefFrameList& rcRefFrameList0 = rcControlData.getPrdFrameList( LIST_0 );
    RefFrameList& rcRefFrameList1 = rcControlData.getPrdFrameList( LIST_1 );
    RNOK( xGetPredictionLists         ( rcRefFrameList0, rcRefFrameList1,
                                        uiBaseLevel, uiFramePrd, false ) );
    RNOK( xMotionCompensation         ( pcMCFrame, &rcRefFrameList0, &rcRefFrameList1,
                                        rcControlData.getMbDataCtrl(), *rcControlData.getSliceHeader() ) );
    RNOK( pcFrame ->inversePrediction ( pcMCFrame, pcFrame ) );
  }
  RNOK( xClearBufferExtensions() );

  return Err::m_nOK;
}


ErrVal
MCTF::xStoreReconstruction( PicBufferList&  rcPicBufferOutputList )
{
  PicBufferList::iterator cOutputIter = rcPicBufferOutputList.begin();
  for( UInt uiIndex = (m_bFirstGOPCoded?1:0); uiIndex <= m_uiGOPSize; uiIndex++, cOutputIter++ )
  {
    RNOK( m_papcFrame[uiIndex]->store( *cOutputIter ) );
  }
  return Err::m_nOK;
}


ErrVal
MCTF::xProcessGOP( PicBufferList&    rcPicBufferInputList,
                   PicBufferList&    rcPicBufferOutputList,
                   PicBufferList&    rcPicBufferUnusedList )
{
  RNOK( xInitGOP( rcPicBufferInputList ) );

  for( Int iLevel = 0; iLevel < (Int)m_uiDecompositionStages; iLevel++ )
  {
    RNOK( xMotionEstimationStage  ( iLevel ) );
    RNOK( xDecompositionStage     ( iLevel ) );
    RNOK( xSetScalingFactors      ( iLevel ) );
  }

  UInt   uiStage    = m_uiDecompositionStages;
  while( uiStage--  > 0 )
  {
    RNOK( xCompositionStage( uiStage, rcPicBufferInputList ) );
  }

  RNOK( xStoreReconstruction( rcPicBufferOutputList ) );
  RNOK( xFinishGOP          ( rcPicBufferInputList,
                              rcPicBufferOutputList,
                              rcPicBufferUnusedList ) );

  return Err::m_nOK;
}


ErrVal
MCTF::xFinishGOP( PicBufferList& rcPicBufferInputList,
                  PicBufferList& rcPicBufferOutputList,
                  PicBufferList& rcPicBufferUnusedList )
{
  while( rcPicBufferOutputList.size() > m_uiGOPSize + ( m_bFirstGOPCoded ? 0 : 1 ) )
  {
    PicBuffer*  pcPicBuffer = rcPicBufferOutputList.popBack();
    rcPicBufferUnusedList.push_back( pcPicBuffer );
  }
  m_bFirstGOPCoded = true;

  return Err::m_nOK;
}


ErrVal
MCTF::xUpdateCompensation( IntFrame*        pcMCFrame,
                           RefFrameList*    pcRefFrameList,
                           CtrlDataList*    pcCtrlDataList,
                           ListIdx          eListUpd)
{
  ROFRS( pcCtrlDataList->getActive(), Err::m_nOK );

  ListIdx eListPrd = ListIdx( 1-eListUpd );
  for( Int iRefIdx = 1; iRefIdx <= (Int)pcCtrlDataList->getActive(); iRefIdx++ )    
  {
    for( UInt uiMbIndex = 0; uiMbIndex < m_uiMbNumber; uiMbIndex++ )
    {
      UInt          uiMbY           = uiMbIndex / m_uiFrameWidthInMb;
      UInt          uiMbX           = uiMbIndex % m_uiFrameWidthInMb;
      MbDataCtrl*   pcMbDataCtrlPrd = (*pcCtrlDataList)[ iRefIdx ]->getMbDataCtrl();
      MbDataAccess* pcMbDataAccess  = 0;

      RNOK( pcMbDataCtrlPrd         ->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->compensateUpdate ( *pcMbDataAccess, pcMCFrame,
                                              iRefIdx, eListPrd, (*pcRefFrameList)[ iRefIdx ] ) );
    }
  }

  return Err::m_nOK;
}


ErrVal
MCTF::process( PicBuffer*     pcOrgPicBuffer,
               PicBuffer*     pcRecPicBuffer,
               PicBufferList& rcPicBufferOutputList,
               PicBufferList& rcPicBufferUnusedList )
{
  if( pcOrgPicBuffer == NULL )
  {
    //===== finish =====
    if( pcRecPicBuffer )
    {
      rcPicBufferUnusedList.push_back( pcRecPicBuffer );
    }
    if( m_cOrgPicBufferList.size() )
    {
      RNOK( xProcessGOP( m_cOrgPicBufferList, m_cRecPicBufferList, rcPicBufferUnusedList ) );
      rcPicBufferOutputList += m_cRecPicBufferList;
    }
    rcPicBufferUnusedList   += m_cOrgPicBufferList;
    rcPicBufferUnusedList   += m_cRecPicBufferList;
    m_cOrgPicBufferList.clear();
    m_cRecPicBufferList.clear();
    return Err::m_nOK;
  }

  //===== insert buffers =====
  m_cOrgPicBufferList.push_back( pcOrgPicBuffer );
  m_cRecPicBufferList.push_back( pcRecPicBuffer );

  UInt uiTargetBufferSize = ( 1 << m_uiDecompositionStages ) + ( m_bFirstGOPCoded ? 0 : 1 );
  ROT( m_cOrgPicBufferList.size() > uiTargetBufferSize );

  if( m_cOrgPicBufferList.size() == uiTargetBufferSize )
  {
    RNOK( xProcessGOP( m_cOrgPicBufferList, m_cRecPicBufferList, rcPicBufferUnusedList ) );
    rcPicBufferOutputList += m_cRecPicBufferList;
    rcPicBufferUnusedList += m_cOrgPicBufferList;
    rcPicBufferUnusedList += m_cRecPicBufferList;
    m_cOrgPicBufferList.clear();
    m_cRecPicBufferList.clear();
  }

  return Err::m_nOK;
}


H264AVC_NAMESPACE_END

⌨️ 快捷键说明

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