Src_HM/source/App/TAppDecoder/TAppDecTop.cpp
/** \param pcListPic list of pictures to be written to file
    \todo            DYN_REF_FREE should be revised
 */
\param pcListPic list of pictures to be written to file
\todo            DYN_REF_FREE should be revised
\ param pcListPic list of pictures to be written to file \ todo DYN_REF_FREE should be revised
Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
{
  if (pcListPic->empty())
  {
    return;
  }
  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
  Int numPicsNotYetDisplayed = 0;
  Int dpbFullness = 0;
  TComSPS* activeSPS = m_cTDecTop.getActiveSPS();
  UInt numReorderPicsHighestTid;
  UInt maxDecPicBufferingHighestTid;
  UInt maxNrSublayers = activeSPS->getMaxTLayers();
  if(m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers)
  {
    numReorderPicsHighestTid = activeSPS->getNumReorderPics(maxNrSublayers-1);
    maxDecPicBufferingHighestTid =  activeSPS->getMaxDecPicBuffering(maxNrSublayers-1); 
  }
  else
  {
    numReorderPicsHighestTid = activeSPS->getNumReorderPics(m_iMaxTemporalLayer);
    maxDecPicBufferingHighestTid = activeSPS->getMaxDecPicBuffering(m_iMaxTemporalLayer); 
  }
  while (iterPic != pcListPic->end())
  {
    TComPic* pcPic = *(iterPic);
    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
    {
      numPicsNotYetDisplayed++;
      dpbFullness++;
    }
    else if(pcPic->getSlice( 0 )->isReferenced())
    {
      dpbFullness++;
    }
    iterPic++;
  }
  iterPic   = pcListPic->begin();
  if (numPicsNotYetDisplayed>2)
  {
    iterPic++;
  }
  TComPic* pcPic = *(iterPic);
  if (numPicsNotYetDisplayed>2 && pcPic->isField()) 
  {
    TComList<TComPic*>::iterator endPic   = pcListPic->end();
    endPic--;
    iterPic   = pcListPic->begin();
    while (iterPic != endPic)
    {
      TComPic* pcPicTop = *(iterPic);
      iterPic++;
      TComPic* pcPicBottom = *(iterPic);
      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
          (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
          (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&
          (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay < 0))
      {
        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
        if ( m_pchReconFile )
        {
          const Window &conf = pcPicTop->getConformanceWindow();
          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
          const Bool isTff = pcPicTop->isTopField();
          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
        }
        m_iPOCLastDisplay = pcPicBottom->getPOC();
        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
        {
#if !DYN_REF_FREE
          pcPicTop->setReconMark(false);
          pcPicTop->getPicYuvRec()->setBorderExtension( false );
#else
          pcPicTop->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); 
          continue;
#endif
        }
        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
        {
#if !DYN_REF_FREE
          pcPicBottom->setReconMark(false);
          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
#else
          pcPicBottom->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); 
          continue;
#endif
        }
        pcPicTop->setOutputMark(false);
        pcPicBottom->setOutputMark(false);
      }
    }
  }
  else if (!pcPic->isField()) 
  {
    iterPic = pcListPic->begin();
    while (iterPic != pcListPic->end())
    {
      pcPic = *(iterPic);
      if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay &&
        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
      {
        numPicsNotYetDisplayed--;
        if(pcPic->getSlice(0)->isReferenced() == false)
        {
          dpbFullness--;
        }
        if ( m_pchReconFile )
        {
          const Window &conf = pcPic->getConformanceWindow();
          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
        }
        m_iPOCLastDisplay = pcPic->getPOC();
        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
        {
#if !DYN_REF_FREE
          pcPic->setReconMark(false);
          pcPic->getPicYuvRec()->setBorderExtension( false );
#else
          pcPic->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); 
          continue;
#endif
        }
        pcPic->setOutputMark(false);
      }
      iterPic++;
    }
  }
}
Void TAppDecTop :: xWriteOutput ( TComList < TComPic * > * pcListPic , UInt tId ) { if ( pcListPic -> empty ( ) ) { return ; } TComList < TComPic * > :: iterator iterPic = pcListPic -> begin ( ) ; Int numPicsNotYetDisplayed = 0 ; Int dpbFullness = 0 ; TComSPS * activeSPS = m_cTDecTop . getActiveSPS ( ) ; UInt numReorderPicsHighestTid ; UInt maxDecPicBufferingHighestTid ; UInt maxNrSublayers = activeSPS -> getMaxTLayers ( ) ; if ( m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers ) { numReorderPicsHighestTid = activeSPS -> getNumReorderPics ( maxNrSublayers - 1 ) ; maxDecPicBufferingHighestTid = activeSPS -> getMaxDecPicBuffering ( maxNrSublayers - 1 ) ; } else { numReorderPicsHighestTid = activeSPS -> getNumReorderPics ( m_iMaxTemporalLayer ) ; maxDecPicBufferingHighestTid = activeSPS -> getMaxDecPicBuffering ( m_iMaxTemporalLayer ) ; } while ( iterPic != pcListPic -> end ( ) ) { TComPic * pcPic = * ( iterPic ) ; if ( pcPic -> getOutputMark ( ) && pcPic -> getPOC ( ) > m_iPOCLastDisplay ) { numPicsNotYetDisplayed ++ ; dpbFullness ++ ; } else if ( pcPic -> getSlice ( 0 ) -> isReferenced ( ) ) { dpbFullness ++ ; } iterPic ++ ; } iterPic = pcListPic -> begin ( ) ; if ( numPicsNotYetDisplayed > 2 ) { iterPic ++ ; } TComPic * pcPic = * ( iterPic ) ; if ( numPicsNotYetDisplayed > 2 && pcPic -> isField ( ) ) { TComList < TComPic * > :: iterator endPic = pcListPic -> end ( ) ; endPic -- ; iterPic = pcListPic -> begin ( ) ; while ( iterPic != endPic ) { TComPic * pcPicTop = * ( iterPic ) ; iterPic ++ ; TComPic * pcPicBottom = * ( iterPic ) ; if ( pcPicTop -> getOutputMark ( ) && pcPicBottom -> getOutputMark ( ) && ( numPicsNotYetDisplayed > numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid ) && ( ! ( pcPicTop -> getPOC ( ) % 2 ) && pcPicBottom -> getPOC ( ) == pcPicTop -> getPOC ( ) + 1 ) && ( pcPicTop -> getPOC ( ) == m_iPOCLastDisplay + 1 || m_iPOCLastDisplay < 0 ) ) { numPicsNotYetDisplayed = numPicsNotYetDisplayed - 2 ; if ( m_pchReconFile ) { const Window & conf = pcPicTop -> getConformanceWindow ( ) ; const Window & defDisp = m_respectDefDispWindow ? pcPicTop -> getDefDisplayWindow ( ) : Window ( ) ; const Bool isTff = pcPicTop -> isTopField ( ) ; m_cTVideoIOYuvReconFile . write ( pcPicTop -> getPicYuvRec ( ) , pcPicBottom -> getPicYuvRec ( ) , conf . getWindowLeftOffset ( ) + defDisp . getWindowLeftOffset ( ) , conf . getWindowRightOffset ( ) + defDisp . getWindowRightOffset ( ) , conf . getWindowTopOffset ( ) + defDisp . getWindowTopOffset ( ) , conf . getWindowBottomOffset ( ) + defDisp . getWindowBottomOffset ( ) , isTff ) ; } m_iPOCLastDisplay = pcPicBottom -> getPOC ( ) ; if ( ! pcPicTop -> getSlice ( 0 ) -> isReferenced ( ) && pcPicTop -> getReconMark ( ) == true ) { #if ! DYN_REF_FREE pcPicTop -> setReconMark ( false ) ; pcPicTop -> getPicYuvRec ( ) -> setBorderExtension ( false ) ; #else pcPicTop -> destroy ( ) ; pcListPic -> erase ( iterPic ) ; iterPic = pcListPic -> begin ( ) ; continue ; #endif } if ( ! pcPicBottom -> getSlice ( 0 ) -> isReferenced ( ) && pcPicBottom -> getReconMark ( ) == true ) { #if ! DYN_REF_FREE pcPicBottom -> setReconMark ( false ) ; pcPicBottom -> getPicYuvRec ( ) -> setBorderExtension ( false ) ; #else pcPicBottom -> destroy ( ) ; pcListPic -> erase ( iterPic ) ; iterPic = pcListPic -> begin ( ) ; continue ; #endif } pcPicTop -> setOutputMark ( false ) ; pcPicBottom -> setOutputMark ( false ) ; } } } else if ( ! pcPic -> isField ( ) ) { iterPic = pcListPic -> begin ( ) ; while ( iterPic != pcListPic -> end ( ) ) { pcPic = * ( iterPic ) ; if ( pcPic -> getOutputMark ( ) && pcPic -> getPOC ( ) > m_iPOCLastDisplay && ( numPicsNotYetDisplayed > numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid ) ) { numPicsNotYetDisplayed -- ; if ( pcPic -> getSlice ( 0 ) -> isReferenced ( ) == false ) { dpbFullness -- ; } if ( m_pchReconFile ) { const Window & conf = pcPic -> getConformanceWindow ( ) ; const Window & defDisp = m_respectDefDispWindow ? pcPic -> getDefDisplayWindow ( ) : Window ( ) ; m_cTVideoIOYuvReconFile . write ( pcPic -> getPicYuvRec ( ) , conf . getWindowLeftOffset ( ) + defDisp . getWindowLeftOffset ( ) , conf . getWindowRightOffset ( ) + defDisp . getWindowRightOffset ( ) , conf . getWindowTopOffset ( ) + defDisp . getWindowTopOffset ( ) , conf . getWindowBottomOffset ( ) + defDisp . getWindowBottomOffset ( ) ) ; } m_iPOCLastDisplay = pcPic -> getPOC ( ) ; if ( ! pcPic -> getSlice ( 0 ) -> isReferenced ( ) && pcPic -> getReconMark ( ) == true ) { #if ! DYN_REF_FREE pcPic -> setReconMark ( false ) ; pcPic -> getPicYuvRec ( ) -> setBorderExtension ( false ) ; #else pcPic -> destroy ( ) ; pcListPic -> erase ( iterPic ) ; iterPic = pcListPic -> begin ( ) ; continue ; #endif } pcPic -> setOutputMark ( false ) ; } iterPic ++ ; } } }
\param pcListPic list of pictures to be written to file
\todo            DYN_REF_FREE should be revised
\ param pcListPic list of pictures to be written to file \ todo DYN_REF_FREE should be revised
//Field Decoding // write to file // update POC of display order // erase non-referenced picture in the reference picture list after display // mark it should be extended later // to the beginning, non-efficient way, have to be revised! // mark it should be extended later // to the beginning, non-efficient way, have to be revised! //Frame Decoding // write to file // update POC of display order // erase non-referenced picture in the reference picture list after display // mark it should be extended later // to the beginning, non-efficient way, have to be revised!