source: SHVCSoftware/branches/SHM-upgrade/source/App/TAppDecoder/TAppDecTop.cpp @ 917

Last change on this file since 917 was 916, checked in by seregin, 10 years ago

initial porting

  • Property svn:eol-style set to native
File size: 57.7 KB
Line 
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
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2014, ITU/ISO/IEC
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.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
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 */
33
34/** \file     TAppDecTop.cpp
35    \brief    Decoder application class
36*/
37
38#include <list>
39#include <vector>
40#include <stdio.h>
41#include <fcntl.h>
42#include <assert.h>
43
44#include "TAppDecTop.h"
45#include "TLibDecoder/AnnexBread.h"
46#include "TLibDecoder/NALread.h"
47#if RExt__DECODER_DEBUG_BIT_STATISTICS
48#include "TLibCommon/TComCodingStatistics.h"
49#endif
50
51//! \ingroup TAppDecoder
52//! \{
53
54// ====================================================================================================================
55// Constructor / destructor / initialization / destroy
56// ====================================================================================================================
57
58#if SVC_EXTENSION
59TAppDecTop::TAppDecTop()
60{
61  for(UInt layer=0; layer < MAX_LAYERS; layer++)
62  {
63    m_aiPOCLastDisplay[layer]  = -MAX_INT;
64    m_apcTDecTop[layer] = &m_acTDecTop[layer];
65  }
66}
67#else
68TAppDecTop::TAppDecTop()
69: m_iPOCLastDisplay(-MAX_INT)
70{
71}
72#endif
73
74Void TAppDecTop::create()
75{
76}
77
78Void TAppDecTop::destroy()
79{
80  if (m_pchBitstreamFile)
81  {
82    free (m_pchBitstreamFile);
83    m_pchBitstreamFile = NULL;
84  }
85#if SVC_EXTENSION
86  for( Int i = 0; i <= m_tgtLayerId; i++ )
87  {
88    if( m_pchReconFile[i] )
89    {
90      free ( m_pchReconFile[i] );
91      m_pchReconFile[i] = NULL;
92    }
93  }
94#if AVC_BASE
95  if( m_pchBLReconFile )
96  {
97    free ( m_pchBLReconFile );
98    m_pchBLReconFile = NULL;
99  }
100#endif
101#else
102  if (m_pchReconFile)
103  {
104    free (m_pchReconFile);
105    m_pchReconFile = NULL;
106  }
107#endif
108}
109
110// ====================================================================================================================
111// Public member functions
112// ====================================================================================================================
113
114/**
115 - create internal class
116 - initialize internal class
117 - until the end of the bitstream, call decoding function in TDecTop class
118 - delete allocated buffers
119 - destroy internal class
120 .
121 */
122#if SVC_EXTENSION
123Void TAppDecTop::decode()
124{
125  Int                poc;
126  TComList<TComPic*>* pcListPic = NULL;
127
128  ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
129  if (!bitstreamFile)
130  {
131    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
132    exit(EXIT_FAILURE);
133  }
134
135  InputByteStream bytestream(bitstreamFile);
136
137  if (!m_outputDecodedSEIMessagesFilename.empty() && m_outputDecodedSEIMessagesFilename!="-")
138  {
139    m_seiMessageFileStream.open(m_outputDecodedSEIMessagesFilename.c_str(), std::ios::out);
140    if (!m_seiMessageFileStream.is_open() || !m_seiMessageFileStream.good())
141    {
142      fprintf(stderr, "\nUnable to open file `%s' for writing decoded SEI messages\n", m_outputDecodedSEIMessagesFilename.c_str());
143      exit(EXIT_FAILURE);
144    }
145  }
146
147  // create & initialize internal classes
148  xCreateDecLib();
149  xInitDecLib  (); 
150
151  // main decoder loop
152  Bool openedReconFile[MAX_LAYERS]; // reconstruction file not yet opened. (must be performed after SPS is seen)
153  Bool loopFiltered[MAX_LAYERS];
154  memset( loopFiltered, false, sizeof( loopFiltered ) );
155
156  for(UInt layer=0; layer<=m_tgtLayerId; layer++)
157  {
158    openedReconFile[layer] = false;
159    m_aiPOCLastDisplay[layer] += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
160  }
161
162  UInt curLayerId = 0;     // current layer to be reconstructed
163
164#if AVC_BASE
165  TComPic pcBLPic;
166  fstream streamYUV;
167  if( m_pchBLReconFile )
168  {
169    streamYUV.open( m_pchBLReconFile, fstream::in | fstream::binary );
170  }
171  TComList<TComPic*> *cListPic = m_acTDecTop[0].getListPic();
172  m_acTDecTop[0].setBLReconFile( &streamYUV );
173  pcBLPic.setLayerId( 0 );
174  cListPic->pushBack( &pcBLPic );
175#endif
176
177  while (!!bitstreamFile)
178  {
179    /* location serves to work around a design fault in the decoder, whereby
180     * the process of reading a new slice that is the first slice of a new frame
181     * requires the TDecTop::decode() method to be called again with the same
182     * nal unit. */
183#if RExt__DECODER_DEBUG_BIT_STATISTICS
184    TComCodingStatistics::TComCodingStatisticsData backupStats(TComCodingStatistics::GetStatistics());
185    streampos location = bitstreamFile.tellg() - streampos(bytestream.GetNumBufferedBytes());
186#else
187    streampos location = bitstreamFile.tellg();
188#endif
189    AnnexBStats stats = AnnexBStats();
190
191    vector<uint8_t> nalUnit;
192    InputNALUnit nalu;
193    byteStreamNALUnit(bytestream, nalUnit, stats);
194
195    // call actual decoding function
196    Bool bNewPicture = false;
197    Bool bNewPOC = false;
198
199    if (nalUnit.empty())
200    {
201      /* this can happen if the following occur:
202       *  - empty input file
203       *  - two back-to-back start_code_prefixes
204       *  - start_code_prefix immediately followed by EOF
205       */
206      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
207    }
208    else
209    {
210      read(nalu, nalUnit);
211      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  ||
212        (nalu.m_layerId > m_tgtLayerId) )
213      {
214        bNewPicture = false;
215      }
216      else
217      {
218        bNewPicture = m_acTDecTop[nalu.m_layerId].decode(nalu, m_iSkipFrame, m_aiPOCLastDisplay[nalu.m_layerId], curLayerId, bNewPOC);
219#if POC_RESET_IDC_DECODER
220        if ( (bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 3) || (m_acTDecTop[nalu.m_layerId].getParseIdc() == 0) )
221#else
222        if (bNewPicture)
223#endif
224        {
225          bitstreamFile.clear();
226          /* location points to the current nalunit payload[1] due to the
227           * need for the annexB parser to read three extra bytes.
228           * [1] except for the first NAL unit in the file
229           *     (but bNewPicture doesn't happen then) */
230#if RExt__DECODER_DEBUG_BIT_STATISTICS
231          bitstreamFile.seekg(location);
232          bytestream.reset();
233          TComCodingStatistics::SetStatistics(backupStats);
234#else
235          bitstreamFile.seekg(location-streamoff(3));
236          bytestream.reset();
237#endif
238        }
239#if POC_RESET_IDC_DECODER
240        else if(m_acTDecTop[nalu.m_layerId].getParseIdc() == 1) 
241        {
242          bitstreamFile.clear();
243          // This is before third parse of the NAL unit, and
244          // location points to correct beginning of the NALU
245          bitstreamFile.seekg(location);
246          bytestream.reset();
247#if RExt__DECODER_DEBUG_BIT_STATISTICS
248          TComCodingStatistics::SetStatistics(backupStats);
249#endif
250        }
251#endif
252      }
253    }
254
255#if POC_RESET_IDC_DECODER
256    if ( (bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 3) || (m_acTDecTop[nalu.m_layerId].getParseIdc() == 0) || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS &&
257        !m_acTDecTop[nalu.m_layerId].getFirstSliceInSequence() )
258#else
259    if (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS &&
260        !m_acTDecTop[nalu.m_layerId].getFirstSliceInSequence() )
261#endif
262    {
263#if O0194_DIFFERENT_BITDEPTH_EL_BL
264      //Bug fix: The bit depth was not set correctly for each layer when doing DBF
265      g_bitDepth[CHANNEL_TYPE_LUMA]   = g_bitDepthLayer[CHANNEL_TYPE_LUMA][curLayerId];
266      g_bitDepth[CHANNEL_TYPE_CHROMA] = g_bitDepthLayer[CHANNEL_TYPE_CHROMA][curLayerId];
267#endif
268      if (!loopFiltered[curLayerId] || bitstreamFile)
269      {
270        m_acTDecTop[curLayerId].executeLoopFilters(poc, pcListPic);
271      }
272      loopFiltered[curLayerId] = (nalu.m_nalUnitType == NAL_UNIT_EOS);
273#if EARLY_REF_PIC_MARKING
274      m_acTDecTop[curLayerId].earlyPicMarking(m_iMaxTemporalLayer, m_targetDecLayerIdSet);
275#endif
276      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
277      {
278        m_acTDecTop[nalu.m_layerId].setFirstSliceInSequence(true);
279      }
280    }
281    else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) &&
282              m_acTDecTop[nalu.m_layerId].getFirstSliceInSequence () ) 
283    {
284      m_acTDecTop[nalu.m_layerId].setFirstSliceInPicture (true);
285    }
286
287#if POC_RESET_IDC_DECODER
288    if( bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 0 )
289    {
290      outputAllPictures( nalu.m_layerId, true );
291    }
292#endif
293
294    if( pcListPic )
295    {
296      if ( m_pchReconFile[curLayerId] && !openedReconFile[curLayerId] )
297      {
298        for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
299        {
300          if (m_outputBitDepth[channelType] == 0) m_outputBitDepth[channelType] = g_bitDepth[channelType];
301        }
302        m_acTVideoIOYuvReconFile[curLayerId].open( m_pchReconFile[curLayerId], true, m_outputBitDepth, m_outputBitDepth, g_bitDepth ); // write mode
303
304        openedReconFile[curLayerId] = true;
305      }
306#if ALIGNED_BUMPING
307      Bool outputPicturesFlag = true; 
308#if NO_OUTPUT_OF_PRIOR_PICS
309      if( m_acTDecTop[nalu.m_layerId].getNoOutputPriorPicsFlag() )
310      {
311        outputPicturesFlag = false;
312      }
313#endif
314
315      if (nalu.m_nalUnitType == NAL_UNIT_EOS) // End of sequence
316      {
317        flushAllPictures( nalu.m_layerId, outputPicturesFlag );       
318      }
319
320#if POC_RESET_IDC_DECODER
321      if( bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() != 0 )
322      // New picture, slice header parsed but picture not decoded
323#else
324      if( bNewPicture ) // New picture, slice header parsed but picture not decoded
325#endif
326      {
327#if NO_OUTPUT_OF_PRIOR_PICS
328        if( 
329#else
330        if ( bNewPOC &&
331#endif
332           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
333            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
334            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
335            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
336            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
337        {
338          flushAllPictures( nalu.m_layerId, outputPicturesFlag );
339        }
340        else
341        {
342          this->checkOutputBeforeDecoding( nalu.m_layerId );
343        }
344      }
345
346      /* The following code has to be executed when the last DU of the picture is decoded
347         TODO: Need code to identify end of decoding a picture
348      {
349        this->checkOutputAfterDecoding( );
350      } */
351#else
352      if ( bNewPicture && bNewPOC &&
353           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
354            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
355            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
356            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
357            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
358      {
359        xFlushOutput( pcListPic, curLayerId );
360      }
361      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
362      {
363        xFlushOutput( pcListPic, curLayerId );       
364      }
365      // write reconstruction to file
366      if(bNewPicture)
367      {
368        xWriteOutput( pcListPic, curLayerId, nalu.m_temporalId );
369      }
370#endif
371    }
372  }
373#if ALIGNED_BUMPING
374   flushAllPictures( true );   
375#else
376  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
377  {
378    xFlushOutput( m_acTDecTop[layer].getListPic(), layer );
379  }
380#endif
381  // delete buffers
382#if AVC_BASE
383  UInt layerIdmin = m_acTDecTop[0].getBLReconFile()->is_open() ? 1 : 0;
384
385  if( streamYUV.is_open() )
386  {
387    streamYUV.close();
388  }
389  pcBLPic.destroy();
390
391  for(UInt layer = layerIdmin; layer <= m_tgtLayerId; layer++)
392#else
393  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
394#endif
395  {
396    m_acTDecTop[layer].deletePicBuffer();
397  }
398
399  // destroy internal classes
400  xDestroyDecLib();
401}
402#else
403Void TAppDecTop::decode()
404{
405  Int                 poc;
406  TComList<TComPic*>* pcListPic = NULL;
407
408  ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
409  if (!bitstreamFile)
410  {
411    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
412    exit(EXIT_FAILURE);
413  }
414
415  InputByteStream bytestream(bitstreamFile);
416
417  if (!m_outputDecodedSEIMessagesFilename.empty() && m_outputDecodedSEIMessagesFilename!="-")
418  {
419    m_seiMessageFileStream.open(m_outputDecodedSEIMessagesFilename.c_str(), std::ios::out);
420    if (!m_seiMessageFileStream.is_open() || !m_seiMessageFileStream.good())
421    {
422      fprintf(stderr, "\nUnable to open file `%s' for writing decoded SEI messages\n", m_outputDecodedSEIMessagesFilename.c_str());
423      exit(EXIT_FAILURE);
424    }
425  }
426
427  // create & initialize internal classes
428  xCreateDecLib();
429  xInitDecLib  ();
430  m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
431
432  // main decoder loop
433  Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
434  Bool loopFiltered = false;
435
436  while (!!bitstreamFile)
437  {
438    /* location serves to work around a design fault in the decoder, whereby
439     * the process of reading a new slice that is the first slice of a new frame
440     * requires the TDecTop::decode() method to be called again with the same
441     * nal unit. */
442#if RExt__DECODER_DEBUG_BIT_STATISTICS
443    TComCodingStatistics::TComCodingStatisticsData backupStats(TComCodingStatistics::GetStatistics());
444    streampos location = bitstreamFile.tellg() - streampos(bytestream.GetNumBufferedBytes());
445#else
446    streampos location = bitstreamFile.tellg();
447#endif
448    AnnexBStats stats = AnnexBStats();
449
450    vector<uint8_t> nalUnit;
451    InputNALUnit nalu;
452    byteStreamNALUnit(bytestream, nalUnit, stats);
453
454    // call actual decoding function
455    Bool bNewPicture = false;
456    if (nalUnit.empty())
457    {
458      /* this can happen if the following occur:
459       *  - empty input file
460       *  - two back-to-back start_code_prefixes
461       *  - start_code_prefix immediately followed by EOF
462       */
463      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
464    }
465    else
466    {
467      read(nalu, nalUnit);
468      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
469      {
470        bNewPicture = false;
471      }
472      else
473      {
474        bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
475        if (bNewPicture)
476        {
477          bitstreamFile.clear();
478          /* location points to the current nalunit payload[1] due to the
479           * need for the annexB parser to read three extra bytes.
480           * [1] except for the first NAL unit in the file
481           *     (but bNewPicture doesn't happen then) */
482#if RExt__DECODER_DEBUG_BIT_STATISTICS
483          bitstreamFile.seekg(location);
484          bytestream.reset();
485          TComCodingStatistics::SetStatistics(backupStats);
486#else
487          bitstreamFile.seekg(location-streamoff(3));
488          bytestream.reset();
489#endif
490        }
491      }
492    }
493
494    if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) &&
495        !m_cTDecTop.getFirstSliceInSequence () )
496    {
497      if (!loopFiltered || bitstreamFile)
498      {
499        m_cTDecTop.executeLoopFilters(poc, pcListPic);
500      }
501      loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
502      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
503      {
504        m_cTDecTop.setFirstSliceInSequence(true);
505      }
506    }
507    else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) &&
508              m_cTDecTop.getFirstSliceInSequence () ) 
509    {
510      m_cTDecTop.setFirstSliceInPicture (true);
511    }
512
513    if( pcListPic )
514    {
515      if ( m_pchReconFile && !openedReconFile )
516      {
517        for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
518        {
519          if (m_outputBitDepth[channelType] == 0) m_outputBitDepth[channelType] = g_bitDepth[channelType];
520        }
521
522        m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepth, m_outputBitDepth, g_bitDepth ); // write mode
523        openedReconFile = true;
524      }
525      // write reconstruction to file
526      if( bNewPicture )
527      {
528        xWriteOutput( pcListPic, nalu.m_temporalId );
529      }
530      if ( (bNewPicture || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) && m_cTDecTop.getNoOutputPriorPicsFlag() )
531      {
532        m_cTDecTop.checkNoOutputPriorPics( pcListPic );
533        m_cTDecTop.setNoOutputPriorPicsFlag (false);
534      }
535      if ( bNewPicture &&
536           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
537            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
538            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
539            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
540            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
541      {
542        xFlushOutput( pcListPic );
543      }
544      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
545      {
546        xWriteOutput( pcListPic, nalu.m_temporalId );
547        m_cTDecTop.setFirstSliceInPicture (false);
548      }
549      // write reconstruction to file -- for additional bumping as defined in C.5.2.3
550      if(!bNewPicture && nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL_N && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL31)
551      {
552        xWriteOutput( pcListPic, nalu.m_temporalId );
553      }
554    }
555  }
556
557  xFlushOutput( pcListPic );
558  // delete buffers
559  m_cTDecTop.deletePicBuffer();
560
561  // destroy internal classes
562  xDestroyDecLib();
563}
564#endif
565
566// ====================================================================================================================
567// Protected member functions
568// ====================================================================================================================
569
570Void TAppDecTop::xCreateDecLib()
571{
572#if SVC_EXTENSION
573  // initialize global variables
574  initROM();
575
576  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
577  {
578    // set layer ID
579    m_acTDecTop[layer].setLayerId                      ( layer );
580
581    // create decoder class
582    m_acTDecTop[layer].create();
583
584    m_acTDecTop[layer].setLayerDec(m_apcTDecTop);
585  }
586#else
587  // create decoder class
588  m_cTDecTop.create();
589#endif
590}
591
592Void TAppDecTop::xDestroyDecLib()
593{
594#if SVC_EXTENSION
595  // destroy ROM
596  destroyROM();
597
598  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
599  {
600    if ( m_pchReconFile[layer] )
601    {
602      m_acTVideoIOYuvReconFile[layer].close();
603    }
604
605    // destroy decoder class
606    m_acTDecTop[layer].destroy();
607  }
608#else
609  if ( m_pchReconFile )
610  {
611    m_cTVideoIOYuvReconFile. close();
612  }
613
614  // destroy decoder class
615  m_cTDecTop.destroy();
616#endif
617}
618
619Void TAppDecTop::xInitDecLib()
620{
621  // initialize decoder class
622#if SVC_EXTENSION
623  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
624  {
625    m_acTDecTop[layer].init();
626    m_acTDecTop[layer].setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
627#if Q0074_COLOUR_REMAPPING_SEI
628    m_acTDecTop[layer].setColourRemappingInfoSEIEnabled(m_colourRemapSEIEnabled);
629#endif
630    m_acTDecTop[layer].setNumLayer( m_tgtLayerId + 1 );
631#if OUTPUT_LAYER_SET_INDEX
632    m_acTDecTop[layer].setCommonDecoderParams( this->getCommonDecoderParams() );
633#endif
634  }
635#else
636  m_cTDecTop.init();
637  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
638#if O0043_BEST_EFFORT_DECODING
639  m_cTDecTop.setForceDecodeBitDepth(m_forceDecodeBitDepth);
640#endif
641  if (!m_outputDecodedSEIMessagesFilename.empty())
642  {
643    std::ostream &os=m_seiMessageFileStream.is_open() ? m_seiMessageFileStream : std::cout;
644    m_cTDecTop.setDecodedSEIMessageOutputStream(&os);
645  }
646#if Q0074_COLOUR_REMAPPING_SEI
647  m_cTDecTop.setColourRemappingInfoSEIEnabled(m_colourRemapSEIEnabled);
648#endif
649#endif
650}
651
652/** \param pcListPic list of pictures to be written to file
653    \todo            DYN_REF_FREE should be revised
654 */
655#if SVC_EXTENSION
656Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt layerId, UInt tId )
657#else
658Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
659#endif
660{
661  if (pcListPic->empty())
662  {
663    return;
664  }
665
666  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
667  Int numPicsNotYetDisplayed = 0;
668  Int dpbFullness = 0;
669#if SVC_EXTENSION
670TComSPS* activeSPS = m_acTDecTop[layerId].getActiveSPS();
671#else
672  TComSPS* activeSPS = m_cTDecTop.getActiveSPS();
673#endif
674  UInt numReorderPicsHighestTid;
675  UInt maxDecPicBufferingHighestTid;
676  UInt maxNrSublayers = activeSPS->getMaxTLayers();
677
678  if(m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers)
679  {
680    numReorderPicsHighestTid = activeSPS->getNumReorderPics(maxNrSublayers-1);
681    maxDecPicBufferingHighestTid =  activeSPS->getMaxDecPicBuffering(maxNrSublayers-1); 
682  }
683  else
684  {
685    numReorderPicsHighestTid = activeSPS->getNumReorderPics(m_iMaxTemporalLayer);
686    maxDecPicBufferingHighestTid = activeSPS->getMaxDecPicBuffering(m_iMaxTemporalLayer); 
687  }
688
689  while (iterPic != pcListPic->end())
690  {
691    TComPic* pcPic = *(iterPic);
692#if SVC_EXTENSION
693    if(pcPic->getOutputMark() && pcPic->getPOC() > m_aiPOCLastDisplay[layerId])
694#else
695    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
696#endif
697    {
698       numPicsNotYetDisplayed++;
699      dpbFullness++;
700    }
701    else if(pcPic->getSlice( 0 )->isReferenced())
702    {
703      dpbFullness++;
704    }
705    iterPic++;
706  }
707
708  iterPic = pcListPic->begin();
709
710  if (numPicsNotYetDisplayed>2)
711  {
712    iterPic++;
713  }
714
715  TComPic* pcPic = *(iterPic);
716  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
717  {
718    TComList<TComPic*>::iterator endPic   = pcListPic->end();
719    endPic--;
720    iterPic   = pcListPic->begin();
721    while (iterPic != endPic)
722    {
723      TComPic* pcPicTop = *(iterPic);
724      iterPic++;
725      TComPic* pcPicBottom = *(iterPic);
726
727#if SVC_EXTENSION
728      if( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
729        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
730        (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&       
731        (pcPicTop->getPOC() == m_aiPOCLastDisplay[layerId]+1 || m_aiPOCLastDisplay[layerId]<0) )
732#else
733      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
734          (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
735          (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&
736          (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay < 0))
737#endif
738      {
739        // write to file
740        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
741#if SVC_EXTENSION
742        if ( m_pchReconFile[layerId] )
743        {
744          const Window &conf = pcPicTop->getConformanceWindow();
745          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
746          const Bool isTff = pcPicTop->isTopField();
747
748          Bool display = true;
749          if( m_decodedNoDisplaySEIEnabled )
750          {
751            SEIMessages noDisplay = getSeisByType(pcPic->getSEIs(), SEI::NO_DISPLAY );
752            const SEINoDisplay *nd = ( noDisplay.size() > 0 ) ? (SEINoDisplay*) *(noDisplay.begin()) : NULL;
753            if( (nd != NULL) && nd->m_noDisplay )
754            {
755              display = false;
756            }
757          }
758
759          if (display)
760          {           
761#if REPN_FORMAT_IN_VPS
762            UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
763            Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
764
765            m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
766              m_outputColourSpaceConvert,
767              conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
768              conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
769              conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
770              conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
771#else
772            m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
773              m_outputColourSpaceConvert,
774              conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
775              conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
776              conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
777              conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
778#endif
779          }
780        }
781
782        // update POC of display order
783        m_aiPOCLastDisplay[layerId] = pcPicBottom->getPOC();
784#else
785        if ( m_pchReconFile )
786        {
787          const Window &conf = pcPicTop->getConformanceWindow();
788          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
789          const Bool isTff = pcPicTop->isTopField();
790
791          Bool display = true;
792          if( m_decodedNoDisplaySEIEnabled )
793          {
794            SEIMessages noDisplay = getSeisByType(pcPic->getSEIs(), SEI::NO_DISPLAY );
795            const SEINoDisplay *nd = ( noDisplay.size() > 0 ) ? (SEINoDisplay*) *(noDisplay.begin()) : NULL;
796            if( (nd != NULL) && nd->m_noDisplay )
797            {
798              display = false;
799            }
800          }
801
802          if (display)
803          {
804            m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
805                                           m_outputColourSpaceConvert,
806                                           conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
807                                           conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
808                                           conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
809                                           conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
810          }
811        }
812
813        // update POC of display order
814        m_iPOCLastDisplay = pcPicBottom->getPOC();
815#endif
816
817        // erase non-referenced picture in the reference picture list after display
818        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
819        {
820#if !DYN_REF_FREE
821          pcPicTop->setReconMark(false);
822
823          // mark it should be extended later
824          pcPicTop->getPicYuvRec()->setBorderExtension( false );
825
826#else
827          pcPicTop->destroy();
828          pcListPic->erase( iterPic );
829          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
830          continue;
831#endif
832        }
833        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
834        {
835#if !DYN_REF_FREE
836          pcPicBottom->setReconMark(false);
837
838          // mark it should be extended later
839          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
840
841#else
842          pcPicBottom->destroy();
843          pcListPic->erase( iterPic );
844          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
845          continue;
846#endif
847        }
848        pcPicTop->setOutputMark(false);
849        pcPicBottom->setOutputMark(false);
850      }
851    }
852  }
853  else if (!pcPic->isField()) //Frame Decoding
854  {
855    iterPic = pcListPic->begin();
856
857    while (iterPic != pcListPic->end())
858    {
859      pcPic = *(iterPic);
860
861#if SVC_EXTENSION
862      if( pcPic->getOutputMark() && pcPic->getPOC() > m_aiPOCLastDisplay[layerId] &&
863        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) )
864#else
865      if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay &&
866        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
867#endif
868      {
869        // write to file
870         numPicsNotYetDisplayed--;
871        if(pcPic->getSlice(0)->isReferenced() == false)
872        {
873          dpbFullness--;
874        }
875#if SVC_EXTENSION
876        if( m_pchReconFile[layerId] )
877        {
878          const Window &conf = pcPic->getConformanceWindow();
879          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();         
880#if REPN_FORMAT_IN_VPS
881          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
882          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
883
884          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(), m_outputColourSpaceConvert,
885            conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
886            conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
887            conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
888            conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
889#else
890          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(), m_outputColourSpaceConvert,
891            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
892            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
893            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
894            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
895#endif
896        }
897
898        // update POC of display order
899        m_aiPOCLastDisplay[layerId] = pcPic->getPOC();
900#else
901        if ( m_pchReconFile )
902        {
903          const Window &conf    = pcPic->getConformanceWindow();
904          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
905
906          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
907                                         m_outputColourSpaceConvert,
908                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
909                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
910                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
911                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
912        }
913
914        // update POC of display order
915        m_iPOCLastDisplay = pcPic->getPOC();
916#endif
917
918        // erase non-referenced picture in the reference picture list after display
919        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
920        {
921#if !DYN_REF_FREE
922          pcPic->setReconMark(false);
923
924          // mark it should be extended later
925          pcPic->getPicYuvRec()->setBorderExtension( false );
926
927#else
928          pcPic->destroy();
929          pcListPic->erase( iterPic );
930          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
931          continue;
932#endif
933        }
934        pcPic->setOutputMark(false);
935      }
936
937      iterPic++;
938    }
939  }
940}
941
942/** \param pcListPic list of pictures to be written to file
943    \todo            DYN_REF_FREE should be revised
944 */
945#if SVC_EXTENSION
946Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, UInt layerId )
947#else
948Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
949#endif
950{
951  if(!pcListPic || pcListPic->empty())
952  {
953    return;
954  }
955  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
956
957  iterPic   = pcListPic->begin();
958  TComPic* pcPic = *(iterPic);
959
960  if (pcPic->isField()) //Field Decoding
961  {
962    TComList<TComPic*>::iterator endPic   = pcListPic->end();
963    endPic--;
964    TComPic *pcPicTop, *pcPicBottom = NULL;
965    while (iterPic != endPic)
966    {
967      pcPicTop = *(iterPic);
968      iterPic++;
969      pcPicBottom = *(iterPic);
970
971      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
972      {
973        // write to file
974#if SVC_EXTENSION
975        if ( m_pchReconFile[layerId] )
976        {
977          const Window &conf = pcPicTop->getConformanceWindow();
978          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
979          const Bool isTff = pcPicTop->isTopField();         
980#if REPN_FORMAT_IN_VPS
981          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
982          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
983
984          m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(), m_outputColourSpaceConvert,
985            conf.getWindowLeftOffset()  *xScal + defDisp.getWindowLeftOffset(),
986            conf.getWindowRightOffset() *xScal + defDisp.getWindowRightOffset(),
987            conf.getWindowTopOffset()   *yScal + defDisp.getWindowTopOffset(),
988            conf.getWindowBottomOffset()*yScal + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
989#else
990          m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(), m_outputColourSpaceConvert,
991            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
992            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
993            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
994            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
995#endif
996        }
997
998        // update POC of display order
999        m_aiPOCLastDisplay[layerId] = pcPicBottom->getPOC();
1000#else
1001        if ( m_pchReconFile )
1002        {
1003          const Window &conf = pcPicTop->getConformanceWindow();
1004          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
1005          const Bool isTff = pcPicTop->isTopField();
1006          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
1007                                         m_outputColourSpaceConvert,
1008                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
1009                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
1010                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
1011                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
1012        }
1013
1014        // update POC of display order
1015        m_iPOCLastDisplay = pcPicBottom->getPOC();
1016#endif
1017
1018        // erase non-referenced picture in the reference picture list after display
1019        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
1020        {
1021#if !DYN_REF_FREE
1022          pcPicTop->setReconMark(false);
1023
1024          // mark it should be extended later
1025          pcPicTop->getPicYuvRec()->setBorderExtension( false );
1026
1027#else
1028          pcPicTop->destroy();
1029          pcListPic->erase( iterPic );
1030          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
1031          continue;
1032#endif
1033        }
1034        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
1035        {
1036#if !DYN_REF_FREE
1037          pcPicBottom->setReconMark(false);
1038
1039          // mark it should be extended later
1040          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
1041
1042#else
1043          pcPicBottom->destroy();
1044          pcListPic->erase( iterPic );
1045          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
1046          continue;
1047#endif
1048        }
1049        pcPicTop->setOutputMark(false);
1050        pcPicBottom->setOutputMark(false);
1051
1052#if !DYN_REF_FREE
1053        if(pcPicTop)
1054        {
1055          pcPicTop->destroy();
1056          delete pcPicTop;
1057          pcPicTop = NULL;
1058        }
1059#endif
1060      }
1061    }
1062    if(pcPicBottom)
1063    {
1064      pcPicBottom->destroy();
1065      delete pcPicBottom;
1066      pcPicBottom = NULL;
1067    }
1068  }
1069  else //Frame decoding
1070  {
1071    while (iterPic != pcListPic->end())
1072    {
1073      pcPic = *(iterPic);
1074
1075      if ( pcPic->getOutputMark() )
1076      {
1077        // write to file
1078#if SVC_EXTENSION
1079        if ( m_pchReconFile[layerId] )
1080        {
1081          const Window &conf = pcPic->getConformanceWindow();
1082          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();         
1083#if REPN_FORMAT_IN_VPS
1084          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
1085          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1086
1087          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(), m_outputColourSpaceConvert,
1088            conf.getWindowLeftOffset()  *xScal + defDisp.getWindowLeftOffset(),
1089            conf.getWindowRightOffset() *xScal + defDisp.getWindowRightOffset(),
1090            conf.getWindowTopOffset()   *yScal + defDisp.getWindowTopOffset(),
1091            conf.getWindowBottomOffset()*yScal + defDisp.getWindowBottomOffset() );
1092#else
1093          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(), m_outputColourSpaceConvert,
1094            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
1095            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
1096            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
1097            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
1098#endif
1099        }
1100
1101        // update POC of display order
1102        m_aiPOCLastDisplay[layerId] = pcPic->getPOC();
1103#else
1104        if ( m_pchReconFile )
1105        {
1106          const Window &conf    = pcPic->getConformanceWindow();
1107          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
1108
1109          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
1110                                         m_outputColourSpaceConvert,
1111                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
1112                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
1113                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
1114                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
1115        }
1116
1117        // update POC of display order
1118        m_iPOCLastDisplay = pcPic->getPOC();
1119#endif
1120
1121        // erase non-referenced picture in the reference picture list after display
1122        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
1123        {
1124#if !DYN_REF_FREE
1125          pcPic->setReconMark(false);
1126
1127          // mark it should be extended later
1128          pcPic->getPicYuvRec()->setBorderExtension( false );
1129
1130#else
1131          pcPic->destroy();
1132          pcListPic->erase( iterPic );
1133          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
1134          continue;
1135#endif
1136        }
1137        pcPic->setOutputMark(false);
1138      }
1139#if !SVC_EXTENSION
1140#if !DYN_REF_FREE
1141      if(pcPic)
1142      {
1143        pcPic->destroy();
1144        delete pcPic;
1145        pcPic = NULL;
1146      }
1147#endif
1148#endif
1149      iterPic++;
1150    }
1151  }
1152#if SVC_EXTENSION
1153  m_aiPOCLastDisplay[layerId] = -MAX_INT;
1154#else
1155  pcListPic->clear();
1156  m_iPOCLastDisplay = -MAX_INT;
1157#endif
1158}
1159
1160/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
1161 */
1162Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
1163{
1164  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
1165  {
1166    return true;
1167  }
1168  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
1169  {
1170    if ( nalu->m_reservedZero6Bits == (*it) )
1171    {
1172      return true;
1173    }
1174  }
1175  return false;
1176}
1177#if ALIGNED_BUMPING
1178// Function outputs a picture, and marks it as not needed for output.
1179Void TAppDecTop::xOutputAndMarkPic( TComPic *pic, const Char *reconFile, const Int layerIdx, Int &pocLastDisplay, DpbStatus &dpbStatus )
1180{
1181  if ( reconFile )
1182  {
1183    const Window &conf = pic->getConformanceWindow();
1184    const Window &defDisp = m_respectDefDispWindow ? pic->getDefDisplayWindow() : Window();
1185    Int xScal =  1, yScal = 1;
1186#if REPN_FORMAT_IN_VPS
1187    UInt chromaFormatIdc = pic->getSlice(0)->getChromaFormatIdc();
1188    xScal = TComSPS::getWinUnitX( chromaFormatIdc );
1189    yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1190#endif
1191    TComPicYuv* pPicCYuvRec = pic->getPicYuvRec();
1192    m_acTVideoIOYuvReconFile[layerIdx].write( pPicCYuvRec, m_outputColourSpaceConvert,
1193      conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
1194      conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
1195      conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
1196      conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
1197  }
1198  // update POC of display order
1199  pocLastDisplay = pic->getPOC();
1200
1201  // Mark as not needed for output
1202  pic->setOutputMark(false);
1203
1204  // "erase" non-referenced picture in the reference picture list after display
1205  if ( !pic->getSlice(0)->isReferenced() && pic->getReconMark() == true )
1206  {
1207    pic->setReconMark(false);
1208
1209    // mark it should be extended later
1210    pic->getPicYuvRec()->setBorderExtension( false );
1211
1212#if RESOLUTION_BASED_DPB
1213    dpbStatus.m_numPicsInLayer[layerIdx]--;
1214#endif
1215    dpbStatus.m_numPicsInSubDpb[layerIdx]--;
1216  }
1217}
1218
1219Void TAppDecTop::flushAllPictures(Int layerId, Bool outputPictures)
1220{
1221  // First "empty" all pictures that are not used for reference and not needed for output
1222  emptyUnusedPicturesNotNeededForOutput();
1223
1224  if( outputPictures )  // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1225  {
1226    std::vector<Int>  listOfPocs;
1227    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1228    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1229    DpbStatus dpbStatus;
1230
1231    // Find the status of the DPB
1232    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1233
1234    if( listOfPocs.size() )
1235    {
1236      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1237      {
1238        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1239      }
1240    }
1241  }
1242
1243  // Now remove all pictures from the layer DPB?
1244  markAllPicturesAsErased(layerId);
1245}
1246Void TAppDecTop::flushAllPictures(Bool outputPictures)
1247{
1248  // First "empty" all pictures that are not used for reference and not needed for output
1249  emptyUnusedPicturesNotNeededForOutput();
1250
1251  if( outputPictures )  // All pictures in the DPB are to be output
1252  {
1253    std::vector<Int>  listOfPocs;
1254    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1255    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1256    DpbStatus dpbStatus;
1257
1258    // Find the status of the DPB
1259#if POC_RESET_IDC_DECODER
1260    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, false);
1261#else
1262    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1263#endif
1264
1265    while( dpbStatus.m_numAUsNotDisplayed )
1266    {
1267      bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1268    }
1269  }
1270
1271  // Now remove all pictures from the DPB?
1272  markAllPicturesAsErased();
1273}
1274
1275Void TAppDecTop::markAllPicturesAsErased()
1276{
1277  for(Int i = 0; i < MAX_LAYERS; i++)
1278  {
1279    markAllPicturesAsErased(i);
1280  }
1281}
1282
1283Void TAppDecTop::markAllPicturesAsErased(Int layerIdx)
1284{
1285  TComList<TComPic*>::iterator  iterPic = m_acTDecTop[layerIdx].getListPic()->begin();
1286  Int iSize = Int( m_acTDecTop[layerIdx].getListPic()->size() );
1287 
1288  for (Int i = 0; i < iSize; i++ )
1289  {
1290    TComPic* pcPic = *(iterPic++);
1291
1292    if( pcPic )
1293    {
1294      pcPic->destroy();
1295
1296      // pcPic is statically created for the external (AVC) base layer, no need to delete it
1297#if VPS_AVC_BL_FLAG_REMOVAL
1298      if( !m_acTDecTop[layerIdx].getParameterSetManager()->getActiveVPS()->getNonHEVCBaseLayerFlag() || layerIdx )
1299#else
1300      if( !m_acTDecTop[layerIdx].getParameterSetManager()->getActiveVPS()->getAvcBaseLayerFlag() || layerIdx )
1301#endif
1302      {
1303        delete pcPic;
1304        pcPic = NULL;
1305      }
1306    }
1307  }
1308
1309  m_acTDecTop[layerIdx].getListPic()->clear();
1310}
1311
1312Void TAppDecTop::checkOutputBeforeDecoding(Int layerIdx)
1313{
1314   
1315  std::vector<Int>  listOfPocs;
1316  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1317  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1318  DpbStatus dpbStatus;
1319
1320  // First "empty" all pictures that are not used for reference and not needed for output
1321  emptyUnusedPicturesNotNeededForOutput();
1322
1323  // Find the status of the DPB
1324  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1325
1326  // If not picture to be output, return
1327  if( listOfPocs.size() == 0 )
1328  {
1329    return;
1330  }
1331
1332  // Find DPB-information from the VPS
1333  DpbStatus maxDpbLimit;
1334#if RESOLUTION_BASED_DPB
1335  Int targetLsIdx, subDpbIdx;
1336  TComVPS *vps = findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1337
1338  if( getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 )
1339  {
1340    targetLsIdx = 0;
1341    subDpbIdx   = 0; 
1342  }
1343  else
1344  {
1345    targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1346    subDpbIdx   = vps->getSubDpbAssigned( targetLsIdx, layerIdx );
1347  }
1348#else
1349  Int subDpbIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 ? 0 : layerIdx;
1350  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1351#endif
1352  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1353  while( ifInvokeBumpingBeforeDecoding(dpbStatus, maxDpbLimit, layerIdx, subDpbIdx) )
1354  {
1355    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1356  } 
1357}
1358
1359Void TAppDecTop::checkOutputAfterDecoding()
1360{   
1361  std::vector<Int>  listOfPocs;
1362  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1363  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1364  DpbStatus dpbStatus;
1365
1366  // First "empty" all pictures that are not used for reference and not needed for output
1367  emptyUnusedPicturesNotNeededForOutput();
1368
1369  // Find the status of the DPB
1370  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1371
1372  // If not picture to be output, return
1373  if( listOfPocs.size() == 0 )
1374  {
1375    return;
1376  }
1377
1378  // Find DPB-information from the VPS
1379  DpbStatus maxDpbLimit;
1380  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1381
1382  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1383  while( ifInvokeBumpingAfterDecoding(dpbStatus, maxDpbLimit) )
1384  {
1385    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1386  } 
1387}
1388
1389Void TAppDecTop::bumpingProcess(std::vector<Int> &listOfPocs, std::vector<Int> *listOfPocsInEachLayer, std::vector<Int> *listOfPocsPositionInEachLayer, DpbStatus &dpbStatus)
1390{
1391  // Choose the smallest POC value
1392  Int pocValue = *(listOfPocs.begin());
1393  std::vector<int>::iterator it;
1394  TComList<TComPic*>::iterator iterPic;
1395  for( Int layerIdx = 0; layerIdx < dpbStatus.m_numLayers; layerIdx++)
1396  {
1397    // Check if picture with pocValue is present.
1398    it = find( listOfPocsInEachLayer[layerIdx].begin(), listOfPocsInEachLayer[layerIdx].end(), pocValue );
1399    if( it != listOfPocsInEachLayer[layerIdx].end() )  // picture found.
1400    {
1401      Int picPosition = std::distance( listOfPocsInEachLayer[layerIdx].begin(), it );
1402      Int j;
1403      for(j = 0, iterPic = m_acTDecTop[layerIdx].getListPic()->begin(); j < listOfPocsPositionInEachLayer[layerIdx][picPosition]; j++) // Picture to be output
1404      {
1405        iterPic++;
1406      }
1407      TComPic *pic = *iterPic;
1408
1409      xOutputAndMarkPic( pic, m_pchReconFile[layerIdx], layerIdx, m_aiPOCLastDisplay[layerIdx], dpbStatus );
1410
1411      listOfPocsInEachLayer[layerIdx].erase( it );
1412      listOfPocsPositionInEachLayer[layerIdx].erase( listOfPocsPositionInEachLayer[layerIdx].begin() + picPosition );
1413    }
1414  }
1415  // Update sub-DPB status
1416  for( Int subDpbIdx = 0; subDpbIdx < dpbStatus.m_numSubDpbs; subDpbIdx++)
1417  {
1418    dpbStatus.m_numPicsInSubDpb[subDpbIdx]--;
1419  }
1420  dpbStatus.m_numAUsNotDisplayed--;   
1421
1422  // Remove the picture from the listOfPocs
1423  listOfPocs.erase( listOfPocs.begin() );
1424}
1425
1426TComVPS *TAppDecTop::findDpbParametersFromVps(std::vector<Int> const &listOfPocs, std::vector<Int> const *listOfPocsInEachLayer, std::vector<Int> const *listOfPocsPositionInEachLayer, DpbStatus &maxDpbLimit)
1427{
1428  Int targetOutputLsIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx();
1429  TComVPS *vps = NULL;
1430
1431  if( targetOutputLsIdx == 0 )   // Only base layer is output
1432  {
1433    TComSPS *sps = NULL;
1434    assert( listOfPocsInEachLayer[0].size() != 0 );
1435    TComList<TComPic*>::iterator iterPic;
1436    Int j;
1437    for(j = 0, iterPic = m_acTDecTop[0].getListPic()->begin(); j < listOfPocsPositionInEachLayer[0][0]; j++) // Picture to be output
1438    {
1439      iterPic++;
1440    }
1441    TComPic *pic = *iterPic;
1442    sps = pic->getSlice(0)->getSPS();   assert( sps->getLayerId() == 0 );
1443    vps = pic->getSlice(0)->getVPS();
1444    Int highestTId = sps->getMaxTLayers() - 1;
1445
1446    maxDpbLimit.m_numAUsNotDisplayed = sps->getNumReorderPics( highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1447    maxDpbLimit.m_maxLatencyIncrease = sps->getMaxLatencyIncrease( highestTId ) > 0;
1448    if( maxDpbLimit.m_maxLatencyIncrease )
1449    {
1450      maxDpbLimit.m_maxLatencyPictures = sps->getMaxLatencyIncrease( highestTId ) + sps->getNumReorderPics( highestTId ) - 1;
1451    }
1452#if RESOLUTION_BASED_DPB
1453    maxDpbLimit.m_numPicsInLayer[0] = sps->getMaxDecPicBuffering( highestTId );
1454#endif
1455    maxDpbLimit.m_numPicsInSubDpb[0] = sps->getMaxDecPicBuffering( highestTId );
1456  }
1457  else
1458  {
1459    // -------------------------------------
1460    // Find the VPS used for the pictures
1461    // -------------------------------------
1462    for(Int i = 0; i < MAX_LAYERS; i++)
1463    {
1464      if( m_acTDecTop[i].getListPic()->empty() )
1465      {
1466        assert( listOfPocsInEachLayer[i].size() == 0 );
1467        continue;
1468      }
1469      std::vector<Int>::const_iterator it;
1470      it = find( listOfPocsInEachLayer[i].begin(), listOfPocsInEachLayer[i].end(), listOfPocs[0] );
1471      TComList<TComPic*>::iterator iterPic;
1472      if( it != listOfPocsInEachLayer[i].end() )
1473      {
1474        Int picPosition = std::distance( listOfPocsInEachLayer[i].begin(), it );
1475        Int j;
1476        for(j = 0, iterPic = m_acTDecTop[i].getListPic()->begin(); j < listOfPocsPositionInEachLayer[i][picPosition]; j++) // Picture to be output
1477        {
1478          iterPic++;
1479        }
1480        TComPic *pic = *iterPic;
1481        vps = pic->getSlice(0)->getVPS();
1482        break;
1483      }
1484    }
1485
1486    Int targetLsIdx       = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1487    Int highestTId = vps->getMaxTLayers() - 1;
1488
1489    maxDpbLimit.m_numAUsNotDisplayed = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1490    maxDpbLimit.m_maxLatencyIncrease  = vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) > 0;
1491    if( maxDpbLimit.m_maxLatencyIncrease )
1492    {
1493      maxDpbLimit.m_maxLatencyPictures = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ) + vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) - 1;
1494    }
1495    for(Int i = 0; i < vps->getNumLayersInIdList( targetLsIdx ); i++)
1496    {
1497#if RESOUTION_BASED_DPB
1498      maxDpbLimit.m_numPicsInLayer[i] = vps->getMaxVpsLayerDecPicBuffMinus1( targetOutputLsIdx, i, highestTId ) + 1;
1499      maxDpbLimit.m_numPicsInSubDpb[vps->getSubDpbAssigned( targetLsIdx, i )] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, vps->getSubDpbAssigned( targetLsIdx, i ), highestTId) + 1;
1500#else
1501      maxDpbLimit.m_numPicsInSubDpb[i] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, i, highestTId) + 1;
1502#endif
1503    }
1504    // -------------------------------------
1505  }
1506  return vps;
1507}
1508Void TAppDecTop::emptyUnusedPicturesNotNeededForOutput()
1509{
1510  for(Int layerIdx = 0; layerIdx < MAX_LAYERS; layerIdx++)
1511  {
1512    TComList <TComPic*> *pcListPic = m_acTDecTop[layerIdx].getListPic();
1513    TComList<TComPic*>::iterator iterPic = pcListPic->begin();
1514    while ( iterPic != pcListPic->end() )
1515    {
1516      TComPic *pic = *iterPic;
1517      if( !pic->getSlice(0)->isReferenced() && !pic->getOutputMark() )
1518      {
1519        // Emtpy the picture buffer
1520        pic->setReconMark( false );
1521      }
1522      iterPic++;
1523    }
1524  }
1525}
1526
1527Bool TAppDecTop::ifInvokeBumpingBeforeDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit, const Int layerIdx, const Int subDpbIdx )
1528{
1529  Bool retVal = false;
1530  // Number of reorder picutres
1531  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1532
1533  // Number of pictures in each sub-DPB
1534  retVal |= ( dpbStatus.m_numPicsInSubDpb[subDpbIdx] >= dpbLimit.m_numPicsInSubDpb[subDpbIdx] );
1535 
1536#if RESOLUTION_BASED_DPB
1537  // Number of pictures in each layer
1538  retVal |= ( dpbStatus.m_numPicsInLayer[layerIdx] >= dpbLimit.m_numPicsInLayer[layerIdx]);
1539#endif
1540
1541  return retVal;
1542}
1543
1544Bool TAppDecTop::ifInvokeBumpingAfterDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit )
1545{
1546  Bool retVal = false;
1547
1548  // Number of reorder picutres
1549  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1550
1551  return retVal;
1552}
1553
1554Void TAppDecTop::xFindDPBStatus( std::vector<Int> &listOfPocs
1555                            , std::vector<Int> *listOfPocsInEachLayer
1556                            , std::vector<Int> *listOfPocsPositionInEachLayer
1557                            , DpbStatus &dpbStatus
1558#if POC_RESET_IDC_DECODER
1559                            , Bool notOutputCurrAu
1560#endif
1561                            )
1562{
1563  TComVPS *vps = NULL;
1564  dpbStatus.init();
1565  for( Int i = 0; i < MAX_LAYERS; i++ )
1566  {
1567    if( m_acTDecTop[i].getListPic()->empty() )
1568    {
1569      continue;
1570    }
1571   
1572    // To check # AUs that have at least one picture not output,
1573    // For each layer, populate listOfPOcs if not already present
1574    TComList<TComPic*>::iterator iterPic = m_acTDecTop[i].getListPic()->begin();
1575    Int picPositionInList = 0;
1576    while (iterPic != m_acTDecTop[i].getListPic()->end())
1577    {
1578      TComPic* pic = *(iterPic);
1579      if( pic->getReconMark() )
1580      {
1581        if( vps == NULL )
1582        {
1583          vps = pic->getSlice(0)->getVPS();
1584        }
1585#if POC_RESET_IDC_DECODER
1586        if( !(pic->isCurrAu() && notOutputCurrAu ) )
1587        {
1588#endif
1589          std::vector<Int>::iterator it;
1590          if( pic->getOutputMark() ) // && pic->getPOC() > m_aiPOCLastDisplay[i])
1591          {
1592            it = find( listOfPocs.begin(), listOfPocs.end(), pic->getPOC() ); // Check if already included
1593            if( it == listOfPocs.end() )  // New POC value - i.e. new AU - add to the list
1594            {
1595              listOfPocs.push_back( pic->getPOC() );
1596            }
1597            listOfPocsInEachLayer         [i].push_back( pic->getPOC()    );    // POC to be output in each layer
1598            listOfPocsPositionInEachLayer [i].push_back( picPositionInList  );  // For ease of access
1599          }
1600          if( pic->getSlice(0)->isReferenced() || pic->getOutputMark() )
1601          {
1602#if RESOLUTION_BASED_DPB
1603            dpbStatus.m_numPicsInLayer[i]++;  // Count pictures that are "used for reference" or "needed for output"
1604#else
1605            dpbStatus.m_numPicsInSubDpb[i]++;  // Count pictures that are "used for reference" or "needed for output"
1606#endif
1607          }
1608#if POC_RESET_IDC_DECODER
1609        }
1610#endif
1611      }
1612      iterPic++;
1613      picPositionInList++;
1614    }
1615  }
1616
1617  assert( vps != NULL );    // No picture in any DPB?
1618  std::sort( listOfPocs.begin(), listOfPocs.end() );    // Sort in increasing order of POC
1619  Int targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1620  // Update status
1621  dpbStatus.m_numAUsNotDisplayed = listOfPocs.size();   // Number of AUs not displayed
1622  dpbStatus.m_numLayers = vps->getNumLayersInIdList( targetLsIdx );
1623  dpbStatus.m_numSubDpbs = vps->getNumSubDpbs( vps->getOutputLayerSetIdx(
1624                                                      this->getCommonDecoderParams()->getTargetOutputLayerSetIdx() ) );
1625
1626  for(Int i = 0; i < dpbStatus.m_numLayers; i++)
1627  {
1628    dpbStatus.m_numPicsNotDisplayedInLayer[i] = listOfPocsInEachLayer[i].size();
1629#if RESOLUTION_BASED_DPB
1630    dpbStatus.m_numPicsInSubDpb[vps->getSubDpbAssigned(targetLsIdx,i)] += dpbStatus.m_numPicsInLayer[i];
1631    dpbStatus.m_numPicsInSubDpb[i] += dpbStatus.m_numPicsInLayer[i];
1632#endif
1633  }
1634  assert( dpbStatus.m_numAUsNotDisplayed != -1 );
1635} 
1636
1637#if POC_RESET_IDC_DECODER
1638Void TAppDecTop::outputAllPictures(Int layerId, Bool notOutputCurrPic)
1639{
1640  { // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1641    std::vector<Int>  listOfPocs;
1642    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1643    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1644    DpbStatus dpbStatus;
1645
1646    // Find the status of the DPB
1647    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, notOutputCurrPic);
1648
1649    if( listOfPocs.size() )
1650    {
1651      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1652      {
1653        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1654      }
1655    }
1656  }
1657}
1658#endif
1659#endif
1660//! \}
Note: See TracBrowser for help on using the repository browser.