source: SHVCSoftware/trunk/source/App/TAppDecoder/TAppDecTop.cpp @ 1114

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

merge SHM-dev

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