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

📄 scheduler.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
字号:
/**************************************************************************
// JVT-V068 HRD
**************************************************************************/
// JVT-V068 HRD {

#include "H264AVCEncoderLib.h"

#include "H264AVCCommonLib/ParameterSetMng.h"
#include "Scheduler.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

// h264 namespace begin
//##ModelId=404734B00263
H264AVC_NAMESPACE_BEGIN

Scheduler::Scheduler():
  m_dFieldTimeDelta     ( 0.0208 ),
  m_dOutputFrequency    ( 30 ),
  m_uiOutputTicks       ( 1000 ),
  m_dClockFrequency     ( 30000),
  m_dActualOutTime      ( 0 ),
  m_dActualInTime       ( 0 ),
  m_dLastBPTime         ( 0),
  m_uiInitialOutputDelay( 1 ),
  m_pcCodingParameter   ( NULL ),
  m_pfFileDebug         ( NULL ),
  m_bInitDone           ( false )
{
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B00266
ErrVal Scheduler::create( Scheduler*& rpcScheduler )
{
  rpcScheduler = new Scheduler;

  ROT( NULL == rpcScheduler );

  return Err::m_nOK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B00284
ErrVal Scheduler::init(  CodingParameter* pcCodingParameter, UInt uiLayer )
{
  ROT( NULL == pcCodingParameter );
  ROT ( m_bInitDone );

  m_pcCodingParameter = pcCodingParameter;

#ifdef DEBUG_SCHEDULER
  m_pfFileDebug = fopen(DEBUG_SCHEDULER_FILE, "w");
  ROT (NULL==m_pfFileDebug);
#endif

  m_dOutputFrequency = pcCodingParameter->getLayerParameters(uiLayer).getOutputFrameRate();

  m_bInitDone = true;
  m_uiLayerBits = 0;

  return Err::m_nOK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B00288
ErrVal Scheduler::uninit()
{
  ROF ( m_bInitDone );

  if( NULL != m_pfFileDebug )
  {
    fclose (  m_pfFileDebug );
  }

  m_aacTiming[ HRD::VCL_HRD ].uninit();
  m_aacTiming[ HRD::NAL_HRD ].uninit();

  m_bInitDone = false;

  return Err::m_nOK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B00286
ErrVal Scheduler::initBuffer( const VUI* pcVui, UInt uiLayerIndex)
{
  ROF ( m_bInitDone );
  
  RNOK ( xInitHrd (pcVui->getNalHrd(uiLayerIndex), HRD::NAL_HRD) );
  RNOK ( xInitHrd (pcVui->getVclHrd(uiLayerIndex), HRD::VCL_HRD) );

  if(pcVui->getTimingInfo(uiLayerIndex).getTimingInfoPresentFlag() ) 
  {
    m_dClockFrequency = (Double)pcVui->getTimingInfo(uiLayerIndex).getTimeScale() / (Double)pcVui->getTimingInfo(uiLayerIndex).getNumUnitsInTick();
    m_uiOutputTicks = 1;
    m_dFieldTimeDelta = 1 / m_dClockFrequency;
  }
  return Err::m_nOK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=40DFBB09007D
ErrVal Scheduler::xInitHrd ( const HRD &rcHrd, const HRD::HrdParamType eHrdParamType)
{
  m_aacTiming[ eHrdParamType ].uninit();
  m_apcHrd[eHrdParamType] = &rcHrd;
  // initial filling level for CPB
  //Double dInitialCpbLevel = m_pcCodingParameter->getVUIParams().getInitialCpbLevel() / 100.0;
  Double dInitialCpbLevel = 0.7; // fixed to 90 percent

  if( rcHrd.getHrdParametersPresentFlag() ) 
  {
    UInt uiCpbCnt = rcHrd.getCpbCnt();
    UInt uiBrScale = 6 + rcHrd.getBitRateScale();
    UInt uiCSScale = 4 + rcHrd.getCpbSizeScale();
    m_aacTiming[eHrdParamType].init( uiCpbCnt );
    for( UInt i=0; i<uiCpbCnt; i++) 
    {
      UInt uiBitRate = ( rcHrd.getCntBuf(i).getBitRateValue() << uiBrScale);
      m_aacTiming[eHrdParamType][i].m_iBitRate = uiBitRate;
      UInt uiCPBSize = ( rcHrd.getCntBuf(i).getCpbSizeValue() << uiCSScale);
      m_aacTiming[eHrdParamType][i].m_uiFirstIrd = UInt((dInitialCpbLevel*uiCPBSize/(Double)uiBitRate)*90000);
      m_aacTiming[eHrdParamType][i].m_dRemoval   = m_aacTiming[eHrdParamType][i].m_uiFirstIrd/Double(90000);
      m_aacTiming[eHrdParamType][i].m_uiIrd      = m_aacTiming[eHrdParamType][i].m_uiFirstIrd;
      m_aacTiming[eHrdParamType][i].m_bCbr       = rcHrd.getCntBuf(i).getVbrCbrFlag();
    } 
  }
  return Err::m_nOK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B00272
ErrVal Scheduler::destroy()
{
  if (m_bInitDone)
  {
    uninit();
  }
  delete this;
  return Err::m_nOK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=407BE99E002E
ErrVal Scheduler::createBufferingSei( SEI::BufferingPeriod*& rpcBufferingPeriod, ParameterSetMng* pcParameterSetMng, UInt uiDQId )
{
  ROF ( m_bInitDone );

  RNOK( SEI::BufferingPeriod::create( rpcBufferingPeriod, pcParameterSetMng ) );

  SequenceParameterSet *pcSPS;
  RNOK( pcParameterSetMng->getActiveSPS( pcSPS, uiDQId ) );

  rpcBufferingPeriod->setHRD(pcSPS->getSeqParameterSetId(), pcSPS->isSubSetSPS(), m_apcHrd );

  RNOK (xCreateBufferingSeiHrd(HRD::NAL_HRD, *m_apcHrd[HRD::NAL_HRD], rpcBufferingPeriod));
  RNOK (xCreateBufferingSeiHrd(HRD::VCL_HRD, *m_apcHrd[HRD::VCL_HRD], rpcBufferingPeriod));

  return Err::m_nOK;
}

//##ModelId=40DFBB090080
ErrVal Scheduler::xCreateBufferingSeiHrd( HRD::HrdParamType eHrdParamType, const HRD &rcHrd, SEI::BufferingPeriod* pcBPSei)
{
  if( rcHrd.getHrdParametersPresentFlag())
  {
    for( UInt i=0; i<rcHrd.getCpbCnt(); i++)
    {
      TimingUnit* myTU = &m_aacTiming[eHrdParamType][i];
      myTU->calcIrd( m_dActualInTime);
      pcBPSei->getSchedSel(eHrdParamType, i).setDelay(myTU->m_uiIrd);
      pcBPSei->getSchedSel(eHrdParamType, i).setDelayOffset(myTU->m_uiIrdOffset);   
      if( NULL != m_pfFileDebug )
      {
        if (HRD::VCL_HRD == eHrdParamType)
        {
          fprintf( m_pfFileDebug, "VCL Delay= %d    Offset = %d\n", myTU->m_uiIrd, myTU->m_uiIrdOffset );
        }
        else
        {
          fprintf( m_pfFileDebug, "NAL Delay= %d    Offset = %d\n", myTU->m_uiIrd, myTU->m_uiIrdOffset );
        }
      }
    } 
  }
  return Err::m_nOK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=407BE99E003F
ErrVal Scheduler::createTimingSei( SEI::PicTiming*& rpcPicTiming, const VUI* pcVui, UInt uiPicNumOffset,  SliceHeader &rcSH, UInt uiInputFormat, UInt uiLayerIndex)
{
  ROF ( m_bInitDone );

  RNOK( SEI::PicTiming::create( rpcPicTiming, pcVui, uiLayerIndex ) );
    
  rpcPicTiming->setCpbRemovalDelay(UInt((m_dActualInTime - m_dLastBPTime) * m_dClockFrequency + 0.5) );
  
  if( rcSH.getIdrFlag() )
  {
    m_dLastBPTime = m_dActualInTime;
  }

  UInt uiTopAdd = (uiInputFormat==2)?1:0;
  UInt uiBotAdd = (uiInputFormat==1)?1:0;
  
  UInt uiDpbOutputDelay = m_uiInitialOutputDelay + 2*(uiPicNumOffset) + (rcSH.getFieldPicFlag() ? (rcSH.getBottomFieldFlag()?uiBotAdd:uiTopAdd):0);
  rpcPicTiming->setDpbOutputDelay(m_uiOutputTicks*uiDpbOutputDelay);
  
  PicStruct ePictstruct;

  if (rcSH.getFieldPicFlag())
  {
    ePictstruct=rcSH.getBottomFieldFlag()?PS_BOT:PS_TOP;
  }
  else
  {
    switch (uiInputFormat)
    {
    case 0:
      ePictstruct = PS_FRAME;
      break;
    case 1:
      ePictstruct = PS_TOP_BOT;
      break;
    case 2:
      ePictstruct = PS_BOT_TOP;
      break;
    default:
      ePictstruct = PS_NOT_SPECIFIED;
      break;
    }
  }
  rpcPicTiming->setPicStruct(ePictstruct);

//  printf ("\nOutput delay: %d", uiDpbOutputDelay);

  return Err::m_nOK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B00280
ErrVal Scheduler::calculateTiming( UInt uiVclSize, UInt uiAUSize, Bool bIsIdr, Bool bFieldPicFlag)
{
  ROF ( m_bInitDone );

  RNOK (xCalculateTiming(HRD::NAL_HRD,  uiAUSize, bIsIdr));
  RNOK (xCalculateTiming(HRD::VCL_HRD, uiVclSize, bIsIdr));

  if (bFieldPicFlag)
  {
    m_dActualInTime += m_dFieldTimeDelta;
  }
  else
  {
    m_dActualInTime += 2 * m_dFieldTimeDelta;
  }

  return Err::m_nOK;
}

//##ModelId=40DFBB09008D
ErrVal Scheduler::xCalculateTiming( HRD::HrdParamType eHrdParamType, UInt uiSize, Bool bIsIdr )
{
  UInt i;
  for( i=0; i<m_aacTiming[eHrdParamType].size(); i++) 
  {
    m_aacTiming[eHrdParamType][i].calcTiming( uiSize, m_dActualInTime, bIsIdr);
    if ( HRD::VCL_HRD == eHrdParamType )
    {
      if( NULL != m_pfFileDebug ) 
      {
        fprintf( m_pfFileDebug, "Ird = %d   Irdo = %d   Taie = %f   Tai = %f   Taf = %f   Trn = %f   Size = %d\n",
          m_aacTiming[eHrdParamType][i].m_uiIrd, m_aacTiming[eHrdParamType][i].m_uiIrdOffset, m_aacTiming[eHrdParamType][i].m_dInitialArrivalEarliest,
          m_aacTiming[eHrdParamType][i].m_dInitialArrival, m_aacTiming[eHrdParamType][i].m_dFinalArrival, m_aacTiming[eHrdParamType][i].m_dRemoval,
          uiSize);
        fflush (m_pfFileDebug);
      }
    }
  }
  return Err::m_nOK;
}
 
/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B0030E
Scheduler::TimingUnit::TimingUnit( ) //KR
: m_iDataLength(0),
  m_iBitRate(0),
  m_dInitialArrivalEarliest(0),
  m_dInitialArrival(0),
  m_dFinalArrival(0),
  m_dRemoval(0),
  m_uiFirstIrd(0),
  m_uiIrd(0),
  m_uiIrdOffset(0),
  m_bCbr(false)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B00313
ErrVal Scheduler::TimingUnit::calcIrd( Double dTime) //KR
{
  m_dRemoval = dTime + (Double)m_uiFirstIrd/(Double)90000;
  UInt uiTmp = UInt((m_dRemoval - m_dFinalArrival) * 90000 + 0.5); // C-16 
  if(m_bCbr) 
  {
    m_uiIrd = uiTmp;
    m_dInitialArrivalEarliest = 0;  //not used in this case
    m_uiIrdOffset = 0;
  }
  else 
  {
    m_uiIrd = (uiTmp > m_uiFirstIrd) ? m_uiFirstIrd : uiTmp; // final arrival last AU
    m_dInitialArrivalEarliest = m_dRemoval - Double(m_uiIrd)/(Double)90000;
    m_uiIrdOffset = m_uiFirstIrd - m_uiIrd;
  }

  return Err::m_nOK;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//##ModelId=404734B0030F
ErrVal Scheduler::TimingUnit::calcTiming( UInt uiSize, Double dTime, Bool bIsIdr) //KR
{
  m_iDataLength = uiSize * 8; // in Bits
  if( !bIsIdr) 
  {
    m_dRemoval = dTime + (Double)m_uiFirstIrd/(Double)90000;
    m_dInitialArrivalEarliest = (m_bCbr) ? 0 : m_dRemoval - Double(m_uiIrd + m_uiIrdOffset)/(Double)90000;
  }

  m_dInitialArrival = max(m_dFinalArrival, m_dInitialArrivalEarliest);
  m_dFinalArrival = m_dInitialArrival + (Double)m_iDataLength / (Double)(m_iBitRate);

  return Err::m_nOK;
}
// JVT-V068 HRD }

// h264 namespace end
H264AVC_NAMESPACE_END

⌨️ 快捷键说明

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