gopdecoder.cpp

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

CPP
1,768
字号
  ROF( rcDPBUnit.m_bWaitForOutput             == m_bWaitForOutput );
  ROF( rcDPBUnit.m_bRefPic                    == m_bRefPic );
  //===== update parameters =====
  Int i2ndF                               = m_ePicStatus - 1;
  rcDPBUnit.m_ePicStatus                  = FRAME;
  rcDPBUnit.m_iLongTermFrameIdx           = ( m_abLongTerm[i2ndF] ? m_iLongTermFrameIdx : rcDPBUnit.m_iLongTermFrameIdx );
  rcDPBUnit.m_bBaseRepresentation         = bRefBasePic;
  rcDPBUnit.m_aiPoc               [i2ndF] = m_aiPoc               [i2ndF];
  rcDPBUnit.m_abUseBasePred       [i2ndF] = m_abUseBasePred       [i2ndF];
  rcDPBUnit.m_abNeededForReference[i2ndF] = m_abNeededForReference[i2ndF];
  rcDPBUnit.m_abLongTerm          [i2ndF] = m_abLongTerm          [i2ndF];
  //===== update frame =====
  {
    SliceHeader*  pcSliceHeader = m_pcControlData->getSliceHeader();
    Frame*        pcFrame       = ( bRefBasePic ? m_pcRefBasePicFrame : m_pcFrame );
    ROF ( pcSliceHeader );
    ROF ( pcFrame );
    RNOK( rcDPBUnit.m_pcFrame->copy( pcFrame, m_ePicStatus ) );
    rcDPBUnit.m_pcFrame->setPoc( *pcSliceHeader );
  }
  //===== update base layer macroblock data =====
  if( rcDPBUnit.m_pcMbDataCtrlBaseLayer )
  {
    ROF ( m_pcMbDataCtrlBaseLayer );
    RNOK( rcDPBUnit.m_pcMbDataCtrlBaseLayer->copyMotion( *m_pcMbDataCtrlBaseLayer, m_ePicStatus ) );
  }
  return Err::m_nOK;
}

ErrVal
CurrDPBUnit::uninit()
{
  ROF ( m_bInUse && m_bCompleted );
  RNOK( DPBUnit::uninit() );
  m_bInUse            = false;
  m_bRefBasePicInUse  = false;
  m_bCompleted        = false;
  m_uiQualityId       = 0;
  return Err::m_nOK;
}





//////////////////////////////////////////////////////////////////////////
// REFERENCE PICTURE ENTRY
//////////////////////////////////////////////////////////////////////////
RefPicEntry::RefPicEntry( PicType ePicType, DPBUnit* pcDPBUnit )
: m_ePicType  ( ePicType )
, m_pcDPBUnit ( pcDPBUnit )
{
}

RefPicEntry::RefPicEntry( const RefPicEntry& rcRefPicEntry )
: m_ePicType  ( rcRefPicEntry.m_ePicType )
, m_pcDPBUnit ( rcRefPicEntry.m_pcDPBUnit )
{
}

RefPicEntry::~RefPicEntry()
{
}



//////////////////////////////////////////////////////////////////////////
// DECODED PICTURE BUFFER
//////////////////////////////////////////////////////////////////////////
DecodedPicBuffer::DecodedPicBuffer()
: m_bInitDone               ( false )
, m_bInitBufferDone         ( false )
, m_bDebugOutput            ( false )
, m_pcYuvBufferCtrl         ( 0 )
, m_uiDependencyId          ( 0 )
, m_uiFrameWidthInMbs       ( 0 )
, m_uiFrameHeightInMbs      ( 0 )
, m_uiBufferSizeInFrames    ( 0 )
, m_uiDPBSizeInFrames       ( 0 )
, m_uiMaxNumRefFrames       ( 0 )
, m_uiMaxFrameNum           ( 0 )
, m_uiLastRefFrameNum       ( MSYS_UINT_MAX )
, m_iMaxLongTermFrameIdx    ( -1 )
, m_pcLastDPBUnit           ( 0 )
, m_pcLastDPBUnitRefBasePic ( 0 )
, m_pcCurrDPBUnit           ( 0 )
, m_pcCurrDPBUnitILPred     ( 0 )
{
}

DecodedPicBuffer::~DecodedPicBuffer()
{
}

