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

Last change on this file since 1164 was 1139, checked in by seregin, 9 years ago

macro cleanup: NO_OUTPUT_OF_PRIOR_PICS

  • Property svn:eol-style set to native
File size: 75.3 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2014, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TAppDecTop.cpp
35    \brief    Decoder application class
36*/
37
38#include <list>
39#include <vector>
40#include <stdio.h>
41#include <fcntl.h>
42#include <assert.h>
43
44#include "TAppDecTop.h"
45#include "TLibDecoder/AnnexBread.h"
46#include "TLibDecoder/NALread.h"
47#if RExt__DECODER_DEBUG_BIT_STATISTICS
48#include "TLibCommon/TComCodingStatistics.h"
49#endif
50#if CONFORMANCE_BITSTREAM_MODE
51#include "TLibCommon/TComPicYuv.h"
52#include "libmd5/MD5.h"
53#endif
54
55//! \ingroup TAppDecoder
56//! \{
57
58#if Q0074_COLOUR_REMAPPING_SEI
59static Void applyColourRemapping(TComPicYuv& pic, const SEIColourRemappingInfo* colourRemappingInfoSEI, UInt layerId=0 );
60static std::vector<SEIColourRemappingInfo> storeCriSEI; //Persistent Colour Remapping Information SEI
61static SEIColourRemappingInfo *seiColourRemappingInfoPrevious=NULL ;
62#endif
63
64// ====================================================================================================================
65// Constructor / destructor / initialization / destroy
66// ====================================================================================================================
67
68#if SVC_EXTENSION
69TAppDecTop::TAppDecTop()
70{
71  for(UInt layer=0; layer < MAX_LAYERS; layer++)
72  {
73    m_aiPOCLastDisplay[layer]  = -MAX_INT;
74    m_apcTDecTop[layer] = &m_acTDecTop[layer];
75  }
76}
77#else
78TAppDecTop::TAppDecTop()
79: m_iPOCLastDisplay(-MAX_INT)
80{
81}
82#endif
83
84Void TAppDecTop::create()
85{
86}
87
88Void TAppDecTop::destroy()
89{
90  if (m_pchBitstreamFile)
91  {
92    free (m_pchBitstreamFile);
93    m_pchBitstreamFile = NULL;
94  }
95#if SVC_EXTENSION
96#if CONFORMANCE_BITSTREAM_MODE
97  for(Int i = 0; i < MAX_VPS_LAYER_IDX_PLUS1; i++ )
98#else
99  for( Int i = 0; i <= m_tgtLayerId; i++ )
100#endif
101  {
102    if( m_pchReconFile[i] )
103    {
104      free ( m_pchReconFile[i] );
105      m_pchReconFile[i] = NULL;
106    }
107  }
108#if AVC_BASE
109  if( m_pchBLReconFile )
110  {
111    free ( m_pchBLReconFile );
112    m_pchBLReconFile = NULL;
113  }
114#endif
115#else
116  if (m_pchReconFile)
117  {
118    free (m_pchReconFile);
119    m_pchReconFile = NULL;
120  }
121#endif
122#if Q0074_COLOUR_REMAPPING_SEI
123  if (seiColourRemappingInfoPrevious != NULL)
124  {
125    delete seiColourRemappingInfoPrevious;
126  }
127#endif
128}
129
130// ====================================================================================================================
131// Public member functions
132// ====================================================================================================================
133
134/**
135 - create internal class
136 - initialize internal class
137 - until the end of the bitstream, call decoding function in TDecTop class
138 - delete allocated buffers
139 - destroy internal class
140 .
141 */
142#if SVC_EXTENSION
143Void TAppDecTop::decode()
144{
145  Int                poc;
146  TComList<TComPic*>* pcListPic = NULL;
147
148  ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
149  if (!bitstreamFile)
150  {
151    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
152    exit(EXIT_FAILURE);
153  }
154
155  InputByteStream bytestream(bitstreamFile);
156
157  if (!m_outputDecodedSEIMessagesFilename.empty() && m_outputDecodedSEIMessagesFilename!="-")
158  {
159    m_seiMessageFileStream.open(m_outputDecodedSEIMessagesFilename.c_str(), std::ios::out);
160    if (!m_seiMessageFileStream.is_open() || !m_seiMessageFileStream.good())
161    {
162      fprintf(stderr, "\nUnable to open file `%s' for writing decoded SEI messages\n", m_outputDecodedSEIMessagesFilename.c_str());
163      exit(EXIT_FAILURE);
164    }
165  }
166
167  // create & initialize internal classes
168  xCreateDecLib();
169  xInitDecLib  (); 
170
171  // main decoder loop
172  Bool openedReconFile[MAX_LAYERS]; // reconstruction file not yet opened. (must be performed after SPS is seen)
173  Bool loopFiltered[MAX_LAYERS];
174  memset( loopFiltered, false, sizeof( loopFiltered ) );
175
176#if CONFORMANCE_BITSTREAM_MODE
177  for(UInt layer = 0; layer < MAX_VPS_LAYER_IDX_PLUS1; layer++)
178#else
179  for(UInt layer=0; layer<=m_tgtLayerId; layer++)
180#endif
181  {
182    openedReconFile[layer] = false;
183    m_aiPOCLastDisplay[layer] += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
184  }
185
186  UInt curLayerId = 0;     // current layer to be reconstructed
187
188#if AVC_BASE
189  TComPic pcBLPic;
190  fstream streamYUV;
191  if( m_pchBLReconFile )
192  {
193    streamYUV.open( m_pchBLReconFile, fstream::in | fstream::binary );
194  }
195  TComList<TComPic*> *cListPic = m_acTDecTop[0].getListPic();
196  m_acTDecTop[0].setBLReconFile( &streamYUV );
197  pcBLPic.setLayerId( 0 );
198  cListPic->pushBack( &pcBLPic );
199#endif
200
201  while (!!bitstreamFile)
202  {
203    /* location serves to work around a design fault in the decoder, whereby
204     * the process of reading a new slice that is the first slice of a new frame
205     * requires the TDecTop::decode() method to be called again with the same
206     * nal unit. */
207#if RExt__DECODER_DEBUG_BIT_STATISTICS
208    TComCodingStatistics::TComCodingStatisticsData backupStats(TComCodingStatistics::GetStatistics());
209    streampos location = bitstreamFile.tellg() - streampos(bytestream.GetNumBufferedBytes());
210#else
211    streampos location = bitstreamFile.tellg();
212#endif
213    AnnexBStats stats = AnnexBStats();
214
215    vector<uint8_t> nalUnit;
216    InputNALUnit nalu;
217    byteStreamNALUnit(bytestream, nalUnit, stats);
218
219    // call actual decoding function
220    Bool bNewPicture = false;
221    Bool bNewPOC = false;
222
223    if (nalUnit.empty())
224    {
225      /* this can happen if the following occur:
226       *  - empty input file
227       *  - two back-to-back start_code_prefixes
228       *  - start_code_prefix immediately followed by EOF
229       */
230      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
231    }
232    else
233    {
234      read(nalu, nalUnit);
235      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  ||
236#if CONFORMANCE_BITSTREAM_MODE
237        (nalu.m_layerId > m_commonDecoderParams.getTargetLayerId()) )
238#else
239        (nalu.m_layerId > m_tgtLayerId) )
240#endif
241      {
242        bNewPicture = false;
243      }
244      else
245      {
246        bNewPicture = m_acTDecTop[nalu.m_layerId].decode(nalu, m_iSkipFrame, m_aiPOCLastDisplay[nalu.m_layerId], curLayerId, bNewPOC);
247#if POC_RESET_IDC_DECODER
248        if ( (bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 3) || (m_acTDecTop[nalu.m_layerId].getParseIdc() == 0) )
249#else
250        if (bNewPicture)
251#endif
252        {
253          bitstreamFile.clear();
254          /* location points to the current nalunit payload[1] due to the
255           * need for the annexB parser to read three extra bytes.
256           * [1] except for the first NAL unit in the file
257           *     (but bNewPicture doesn't happen then) */
258#if RExt__DECODER_DEBUG_BIT_STATISTICS
259          bitstreamFile.seekg(location);
260          bytestream.reset();
261          TComCodingStatistics::SetStatistics(backupStats);
262#else
263          bitstreamFile.seekg(location-streamoff(3));
264          bytestream.reset();
265#endif
266        }
267#if POC_RESET_IDC_DECODER
268        else if(m_acTDecTop[nalu.m_layerId].getParseIdc() == 1) 
269        {
270          bitstreamFile.clear();
271          // This is before third parse of the NAL unit, and
272          // location points to correct beginning of the NALU
273          bitstreamFile.seekg(location);
274          bytestream.reset();
275#if RExt__DECODER_DEBUG_BIT_STATISTICS
276          TComCodingStatistics::SetStatistics(backupStats);
277#endif
278        }
279#endif
280      }
281    }
282
283#if POC_RESET_IDC_DECODER
284    if ( ( (bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 3) || m_acTDecTop[nalu.m_layerId].getParseIdc() == 0 || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) && 
285        !m_acTDecTop[nalu.m_layerId].getFirstSliceInSequence() )
286#else
287    if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) &&
288        !m_acTDecTop[nalu.m_layerId].getFirstSliceInSequence() )
289#endif
290    {
291#if O0194_DIFFERENT_BITDEPTH_EL_BL
292      //Bug fix: The bit depth was not set correctly for each layer when doing DBF
293      g_bitDepth[CHANNEL_TYPE_LUMA]   = g_bitDepthLayer[CHANNEL_TYPE_LUMA][curLayerId];
294      g_bitDepth[CHANNEL_TYPE_CHROMA] = g_bitDepthLayer[CHANNEL_TYPE_CHROMA][curLayerId];
295#endif
296      if (!loopFiltered[curLayerId] || bitstreamFile)
297      {
298        m_acTDecTop[curLayerId].executeLoopFilters(poc, pcListPic);
299      }
300      loopFiltered[curLayerId] = (nalu.m_nalUnitType == NAL_UNIT_EOS);
301
302      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
303      {
304        m_acTDecTop[nalu.m_layerId].setFirstSliceInSequence(true);
305      }
306    }
307    else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) &&
308              m_acTDecTop[nalu.m_layerId].getFirstSliceInSequence () ) 
309    {
310      m_acTDecTop[nalu.m_layerId].setFirstSliceInPicture (true);
311    }
312
313#if POC_RESET_IDC_DECODER
314    if( bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 0 )
315    {
316      outputAllPictures( nalu.m_layerId, true );
317    }
318#endif
319
320    if( pcListPic )
321    {
322      if ( m_pchReconFile[curLayerId] && !openedReconFile[curLayerId] )
323      {
324        for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
325        {
326          if (m_outputBitDepth[channelType] == 0) m_outputBitDepth[channelType] = g_bitDepth[channelType];
327        }
328        m_acTVideoIOYuvReconFile[curLayerId].open( m_pchReconFile[curLayerId], true, m_outputBitDepth, m_outputBitDepth, g_bitDepth ); // write mode
329
330        openedReconFile[curLayerId] = true;
331      }
332#if ALIGNED_BUMPING
333      Bool outputPicturesFlag = true; 
334
335      if( m_acTDecTop[nalu.m_layerId].getNoOutputPriorPicsFlag() )
336      {
337        outputPicturesFlag = false;
338      }
339
340      if (nalu.m_nalUnitType == NAL_UNIT_EOS) // End of sequence
341      {
342        flushAllPictures( nalu.m_layerId, outputPicturesFlag );       
343      }
344
345#if POC_RESET_IDC_DECODER
346      if( bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() != 0 )
347      // New picture, slice header parsed but picture not decoded
348#else
349      if( bNewPicture ) // New picture, slice header parsed but picture not decoded
350#endif
351      {
352         if(   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
353            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
354            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
355            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
356            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP   )
357        {
358          flushAllPictures( nalu.m_layerId, outputPicturesFlag );
359        }
360        else
361        {
362          this->checkOutputBeforeDecoding( nalu.m_layerId );
363        }
364      }
365
366      /* The following code has to be executed when the last DU of the picture is decoded
367         TODO: Need code to identify end of decoding a picture
368      {
369        this->checkOutputAfterDecoding( );
370      } */
371#else
372      if ( bNewPicture && bNewPOC &&
373           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
374            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
375            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
376            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
377            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
378      {
379        xFlushOutput( pcListPic, curLayerId );
380      }
381      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
382      {
383        xFlushOutput( pcListPic, curLayerId );       
384      }
385      // write reconstruction to file
386      if(bNewPicture)
387      {
388        xWriteOutput( pcListPic, curLayerId, nalu.m_temporalId );
389      }
390#endif
391    }
392  }
393#if ALIGNED_BUMPING
394   flushAllPictures( true );   
395#else
396  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
397  {
398    xFlushOutput( m_acTDecTop[layer].getListPic(), layer );
399  }
400#endif
401  // delete buffers
402#if AVC_BASE
403  UInt layerIdxmin = m_acTDecTop[0].getBLReconFile()->is_open() ? 1 : 0;
404
405  if( streamYUV.is_open() )
406  {
407    streamYUV.close();
408  }
409  pcBLPic.destroy();
410
411#if CONFORMANCE_BITSTREAM_MODE
412  for(UInt layer = layerIdxmin; layer < MAX_VPS_LAYER_IDX_PLUS1; layer++)
413#else
414  for(UInt layer = layerIdxmin; layer <= m_tgtLayerId; layer++)
415#endif
416#else
417  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
418#endif
419  {
420    m_acTDecTop[layer].deletePicBuffer();
421  }
422
423  // destroy internal classes
424  xDestroyDecLib();
425}
426#else
427Void TAppDecTop::decode()
428{
429  Int                 poc;
430  TComList<TComPic*>* pcListPic = NULL;
431
432  ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
433  if (!bitstreamFile)
434  {
435    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
436    exit(EXIT_FAILURE);
437  }
438
439  InputByteStream bytestream(bitstreamFile);
440
441  if (!m_outputDecodedSEIMessagesFilename.empty() && m_outputDecodedSEIMessagesFilename!="-")
442  {
443    m_seiMessageFileStream.open(m_outputDecodedSEIMessagesFilename.c_str(), std::ios::out);
444    if (!m_seiMessageFileStream.is_open() || !m_seiMessageFileStream.good())
445    {
446      fprintf(stderr, "\nUnable to open file `%s' for writing decoded SEI messages\n", m_outputDecodedSEIMessagesFilename.c_str());
447      exit(EXIT_FAILURE);
448    }
449  }
450
451  // create & initialize internal classes
452  xCreateDecLib();
453  xInitDecLib  ();
454  m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
455
456  // main decoder loop
457  Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
458  Bool loopFiltered = false;
459
460  while (!!bitstreamFile)
461  {
462    /* location serves to work around a design fault in the decoder, whereby
463     * the process of reading a new slice that is the first slice of a new frame
464     * requires the TDecTop::decode() method to be called again with the same
465     * nal unit. */
466#if RExt__DECODER_DEBUG_BIT_STATISTICS
467    TComCodingStatistics::TComCodingStatisticsData backupStats(TComCodingStatistics::GetStatistics());
468    streampos location = bitstreamFile.tellg() - streampos(bytestream.GetNumBufferedBytes());
469#else
470    streampos location = bitstreamFile.tellg();
471#endif
472    AnnexBStats stats = AnnexBStats();
473
474    vector<uint8_t> nalUnit;
475    InputNALUnit nalu;
476    byteStreamNALUnit(bytestream, nalUnit, stats);
477
478    // call actual decoding function
479    Bool bNewPicture = false;
480    if (nalUnit.empty())
481    {
482      /* this can happen if the following occur:
483       *  - empty input file
484       *  - two back-to-back start_code_prefixes
485       *  - start_code_prefix immediately followed by EOF
486       */
487      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
488    }
489    else
490    {
491      read(nalu, nalUnit);
492      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
493      {
494        bNewPicture = false;
495      }
496      else
497      {
498        bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
499        if (bNewPicture)
500        {
501          bitstreamFile.clear();
502          /* location points to the current nalunit payload[1] due to the
503           * need for the annexB parser to read three extra bytes.
504           * [1] except for the first NAL unit in the file
505           *     (but bNewPicture doesn't happen then) */
506#if RExt__DECODER_DEBUG_BIT_STATISTICS
507          bitstreamFile.seekg(location);
508          bytestream.reset();
509          TComCodingStatistics::SetStatistics(backupStats);
510#else
511          bitstreamFile.seekg(location-streamoff(3));
512          bytestream.reset();
513#endif
514        }
515      }
516    }
517
518    if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) &&
519        !m_cTDecTop.getFirstSliceInSequence () )
520    {
521      if (!loopFiltered || bitstreamFile)
522      {
523        m_cTDecTop.executeLoopFilters(poc, pcListPic);
524      }
525      loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
526      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
527      {
528        m_cTDecTop.setFirstSliceInSequence(true);
529      }
530    }
531    else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) &&
532              m_cTDecTop.getFirstSliceInSequence () ) 
533    {
534      m_cTDecTop.setFirstSliceInPicture (true);
535    }
536
537    if( pcListPic )
538    {
539      if ( m_pchReconFile && !openedReconFile )
540      {
541        for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
542        {
543          if (m_outputBitDepth[channelType] == 0) m_outputBitDepth[channelType] = g_bitDepth[channelType];
544        }
545
546        m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepth, m_outputBitDepth, g_bitDepth ); // write mode
547        openedReconFile = true;
548      }
549      // write reconstruction to file
550      if( bNewPicture )
551      {
552        xWriteOutput( pcListPic, nalu.m_temporalId );
553      }
554      if ( (bNewPicture || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) && m_cTDecTop.getNoOutputPriorPicsFlag() )
555      {
556        m_cTDecTop.checkNoOutputPriorPics( pcListPic );
557        m_cTDecTop.setNoOutputPriorPicsFlag (false);
558      }
559      if ( bNewPicture &&
560           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
561            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
562            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
563            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
564            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
565      {
566        xFlushOutput( pcListPic );
567      }
568      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
569      {
570        xWriteOutput( pcListPic, nalu.m_temporalId );
571        m_cTDecTop.setFirstSliceInPicture (false);
572      }
573      // write reconstruction to file -- for additional bumping as defined in C.5.2.3
574      if(!bNewPicture && nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL_N && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL31)
575      {
576        xWriteOutput( pcListPic, nalu.m_temporalId );
577      }
578    }
579  }
580
581  xFlushOutput( pcListPic );
582  // delete buffers
583  m_cTDecTop.deletePicBuffer();
584
585  // destroy internal classes
586  xDestroyDecLib();
587}
588#endif
589
590// ====================================================================================================================
591// Protected member functions
592// ====================================================================================================================
593
594Void TAppDecTop::xCreateDecLib()
595{
596#if SVC_EXTENSION
597  // initialize global variables
598  initROM();
599
600#if CONFORMANCE_BITSTREAM_MODE
601  for(UInt layer = 0; layer < MAX_VPS_LAYER_IDX_PLUS1; layer++)
602#else
603  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
604#endif
605  {
606    // set layer ID
607    m_acTDecTop[layer].setLayerId                      ( layer );
608
609    // create decoder class
610    m_acTDecTop[layer].create();
611
612    m_acTDecTop[layer].setLayerDec(m_apcTDecTop);
613  }
614#else
615  // create decoder class
616  m_cTDecTop.create();
617#endif
618}
619
620Void TAppDecTop::xDestroyDecLib()
621{
622#if SVC_EXTENSION
623  // destroy ROM
624  destroyROM();
625
626#if CONFORMANCE_BITSTREAM_MODE
627  for(UInt layer = 0; layer < MAX_VPS_LAYER_IDX_PLUS1; layer++)
628#else
629  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
630#endif
631  {
632    if ( m_pchReconFile[layer] )
633    {
634      m_acTVideoIOYuvReconFile[layer].close();
635    }
636
637    // destroy decoder class
638    m_acTDecTop[layer].destroy();
639  }
640#else
641  if ( m_pchReconFile )
642  {
643    m_cTVideoIOYuvReconFile. close();
644  }
645
646  // destroy decoder class
647  m_cTDecTop.destroy();
648#endif
649}
650
651Void TAppDecTop::xInitDecLib()
652{
653  // initialize decoder class
654#if SVC_EXTENSION
655#if CONFORMANCE_BITSTREAM_MODE
656  for(UInt layer = 0; layer < MAX_VPS_LAYER_IDX_PLUS1; layer++)
657#else
658  for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
659#endif
660  {
661    m_acTDecTop[layer].init();
662    m_acTDecTop[layer].setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
663#if CONFORMANCE_BITSTREAM_MODE
664    m_acTDecTop[layer].setNumLayer( MAX_LAYERS );
665#else
666    m_acTDecTop[layer].setNumLayer( m_tgtLayerId + 1 );
667#endif
668#if OUTPUT_LAYER_SET_INDEX
669    m_acTDecTop[layer].setCommonDecoderParams( &m_commonDecoderParams );
670#endif
671  }
672#if CONFORMANCE_BITSTREAM_MODE
673  for(UInt layer = 0; layer < MAX_VPS_LAYER_IDX_PLUS1; layer++)
674  {
675    m_acTDecTop[layer].setConfModeFlag( m_confModeFlag );
676  }
677#endif
678#else
679  m_cTDecTop.init();
680  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
681#if O0043_BEST_EFFORT_DECODING
682  m_cTDecTop.setForceDecodeBitDepth(m_forceDecodeBitDepth);
683#endif
684  if (!m_outputDecodedSEIMessagesFilename.empty())
685  {
686    std::ostream &os=m_seiMessageFileStream.is_open() ? m_seiMessageFileStream : std::cout;
687    m_cTDecTop.setDecodedSEIMessageOutputStream(&os);
688  }
689#endif
690}
691
692/** \param pcListPic list of pictures to be written to file
693    \todo            DYN_REF_FREE should be revised
694 */
695#if SVC_EXTENSION
696Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt layerId, UInt tId )
697#else
698Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
699#endif
700{
701  if (pcListPic->empty())
702  {
703    return;
704  }
705
706  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
707  Int numPicsNotYetDisplayed = 0;
708  Int dpbFullness = 0;
709#if SVC_EXTENSION
710TComSPS* activeSPS = m_acTDecTop[layerId].getActiveSPS();
711#else
712  TComSPS* activeSPS = m_cTDecTop.getActiveSPS();
713#endif
714  UInt numReorderPicsHighestTid;
715  UInt maxDecPicBufferingHighestTid;
716  UInt maxNrSublayers = activeSPS->getMaxTLayers();
717
718  if(m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers)
719  {
720    numReorderPicsHighestTid = activeSPS->getNumReorderPics(maxNrSublayers-1);
721    maxDecPicBufferingHighestTid =  activeSPS->getMaxDecPicBuffering(maxNrSublayers-1); 
722  }
723  else
724  {
725    numReorderPicsHighestTid = activeSPS->getNumReorderPics(m_iMaxTemporalLayer);
726    maxDecPicBufferingHighestTid = activeSPS->getMaxDecPicBuffering(m_iMaxTemporalLayer); 
727  }
728
729  while (iterPic != pcListPic->end())
730  {
731    TComPic* pcPic = *(iterPic);
732#if SVC_EXTENSION
733    if(pcPic->getOutputMark() && pcPic->getPOC() > m_aiPOCLastDisplay[layerId])
734#else
735    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
736#endif
737    {
738       numPicsNotYetDisplayed++;
739      dpbFullness++;
740    }
741    else if(pcPic->getSlice( 0 )->isReferenced())
742    {
743      dpbFullness++;
744    }
745    iterPic++;
746  }
747
748  iterPic = pcListPic->begin();
749
750  if (numPicsNotYetDisplayed>2)
751  {
752    iterPic++;
753  }
754
755  TComPic* pcPic = *(iterPic);
756  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
757  {
758    TComList<TComPic*>::iterator endPic   = pcListPic->end();
759    endPic--;
760    iterPic   = pcListPic->begin();
761    while (iterPic != endPic)
762    {
763      TComPic* pcPicTop = *(iterPic);
764      iterPic++;
765      TComPic* pcPicBottom = *(iterPic);
766
767#if SVC_EXTENSION
768      if( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
769        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
770        (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&       
771        (pcPicTop->getPOC() == m_aiPOCLastDisplay[layerId]+1 || m_aiPOCLastDisplay[layerId]<0) )
772#else
773      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
774          (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
775          (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&
776          (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay < 0))
777#endif
778      {
779        // write to file
780        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
781#if SVC_EXTENSION
782        if ( m_pchReconFile[layerId] )
783        {
784          const Window &conf = pcPicTop->getConformanceWindow();
785          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
786          const Bool isTff = pcPicTop->isTopField();
787
788          Bool display = true;
789          if( m_decodedNoDisplaySEIEnabled )
790          {
791            SEIMessages noDisplay = getSeisByType(pcPic->getSEIs(), SEI::NO_DISPLAY );
792            const SEINoDisplay *nd = ( noDisplay.size() > 0 ) ? (SEINoDisplay*) *(noDisplay.begin()) : NULL;
793            if( (nd != NULL) && nd->m_noDisplay )
794            {
795              display = false;
796            }
797          }
798
799          if (display)
800          {           
801#if REPN_FORMAT_IN_VPS
802            UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
803            Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
804
805            m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
806              m_outputColourSpaceConvert,
807              conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
808              conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
809              conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
810              conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
811#else
812            m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
813              m_outputColourSpaceConvert,
814              conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
815              conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
816              conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
817              conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
818#endif
819          }
820        }
821
822        // update POC of display order
823        m_aiPOCLastDisplay[layerId] = pcPicBottom->getPOC();
824#else
825        if ( m_pchReconFile )
826        {
827          const Window &conf = pcPicTop->getConformanceWindow();
828          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
829          const Bool isTff = pcPicTop->isTopField();
830
831          Bool display = true;
832          if( m_decodedNoDisplaySEIEnabled )
833          {
834            SEIMessages noDisplay = getSeisByType(pcPic->getSEIs(), SEI::NO_DISPLAY );
835            const SEINoDisplay *nd = ( noDisplay.size() > 0 ) ? (SEINoDisplay*) *(noDisplay.begin()) : NULL;
836            if( (nd != NULL) && nd->m_noDisplay )
837            {
838              display = false;
839            }
840          }
841
842          if (display)
843          {
844            m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
845                                           m_outputColourSpaceConvert,
846                                           conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
847                                           conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
848                                           conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
849                                           conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
850          }
851        }
852
853        // update POC of display order
854        m_iPOCLastDisplay = pcPicBottom->getPOC();
855#endif
856
857        // erase non-referenced picture in the reference picture list after display
858        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
859        {
860#if !DYN_REF_FREE
861          pcPicTop->setReconMark(false);
862
863          // mark it should be extended later
864          pcPicTop->getPicYuvRec()->setBorderExtension( false );
865
866#else
867          pcPicTop->destroy();
868          pcListPic->erase( iterPic );
869          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
870          continue;
871#endif
872        }
873        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
874        {
875#if !DYN_REF_FREE
876          pcPicBottom->setReconMark(false);
877
878          // mark it should be extended later
879          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
880
881#else
882          pcPicBottom->destroy();
883          pcListPic->erase( iterPic );
884          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
885          continue;
886#endif
887        }
888        pcPicTop->setOutputMark(false);
889        pcPicBottom->setOutputMark(false);
890      }
891    }
892  }
893  else if (!pcPic->isField()) //Frame Decoding
894  {
895    iterPic = pcListPic->begin();
896
897    while (iterPic != pcListPic->end())
898    {
899      pcPic = *(iterPic);
900
901#if SVC_EXTENSION
902      if( pcPic->getOutputMark() && pcPic->getPOC() > m_aiPOCLastDisplay[layerId] &&
903        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) )
904#else
905      if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay &&
906        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
907#endif
908      {
909        // write to file
910         numPicsNotYetDisplayed--;
911        if(pcPic->getSlice(0)->isReferenced() == false)
912        {
913          dpbFullness--;
914        }
915#if SVC_EXTENSION
916        if( m_pchReconFile[layerId] )
917        {
918          const Window &conf = pcPic->getConformanceWindow();
919          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();         
920#if REPN_FORMAT_IN_VPS
921          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
922          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
923
924          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(), m_outputColourSpaceConvert,
925            conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
926            conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
927            conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
928            conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
929#else
930          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(), m_outputColourSpaceConvert,
931            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
932            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
933            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
934            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
935#endif
936        }
937
938        // update POC of display order
939        m_aiPOCLastDisplay[layerId] = pcPic->getPOC();
940#else
941        if ( m_pchReconFile )
942        {
943          const Window &conf    = pcPic->getConformanceWindow();
944          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
945
946          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
947                                         m_outputColourSpaceConvert,
948                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
949                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
950                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
951                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
952        }
953
954#if Q0074_COLOUR_REMAPPING_SEI
955        if (m_colourRemapSEIEnabled)
956        {
957          SEIMessages colourRemappingInfo = getSeisByType(pcPic->getSEIs(), SEI::COLOUR_REMAPPING_INFO );
958          const SEIColourRemappingInfo *seiColourRemappingInfo = ( colourRemappingInfo.size() > 0 ) ? (SEIColourRemappingInfo*) *(colourRemappingInfo.begin()) : NULL;
959          if (colourRemappingInfo.size() > 1)
960          {
961            printf ("Warning: Got multiple Colour Remapping Information SEI messages. Using first.");
962          }
963          if (seiColourRemappingInfo)
964          {
965            applyColourRemapping(*pcPic->getPicYuvRec(), seiColourRemappingInfo);
966          }
967          else  // using the last CRI SEI received
968          {
969            const SEIColourRemappingInfo *seiColourRemappingInfoCopy;
970            seiColourRemappingInfoCopy = seiColourRemappingInfoPrevious;
971            applyColourRemapping(*pcPic->getPicYuvRec(), seiColourRemappingInfoCopy);
972          }
973
974          // save the last CRI SEI received
975          if( seiColourRemappingInfo != NULL){
976            if (seiColourRemappingInfoPrevious != NULL)
977            {
978              delete seiColourRemappingInfoPrevious;
979              seiColourRemappingInfoPrevious = NULL;
980            }
981            if (seiColourRemappingInfo->m_colourRemapPersistenceFlag)
982            {
983              seiColourRemappingInfoPrevious = new SEIColourRemappingInfo();
984              seiColourRemappingInfoPrevious->copyFrom(seiColourRemappingInfo);
985            }
986          }
987        }
988#endif
989
990        // update POC of display order
991        m_iPOCLastDisplay = pcPic->getPOC();
992#endif
993
994        // erase non-referenced picture in the reference picture list after display
995        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
996        {
997#if !DYN_REF_FREE
998          pcPic->setReconMark(false);
999
1000          // mark it should be extended later
1001          pcPic->getPicYuvRec()->setBorderExtension( false );
1002
1003#else
1004          pcPic->destroy();
1005          pcListPic->erase( iterPic );
1006          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
1007          continue;
1008#endif
1009        }
1010        pcPic->setOutputMark(false);
1011      }
1012
1013      iterPic++;
1014    }
1015  }
1016}
1017
1018/** \param pcListPic list of pictures to be written to file
1019    \todo            DYN_REF_FREE should be revised
1020 */
1021#if SVC_EXTENSION
1022Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, UInt layerId )
1023#else
1024Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
1025#endif
1026{
1027  if(!pcListPic || pcListPic->empty())
1028  {
1029    return;
1030  }
1031  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
1032
1033  iterPic   = pcListPic->begin();
1034  TComPic* pcPic = *(iterPic);
1035
1036  if (pcPic->isField()) //Field Decoding
1037  {
1038    TComList<TComPic*>::iterator endPic   = pcListPic->end();
1039    endPic--;
1040    TComPic *pcPicTop, *pcPicBottom = NULL;
1041    while (iterPic != endPic)
1042    {
1043      pcPicTop = *(iterPic);
1044      iterPic++;
1045      pcPicBottom = *(iterPic);
1046
1047      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
1048      {
1049        // write to file
1050#if SVC_EXTENSION
1051        if ( m_pchReconFile[layerId] )
1052        {
1053          const Window &conf = pcPicTop->getConformanceWindow();
1054          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
1055          const Bool isTff = pcPicTop->isTopField();         
1056#if REPN_FORMAT_IN_VPS
1057          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
1058          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1059
1060          m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(), m_outputColourSpaceConvert,
1061            conf.getWindowLeftOffset()  *xScal + defDisp.getWindowLeftOffset(),
1062            conf.getWindowRightOffset() *xScal + defDisp.getWindowRightOffset(),
1063            conf.getWindowTopOffset()   *yScal + defDisp.getWindowTopOffset(),
1064            conf.getWindowBottomOffset()*yScal + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
1065#else
1066          m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(), m_outputColourSpaceConvert,
1067            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
1068            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
1069            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
1070            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
1071#endif
1072        }
1073
1074        // update POC of display order
1075        m_aiPOCLastDisplay[layerId] = pcPicBottom->getPOC();
1076#else
1077        if ( m_pchReconFile )
1078        {
1079          const Window &conf = pcPicTop->getConformanceWindow();
1080          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
1081          const Bool isTff = pcPicTop->isTopField();
1082          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
1083                                         m_outputColourSpaceConvert,
1084                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
1085                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
1086                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
1087                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
1088        }
1089
1090        // update POC of display order
1091        m_iPOCLastDisplay = pcPicBottom->getPOC();
1092#endif
1093
1094        // erase non-referenced picture in the reference picture list after display
1095        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
1096        {
1097#if !DYN_REF_FREE
1098          pcPicTop->setReconMark(false);
1099
1100          // mark it should be extended later
1101          pcPicTop->getPicYuvRec()->setBorderExtension( false );
1102
1103#else
1104          pcPicTop->destroy();
1105          pcListPic->erase( iterPic );
1106          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
1107          continue;
1108#endif
1109        }
1110        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
1111        {
1112#if !DYN_REF_FREE
1113          pcPicBottom->setReconMark(false);
1114
1115          // mark it should be extended later
1116          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
1117
1118#else
1119          pcPicBottom->destroy();
1120          pcListPic->erase( iterPic );
1121          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
1122          continue;
1123#endif
1124        }
1125        pcPicTop->setOutputMark(false);
1126        pcPicBottom->setOutputMark(false);
1127
1128#if !DYN_REF_FREE
1129        if(pcPicTop)
1130        {
1131          pcPicTop->destroy();
1132          delete pcPicTop;
1133          pcPicTop = NULL;
1134        }
1135#endif
1136      }
1137    }
1138    if(pcPicBottom)
1139    {
1140      pcPicBottom->destroy();
1141      delete pcPicBottom;
1142      pcPicBottom = NULL;
1143    }
1144  }
1145  else //Frame decoding
1146  {
1147    while (iterPic != pcListPic->end())
1148    {
1149      pcPic = *(iterPic);
1150
1151      if ( pcPic->getOutputMark() )
1152      {
1153        // write to file
1154#if SVC_EXTENSION
1155        if ( m_pchReconFile[layerId] )
1156        {
1157          const Window &conf = pcPic->getConformanceWindow();
1158          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();         
1159#if REPN_FORMAT_IN_VPS
1160          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
1161          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1162
1163          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(), m_outputColourSpaceConvert,
1164            conf.getWindowLeftOffset()  *xScal + defDisp.getWindowLeftOffset(),
1165            conf.getWindowRightOffset() *xScal + defDisp.getWindowRightOffset(),
1166            conf.getWindowTopOffset()   *yScal + defDisp.getWindowTopOffset(),
1167            conf.getWindowBottomOffset()*yScal + defDisp.getWindowBottomOffset() );
1168#else
1169          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(), m_outputColourSpaceConvert,
1170            conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
1171            conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
1172            conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
1173            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
1174#endif
1175        }
1176
1177        // update POC of display order
1178        m_aiPOCLastDisplay[layerId] = pcPic->getPOC();
1179#else
1180        if ( m_pchReconFile )
1181        {
1182          const Window &conf    = pcPic->getConformanceWindow();
1183          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
1184
1185          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
1186                                         m_outputColourSpaceConvert,
1187                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
1188                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
1189                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
1190                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
1191        }
1192
1193#if Q0074_COLOUR_REMAPPING_SEI
1194        if (m_colourRemapSEIEnabled)
1195        {
1196          SEIMessages colourRemappingInfo = getSeisByType(pcPic->getSEIs(), SEI::COLOUR_REMAPPING_INFO );
1197          const SEIColourRemappingInfo *seiColourRemappingInfo = ( colourRemappingInfo.size() > 0 ) ? (SEIColourRemappingInfo*) *(colourRemappingInfo.begin()) : NULL;
1198          if (colourRemappingInfo.size() > 1)
1199          {
1200            printf ("Warning: Got multiple Colour Remapping Information SEI messages. Using first.");
1201          }
1202          if (seiColourRemappingInfo)
1203          {
1204            applyColourRemapping(*pcPic->getPicYuvRec(), seiColourRemappingInfo);
1205          }
1206          else  // using the last CRI SEI received
1207          {
1208            const SEIColourRemappingInfo *seiColourRemappingInfoCopy;
1209            seiColourRemappingInfoCopy = seiColourRemappingInfoPrevious;
1210            applyColourRemapping(*pcPic->getPicYuvRec(), seiColourRemappingInfoCopy);
1211          }
1212
1213          // save the last CRI SEI received
1214          if( seiColourRemappingInfo != NULL){
1215            if (seiColourRemappingInfoPrevious != NULL)
1216            {
1217              delete seiColourRemappingInfoPrevious;
1218              seiColourRemappingInfoPrevious = NULL;
1219            }
1220            if (seiColourRemappingInfo->m_colourRemapPersistenceFlag)
1221            {
1222              seiColourRemappingInfoPrevious = new SEIColourRemappingInfo();
1223              seiColourRemappingInfoPrevious->copyFrom(seiColourRemappingInfo);
1224            }
1225          }
1226        }
1227#endif
1228
1229        // update POC of display order
1230        m_iPOCLastDisplay = pcPic->getPOC();
1231#endif
1232
1233        // erase non-referenced picture in the reference picture list after display
1234        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
1235        {
1236#if !DYN_REF_FREE
1237          pcPic->setReconMark(false);
1238
1239          // mark it should be extended later
1240          pcPic->getPicYuvRec()->setBorderExtension( false );
1241
1242#else
1243          pcPic->destroy();
1244          pcListPic->erase( iterPic );
1245          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
1246          continue;
1247#endif
1248        }
1249        pcPic->setOutputMark(false);
1250      }
1251#if !SVC_EXTENSION
1252#if !DYN_REF_FREE
1253      if(pcPic)
1254      {
1255        pcPic->destroy();
1256        delete pcPic;
1257        pcPic = NULL;
1258      }
1259#endif
1260#endif
1261      iterPic++;
1262    }
1263  }
1264#if SVC_EXTENSION
1265  m_aiPOCLastDisplay[layerId] = -MAX_INT;
1266#else
1267  pcListPic->clear();
1268  m_iPOCLastDisplay = -MAX_INT;
1269#endif
1270}
1271
1272/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
1273 */
1274Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
1275{
1276  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
1277  {
1278    return true;
1279  }
1280#if SVC_EXTENSION
1281  if (nalu->m_layerId == 0 && (nalu->m_nalUnitType == NAL_UNIT_VPS || nalu->m_nalUnitType == NAL_UNIT_SPS || nalu->m_nalUnitType == NAL_UNIT_PPS || nalu->m_nalUnitType == NAL_UNIT_EOS))
1282  {
1283    return true;
1284  }
1285#endif
1286  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
1287  {
1288    if ( nalu->m_reservedZero6Bits == (*it) )
1289    {
1290      return true;
1291    }
1292  }
1293  return false;
1294}
1295
1296#if ALIGNED_BUMPING
1297// Function outputs a picture, and marks it as not needed for output.
1298Void TAppDecTop::xOutputAndMarkPic( TComPic *pic, const Char *reconFile, const Int layerId, Int &pocLastDisplay, DpbStatus &dpbStatus )
1299{
1300  if ( reconFile )
1301  {
1302    const Window &conf = pic->getConformanceWindow();
1303    const Window &defDisp = m_respectDefDispWindow ? pic->getDefDisplayWindow() : Window();
1304    Int xScal =  1, yScal = 1;
1305#if REPN_FORMAT_IN_VPS
1306    UInt chromaFormatIdc = pic->getSlice(0)->getChromaFormatIdc();
1307    xScal = TComSPS::getWinUnitX( chromaFormatIdc );
1308    yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1309#endif
1310    TComPicYuv* pPicCYuvRec = pic->getPicYuvRec();
1311    m_acTVideoIOYuvReconFile[layerId].write( pPicCYuvRec, m_outputColourSpaceConvert,
1312      conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
1313      conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
1314      conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
1315      conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
1316
1317#if Q0074_COLOUR_REMAPPING_SEI
1318    if (m_colourRemapSEIEnabled)
1319    {
1320      SEIMessages colourRemappingInfo = getSeisByType(pic->getSEIs(), SEI::COLOUR_REMAPPING_INFO );
1321      const SEIColourRemappingInfo *seiColourRemappingInfo = ( colourRemappingInfo.size() > 0 ) ? (SEIColourRemappingInfo*) *(colourRemappingInfo.begin()) : NULL;
1322      if (colourRemappingInfo.size() > 1)
1323      {
1324        printf ("Warning: Got multiple Colour Remapping Information SEI messages. Using first.");
1325      }
1326
1327      if (seiColourRemappingInfo)
1328      {
1329        //printf ("\n\nColour Remapping is applied to POC : %d and LayerId : %d ",pic->getPOC(), pic->getLayerId());
1330        applyColourRemapping(*pic->getPicYuvRec(), seiColourRemappingInfo
1331#if SVC_EXTENSION
1332       , pic->getLayerId()
1333#endif
1334        );
1335      }
1336      else  // using the last CRI SEI received
1337      {
1338        const SEIColourRemappingInfo *seiColourRemappingInfoCopy;
1339        seiColourRemappingInfoCopy = seiColourRemappingInfoPrevious;
1340        applyColourRemapping(*pic->getPicYuvRec(), seiColourRemappingInfoCopy
1341#if SVC_EXTENSION
1342        , pic->getLayerId()
1343#endif
1344        );
1345      }
1346
1347      // save the last CRI SEI received
1348      if( seiColourRemappingInfo != NULL){
1349        if (seiColourRemappingInfoPrevious != NULL)
1350        {
1351          delete seiColourRemappingInfoPrevious;
1352          seiColourRemappingInfoPrevious = NULL;
1353        }
1354        if (seiColourRemappingInfo->m_colourRemapPersistenceFlag)
1355        {
1356          seiColourRemappingInfoPrevious = new SEIColourRemappingInfo();
1357          seiColourRemappingInfoPrevious->copyFrom(seiColourRemappingInfo);
1358        }
1359      }
1360    }
1361
1362#endif
1363  }
1364  // update POC of display order
1365  pocLastDisplay = pic->getPOC();
1366
1367  // Mark as not needed for output
1368  pic->setOutputMark(false);
1369
1370  // "erase" non-referenced picture in the reference picture list after display
1371  if ( !pic->getSlice(0)->isReferenced() && pic->getReconMark() == true )
1372  {
1373    pic->setReconMark(false);
1374
1375    // mark it should be extended later
1376    pic->getPicYuvRec()->setBorderExtension( false );
1377
1378#if FIX_ALIGN_BUMPING
1379    dpbStatus.m_numPicsInSubDpb[dpbStatus.m_layerIdToSubDpbIdMap[layerId]]--;
1380#else
1381    dpbStatus.m_numPicsInSubDpb[layerIdx]--;
1382#endif
1383  }
1384}
1385
1386Void TAppDecTop::flushAllPictures(Int layerId, Bool outputPictures)
1387{
1388  // First "empty" all pictures that are not used for reference and not needed for output
1389  emptyUnusedPicturesNotNeededForOutput();
1390
1391  if( outputPictures )  // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1392  {
1393    std::vector<Int>  listOfPocs;
1394#if FIX_ALIGN_BUMPING
1395    std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1396    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1397#else
1398    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1399    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1400#endif
1401    DpbStatus dpbStatus;
1402
1403    // Find the status of the DPB
1404    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1405
1406    if( listOfPocs.size() )
1407    {
1408      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1409      {
1410        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1411      }
1412    }
1413  }
1414
1415  // Now remove all pictures from the layer DPB?
1416  markAllPicturesAsErased(layerId);
1417}
1418Void TAppDecTop::flushAllPictures(Bool outputPictures)
1419{
1420  // First "empty" all pictures that are not used for reference and not needed for output
1421  emptyUnusedPicturesNotNeededForOutput();
1422
1423  if( outputPictures )  // All pictures in the DPB are to be output
1424  {
1425    std::vector<Int>  listOfPocs;
1426#if FIX_ALIGN_BUMPING
1427    std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1428    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1429#else
1430    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1431    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1432#endif
1433    DpbStatus dpbStatus;
1434
1435    // Find the status of the DPB
1436#if POC_RESET_IDC_DECODER
1437    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, false);
1438#else
1439    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1440#endif
1441
1442    while( dpbStatus.m_numAUsNotDisplayed )
1443    {
1444      bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1445    }
1446  }
1447
1448  // Now remove all pictures from the DPB?
1449  markAllPicturesAsErased();
1450}
1451
1452Void TAppDecTop::markAllPicturesAsErased()
1453{
1454#if FIX_ALIGN_BUMPING
1455  for(Int i = 0; i < MAX_VPS_LAYER_IDX_PLUS1; i++)
1456#else
1457  for(Int i = 0; i < MAX_LAYERS; i++)
1458#endif
1459  {
1460    markAllPicturesAsErased(i);
1461  }
1462}
1463
1464Void TAppDecTop::markAllPicturesAsErased(Int layerIdx)
1465{
1466  TComList<TComPic*>::iterator  iterPic = m_acTDecTop[layerIdx].getListPic()->begin();
1467  Int iSize = Int( m_acTDecTop[layerIdx].getListPic()->size() );
1468 
1469  for (Int i = 0; i < iSize; i++ )
1470  {
1471    TComPic* pcPic = *(iterPic++);
1472
1473    if( pcPic )
1474    {
1475      pcPic->destroy();
1476
1477      // pcPic is statically created for the external (AVC) base layer, no need to delete it
1478      if( !m_acTDecTop[layerIdx].getParameterSetManager()->getActiveVPS()->getNonHEVCBaseLayerFlag() || layerIdx )
1479      {
1480        delete pcPic;
1481        pcPic = NULL;
1482      }
1483    }
1484  }
1485
1486  m_acTDecTop[layerIdx].getListPic()->clear();
1487}
1488
1489Void TAppDecTop::checkOutputBeforeDecoding(Int layerIdx)
1490{
1491   
1492  std::vector<Int>  listOfPocs;
1493#if FIX_ALIGN_BUMPING
1494  std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1495  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1496#else
1497  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1498  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1499#endif
1500  DpbStatus dpbStatus;
1501
1502  // First "empty" all pictures that are not used for reference and not needed for output
1503  emptyUnusedPicturesNotNeededForOutput();
1504
1505  // Find the status of the DPB
1506  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1507
1508  // If not picture to be output, return
1509  if( listOfPocs.size() == 0 )
1510  {
1511    return;
1512  }
1513
1514  // Find DPB-information from the VPS
1515  DpbStatus maxDpbLimit;
1516#if FIX_ALIGN_BUMPING
1517  Int subDpbIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 
1518                  ? dpbStatus.m_layerIdToSubDpbIdMap[0] 
1519                  : dpbStatus.m_layerIdToSubDpbIdMap[layerIdx];
1520#else
1521  Int subDpbIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 ? 0 : layerIdx;
1522#endif
1523  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1524  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1525  while( ifInvokeBumpingBeforeDecoding(dpbStatus, maxDpbLimit, layerIdx, subDpbIdx) )
1526  {
1527    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1528  } 
1529}
1530
1531Void TAppDecTop::checkOutputAfterDecoding()
1532{   
1533  std::vector<Int>  listOfPocs;
1534#if FIX_ALIGN_BUMPING
1535  std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1536  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1537#else
1538  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1539  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1540#endif
1541  DpbStatus dpbStatus;
1542
1543  // First "empty" all pictures that are not used for reference and not needed for output
1544  emptyUnusedPicturesNotNeededForOutput();
1545
1546  // Find the status of the DPB
1547  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
1548
1549  // If not picture to be output, return
1550  if( listOfPocs.size() == 0 )
1551  {
1552    return;
1553  }
1554
1555  // Find DPB-information from the VPS
1556  DpbStatus maxDpbLimit;
1557  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
1558
1559  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
1560  while( ifInvokeBumpingAfterDecoding(dpbStatus, maxDpbLimit) )
1561  {
1562    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1563  } 
1564}
1565
1566Void TAppDecTop::bumpingProcess(std::vector<Int> &listOfPocs, std::vector<Int> *listOfPocsInEachLayer, std::vector<Int> *listOfPocsPositionInEachLayer, DpbStatus &dpbStatus)
1567{
1568  // Choose the smallest POC value
1569  Int pocValue = *(listOfPocs.begin());
1570  std::vector<int>::iterator it;
1571  TComList<TComPic*>::iterator iterPic;
1572#if FIX_ALIGN_BUMPING
1573  for( Int dpbLayerCtr = 0; dpbLayerCtr < dpbStatus.m_numLayers; dpbLayerCtr++)
1574  {
1575    Int layerId  = dpbStatus.m_targetDecLayerIdList[dpbLayerCtr];
1576#else
1577  for( Int layerIdx = 0; layerIdx < dpbStatus.m_numLayers; layerIdx++)
1578  {
1579#endif
1580    // Check if picture with pocValue is present.
1581    it = find( listOfPocsInEachLayer[layerId].begin(), listOfPocsInEachLayer[layerId].end(), pocValue );
1582    if( it != listOfPocsInEachLayer[layerId].end() )  // picture found.
1583    {
1584      Int picPosition = (Int)std::distance( listOfPocsInEachLayer[layerId].begin(), it );
1585      Int j;
1586      for(j = 0, iterPic = m_acTDecTop[layerId].getListPic()->begin(); j < listOfPocsPositionInEachLayer[layerId][picPosition]; j++) // Picture to be output
1587      {
1588        iterPic++;
1589      }
1590      TComPic *pic = *iterPic;
1591
1592      xOutputAndMarkPic( pic, m_pchReconFile[layerId], layerId, m_aiPOCLastDisplay[layerId], dpbStatus );
1593
1594#if CONFORMANCE_BITSTREAM_MODE
1595      FILE *fptr;
1596      if( m_confModeFlag )
1597      {
1598        if( m_metadataFileRefresh )
1599        {
1600          fptr = fopen( this->getMetadataFileName().c_str(), "w" );
1601          fprintf(fptr, " LayerId      POC    MD5\n");
1602          fprintf(fptr, "------------------------\n");
1603        }
1604        else
1605        {
1606          fptr = fopen( this->getMetadataFileName().c_str(), "a+" );
1607        }
1608        this->setMetadataFileRefresh(false);
1609
1610        TComDigest recon_digest;
1611        Int numChar = calcMD5(*pic->getPicYuvRec(), recon_digest);
1612        fprintf(fptr, "%8d%9d    MD5:%s\n", pic->getLayerId(), pic->getSlice(0)->getPOC(), digestToString(recon_digest, numChar).c_str());
1613        fclose(fptr);
1614      }
1615#endif
1616
1617      listOfPocsInEachLayer[layerId].erase( it );
1618      listOfPocsPositionInEachLayer[layerId].erase( listOfPocsPositionInEachLayer[layerId].begin() + picPosition );
1619#if FIX_ALIGN_BUMPING
1620      dpbStatus.m_numPicsInSubDpb[dpbStatus.m_layerIdToSubDpbIdMap[layerId]]--;
1621#endif
1622    }
1623  }
1624#if !FIX_ALIGN_BUMPING
1625  // Update sub-DPB status
1626  for( Int subDpbIdx = 0; subDpbIdx < dpbStatus.m_numSubDpbs; subDpbIdx++)
1627  {
1628    dpbStatus.m_numPicsInSubDpb[subDpbIdx]--;
1629  }
1630#endif
1631  dpbStatus.m_numAUsNotDisplayed--;
1632
1633#if CONFORMANCE_BITSTREAM_MODE
1634  if( m_confModeFlag )
1635  {
1636    for( Int dpbLayerCtr = 0; dpbLayerCtr < dpbStatus.m_numLayers; dpbLayerCtr++)
1637    {
1638      Int layerId = dpbStatus.m_targetDecLayerIdList[dpbLayerCtr];
1639      // Output all picutres "decoded" in that layer that have POC less than the current picture
1640      std::vector<TComPic> *layerBuffer = (m_acTDecTop->getLayerDec(layerId))->getConfListPic();
1641      // Write all pictures to the file.
1642      if( this->getDecodedYuvLayerRefresh(layerId) )
1643      {
1644        m_outputBitDepth[CHANNEL_TYPE_LUMA]   = g_bitDepth[CHANNEL_TYPE_LUMA]   = g_bitDepthLayer[CHANNEL_TYPE_LUMA][layerId];
1645        m_outputBitDepth[CHANNEL_TYPE_CHROMA] = g_bitDepth[CHANNEL_TYPE_CHROMA] = g_bitDepthLayer[CHANNEL_TYPE_CHROMA][layerId];
1646
1647        char tempFileName[256];
1648        strcpy(tempFileName, this->getDecodedYuvLayerFileName( layerId ).c_str());
1649        m_confReconFile[layerId].open(tempFileName, true, m_outputBitDepth, m_outputBitDepth, g_bitDepth ); // write mode
1650        this->setDecodedYuvLayerRefresh( layerId, false );
1651      }
1652
1653      std::vector<TComPic>::iterator itPic;
1654      for(itPic = layerBuffer->begin(); itPic != layerBuffer->end(); itPic++)
1655      {
1656        TComPic checkPic = *itPic;
1657        const Window &conf = checkPic.getConformanceWindow();
1658        const Window &defDisp = m_respectDefDispWindow ? checkPic.getDefDisplayWindow() : Window();
1659        Int xScal = 1, yScal = 1;
1660  #if REPN_FORMAT_IN_VPS
1661        UInt chromaFormatIdc = checkPic.getSlice(0)->getChromaFormatIdc();
1662        xScal = TComSPS::getWinUnitX( chromaFormatIdc );
1663        yScal = TComSPS::getWinUnitY( chromaFormatIdc );
1664  #endif
1665        if( checkPic.getPOC() <= pocValue )
1666        {
1667          TComPicYuv* pPicCYuvRec = checkPic.getPicYuvRec();
1668          m_confReconFile[layerId].write( pPicCYuvRec, m_outputColourSpaceConvert,
1669            conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
1670            conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
1671            conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
1672            conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
1673          layerBuffer->erase(itPic);
1674          itPic = layerBuffer->begin();  // Ensure doesn't go to infinite loop
1675          if(layerBuffer->size() == 0)
1676          {
1677            break;
1678          }
1679        }
1680      }
1681    }
1682  }
1683#endif
1684
1685  // Remove the picture from the listOfPocs
1686  listOfPocs.erase( listOfPocs.begin() );
1687}
1688
1689TComVPS *TAppDecTop::findDpbParametersFromVps(std::vector<Int> const &listOfPocs, std::vector<Int> const *listOfPocsInEachLayer, std::vector<Int> const *listOfPocsPositionInEachLayer, DpbStatus &maxDpbLimit)
1690{
1691  Int targetOutputLsIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx();
1692  TComVPS *vps = NULL;
1693
1694  if( targetOutputLsIdx == 0 )   // Only base layer is output
1695  {
1696    TComSPS *sps = NULL;
1697    assert( listOfPocsInEachLayer[0].size() != 0 );
1698    TComList<TComPic*>::iterator iterPic;
1699    Int j;
1700    for(j = 0, iterPic = m_acTDecTop[0].getListPic()->begin(); j < listOfPocsPositionInEachLayer[0][0]; j++) // Picture to be output
1701    {
1702      iterPic++;
1703    }
1704    TComPic *pic = *iterPic;
1705    sps = pic->getSlice(0)->getSPS();   assert( sps->getLayerId() == 0 );
1706    vps = pic->getSlice(0)->getVPS();
1707    Int highestTId = sps->getMaxTLayers() - 1;
1708
1709    maxDpbLimit.m_numAUsNotDisplayed = sps->getNumReorderPics( highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1710    maxDpbLimit.m_maxLatencyIncrease = sps->getMaxLatencyIncrease( highestTId ) > 0;
1711    if( maxDpbLimit.m_maxLatencyIncrease )
1712    {
1713      maxDpbLimit.m_maxLatencyPictures = sps->getMaxLatencyIncrease( highestTId ) + sps->getNumReorderPics( highestTId ) - 1;
1714    }
1715    maxDpbLimit.m_numPicsInSubDpb[0] = sps->getMaxDecPicBuffering( highestTId );
1716  }
1717  else
1718  {
1719    // -------------------------------------
1720    // Find the VPS used for the pictures
1721    // -------------------------------------
1722#if FIX_ALIGN_BUMPING
1723    for(Int i = 0; i < MAX_VPS_LAYER_IDX_PLUS1; i++)
1724#else
1725    for(Int i = 0; i < MAX_LAYERS; i++)
1726#endif
1727    {
1728      if( m_acTDecTop[i].getListPic()->empty() )
1729      {
1730        assert( listOfPocsInEachLayer[i].size() == 0 );
1731        continue;
1732      }
1733      std::vector<Int>::const_iterator it;
1734      it = find( listOfPocsInEachLayer[i].begin(), listOfPocsInEachLayer[i].end(), listOfPocs[0] );
1735      TComList<TComPic*>::iterator iterPic;
1736      if( it != listOfPocsInEachLayer[i].end() )
1737      {
1738        Int picPosition = (Int)std::distance( listOfPocsInEachLayer[i].begin(), it );
1739        Int j;
1740        for(j = 0, iterPic = m_acTDecTop[i].getListPic()->begin(); j < listOfPocsPositionInEachLayer[i][picPosition]; j++) // Picture to be output
1741        {
1742          iterPic++;
1743        }
1744        TComPic *pic = *iterPic;
1745        vps = pic->getSlice(0)->getVPS();
1746        break;
1747      }
1748    }
1749
1750    Int targetLsIdx       = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1751    Int highestTId = vps->getMaxTLayers() - 1;
1752
1753    maxDpbLimit.m_numAUsNotDisplayed = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
1754    maxDpbLimit.m_maxLatencyIncrease  = vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) > 0;
1755    if( maxDpbLimit.m_maxLatencyIncrease )
1756    {
1757      maxDpbLimit.m_maxLatencyPictures = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ) + vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) - 1;
1758    }
1759    for(Int i = 0; i < vps->getNumLayersInIdList( targetLsIdx ); i++)
1760    {
1761#if RESOUTION_BASED_DPB
1762      maxDpbLimit.m_numPicsInLayer[i] = vps->getMaxVpsLayerDecPicBuffMinus1( targetOutputLsIdx, i, highestTId ) + 1;
1763      maxDpbLimit.m_numPicsInSubDpb[vps->getSubDpbAssigned( targetLsIdx, i )] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, vps->getSubDpbAssigned( targetLsIdx, i ), highestTId) + 1;
1764#else
1765      maxDpbLimit.m_numPicsInSubDpb[i] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, i, highestTId) + 1;
1766#endif
1767    }
1768    // -------------------------------------
1769  }
1770  return vps;
1771}
1772Void TAppDecTop::emptyUnusedPicturesNotNeededForOutput()
1773{
1774#if FIX_ALIGN_BUMPING
1775  for(Int layerIdx = 0; layerIdx < MAX_VPS_LAYER_IDX_PLUS1; layerIdx++)
1776#else
1777  for(Int layerIdx = 0; layerIdx < MAX_LAYERS; layerIdx++)
1778#endif
1779  {
1780    TComList <TComPic*> *pcListPic = m_acTDecTop[layerIdx].getListPic();
1781    TComList<TComPic*>::iterator iterPic = pcListPic->begin();
1782    while ( iterPic != pcListPic->end() )
1783    {
1784      TComPic *pic = *iterPic;
1785      if( !pic->getSlice(0)->isReferenced() && !pic->getOutputMark() )
1786      {
1787        // Emtpy the picture buffer
1788        pic->setReconMark( false );
1789      }
1790      iterPic++;
1791    }
1792  }
1793}
1794
1795Bool TAppDecTop::ifInvokeBumpingBeforeDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit, const Int layerIdx, const Int subDpbIdx )
1796{
1797  Bool retVal = false;
1798  // Number of reorder picutres
1799  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1800
1801  // Number of pictures in each sub-DPB
1802  retVal |= ( dpbStatus.m_numPicsInSubDpb[subDpbIdx] >= dpbLimit.m_numPicsInSubDpb[subDpbIdx] );
1803
1804  return retVal;
1805}
1806
1807Bool TAppDecTop::ifInvokeBumpingAfterDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit )
1808{
1809  Bool retVal = false;
1810
1811  // Number of reorder picutres
1812  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
1813
1814  return retVal;
1815}
1816
1817Void TAppDecTop::xFindDPBStatus( std::vector<Int> &listOfPocs
1818                            , std::vector<Int> *listOfPocsInEachLayer
1819                            , std::vector<Int> *listOfPocsPositionInEachLayer
1820                            , DpbStatus &dpbStatus
1821#if POC_RESET_IDC_DECODER
1822                            , Bool notOutputCurrAu
1823#endif
1824                            )
1825{
1826  TComVPS *vps = NULL;
1827  dpbStatus.init();
1828#if FIX_ALIGN_BUMPING
1829  for( Int i = 0; i < MAX_VPS_LAYER_IDX_PLUS1; i++ )
1830#else
1831  for( Int i = 0; i < MAX_LAYERS; i++ )
1832#endif
1833  {
1834    if( m_acTDecTop[i].getListPic()->empty() )
1835    {
1836      continue;
1837    }
1838   
1839    // To check # AUs that have at least one picture not output,
1840    // For each layer, populate listOfPOcs if not already present
1841    TComList<TComPic*>::iterator iterPic = m_acTDecTop[i].getListPic()->begin();
1842    Int picPositionInList = 0;
1843    while (iterPic != m_acTDecTop[i].getListPic()->end())
1844    {
1845      TComPic* pic = *(iterPic);
1846      if( pic->getReconMark() )
1847      {
1848        if( vps == NULL )
1849        {
1850          vps = pic->getSlice(0)->getVPS();
1851        }
1852#if POC_RESET_IDC_DECODER
1853        if( !(pic->isCurrAu() && notOutputCurrAu ) )
1854        {
1855#endif
1856          std::vector<Int>::iterator it;
1857          if( pic->getOutputMark() ) // && pic->getPOC() > m_aiPOCLastDisplay[i])
1858          {
1859            it = find( listOfPocs.begin(), listOfPocs.end(), pic->getPOC() ); // Check if already included
1860            if( it == listOfPocs.end() )  // New POC value - i.e. new AU - add to the list
1861            {
1862              listOfPocs.push_back( pic->getPOC() );
1863            }
1864            listOfPocsInEachLayer         [i].push_back( pic->getPOC()    );    // POC to be output in each layer
1865            listOfPocsPositionInEachLayer [i].push_back( picPositionInList  );  // For ease of access
1866          }
1867          if( pic->getSlice(0)->isReferenced() || pic->getOutputMark() )
1868          {
1869            dpbStatus.m_numPicsInSubDpb[i]++;  // Count pictures that are "used for reference" or "needed for output"
1870          }
1871#if POC_RESET_IDC_DECODER
1872        }
1873#endif
1874      }
1875      iterPic++;
1876      picPositionInList++;
1877    }
1878  }
1879
1880  assert( vps != NULL );    // No picture in any DPB?
1881  std::sort( listOfPocs.begin(), listOfPocs.end() );    // Sort in increasing order of POC
1882  Int targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
1883  // Update status
1884  dpbStatus.m_numAUsNotDisplayed = (Int)listOfPocs.size();   // Number of AUs not displayed
1885  dpbStatus.m_numLayers = vps->getNumLayersInIdList( targetLsIdx );
1886#if FIX_ALIGN_BUMPING
1887  for(Int i = 0; i < dpbStatus.m_numLayers; i++)
1888  {
1889    dpbStatus.m_layerIdToSubDpbIdMap[vps->getLayerSetLayerIdList(targetLsIdx, i)] = i;
1890    dpbStatus.m_targetDecLayerIdList[i] = vps->getLayerSetLayerIdList(targetLsIdx, i);  // Layer Id stored in a particular sub-DPB
1891  }
1892  dpbStatus.m_numSubDpbs = vps->getNumSubDpbs( targetLsIdx ); 
1893#else
1894  dpbStatus.m_numSubDpbs = vps->getNumSubDpbs( vps->getOutputLayerSetIdx(
1895                                                      this->getCommonDecoderParams()->getTargetOutputLayerSetIdx() ) );
1896#endif
1897
1898#if FIX_ALIGN_BUMPING
1899  for(Int i = 0; i < MAX_VPS_LAYER_IDX_PLUS1; i++)
1900#else
1901  for(Int i = 0; i < dpbStatus.m_numLayers; i++)
1902#endif
1903  {
1904    dpbStatus.m_numPicsNotDisplayedInLayer[i] = (Int)listOfPocsInEachLayer[i].size();
1905  }
1906  assert( dpbStatus.m_numAUsNotDisplayed != -1 );
1907} 
1908
1909#if POC_RESET_IDC_DECODER
1910Void TAppDecTop::outputAllPictures(Int layerId, Bool notOutputCurrPic)
1911{
1912  { // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
1913    std::vector<Int>  listOfPocs;
1914#if FIX_ALIGN_BUMPING
1915    std::vector<Int>  listOfPocsInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1916    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_VPS_LAYER_IDX_PLUS1];
1917#else
1918    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
1919    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
1920#endif
1921    DpbStatus dpbStatus;
1922
1923    // Find the status of the DPB
1924    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, notOutputCurrPic);
1925
1926    if( listOfPocs.size() )
1927    {
1928      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
1929      {
1930        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
1931      }
1932    }
1933  }
1934}
1935#endif
1936#endif
1937
1938#if Q0074_COLOUR_REMAPPING_SEI
1939Void xInitColourRemappingLut( const Int bitDepthY, const Int bitDepthC, std::vector<Int>(&preLut)[3], std::vector<Int>(&postLut)[3], const SEIColourRemappingInfo* const pCriSEI )
1940{
1941  for ( Int c=0 ; c<3 ; c++ )
1942  { 
1943    Int bitDepth = c ? bitDepthC : bitDepthY ;
1944    preLut[c].resize(1 << bitDepth);
1945    postLut[c].resize(1 << pCriSEI->m_colourRemapBitDepth);
1946   
1947    Int bitDepthDiff = pCriSEI->m_colourRemapBitDepth - bitDepth;
1948    Int iShift1 = (bitDepthDiff>0) ? bitDepthDiff : 0; //bit scale from bitdepth to ColourRemapBitdepth (manage only case colourRemapBitDepth>= bitdepth)
1949    if( bitDepthDiff<0 )
1950      printf ("Warning: CRI SEI - colourRemapBitDepth (%d) <bitDepth (%d) - case not handled\n", pCriSEI->m_colourRemapBitDepth, bitDepth);
1951    bitDepthDiff = pCriSEI->m_colourRemapBitDepth - pCriSEI->m_colourRemapInputBitDepth;
1952    Int iShift2 = (bitDepthDiff>0) ? bitDepthDiff : 0; //bit scale from ColourRemapInputBitdepth to ColourRemapBitdepth (manage only case colourRemapBitDepth>= colourRemapInputBitDepth)
1953    if( bitDepthDiff<0 )
1954      printf ("Warning: CRI SEI - colourRemapBitDepth (%d) <colourRemapInputBitDepth (%d) - case not handled\n", pCriSEI->m_colourRemapBitDepth, pCriSEI->m_colourRemapInputBitDepth);
1955
1956    //Fill preLut
1957    for ( Int k=0 ; k<(1<<bitDepth) ; k++ )
1958    {
1959      Int iSample = k << iShift1 ;
1960      for ( Int iPivot=0 ; iPivot<=pCriSEI->m_preLutNumValMinus1[c] ; iPivot++ )
1961      {
1962        Int iCodedPrev  = pCriSEI->m_preLutCodedValue[c][iPivot]    << iShift2; //Coded in CRInputBitdepth
1963        Int iCodedNext  = pCriSEI->m_preLutCodedValue[c][iPivot+1]  << iShift2; //Coded in CRInputBitdepth
1964        Int iTargetPrev = pCriSEI->m_preLutTargetValue[c][iPivot];              //Coded in CRBitdepth
1965        Int iTargetNext = pCriSEI->m_preLutTargetValue[c][iPivot+1];            //Coded in CRBitdepth
1966        if ( iCodedPrev <= iSample && iSample <= iCodedNext )
1967        {
1968          Float fInterpol = (Float)( (iCodedNext - iSample)*iTargetPrev + (iSample - iCodedPrev)*iTargetNext ) * 1.f / (Float)(iCodedNext - iCodedPrev);
1969          preLut[c][k]  = (Int)( 0.5f + fInterpol );
1970          iPivot = pCriSEI->m_preLutNumValMinus1[c] + 1;
1971        }
1972      }
1973    }
1974   
1975    //Fill postLut
1976    for ( Int k=0 ; k<(1<<pCriSEI->m_colourRemapBitDepth) ; k++ )
1977    {
1978      Int iSample = k;
1979      for ( Int iPivot=0 ; iPivot<=pCriSEI->m_postLutNumValMinus1[c] ; iPivot++ )
1980      {
1981        Int iCodedPrev  = pCriSEI->m_postLutCodedValue[c][iPivot];    //Coded in CRBitdepth
1982        Int iCodedNext  = pCriSEI->m_postLutCodedValue[c][iPivot+1];  //Coded in CRBitdepth
1983        Int iTargetPrev = pCriSEI->m_postLutTargetValue[c][iPivot];   //Coded in CRBitdepth
1984        Int iTargetNext = pCriSEI->m_postLutTargetValue[c][iPivot+1]; //Coded in CRBitdepth
1985        if ( iCodedPrev <= iSample && iSample <= iCodedNext )
1986        {
1987          Float fInterpol =  (Float)( (iCodedNext - iSample)*iTargetPrev + (iSample - iCodedPrev)*iTargetNext ) * 1.f / (Float)(iCodedNext - iCodedPrev) ;
1988          postLut[c][k]  = (Int)( 0.5f + fInterpol );
1989          iPivot = pCriSEI->m_postLutNumValMinus1[c] + 1;
1990        }
1991      }
1992    }
1993  }
1994}
1995
1996static void applyColourRemapping(TComPicYuv& pic, const SEIColourRemappingInfo* pCriSEI, UInt layerId )
1997{ 
1998  if( !storeCriSEI.size() )
1999#if SVC_EXTENSION
2000    storeCriSEI.resize(MAX_LAYERS);
2001#else
2002    storeCriSEI.resize(1);
2003#endif
2004
2005  if ( pCriSEI ) //if a CRI SEI has just been retrieved, keep it in memory (persistence management)
2006    storeCriSEI[layerId] = *pCriSEI;
2007
2008  if( !storeCriSEI[layerId].m_colourRemapCancelFlag && pCriSEI) 
2009  {
2010    Int iHeight  = pic.getHeight(COMPONENT_Y);
2011    Int iWidth   = pic.getWidth(COMPONENT_Y);
2012    Int iStride  = pic.getStride(COMPONENT_Y);
2013    Int iCStride = pic.getStride(COMPONENT_Cb);
2014
2015    Pel *YUVIn[3], *YUVOut[3];
2016    YUVIn[0] = pic.getAddr(COMPONENT_Y);
2017    YUVIn[1] = pic.getAddr(COMPONENT_Cb);
2018    YUVIn[2] = pic.getAddr(COMPONENT_Cr);
2019   
2020    TComPicYuv picColourRemapped;
2021#if SVC_EXTENSION
2022#if AUXILIARY_PICTURES
2023    picColourRemapped.create( pic.getWidth(COMPONENT_Y), pic.getHeight(COMPONENT_Y), pic.getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL );
2024#else
2025    picColourRemapped.create( pic.getWidth(), pic.getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL );
2026#endif
2027#else
2028    picColourRemapped.create( pic.getWidth(COMPONENT_Y), pic.getHeight(COMPONENT_Y), pic.getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
2029#endif
2030    YUVOut[0] = picColourRemapped.getAddr(COMPONENT_Y);
2031    YUVOut[1] = picColourRemapped.getAddr(COMPONENT_Cb);
2032    YUVOut[2] = picColourRemapped.getAddr(COMPONENT_Cr);
2033
2034#if SVC_EXTENSION
2035    Int bitDepthY = g_bitDepthLayer[CHANNEL_TYPE_LUMA][layerId];
2036    Int bitDepthC = g_bitDepthLayer[CHANNEL_TYPE_CHROMA][layerId];
2037
2038#else
2039    Int bitDepthY = g_bitDepth[CHANNEL_TYPE_LUMA];
2040    Int bitDepthC = g_bitDepth[CHANNEL_TYPE_CHROMA];
2041#endif
2042
2043    std::vector<Int> preLut[3];
2044    std::vector<Int> postLut[3];
2045    xInitColourRemappingLut( bitDepthY, bitDepthC, preLut, postLut, &storeCriSEI[layerId] );
2046   
2047    Int roundingOffset = (storeCriSEI[layerId].m_log2MatrixDenom==0) ? 0 : (1 << (storeCriSEI[layerId].m_log2MatrixDenom - 1));
2048
2049    for( Int y = 0; y < iHeight ; y++ )
2050    {
2051      for( Int x = 0; x < iWidth ; x++ )
2052      {
2053        Int YUVPre[3], YUVMat[3];
2054        YUVPre[0] = preLut[0][ YUVIn[0][x]   ];
2055        YUVPre[1] = preLut[1][ YUVIn[1][x>>1] ];
2056        YUVPre[2] = preLut[2][ YUVIn[2][x>>1] ];
2057
2058        YUVMat[0] = ( storeCriSEI[layerId].m_colourRemapCoeffs[0][0]*YUVPre[0]
2059                    + storeCriSEI[layerId].m_colourRemapCoeffs[0][1]*YUVPre[1] 
2060                    + storeCriSEI[layerId].m_colourRemapCoeffs[0][2]*YUVPre[2] 
2061                    + roundingOffset ) >> ( storeCriSEI[layerId].m_log2MatrixDenom );
2062        YUVMat[0] = Clip3( 0, (1<<storeCriSEI[layerId].m_colourRemapBitDepth)-1, YUVMat[0] );
2063        YUVOut[0][x] = postLut[0][ YUVMat[0] ];
2064
2065        if( (y&1) && (x&1) )
2066        {
2067          for(Int c=1 ; c<3 ; c++)
2068          {
2069            YUVMat[c] = ( storeCriSEI[layerId].m_colourRemapCoeffs[c][0]*YUVPre[0] 
2070                        + storeCriSEI[layerId].m_colourRemapCoeffs[c][1]*YUVPre[1] 
2071                        + storeCriSEI[layerId].m_colourRemapCoeffs[c][2]*YUVPre[2] 
2072                        + roundingOffset ) >> ( storeCriSEI[layerId].m_log2MatrixDenom );
2073            YUVMat[c] = Clip3( 0, (1<<storeCriSEI[layerId].m_colourRemapBitDepth)-1, YUVMat[c] );
2074            YUVOut[c][x>>1] = postLut[c][ YUVMat[c] ];   
2075          }
2076        }
2077      }
2078      YUVIn[0]  += iStride;
2079      YUVOut[0] += iStride;
2080      if( y&1 )
2081      {
2082        YUVIn[1]  += iCStride;
2083        YUVIn[2]  += iCStride;
2084        YUVOut[1] += iCStride;
2085        YUVOut[2] += iCStride;
2086      }
2087    }
2088
2089    //Write remapped picture in decoding order
2090    Char  cTemp[255];
2091    sprintf(cTemp, "seiColourRemappedPic_L%d_%dx%d_%dbits.yuv", layerId, iWidth, iHeight, storeCriSEI[layerId].m_colourRemapBitDepth );
2092    picColourRemapped.dump( cTemp, true, storeCriSEI[layerId].m_colourRemapBitDepth );
2093
2094    picColourRemapped.destroy();
2095
2096    storeCriSEI[layerId].m_colourRemapCancelFlag = !storeCriSEI[layerId].m_colourRemapPersistenceFlag; //Handling persistence
2097  }
2098  else
2099  {
2100    //Write no remapped picture in decoding order
2101    if (storeCriSEI[layerId].m_colourRemapBitDepth == 8 || storeCriSEI[layerId].m_colourRemapBitDepth == 10)
2102    {
2103      Char  cTemp[255];
2104      sprintf(cTemp, "seiColourRemappedPic_L%d_%dx%d_%dbits.yuv", layerId, pic.getWidth(COMPONENT_Y), pic.getHeight(COMPONENT_Y), storeCriSEI[layerId].m_colourRemapBitDepth );
2105      pic.dump( cTemp, true, storeCriSEI[layerId].m_colourRemapBitDepth );
2106    }
2107  }
2108}
2109#endif
2110//! \}
Note: See TracBrowser for help on using the repository browser.