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

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

port the fix for ticket #38

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