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

Last change on this file since 1598 was 1006, checked in by seregin, 10 years ago

port implementation of JCTVC-R0235 - Processing of bitstreams without an available base layer (rev 1005)

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