source: 3DVCSoftware/trunk/source/App/TAppDecoder/TAppDecTop.cpp @ 1071

Last change on this file since 1071 was 1066, checked in by tech, 10 years ago

Merged 12.0-dev1@1065.

  • Property svn:eol-style set to native
File size: 36.4 KB
RevLine 
[5]1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
[56]4 * granted under this license. 
[5]5 *
[872]6* Copyright (c) 2010-2014, ITU/ISO/IEC
[5]7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
[56]17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
[5]18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
[2]33
34/** \file     TAppDecTop.cpp
35    \brief    Decoder application class
36*/
37
38#include <list>
[56]39#include <vector>
[2]40#include <stdio.h>
41#include <fcntl.h>
42#include <assert.h>
43
44#include "TAppDecTop.h"
[56]45#include "TLibDecoder/AnnexBread.h"
46#include "TLibDecoder/NALread.h"
[2]47
[56]48//! \ingroup TAppDecoder
49//! \{
[2]50
51// ====================================================================================================================
52// Constructor / destructor / initialization / destroy
53// ====================================================================================================================
54
55TAppDecTop::TAppDecTop()
[608]56#if !H_MV
57: m_iPOCLastDisplay(-MAX_INT)
58#else
59: m_numDecoders( 0 )
60#endif
[2]61{
[608]62#if H_MV
[738]63  for (Int i = 0; i < MAX_NUM_LAYER_IDS; i++) 
64  {
65    m_layerIdToDecIdx[i] = -1; 
66    m_layerInitilizedFlags[i] = false; 
67  }
[608]68#endif
69#if H_3D
70    m_pScaleOffsetFile  = 0;
71#endif
[964]72
[976]73#if H_MV
[964]74    m_markedForOutput = false; 
75#endif
76
[2]77}
78
79Void TAppDecTop::create()
80{
81}
82
83Void TAppDecTop::destroy()
84{
[608]85  if (m_pchBitstreamFile)
86  {
87    free (m_pchBitstreamFile);
88    m_pchBitstreamFile = NULL;
89  }
90#if H_MV
91  for (Int decIdx = 0; decIdx < m_numDecoders; decIdx++)
92  {
93    if (m_pchReconFiles[decIdx])
94    {
95      free (m_pchReconFiles[decIdx]);
96      m_pchReconFiles[decIdx] = NULL;
97    }
98  }
99#endif
100  if (m_pchReconFile)
101  {
102    free (m_pchReconFile);
103    m_pchReconFile = NULL;
104  }
105#if H_3D
106  if (m_pchScaleOffsetFile)
107  {
108    free (m_pchScaleOffsetFile);
109    m_pchScaleOffsetFile = NULL; 
110  }
111#endif
[2]112}
113
114// ====================================================================================================================
115// Public member functions
116// ====================================================================================================================
117
118/**
119 - create internal class
120 - initialize internal class
121 - until the end of the bitstream, call decoding function in TDecTop class
122 - delete allocated buffers
123 - destroy internal class
124 .
125 */
126Void TAppDecTop::decode()
127{
[608]128  Int                 poc;
129#if H_MV
130  poc = -1; 
[77]131#endif
[608]132  TComList<TComPic*>* pcListPic = NULL;
[210]133
[56]134  ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
135  if (!bitstreamFile)
136  {
137    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
138    exit(EXIT_FAILURE);
139  }
[2]140
[608]141#if H_3D
[56]142  if( m_pchScaleOffsetFile ) 
143  { 
144    m_pScaleOffsetFile = ::fopen( m_pchScaleOffsetFile, "wt" ); 
145    AOF( m_pScaleOffsetFile ); 
146  }
[608]147#endif
[56]148  InputByteStream bytestream(bitstreamFile);
149
[608]150  // create & initialize internal classes
151  xCreateDecLib();
152  xInitDecLib  ();
153#if !H_MV
154  m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
155
156  // main decoder loop
[655]157  Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
[608]158#else
[964]159
[608]160  Int  pocCurrPic        = -MAX_INT;     
161  Int  pocLastPic        = -MAX_INT;   
[964]162
163  Int  layerIdLastPic    = -MAX_INT; 
[608]164  Int  layerIdCurrPic    = 0; 
165
166  Int  decIdxLastPic     = 0; 
167  Int  decIdxCurrPic     = 0; 
168
169  Bool firstSlice        = true; 
170#endif
[872]171  Bool loopFiltered      = false;
172
[56]173  while (!!bitstreamFile)
[2]174  {
[56]175    /* location serves to work around a design fault in the decoder, whereby
176     * the process of reading a new slice that is the first slice of a new frame
177     * requires the TDecTop::decode() method to be called again with the same
178     * nal unit. */
179    streampos location = bitstreamFile.tellg();
[608]180#if H_MV
181#if ENC_DEC_TRACE
182    Int64 symCount = g_nSymbolCounter;
183#endif
184#endif
[56]185    AnnexBStats stats = AnnexBStats();
186    vector<uint8_t> nalUnit;
187    InputNALUnit nalu;
188    byteStreamNALUnit(bytestream, nalUnit, stats);
189
190    // call actual decoding function
[608]191    Bool bNewPicture = false;
192#if H_MV
193    Bool newSliceDiffPoc   = false;
194    Bool newSliceDiffLayer = false;
[964]195    Bool sliceSkippedFlag  = false; 
[608]196    Bool allLayersDecoded  = false;     
197#endif
[56]198    if (nalUnit.empty())
[2]199    {
[56]200      /* this can happen if the following occur:
201       *  - empty input file
202       *  - two back-to-back start_code_prefixes
203       *  - start_code_prefix immediately followed by EOF
204       */
205      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
[2]206    }
207    else
208    {
[56]209      read(nalu, nalUnit);
[608]210#if H_MV     
[872]211      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) 
212          || !isNaluWithinTargetDecLayerIdSet(&nalu)
213          || nalu.m_layerId > MAX_NUM_LAYER_IDS-1
214          || (nalu.m_nalUnitType == NAL_UNIT_VPS && nalu.m_layerId > 0)           
[964]215          || (nalu.m_nalUnitType == NAL_UNIT_EOB && nalu.m_layerId > 0)   
216          || (nalu.m_nalUnitType == NAL_UNIT_EOS && nalu.m_layerId > 0)   
[872]217         ) 
[77]218      {
[608]219        bNewPicture = false;
[738]220        if ( !bitstreamFile )
221        {
222          decIdxLastPic     = decIdxCurrPic; 
223        }
[77]224      }
[210]225      else
[608]226      { 
[738]227        Int decIdx     = xGetDecoderIdx( nalu.m_layerId , true );     
[608]228        newSliceDiffLayer = nalu.isSlice() && ( nalu.m_layerId != layerIdCurrPic ) && !firstSlice;
[738]229        newSliceDiffPoc   = m_tDecTop[decIdx]->decode(nalu, m_iSkipFrame, m_pocLastDisplay[decIdx], newSliceDiffLayer, sliceSkippedFlag );
[608]230        // decode function only returns true when all of the following conditions are true
231        // - poc in particular layer changes
232        // - nalu does not belong to first slice in layer
233        // - nalu.isSlice() == true     
234
[964]235        if ( nalu.m_nalUnitType == NAL_UNIT_VPS )
236        {
237          m_vps = m_tDecTop[decIdx]->getPrefetchedVPS(); 
238          if ( m_targetDecLayerIdSetFileEmpty )
239          {
240            TComVPS* vps = m_vps; 
[1066]241            if ( m_targetOptLayerSetIdx == -1 )
242            {
243              // Not normative! Corresponds to specification by "External Means". (Should be set equal to 0, when no external means available. )
244              m_targetOptLayerSetIdx = vps->getVpsNumLayerSetsMinus1(); 
245            }
[976]246
[1066]247            for (Int dI = 0; dI < m_numDecoders; dI++ )
248            {
249              m_tDecTop[decIdx]->setTargetOptLayerSetIdx( m_targetOptLayerSetIdx ); 
250            }
251
252            if ( m_targetOptLayerSetIdx < 0 || m_targetOptLayerSetIdx >= vps->getNumOutputLayerSets() )
253            {
254              fprintf(stderr, "\ntarget output layer set index must be in the range of 0 to %d, inclusive \n", vps->getNumOutputLayerSets() - 1 );           
255              exit(EXIT_FAILURE);
256            }
257            m_targetDecLayerIdSet = vps->getTargetDecLayerIdList( m_targetOptLayerSetIdx ); 
[964]258          }
[1066]259#if H_MV_HLS10_GEN_FIX
260          if (m_outputVpsInfo )
[872]261          {
[1066]262#if H_MV_HLS10_AUX
263            m_vps->printScalabilityId();
264#endif
265            m_vps->printLayerDependencies();
266            m_vps->printLayerSets();
267            m_vps->printPTL(); 
[872]268          }
[1066]269#endif
[738]270        }
[872]271#if H_3D
272        if (nalu.m_nalUnitType == NAL_UNIT_VPS )
[884]273        {                 
[872]274          m_cCamParsCollector.init( m_pScaleOffsetFile, m_tDecTop[decIdx]->getPrefetchedVPS() );
275        }       
276#endif
[738]277        bNewPicture       = ( newSliceDiffLayer || newSliceDiffPoc ) && !sliceSkippedFlag; 
278        if ( nalu.isSlice() && firstSlice && !sliceSkippedFlag )       
[210]279        {
[608]280          layerIdCurrPic = nalu.m_layerId; 
281          pocCurrPic     = m_tDecTop[decIdx]->getCurrPoc(); 
282          decIdxCurrPic  = decIdx; 
283          firstSlice     = false; 
[210]284        }
[608]285
286        if ( bNewPicture || !bitstreamFile )
287        { 
[964]288          layerIdLastPic    = layerIdCurrPic; 
[608]289          layerIdCurrPic    = nalu.m_layerId; 
290          pocLastPic        = pocCurrPic; 
291          pocCurrPic        = m_tDecTop[decIdx]->getCurrPoc(); 
292          decIdxLastPic     = decIdxCurrPic; 
293          decIdxCurrPic     = decIdx; 
294          allLayersDecoded = ( pocCurrPic != pocLastPic );
[210]295        }
296#else
[608]297      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
[210]298      {
[655]299        bNewPicture = false;
[210]300      }
[608]301      else
[2]302      {
[608]303        bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
[56]304#endif
[608]305        if (bNewPicture)
[42]306        {
[56]307          bitstreamFile.clear();
308          /* location points to the current nalunit payload[1] due to the
309           * need for the annexB parser to read three extra bytes.
310           * [1] except for the first NAL unit in the file
311           *     (but bNewPicture doesn't happen then) */
312          bitstreamFile.seekg(location-streamoff(3));
313          bytestream.reset();
[872]314#if H_MV_ENC_DEC_TRAC
[608]315#if ENC_DEC_TRACE
316          const Bool resetCounter = false; 
317          if ( resetCounter )
318          {
319            g_nSymbolCounter  = symCount; // Only reset counter SH becomes traced twice
[210]320          }
[608]321          else
322          {
[872]323            g_disableHLSTrace = true;     // Tracing of second parsing of SH is not carried out
324          }     
[210]325#endif
[608]326#endif
[42]327        }
328      }
[56]329    }
[872]330    if (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS )
[56]331    {
[872]332      if (!loopFiltered || bitstreamFile)
333      {
[608]334#if H_MV
[872]335        assert( decIdxLastPic != -1 ); 
336        m_tDecTop[decIdxLastPic]->endPicDecoding(poc, pcListPic, m_targetDecLayerIdSet );
[964]337        xMarkForOutput( allLayersDecoded, poc, layerIdLastPic ); 
[608]338#else
[872]339        m_cTDecTop.executeLoopFilters(poc, pcListPic);
[608]340#endif
[872]341      }
342      loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
[56]343    }
[964]344#if !FIX_WRITING_OUTPUT
345#if SETTING_NO_OUT_PIC_PRIOR
346    if (bNewPicture && m_cTDecTop.getIsNoOutputPriorPics())
347    {
348      m_cTDecTop.checkNoOutputPriorPics( pcListPic );
349    }
350#endif
351#endif
[608]352#if H_3D
353    if ( allLayersDecoded || !bitstreamFile )
[56]354    {
[608]355      for( Int dI = 0; dI < m_numDecoders; dI++ )
356      {
357        TComPic* picLastCoded = m_ivPicLists.getPic( m_tDecTop[dI]->getLayerId(), pocLastPic );
358        assert( picLastCoded != NULL );       
359        picLastCoded->compressMotion(1);
360      }
361    }
362#endif
363
364    if( pcListPic )
365    {
366#if H_MV
367      if ( m_pchReconFiles[decIdxLastPic] && !m_reconOpen[decIdxLastPic] )
368#else
[655]369      if ( m_pchReconFile && !openedReconFile  )
[608]370#endif
[2]371      {
[608]372        if (!m_outputBitDepthY) { m_outputBitDepthY = g_bitDepthY; }
373        if (!m_outputBitDepthC) { m_outputBitDepthC = g_bitDepthC; }
374
375#if H_MV
376        m_tVideoIOYuvReconFile[decIdxLastPic]->open( m_pchReconFiles[decIdxLastPic], true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
377        m_reconOpen[decIdxLastPic] = true;
[2]378      }
[964]379#if FIX_WRITING_OUTPUT
380      // write reconstruction to file
381      if( bNewPicture )
382      {
383        // Bumping after picture has been decoded
384#if ENC_DEC_TRACE
385        g_bJustDoIt = true; 
386        writeToTraceFile( "Bumping after decoding \n", g_decTracePicOutput  );         
387        g_bJustDoIt = false; 
388#endif
389        xWriteOutput( pcListPic, decIdxLastPic, nalu.m_temporalId );
390      }
391#if SETTING_NO_OUT_PIC_PRIOR
392      if ( (bNewPicture || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) && m_tDecTop[decIdxLastPic]->getNoOutputPriorPicsFlag() )
393      {
394        m_tDecTop[decIdxLastPic]->checkNoOutputPriorPics( pcListPic );
395        m_tDecTop[decIdxLastPic]->setNoOutputPriorPicsFlag (false);
396      }
397#endif
398#endif
[608]399      if ( bNewPicture && newSliceDiffPoc && 
400#else
401        m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
[655]402        openedReconFile  = true;
[608]403      }
[964]404#if FIX_WRITING_OUTPUT
405      // write reconstruction to file
406      if( bNewPicture )
407      {
408        xWriteOutput( pcListPic, nalu.m_temporalId );
409      }
410#if SETTING_NO_OUT_PIC_PRIOR
411      if ( (bNewPicture || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) && m_cTDecTop.getNoOutputPriorPicsFlag() )
412      {
413        m_cTDecTop.checkNoOutputPriorPics( pcListPic );
414        m_cTDecTop.setNoOutputPriorPicsFlag (false);
415      }
416#endif
417#endif
[608]418      if ( bNewPicture && 
419#endif
420           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
421            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
422            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
423            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
424            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
425      {
426#if H_MV
427        xFlushOutput( pcListPic, decIdxLastPic );
428#else
429        xFlushOutput( pcListPic );
430#endif
431      }
[872]432      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
433      {
434#if H_MV
[964]435#if FIX_OUTPUT_EOS
436        xWriteOutput( pcListPic, decIdxLastPic, nalu.m_temporalId );
437#else
[872]438        xFlushOutput( pcListPic, decIdxLastPic );
[964]439#endif
[872]440#else
[964]441#if FIX_OUTPUT_EOS
442        xWriteOutput( pcListPic, nalu.m_temporalId );
443#else
[872]444        xFlushOutput( pcListPic );
445#endif
[964]446
447#endif
[872]448      }
[964]449      // write reconstruction to file -- for additional bumping as defined in C.5.2.3
450#if H_MV
451      // Above comment seems to be wrong
452#endif
453#if FIX_WRITING_OUTPUT
454      if(!bNewPicture && nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL_N && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL31)
455#else
[608]456      if(bNewPicture)
[964]457#endif
[2]458      {
[964]459#if H_MV       
460        // Bumping after reference picture set has been applied (here after first vcl nalu.
461#if ENC_DEC_TRACE
462        g_bJustDoIt = true; 
463        writeToTraceFile( "Bumping after reference picture set has been applied \n", g_decTracePicOutput  );         
464        g_bJustDoIt = false; 
465#endif
466
467        xWriteOutput( m_tDecTop[decIdxCurrPic]->getListPic(), decIdxCurrPic, nalu.m_temporalId );
468#else
469        xWriteOutput( pcListPic, nalu.m_temporalId );
470#endif
[2]471      }
472    }
[608]473  }
[964]474#if H_MV
[608]475#if H_3D
[57]476  if( m_cCamParsCollector.isInitialized() )
477  {
478    m_cCamParsCollector.setSlice( 0 );
479  }
[608]480#endif
481  for(UInt decIdx = 0; decIdx < m_numDecoders; decIdx++)
[2]482  {
[608]483    xFlushOutput( m_tDecTop[decIdx]->getListPic(), decIdx );
484  }
[964]485#else 
[608]486  xFlushOutput( pcListPic );
487  // delete buffers
488  m_cTDecTop.deletePicBuffer();
489#endif
490     
491  // destroy internal classes
[2]492  xDestroyDecLib();
493}
494
495// ====================================================================================================================
496// Protected member functions
497// ====================================================================================================================
498
[608]499Void TAppDecTop::xCreateDecLib()
500{
501#if H_MV
502  // initialize global variables
503  initROM(); 
504#if H_3D_DIM_DMM
505  initWedgeLists();
506#endif
507#else
508  // create decoder class
509  m_cTDecTop.create();
510#endif
511}
512
[2]513Void TAppDecTop::xDestroyDecLib()
514{
[608]515#if H_MV
516  // destroy ROM
517  destroyROM();
[2]518
[608]519  for(Int decIdx = 0; decIdx < m_numDecoders ; decIdx++)
[2]520  {
[608]521    if( m_tVideoIOYuvReconFile[decIdx] )
[56]522    {
[608]523      m_tVideoIOYuvReconFile[decIdx]->close();
524      delete m_tVideoIOYuvReconFile[decIdx]; 
525      m_tVideoIOYuvReconFile[decIdx] = NULL ;
[56]526    }
[2]527
[608]528    if( m_tDecTop[decIdx] )
[56]529    {
[608]530      m_tDecTop[decIdx]->deletePicBuffer();
531      m_tDecTop[decIdx]->destroy() ;
[56]532    }
[608]533    delete m_tDecTop[decIdx] ; 
534    m_tDecTop[decIdx] = NULL ;
[2]535  }
[608]536#else
537  if ( m_pchReconFile )
538  {
539    m_cTVideoIOYuvReconFile. close();
540  }
541 
542  // destroy decoder class
543  m_cTDecTop.destroy();
544#endif
545#if H_3D
[57]546  m_cCamParsCollector.uninit();
547  if( m_pScaleOffsetFile ) 
548  { 
549    ::fclose( m_pScaleOffsetFile ); 
550  }
[608]551#endif
[56]552}
[2]553
[608]554Void TAppDecTop::xInitDecLib()
[56]555{
[608]556#if !H_MV
557  // initialize decoder class
558  m_cTDecTop.init();
559  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
560#endif
561}
562
563/** \param pcListPic list of pictures to be written to file
564    \todo            DYN_REF_FREE should be revised
565 */
566#if H_MV
567Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, Int decIdx, Int tId )
568#else
569Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
570#endif
571{
[872]572
573  if (pcListPic->empty())
574  {
575    return;
576  }
577
[56]578  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
[655]579  Int numPicsNotYetDisplayed = 0;
[964]580  Int dpbFullness = 0;
581#if H_MV
[1066]582#if H_MV_HLS10_ADD_LAYERSETS
583  TComSPS* activeSPS = m_tDecTop[ decIdx ]->getActiveSPS();
584#else
[964]585  // preliminary fix
586  TComSPS* activeSPS = m_tDecTop[0]->getActiveSPS();
[1066]587#endif
[964]588#else
589  TComSPS* activeSPS = m_cTDecTop.getActiveSPS();
590#endif
591  UInt numReorderPicsHighestTid;
592  UInt maxDecPicBufferingHighestTid;
593  UInt maxNrSublayers = activeSPS->getMaxTLayers();
594
595  if(m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers)
596  {
597    numReorderPicsHighestTid = activeSPS->getNumReorderPics(maxNrSublayers-1);
598    maxDecPicBufferingHighestTid =  activeSPS->getMaxDecPicBuffering(maxNrSublayers-1); 
599  }
600  else
601  {
602    numReorderPicsHighestTid = activeSPS->getNumReorderPics(m_iMaxTemporalLayer);
603    maxDecPicBufferingHighestTid = activeSPS->getMaxDecPicBuffering(m_iMaxTemporalLayer); 
604  }
[655]605 
[56]606  while (iterPic != pcListPic->end())
[2]607  {
[56]608    TComPic* pcPic = *(iterPic);
[608]609#if H_MV
610    if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[decIdx])
611#else
612    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
613#endif
[56]614    {
[655]615      numPicsNotYetDisplayed++;
[964]616      dpbFullness++;
[56]617    }
[964]618    else if(pcPic->getSlice( 0 )->isReferenced())
619    {
620      dpbFullness++;
621    }
[56]622    iterPic++;
[2]623  }
[56]624  iterPic   = pcListPic->begin();
[655]625  if (numPicsNotYetDisplayed>2)
626  {
627    iterPic++;
628  }
[56]629 
[655]630  TComPic* pcPic = *(iterPic);
631  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
[2]632  {
[655]633    TComList<TComPic*>::iterator endPic   = pcListPic->end();
634    endPic--;
635    iterPic   = pcListPic->begin();
636    while (iterPic != endPic)
637    {
638      TComPic* pcPicTop = *(iterPic);
639      iterPic++;
640      TComPic* pcPicBottom = *(iterPic);
641     
[608]642#if H_MV
[655]643      if ( pcPicTop->getOutputMark() && (numPicsNotYetDisplayed >  pcPicTop->getNumReorderPics(tId) && !(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1)
644          && pcPicBottom->getOutputMark() && (numPicsNotYetDisplayed >  pcPicBottom->getNumReorderPics(tId) && (pcPicTop->getPOC() == m_pocLastDisplay[decIdx]+1 || m_pocLastDisplay[decIdx]<0)))
[608]645#else
[964]646      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
647          (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
648          (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&
649          (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay < 0))
[608]650#endif
[655]651      {
652        // write to file
653        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
[608]654#if H_MV
655      if ( m_pchReconFiles[decIdx] )
656#else
[655]657        if ( m_pchReconFile )
[608]658#endif
[655]659        {
660          const Window &conf = pcPicTop->getConformanceWindow();
661          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
662
663          const Bool isTff = pcPicTop->isTopField();
[608]664#if H_MV
[622]665        assert( conf   .getScaledFlag() );
666        assert( defDisp.getScaledFlag() );
[976]667#if ENC_DEC_TRACE
[964]668        g_bJustDoIt = true; 
669        writeToTraceFile( "OutputPic Poc"   , pcPic->getPOC    (), g_decTracePicOutput  ); 
670        writeToTraceFile( "OutputPic LayerId", pcPic->getLayerId(), g_decTracePicOutput );         
671        g_bJustDoIt = false; 
672#endif
[655]673        m_tVideoIOYuvReconFile[decIdx]->write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
674#else
675          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
[622]676#endif
[655]677                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
678                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
679                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
680                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
681        }
682       
683        // update POC of display order
684#if H_MV
685        m_pocLastDisplay[decIdx] = pcPic->getPOC();
[608]686#else
[655]687        m_iPOCLastDisplay = pcPicBottom->getPOC();
[608]688#endif
[655]689       
690        // erase non-referenced picture in the reference picture list after display
691        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
692        {
693#if !DYN_REF_FREE
694          pcPicTop->setReconMark(false);
695         
696          // mark it should be extended later
697          pcPicTop->getPicYuvRec()->setBorderExtension( false );
698         
699#else
700          pcPicTop->destroy();
701          pcListPic->erase( iterPic );
702          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
703          continue;
704#endif
705        }
706        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
707        {
708#if !DYN_REF_FREE
709          pcPicBottom->setReconMark(false);
710         
711          // mark it should be extended later
712          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
713         
714#else
715          pcPicBottom->destroy();
716          pcListPic->erase( iterPic );
717          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
718          continue;
719#endif
720        }
721        pcPicTop->setOutputMark(false);
722        pcPicBottom->setOutputMark(false);
[56]723      }
[655]724    }
725  }
726  else if (!pcPic->isField()) //Frame Decoding
727  {
728    iterPic = pcListPic->begin();
729    while (iterPic != pcListPic->end())
730    {
731      pcPic = *(iterPic);
732
[608]733#if H_MV
[964]734      if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[decIdx] &&
735        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
[655]736#else     
[964]737      if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay &&
738        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
[655]739#endif
740      {
741        // write to file
742        numPicsNotYetDisplayed--;
[964]743        if(pcPic->getSlice(0)->isReferenced() == false)
744        {
745          dpbFullness--;
746        }
[655]747#if H_MV
748      if ( m_pchReconFiles[decIdx] )
[608]749#else
[655]750        if ( m_pchReconFile )
[608]751#endif
[655]752        {
753          const Window &conf = pcPic->getConformanceWindow();
754          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
755#if H_MV
756        assert( conf   .getScaledFlag() );
757        assert( defDisp.getScaledFlag() );
[964]758#if ENC_DEC_TRACE
759        g_bJustDoIt = true; 
760        writeToTraceFile( "OutputPic Poc"   , pcPic->getPOC    (), g_decTracePicOutput  ); 
761        writeToTraceFile( "OutputPic LayerId", pcPic->getLayerId(), g_decTracePicOutput );         
762        g_bJustDoIt = false; 
763#endif
[655]764        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
765#else
766          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
767#endif
768                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
769                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
770                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
771                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
772        }
[56]773       
[655]774        // update POC of display order
775#if H_MV
776        m_pocLastDisplay[decIdx] = pcPic->getPOC();
777#else
778        m_iPOCLastDisplay = pcPic->getPOC();
779#endif
[56]780       
[655]781        // erase non-referenced picture in the reference picture list after display
782        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
783        {
784#if !DYN_REF_FREE
785          pcPic->setReconMark(false);
786         
787          // mark it should be extended later
788          pcPic->getPicYuvRec()->setBorderExtension( false );
789         
[56]790#else
[655]791          pcPic->destroy();
792          pcListPic->erase( iterPic );
793          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
794          continue;
[56]795#endif
[655]796        }
797        pcPic->setOutputMark(false);
[976]798#if H_MV
[964]799        pcPic->setPicOutputFlag(false);
800#endif
[56]801      }
[655]802     
803      iterPic++;
[56]804    }
[2]805  }
806}
807/** \param pcListPic list of pictures to be written to file
808    \todo            DYN_REF_FREE should be revised
809 */
[608]810#if H_MV
811Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int decIdx )
812#else
813Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
814#endif
[2]815{
[872]816  if(!pcListPic || pcListPic->empty())
[56]817  {
818    return;
[655]819  }
[2]820  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
[655]821 
[56]822  iterPic   = pcListPic->begin();
[655]823  TComPic* pcPic = *(iterPic);
[56]824 
[655]825  if (pcPic->isField()) //Field Decoding
[2]826  {
[655]827    TComList<TComPic*>::iterator endPic   = pcListPic->end();
828    endPic--;
829    TComPic *pcPicTop, *pcPicBottom = NULL;
830    while (iterPic != endPic)
[2]831    {
[655]832      pcPicTop = *(iterPic);
833      iterPic++;
834      pcPicBottom = *(iterPic);
835     
836      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
837      {
838        // write to file
[608]839#if H_MV
840      if ( m_pchReconFiles[decIdx] )
841#else
[655]842        if ( m_pchReconFile )
[608]843#endif
[655]844        {
845          const Window &conf = pcPicTop->getConformanceWindow();
846          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
847          const Bool isTff = pcPicTop->isTopField();
[608]848#if H_MV
[622]849        assert( conf   .getScaledFlag() );
850        assert( defDisp.getScaledFlag() );
[964]851#if ENC_DEC_TRACE
852        g_bJustDoIt = true; 
853        writeToTraceFile( "OutputPic Poc"   , pcPic->getPOC    (), g_decTracePicOutput  ); 
854        writeToTraceFile( "OutputPic LayerId", pcPic->getLayerId(), g_decTracePicOutput );         
855        g_bJustDoIt = false; 
856#endif
[655]857        m_tVideoIOYuvReconFile[decIdx]->write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
858#else
859          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
[622]860#endif
[655]861                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
862                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
863                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
864                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
865        }
866       
867        // update POC of display order
868#if H_MV
869      m_pocLastDisplay[decIdx] = pcPic->getPOC();
[608]870#else
[655]871      m_iPOCLastDisplay = pcPicBottom->getPOC();
872#endif       
873        // erase non-referenced picture in the reference picture list after display
874        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
875        {
876#if !DYN_REF_FREE
877          pcPicTop->setReconMark(false);
878         
879          // mark it should be extended later
880          pcPicTop->getPicYuvRec()->setBorderExtension( false );
881         
882#else
883          pcPicTop->destroy();
884          pcListPic->erase( iterPic );
885          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
886          continue;
[608]887#endif
[655]888        }
889        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
890        {
891#if !DYN_REF_FREE
892          pcPicBottom->setReconMark(false);
893         
894          // mark it should be extended later
895          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
896         
897#else
898          pcPicBottom->destroy();
899          pcListPic->erase( iterPic );
900          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
901          continue;
902#endif
903        }
904        pcPicTop->setOutputMark(false);
905        pcPicBottom->setOutputMark(false);
906       
907#if !DYN_REF_FREE
908        if(pcPicTop)
909        {
910          pcPicTop->destroy();
911          delete pcPicTop;
912          pcPicTop = NULL;
913        }
914#endif
[2]915      }
[655]916    }
917    if(pcPicBottom)
918    {
919      pcPicBottom->destroy();
920      delete pcPicBottom;
921      pcPicBottom = NULL;
922    }
923  }
924  else //Frame decoding
925  {
926    while (iterPic != pcListPic->end())
927    {
928      pcPic = *(iterPic);
[56]929     
[655]930      if ( pcPic->getOutputMark() )
931      {
932        // write to file
[608]933#if H_MV
[655]934      if ( m_pchReconFiles[decIdx] )
935#else
936        if ( m_pchReconFile )
937#endif
938        {
939          const Window &conf = pcPic->getConformanceWindow();
940          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
941#if H_MV
942        assert( conf   .getScaledFlag() );
943        assert( defDisp.getScaledFlag() );
[964]944#if ENC_DEC_TRACE
945        g_bJustDoIt = true; 
946        writeToTraceFile( "OutputPic Poc"   , pcPic->getPOC    (), g_decTracePicOutput  ); 
947        writeToTraceFile( "OutputPic LayerId", pcPic->getLayerId(), g_decTracePicOutput );         
948        g_bJustDoIt = false; 
949#endif
[655]950        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
951#else
952          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
953#endif
954                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
955                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
956                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
957                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
958        }
959       
960        // update POC of display order
961#if H_MV
[608]962      m_pocLastDisplay[decIdx] = pcPic->getPOC();
963#else
[655]964        m_iPOCLastDisplay = pcPic->getPOC();
[608]965#endif
[655]966       
967        // erase non-referenced picture in the reference picture list after display
968        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
969        {
[56]970#if !DYN_REF_FREE
[655]971          pcPic->setReconMark(false);
972         
973          // mark it should be extended later
974          pcPic->getPicYuvRec()->setBorderExtension( false );
975         
[56]976#else
[655]977          pcPic->destroy();
978          pcListPic->erase( iterPic );
979          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
980          continue;
[56]981#endif
[655]982        }
983        pcPic->setOutputMark(false);
[976]984#if H_MV
[964]985        pcPic->setPicOutputFlag(false);
986#endif
[2]987      }
[608]988#if !H_MV
989#if !DYN_REF_FREE
[655]990      if(pcPic)
991      {
992        pcPic->destroy();
993        delete pcPic;
994        pcPic = NULL;
995      }
996#endif   
997#endif
998      iterPic++;
[608]999    }
[2]1000  }
[608]1001#if H_MV
1002  m_pocLastDisplay[decIdx] = -MAX_INT;
1003#else
[56]1004  pcListPic->clear();
[608]1005  m_iPOCLastDisplay = -MAX_INT;
1006#endif
[2]1007}
[608]1008
1009/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
1010 */
1011Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
[2]1012{
[608]1013  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
[2]1014  {
[608]1015    return true;
[2]1016  }
[608]1017  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
1018  {
1019#if H_MV
1020    if ( nalu->m_layerId == (*it) )
[81]1021#else
[608]1022    if ( nalu->m_reservedZero6Bits == (*it) )
[81]1023#endif
[56]1024    {
[608]1025      return true;
[56]1026    }
1027  }
[608]1028  return false;
[2]1029}
1030
[608]1031#if H_MV
1032Int TAppDecTop::xGetDecoderIdx( Int layerId, Bool createFlag /*= false */ )
1033{
1034  Int decIdx = -1; 
[738]1035
1036  if ( layerId > MAX_NUM_LAYER_IDS-1 ) 
1037  {
1038    return decIdx; 
1039  }
1040
[608]1041  if ( m_layerIdToDecIdx[ layerId ] != -1 ) 
1042  {     
1043    decIdx = m_layerIdToDecIdx[ layerId ]; 
[210]1044  }
1045  else
[608]1046  {     
1047    assert ( createFlag ); 
1048    assert( m_numDecoders < MAX_NUM_LAYERS ); 
[210]1049
[608]1050    decIdx = m_numDecoders; 
1051
1052    // Init decoder
1053    m_tDecTop[ decIdx ] =  new TDecTop;
1054    m_tDecTop[ decIdx ]->create();
1055    m_tDecTop[ decIdx ]->init( );
1056    m_tDecTop[ decIdx ]->setLayerId( layerId );
1057    m_tDecTop[ decIdx ]->setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
1058    m_tDecTop[ decIdx ]->setIvPicLists( &m_ivPicLists ); 
[738]1059    m_tDecTop[ decIdx ]->setLayerInitilizedFlags( m_layerInitilizedFlags );
[964]1060    m_tDecTop[ decIdx ]->setTargetOptLayerSetIdx( m_targetOptLayerSetIdx );   
[738]1061
[608]1062#if H_3D
1063   m_tDecTop[ decIdx ]->setCamParsCollector( &m_cCamParsCollector );
[210]1064#endif
[2]1065
[608]1066    // append pic list of new decoder to PicLists
1067    assert( m_ivPicLists.size() == m_numDecoders );
1068    m_ivPicLists.push_back( m_tDecTop[ decIdx ]->getListPic() );
[2]1069
[608]1070    // create recon file related stuff     
1071    Char* pchTempFilename = NULL;
1072    if ( m_pchReconFile )
1073    {     
1074      Char buffer[4];     
1075      sprintf(buffer,"_%i", layerId );
1076      assert ( m_pchReconFile ); 
1077      xAppendToFileNameEnd( m_pchReconFile , buffer, pchTempFilename );
1078      assert( m_pchReconFiles.size() == m_numDecoders );
[2]1079    }
[210]1080
[608]1081    m_pchReconFiles.push_back( pchTempFilename );   
[296]1082
[608]1083    m_tVideoIOYuvReconFile[ decIdx ] = new TVideoIOYuv;
1084    m_reconOpen           [ decIdx ] = false;
[443]1085
[608]1086    // set others
1087    m_pocLastDisplay      [ decIdx ] = -MAX_INT;
1088    m_layerIdToDecIdx     [ layerId ] = decIdx; 
[296]1089
[608]1090    m_numDecoders++; 
1091  };
1092  return decIdx;
[964]1093
[296]1094}
[964]1095
1096Void TAppDecTop::xMarkForOutput( Bool allLayersDecoded, Int pocLastPic, Int layerIdLastPic )
1097{ 
1098  vector<Int> targetOptLayerIdList = m_vps->getTargetOptLayerIdList( m_targetOptLayerSetIdx );
1099
1100  if (m_vps->getAltOutputLayerFlagVar( m_targetOptLayerSetIdx ) )
1101  {
1102    assert( targetOptLayerIdList.size() == 1 ); 
1103    Int targetLayerId = targetOptLayerIdList[0];     
1104
1105    TComPic* curPic = m_ivPicLists.getPic( layerIdLastPic, pocLastPic );
1106    assert( curPic != NULL );
1107
1108    if ( layerIdLastPic == targetLayerId )
1109    {
1110      if ( curPic->getPicOutputFlag() )
1111      {
1112        curPic->setOutputMark( true );
1113      }
1114      else
1115      {       
1116        xMarkAltOutPic( targetLayerId, pocLastPic ); 
1117      }
1118      m_markedForOutput = true; 
1119    }
1120    else if ( ( layerIdLastPic > targetLayerId || allLayersDecoded ) && !m_markedForOutput )
1121    {
1122      xMarkAltOutPic( targetLayerId, pocLastPic );
1123    }
1124
1125    if ( allLayersDecoded )
1126    {
1127      m_markedForOutput = false; 
1128    }
1129  }
1130  else
1131  { 
1132    for( Int dI = 0; dI < m_numDecoders; dI++ )
1133    {     
1134      Int layerId = m_tDecTop[dI]->getLayerId(); 
1135      TComPic* curPic = m_ivPicLists.getPic( layerId, pocLastPic );
1136      if ( curPic != NULL )
1137      {
1138        if ( curPic->getReconMark() )
1139        {
1140          Bool isTargetOptLayer = std::find(targetOptLayerIdList.begin(), targetOptLayerIdList.end(), layerId) != targetOptLayerIdList.end();
1141          curPic->setOutputMark( isTargetOptLayer ? curPic->getPicOutputFlag() : false ); 
1142        }
1143      }
1144    }
1145  }
1146}
[976]1147
1148Void TAppDecTop::xMarkAltOutPic( Int targetOutputLayer, Int pocLastPic )
1149{
1150  Int optLayerIdxInVps = m_vps->getLayerIdInNuh( targetOutputLayer ); 
1151  Int highestNuhLayerId = -1; 
1152  TComPic* picWithHighestNuhLayerId = NULL; 
1153  for (Int dIdx = 0; dIdx < m_numDecoders; dIdx++)
1154  {
1155    Int curLayerId = m_tDecTop[dIdx]->getLayerId();
1156    Int curLayerIdxInVps = m_vps->getLayerIdInNuh( curLayerId  ); 
[1066]1157#if H_MV_HLS10_REF_PRED_LAYERS
1158    if ( m_vps->getDependencyFlag(optLayerIdxInVps, curLayerIdxInVps ) )
1159#else
[976]1160    if ( m_vps->getInDirectDependencyFlag(optLayerIdxInVps, curLayerIdxInVps ) )
[1066]1161#endif
[976]1162    {
1163      TComPic* curPic = m_ivPicLists.getPic( curLayerId, pocLastPic ); 
1164      if (curPic != NULL)
1165      {
1166        if (curPic->getReconMark() && curPic->getPicOutputFlag() )
1167        {
1168          curPic->setOutputMark   ( false ); 
1169          curPic->setPicOutputFlag( false ); 
1170          if ( curLayerId > highestNuhLayerId)
1171          {
1172            highestNuhLayerId = curLayerId ; 
1173            picWithHighestNuhLayerId = curPic; 
1174          }           
1175        }
1176      }
1177    }
1178  }
1179  if ( picWithHighestNuhLayerId != NULL )
1180  {
1181    picWithHighestNuhLayerId->setPicOutputFlag(true); 
1182    picWithHighestNuhLayerId->setOutputMark   (true); 
1183  }
1184}
1185
[296]1186#endif
[56]1187//! \}
Note: See TracBrowser for help on using the repository browser.