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

Last change on this file since 1129 was 1116, checked in by seregin, 9 years ago

macro cleanup: VPS_AVC_BL_FLAG_REMOVAL

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