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

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

port fixes for conformance testing and non-output layers (rev 953)

  • Property svn:eol-style set to native
File size: 64.1 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  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
1215  {
1216    if ( nalu->m_reservedZero6Bits == (*it) )
1217    {
1218      return true;
1219    }
1220  }
1221  return false;
1222}
1223#if ALIGNED_BUMPING
1224// Function outputs a picture, and marks it as not needed for output.
1225Void TAppDecTop::xOutputAndMarkPic( TComPic *pic, const Char *reconFile, const Int layerIdx, Int &pocLastDisplay, DpbStatus &dpbStatus )
1226{
1227  if ( reconFile )
1228  {
1229    const Window &conf = pic->getConformanceWindow();
1230    const Window &defDisp = m_respectDefDispWindow ? pic->getDefDisplayWindow() : Window();
1231    Int xScal =  1, yScal = 1;
1232#if REPN_FORMAT_IN_VPS
1233    UInt chromaFormatIdc = pic->getSlice(0)->getChromaFormatIdc();
1234    xScal = TComSPS::getWinUnitX( chromaFormatIdc );
1235    yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1236#endif
1237    TComPicYuv* pPicCYuvRec = pic->getPicYuvRec();
1238    m_acTVideoIOYuvReconFile[layerIdx].write( pPicCYuvRec, m_outputColourSpaceConvert,
1239      conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
1240      conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
1241      conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
1242      conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
1243  }
1244  // update POC of display order
1245  pocLastDisplay = pic->getPOC();
1246
1247  // Mark as not needed for output
1248  pic->setOutputMark(false);
1249
1250  // "erase" non-referenced picture in the reference picture list after display
1251  if ( !pic->getSlice(0)->isReferenced() && pic->getReconMark() == true )
1252  {
1253    pic->setReconMark(false);
1254
1255    // mark it should be extended later
1256    pic->getPicYuvRec()->setBorderExtension( false );
1257
1258#if RESOLUTION_BASED_DPB
1259    dpbStatus.m_numPicsInLayer[layerIdx]--;
1260#endif
1261#if FIX_ALIGN_BUMPING
1262    dpbStatus.m_numPicsInSubDpb[dpbStatus.m_layerIdToSubDpbIdMap[layerIdx]]--;
1263#else
1264    dpbStatus.m_numPicsInSubDpb[layerIdx]--;
1265#endif
1266  }
1267}
1268
1269Void TAppDecTop::flushAllPictures(Int layerId, 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 in that layer are to be output; this means other pictures would also 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    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1288
1289    if( listOfPocs.size() )
1290    {
1291      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1292      {
1293        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1294      }
1295    }
1296  }
1297
1298  // Now remove all pictures from the layer DPB?
1299  markAllPicturesAsErased(layerId);
1300}
1301Void TAppDecTop::flushAllPictures(Bool outputPictures)
1302{
1303  // First "empty" all pictures that are not used for reference and not needed for output
1304  emptyUnusedPicturesNotNeededForOutput();
1305
1306  if( outputPictures )  // All pictures in the DPB are to be output
1307  {
1308    std::vector<Int>  listOfPocs;
1309#if FIX_ALIGN_BUMPING
1310    std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_ID_PLUS1];
1311    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_ID_PLUS1];
1312#else
1313    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1314    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1315#endif
1316    DpbStatus dpbStatus;
1317
1318    // Find the status of the DPB
1319#if POC_RESET_IDC_DECODER
1320    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, false);
1321#else
1322    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1323#endif
1324
1325    while( dpbStatus.m_numAUsNotDisplayed )
1326    {
1327      bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1328    }
1329  }
1330
1331  // Now remove all pictures from the DPB?
1332  markAllPicturesAsErased();
1333}
1334
1335Void TAppDecTop::markAllPicturesAsErased()
1336{
1337#if FIX_ALIGN_BUMPING
1338  for(Int i = 0; i < MAX_VPS_LAYER_ID_PLUS1; i++)
1339#else
1340  for(Int i = 0; i < MAX_LAYERS; i++)
1341#endif
1342  {
1343    markAllPicturesAsErased(i);
1344  }
1345}
1346
1347Void TAppDecTop::markAllPicturesAsErased(Int layerIdx)
1348{
1349  TComList<TComPic*>::iterator  iterPic = m_acTDecTop[layerIdx].getListPic()->begin();
1350  Int iSize = Int( m_acTDecTop[layerIdx].getListPic()->size() );
1351 
1352  for (Int i = 0; i < iSize; i++ )
1353  {
1354    TComPic* pcPic = *(iterPic++);
1355
1356    if( pcPic )
1357    {
1358      pcPic->destroy();
1359
1360      // pcPic is statically created for the external (AVC) base layer, no need to delete it
1361#if VPS_AVC_BL_FLAG_REMOVAL
1362      if( !m_acTDecTop[layerIdx].getParameterSetManager()->getActiveVPS()->getNonHEVCBaseLayerFlag() || layerIdx )
1363#else
1364      if( !m_acTDecTop[layerIdx].getParameterSetManager()->getActiveVPS()->getAvcBaseLayerFlag() || layerIdx )
1365#endif
1366      {
1367        delete pcPic;
1368        pcPic = NULL;
1369      }
1370    }
1371  }
1372
1373  m_acTDecTop[layerIdx].getListPic()->clear();
1374}
1375
1376Void TAppDecTop::checkOutputBeforeDecoding(Int layerIdx)
1377{
1378   
1379  std::vector<Int>  listOfPocs;
1380#if FIX_ALIGN_BUMPING
1381  std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_ID_PLUS1];
1382  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_ID_PLUS1];
1383#else
1384  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1385  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1386#endif
1387  DpbStatus dpbStatus;
1388
1389  // First "empty" all pictures that are not used for reference and not needed for output
1390  emptyUnusedPicturesNotNeededForOutput();
1391
1392  // Find the status of the DPB
1393  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1394
1395  // If not picture to be output, return
1396  if( listOfPocs.size() == 0 )
1397  {
1398    return;
1399  }
1400
1401  // Find DPB-information from the VPS
1402  DpbStatus maxDpbLimit;
1403#if RESOLUTION_BASED_DPB
1404  Int targetLsIdx, subDpbIdx;
1405  TComVPS *vps = findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1406
1407  if( getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 )
1408  {
1409    targetLsIdx = 0;
1410    subDpbIdx   = 0; 
1411  }
1412  else
1413  {
1414    targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1415    subDpbIdx   = vps->getSubDpbAssigned( targetLsIdx, layerIdx );
1416  }
1417#else
1418#if FIX_ALIGN_BUMPING
1419  Int subDpbIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 
1420                  ? dpbStatus.m_layerIdToSubDpbIdMap[0] 
1421                  : dpbStatus.m_layerIdToSubDpbIdMap[layerIdx];
1422#else
1423  Int subDpbIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 ? 0 : layerIdx;
1424#endif
1425  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1426#endif
1427  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1428  while( ifInvokeBumpingBeforeDecoding(dpbStatus, maxDpbLimit, layerIdx, subDpbIdx) )
1429  {
1430    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1431  } 
1432}
1433
1434Void TAppDecTop::checkOutputAfterDecoding()
1435{   
1436  std::vector<Int>  listOfPocs;
1437#if FIX_ALIGN_BUMPING
1438  std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_ID_PLUS1];
1439  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_ID_PLUS1];
1440#else
1441  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1442  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1443#endif
1444  DpbStatus dpbStatus;
1445
1446  // First "empty" all pictures that are not used for reference and not needed for output
1447  emptyUnusedPicturesNotNeededForOutput();
1448
1449  // Find the status of the DPB
1450  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1451
1452  // If not picture to be output, return
1453  if( listOfPocs.size() == 0 )
1454  {
1455    return;
1456  }
1457
1458  // Find DPB-information from the VPS
1459  DpbStatus maxDpbLimit;
1460  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1461
1462  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1463  while( ifInvokeBumpingAfterDecoding(dpbStatus, maxDpbLimit) )
1464  {
1465    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1466  } 
1467}
1468
1469Void TAppDecTop::bumpingProcess(std::vector<Int> &listOfPocs, std::vector<Int> *listOfPocsInEachLayer, std::vector<Int> *listOfPocsPositionInEachLayer, DpbStatus &dpbStatus)
1470{
1471  // Choose the smallest POC value
1472  Int pocValue = *(listOfPocs.begin());
1473  std::vector<int>::iterator it;
1474  TComList<TComPic*>::iterator iterPic;
1475#if FIX_ALIGN_BUMPING
1476  for( Int dpbLayerCtr = 0; dpbLayerCtr < dpbStatus.m_numLayers; dpbLayerCtr++)
1477  {
1478    Int layerIdx  = dpbStatus.m_targetDecLayerIdList[dpbLayerCtr];
1479#else
1480  for( Int layerIdx = 0; layerIdx < dpbStatus.m_numLayers; layerIdx++)
1481  {
1482#endif
1483    // Check if picture with pocValue is present.
1484    it = find( listOfPocsInEachLayer[layerIdx].begin(), listOfPocsInEachLayer[layerIdx].end(), pocValue );
1485    if( it != listOfPocsInEachLayer[layerIdx].end() )  // picture found.
1486    {
1487      Int picPosition = std::distance( listOfPocsInEachLayer[layerIdx].begin(), it );
1488      Int j;
1489      for(j = 0, iterPic = m_acTDecTop[layerIdx].getListPic()->begin(); j < listOfPocsPositionInEachLayer[layerIdx][picPosition]; j++) // Picture to be output
1490      {
1491        iterPic++;
1492      }
1493      TComPic *pic = *iterPic;
1494
1495      xOutputAndMarkPic( pic, m_pchReconFile[layerIdx], layerIdx, m_aiPOCLastDisplay[layerIdx], dpbStatus );
1496
1497#if CONFORMANCE_BITSTREAM_MODE
1498      FILE *fptr;
1499      if( m_confModeFlag )
1500      {
1501        if( m_metadataFileRefresh )
1502        {
1503          fptr = fopen( this->getMetadataFileName().c_str(), "w" );
1504          fprintf(fptr, " LayerId      POC    MD5\n");
1505          fprintf(fptr, "------------------------\n");
1506        }
1507        else
1508        {
1509          fptr = fopen( this->getMetadataFileName().c_str(), "a+" );
1510        }
1511        this->setMetadataFileRefresh(false);
1512
1513        TComDigest recon_digest;
1514        Int numChar = calcMD5(*pic->getPicYuvRec(), recon_digest);
1515        fprintf(fptr, "%8d%9d    MD5:%s\n", pic->getLayerId(), pic->getSlice(0)->getPOC(), digestToString(recon_digest, numChar).c_str());
1516        fclose(fptr);
1517      }
1518#endif
1519
1520      listOfPocsInEachLayer[layerIdx].erase( it );
1521      listOfPocsPositionInEachLayer[layerIdx].erase( listOfPocsPositionInEachLayer[layerIdx].begin() + picPosition );
1522#if FIX_ALIGN_BUMPING
1523      dpbStatus.m_numPicsInSubDpb[dpbStatus.m_layerIdToSubDpbIdMap[layerIdx]]--;
1524#endif
1525    }
1526  }
1527#if !FIX_ALIGN_BUMPING
1528  // Update sub-DPB status
1529  for( Int subDpbIdx = 0; subDpbIdx < dpbStatus.m_numSubDpbs; subDpbIdx++)
1530  {
1531    dpbStatus.m_numPicsInSubDpb[subDpbIdx]--;
1532  }
1533#endif
1534  dpbStatus.m_numAUsNotDisplayed--;
1535
1536#if CONFORMANCE_BITSTREAM_MODE
1537  if( m_confModeFlag )
1538  {
1539    for( Int dpbLayerCtr = 0; dpbLayerCtr < dpbStatus.m_numLayers; dpbLayerCtr++)
1540    {
1541      Int layerIdx  = dpbStatus.m_targetDecLayerIdList[dpbLayerCtr];
1542      // Output all picutres "decoded" in that layer that have POC less than the current picture
1543      std::vector<TComPic> *layerBuffer = (m_acTDecTop->getLayerDec(layerIdx))->getConfListPic();
1544      // Write all pictures to the file.
1545      if( this->getDecodedYuvLayerRefresh(layerIdx) )
1546      {
1547        if (!m_outputBitDepth[CHANNEL_TYPE_LUMA]) { m_outputBitDepth[CHANNEL_TYPE_LUMA] = g_bitDepth[CHANNEL_TYPE_LUMA]; }
1548        if (!m_outputBitDepth[CHANNEL_TYPE_CHROMA]) { m_outputBitDepth[CHANNEL_TYPE_CHROMA] = g_bitDepth[CHANNEL_TYPE_CHROMA]; }
1549
1550        char tempFileName[256];
1551        strcpy(tempFileName, this->getDecodedYuvLayerFileName( layerIdx ).c_str());
1552        m_confReconFile[layerIdx].open(tempFileName, true, m_outputBitDepth, m_outputBitDepth, g_bitDepth ); // write mode
1553        this->setDecodedYuvLayerRefresh( layerIdx, false );
1554      }
1555
1556      std::vector<TComPic>::iterator itPic;
1557      for(itPic = layerBuffer->begin(); itPic != layerBuffer->end(); itPic++)
1558      {
1559        TComPic checkPic = *itPic;
1560        const Window &conf = checkPic.getConformanceWindow();
1561        const Window &defDisp = m_respectDefDispWindow ? checkPic.getDefDisplayWindow() : Window();
1562        Int xScal = 1, yScal = 1;
1563  #if REPN_FORMAT_IN_VPS
1564        UInt chromaFormatIdc = checkPic.getSlice(0)->getChromaFormatIdc();
1565        xScal = TComSPS::getWinUnitX( chromaFormatIdc );
1566        yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1567  #endif
1568        if( checkPic.getPOC() <= pocValue )
1569        {
1570          TComPicYuv* pPicCYuvRec = checkPic.getPicYuvRec();
1571          m_confReconFile[layerIdx].write( pPicCYuvRec, m_outputColourSpaceConvert,
1572            conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
1573            conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
1574            conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
1575            conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
1576          layerBuffer->erase(itPic);
1577          itPic = layerBuffer->begin();  // Ensure doesn't go to infinite loop
1578          if(layerBuffer->size() == 0)
1579          {
1580            break;
1581          }
1582        }
1583      }
1584    }
1585  }
1586#endif
1587
1588  // Remove the picture from the listOfPocs
1589  listOfPocs.erase( listOfPocs.begin() );
1590}
1591
1592TComVPS *TAppDecTop::findDpbParametersFromVps(std::vector<Int> const &listOfPocs, std::vector<Int> const *listOfPocsInEachLayer, std::vector<Int> const *listOfPocsPositionInEachLayer, DpbStatus &maxDpbLimit)
1593{
1594  Int targetOutputLsIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx();
1595  TComVPS *vps = NULL;
1596
1597  if( targetOutputLsIdx == 0 )   // Only base layer is output
1598  {
1599    TComSPS *sps = NULL;
1600    assert( listOfPocsInEachLayer[0].size() != 0 );
1601    TComList<TComPic*>::iterator iterPic;
1602    Int j;
1603    for(j = 0, iterPic = m_acTDecTop[0].getListPic()->begin(); j < listOfPocsPositionInEachLayer[0][0]; j++) // Picture to be output
1604    {
1605      iterPic++;
1606    }
1607    TComPic *pic = *iterPic;
1608    sps = pic->getSlice(0)->getSPS();   assert( sps->getLayerId() == 0 );
1609    vps = pic->getSlice(0)->getVPS();
1610    Int highestTId = sps->getMaxTLayers() - 1;
1611
1612    maxDpbLimit.m_numAUsNotDisplayed = sps->getNumReorderPics( highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1613    maxDpbLimit.m_maxLatencyIncrease = sps->getMaxLatencyIncrease( highestTId ) > 0;
1614    if( maxDpbLimit.m_maxLatencyIncrease )
1615    {
1616      maxDpbLimit.m_maxLatencyPictures = sps->getMaxLatencyIncrease( highestTId ) + sps->getNumReorderPics( highestTId ) - 1;
1617    }
1618#if RESOLUTION_BASED_DPB
1619    maxDpbLimit.m_numPicsInLayer[0] = sps->getMaxDecPicBuffering( highestTId );
1620#endif
1621    maxDpbLimit.m_numPicsInSubDpb[0] = sps->getMaxDecPicBuffering( highestTId );
1622  }
1623  else
1624  {
1625    // -------------------------------------
1626    // Find the VPS used for the pictures
1627    // -------------------------------------
1628#if FIX_ALIGN_BUMPING
1629    for(Int i = 0; i < MAX_VPS_LAYER_ID_PLUS1; i++)
1630#else
1631    for(Int i = 0; i < MAX_LAYERS; i++)
1632#endif
1633    {
1634      if( m_acTDecTop[i].getListPic()->empty() )
1635      {
1636        assert( listOfPocsInEachLayer[i].size() == 0 );
1637        continue;
1638      }
1639      std::vector<Int>::const_iterator it;
1640      it = find( listOfPocsInEachLayer[i].begin(), listOfPocsInEachLayer[i].end(), listOfPocs[0] );
1641      TComList<TComPic*>::iterator iterPic;
1642      if( it != listOfPocsInEachLayer[i].end() )
1643      {
1644        Int picPosition = std::distance( listOfPocsInEachLayer[i].begin(), it );
1645        Int j;
1646        for(j = 0, iterPic = m_acTDecTop[i].getListPic()->begin(); j < listOfPocsPositionInEachLayer[i][picPosition]; j++) // Picture to be output
1647        {
1648          iterPic++;
1649        }
1650        TComPic *pic = *iterPic;
1651        vps = pic->getSlice(0)->getVPS();
1652        break;
1653      }
1654    }
1655
1656    Int targetLsIdx       = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1657    Int highestTId = vps->getMaxTLayers() - 1;
1658
1659    maxDpbLimit.m_numAUsNotDisplayed = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1660    maxDpbLimit.m_maxLatencyIncrease  = vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) > 0;
1661    if( maxDpbLimit.m_maxLatencyIncrease )
1662    {
1663      maxDpbLimit.m_maxLatencyPictures = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ) + vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) - 1;
1664    }
1665    for(Int i = 0; i < vps->getNumLayersInIdList( targetLsIdx ); i++)
1666    {
1667#if RESOUTION_BASED_DPB
1668      maxDpbLimit.m_numPicsInLayer[i] = vps->getMaxVpsLayerDecPicBuffMinus1( targetOutputLsIdx, i, highestTId ) + 1;
1669      maxDpbLimit.m_numPicsInSubDpb[vps->getSubDpbAssigned( targetLsIdx, i )] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, vps->getSubDpbAssigned( targetLsIdx, i ), highestTId) + 1;
1670#else
1671      maxDpbLimit.m_numPicsInSubDpb[i] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, i, highestTId) + 1;
1672#endif
1673    }
1674    // -------------------------------------
1675  }
1676  return vps;
1677}
1678Void TAppDecTop::emptyUnusedPicturesNotNeededForOutput()
1679{
1680#if FIX_ALIGN_BUMPING
1681  for(Int layerIdx = 0; layerIdx < MAX_VPS_LAYER_ID_PLUS1; layerIdx++)
1682#else
1683  for(Int layerIdx = 0; layerIdx < MAX_LAYERS; layerIdx++)
1684#endif
1685  {
1686    TComList <TComPic*> *pcListPic = m_acTDecTop[layerIdx].getListPic();
1687    TComList<TComPic*>::iterator iterPic = pcListPic->begin();
1688    while ( iterPic != pcListPic->end() )
1689    {
1690      TComPic *pic = *iterPic;
1691      if( !pic->getSlice(0)->isReferenced() && !pic->getOutputMark() )
1692      {
1693        // Emtpy the picture buffer
1694        pic->setReconMark( false );
1695      }
1696      iterPic++;
1697    }
1698  }
1699}
1700
1701Bool TAppDecTop::ifInvokeBumpingBeforeDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit, const Int layerIdx, const Int subDpbIdx )
1702{
1703  Bool retVal = false;
1704  // Number of reorder picutres
1705  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1706
1707  // Number of pictures in each sub-DPB
1708  retVal |= ( dpbStatus.m_numPicsInSubDpb[subDpbIdx] >= dpbLimit.m_numPicsInSubDpb[subDpbIdx] );
1709 
1710#if RESOLUTION_BASED_DPB
1711  // Number of pictures in each layer
1712  retVal |= ( dpbStatus.m_numPicsInLayer[layerIdx] >= dpbLimit.m_numPicsInLayer[layerIdx]);
1713#endif
1714
1715  return retVal;
1716}
1717
1718Bool TAppDecTop::ifInvokeBumpingAfterDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit )
1719{
1720  Bool retVal = false;
1721
1722  // Number of reorder picutres
1723  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1724
1725  return retVal;
1726}
1727
1728Void TAppDecTop::xFindDPBStatus( std::vector<Int> &listOfPocs
1729                            , std::vector<Int> *listOfPocsInEachLayer
1730                            , std::vector<Int> *listOfPocsPositionInEachLayer
1731                            , DpbStatus &dpbStatus
1732#if POC_RESET_IDC_DECODER
1733                            , Bool notOutputCurrAu
1734#endif
1735                            )
1736{
1737  TComVPS *vps = NULL;
1738  dpbStatus.init();
1739#if FIX_ALIGN_BUMPING
1740  for( Int i = 0; i < MAX_VPS_LAYER_ID_PLUS1; i++ )
1741#else
1742  for( Int i = 0; i < MAX_LAYERS; i++ )
1743#endif
1744  {
1745    if( m_acTDecTop[i].getListPic()->empty() )
1746    {
1747      continue;
1748    }
1749   
1750    // To check # AUs that have at least one picture not output,
1751    // For each layer, populate listOfPOcs if not already present
1752    TComList<TComPic*>::iterator iterPic = m_acTDecTop[i].getListPic()->begin();
1753    Int picPositionInList = 0;
1754    while (iterPic != m_acTDecTop[i].getListPic()->end())
1755    {
1756      TComPic* pic = *(iterPic);
1757      if( pic->getReconMark() )
1758      {
1759        if( vps == NULL )
1760        {
1761          vps = pic->getSlice(0)->getVPS();
1762        }
1763#if POC_RESET_IDC_DECODER
1764        if( !(pic->isCurrAu() && notOutputCurrAu ) )
1765        {
1766#endif
1767          std::vector<Int>::iterator it;
1768          if( pic->getOutputMark() ) // && pic->getPOC() > m_aiPOCLastDisplay[i])
1769          {
1770            it = find( listOfPocs.begin(), listOfPocs.end(), pic->getPOC() ); // Check if already included
1771            if( it == listOfPocs.end() )  // New POC value - i.e. new AU - add to the list
1772            {
1773              listOfPocs.push_back( pic->getPOC() );
1774            }
1775            listOfPocsInEachLayer         [i].push_back( pic->getPOC()    );    // POC to be output in each layer
1776            listOfPocsPositionInEachLayer [i].push_back( picPositionInList  );  // For ease of access
1777          }
1778          if( pic->getSlice(0)->isReferenced() || pic->getOutputMark() )
1779          {
1780#if RESOLUTION_BASED_DPB
1781            dpbStatus.m_numPicsInLayer[i]++;  // Count pictures that are "used for reference" or "needed for output"
1782#else
1783            dpbStatus.m_numPicsInSubDpb[i]++;  // Count pictures that are "used for reference" or "needed for output"
1784#endif
1785          }
1786#if POC_RESET_IDC_DECODER
1787        }
1788#endif
1789      }
1790      iterPic++;
1791      picPositionInList++;
1792    }
1793  }
1794
1795  assert( vps != NULL );    // No picture in any DPB?
1796  std::sort( listOfPocs.begin(), listOfPocs.end() );    // Sort in increasing order of POC
1797  Int targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1798  // Update status
1799  dpbStatus.m_numAUsNotDisplayed = listOfPocs.size();   // Number of AUs not displayed
1800  dpbStatus.m_numLayers = vps->getNumLayersInIdList( targetLsIdx );
1801#if FIX_ALIGN_BUMPING
1802  for(Int i = 0; i < dpbStatus.m_numLayers; i++)
1803  {
1804    dpbStatus.m_layerIdToSubDpbIdMap[vps->getLayerSetLayerIdList(targetLsIdx, i)] = i;
1805    dpbStatus.m_targetDecLayerIdList[i] = vps->getLayerSetLayerIdList(targetLsIdx, i);  // Layer Id stored in a particular sub-DPB
1806  }
1807  dpbStatus.m_numSubDpbs = vps->getNumSubDpbs( targetLsIdx ); 
1808#else
1809  dpbStatus.m_numSubDpbs = vps->getNumSubDpbs( vps->getOutputLayerSetIdx(
1810                                                      this->getCommonDecoderParams()->getTargetOutputLayerSetIdx() ) );
1811#endif
1812
1813#if FIX_ALIGN_BUMPING
1814  for(Int i = 0; i < MAX_VPS_LAYER_ID_PLUS1; i++)
1815#else
1816  for(Int i = 0; i < dpbStatus.m_numLayers; i++)
1817#endif
1818  {
1819    dpbStatus.m_numPicsNotDisplayedInLayer[i] = listOfPocsInEachLayer[i].size();
1820#if RESOLUTION_BASED_DPB
1821    dpbStatus.m_numPicsInSubDpb[vps->getSubDpbAssigned(targetLsIdx,i)] += dpbStatus.m_numPicsInLayer[i];
1822    dpbStatus.m_numPicsInSubDpb[i] += dpbStatus.m_numPicsInLayer[i];
1823#endif
1824  }
1825  assert( dpbStatus.m_numAUsNotDisplayed != -1 );
1826} 
1827
1828#if POC_RESET_IDC_DECODER
1829Void TAppDecTop::outputAllPictures(Int layerId, Bool notOutputCurrPic)
1830{
1831  { // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1832    std::vector<Int>  listOfPocs;
1833#if FIX_ALIGN_BUMPING
1834    std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_ID_PLUS1];
1835    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_ID_PLUS1];
1836#else
1837    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1838    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1839#endif
1840    DpbStatus dpbStatus;
1841
1842    // Find the status of the DPB
1843    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, notOutputCurrPic);
1844
1845    if( listOfPocs.size() )
1846    {
1847      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1848      {
1849        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1850      }
1851    }
1852  }
1853}
1854#endif
1855#endif
1856//! \}
Note: See TracBrowser for help on using the repository browser.