framemng.cpp

来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,500 行 · 第 1/3 页

CPP
1,500
字号
  RNOK( m_cFrameUnitBuffer.getFrameUnit( m_pcCurrentFrameUnit ) );
  RNOK( m_pcCurrentFrameUnit->init( rcSH, pcPicBuffer ) );


  m_pcCurrentFrameUnit->getFrame().setViewId( rcSH.getViewId() );

  m_pcCurrentFrameUnit->getFrame().setInterViewFlag(rcSH.getInterViewFlag()); //JVT-W056	

  rcSH.setFrameUnit( m_pcCurrentFrameUnit );

  return Err::m_nOK;
}


ErrVal FrameMng::xCheckMissingFrameNums( SliceHeader& rcSH )
{
  //===== check frame numbers for reference pictures =====
  if( ( ( m_uiPrecedingRefFrameNum + 1 ) % m_uiMaxFrameNumCurr) != rcSH.getFrameNum() && 
      (m_uiLastViewId == rcSH.getViewId()) )
  {
    UInt  uiNumMissingPictures = rcSH.getFrameNum() - m_uiPrecedingRefFrameNum - 1;
    if( rcSH.getFrameNum() <= m_uiPrecedingRefFrameNum )
    {
      uiNumMissingPictures += m_uiMaxFrameNumCurr;
    }

    if( rcSH.getSPS().getRequiredFrameNumUpdateBehaviourFlag() )
    {
      for( UInt uiIndex = 1; uiIndex <= uiNumMissingPictures; uiIndex++ )
      {
        UInt        uiFrameNum  = ( m_uiPrecedingRefFrameNum + uiIndex ) % m_uiMaxFrameNumCurr;
        FrameUnit*  pcFrameUnit = 0;
        RNOK( m_cFrameUnitBuffer.getFrameUnit( pcFrameUnit ) );
		//JVT-S036 {
		if( !m_pcCurrentFrameUnit->getBaseRep() )
		{
			FUList::iterator iter = m_cShortTermList.begin();
			FUList::iterator end  = m_cShortTermList.end();
			Bool bFlag = false;
			for( ; iter != m_cShortTermList.end(); iter++ )
			{
				if( (*iter)->getBaseRep() && (*iter)->getFrameNumber() == m_pcCurrentFrameUnit->getFrameNumber())
				{
				    bFlag = true;
					break;
				}
			}
			if( bFlag )
			{
					FrameUnit* pcFrameUnitTemp = (*iter);
					RNOK(pcFrameUnit->init( rcSH, *pcFrameUnitTemp ));
			}
			else
			{
				RNOK( pcFrameUnit->init( rcSH, *m_pcCurrentFrameUnit ) );
			}
			
		}
		else
		//JVT-S036 }
		{
			RNOK( pcFrameUnit->init( rcSH, *m_pcCurrentFrameUnit ) ); // HS: decoder robustness
		}

        pcFrameUnit->setFrameNumber( uiFrameNum );
        m_cShortTermList.push_front( pcFrameUnit );
        m_iEntriesInDPB++;

		RNOK( xSlidingWindowUpdate() );

      }
    }
    else
    {
      printf("\n  LOST PICTURES: %d\n", uiNumMissingPictures );
      AF();
    }

    m_uiPrecedingRefFrameNum = ( m_uiPrecedingRefFrameNum + uiNumMissingPictures ) % m_uiMaxFrameNumCurr;
  }
  return Err::m_nOK;
}



ErrVal FrameMng::setPicBufferLists( PicBufferList& rcPicBufferOutputList, PicBufferList& rcPicBufferUnusedList )
{
  rcPicBufferUnusedList += m_cPicBufferUnusedList;
  m_cPicBufferUnusedList.clear();

  rcPicBufferOutputList += m_cPicBufferOutputList;
  m_cPicBufferOutputList.clear();

  return Err::m_nOK;
}


ErrVal FrameMng::storePicture( const SliceHeader& rcSH )
{
  //===== memory managment =====
  if( rcSH.isIdrNalUnit() )
  {
    RNOK( xClearListsIDR( rcSH ) );
  }
  RNOK( xManageMemory( rcSH ) );

  //===== store current picture =====
  RNOK( xStoreCurrentPicture( rcSH ) );

  //===== set pictures for output =====
  RNOK( xSetOutputListMVC( m_pcCurrentFrameUnit, rcSH.getSPS().getSpsMVC()->getNumViewMinus1()+1) );


  if( rcSH.getNalRefIdc() )
  {
    m_uiPrecedingRefFrameNum = m_pcCurrentFrameUnit->getFrameNumber();
  }

  return Err::m_nOK;
}


