gopdecoder.cpp

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

CPP
1,768
字号
ErrVal
DecodedPicBuffer::xMarkAllUnusedForRef( Bool bRemoveOutputFlag )
{
  m_iMaxLongTermFrameIdx      = -1;
  DPBUnitList::iterator iter  = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end   = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    RNOK( (*iter)->markUnusedForRef( FRAME, bRemoveOutputFlag ) );
  }
  m_pcLastDPBUnit           = 0;
  m_pcLastDPBUnitRefBasePic = 0;
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xSlidingWindow( UInt uiCurrFrameNum )
{
  ROF( m_bInitDone && m_bInitBufferDone );
  //===== determine number of reference frames and DPB units with smallest FrameNumWrap value =====
  UInt                  uiNumShortTerm    = 0;
  UInt                  uiNumLongTerm     = 0;
  Int                   iMinFrameNumWrap  = MSYS_INT_MAX;
  DPBUnit*              pcMinFrameNumUnit = 0;
  DPBUnitList::iterator iter              = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end               = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isLongTermUnit() )
    {
      uiNumLongTerm++;
    }
    else if( (*iter)->isShortTermUnit() )
    {
      uiNumShortTerm++;
      if( ( (*iter)->getFrameNumWrap( uiCurrFrameNum, m_uiMaxFrameNum )  < iMinFrameNumWrap ) ||
          ( (*iter)->getFrameNumWrap( uiCurrFrameNum, m_uiMaxFrameNum ) == iMinFrameNumWrap && (*iter)->isRefBasePicUnit() ) )
      {
        pcMinFrameNumUnit = *iter;
        iMinFrameNumWrap  = pcMinFrameNumUnit->getFrameNumWrap( uiCurrFrameNum, m_uiMaxFrameNum );
      }
    }
  }
  //===== check number of reference frames =====
  ROTRS ( uiNumShortTerm + uiNumLongTerm < m_uiMaxNumRefFrames,  Err::m_nOK );
  ROT   ( uiNumShortTerm + uiNumLongTerm > m_uiMaxNumRefFrames );
  ROF   ( pcMinFrameNumUnit ); // no short-term reference picture available
  //===== mark DPB unit with smallest FrameNumWrap value as "unused for reference" =====
  RNOK  ( pcMinFrameNumUnit->markUnusedForRef( FRAME ) );
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xMMCO( PocCalculator& rcPocCalculator, SliceHeader& rcSliceHeader, Bool& rbMMCO6, Bool bRefBasePic )
{
  Mmco                    eMmcoOp;
  UInt                    uiVal1, uiVal2;
  UInt                    uiCurrFrameNum  = rcSliceHeader.getFrameNum (); 
  PicType                 eCurrPicType    = rcSliceHeader.getPicType  ();
  const DecRefPicMarking& rcMmcoBuffer    = ( bRefBasePic ? rcSliceHeader.getDecRefBasePicMarking() : rcSliceHeader.getDecRefPicMarking() );
  Int                     iIndex          = 0;
  Int                     iMMCO6LTFrmIdx  = -1;
  Bool                    bMMCO123        = false;
  Bool                    bMMCO4          = false;
  Bool                    bMMCO5          = false;
  rbMMCO6                                 = false;

  while( MMCO_END != ( eMmcoOp = rcMmcoBuffer.get( iIndex++ ).getCommand( uiVal1, uiVal2 ) ) )
  {
    switch( eMmcoOp )
    {
    case MMCO_SHORT_TERM_UNUSED:
      ROT ( bMMCO5 );
      RNOK( xMarkShortTermUnused( uiCurrFrameNum, eCurrPicType, uiVal1, bRefBasePic ) );
      bMMCO123  = true;
      break;
    case MMCO_LONG_TERM_UNUSED:
      ROT ( bMMCO5 );
      ROT ( rbMMCO6 && iMMCO6LTFrmIdx == (Int)( eCurrPicType == FRAME ? uiVal1 : ( uiVal1 >> 1 ) ) );
      RNOK( xMarkLongTermUnused( eCurrPicType, uiVal1, bRefBasePic ) );
      bMMCO123  = true;
      break;
    case MMCO_ASSIGN_LONG_TERM:
      ROT ( bRefBasePic );
      ROT ( bMMCO5 );
      ROT ( rbMMCO6 && iMMCO6LTFrmIdx == (Int)uiVal2 );
      ROF ( (Int)uiVal2 <= m_iMaxLongTermFrameIdx );
      RNOK( xAssignLongTermIndex( uiCurrFrameNum, eCurrPicType, uiVal1, uiVal2 ) );
      bMMCO123  = true;
      break;
    case MMCO_MAX_LONG_TERM_IDX:
      ROT ( bRefBasePic );
      ROT ( bMMCO4 );
      ROT ( rbMMCO6 && iMMCO6LTFrmIdx >= (Int)uiVal1 )
      RNOK( xSetMaxLongTermIndex( uiVal1 ) );
      bMMCO4  = true;
      break;
    case MMCO_RESET:
      ROT ( bRefBasePic );
      ROT ( bMMCO123 );
      ROT ( bMMCO5 );
      ROT ( rbMMCO6 );
      RNOK( xReset( rcPocCalculator, rcSliceHeader ) );
      bMMCO5  = true;
      break;
    case MMCO_SET_LONG_TERM:
      ROT ( bRefBasePic );
      ROT ( rbMMCO6 );
      ROF ( (Int)uiVal1 <= m_iMaxLongTermFrameIdx );
      RNOK( xStoreCurrentLongTerm( uiVal1, rcSliceHeader.getStoreRefBasePicFlag() ) );
      rbMMCO6         = true;
      iMMCO6LTFrmIdx  = uiVal1;
      break;
    default:
      ROT ( true );
    }
  }
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xMarkShortTermUnused( UInt uiCurrFrameNum, PicType eCurrPicType, UInt uiPicNumDiff, Bool bRefBasePic )
{
  Int     iCurrPicNum     = ( eCurrPicType == FRAME ? (Int)uiCurrFrameNum : 2 * (Int)uiCurrFrameNum + 1 );
  Int     iPicNumX        = ( iCurrPicNum - (Int)uiPicNumDiff - 1 );
  PicType ePicTypeX       = ( eCurrPicType == FRAME ? FRAME    : ( iPicNumX  % 2 ? eCurrPicType : PicType( FRAME - eCurrPicType ) ) );
  UInt    iFrameNumWrapX  = ( eCurrPicType == FRAME ? iPicNumX : ( iPicNumX >> 1 ) );
  //===== find short-term picture and mark "unused for reference" =====
  DPBUnit*              pcDPBUnit = 0;
  DPBUnitList::iterator iter      = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end       = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isShortTermRef   ( ePicTypeX )                                         &&
        (*iter)->isRefBasePicUnit ()                                  == bRefBasePic    &&
        (*iter)->getFrameNumWrap  ( uiCurrFrameNum, m_uiMaxFrameNum ) == iFrameNumWrapX   )
    {
      ROT( pcDPBUnit );
      pcDPBUnit = *iter;
    }
  }
  ROF ( pcDPBUnit ); // not found
  RNOK( pcDPBUnit->markUnusedForRef( ePicTypeX ) );
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xMarkLongTermUnused( PicType eCurrPicType, UInt uiLongTermPicNum, Bool bRefBasePic )
{
  PicType ePicTypeX         = ( eCurrPicType == FRAME ? FRAME                 : ( (Int)uiLongTermPicNum % 2 ? eCurrPicType : PicType( FRAME - eCurrPicType ) ) );
  Int     iLongTermFrameIdx = ( eCurrPicType == FRAME ? (Int)uiLongTermPicNum : ( (Int)uiLongTermPicNum >> 1 ) );
  //===== find long-term picture and mark "unused for reference" =====
  DPBUnit*              pcDPBUnit = 0;
  DPBUnitList::iterator iter      = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end       = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isLongTermRef    ( ePicTypeX )                       &&
        (*iter)->isRefBasePicUnit ()            == bRefBasePic        &&
        (*iter)->getLongTermIndex ()            == iLongTermFrameIdx    )
    {
      ROT( pcDPBUnit );
      pcDPBUnit = *iter;
    }
  }
  ROF ( pcDPBUnit ); // not found
  RNOK( pcDPBUnit->markUnusedForRef( ePicTypeX ) );
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xAssignLongTermIndex( UInt uiCurrFrameNum, PicType eCurrPicType, UInt uiPicNumDiff, UInt uiLongTermFrameIndex )
{
  ROF( (Int)uiLongTermFrameIndex <= m_iMaxLongTermFrameIdx );
  Int     iCurrPicNum       = ( eCurrPicType == FRAME ? (Int)uiCurrFrameNum : 2 * (Int)uiCurrFrameNum + 1 );
  Int     iPicNumX          = ( iCurrPicNum - (Int)uiPicNumDiff - 1 );
  PicType ePicTypeX         = ( eCurrPicType == FRAME ? FRAME    : ( iPicNumX  % 2 ? eCurrPicType : PicType( FRAME - eCurrPicType ) ) );
  UInt    iFrameNumWrapX    = ( eCurrPicType == FRAME ? iPicNumX : ( iPicNumX >> 1 ) );
  Int     iLongTermFrameIdx = (Int)uiLongTermFrameIndex;
  //===== mark long-term pictures with specified index as "unused for reference" =====
  DPBUnitList::iterator iter  = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end   = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isLongTermUnit   ()                      &&
        (*iter)->getLongTermIndex () == iLongTermFrameIdx   )
    {
      RNOK( (*iter)->markUnusedForRef( FRAME ) );
    }
  }
  //===== find short-term pictures =====
  DPBUnit*  pcDPBUnit     = 0;
  DPBUnit*  pcDPBUnitBase = 0;
  iter                    = m_cUsedDPBUnitList.begin();
  end                     = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isShortTermRef   ( ePicTypeX )                                         &&
        (*iter)->getFrameNumWrap  ( uiCurrFrameNum, m_uiMaxFrameNum ) == iFrameNumWrapX   )
    {
      if( (*iter)->isRefBasePicUnit() )
      {
        ROT( pcDPBUnitBase );
        pcDPBUnitBase = *iter;
      }
      else
      {
        ROT( pcDPBUnit );
        pcDPBUnit = *iter;
      }
    }
  }
  //===== mark pictures =====
  ROF   ( pcDPBUnit );
  RNOK  ( pcDPBUnit     ->markLongTerm( ePicTypeX, iLongTermFrameIdx ) );
  ROFRS ( pcDPBUnitBase,  Err::m_nOK );
  RNOK  ( pcDPBUnitBase ->markLongTerm( ePicTypeX, iLongTermFrameIdx ) );
  return  Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xSetMaxLongTermIndex( UInt uiMaxLongTermFrameIdxPlus1 )
{
  m_iMaxLongTermFrameIdx = (Int)uiMaxLongTermFrameIdxPlus1 - 1;
  //===== mark long-term pictures with higher index as "unused for reference" =====
  DPBUnitList::iterator iter  = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end   = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isLongTermUnit   ()                          &&
        (*iter)->getLongTermIndex () > m_iMaxLongTermFrameIdx   )
    {
      RNOK( (*iter)->markUnusedForRef( FRAME ) );
    }
  }
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xReset( PocCalculator& rcPocCalculator, SliceHeader& rcSliceHeader )
{
  //===== check maximum POC of all required pictures =====
  Int                   iMaxPoc = MSYS_INT_MIN;
  DPBUnitList::iterator iter    = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end     = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isRequired() )
    {
      Int iPoc  = (*iter)->getMaxPoc( rcSliceHeader.getSPS().getPicOrderCntType() == 0 );
      iMaxPoc   = max( iMaxPoc, iPoc );
    }
  }
  ROF( m_pcCurrDPBUnit->getPoc() > iMaxPoc );
  //===== mark all pictures as "unused for reference" =====
  RNOK( xMarkAllUnusedForRef() );
  //===== reset PocCalculator and POC values in slice Header =====
  RNOK( rcPocCalculator .resetMMCO5 ( rcSliceHeader ) );
  //===== update parameters in current DPB unit =====
  ROF ( m_pcCurrDPBUnit->isCompleted() );
  RNOK( m_pcCurrDPBUnit->resetMMCO5 ( rcSliceHeader ) );
  return Err::m_nOK;
}

