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

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

picture memory release after output

  • Property svn:eol-style set to native
File size: 54.6 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    dpbStatus.m_numPicsInLayer[layerIdx]--;
1163  }
1164}
1165
1166Void TAppDecTop::flushAllPictures(Int layerId, Bool outputPictures)
1167{
1168  // First "empty" all pictures that are not used for reference and not needed for output
1169  emptyUnusedPicturesNotNeededForOutput();
1170
1171  if( outputPictures )  // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1172  {
1173    std::vector<Int>  listOfPocs;
1174    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1175    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1176    DpbStatus dpbStatus;
1177
1178    // Find the status of the DPB
1179    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1180
1181    if( listOfPocs.size() )
1182    {
1183      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1184      {
1185        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1186      }
1187    }
1188  }
1189
1190  // Now remove all pictures from the layer DPB?
1191  markAllPicturesAsErased(layerId);
1192}
1193Void TAppDecTop::flushAllPictures(Bool outputPictures)
1194{
1195  // First "empty" all pictures that are not used for reference and not needed for output
1196  emptyUnusedPicturesNotNeededForOutput();
1197
1198  if( outputPictures )  // All pictures in the DPB are to be output
1199  {
1200    std::vector<Int>  listOfPocs;
1201    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1202    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1203    DpbStatus dpbStatus;
1204
1205    // Find the status of the DPB
1206#if POC_RESET_IDC_DECODER
1207    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, false);
1208#else
1209    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1210#endif
1211
1212    while( dpbStatus.m_numAUsNotDisplayed )
1213    {
1214      bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1215    }
1216  }
1217
1218  // Now remove all pictures from the DPB?
1219  markAllPicturesAsErased();
1220}
1221
1222Void TAppDecTop::markAllPicturesAsErased()
1223{
1224  for(Int i = 0; i < MAX_LAYERS; i++)
1225  {
1226    markAllPicturesAsErased(i);
1227  }
1228}
1229
1230Void TAppDecTop::markAllPicturesAsErased(Int layerIdx)
1231{
1232  TComList<TComPic*>::iterator  iterPic = m_acTDecTop[layerIdx].getListPic()->begin();
1233  Int iSize = Int( m_acTDecTop[layerIdx].getListPic()->size() );
1234 
1235  for (Int i = 0; i < iSize; i++ )
1236  {
1237    TComPic* pcPic = *(iterPic++);
1238
1239    if( pcPic )
1240    {
1241      pcPic->destroy();
1242
1243      delete pcPic;
1244      pcPic = NULL;
1245    }
1246  }
1247
1248  m_acTDecTop[layerIdx].getListPic()->clear();
1249}
1250
1251Void TAppDecTop::checkOutputBeforeDecoding(Int layerIdx)
1252{
1253   
1254  std::vector<Int>  listOfPocs;
1255  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1256  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1257  DpbStatus dpbStatus;
1258
1259  // First "empty" all pictures that are not used for reference and not needed for output
1260  emptyUnusedPicturesNotNeededForOutput();
1261
1262  // Find the status of the DPB
1263  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1264
1265  // If not picture to be output, return
1266  if( listOfPocs.size() == 0 )
1267  {
1268    return;
1269  }
1270
1271  // Find DPB-information from the VPS
1272  DpbStatus maxDpbLimit;
1273#if RESOLUTION_BASED_DPB
1274  Int targetLsIdx, subDpbIdx;
1275  TComVPS *vps = findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1276
1277  if( getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 )
1278  {
1279    targetLsIdx = 0;
1280    subDpbIdx   = 0; 
1281  }
1282  else
1283  {
1284    targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1285    subDpbIdx   = vps->getSubDpbAssigned( targetLsIdx, layerIdx );
1286  }
1287#else
1288  Int subDpbIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 ? 0 : layerIdx;
1289  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1290#endif
1291  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1292  while( ifInvokeBumpingBeforeDecoding(dpbStatus, maxDpbLimit, layerIdx, subDpbIdx) )
1293  {
1294    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1295  } 
1296}
1297
1298Void TAppDecTop::checkOutputAfterDecoding()
1299{   
1300  std::vector<Int>  listOfPocs;
1301  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1302  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1303  DpbStatus dpbStatus;
1304
1305  // First "empty" all pictures that are not used for reference and not needed for output
1306  emptyUnusedPicturesNotNeededForOutput();
1307
1308  // Find the status of the DPB
1309  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1310
1311  // If not picture to be output, return
1312  if( listOfPocs.size() == 0 )
1313  {
1314    return;
1315  }
1316
1317  // Find DPB-information from the VPS
1318  DpbStatus maxDpbLimit;
1319  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1320
1321  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1322  while( ifInvokeBumpingAfterDecoding(dpbStatus, maxDpbLimit) )
1323  {
1324    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1325  } 
1326}
1327
1328Void TAppDecTop::bumpingProcess(std::vector<Int> &listOfPocs, std::vector<Int> *listOfPocsInEachLayer, std::vector<Int> *listOfPocsPositionInEachLayer, DpbStatus &dpbStatus)
1329{
1330  // Choose the smallest POC value
1331  Int pocValue = *(listOfPocs.begin());
1332  std::vector<int>::iterator it;
1333  TComList<TComPic*>::iterator iterPic;
1334  for( Int layerIdx = 0; layerIdx < dpbStatus.m_numLayers; layerIdx++)
1335  {
1336    // Check if picture with pocValue is present.
1337    it = find( listOfPocsInEachLayer[layerIdx].begin(), listOfPocsInEachLayer[layerIdx].end(), pocValue );
1338    if( it != listOfPocsInEachLayer[layerIdx].end() )  // picture found.
1339    {
1340      Int picPosition = std::distance( listOfPocsInEachLayer[layerIdx].begin(), it );
1341      Int j;
1342      for(j = 0, iterPic = m_acTDecTop[layerIdx].getListPic()->begin(); j < listOfPocsPositionInEachLayer[layerIdx][picPosition]; j++) // Picture to be output
1343      {
1344        iterPic++;
1345      }
1346      TComPic *pic = *iterPic;
1347
1348      xOutputAndMarkPic( pic, m_pchReconFile[layerIdx], layerIdx, m_aiPOCLastDisplay[layerIdx], dpbStatus );
1349
1350      listOfPocsInEachLayer[layerIdx].erase( it );
1351      listOfPocsPositionInEachLayer[layerIdx].erase( listOfPocsPositionInEachLayer[layerIdx].begin() + picPosition );
1352    }
1353  }
1354  // Update sub-DPB status
1355  for( Int subDpbIdx = 0; subDpbIdx < dpbStatus.m_numSubDpbs; subDpbIdx++)
1356  {
1357    dpbStatus.m_numPicsInSubDpb[subDpbIdx]--;
1358  }
1359  dpbStatus.m_numAUsNotDisplayed--;   
1360
1361  // Remove the picture from the listOfPocs
1362  listOfPocs.erase( listOfPocs.begin() );
1363}
1364
1365TComVPS *TAppDecTop::findDpbParametersFromVps(std::vector<Int> const &listOfPocs, std::vector<Int> const *listOfPocsInEachLayer, std::vector<Int> const *listOfPocsPositionInEachLayer, DpbStatus &maxDpbLimit)
1366{
1367  Int targetOutputLsIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx();
1368  TComVPS *vps = NULL;
1369
1370  if( targetOutputLsIdx == 0 )   // Only base layer is output
1371  {
1372    TComSPS *sps = NULL;
1373    assert( listOfPocsInEachLayer[0].size() != 0 );
1374    TComList<TComPic*>::iterator iterPic;
1375    Int j;
1376    for(j = 0, iterPic = m_acTDecTop[0].getListPic()->begin(); j < listOfPocsPositionInEachLayer[0][0]; j++) // Picture to be output
1377    {
1378      iterPic++;
1379    }
1380    TComPic *pic = *iterPic;
1381    sps = pic->getSlice(0)->getSPS();   assert( sps->getLayerId() == 0 );
1382    vps = pic->getSlice(0)->getVPS();
1383    Int highestTId = sps->getMaxTLayers() - 1;
1384
1385    maxDpbLimit.m_numAUsNotDisplayed = sps->getNumReorderPics( highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1386    maxDpbLimit.m_maxLatencyIncrease = sps->getMaxLatencyIncrease( highestTId ) > 0;
1387    if( maxDpbLimit.m_maxLatencyIncrease )
1388    {
1389      maxDpbLimit.m_maxLatencyPictures = sps->getMaxLatencyIncrease( highestTId ) + sps->getNumReorderPics( highestTId ) - 1;
1390    }
1391    maxDpbLimit.m_numPicsInLayer[0] = sps->getMaxDecPicBuffering( highestTId );
1392    maxDpbLimit.m_numPicsInSubDpb[0] = sps->getMaxDecPicBuffering( highestTId );
1393  }
1394  else
1395  {
1396    // -------------------------------------
1397    // Find the VPS used for the pictures
1398    // -------------------------------------
1399    for(Int i = 0; i < MAX_LAYERS; i++)
1400    {
1401      if( m_acTDecTop[i].getListPic()->empty() )
1402      {
1403        assert( listOfPocsInEachLayer[i].size() == 0 );
1404        continue;
1405      }
1406      std::vector<Int>::const_iterator it;
1407      it = find( listOfPocsInEachLayer[i].begin(), listOfPocsInEachLayer[i].end(), listOfPocs[0] );
1408      TComList<TComPic*>::iterator iterPic;
1409      if( it != listOfPocsInEachLayer[i].end() )
1410      {
1411        Int picPosition = std::distance( listOfPocsInEachLayer[i].begin(), it );
1412        Int j;
1413        for(j = 0, iterPic = m_acTDecTop[i].getListPic()->begin(); j < listOfPocsPositionInEachLayer[i][picPosition]; j++) // Picture to be output
1414        {
1415          iterPic++;
1416        }
1417        TComPic *pic = *iterPic;
1418        vps = pic->getSlice(0)->getVPS();
1419        break;
1420      }
1421    }
1422
1423    Int targetLsIdx       = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1424    Int highestTId = vps->getMaxTLayers() - 1;
1425
1426    maxDpbLimit.m_numAUsNotDisplayed = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1427    maxDpbLimit.m_maxLatencyIncrease  = vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) > 0;
1428    if( maxDpbLimit.m_maxLatencyIncrease )
1429    {
1430      maxDpbLimit.m_maxLatencyPictures = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ) + vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) - 1;
1431    }
1432    for(Int i = 0; i < vps->getNumLayersInIdList( targetLsIdx ); i++)
1433    {
1434#if RESOUTION_BASED_DPB
1435      maxDpbLimit.m_numPicsInLayer[i] = vps->getMaxVpsLayerDecPicBuffMinus1( targetOutputLsIdx, i, highestTId ) + 1;
1436      maxDpbLimit.m_numPicsInSubDpb[vps->getSubDpbAssigned( targetLsIdx, i )] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, vps->getSubDpbAssigned( targetLsIdx, i ), highestTId) + 1;
1437#else
1438      maxDpbLimit.m_numPicsInSubDpb[i] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, i, highestTId) + 1;
1439#endif
1440    }
1441    // -------------------------------------
1442  }
1443  return vps;
1444}
1445Void TAppDecTop::emptyUnusedPicturesNotNeededForOutput()
1446{
1447  for(Int layerIdx = 0; layerIdx < MAX_LAYERS; layerIdx++)
1448  {
1449    TComList <TComPic*> *pcListPic = m_acTDecTop[layerIdx].getListPic();
1450    TComList<TComPic*>::iterator iterPic = pcListPic->begin();
1451    while ( iterPic != pcListPic->end() )
1452    {
1453      TComPic *pic = *iterPic;
1454      if( !pic->getSlice(0)->isReferenced() && !pic->getOutputMark() )
1455      {
1456        // Emtpy the picture buffer
1457        pic->setReconMark( false );
1458      }
1459      iterPic++;
1460    }
1461  }
1462}
1463
1464Bool TAppDecTop::ifInvokeBumpingBeforeDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit, const Int layerIdx, const Int subDpbIdx )
1465{
1466  Bool retVal = false;
1467  // Number of reorder picutres
1468  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1469
1470  // Number of pictures in each sub-DPB
1471  retVal |= ( dpbStatus.m_numPicsInSubDpb[subDpbIdx] >= dpbLimit.m_numPicsInSubDpb[subDpbIdx] );
1472 
1473#if RESOLUTION_BASED_DPB
1474  // Number of pictures in each layer
1475  retVal |= ( dpbStatus.m_numPicsInLayer[layerIdx] >= dpbLimit.m_numPicsInLayer[layerIdx]);
1476#endif
1477
1478  return retVal;
1479}
1480
1481Bool TAppDecTop::ifInvokeBumpingAfterDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit )
1482{
1483  Bool retVal = false;
1484
1485  // Number of reorder picutres
1486  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1487
1488  return retVal;
1489}
1490
1491Void TAppDecTop::xFindDPBStatus( std::vector<Int> &listOfPocs
1492                            , std::vector<Int> *listOfPocsInEachLayer
1493                            , std::vector<Int> *listOfPocsPositionInEachLayer
1494                            , DpbStatus &dpbStatus
1495#if POC_RESET_IDC_DECODER
1496                            , Bool notOutputCurrAu
1497#endif
1498                            )
1499{
1500  TComVPS *vps = NULL;
1501  dpbStatus.init();
1502  for( Int i = 0; i < MAX_LAYERS; i++ )
1503  {
1504    if( m_acTDecTop[i].getListPic()->empty() )
1505    {
1506      continue;
1507    }
1508   
1509    // To check # AUs that have at least one picture not output,
1510    // For each layer, populate listOfPOcs if not already present
1511    TComList<TComPic*>::iterator iterPic = m_acTDecTop[i].getListPic()->begin();
1512    Int picPositionInList = 0;
1513    while (iterPic != m_acTDecTop[i].getListPic()->end())
1514    {
1515      TComPic* pic = *(iterPic);
1516      if( pic->getReconMark() )
1517      {
1518        if( vps == NULL )
1519        {
1520          vps = pic->getSlice(0)->getVPS();
1521        }
1522#if POC_RESET_IDC_DECODER
1523        if( !(pic->isCurrAu() && notOutputCurrAu ) )
1524        {
1525#endif
1526          std::vector<Int>::iterator it;
1527          if( pic->getOutputMark() ) // && pic->getPOC() > m_aiPOCLastDisplay[i])
1528          {
1529            it = find( listOfPocs.begin(), listOfPocs.end(), pic->getPOC() ); // Check if already included
1530            if( it == listOfPocs.end() )  // New POC value - i.e. new AU - add to the list
1531            {
1532              listOfPocs.push_back( pic->getPOC() );
1533            }
1534            listOfPocsInEachLayer         [i].push_back( pic->getPOC()    );    // POC to be output in each layer
1535            listOfPocsPositionInEachLayer [i].push_back( picPositionInList  );  // For ease of access
1536          }
1537          if( pic->getSlice(0)->isReferenced() || pic->getOutputMark() )
1538          {
1539            dpbStatus.m_numPicsInLayer[i]++;  // Count pictures that are "used for reference" or "needed for output"
1540          }
1541#if POC_RESET_IDC_DECODER
1542        }
1543#endif
1544      }
1545      iterPic++;
1546      picPositionInList++;
1547    }
1548  }
1549
1550  assert( vps != NULL );    // No picture in any DPB?
1551  std::sort( listOfPocs.begin(), listOfPocs.end() );    // Sort in increasing order of POC
1552  Int targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1553  // Update status
1554  dpbStatus.m_numAUsNotDisplayed = listOfPocs.size();   // Number of AUs not displayed
1555  dpbStatus.m_numLayers = vps->getNumLayersInIdList( targetLsIdx );
1556  dpbStatus.m_numSubDpbs = vps->getNumSubDpbs( vps->getOutputLayerSetIdx(
1557                                                      this->getCommonDecoderParams()->getTargetOutputLayerSetIdx() ) );
1558
1559  for(Int i = 0; i < dpbStatus.m_numLayers; i++)
1560  {
1561    dpbStatus.m_numPicsNotDisplayedInLayer[i] = listOfPocsInEachLayer[i].size();
1562#if RESOLUTION_BASED_DPB
1563    dpbStatus.m_numPicsInSubDpb[vps->getSubDpbAssigned(targetLsIdx,i)] += dpbStatus.m_numPicsInLayer[i];
1564#else
1565    dpbStatus.m_numPicsInSubDpb[i] += dpbStatus.m_numPicsInLayer[i];
1566#endif
1567  }
1568  assert( dpbStatus.m_numAUsNotDisplayed != -1 );
1569} 
1570
1571#if POC_RESET_IDC_DECODER
1572Void TAppDecTop::outputAllPictures(Int layerId, Bool notOutputCurrPic)
1573{
1574  { // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1575    std::vector<Int>  listOfPocs;
1576    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1577    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1578    DpbStatus dpbStatus;
1579
1580    // Find the status of the DPB
1581    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, notOutputCurrPic);
1582
1583    if( listOfPocs.size() )
1584    {
1585      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1586      {
1587        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1588      }
1589    }
1590  }
1591}
1592#endif
1593#endif
1594//! \}
Note: See TracBrowser for help on using the repository browser.