UInt FrameMng::xSortPocOrderedList()
{
  UInt  uiFirstPosWithGreaterPoc;
  Int   iCurrPoc = m_pcCurrentFrameUnit->getFrame().getPOC();

  std::sort( m_cPocOrderedFrameList.begin(), m_cPocOrderedFrameList.end(), PocOrder() );
  for( uiFirstPosWithGreaterPoc = 0; uiFirstPosWithGreaterPoc < m_cPocOrderedFrameList.size(); uiFirstPosWithGreaterPoc++ )
  {
    if( m_cPocOrderedFrameList.get( uiFirstPosWithGreaterPoc )->getPOC() > iCurrPoc )
    {
      break;
    }
  }
  return uiFirstPosWithGreaterPoc;
}

ErrVal FrameMng::xSetInitialReferenceListPFrame( SliceHeader& rcSH )
{
  RefPicList<RefPic>& rcList = rcSH.getRefPicList( LIST_0 );
  /*
  if( ! rcSH.getKeyPictureFlag() ) 
    m_cShortTermList.setRefPicListFGS( rcList, rcSH );
  else
  */
    m_cShortTermList.setRefPicList( rcList, rcSH);
  return Err::m_nOK;
}



ErrVal FrameMng::xSetInitialReferenceListBFrame( SliceHeader& rcSH )
{
  RefPicList<RefPic>& rcList0 = rcSH.getRefPicList( LIST_0 );
  RefPicList<RefPic>& rcList1 = rcSH.getRefPicList( LIST_1 );
  UInt                uiFirstPosWithGreaterPoc, uiPos;
  FUIter              iter;

  //====== set Poc ordered short-term list and get index with smallest Poc greater than current ======
  m_cPocOrderedFrameList.reset();
  /*
  if( ! rcSH.getKeyPictureFlag() )
    m_cShortTermList.setRefFrameListFGS( m_cPocOrderedFrameList, rcSH );
  else
  */
  m_cShortTermList.setRefFrameList( m_cPocOrderedFrameList , rcSH);

  uiFirstPosWithGreaterPoc = xSortPocOrderedList();

  //===== set short term reference frames =====
  for( uiPos = uiFirstPosWithGreaterPoc - 1; uiPos != MSYS_UINT_MAX; uiPos-- )
  {
    rcList0.next().setFrame( m_cPocOrderedFrameList.get( uiPos ) );
  }
  for( uiPos = uiFirstPosWithGreaterPoc; uiPos != m_cPocOrderedFrameList.size(); uiPos++ )
  {
    rcList0.next().setFrame( m_cPocOrderedFrameList.get( uiPos ) );
    rcList1.next().setFrame( m_cPocOrderedFrameList.get( uiPos ) );
  }
  for( uiPos = uiFirstPosWithGreaterPoc - 1; uiPos != MSYS_UINT_MAX; uiPos-- )
  {
    rcList1.next().setFrame( m_cPocOrderedFrameList.get( uiPos ) );
  }

  return Err::m_nOK;
}


ErrVal FrameMng::setRefPicLists( SliceHeader& rcSH, Bool bDoNotRemap )
{
  RNOK( xSetReferenceLists( rcSH) );

  if(rcSH.getNalUnitType() == NAL_UNIT_CODED_SLICE_SCALABLE)
    xSetReferenceListsMVC( rcSH );

  if( ! bDoNotRemap )
  {
    //===== remapping =====
    RNOK( xReferenceListRemapping( rcSH, LIST_0 ) );
    RNOK( xReferenceListRemapping( rcSH, LIST_1 ) );
  }
// cleanup //dump
#if 0
  if( rcSH.isInterP() )
  {
    xDumpRefList( LIST_0, rcSH );
  }
  else if (rcSH.isInterB())
  {
    xDumpRefList( LIST_0, rcSH );
    xDumpRefList( LIST_1, rcSH );
  }
#endif 
  return Err::m_nOK;
}



ErrVal FrameMng::xSetReferenceLists( SliceHeader& rcSH )
{
  rcSH.getRefPicList( LIST_0 ).reset( 0 );
  rcSH.getRefPicList( LIST_1 ).reset( 0 );

  if( rcSH.isIntra() )
  {
    return Err::m_nOK;
  }

  rcSH.getRefPicList( LIST_0 ).reset();
  if( rcSH.isInterB() )
  {
    rcSH.getRefPicList( LIST_1 ).reset();
  }

  if(rcSH.getNalUnitType() == NAL_UNIT_CODED_SLICE_SCALABLE)
  {
    if(rcSH.getAnchorPicFlag()) //no temporal pics
        return Err::m_nOK;      
  }
  
  //===== initial lists =====
  if( ! rcSH.isInterB() )
  {
    RNOK( xSetInitialReferenceListPFrame( rcSH ) );
  }
  else
  {
      RNOK( xSetInitialReferenceListBFrame( rcSH ) );
  }


// cleanup 


  return Err::m_nOK;
}