ErrVal
DecodedPicBuffer::xStoreCurrentLongTerm( UInt uiLongTermFrameIndex, Bool bStoreRefBasePic )
{
  Int  iLongTermFrameIdx  = (Int)uiLongTermFrameIndex;
  ROF( iLongTermFrameIdx <= m_iMaxLongTermFrameIdx );
  //===== mark long-term pictures with specified index as "unused for reference" =====
  DPBUnitList::iterator iter  = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end   = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    if( (*iter)->isLongTermUnit   ()                      &&
        (*iter)->getLongTermIndex () == iLongTermFrameIdx   )
    {
      if( xIs2ndFieldOfCompFieldPair( bStoreRefBasePic ) )
      {
        ROF( *iter == ( bStoreRefBasePic ? m_pcLastDPBUnitRefBasePic : m_pcLastDPBUnit ) );
      }
      else
      {
        RNOK( (*iter)->markUnusedForRef( FRAME ) );
      }
    }
  }
  //===== mark current picture as long-term =====
  RNOK( m_pcCurrDPBUnit->markLongTerm( m_pcCurrDPBUnit->getPicStatus(), uiLongTermFrameIndex ) );
  //===== store current picture =====
  if( xIs2ndFieldOfCompFieldPair() )
  {
    RNOK( m_pcCurrDPBUnit->store    ( *m_pcLastDPBUnit ) );
  }
  else
  {
    RNOK( xInsertCurrentInNewBuffer (  m_pcLastDPBUnit ) );
  }
  //===== store reference base picture =====
  if( bStoreRefBasePic )
  {
    if( xIs2ndFieldOfCompFieldPair( true ) )
    {
      RNOK( m_pcCurrDPBUnit->store    ( *m_pcLastDPBUnitRefBasePic, true ) );
    }
    else
    {
      RNOK( xInsertCurrentInNewBuffer (  m_pcLastDPBUnitRefBasePic, true ) );
    }
  }
  else
  {
    m_pcLastDPBUnitRefBasePic = 0;
  }
  return Err::m_nOK;
}

