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

📄 recpicbuffer.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
  //===== clear lists =====
  rcList0.reset();
  rcList1.reset();
  ROTRS( rcSliceHeader.isIntra(), Err::m_nOK );

  if( rcSliceHeader.isInterP() )
  {
 
    RNOK( xInitRefListPSlice  ( rcList0 ) );
    AddMultiviewRef (m_cUsedRecPicBufUnitList, rcList0, rcSliceHeader.getNumRefIdxActive(LIST_0), FORWARD, rcSliceHeader);//JVT-W056  Samsung
    RNOK( xRefListRemapping   ( rcList0, LIST_0, &rcSliceHeader ) );

    RNOK( xAdaptListSize      ( rcList0, LIST_0,  rcSliceHeader ) );
    RNOK( xDumpRefList        ( rcList0, LIST_0 ) );
  }
  else // rcSliceHeader.isInterB()
  {
    
	  RNOK( xInitRefListsBSlice ( rcList0, rcList1 ) );
    AddMultiviewRef(m_cUsedRecPicBufUnitList, rcList0, rcSliceHeader.getNumRefIdxActive(LIST_0), FORWARD, rcSliceHeader);//JVT-W056  Samsung
    AddMultiviewRef(m_cUsedRecPicBufUnitList, rcList1, rcSliceHeader.getNumRefIdxActive(LIST_1), BACKWARD, rcSliceHeader);//JVT-W056  Samsung
    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->isIdrNalUnit(), 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().getRequiredFrameNumUpdateBehaviourFlag() );
  
  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 );

    if( !pcSliceHeader->getInterViewRef()) // 
    {
    RNOK( xUpdateMemory( pcSliceHeader ) );
    }
    RNOK( xOutput( rcOutputList, rcUnusedList ) );
  }
  RNOK( xDumpRecPicBuffer() );

  m_pcCurrRecPicBufUnit = m_cFreeRecPicBufUnitList.popFront();

  return Err::m_nOK;
}


// ----------------------------------------------------------------------
//
// FUNCTION:	RemoveMultiviewRef
//
// INPUTS:	pcRecPicBufUnit:  A RecPicBufUnit representing a multiview
//				  reference to remove from the prediction
//				  buffer.
//
// PURPOSE:	Remove a multiview prediction reference from the
//		prediction list.  We do this by manually removing
//		the item from the m_cUsedRecPicBufUnitList instead
//		of calling xSlidingWindow or xMMCO because we don't
//		want to invoke other buffer management routines
//		that could get confused by the multiview references.
//
// MODIFIED:	Tue Mar 14, 2006
//
// ----------------------------------------------------------------------

void RecPicBuffer::RemoveMultiviewRef
(RecPicBufUnit* pcRecPicBufUnitToRemove)  {
  pcRecPicBufUnitToRemove->uninit();
  m_cUsedRecPicBufUnitList.remove   ( pcRecPicBufUnitToRemove );
  m_cFreeRecPicBufUnitList.push_back( pcRecPicBufUnitToRemove );
}


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->getAdaptiveRefPicBufferingFlag() )
  {
    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 )
{
  ROF( pcSliceHeader );

  MmcoOp            eMmcoOp;
  const MmcoBuffer& rcMmcoBuffer  = pcSliceHeader->getMmcoBuffer();
  Int               iIndex        = 0;
  UInt              uiVal1, uiVal2;

  while( MMCO_END != ( eMmcoOp = rcMmcoBuffer.get( iIndex++ ).getCommand( uiVal1, uiVal2 ) ) )
  {
    switch( eMmcoOp )
    {
    case MMCO_SHORT_TERM_UNUSED:
      RNOK( xMarkShortTermUnused( m_pcCurrRecPicBufUnit, uiVal1 ) );
      break;
    case MMCO_RESET:
    case MMCO_MAX_LONG_TERM_IDX:
    case MMCO_ASSIGN_LONG_TERM:
    case MMCO_LONG_TERM_UNUSED:
    case MMCO_SET_LONG_TERM:
    default:
      RERR();
    }
  }
  return Err::m_nOK;
}


ErrVal
RecPicBuffer::xMarkShortTermUnused( RecPicBufUnit*  pcCurrentRecPicBufUnit,
                                    UInt            uiDiffOfPicNums )
{
  ROF( pcCurrentRecPicBufUnit );

  UInt  uiCurrPicNum  = pcCurrentRecPicBufUnit->getFrameNum();
  Int   iPicNumN      = (Int)uiCurrPicNum - (Int)uiDiffOfPicNums - 1;

  RecPicBufUnitList::iterator iter            = m_cUsedRecPicBufUnitList.begin();
  RecPicBufUnitList::iterator end             = m_cUsedRecPicBufUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isNeededForRef() && (*iter)->getPicNum( uiCurrPicNum, m_uiMaxFrameNum ) == iPicNumN )
    {
      (*iter)->markNonRef();
      return Err::m_nOK;
    }
  }
  RERR();
}


ErrVal
RecPicBuffer::xSlidingWindow()
{
  //===== get number of reference frames =====
  UInt                        uiCurrNumRefFrames  = 0;
  RecPicBufUnitList::iterator iter                = m_cUsedRecPicBufUnitList.begin();

⌨️ 快捷键说明

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