ErrVal FrameMng::xClearListsIDR( const SliceHeader& rcSH  )
{
  //===== output =====
  for( FUIter iter = m_cOrderedPOCList.begin(); iter != m_cOrderedPOCList.end(); iter++ )
  {
    if(rcSH.getViewId() == (*iter)->getFrame().getViewId() )
    {
      if( ! rcSH.getNoOutputOfPriorPicsFlag() )
      {
/*        if( (*iter)->getFGSPicBuffer() )
        {
          (*iter)->getFGSPicBuffer()->setCts( (UInt64)((*iter)->getMaxPOC()) ); // HS: decoder robustness
          m_cPicBufferOutputList.push_back( (*iter)->getFGSPicBuffer() );
        }
        else */
        if ((*iter)->getPicBuffer() )  //JVT-S036 
        {
          (*iter)->getPicBuffer()->setCts( (UInt64)((*iter)->getMaxPOC()) ); // HS: decoder robustness
          m_cPicBufferOutputList.push_back( (*iter)->getPicBuffer() );
        }
      }

      (*iter)->setOutputDone();

      if( xFindAndErase( m_cNonRefList, *iter ) )
      {
        RNOK( xAddToFreeList( (*iter) ) );
      }
      m_cOrderedPOCList.erase((iter));
    }
  }

//  m_cOrderedPOCList.clear();

  return Err::m_nOK;
}


UInt FrameMng::MaxRefFrames( UInt uiLevel, UInt uiNumMbs )
{
  return m_uiDBPMemory[ uiLevel ] / ( 384 * uiNumMbs );
}



ErrVal FrameMng::outputAll()
{
  FUIter  iter;
  //===== output =====
  for( iter = m_cOrderedPOCList.begin(); iter != m_cOrderedPOCList.end(); iter++ )
  {
/*    if( (*iter)->getFGSPicBuffer() )
    {
      (*iter)->getFGSPicBuffer()->setCts( (UInt64)((*iter)->getMaxPOC()) ); // HS: decoder robustness
      m_cPicBufferOutputList.push_back( (*iter)->getFGSPicBuffer() );
    }
    else 
*/
    if ((*iter)->getPicBuffer() )  //JVT-S036 
    {
      (*iter)->getPicBuffer()->setCts( (UInt64)((*iter)->getMaxPOC()) ); // HS: decoder robustness
      m_cPicBufferOutputList.push_back( (*iter)->getPicBuffer() );
    }
    (*iter)->setOutputDone();
  }
  m_cOrderedPOCList.erase( m_cOrderedPOCList.begin(), iter );

  RNOK( xAddToFreeList( m_cShortTermList ) );
  RNOK( xAddToFreeList( m_cNonRefList ) );

  return Err::m_nOK;
}





/*
ErrVal FrameMng::storeFGSPicture( PicBuffer* pcPicBuffer )
{
  UInt uiFGSReconCount = m_pcCurrentFrameUnit->getFGSReconCount();
  m_pcCurrentFrameUnit->getFGSReconstruction(uiFGSReconCount)->copyAll(m_pcCurrentFrameUnit->getFGSIntFrame());
  m_pcCurrentFrameUnit->setFGSReconCount(uiFGSReconCount + 1);

  m_pcCurrentFrameUnit->setFGS( pcPicBuffer );
  m_pcCurrentFrameUnit->getFGSIntFrame()->store( pcPicBuffer );

  m_pcCurrentFrameUnit->getFGSFrame().extendFrame( m_pcQuarterPelFilter );
  
  return Err::m_nOK;
}
*/