Bool
DecodedPicBuffer::xExistsRefBasePicShortTerm( UInt uiFrameNum )
{
  DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end  = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    ROTRS( (*iter)->isShortTermUnit() && (*iter)->isRefBasePicUnit() && (*iter)->getFrameNum() == uiFrameNum, true );
  }
  return false;
}

Bool
DecodedPicBuffer::xExistsRefBasePicLongTerm ( Int iLongTermFrameIdx )
{
  DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
  DPBUnitList::iterator end  = m_cUsedDPBUnitList.end  ();
  for( ; iter != end; iter++ )
  {
    ROTRS( (*iter)->isLongTermUnit() && (*iter)->isRefBasePicUnit() && (*iter)->getLongTermIndex() == iLongTermFrameIdx, true );
  }
  return false;
}

Bool
DecodedPicBuffer::xIsAvailableForRefLists( const DPBUnit* pcDPBUnit, Bool bFieldPicture, Bool bExcludeNonExisting, Bool bUseRefBasePic )
{
  AOF  ( pcDPBUnit );
  ROFRS( bFieldPicture       ||  pcDPBUnit->isRefFrame(), false );
  ROTRS( bExcludeNonExisting && !pcDPBUnit->isExisting(), false );
  if( !bUseRefBasePic )
  {
    ROTRS( pcDPBUnit->isUsedForRef () && ! pcDPBUnit->isRefBasePicUnit(), true );
    return false;
  }

⌨️ 快捷键说明

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