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

📄 recpicbuffer.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 3 页
字号:


ErrVal
RecPicBuffer::store( RecPicBufUnit*   pcRecPicBufUnit,
                     SliceHeader*     pcSliceHeader,
                     PicBufferList&   rcOutputList,
                     PicBufferList&   rcUnusedList )
{
  RNOK( xStorePicture( pcRecPicBufUnit, rcOutputList, rcUnusedList, pcSliceHeader, pcSliceHeader->getIdrFlag() ) );
  
  if( pcRecPicBufUnit->isNeededForRef() )
  {
    m_uiLastRefFrameNum = pcRecPicBufUnit->getFrameNum();
  }

  return Err::m_nOK;
}


ErrVal
RecPicBuffer::getRefLists( RefFrameList&  rcList0,
                           RefFrameList&  rcList1,
                           SliceHeader&   rcSliceHeader )
{
  //===== clear lists =====
  rcList0.reset();
  rcList1.reset();
  ROTRS( rcSliceHeader.isIntraSlice(), Err::m_nOK );

  if( rcSliceHeader.isPSlice() )
  {
    RNOK( xInitRefListPSlice  ( rcList0 ) );
    RNOK( xRefListRemapping   ( rcList0, LIST_0, &rcSliceHeader ) );
    RNOK( xAdaptListSize      ( rcList0, LIST_0,  rcSliceHeader ) );
    RNOK( xDumpRefList        ( rcList0, LIST_0 ) );
  }
  else // rcSliceHeader.isBSlice()
  {
    RNOK( xInitRefListsBSlice ( rcList0, rcList1 ) );
    RNOK( xRefListRemapping   ( rcList0, LIST_0, &rcSliceHeader ) );
    RNOK( xRefListRemapping   ( rcList1, LIST_1, &rcSliceHeader ) );
    RNOK( xAdaptListSize      ( rcList0, LIST_0,  rcSliceHeader ) );
    RNOK( xAdaptListSize      ( rcList1, LIST_1,  rcSliceHeader ) );
    RNOK( xDumpRefList        ( rcList0, LIST_0 ) );
    RNOK( xDumpRefList        ( rcList1, LIST_1 ) );
  }

  return Err::m_nOK;
}
 