ErrVal FrameMng::xStoreCurrentPicture( const SliceHeader& rcSH )
{
  Frame& cBaseFrame = m_pcCurrentFrameUnit->getFrame();
  PicBuffer cTempPicBuffer(cBaseFrame.getFullPelYuvBuffer()->getBuffer());

  PicBuffer*  pcTempPicBuffer = m_pcCurrentFrameUnit->getPicBuffer();
  cBaseFrame.setViewId(rcSH.getViewId());
  pcTempPicBuffer->setViewId(rcSH.getViewId());
  m_uiLastViewId = rcSH.getViewId();

  // Base layer
  /*
  m_pcCurrentFrameUnit->getFGSReconstruction(0)->load(& cTempPicBuffer);
  m_pcCurrentFrameUnit->setFGSReconCount(1);
  */

  RNOK( m_pcCurrentFrameUnit->getFrame().extendFrame( m_pcQuarterPelFilter ) );

  if( rcSH.getNalRefIdc() )
  {
    //===== store as short term picture =====
    m_pcCurrentFrameUnit->setFrameNumber( rcSH.getFrameNum() );
    m_pcCurrentFrameUnit->setUsed       ();

    m_cShortTermList.push_front( m_pcCurrentFrameUnit );
    m_iEntriesInDPB++;

//JVT-S036  start
	if( rcSH.getKeyPicFlagScalable() )
	{
		RNOK( m_cFrameUnitBuffer.getFrameUnit( m_pcCurrentFrameUnitBase ) );
		RNOK( m_pcCurrentFrameUnitBase->copyBase( rcSH, *m_pcCurrentFrameUnit ) );
		m_pcCurrentFrameUnitBase->setBaseRep( true );
		m_cShortTermList.push_front( m_pcCurrentFrameUnitBase );
		m_iEntriesInDPB++; 
	}
//JVT-S036  end
  }
  else
  {

    m_cNonRefList.push_back( m_pcCurrentFrameUnit );
    m_iEntriesInDPB++;
  }

  //===== store reference in ordered POC List =====
  FUIter  iter;
  for( iter = m_cOrderedPOCList.begin(); iter != m_cOrderedPOCList.end(); iter++ )
  {
    if( (*iter)->getMaxPOC() > m_pcCurrentFrameUnit->getMaxPOC() )
    {
      break;
    }
  }

  if( rcSH.getKeyPicFlagScalable() ) //JVT-S036 
  {
	m_cOrderedPOCList.insert( iter, m_pcCurrentFrameUnitBase );
  }
  else
  {
	  m_cOrderedPOCList.insert( iter, m_pcCurrentFrameUnit );
  }

  return Err::m_nOK;
}



ErrVal FrameMng::xMmcoMarkShortTermAsUnused( const FrameUnit* pcCurrFrameUnit, UInt uiDiffOfPicNums )
{
  UInt  uiCurrPicNum  = pcCurrFrameUnit->getFrameNumber();
  UInt  uiPicNumN     = uiCurrPicNum - uiDiffOfPicNums - 1;

  if( uiCurrPicNum <= uiDiffOfPicNums )
  {
    uiPicNumN += m_uiMaxFrameNumPrev;
  }

  FUIter iter = m_cShortTermList.findShortTerm( uiPicNumN );
  if( iter == m_cShortTermList.end() )
  {
    printf("\nMMCO not possible\n" );
    return Err::m_nOK; // HS: decoder robustness
  }

  FrameUnit* pcFrameUnit = (*iter);
  pcFrameUnit->setUnused();
  RNOK( xRemoveFromRefList( m_cShortTermList, iter ) );

  return Err::m_nOK;
}

//JVT-S036  start
ErrVal FrameMng::xMmcoMarkShortTermAsUnusedBase( const FrameUnit* pcCurrFrameUnit, UInt uiDiffOfPicNums )
{
  UInt  uiCurrPicNum  = pcCurrFrameUnit->getFrameNumber();
  UInt  uiPicNumN     = uiCurrPicNum - uiDiffOfPicNums - 1;

  if( uiCurrPicNum <= uiDiffOfPicNums )
  {
    uiPicNumN += m_uiMaxFrameNumPrev;
  }

  FUIter iter = m_cShortTermList.findShortTerm( uiPicNumN );
  if( iter == m_cShortTermList.end() )
  {
    printf("\nMMCO not possible\n" );
    return Err::m_nOK; // HS: decoder robustness
  }

  FrameUnit* pcFrameUnit = (*iter);
  if(pcFrameUnit->getBaseRep() )
  {
	  pcFrameUnit->setUnused();
	  RNOK( xRemoveFromRefList( m_cShortTermList, iter ) );
  }
  
  return Err::m_nOK;
}
//JVT-S036  end

ErrVal FrameMng::xManageMemory( const SliceHeader& rcSH )
{
  ROTRS( ! rcSH.getNalRefIdc(), Err::m_nOK );

  if( ! rcSH.getAdaptiveRefPicBufferingFlag() )
  {
    RNOK( xSlidingWindowUpdate() );
    return Err::m_nOK;
  }


  MmcoOp eMmcoOp;
  const MmcoBuffer& rcMmcoBuffer = rcSH.getMmcoBuffer();
  UInt uiVal1, uiVal2;
  Int iIndex = 0;
  while( MMCO_END != (eMmcoOp = rcMmcoBuffer.get( iIndex++ ).getCommand( uiVal1, uiVal2)) )
  {

    switch (eMmcoOp)
    {
    case MMCO_SHORT_TERM_UNUSED:
      RNOK( xMmcoMarkShortTermAsUnusedMVC( m_pcCurrentFrameUnit, uiVal1, rcSH.getViewId() ) );
      break;
    case MMCO_RESET:
    case MMCO_MAX_LONG_TERM_IDX:

⌨️ 快捷键说明

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