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

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

Patch provided by Hiron Franck <franck.hiron@…> to complete implementation of the CRI (Colour remapping info) with the following features:

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