source: SHVCSoftware/branches/SHM-dev/source/App/TAppDecoder/TAppDecTop.cpp @ 978

Last change on this file since 978 was 953, checked in by qualcomm, 11 years ago

Fixes for conformance testing and non-output layers.

  • Value of PicOutputFlag of non-output layers was not being computed correctly. Fixed under MACRO FIX_NON_OUTPUT_LAYER
  • Some fixes for conformance testing under macro FIX_CONF_MODE.

From: Adarsh K. Ramasubramonian <aramasub@…>

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