ErrVal
RecPicBuffer::xAdaptListSize( RefFrameList& rcList,
                              ListIdx       eListIdx,
                              SliceHeader&  rcSliceHeader )
{
  UInt  uiDefaultListSize = rcSliceHeader.getNumRefIdxActive( eListIdx );
  UInt  uiMaximumListSize = rcList.getActive();
  UInt  uiCurrentListSize = min( uiDefaultListSize, uiMaximumListSize );

  //===== update slice header =====
  rcList.       setActive         (           uiCurrentListSize );
  rcSliceHeader.setNumRefIdxActive( eListIdx, uiCurrentListSize );
  if( uiCurrentListSize != rcSliceHeader.getPPS().getNumRefIdxActive( eListIdx ) )
  {
    rcSliceHeader.setNumRefIdxActiveOverrideFlag( true );
  }

  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xCreateData( UInt                         uiMaxFramesInDPB,
                           const SequenceParameterSet&  rcSPS )
{
  ROF( m_bInitDone );
  RNOK( xDeleteData() );

  while( uiMaxFramesInDPB-- )
  {
    RecPicBufUnit* pcRecPicBufUnit = 0;
    RNOK( RecPicBufUnit::create( pcRecPicBufUnit, *m_pcYuvBufferCtrlFullPel, *m_pcYuvBufferCtrlHalfPel, rcSPS ) );
    m_cFreeRecPicBufUnitList.push_back( pcRecPicBufUnit );
  }
  RNOK( RecPicBufUnit::create( m_pcCurrRecPicBufUnit, *m_pcYuvBufferCtrlFullPel, *m_pcYuvBufferCtrlHalfPel, rcSPS ) );
  RNOK( m_pcCurrRecPicBufUnit->uninit() );

  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xDeleteData()
{
  ROF( m_bInitDone );

  m_cFreeRecPicBufUnitList += m_cUsedRecPicBufUnitList;
  m_cUsedRecPicBufUnitList.clear();

  while( m_cFreeRecPicBufUnitList.size() )
  {
    RecPicBufUnit* pcRecPicBufUnit = m_cFreeRecPicBufUnitList.popFront();
    pcRecPicBufUnit->destroy();
  }
  if( m_pcCurrRecPicBufUnit )
  {
    m_pcCurrRecPicBufUnit->destroy();
    m_pcCurrRecPicBufUnit = NULL;
  }
  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xCheckMissingPics( SliceHeader*   pcSliceHeader,
                                 PicBufferList& rcOutputList,
                                 PicBufferList& rcUnusedList )
{
  ROTRS( pcSliceHeader->getIdrFlag(), Err::m_nOK );
  ROTRS( ( ( m_uiLastRefFrameNum + 1 ) % m_uiMaxFrameNum ) == pcSliceHeader->getFrameNum(), Err::m_nOK );

  UInt  uiMissingFrames = pcSliceHeader->getFrameNum() - m_uiLastRefFrameNum - 1;
  if( pcSliceHeader->getFrameNum() <= m_uiLastRefFrameNum )
  {
    uiMissingFrames += m_uiMaxFrameNum;
  }
  ROF( pcSliceHeader->getSPS().getGapsInFrameNumValueAllowedFlag());
  
  for( UInt uiIndex = 1; uiIndex <= uiMissingFrames; uiIndex++ )
  {
    Bool  bTreatAsIdr   = ( m_cUsedRecPicBufUnitList.empty() );
    Int   iPoc          = ( bTreatAsIdr ? 0 : m_cUsedRecPicBufUnitList.back()->getPoc() );
    UInt  uiFrameNum    = ( m_uiLastRefFrameNum + uiIndex ) % m_uiMaxFrameNum;

    RNOK( m_pcCurrRecPicBufUnit->initNonEx( iPoc, uiFrameNum ) );
    RNOK( xStorePicture( m_pcCurrRecPicBufUnit, rcOutputList, rcUnusedList, pcSliceHeader, bTreatAsIdr ) );
  }

  m_uiLastRefFrameNum = ( m_uiLastRefFrameNum + uiMissingFrames ) % m_uiMaxFrameNum;
  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xStorePicture( RecPicBufUnit* pcRecPicBufUnit,
                             PicBufferList& rcOutputList,
                             PicBufferList& rcUnusedList,
                             SliceHeader*   pcSliceHeader,
                             Bool           bTreatAsIdr )
{
  ROF( pcRecPicBufUnit == m_pcCurrRecPicBufUnit );

  if( bTreatAsIdr )
  {
    RNOK( xClearOutputAll( rcOutputList, rcUnusedList ) );
    m_cUsedRecPicBufUnitList.push_back( pcRecPicBufUnit );
  }
  else
  {
    m_cUsedRecPicBufUnitList.push_back( pcRecPicBufUnit );
    RNOK( xUpdateMemory( pcSliceHeader ) );
    RNOK( xOutput( rcOutputList, rcUnusedList ) );
  }
  RNOK( xDumpRecPicBuffer() );

  m_pcCurrRecPicBufUnit = m_cFreeRecPicBufUnitList.popFront();

  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xOutput( PicBufferList& rcOutputList,
                       PicBufferList& rcUnusedList )
{
  ROTRS( m_cFreeRecPicBufUnitList.size(), Err::m_nOK );

  //===== smallest non-ref/output poc value =====
  Int                         iMinOutputPoc   = MSYS_INT_MAX;
  RecPicBufUnit*              pcElemToRemove  = 0;
  RecPicBufUnitList::iterator iter            = m_cUsedRecPicBufUnitList.begin();
  RecPicBufUnitList::iterator end             = m_cUsedRecPicBufUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    Bool bOutput = ( ! (*iter)->isOutputted() && (*iter)->isExisting() && ! (*iter)->isNeededForRef() );
    if( bOutput && (*iter)->getPoc() < iMinOutputPoc )
    {
      iMinOutputPoc   = (*iter)->getPoc();
      pcElemToRemove  = (*iter);
    }
  }
  ROF( pcElemToRemove ); // error, nothing can be removed

  //===== copy all output elements to temporary list =====
  RecPicBufUnitList cOutputList;
  Int               iMaxPoc = iMinOutputPoc;
  Int               iMinPoc = MSYS_INT_MAX;
  iter                      = m_cUsedRecPicBufUnitList.begin();
  for( ; iter != end; iter++ )
  {
    Bool bOutput = ( (*iter)->getPoc() <= iMinOutputPoc && ! (*iter)->isOutputted() );
    if( bOutput )
    {
      if( (*iter)->isExisting() )
      {
        cOutputList.push_back( *iter );
        if( (*iter)->getPoc() < iMinPoc )
        {
          iMinPoc = (*iter)->getPoc();
        }
      }
      else
      {
        RNOK( (*iter)->markOutputted() );
      }
    }
  }

  //===== real output =====
  for( Int iPoc = iMinPoc; iPoc <= iMaxPoc; iPoc++ )
  {
    iter = cOutputList.begin();
    end  = cOutputList.end  ();
    for( ; iter != end; iter++ )
    {
      if( (*iter)->getPoc() == iPoc )
      {
        RecPicBufUnit* pcRecPicBufUnit = *iter;
        cOutputList.remove( pcRecPicBufUnit );

        PicBuffer* pcPicBuffer = pcRecPicBufUnit->getPicBuffer();
        ROF( pcPicBuffer );
        pcRecPicBufUnit->getRecFrame()->store( pcPicBuffer );
        rcOutputList.push_back( pcPicBuffer );
        rcUnusedList.push_back( pcPicBuffer );

        pcRecPicBufUnit->markOutputted();
        break; // only one picture per POC
      }
    }
  }
  ROT( cOutputList.size() );

  //===== clear buffer ====
  RNOK( xClearBuffer() );

  //===== check =====
  ROT( m_cFreeRecPicBufUnitList.empty() ); // this should never happen

  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xClearOutputAll( PicBufferList& rcOutputList,
                               PicBufferList& rcUnusedList )
{
  //===== create output list =====
  RecPicBufUnitList           cOutputList;
  Int                         iMinPoc = MSYS_INT_MAX;
  Int                         iMaxPoc = MSYS_INT_MIN;
  RecPicBufUnitList::iterator iter    = m_cUsedRecPicBufUnitList.begin();
  RecPicBufUnitList::iterator end     = m_cUsedRecPicBufUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    Bool bOutput = ( ! (*iter)->isOutputted() && (*iter)->isExisting() );
    if( bOutput )
    {
      cOutputList.push_back( *iter );
      if( (*iter)->getPoc() < iMinPoc )   iMinPoc = (*iter)->getPoc();
      if( (*iter)->getPoc() > iMaxPoc )   iMaxPoc = (*iter)->getPoc();
    }
  }

  //===== real output =====
  for( Int iPoc = iMinPoc; iPoc <= iMaxPoc; iPoc++ )
  {
    iter = cOutputList.begin();
    end  = cOutputList.end  ();
    for( ; iter != end; iter++ )
    {
      if( (*iter)->getPoc() == iPoc )
      {
        RecPicBufUnit* pcRecPicBufUnit = *iter;
        cOutputList.remove( pcRecPicBufUnit );

        //--- output ---
        PicBuffer* pcPicBuffer = pcRecPicBufUnit->getPicBuffer();
        ROF( pcPicBuffer );
        pcRecPicBufUnit->getRecFrame()->store( pcPicBuffer );
        rcOutputList.push_back( pcPicBuffer );
        rcUnusedList.push_back( pcPicBuffer );
        break; // only one picture per poc
      }
    }
  }
  ROT( cOutputList.size() );

  //===== uninit all elements and move to free list =====
  while( m_cUsedRecPicBufUnitList.size() )
  {
    RecPicBufUnit* pcRecPicBufUnit = m_cUsedRecPicBufUnitList.popFront();
    RNOK( pcRecPicBufUnit->uninit() );
    m_cFreeRecPicBufUnitList.push_back( pcRecPicBufUnit );
  }
  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xUpdateMemory( SliceHeader* pcSliceHeader )
{
  ROTRS( pcSliceHeader && pcSliceHeader->getNalRefIdc() == NAL_REF_IDC_PRIORITY_LOWEST, Err::m_nOK );

  if( pcSliceHeader && pcSliceHeader->getDecRefPicMarking().getAdaptiveRefPicMarkingModeFlag() )
  {
    RNOK( xMMCO( pcSliceHeader ) );
  }
  else
  {
    RNOK( xSlidingWindow() );
  }

  //===== clear buffer -> remove non-ref pictures =====
  RNOK( xClearBuffer() );

  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xClearBuffer()
{
  //===== remove non-output / non-ref pictures =====
  //--- store in temporary list ---
  RecPicBufUnitList           cTempList;
  RecPicBufUnitList::iterator iter  = m_cUsedRecPicBufUnitList.begin();
  RecPicBufUnitList::iterator end   = m_cUsedRecPicBufUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    Bool  bNoOutput   = ( ! (*iter)->isExisting() || (*iter)->isOutputted() );
    Bool  bNonRef     = ( ! (*iter)->isNeededForRef() );

    if( bNonRef && bNoOutput )
    {
      cTempList.push_back( *iter );
    }
  }
  //--- uninit and move to free list ---
  while( cTempList.size() )
  {
    RecPicBufUnit*  pcRecPicBufUnit = cTempList.popFront();
    RNOK( pcRecPicBufUnit->uninit() );
    m_cUsedRecPicBufUnitList.remove   ( pcRecPicBufUnit );
    m_cFreeRecPicBufUnitList.push_back( pcRecPicBufUnit );
  }
  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xMMCO( SliceHeader* pcSliceHeader )
{

⌨️ 快捷键说明

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