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

Last change on this file since 851 was 845, checked in by qualcomm, 10 years ago

Bug-fix in DPB operation for decoding single layer bitstream.

From: Adarsh K. Ramasubramonian <aramasub@…>

  • Property svn:eol-style set to native
File size: 55.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#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    m_acTDecTop[layer].setNumLayer( m_tgtLayerId + 1 );
571#if OUTPUT_LAYER_SET_INDEX
572    m_acTDecTop[layer].setCommonDecoderParams( this->getCommonDecoderParams() );
573#endif
574  }
575
576#else
577  m_cTDecTop.init();
578  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
579#endif
580}
581
582/** \param pcListPic list of pictures to be written to file
583    \todo            DYN_REF_FREE should be revised
584 */
585#if SVC_EXTENSION
586Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt layerId, UInt tId )
587#else
588Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
589#endif
590{
591  if (pcListPic->empty())
592  {
593    return;
594  }
595
596  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
597  Int numPicsNotYetDisplayed = 0;
598  Int dpbFullness = 0;
599#if SVC_EXTENSION
600TComSPS* activeSPS = m_acTDecTop[layerId].getActiveSPS();
601#else
602  TComSPS* activeSPS = m_cTDecTop.getActiveSPS();
603#endif
604  UInt numReorderPicsHighestTid;
605  UInt maxDecPicBufferingHighestTid;
606  UInt maxNrSublayers = activeSPS->getMaxTLayers();
607
608  if(m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers)
609  {
610    numReorderPicsHighestTid = activeSPS->getNumReorderPics(maxNrSublayers-1);
611    maxDecPicBufferingHighestTid =  activeSPS->getMaxDecPicBuffering(maxNrSublayers-1); 
612  }
613  else
614  {
615    numReorderPicsHighestTid = activeSPS->getNumReorderPics(m_iMaxTemporalLayer);
616    maxDecPicBufferingHighestTid = activeSPS->getMaxDecPicBuffering(m_iMaxTemporalLayer); 
617  }
618
619  while (iterPic != pcListPic->end())
620  {
621    TComPic* pcPic = *(iterPic);
622#if SVC_EXTENSION
623    if(pcPic->getOutputMark() && pcPic->getPOC() > m_aiPOCLastDisplay[layerId])
624#else
625    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
626#endif
627    {
628      numPicsNotYetDisplayed++;
629      dpbFullness++;
630    }
631    else if(pcPic->getSlice( 0 )->isReferenced())
632    {
633      dpbFullness++;
634    }
635    iterPic++;
636  }
637  iterPic   = pcListPic->begin();
638  if (numPicsNotYetDisplayed>2)
639  {
640    iterPic++;
641  }
642
643  TComPic* pcPic = *(iterPic);
644  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
645  {
646    TComList<TComPic*>::iterator endPic   = pcListPic->end();
647    endPic--;
648    iterPic   = pcListPic->begin();
649    while (iterPic != endPic)
650    {
651      TComPic* pcPicTop = *(iterPic);
652      iterPic++;
653      TComPic* pcPicBottom = *(iterPic);
654
655#if SVC_EXTENSION
656      if( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
657        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
658        (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&       
659        (pcPicTop->getPOC() == m_aiPOCLastDisplay[layerId]+1 || m_aiPOCLastDisplay[layerId]<0) )
660#else
661      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
662          (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
663          (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&
664          (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay < 0))
665#endif
666      {
667        // write to file
668        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
669#if SVC_EXTENSION
670        if ( m_pchReconFile[layerId] )
671        {
672          const Window &conf = pcPicTop->getConformanceWindow();
673          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
674          const Bool isTff = pcPicTop->isTopField();
675          TComPicYuv* pPicCYuvRecTop = pcPicTop->getPicYuvRec();
676          TComPicYuv* pPicCYuvRecBot = pcPicBottom->getPicYuvRec();
677#if Q0074_SEI_COLOR_MAPPING
678          if( m_acTDecTop[layerId].m_ColorMapping->getColorMappingFlag() )
679          {
680            pPicCYuvRecTop = m_acTDecTop[layerId].m_ColorMapping->getColorMapping( pPicCYuvRecTop, 0, layerId );
681            pPicCYuvRecBot = m_acTDecTop[layerId].m_ColorMapping->getColorMapping( pPicCYuvRecBot, 1, layerId );
682          }
683#endif
684#if REPN_FORMAT_IN_VPS
685          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
686          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
687
688          m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRecTop, pPicCYuvRecBot,
689            conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
690            conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
691            conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
692            conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset(), isTff );
693#else
694          m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRecTop, pPicCYuvRecBot,
695            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
696            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
697            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
698            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
699#endif
700        }
701
702        // update POC of display order
703        m_aiPOCLastDisplay[layerId] = pcPicBottom->getPOC();
704#else
705        if ( m_pchReconFile )
706        {
707          const Window &conf = pcPicTop->getConformanceWindow();
708          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
709          const Bool isTff = pcPicTop->isTopField();
710          TComPicYuv* pPicCYuvRecTop = pcPicTop->getPicYuvRec();
711          TComPicYuv* pPicCYuvRecBot = pcPicBottom->getPicYuvRec();
712#if Q0074_SEI_COLOR_MAPPING
713          if ( m_cTDecTop.m_ColorMapping->getColorMappingFlag() )
714          {
715            pPicCYuvRecTop = m_cTDecTop.m_ColorMapping->getColorMapping( pPicCYuvRecTop, 0 );
716            pPicCYuvRecBot = m_cTDecTop.m_ColorMapping->getColorMapping( pPicCYuvRecBot, 1 );
717          }
718#endif
719          m_cTVideoIOYuvReconFile.write( pPicCYuvRecTop, pPicCYuvRecBot,
720            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
721            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
722            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
723            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
724        }
725
726        // update POC of display order
727        m_iPOCLastDisplay = pcPicBottom->getPOC();
728#endif
729
730        // erase non-referenced picture in the reference picture list after display
731        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
732        {
733#if !DYN_REF_FREE
734          pcPicTop->setReconMark(false);
735
736          // mark it should be extended later
737          pcPicTop->getPicYuvRec()->setBorderExtension( false );
738
739#else
740          pcPicTop->destroy();
741          pcListPic->erase( iterPic );
742          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
743          continue;
744#endif
745        }
746        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
747        {
748#if !DYN_REF_FREE
749          pcPicBottom->setReconMark(false);
750
751          // mark it should be extended later
752          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
753
754#else
755          pcPicBottom->destroy();
756          pcListPic->erase( iterPic );
757          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
758          continue;
759#endif
760        }
761        pcPicTop->setOutputMark(false);
762        pcPicBottom->setOutputMark(false);
763      }
764    }
765  }
766  else if (!pcPic->isField()) //Frame Decoding
767  {
768    iterPic = pcListPic->begin();
769    while (iterPic != pcListPic->end())
770    {
771      pcPic = *(iterPic);
772
773#if SVC_EXTENSION
774      if( pcPic->getOutputMark() && pcPic->getPOC() > m_aiPOCLastDisplay[layerId] &&
775        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) )
776#else
777      if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay &&
778        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
779#endif
780      {
781        // write to file
782        numPicsNotYetDisplayed--;
783        if(pcPic->getSlice(0)->isReferenced() == false)
784        {
785          dpbFullness--;
786        }
787#if SVC_EXTENSION
788        if( m_pchReconFile[layerId] )
789        {
790          const Window &conf = pcPic->getConformanceWindow();
791          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
792          TComPicYuv* pPicCYuvRec = pcPic->getPicYuvRec();
793#if Q0074_SEI_COLOR_MAPPING
794          if ( m_acTDecTop[layerId].m_ColorMapping->getColorMappingFlag() )
795          {
796            pPicCYuvRec = m_acTDecTop[layerId].m_ColorMapping->getColorMapping( pPicCYuvRec, 0, layerId );
797          }
798#endif
799
800#if REPN_FORMAT_IN_VPS
801          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
802          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
803
804          m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRec,
805            conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
806            conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
807            conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
808            conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
809#else
810          m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRec,
811            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
812            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
813            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
814            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
815#endif
816        }
817
818        // update POC of display order
819        m_aiPOCLastDisplay[layerId] = pcPic->getPOC();
820#else
821        if ( m_pchReconFile )
822        {
823          const Window &conf = pcPic->getConformanceWindow();
824          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
825          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
826                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
827                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
828                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
829                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
830        }
831
832        // update POC of display order
833        m_iPOCLastDisplay = pcPic->getPOC();
834#endif
835
836        // erase non-referenced picture in the reference picture list after display
837        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
838        {
839#if !DYN_REF_FREE
840          pcPic->setReconMark(false);
841
842          // mark it should be extended later
843          pcPic->getPicYuvRec()->setBorderExtension( false );
844
845#else
846          pcPic->destroy();
847          pcListPic->erase( iterPic );
848          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
849          continue;
850#endif
851        }
852        pcPic->setOutputMark(false);
853      }
854
855      iterPic++;
856    }
857  }
858}
859
860/** \param pcListPic list of pictures to be written to file
861    \todo            DYN_REF_FREE should be revised
862 */
863#if SVC_EXTENSION
864Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, UInt layerId )
865#else
866Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
867#endif
868{
869  if(!pcListPic || pcListPic->empty())
870  {
871    return;
872  }
873  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
874
875  iterPic   = pcListPic->begin();
876  TComPic* pcPic = *(iterPic);
877
878  if (pcPic->isField()) //Field Decoding
879  {
880    TComList<TComPic*>::iterator endPic   = pcListPic->end();
881    endPic--;
882    TComPic *pcPicTop, *pcPicBottom = NULL;
883    while (iterPic != endPic)
884    {
885      pcPicTop = *(iterPic);
886      iterPic++;
887      pcPicBottom = *(iterPic);
888
889      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
890      {
891        // write to file
892#if SVC_EXTENSION
893        if ( m_pchReconFile[layerId] )
894        {
895          const Window &conf = pcPicTop->getConformanceWindow();
896          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
897          const Bool isTff = pcPicTop->isTopField();
898          TComPicYuv* pPicCYuvRecTop = pcPicTop->getPicYuvRec();
899          TComPicYuv* pPicCYuvRecBot = pcPicBottom->getPicYuvRec();
900#if Q0074_SEI_COLOR_MAPPING
901          if( m_acTDecTop[layerId].m_ColorMapping->getColorMappingFlag() )
902          {
903            pPicCYuvRecTop = m_acTDecTop[layerId].m_ColorMapping->getColorMapping( pPicCYuvRecTop, 0, layerId );
904            pPicCYuvRecBot = m_acTDecTop[layerId].m_ColorMapping->getColorMapping( pPicCYuvRecBot, 1, layerId );
905          }
906#endif
907#if REPN_FORMAT_IN_VPS
908          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
909          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
910
911          m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRecTop, pPicCYuvRecBot,
912            conf.getWindowLeftOffset()  *xScal + defDisp.getWindowLeftOffset(),
913            conf.getWindowRightOffset() *xScal + defDisp.getWindowRightOffset(),
914            conf.getWindowTopOffset()   *yScal + defDisp.getWindowTopOffset(),
915            conf.getWindowBottomOffset()*yScal + defDisp.getWindowBottomOffset(), isTff );
916#else
917          m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRecTop, pPicCYuvRecBot,
918            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
919            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
920            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
921            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
922#endif
923        }
924
925        // update POC of display order
926        m_aiPOCLastDisplay[layerId] = pcPicBottom->getPOC();
927#else
928        if ( m_pchReconFile )
929        {
930          const Window &conf = pcPicTop->getConformanceWindow();
931          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
932          const Bool isTff = pcPicTop->isTopField();
933          TComPicYuv* pPicCYuvRecTop = pcPicTop->getPicYuvRec();
934          TComPicYuv* pPicCYuvRecBot = pcPicBottom->getPicYuvRec();
935#if Q0074_SEI_COLOR_MAPPING
936          if( m_cTDecTop.m_ColorMapping->getColorMappingFlag() )
937          {
938            pPicCYuvRecTop = m_cTDecTop.m_ColorMapping->getColorMapping( pPicCYuvRecTop, 0 );
939            pPicCYuvRecBot = m_cTDecTop.m_ColorMapping->getColorMapping( pPicCYuvRecBot, 1 );
940          }
941#endif
942          m_cTVideoIOYuvReconFile.write( pPicCYuvRecTop, pPicCYuvRecBot,
943            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
944            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
945            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
946            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
947        }
948
949        // update POC of display order
950        m_iPOCLastDisplay = pcPicBottom->getPOC();
951#endif
952
953        // erase non-referenced picture in the reference picture list after display
954        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
955        {
956#if !DYN_REF_FREE
957          pcPicTop->setReconMark(false);
958
959          // mark it should be extended later
960          pcPicTop->getPicYuvRec()->setBorderExtension( false );
961
962#else
963          pcPicTop->destroy();
964          pcListPic->erase( iterPic );
965          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
966          continue;
967#endif
968        }
969        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
970        {
971#if !DYN_REF_FREE
972          pcPicBottom->setReconMark(false);
973
974          // mark it should be extended later
975          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
976
977#else
978          pcPicBottom->destroy();
979          pcListPic->erase( iterPic );
980          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
981          continue;
982#endif
983        }
984        pcPicTop->setOutputMark(false);
985        pcPicBottom->setOutputMark(false);
986
987#if !DYN_REF_FREE
988        if(pcPicTop)
989        {
990          pcPicTop->destroy();
991          delete pcPicTop;
992          pcPicTop = NULL;
993        }
994#endif
995      }
996    }
997    if(pcPicBottom)
998    {
999      pcPicBottom->destroy();
1000      delete pcPicBottom;
1001      pcPicBottom = NULL;
1002    }
1003  }
1004  else //Frame decoding
1005  {
1006    while (iterPic != pcListPic->end())
1007    {
1008      pcPic = *(iterPic);
1009
1010      if ( pcPic->getOutputMark() )
1011      {
1012        // write to file
1013#if SVC_EXTENSION
1014        if ( m_pchReconFile[layerId] )
1015        {
1016          const Window &conf = pcPic->getConformanceWindow();
1017          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
1018          TComPicYuv* pPicCYuvRec = pcPic->getPicYuvRec();
1019#if Q0074_SEI_COLOR_MAPPING
1020          if( m_acTDecTop[layerId].m_ColorMapping->getColorMappingFlag() )
1021          {
1022            pPicCYuvRec = m_acTDecTop[layerId].m_ColorMapping->getColorMapping( pPicCYuvRec, 0, layerId );
1023          }
1024#endif
1025#if REPN_FORMAT_IN_VPS
1026          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
1027          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1028
1029          m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRec,
1030            conf.getWindowLeftOffset()  *xScal + defDisp.getWindowLeftOffset(),
1031            conf.getWindowRightOffset() *xScal + defDisp.getWindowRightOffset(),
1032            conf.getWindowTopOffset()   *yScal + defDisp.getWindowTopOffset(),
1033            conf.getWindowBottomOffset()*yScal + defDisp.getWindowBottomOffset() );
1034#else
1035          m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRec,
1036            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
1037            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
1038            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
1039            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
1040#endif
1041        }
1042
1043        // update POC of display order
1044        m_aiPOCLastDisplay[layerId] = pcPic->getPOC();
1045#else
1046        if ( m_pchReconFile )
1047        {
1048          const Window &conf = pcPic->getConformanceWindow();
1049          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
1050          TComPicYuv* pPicCYuvRec = pcPic->getPicYuvRec();
1051#if Q0074_SEI_COLOR_MAPPING
1052          if( m_cTDecTop.m_ColorMapping->getColorMappingFlag() )
1053          {
1054            pPicCYuvRec = m_cTDecTop.m_ColorMapping->getColorMapping( pPicCYuvRec );
1055          }
1056#endif
1057          m_cTVideoIOYuvReconFile.write( pPicCYuvRec,
1058            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
1059            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
1060            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
1061            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
1062        }
1063
1064        // update POC of display order
1065        m_iPOCLastDisplay = pcPic->getPOC();
1066#endif
1067
1068        // erase non-referenced picture in the reference picture list after display
1069        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
1070        {
1071#if !DYN_REF_FREE
1072          pcPic->setReconMark(false);
1073
1074          // mark it should be extended later
1075          pcPic->getPicYuvRec()->setBorderExtension( false );
1076
1077#else
1078          pcPic->destroy();
1079          pcListPic->erase( iterPic );
1080          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
1081          continue;
1082#endif
1083        }
1084        pcPic->setOutputMark(false);
1085      }
1086#if !SVC_EXTENSION
1087#if !DYN_REF_FREE
1088      if(pcPic)
1089      {
1090        pcPic->destroy();
1091        delete pcPic;
1092        pcPic = NULL;
1093      }
1094#endif
1095#endif
1096      iterPic++;
1097    }
1098  }
1099#if SVC_EXTENSION
1100  m_aiPOCLastDisplay[layerId] = -MAX_INT;
1101#else
1102  pcListPic->clear();
1103  m_iPOCLastDisplay = -MAX_INT;
1104#endif
1105}
1106
1107/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
1108 */
1109Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
1110{
1111  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
1112  {
1113    return true;
1114  }
1115  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
1116  {
1117    if ( nalu->m_reservedZero6Bits == (*it) )
1118    {
1119      return true;
1120    }
1121  }
1122  return false;
1123}
1124#if ALIGNED_BUMPING
1125// Function outputs a picture, and marks it as not needed for output.
1126Void TAppDecTop::xOutputAndMarkPic( TComPic *pic, const Char *reconFile, const Int layerIdx, Int &pocLastDisplay, DpbStatus &dpbStatus )
1127{
1128  if ( reconFile )
1129  {
1130    const Window &conf = pic->getConformanceWindow();
1131    const Window &defDisp = m_respectDefDispWindow ? pic->getDefDisplayWindow() : Window();
1132    Int xScal =  1, yScal = 1;
1133#if REPN_FORMAT_IN_VPS
1134    UInt chromaFormatIdc = pic->getSlice(0)->getChromaFormatIdc();
1135    xScal = TComSPS::getWinUnitX( chromaFormatIdc );
1136    yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1137#endif
1138    TComPicYuv* pPicCYuvRec = pic->getPicYuvRec();
1139#if Q0074_SEI_COLOR_MAPPING
1140    pPicCYuvRec = m_acTDecTop[layerIdx].m_ColorMapping->getColorMapping( pPicCYuvRec, 0, layerIdx );
1141#endif
1142    m_acTVideoIOYuvReconFile[layerIdx].write( pPicCYuvRec,
1143      conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
1144      conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
1145      conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
1146      conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
1147  }
1148  // update POC of display order
1149  pocLastDisplay = pic->getPOC();
1150
1151  // Mark as not needed for output
1152  pic->setOutputMark(false);
1153
1154  // "erase" non-referenced picture in the reference picture list after display
1155  if ( !pic->getSlice(0)->isReferenced() && pic->getReconMark() == true )
1156  {
1157    pic->setReconMark(false);
1158
1159    // mark it should be extended later
1160    pic->getPicYuvRec()->setBorderExtension( false );
1161
1162#if RESOLUTION_BASED_DPB
1163    dpbStatus.m_numPicsInLayer[layerIdx]--;
1164#endif
1165    dpbStatus.m_numPicsInSubDpb[layerIdx]--;
1166  }
1167}
1168
1169Void TAppDecTop::flushAllPictures(Int layerId, Bool outputPictures)
1170{
1171  // First "empty" all pictures that are not used for reference and not needed for output
1172  emptyUnusedPicturesNotNeededForOutput();
1173
1174  if( outputPictures )  // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1175  {
1176    std::vector<Int>  listOfPocs;
1177    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1178    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1179    DpbStatus dpbStatus;
1180
1181    // Find the status of the DPB
1182    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1183
1184    if( listOfPocs.size() )
1185    {
1186      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1187      {
1188        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1189      }
1190    }
1191  }
1192
1193  // Now remove all pictures from the layer DPB?
1194  markAllPicturesAsErased(layerId);
1195}
1196Void TAppDecTop::flushAllPictures(Bool outputPictures)
1197{
1198  // First "empty" all pictures that are not used for reference and not needed for output
1199  emptyUnusedPicturesNotNeededForOutput();
1200
1201  if( outputPictures )  // All pictures in the DPB are to be output
1202  {
1203    std::vector<Int>  listOfPocs;
1204    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1205    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1206    DpbStatus dpbStatus;
1207
1208    // Find the status of the DPB
1209#if POC_RESET_IDC_DECODER
1210    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, false);
1211#else
1212    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1213#endif
1214
1215    while( dpbStatus.m_numAUsNotDisplayed )
1216    {
1217      bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1218    }
1219  }
1220
1221  // Now remove all pictures from the DPB?
1222  markAllPicturesAsErased();
1223}
1224
1225Void TAppDecTop::markAllPicturesAsErased()
1226{
1227  for(Int i = 0; i < MAX_LAYERS; i++)
1228  {
1229    markAllPicturesAsErased(i);
1230  }
1231}
1232
1233Void TAppDecTop::markAllPicturesAsErased(Int layerIdx)
1234{
1235  TComList<TComPic*>::iterator  iterPic = m_acTDecTop[layerIdx].getListPic()->begin();
1236  Int iSize = Int( m_acTDecTop[layerIdx].getListPic()->size() );
1237 
1238  for (Int i = 0; i < iSize; i++ )
1239  {
1240    TComPic* pcPic = *(iterPic++);
1241
1242    if( pcPic )
1243    {
1244      pcPic->destroy();
1245
1246      // pcPic is statically created for the external (AVC) base layer, no need to delete it
1247      if( !m_acTDecTop[layerIdx].getParameterSetManager()->getActiveVPS()->getAvcBaseLayerFlag() || layerIdx )
1248      {
1249        delete pcPic;
1250        pcPic = NULL;
1251      }
1252    }
1253  }
1254
1255  m_acTDecTop[layerIdx].getListPic()->clear();
1256}
1257
1258Void TAppDecTop::checkOutputBeforeDecoding(Int layerIdx)
1259{
1260   
1261  std::vector<Int>  listOfPocs;
1262  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1263  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1264  DpbStatus dpbStatus;
1265
1266  // First "empty" all pictures that are not used for reference and not needed for output
1267  emptyUnusedPicturesNotNeededForOutput();
1268
1269  // Find the status of the DPB
1270  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1271
1272  // If not picture to be output, return
1273  if( listOfPocs.size() == 0 )
1274  {
1275    return;
1276  }
1277
1278  // Find DPB-information from the VPS
1279  DpbStatus maxDpbLimit;
1280#if RESOLUTION_BASED_DPB
1281  Int targetLsIdx, subDpbIdx;
1282  TComVPS *vps = findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1283
1284  if( getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 )
1285  {
1286    targetLsIdx = 0;
1287    subDpbIdx   = 0; 
1288  }
1289  else
1290  {
1291    targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1292    subDpbIdx   = vps->getSubDpbAssigned( targetLsIdx, layerIdx );
1293  }
1294#else
1295  Int subDpbIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 ? 0 : layerIdx;
1296  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1297#endif
1298  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1299  while( ifInvokeBumpingBeforeDecoding(dpbStatus, maxDpbLimit, layerIdx, subDpbIdx) )
1300  {
1301    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1302  } 
1303}
1304
1305Void TAppDecTop::checkOutputAfterDecoding()
1306{   
1307  std::vector<Int>  listOfPocs;
1308  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1309  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1310  DpbStatus dpbStatus;
1311
1312  // First "empty" all pictures that are not used for reference and not needed for output
1313  emptyUnusedPicturesNotNeededForOutput();
1314
1315  // Find the status of the DPB
1316  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1317
1318  // If not picture to be output, return
1319  if( listOfPocs.size() == 0 )
1320  {
1321    return;
1322  }
1323
1324  // Find DPB-information from the VPS
1325  DpbStatus maxDpbLimit;
1326  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1327
1328  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1329  while( ifInvokeBumpingAfterDecoding(dpbStatus, maxDpbLimit) )
1330  {
1331    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1332  } 
1333}
1334
1335Void TAppDecTop::bumpingProcess(std::vector<Int> &listOfPocs, std::vector<Int> *listOfPocsInEachLayer, std::vector<Int> *listOfPocsPositionInEachLayer, DpbStatus &dpbStatus)
1336{
1337  // Choose the smallest POC value
1338  Int pocValue = *(listOfPocs.begin());
1339  std::vector<int>::iterator it;
1340  TComList<TComPic*>::iterator iterPic;
1341  for( Int layerIdx = 0; layerIdx < dpbStatus.m_numLayers; layerIdx++)
1342  {
1343    // Check if picture with pocValue is present.
1344    it = find( listOfPocsInEachLayer[layerIdx].begin(), listOfPocsInEachLayer[layerIdx].end(), pocValue );
1345    if( it != listOfPocsInEachLayer[layerIdx].end() )  // picture found.
1346    {
1347      Int picPosition = std::distance( listOfPocsInEachLayer[layerIdx].begin(), it );
1348      Int j;
1349      for(j = 0, iterPic = m_acTDecTop[layerIdx].getListPic()->begin(); j < listOfPocsPositionInEachLayer[layerIdx][picPosition]; j++) // Picture to be output
1350      {
1351        iterPic++;
1352      }
1353      TComPic *pic = *iterPic;
1354
1355      xOutputAndMarkPic( pic, m_pchReconFile[layerIdx], layerIdx, m_aiPOCLastDisplay[layerIdx], dpbStatus );
1356
1357      listOfPocsInEachLayer[layerIdx].erase( it );
1358      listOfPocsPositionInEachLayer[layerIdx].erase( listOfPocsPositionInEachLayer[layerIdx].begin() + picPosition );
1359    }
1360  }
1361  // Update sub-DPB status
1362  for( Int subDpbIdx = 0; subDpbIdx < dpbStatus.m_numSubDpbs; subDpbIdx++)
1363  {
1364    dpbStatus.m_numPicsInSubDpb[subDpbIdx]--;
1365  }
1366  dpbStatus.m_numAUsNotDisplayed--;   
1367
1368  // Remove the picture from the listOfPocs
1369  listOfPocs.erase( listOfPocs.begin() );
1370}
1371
1372TComVPS *TAppDecTop::findDpbParametersFromVps(std::vector<Int> const &listOfPocs, std::vector<Int> const *listOfPocsInEachLayer, std::vector<Int> const *listOfPocsPositionInEachLayer, DpbStatus &maxDpbLimit)
1373{
1374  Int targetOutputLsIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx();
1375  TComVPS *vps = NULL;
1376
1377  if( targetOutputLsIdx == 0 )   // Only base layer is output
1378  {
1379    TComSPS *sps = NULL;
1380    assert( listOfPocsInEachLayer[0].size() != 0 );
1381    TComList<TComPic*>::iterator iterPic;
1382    Int j;
1383    for(j = 0, iterPic = m_acTDecTop[0].getListPic()->begin(); j < listOfPocsPositionInEachLayer[0][0]; j++) // Picture to be output
1384    {
1385      iterPic++;
1386    }
1387    TComPic *pic = *iterPic;
1388    sps = pic->getSlice(0)->getSPS();   assert( sps->getLayerId() == 0 );
1389    vps = pic->getSlice(0)->getVPS();
1390    Int highestTId = sps->getMaxTLayers() - 1;
1391
1392    maxDpbLimit.m_numAUsNotDisplayed = sps->getNumReorderPics( highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1393    maxDpbLimit.m_maxLatencyIncrease = sps->getMaxLatencyIncrease( highestTId ) > 0;
1394    if( maxDpbLimit.m_maxLatencyIncrease )
1395    {
1396      maxDpbLimit.m_maxLatencyPictures = sps->getMaxLatencyIncrease( highestTId ) + sps->getNumReorderPics( highestTId ) - 1;
1397    }
1398#if RESOLUTION_BASED_DPB
1399    maxDpbLimit.m_numPicsInLayer[0] = sps->getMaxDecPicBuffering( highestTId );
1400#endif
1401    maxDpbLimit.m_numPicsInSubDpb[0] = sps->getMaxDecPicBuffering( highestTId );
1402  }
1403  else
1404  {
1405    // -------------------------------------
1406    // Find the VPS used for the pictures
1407    // -------------------------------------
1408    for(Int i = 0; i < MAX_LAYERS; i++)
1409    {
1410      if( m_acTDecTop[i].getListPic()->empty() )
1411      {
1412        assert( listOfPocsInEachLayer[i].size() == 0 );
1413        continue;
1414      }
1415      std::vector<Int>::const_iterator it;
1416      it = find( listOfPocsInEachLayer[i].begin(), listOfPocsInEachLayer[i].end(), listOfPocs[0] );
1417      TComList<TComPic*>::iterator iterPic;
1418      if( it != listOfPocsInEachLayer[i].end() )
1419      {
1420        Int picPosition = std::distance( listOfPocsInEachLayer[i].begin(), it );
1421        Int j;
1422        for(j = 0, iterPic = m_acTDecTop[i].getListPic()->begin(); j < listOfPocsPositionInEachLayer[i][picPosition]; j++) // Picture to be output
1423        {
1424          iterPic++;
1425        }
1426        TComPic *pic = *iterPic;
1427        vps = pic->getSlice(0)->getVPS();
1428        break;
1429      }
1430    }
1431
1432    Int targetLsIdx       = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1433    Int highestTId = vps->getMaxTLayers() - 1;
1434
1435    maxDpbLimit.m_numAUsNotDisplayed = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1436    maxDpbLimit.m_maxLatencyIncrease  = vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) > 0;
1437    if( maxDpbLimit.m_maxLatencyIncrease )
1438    {
1439      maxDpbLimit.m_maxLatencyPictures = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ) + vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) - 1;
1440    }
1441    for(Int i = 0; i < vps->getNumLayersInIdList( targetLsIdx ); i++)
1442    {
1443#if RESOUTION_BASED_DPB
1444      maxDpbLimit.m_numPicsInLayer[i] = vps->getMaxVpsLayerDecPicBuffMinus1( targetOutputLsIdx, i, highestTId ) + 1;
1445      maxDpbLimit.m_numPicsInSubDpb[vps->getSubDpbAssigned( targetLsIdx, i )] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, vps->getSubDpbAssigned( targetLsIdx, i ), highestTId) + 1;
1446#else
1447      maxDpbLimit.m_numPicsInSubDpb[i] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, i, highestTId) + 1;
1448#endif
1449    }
1450    // -------------------------------------
1451  }
1452  return vps;
1453}
1454Void TAppDecTop::emptyUnusedPicturesNotNeededForOutput()
1455{
1456  for(Int layerIdx = 0; layerIdx < MAX_LAYERS; layerIdx++)
1457  {
1458    TComList <TComPic*> *pcListPic = m_acTDecTop[layerIdx].getListPic();
1459    TComList<TComPic*>::iterator iterPic = pcListPic->begin();
1460    while ( iterPic != pcListPic->end() )
1461    {
1462      TComPic *pic = *iterPic;
1463      if( !pic->getSlice(0)->isReferenced() && !pic->getOutputMark() )
1464      {
1465        // Emtpy the picture buffer
1466        pic->setReconMark( false );
1467      }
1468      iterPic++;
1469    }
1470  }
1471}
1472
1473Bool TAppDecTop::ifInvokeBumpingBeforeDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit, const Int layerIdx, const Int subDpbIdx )
1474{
1475  Bool retVal = false;
1476  // Number of reorder picutres
1477  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1478
1479  // Number of pictures in each sub-DPB
1480  retVal |= ( dpbStatus.m_numPicsInSubDpb[subDpbIdx] >= dpbLimit.m_numPicsInSubDpb[subDpbIdx] );
1481 
1482#if RESOLUTION_BASED_DPB
1483  // Number of pictures in each layer
1484  retVal |= ( dpbStatus.m_numPicsInLayer[layerIdx] >= dpbLimit.m_numPicsInLayer[layerIdx]);
1485#endif
1486
1487  return retVal;
1488}
1489
1490Bool TAppDecTop::ifInvokeBumpingAfterDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit )
1491{
1492  Bool retVal = false;
1493
1494  // Number of reorder picutres
1495  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1496
1497  return retVal;
1498}
1499
1500Void TAppDecTop::xFindDPBStatus( std::vector<Int> &listOfPocs
1501                            , std::vector<Int> *listOfPocsInEachLayer
1502                            , std::vector<Int> *listOfPocsPositionInEachLayer
1503                            , DpbStatus &dpbStatus
1504#if POC_RESET_IDC_DECODER
1505                            , Bool notOutputCurrAu
1506#endif
1507                            )
1508{
1509  TComVPS *vps = NULL;
1510  dpbStatus.init();
1511  for( Int i = 0; i < MAX_LAYERS; i++ )
1512  {
1513    if( m_acTDecTop[i].getListPic()->empty() )
1514    {
1515      continue;
1516    }
1517   
1518    // To check # AUs that have at least one picture not output,
1519    // For each layer, populate listOfPOcs if not already present
1520    TComList<TComPic*>::iterator iterPic = m_acTDecTop[i].getListPic()->begin();
1521    Int picPositionInList = 0;
1522    while (iterPic != m_acTDecTop[i].getListPic()->end())
1523    {
1524      TComPic* pic = *(iterPic);
1525      if( pic->getReconMark() )
1526      {
1527        if( vps == NULL )
1528        {
1529          vps = pic->getSlice(0)->getVPS();
1530        }
1531#if POC_RESET_IDC_DECODER
1532        if( !(pic->isCurrAu() && notOutputCurrAu ) )
1533        {
1534#endif
1535          std::vector<Int>::iterator it;
1536          if( pic->getOutputMark() ) // && pic->getPOC() > m_aiPOCLastDisplay[i])
1537          {
1538            it = find( listOfPocs.begin(), listOfPocs.end(), pic->getPOC() ); // Check if already included
1539            if( it == listOfPocs.end() )  // New POC value - i.e. new AU - add to the list
1540            {
1541              listOfPocs.push_back( pic->getPOC() );
1542            }
1543            listOfPocsInEachLayer         [i].push_back( pic->getPOC()    );    // POC to be output in each layer
1544            listOfPocsPositionInEachLayer [i].push_back( picPositionInList  );  // For ease of access
1545          }
1546          if( pic->getSlice(0)->isReferenced() || pic->getOutputMark() )
1547          {
1548#if RESOLUTION_BASED_DPB
1549            dpbStatus.m_numPicsInLayer[i]++;  // Count pictures that are "used for reference" or "needed for output"
1550#else
1551            dpbStatus.m_numPicsInSubDpb[i]++;  // Count pictures that are "used for reference" or "needed for output"
1552#endif
1553          }
1554#if POC_RESET_IDC_DECODER
1555        }
1556#endif
1557      }
1558      iterPic++;
1559      picPositionInList++;
1560    }
1561  }
1562
1563  assert( vps != NULL );    // No picture in any DPB?
1564  std::sort( listOfPocs.begin(), listOfPocs.end() );    // Sort in increasing order of POC
1565  Int targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1566  // Update status
1567  dpbStatus.m_numAUsNotDisplayed = listOfPocs.size();   // Number of AUs not displayed
1568  dpbStatus.m_numLayers = vps->getNumLayersInIdList( targetLsIdx );
1569  dpbStatus.m_numSubDpbs = vps->getNumSubDpbs( vps->getOutputLayerSetIdx(
1570                                                      this->getCommonDecoderParams()->getTargetOutputLayerSetIdx() ) );
1571
1572  for(Int i = 0; i < dpbStatus.m_numLayers; i++)
1573  {
1574    dpbStatus.m_numPicsNotDisplayedInLayer[i] = listOfPocsInEachLayer[i].size();
1575#if RESOLUTION_BASED_DPB
1576    dpbStatus.m_numPicsInSubDpb[vps->getSubDpbAssigned(targetLsIdx,i)] += dpbStatus.m_numPicsInLayer[i];
1577    dpbStatus.m_numPicsInSubDpb[i] += dpbStatus.m_numPicsInLayer[i];
1578#endif
1579  }
1580  assert( dpbStatus.m_numAUsNotDisplayed != -1 );
1581} 
1582
1583#if POC_RESET_IDC_DECODER
1584Void TAppDecTop::outputAllPictures(Int layerId, Bool notOutputCurrPic)
1585{
1586  { // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1587    std::vector<Int>  listOfPocs;
1588    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1589    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1590    DpbStatus dpbStatus;
1591
1592    // Find the status of the DPB
1593    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, notOutputCurrPic);
1594
1595    if( listOfPocs.size() )
1596    {
1597      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1598      {
1599        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1600      }
1601    }
1602  }
1603}
1604#endif
1605#endif
1606//! \}
Note: See TracBrowser for help on using the repository browser.