ErrVal
DecodedPicBuffer::create( DecodedPicBuffer*& rpcDecodedPicBuffer )
{
  ROF(( rpcDecodedPicBuffer = new DecodedPicBuffer() ));
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::destroy()
{
  RNOK( uninit() );
  delete this;
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::init( YuvBufferCtrl* pcYuvBufferCtrl, UInt uiDependencyId )
{
  ROT( m_bInitDone );
  ROT( m_bInitBufferDone );
  ROF( pcYuvBufferCtrl );
  m_bInitDone       = true;
  m_bInitBufferDone = false;
  m_pcYuvBufferCtrl = pcYuvBufferCtrl;
  m_uiDependencyId  = uiDependencyId;
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::uninit()
{
  RNOK( xDeleteData() );
  m_bInitDone               = false;
  m_bInitBufferDone         = false;
  m_pcYuvBufferCtrl         = 0;
  m_uiDependencyId          = 0;
  m_uiFrameWidthInMbs       = 0;
  m_uiFrameHeightInMbs      = 0;
  m_uiBufferSizeInFrames    = 0;
  m_uiDPBSizeInFrames       = 0;
  m_uiMaxNumRefFrames       = 0;
  m_uiMaxFrameNum           = 0;
  m_uiLastRefFrameNum       = MSYS_UINT_MAX;
  m_iMaxLongTermFrameIdx    = -1;
  m_pcLastDPBUnit           = 0;
  m_pcLastDPBUnitRefBasePic = 0;
  m_pcCurrDPBUnit           = 0;
  m_pcCurrDPBUnitILPred     = 0;
  return Err::m_nOK;
}

Bool
DecodedPicBuffer::xNewBufferDimension( const SequenceParameterSet& rcSPS )
{
  ROFRS ( m_bInitBufferDone,                                      true );
  ROFRS ( m_uiFrameWidthInMbs     == rcSPS.getFrameWidthInMbs (), true );
  ROFRS ( m_uiFrameHeightInMbs    == rcSPS.getFrameHeightInMbs(), true );
  ROFRS ( m_uiBufferSizeInFrames  >= rcSPS.getMaxDPBSize      (), true );
  return  false;
}

ErrVal
DecodedPicBuffer::xInitBuffer( const SliceHeader& rcSliceHeader )
{
  ROF( m_bInitDone );
  ROF( rcSliceHeader.getIdrFlag() );
  ROF( rcSliceHeader.getSPS().getMaxDPBSize   () );
  ROF( rcSliceHeader.getSPS().getNumRefFrames () <= rcSliceHeader.getSPS().getMaxDPBSize() );
  m_uiDPBSizeInFrames       = rcSliceHeader.getSPS().getMaxDPBSize();
  m_uiMaxNumRefFrames       = max( 1, rcSliceHeader.getSPS().getNumRefFrames() );
  m_uiMaxFrameNum           = 1 << rcSliceHeader.getSPS().getLog2MaxFrameNum();
  m_uiLastRefFrameNum       = MSYS_UINT_MAX;
  m_iMaxLongTermFrameIdx    = -1;
  m_pcLastDPBUnit           = 0;
  m_pcLastDPBUnitRefBasePic = 0;
  ROFRS( xNewBufferDimension( rcSliceHeader.getSPS() ), Err::m_nOK );
  RNOK ( xCreateData        ( rcSliceHeader.getSPS(), m_uiDPBSizeInFrames, m_uiDependencyId == 0 ) );
  m_uiFrameWidthInMbs       = rcSliceHeader.getSPS().getFrameWidthInMbs ();
  m_uiFrameHeightInMbs      = rcSliceHeader.getSPS().getFrameHeightInMbs();
  m_uiBufferSizeInFrames    = m_uiDPBSizeInFrames;
  m_bInitBufferDone         = true;
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xCreateData( const SequenceParameterSet&  rcSPS,
                               UInt                         uiDPBSizeInFrames,
                               Bool                         bBaseLayer )
{
  ROF ( m_bInitDone );
  RNOK( xDeleteData() );
  //===== create DPB buffer list =====
  uiDPBSizeInFrames += 2; // up to two frame buffers for temporary usage
  while( uiDPBSizeInFrames-- )
  {
    DPBUnit* pcDPBUnit = NULL;
    RNOK( DPBUnit::create( pcDPBUnit, *m_pcYuvBufferCtrl, rcSPS, bBaseLayer ) );
    m_cFreeDPBUnitList.pushBack( pcDPBUnit );
  }
  //===== create current DPB units =====
  RNOK( CurrDPBUnit::create( m_pcCurrDPBUnit,       *m_pcYuvBufferCtrl, rcSPS, true,  bBaseLayer ) );
  RNOK( CurrDPBUnit::create( m_pcCurrDPBUnitILPred, *m_pcYuvBufferCtrl, rcSPS, false, false      ) );
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xDeleteData()
{
  //===== check picture buffer list =====
  ROF( m_cPicBufferList.empty() );
  //===== delete DPB units =====
  m_cFreeDPBUnitList += m_cUsedDPBUnitList;
  m_cUsedDPBUnitList.clear();
  while( m_cFreeDPBUnitList.size() )
  {
    DPBUnit* pcDPBUnit = m_cFreeDPBUnitList.popFront();
    ROF ( pcDPBUnit );
    RNOK( pcDPBUnit->destroy() );
  }
  //===== delete current DPB units =====
  if( m_pcCurrDPBUnit )
  {
    RNOK( m_pcCurrDPBUnit->destroy() );
    m_pcCurrDPBUnit = 0;
  }
  if( m_pcCurrDPBUnitILPred )
  {
    RNOK( m_pcCurrDPBUnitILPred->destroy() );
    m_pcCurrDPBUnitILPred = 0;
  }
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::initCurrDPBUnit( CurrDPBUnit*&  rpcCurrDPBUnit, 
                                   PicBuffer*&    rpcPicBuffer,
                                   SliceHeader&   rcSliceHeader,
                                   PocCalculator& rcPocCalculator,
                                   PicBufferList& rcOutputList,
                                   PicBufferList& rcUnusedList,
                                   Bool           bFirstSliceInDependencyRepresentation,
                                   Bool           bFirstSliceInLayerRepresentation )
{
  ROF( m_bInitDone );
  ROF( m_bInitBufferDone || rcSliceHeader.getIdrFlag() );
  ROF( rpcPicBuffer );
  ROF( rcSliceHeader.getDependencyId() == m_uiDependencyId );
  if( bFirstSliceInDependencyRepresentation )
  {
    ROF ( bFirstSliceInLayerRepresentation );
    ROT ( rcSliceHeader.getQualityId() );
    //--- initialize buffer when required ---
    if( rcSliceHeader.getIdrFlag() )
    {
      if( m_bInitBufferDone )
      {
        RNOK( xMarkAllUnusedForRef( rcSliceHeader.getNoOutputOfPriorPicsFlag() ) );
        RNOK( xBumpingOutput      ( rcOutputList, rcUnusedList, true ) );
        RNOK( xCheckBufferStatus  () );
      }
      RNOK  ( xInitBuffer         ( rcSliceHeader ) );
    }
    //--- check status ---
    ROF ( m_pcCurrDPBUnit       ->isUninitialized() );
    ROF ( m_pcCurrDPBUnitILPred ->isUninitialized() );
    //--- store picture buffer ---
    if( rcSliceHeader.getOutputFlag() && !xIs2ndFieldOfCompFieldPair( rcSliceHeader ) )
    {
      m_cPicBufferList.push_back( rpcPicBuffer );
      rpcPicBuffer = 0;
    }
    //--- check for gaps in frame_num ---
    RNOK( xCheckGapsInFrameNum          ( rcSliceHeader, rcPocCalculator, rcOutputList, rcUnusedList ) );
    //--- initialize POC and DPB unit ---
    RNOK( rcPocCalculator .calculatePoc ( rcSliceHeader ) );
    RNOK( m_pcCurrDPBUnit->init         ( rcSliceHeader ) );
  }
  else
  {
    //--- check status ---
    ROF ( m_pcCurrDPBUnit       ->isCompleted () == bFirstSliceInLayerRepresentation     );
    ROF ( m_pcCurrDPBUnitILPred ->isCompleted () == ( rcSliceHeader.getQualityId() > 0 ) );
    //--- initialize POC and DPB unit ---
    RNOK( rcPocCalculator        .calculatePoc( rcSliceHeader ) );
    RNOK( m_pcCurrDPBUnit       ->reinit      ( rcSliceHeader, bFirstSliceInLayerRepresentation ) );
  }
  rpcCurrDPBUnit = m_pcCurrDPBUnit;
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::storeCurrDPBUnit( Bool bDependencyRepresentationFinished )
{
  ROF ( m_bInitDone && m_bInitBufferDone );
  ROF ( m_pcCurrDPBUnit->inCurrentUse () );
  RNOK( m_pcCurrDPBUnit->setComplete  ( *m_pcCurrDPBUnitILPred, bDependencyRepresentationFinished ) );
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::updateBuffer( PocCalculator& rcPocCalculator, PicBufferList& rcOutputList, PicBufferList& rcUnusedList )
{
  ROF   ( m_bInitDone );
  ROTRS ( !m_bInitBufferDone || m_pcCurrDPBUnit->isUninitialized(),  Err::m_nOK );
  ROF   ( m_pcCurrDPBUnit->isCompleted()   );
  //===== ununit inter-layer prediction DPB unit =====
  if( m_pcCurrDPBUnitILPred->isCompleted() )
  {
    RNOK( m_pcCurrDPBUnitILPred->uninit() );
  }
  //===== update DPB and check whether current DPB unit was correctly stored =====
  RNOK  ( xUpdateAndStoreCurrentPic( rcPocCalculator, rcOutputList, rcUnusedList ) );
  ROF   ( m_pcCurrDPBUnit->isUninitialized() );
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::finish( PicBufferList& rcOutputList, PicBufferList& rcUnusedList )
{
  ROF   ( m_bInitDone );
  ROFRS ( m_bInitBufferDone, Err::m_nOK );
  ROF   ( m_pcCurrDPBUnit      ->isUninitialized() );
  ROF   ( m_pcCurrDPBUnitILPred->isUninitialized() );
  RNOK  ( xMarkAllUnusedForRef    () );
  RNOK  ( xBumpingOutput          ( rcOutputList, rcUnusedList, true ) );
  RNOK  ( xCheckBufferStatus      () );
  ROF   ( m_cUsedDPBUnitList.empty() );
  ROF   ( m_cPicBufferList  .empty() );
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::setPrdRefLists( CurrDPBUnit* pcCurrDPBUnit )
{
  ROF( m_pcCurrDPBUnit == pcCurrDPBUnit  );
  ROF( m_pcCurrDPBUnit->inCurrentUse  () );
  ROF( m_pcCurrDPBUnit->getSliceHeader() );
  SliceHeader&  rcSliceHeader = *m_pcCurrDPBUnit->getSliceHeader();
  RefFrameList& rcRefPicList0 =  m_pcCurrDPBUnit->getCtrlData   ().getPrdFrameList( LIST_0 );
  RefFrameList& rcRefPicList1 =  m_pcCurrDPBUnit->getCtrlData   ().getPrdFrameList( LIST_1 );
  MbDataCtrl*   pcMbDataCtrl0 =  0;
  rcRefPicList0.reset();
  rcRefPicList1.reset();
  m_pcCurrDPBUnit->getCtrlData().setMbDataCtrl0L1( pcMbDataCtrl0 );
  ROTRS ( rcSliceHeader.isIntraSlice(), Err::m_nOK );
  //===== set list 0 =====
  RefPicEntryList cRefPicEntryList0;
  RefPicEntryList cRefPicEntryList1;
  RNOK  ( xCreateInitialRefPicLists ( cRefPicEntryList0,  cRefPicEntryList1,  rcSliceHeader ) );
  RNOK  ( xRefPicListModification   ( cRefPicEntryList0,  rcSliceHeader,      LIST_0 ) );
  RNOK  ( xSetReferencePictureList  ( rcRefPicList0,      cRefPicEntryList0,  rcSliceHeader.getNumRefIdxL0Active() ) );
  RNOK  ( xDumpRefPicList           ( rcRefPicList0,      LIST_0,             "final" ) );
  ROFRS ( rcSliceHeader.isBSlice(), Err::m_nOK );
  //===== set list 1 =====
  RNOK  ( xRefPicListModification   ( cRefPicEntryList1,  rcSliceHeader,     LIST_1 ) );
  RNOK  ( xSetReferencePictureList  ( rcRefPicList1,      cRefPicEntryList1, rcSliceHeader.getNumRefIdxL1Active() ) );
  RNOK  ( xDumpRefPicList           ( rcRefPicList1,      LIST_1,             "final" ) );
  if( rcSliceHeader.isH264AVCCompatible() )
  {
    RNOK( xSetMbDataCtrlEntry0      ( pcMbDataCtrl0,      cRefPicEntryList1 ) );

⌨️ 快捷键说明

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