source: 3DVCSoftware/trunk/source/App/TAppDecoder/TAppDecTop.cpp @ 1413

Last change on this file since 1413 was 1413, checked in by tech, 6 years ago

Merged HTM-16.2-dev@1412

  • Property svn:eol-style set to native
File size: 127.9 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-2017, 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
51//! \ingroup TAppDecoder
52//! \{
53
54// ====================================================================================================================
55// Constructor / destructor / initialization / destroy
56// ====================================================================================================================
57
58TAppDecTop::TAppDecTop()
59#if !NH_MV
60: m_iPOCLastDisplay(-MAX_INT)
61#else
62: m_numDecoders( 0 )
63#endif
64 ,m_pcSeiColourRemappingInfoPrevious(NULL)
65{
66#if NH_MV
67  for (Int i = 0; i < MAX_NUM_LAYER_IDS; i++)
68  {
69    m_layerIdToDecIdx                     [i] = -1;
70    m_layerInitilizedFlag                 [i] = false;
71    m_eosInLayer                          [i] = false;
72    m_firstPicInLayerDecodedFlag          [i] = false;
73    m_pocDecrementedInDpbFlag             [i] = false;
74    m_decodingOrder                       [i] = 0;
75    m_lastPresentPocResetIdc              [i] = MIN_INT;
76    m_firstPicInPocResettingPeriodReceived[i] = true;
77    m_noRaslOutputFlagAssocIrap           [i] = false;
78  }
79
80  m_curPic                          = NULL;
81  m_vps                             = NULL;
82  m_sps                             = NULL;
83  m_pps                             = NULL;
84  m_initilizedFromVPS               = false;
85  m_firstSliceInBitstream           = true;
86  m_newVpsActivatedbyCurAu          = false;
87  m_newVpsActivatedbyCurPic         = false;
88  m_handleCraAsBlaFlag              = false;
89  m_handleCraAsBlaFlagSetByExtMeans = false;
90  m_noClrasOutputFlag               = false;
91  m_noClrasOutputFlagSetByExtMeans  = false;
92  m_layerResetFlag                  = false;
93  m_totalNumofPicsReceived          = 0;
94  m_cvsStartFound                   = false;
95#endif
96#if NH_3D
97    m_pScaleOffsetFile              = 0;
98#endif
99}
100
101Void TAppDecTop::create()
102{
103#if NH_MV
104#if ENC_DEC_TRACE
105  if ( g_hTrace == NULL )
106  {
107    g_hTrace = fopen( "TraceDec.txt", "wb" );
108    g_bJustDoIt = g_bEncDecTraceDisable;
109    g_nSymbolCounter = 0;
110  }
111#endif
112#endif
113}
114
115Void TAppDecTop::destroy()
116{
117#if NH_MV
118  // destroy internal classes
119  xDestroyDecLib();
120#endif
121  m_bitstreamFileName.clear();
122#if NH_MV
123  for (Int decIdx = 0; decIdx < m_numDecoders; decIdx++)
124  {
125    if (m_pchReconFiles[decIdx])
126    {
127      free (m_pchReconFiles[decIdx]);
128      m_pchReconFiles[decIdx] = NULL;
129    }
130  }
131#endif
132  m_reconFileName.clear();
133#if NH_3D
134  if (m_pchScaleOffsetFile)
135  {
136    free (m_pchScaleOffsetFile);
137    m_pchScaleOffsetFile = NULL;
138  }
139#endif
140}
141
142// ====================================================================================================================
143// Public member functions
144// ====================================================================================================================
145
146/**
147 - create internal class
148 - initialize internal class
149 - until the end of the bitstream, call decoding function in TDecTop class
150 - delete allocated buffers
151 - destroy internal class
152 .
153 */
154#if NH_MV
155Void TAppDecTop::decode( Int num )
156{
157  m_targetOptLayerSetIdx = m_targetOptLayerSetInd[ num ]; 
158  // create & initialize internal classes
159  xInitFileIO  ();
160  xCreateDecLib();
161  xInitDecLib  ();
162
163  InputByteStream bytestream(m_bitstreamFile);
164
165  while ( m_bitstreamFile )
166  {
167    AnnexBStats stats = AnnexBStats();
168    InputNALUnit nalu;
169
170    byteStreamNALUnit(bytestream, nalu.getBitstream().getFifo(), stats);
171
172    if (nalu.getBitstream().getFifo().empty())
173    {
174      /* this can happen if the following occur:
175       *  - empty input file
176       *  - two back-to-back start_code_prefixes
177       *  - start_code_prefix immediately followed by EOF
178       */
179      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
180    }
181    else
182    {
183      read(nalu);
184
185      if ( m_printReceivedNalus )
186      {
187        std::cout << "Received NAL unit: ";
188        nalu.print();
189        std::cout << std::endl;
190      }
191
192      if ( xExtractAndRewrite( &nalu )
193          && nalu.m_nuhLayerId <= MAX_NUM_LAYER_IDS-1
194          && !(nalu.m_nalUnitType == NAL_UNIT_VPS && nalu.m_nuhLayerId > 0)
195          && !(nalu.m_nalUnitType == NAL_UNIT_EOB && nalu.m_nuhLayerId > 0)
196         )
197      {
198        xGetDecoderIdx( nalu.m_nuhLayerId , true );
199        if( nalu.isSlice() )
200        {
201          xProcessVclNalu   ( nalu );
202        }
203        else
204        {
205          xProcessNonVclNalu( nalu );
206        }
207      }
208    }
209  }
210 xTerminateDecoding();
211}
212#endif
213
214#if !NH_MV
215Void TAppDecTop::decode( )
216{
217  Int                 poc;
218  TComList<TComPic*>* pcListPic = NULL;
219
220  ifstream bitstreamFile(m_bitstreamFileName.c_str(), ifstream::in | ifstream::binary);
221  if (!bitstreamFile)
222  {
223    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_bitstreamFileName.c_str());
224    exit(EXIT_FAILURE);
225  }
226
227  InputByteStream bytestream(bitstreamFile);
228
229  if (!m_outputDecodedSEIMessagesFilename.empty() && m_outputDecodedSEIMessagesFilename!="-")
230  {
231    m_seiMessageFileStream.open(m_outputDecodedSEIMessagesFilename.c_str(), std::ios::out);
232    if (!m_seiMessageFileStream.is_open() || !m_seiMessageFileStream.good())
233    {
234      fprintf(stderr, "\nUnable to open file `%s' for writing decoded SEI messages\n", m_outputDecodedSEIMessagesFilename.c_str());
235      exit(EXIT_FAILURE);
236    }
237  }
238
239  // create & initialize internal classes
240  xCreateDecLib();
241  xInitDecLib  ();
242
243  m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
244
245  // clear contents of colour-remap-information-SEI output file
246  if (!m_colourRemapSEIFileName.empty())
247  {
248    std::ofstream ofile(m_colourRemapSEIFileName.c_str());
249    if (!ofile.good() || !ofile.is_open())
250    {
251      fprintf(stderr, "\nUnable to open file '%s' for writing colour-remap-information-SEI video\n", m_colourRemapSEIFileName.c_str());
252      exit(EXIT_FAILURE);
253    }
254  }
255
256  // main decoder loop
257  Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
258  Bool loopFiltered = false;
259
260  while (!!bitstreamFile)
261  {
262    /* location serves to work around a design fault in the decoder, whereby
263     * the process of reading a new slice that is the first slice of a new frame
264     * requires the TDecTop::decode() method to be called again with the same
265     * nal unit. */
266#if RExt__DECODER_DEBUG_BIT_STATISTICS
267    TComCodingStatistics::TComCodingStatisticsData backupStats(TComCodingStatistics::GetStatistics());
268    streampos location = bitstreamFile.tellg() - streampos(bytestream.GetNumBufferedBytes());
269#else
270    streampos location = bitstreamFile.tellg();
271#endif
272    AnnexBStats stats = AnnexBStats();
273
274    InputNALUnit nalu;
275    byteStreamNALUnit(bytestream, nalu.getBitstream().getFifo(), stats);
276
277    // call actual decoding function
278    Bool bNewPicture = false;
279    if (nalu.getBitstream().getFifo().empty())
280    {
281      /* this can happen if the following occur:
282       *  - empty input file
283       *  - two back-to-back start_code_prefixes
284       *  - start_code_prefix immediately followed by EOF
285       */
286      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
287    }
288    else
289    {
290      read(nalu);
291
292      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
293      {
294        bNewPicture = false;
295      }
296      else
297      {
298        bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
299        if (bNewPicture)
300        {
301          bitstreamFile.clear();
302          /* location points to the current nalunit payload[1] due to the
303           * need for the annexB parser to read three extra bytes.
304           * [1] except for the first NAL unit in the file
305           *     (but bNewPicture doesn't happen then) */
306#if RExt__DECODER_DEBUG_BIT_STATISTICS
307          bitstreamFile.seekg(location);
308          bytestream.reset();
309          TComCodingStatistics::SetStatistics(backupStats);
310#else
311          bitstreamFile.seekg(location-streamoff(3));
312          bytestream.reset();
313#endif
314        }
315      }
316    }
317
318    if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) &&
319
320      !m_cTDecTop.getFirstSliceInSequence () )
321
322    {
323      if (!loopFiltered || bitstreamFile)
324      {
325        m_cTDecTop.executeLoopFilters(poc, pcListPic);
326      }
327      loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
328      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
329      {
330        m_cTDecTop.setFirstSliceInSequence(true);
331      }
332    }
333    else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) &&
334              m_cTDecTop.getFirstSliceInSequence () )
335    {
336      m_cTDecTop.setFirstSliceInPicture (true);
337   }
338
339    if( pcListPic )
340    {
341      if ( (!m_reconFileName.empty()) && (!openedReconFile) )
342      {
343        const BitDepths &bitDepths=pcListPic->front()->getPicSym()->getSPS().getBitDepths(); // use bit depths of first reconstructed picture.
344        for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
345        {
346          if (m_outputBitDepth[channelType] == 0)
347          {
348            m_outputBitDepth[channelType] = bitDepths.recon[channelType];
349          }
350        }
351
352        m_cTVideoIOYuvReconFile.open( m_reconFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon ); // write mode
353        openedReconFile = true;
354      }
355      // write reconstruction to file
356      if( bNewPicture )
357      {
358        xWriteOutput( pcListPic, nalu.m_temporalId );
359      }
360      if ( (bNewPicture || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) && m_cTDecTop.getNoOutputPriorPicsFlag() )
361      {
362        m_cTDecTop.checkNoOutputPriorPics( pcListPic );
363        m_cTDecTop.setNoOutputPriorPicsFlag (false);
364      }
365
366      if ( bNewPicture &&
367           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
368            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
369            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
370            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
371            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
372      {
373
374        xFlushOutput( pcListPic );
375      }
376      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
377      {
378
379        xWriteOutput( pcListPic, nalu.m_temporalId );
380        m_cTDecTop.setFirstSliceInPicture (false);
381      }
382      // write reconstruction to file -- for additional bumping as defined in C.5.2.3
383      if(!bNewPicture && nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL_N && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL31)
384      {
385        xWriteOutput( pcListPic, nalu.m_temporalId );
386      }
387    }
388  }
389
390  xFlushOutput( pcListPic );
391  // delete buffers
392  m_cTDecTop.deletePicBuffer();
393  // destroy internal classes
394  xDestroyDecLib();
395}
396#endif
397
398// ====================================================================================================================
399// Protected member functions
400// ====================================================================================================================
401
402Void TAppDecTop::xCreateDecLib()
403{
404#if NH_MV
405  // initialize global variables
406  initROM();
407#if NH_3D
408  initWedgeLists();
409#endif
410#else
411  // create decoder class
412  m_cTDecTop.create();
413#endif
414}
415
416Void TAppDecTop::xDestroyDecLib()
417{
418#if NH_MV
419  // destroy ROM
420  destroyROM();
421
422  for(Int decIdx = 0; decIdx < m_numDecoders ; decIdx++)
423  {
424    if( m_tVideoIOYuvReconFile[decIdx] )
425    {
426      m_tVideoIOYuvReconFile[decIdx]->close();
427      delete m_tVideoIOYuvReconFile[decIdx];
428      m_tVideoIOYuvReconFile[decIdx] = NULL ;
429    }
430
431    if( m_tDecTop[decIdx] )
432    {
433#if !NH_MV
434      m_tDecTop[decIdx]->deletePicBuffer();
435#endif
436      m_tDecTop[decIdx]->destroy() ;
437    }
438    delete m_tDecTop[decIdx] ;
439    m_tDecTop[decIdx] = NULL ;
440  }
441#else
442  if ( !m_reconFileName.empty() )
443  {
444    m_cTVideoIOYuvReconFile. close();
445  }
446
447  // destroy decoder class
448  m_cTDecTop.destroy();
449#endif
450  if (m_pcSeiColourRemappingInfoPrevious != NULL)
451  {
452    delete m_pcSeiColourRemappingInfoPrevious;
453    m_pcSeiColourRemappingInfoPrevious = NULL;
454  }
455#if NH_3D
456  m_cCamParsCollector.uninit();
457  if( m_pScaleOffsetFile )
458  {
459    ::fclose( m_pScaleOffsetFile );
460  }
461#endif
462}
463
464Void TAppDecTop::xInitDecLib()
465{
466
467#if NH_3D
468  m_cCamParsCollector.setCodeScaleOffsetFile( m_pScaleOffsetFile );
469#endif
470#if NH_MV
471  m_dpb.setPrintPicOutput(m_printPicOutput);
472#else
473  // initialize decoder class
474  m_cTDecTop.init();
475  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
476#if MCTS_ENC_CHECK
477  m_cTDecTop.setTMctsCheckEnabled(m_tmctsCheck);
478#endif
479#if O0043_BEST_EFFORT_DECODING
480  m_cTDecTop.setForceDecodeBitDepth(m_forceDecodeBitDepth);
481#endif
482  if (!m_outputDecodedSEIMessagesFilename.empty())
483  {
484    std::ostream &os=m_seiMessageFileStream.is_open() ? m_seiMessageFileStream : std::cout;
485    m_cTDecTop.setDecodedSEIMessageOutputStream(&os);
486  }
487#endif
488  if (m_pcSeiColourRemappingInfoPrevious != NULL)
489  {
490    delete m_pcSeiColourRemappingInfoPrevious;
491    m_pcSeiColourRemappingInfoPrevious = NULL;
492  }
493}
494
495
496#if !NH_MV
497/** \param pcListPic list of pictures to be written to file
498    \param tId       temporal sub-layer ID
499 */
500Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
501{
502  if (pcListPic->empty())
503  {
504    return;
505  }
506
507  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
508  Int numPicsNotYetDisplayed = 0;
509  Int dpbFullness = 0;
510  const TComSPS* activeSPS = &(pcListPic->front()->getPicSym()->getSPS());
511
512  UInt numReorderPicsHighestTid;
513  UInt maxDecPicBufferingHighestTid;
514  UInt maxNrSublayers = activeSPS->getMaxTLayers();
515
516  if(m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers)
517  {
518    numReorderPicsHighestTid = activeSPS->getNumReorderPics(maxNrSublayers-1);
519    maxDecPicBufferingHighestTid =  activeSPS->getMaxDecPicBuffering(maxNrSublayers-1);
520  }
521  else
522  {
523    numReorderPicsHighestTid = activeSPS->getNumReorderPics(m_iMaxTemporalLayer);
524    maxDecPicBufferingHighestTid = activeSPS->getMaxDecPicBuffering(m_iMaxTemporalLayer);
525  }
526
527  while (iterPic != pcListPic->end())
528  {
529    TComPic* pcPic = *(iterPic);
530    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
531    {
532       numPicsNotYetDisplayed++;
533      dpbFullness++;
534    }
535    else if(pcPic->getSlice( 0 )->isReferenced())
536    {
537      dpbFullness++;
538    }
539    iterPic++;
540  }
541
542  iterPic = pcListPic->begin();
543
544  if (numPicsNotYetDisplayed>2)
545  {
546    iterPic++;
547  }
548
549  TComPic* pcPic = *(iterPic);
550  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
551  {
552    TComList<TComPic*>::iterator endPic   = pcListPic->end();
553    endPic--;
554    iterPic   = pcListPic->begin();
555    while (iterPic != endPic)
556    {
557      TComPic* pcPicTop = *(iterPic);
558      iterPic++;
559      TComPic* pcPicBottom = *(iterPic);
560
561      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
562          (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
563          (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&
564          (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay < 0))
565      {
566        // write to file
567        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
568        if ( !m_reconFileName.empty() )
569        {
570          const Window &conf = pcPicTop->getConformanceWindow();
571          const Window  defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
572          const Bool isTff = pcPicTop->isTopField();
573
574          Bool display = true;
575          if( m_decodedNoDisplaySEIEnabled )
576          {
577            SEIMessages noDisplay = getSeisByType(pcPic->getSEIs(), SEI::NO_DISPLAY );
578            const SEINoDisplay *nd = ( noDisplay.size() > 0 ) ? (SEINoDisplay*) *(noDisplay.begin()) : NULL;
579            if( (nd != NULL) && nd->m_noDisplay )
580            {
581              display = false;
582            }
583          }
584
585          if (display)
586          {
587        m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
588                                           m_outputColourSpaceConvert,
589                                           conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
590                                           conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
591                                           conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
592                                           conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
593          }
594        }
595
596        // update POC of display order
597        m_iPOCLastDisplay = pcPicBottom->getPOC();
598
599        // erase non-referenced picture in the reference picture list after display
600        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
601        {
602          pcPicTop->setReconMark(false);
603
604          // mark it should be extended later
605          pcPicTop->getPicYuvRec()->setBorderExtension( false );
606        }
607        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
608        {
609          pcPicBottom->setReconMark(false);
610
611          // mark it should be extended later
612          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
613        }
614        pcPicTop->setOutputMark(false);
615        pcPicBottom->setOutputMark(false);
616      }
617    }
618  }
619  else if (!pcPic->isField()) //Frame Decoding
620  {
621    iterPic = pcListPic->begin();
622
623    while (iterPic != pcListPic->end())
624    {
625      pcPic = *(iterPic);
626
627      if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay &&
628        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
629      {
630        // write to file
631         numPicsNotYetDisplayed--;
632        if(pcPic->getSlice(0)->isReferenced() == false)
633        {
634          dpbFullness--;
635        }
636        if ( !m_reconFileName.empty() )
637        {
638          const Window &conf    = pcPic->getConformanceWindow();
639          const Window defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
640
641          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
642                                         m_outputColourSpaceConvert,
643                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
644                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
645                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
646                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(),
647                                         NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range  );
648        }
649
650        if (!m_colourRemapSEIFileName.empty())
651        {
652          xOutputColourRemapPic(pcPic);
653        }
654
655        // update POC of display order
656        m_iPOCLastDisplay = pcPic->getPOC();
657
658        // erase non-referenced picture in the reference picture list after display
659        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
660        {
661          pcPic->setReconMark(false);
662
663          // mark it should be extended later
664          pcPic->getPicYuvRec()->setBorderExtension( false );
665        }
666        pcPic->setOutputMark(false);
667      }
668
669      iterPic++;
670    }
671  }
672}
673
674/** \param pcListPic list of pictures to be written to file
675 */
676Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
677{
678  if(!pcListPic || pcListPic->empty())
679  {
680    return;
681  }
682  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
683
684  iterPic   = pcListPic->begin();
685  TComPic* pcPic = *(iterPic);
686
687  if (pcPic->isField()) //Field Decoding
688  {
689    TComList<TComPic*>::iterator endPic   = pcListPic->end();
690    endPic--;
691    TComPic *pcPicTop, *pcPicBottom = NULL;
692    while (iterPic != endPic)
693    {
694      pcPicTop = *(iterPic);
695      iterPic++;
696      pcPicBottom = *(iterPic);
697
698      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
699      {
700        // write to file
701
702        if ( !m_reconFileName.empty() )
703        {
704          const Window &conf = pcPicTop->getConformanceWindow();
705          const Window  defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
706          const Bool isTff = pcPicTop->isTopField();
707          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
708                                         m_outputColourSpaceConvert,
709                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
710                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
711                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
712                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
713        }
714
715        // update POC of display order
716        m_iPOCLastDisplay = pcPicBottom->getPOC();
717
718        // erase non-referenced picture in the reference picture list after display
719        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
720        {
721          pcPicTop->setReconMark(false);
722
723          // mark it should be extended later
724          pcPicTop->getPicYuvRec()->setBorderExtension( false );
725        }
726        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
727        {
728          pcPicBottom->setReconMark(false);
729
730          // mark it should be extended later
731          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
732        }
733        pcPicTop->setOutputMark(false);
734        pcPicBottom->setOutputMark(false);
735
736        if(pcPicTop)
737        {
738          pcPicTop->destroy();
739          delete pcPicTop;
740          pcPicTop = NULL;
741        }
742      }
743    }
744    if(pcPicBottom)
745    {
746      pcPicBottom->destroy();
747      delete pcPicBottom;
748      pcPicBottom = NULL;
749    }
750  }
751  else //Frame decoding
752  {
753    while (iterPic != pcListPic->end())
754    {
755      pcPic = *(iterPic);
756
757      if ( pcPic->getOutputMark() )
758      {
759        // write to file
760        if ( !m_reconFileName.empty() )
761        {
762          const Window &conf    = pcPic->getConformanceWindow();
763          const Window  defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
764          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
765                                         m_outputColourSpaceConvert,
766                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
767                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
768                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
769                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(),
770                                         NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
771        }
772
773        if (!m_colourRemapSEIFileName.empty())
774        {
775          xOutputColourRemapPic(pcPic);
776        }
777
778        // update POC of display order
779        m_iPOCLastDisplay = pcPic->getPOC();
780        // erase non-referenced picture in the reference picture list after display
781        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
782        {
783          pcPic->setReconMark(false);
784
785          // mark it should be extended later
786          pcPic->getPicYuvRec()->setBorderExtension( false );
787        }
788        pcPic->setOutputMark(false);
789      }
790      if(pcPic != NULL)
791      {
792        pcPic->destroy();
793        delete pcPic;
794        pcPic = NULL;
795      }
796      iterPic++;
797    }
798  }
799  pcListPic->clear();
800  m_iPOCLastDisplay = -MAX_INT;
801}
802#endif
803/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
804 */
805#if NH_MV
806Bool TAppDecTop::xIsNaluInTargetDecLayerIdSet( InputNALUnit* nalu )
807#else
808Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
809#endif
810{
811  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
812  {
813    return true;
814  }
815  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
816  {
817    if ( nalu->m_nuhLayerId == (*it) )
818    {
819      return true;
820    }
821  }
822  return false;
823}
824
825#if NH_MV
826
827Bool TAppDecTop::xExtractAndRewrite( InputNALUnit* nalu )
828{
829  Bool naluInSubStream;
830  if ( !m_initilizedFromVPS )
831  {
832    naluInSubStream = true; // No active VPS yet. Wait for slice activating one.
833  }
834  else
835  {
836    if ( m_decProcCvsg == CLAUSE_8 )
837    {
838      // 8.1.2->clause 10
839
840      // sub-bitstream extraction process as specified in clause 10
841      naluInSubStream = true;
842      if ( nalu->m_temporalId > m_highestTid || !xIsNaluInTargetDecLayerIdSet(nalu) )
843      {
844        naluInSubStream = false;
845      }
846    }
847    else
848    {
849      // F.8.1.2
850      Int targetDecLayerSetIdx = m_vps->olsIdxToLsIdx( m_targetOptLayerSetIdx );
851      if ( targetDecLayerSetIdx <= m_vps->getVpsNumLayerSetsMinus1() && m_vps->getVpsBaseLayerInternalFlag() )
852      {
853        // - If TargetDecLayerSetIdx is less than or equal to vps_num_layer_sets_minus1 and
854        //   vps_base_layer_internal_flag is equal to 1, the following applies:
855        //   - The sub-bitstream extraction process as specified in clause 10 is applied with the CVSG, HighestTid and
856        //     TargetDecLayerIdList as inputs, and the output is assigned to a bitstream referred to as BitstreamToDecode.
857
858        naluInSubStream = true;
859        if ( nalu->m_temporalId > m_highestTid || !xIsNaluInTargetDecLayerIdSet(nalu) )
860        {
861          naluInSubStream = false;
862        }
863
864      }
865      else if ( targetDecLayerSetIdx <= m_vps->getVpsNumLayerSetsMinus1() && !m_vps->getVpsBaseLayerInternalFlag() )
866      {
867        // - Otherwise, if TargetDecLayerSetIdx is less than or equal to vps_num_layer_sets_minus1 and vps_base_layer_internal_flag
868        //   is equal to 0, the following applies:
869        //   - The sub-bitstream extraction process as specified in clause F.10.1 is applied with the CVSG, HighestTid and
870        //     TargetDecLayerIdList as inputs, and the output is assigned to a bitstream referred to as BitstreamToDecode.
871
872        naluInSubStream = true;
873        if ( nalu->m_temporalId > m_highestTid || !xIsNaluInTargetDecLayerIdSet(nalu) )
874        {
875          naluInSubStream = false;
876        }
877      }
878      else if ( targetDecLayerSetIdx > m_vps->getVpsNumLayerSetsMinus1() && m_vps->getNumLayersInIdList( targetDecLayerSetIdx ) == 1 )
879      {
880        // - Otherwise, if TargetDecLayerSetIdx is greater than vps_num_layer_sets_minus1 and
881        //   NumLayersInIdList[ TargetDecLayerSetIdx ] is equal to 1, the following applies:
882        //   - The independent non-base layer rewriting process of clause F.10.2 is applied with the CVSG, HighestTid and
883        //     TargetDecLayerIdList[ 0 ] as inputs, and the output is assigned to a bitstream referred to as BitstreamToDecode.
884
885        Int assingedBaseLayerId = m_targetDecLayerIdSet[0];
886        naluInSubStream = true;
887
888        if ( nalu->m_nalUnitType != NAL_UNIT_SPS &&
889          nalu->m_nalUnitType != NAL_UNIT_PPS &&
890          nalu->m_nalUnitType != NAL_UNIT_EOB &&
891          nalu->m_nuhLayerId != assingedBaseLayerId )
892        {
893          naluInSubStream = false;
894        }
895
896        if ( ( nalu->m_nalUnitType == NAL_UNIT_SPS || nalu->m_nalUnitType != NAL_UNIT_PPS ) &&
897          !( nalu->m_nuhLayerId == 0 || nalu->m_nuhLayerId == assingedBaseLayerId ) )
898        {
899          naluInSubStream = false;
900        }
901
902        if ( nalu->m_nalUnitType == NAL_UNIT_VPS )
903        {
904          naluInSubStream = false;
905        }
906
907        if ( nalu->m_temporalId > m_highestTid )
908        {
909          naluInSubStream = false;
910        }
911               
912        // For now, don't do the layer id change here, but change smallest layer id.
913        // To be verified.         
914        //if ( naluInSubStream )
915        //{
916        //  nalu->m_nuhLayerId = 0;
917        //}
918      }
919      else
920      {
921        // - Otherwise, the following applies:
922        //   - The sub-bitstream extraction process as specified in clause F.10.3 is applied with the CVSG, HighestTid and
923        //     TargetDecLayerIdList as inputs, and the output is assigned to a bitstream referred to as BitstreamToDecode.
924
925        naluInSubStream = true;
926
927        if ( nalu->m_nalUnitType != NAL_UNIT_VPS &&
928          nalu->m_nalUnitType != NAL_UNIT_SPS &&
929          nalu->m_nalUnitType != NAL_UNIT_PPS &&
930          nalu->m_nalUnitType != NAL_UNIT_EOS &&
931          nalu->m_nalUnitType != NAL_UNIT_EOB &&
932          !xIsNaluInTargetDecLayerIdSet(nalu) )
933        {
934          naluInSubStream = false;
935        }
936
937        if ( ( nalu->m_nalUnitType == NAL_UNIT_VPS ||
938          nalu->m_nalUnitType == NAL_UNIT_SPS ||
939          nalu->m_nalUnitType == NAL_UNIT_PPS ||
940          nalu->m_nalUnitType == NAL_UNIT_EOS    ) &&
941          !( nalu->m_nuhLayerId == 0 || xIsNaluInTargetDecLayerIdSet(nalu) )
942          )
943        {
944          naluInSubStream = false;
945        }
946
947        if ( nalu->m_temporalId > m_highestTid )
948        {
949          naluInSubStream = false;
950        }
951        // TBD: vps_base_layer_available_flag in each VPS is set equal to 0.
952      }
953    }
954  }
955
956  return naluInSubStream;
957}
958
959Void TAppDecTop::xProcessVclNalu( InputNALUnit nalu )
960{
961  TDecTop* dec  = xGetDecoder( nalu );
962
963  // Decode slice header of slice of current or new picture.
964  dec->decodeSliceHeader( nalu );
965
966  // Check if slice belongs to current or new picture
967  Bool sliceIsFirstOfNewPicture = dec->getFirstSliceSegementInPicFlag();
968
969  if ( !xIsSkipVclNalu( nalu, sliceIsFirstOfNewPicture ) )
970  {
971    if ( sliceIsFirstOfNewPicture )
972    {
973      xDetectNewPocResettingPeriod( nalu );
974      Bool sliceIsFirstOfNewAU = xDetectNewAu( nalu );
975      xFinalizePreviousPictures ( sliceIsFirstOfNewAU );
976      xDecodeFirstSliceOfPicture( nalu, sliceIsFirstOfNewAU );
977    }
978    else
979    {
980      xDecodeFollowSliceOfPicture( nalu );
981    }
982  }
983}
984
985Bool TAppDecTop::xIsSkipVclNalu( InputNALUnit& nalu, Bool isFirstSliceOfPic )
986{
987
988  TDecTop* dec = xGetDecoder( nalu ); 
989
990  m_handleCraAsBlaFlagSetByExtMeans = false;
991  Bool skipNalu = false;
992
993  if ( isFirstSliceOfPic )
994  {
995    m_totalNumofPicsReceived++;
996  }
997
998  if (!m_cvsStartFound )
999  {
1000    // Skip as specified by decoder option. (Not normative!)
1001    if ( m_totalNumofPicsReceived <= m_iSkipFrame )
1002    {
1003      skipNalu = true;
1004      if ( isFirstSliceOfPic )
1005      {
1006        std::cout << "Layer " << std::setfill(' ') << std::setw(2) << nalu.m_nuhLayerId
1007          << "   POC    ? Skipping picture." << std::setw(5) << m_totalNumofPicsReceived - 1 << std::endl;
1008      }
1009    }
1010    else
1011    {     
1012      if ( dec->getIsInOwnTargetDecLayerIdList() )
1013      {
1014        // Search for initial IRAP access unit
1015        Bool canBeSliceOfInitialIrapAu = nalu.isIrap() && ( dec->decProcClause8() || nalu.m_nuhLayerId == dec->getSmallestLayerId() );
1016
1017        if ( !canBeSliceOfInitialIrapAu )
1018        {
1019          skipNalu = true;
1020          if ( isFirstSliceOfPic )
1021          {
1022            std::cout << "Layer " << std::setfill(' ') << std::setw(2) << nalu.m_nuhLayerId
1023              << "   POC    ? Not an initial IRAP AU. Skipping picture." << std::setw(5) << m_totalNumofPicsReceived - 1 << std::endl;
1024          }
1025        }
1026        else
1027        {
1028          m_cvsStartFound = true;
1029          if( nalu.isCra() )
1030          {
1031            // Ensure that NoRaslOutputFlag of picture is equal to 1.
1032            m_handleCraAsBlaFlagSetByExtMeans = true;
1033            m_handleCraAsBlaFlag = true;
1034          }
1035        }
1036      }
1037      else
1038      {
1039        skipNalu = true; 
1040      }
1041    }
1042  }
1043  else
1044  {
1045    assert( dec->getIsInOwnTargetDecLayerIdList() ); 
1046  }
1047  return skipNalu;
1048}
1049
1050Void TAppDecTop::xProcessNonVclNalu( InputNALUnit nalu )
1051{
1052  xGetDecoder(nalu)->decodeNonVclNalu( nalu );
1053
1054  if (  nalu.m_nalUnitType == NAL_UNIT_EOS )
1055  {
1056    m_eosInLayer[ nalu.m_nuhLayerId ] = true;
1057  }
1058}
1059Void TAppDecTop::xTerminateDecoding()
1060{
1061    xFinalizePic( true );
1062    xFinalizeAU ( );
1063
1064#if NH_3D
1065  if( m_cCamParsCollector.isInitialized() )
1066  {
1067    m_cCamParsCollector.setSlice( 0 );
1068  }
1069#endif
1070   xFlushOutput(); 
1071   m_dpb.emptyAllSubDpbs();
1072}
1073
1074
1075//////////////////////////////
1076/// Process slices
1077//////////////////////////////
1078
1079Void TAppDecTop::xDecodeFirstSliceOfPicture( InputNALUnit nalu, Bool sliceIsFirstOfNewAu )
1080{
1081  TDecTop* dec = xGetDecoder(nalu);
1082  // Initialize from VPS of first slice
1083
1084  // Get current SPS and PPS
1085  TComSlice* slicePilot = dec->getSlicePilot(); 
1086  m_vps = slicePilot->getVPS(); 
1087  m_sps = slicePilot->getSPS(); 
1088  m_pps = slicePilot->getPPS(); 
1089
1090  /// Use VPS activated by the first slice to initialized decoding
1091  if( !m_initilizedFromVPS )
1092  {
1093    xF811GeneralDecProc( nalu );
1094    m_initilizedFromVPS = true;
1095    m_newVpsActivatedbyCurAu  = true; //TBD
1096    m_newVpsActivatedbyCurPic = true;
1097#if NH_3D_VSO || NH_3D
1098    m_dpb.setVPS( m_vps ); 
1099#endif
1100  }
1101
1102  // Create new sub-DBP if not existing
1103  m_dpb.getSubDpb( nalu.m_nuhLayerId, true );
1104
1105  // Create a new picture initialize and make it the current picture
1106  assert( m_curPic == NULL );
1107  m_curPic = new TComPic;
1108
1109  m_curPic->create(*m_sps, *m_pps, true);
1110
1111  m_curPic->setLayerId                      ( nalu.m_nuhLayerId );
1112  m_curPic->setDecodingOrder                ( m_decodingOrder[ nalu.m_nuhLayerId ]);
1113  m_curPic->setIsFstPicOfAllLayOfPocResetPer( m_newPicIsFstPicOfAllLayOfPocResetPer );
1114  m_curPic->setIsPocResettingPic            ( m_newPicIsPocResettingPic );
1115  m_curPic->setActivatesNewVps              ( m_newVpsActivatedbyCurPic );
1116
1117  dec     ->activatePSsAndInitPicOrSlice( m_curPic );
1118
1119  m_decodingOrder[ nalu.m_nuhLayerId ]++;
1120
1121  // Insert pic to current AU
1122  // ( There is also a "current AU in the DBP", however the DBP AU will include the current
1123  //   picture only after it is inserted to the DBP )
1124  m_curAu.addPic(  m_curPic, true );
1125
1126  // Invoke Claus 8 and Annex F decoding process for a picture (only parts before POC derivation ).
1127  xPicDecoding( START_PIC, sliceIsFirstOfNewAu );
1128
1129  if (m_decProcCvsg == ANNEX_F )
1130  {
1131    // Do output before POC derivation
1132    xF13522OutputAndRemOfPicsFromDpb( true );
1133  }
1134
1135  // Decode POC and apply reference picture set
1136  dec->setDecProcPocAndRps( m_decProcPocAndRps );
1137  dec->decodePocAndRps( );
1138
1139  // Do output after POC and RPS derivation
1140  if (m_decProcCvsg == CLAUSE_8 )
1141  {
1142    xC522OutputAndRemOfPicsFromDpb( );
1143  }
1144  else if (m_decProcCvsg == ANNEX_F )
1145  {
1146    xF13522OutputAndRemOfPicsFromDpb( false );
1147  }
1148  else
1149  {
1150    assert(false);
1151  }
1152
1153  // Generate unavailable reference pictures
1154  dec->genUnavailableRefPics( );
1155
1156  // decode first slice segment
1157  dec->decodeSliceSegment( nalu );
1158
1159  m_firstSliceInBitstream = false;
1160}
1161
1162Void TAppDecTop::xDecodeFollowSliceOfPicture( InputNALUnit nalu )
1163{
1164  // decode following segment
1165    TDecTop* dec = xGetDecoder( nalu ); 
1166    dec->activatePSsAndInitPicOrSlice( NULL );
1167    dec->decodeSliceSegment          ( nalu );
1168}
1169
1170Void TAppDecTop::xFinalizePreviousPictures( Bool sliceIsFirstOfNewAU )
1171{
1172  Bool curPicIsLastInAu = sliceIsFirstOfNewAU && (m_curPic != NULL);
1173  // When slice belongs to new picture, finalize current picture.
1174  if( m_curPic != NULL )
1175  {
1176    xFinalizePic( curPicIsLastInAu );
1177
1178    if (m_curPic->isIrap() )
1179    {
1180      m_noRaslOutputFlagAssocIrap[ m_curPic->getLayerId() ] = m_curPic->getNoRaslOutputFlag();
1181    }
1182
1183    m_tDecTop[ xGetDecoderIdx( m_curPic->getLayerId() )]->finalizePic();
1184    m_curPic->getPicYuvRec()->extendPicBorder(); 
1185    m_newVpsActivatedbyCurPic = false;
1186  }
1187
1188  // When slice belongs to new AU, finalize current AU.
1189  if ( curPicIsLastInAu && !m_curAu.empty() )
1190  {
1191    xFinalizeAU( );
1192    m_newVpsActivatedbyCurAu = false;
1193    m_curAu.clear();
1194  }
1195  m_curPic = NULL;
1196}
1197
1198
1199Void TAppDecTop::xFinalizePic(Bool curPicIsLastInAu )
1200{
1201  if ( m_curPic != NULL )
1202  {
1203    m_tDecTop[ xGetDecoderIdx(m_curPic->getLayerId() ) ]->executeLoopFilters( ); // 8.7
1204
1205    // Invoke Claus 8 and F.8 decoding process for a picture (only parts after POC derivation )
1206    xPicDecoding(FINALIZE_PIC, curPicIsLastInAu );
1207
1208    if( m_decProcCvsg == CLAUSE_8 )
1209    {
1210      xC523PicDecMarkAddBumpAndStor    ( );
1211    }
1212    else if ( m_decProcCvsg == ANNEX_F )
1213    {
1214      xF13523PicDecMarkAddBumpAndStor  ( curPicIsLastInAu );
1215    }
1216  }
1217}
1218
1219Void TAppDecTop::xFinalizeAU()
1220{
1221#if NH_3D
1222  if ( !m_curAu.empty())
1223  {
1224    for (TComList<TComPic*>::iterator it = m_curAu.begin(); it != m_curAu.end(); it++)
1225    {
1226      TComPic* pic = (*it);
1227      if ( !pic->getHasGeneratedRefPics() )
1228      {
1229        pic->compressMotion(1);
1230      }
1231    }
1232  }
1233#endif
1234}
1235
1236
1237Void TAppDecTop::xF811GeneralDecProc( InputNALUnit nalu )
1238{
1239  ////////////////////////////////////////////////////////////////////////////////
1240  // F.8.1 General decoding process
1241  ////////////////////////////////////////////////////////////////////////////////
1242
1243  // The following applies at the beginning of decoding a CVSG, after activating the VPS RBSP that is active for
1244  // the entire CVSG and before decoding any VCL NAL units of the CVSG:
1245
1246  if ( !m_vps->getVpsExtensionFlag() )
1247  {
1248    //-   If vps_extension( ) is not present in the active VPS or a decoding process specified in this annex is not in use,
1249    //   clause 8.1.2 is invoked with the CVSG as input.
1250    x812CvsgDecodingProcess( xGetDecoderIdx( nalu.m_nuhLayerId ) );
1251    m_decProcCvsg = CLAUSE_8;
1252  }
1253  else
1254  {
1255    // - Otherwise (vps_extension( ) is present in the active VPS and a decoding process specified in this annex is in use),
1256    xF812CvsgDecodingProcess( xGetDecoderIdx( nalu.m_nuhLayerId ) );
1257    xF13521InitDpb();
1258    m_decProcCvsg = ANNEX_F;
1259  }
1260
1261  if ( m_printVpsInfo  && ( m_decProcCvsg == ANNEX_F ) && ( m_targetOptLayerSetIdx == m_targetOptLayerSetInd[ 0 ] ) )
1262  {
1263    m_vps->printScalabilityId();
1264    m_vps->printLayerDependencies();
1265    m_vps->printLayerSets();
1266    m_vps->printPTL();
1267    m_vps->printRepFormat();
1268  }
1269}
1270
1271Void   TAppDecTop::xPicDecoding( DecProcPart curPart, Bool picPosInAuIndication )
1272{
1273  if ( m_decProcCvsg == CLAUSE_8 )
1274  {
1275    // F.8.1.1 -> 8.1.2 -> 8.1.3
1276    x813decProcForCodPicWithLIdZero  ( curPart );
1277  }
1278  else if ( m_decProcCvsg == ANNEX_F )
1279  {
1280    if ( m_targetOptLayerSetIdx == 0  )
1281    {
1282      // F.8.1.1 -> F.8.1.2 -> 8.1.3
1283      x813decProcForCodPicWithLIdZero  ( curPart );
1284    }
1285    else
1286    {
1287      // F.8.1.1 -> F.8.1.2 -> F.8.1.3
1288      xF813ComDecProcForACodedPic( curPart, picPosInAuIndication );
1289    }
1290  }
1291  else
1292  {
1293    assert( false );
1294  }
1295}
1296
1297Void TAppDecTop::x812CvsgDecodingProcess( Int decIdx )
1298{
1299  ///////////////////////////////////////////////////////////////////////////////////////
1300  //  8.1.2 CVSG decoding process
1301  ///////////////////////////////////////////////////////////////////////////////////////
1302
1303  // The layer identifier list TargetDecLayerIdList, which specifies the list of nuh_layer_id values,
1304  // in increasing order of nuh_layer_id values, of the NAL units to be decoded, is specified as follows:
1305
1306  Bool externalMeansToSetTargetDecLayerIdList = !m_targetDecLayerIdSetFileEmpty;
1307
1308  if ( externalMeansToSetTargetDecLayerIdList )
1309  {
1310    // - If some external means, not specified in this Specification, is available to set TargetDecLayerIdList,
1311    //   TargetDecLayerIdList is set by the external means.
1312    assert( !m_targetDecLayerIdSet.empty() ); // Already done when parsing cfg ile
1313  }
1314  else
1315  {
1316    //-  Otherwise, TargetDecLayerIdList contains only one nuh_layer_id value that is equal to 0.
1317    m_targetDecLayerIdSet.clear();
1318    m_targetDecLayerIdSet.push_back( 0 );
1319  }
1320
1321  // The variable HighestTid, which identifies the highest temporal sub-layer to be decoded, is specified as follows:
1322  Bool externalMeansSetHighestTid = ( m_iMaxTemporalLayer != -1 );
1323  if ( externalMeansSetHighestTid )
1324  {
1325    //- If some external means, not specified in this Specification, is available to set HighestTid,
1326    //  HighestTid is set by the external means.
1327    m_highestTid = m_iMaxTemporalLayer;
1328  }
1329  else
1330  {
1331    //-  Otherwise, HighestTid is set equal to sps_max_sub_layers_minus1.
1332    m_highestTid = m_sps->getSpsMaxSubLayersMinus1();
1333  }
1334
1335  //The variable SubPicHrdFlag is specified as follows:
1336  //- If the decoding process is invoked in a bitstream conformance test as specified in clause C.1, SubPicHrdFlag is set as specified in clause C.1.
1337  //- Otherwise, SubPicHrdFlag is set equal to ( SubPicHrdPreferredFlag  &&  sub_pic_hrd_params_present_flag ).
1338
1339  // The sub-bitstream extraction process as specified in clause 10 is applied with the CVSG, HighestTid and TargetDecLayerIdList as inputs, and the output is assigned to a bitstream referred to as BitstreamToDecode.
1340}
1341
1342Void TAppDecTop::x813decProcForCodPicWithLIdZero( DecProcPart curPart )
1343{
1344  ////////////////////////////////////////////////////////////////////////////////
1345  // 8.1.3 Decoding process for a coded picture with nuh_layer_id equal to 0.
1346  ////////////////////////////////////////////////////////////////////////////////
1347
1348  if ( curPart == START_PIC )
1349  {
1350    Int nuhLayerId = m_curPic->getLayerId();
1351
1352    if ( ( m_curPic->isBla() && m_curPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP ) || m_curPic->isCra() )
1353    {
1354      // Not needed.
1355      // When the current picture is a BLA picture that has nal_unit_type equal to BLA_W_LP or is a CRA picture, the following applies:
1356      // -  If some external means not specified in this Specification is available to set the variable UseAltCpbParamsFlag to a value, UseAltCpbParamsFlag is set equal to the value provided by the external means.
1357      // -  Otherwise, the value of UseAltCpbParamsFlag is set equal to 0.
1358    }
1359
1360    if ( m_curPic->isIrap() )
1361    {
1362      // When the current picture is an IRAP picture, the following applies:
1363      if ( m_curPic->isIdr() || m_curPic->isBla() || m_curPic->getDecodingOrder() == 0 || m_eosInLayer[ nuhLayerId ] )
1364      {
1365        // -  If the current picture is an IDR picture, a BLA picture, the first picture in the bitstream in decoding order,
1366        //    or the first picture that follows an end of sequence NAL unit in decoding order, the variable NoRaslOutputFlag
1367        //    is set equal to 1.
1368
1369        m_curPic->setNoRaslOutputFlag( true );
1370      }
1371      else if ( m_handleCraAsBlaFlagSetByExtMeans )
1372      {
1373        // -  Otherwise, if some external means not specified in this Specification is available to set the variable HandleCraAsBlaFlag
1374        //    to a value for the current picture, the variable HandleCraAsBlaFlag is set equal to the value provided by
1375        //    the external means and the variable NoRaslOutputFlag is set equal to HandleCraAsBlaFlag.
1376
1377        m_curPic->setNoRaslOutputFlag( m_handleCraAsBlaFlag );
1378      }
1379      else
1380      {
1381        // -  Otherwise, the variable HandleCraAsBlaFlag is set equal to 0 and the variable NoRaslOutputFlag is set equal to 0.
1382        m_handleCraAsBlaFlag = false;
1383        m_curPic->setNoRaslOutputFlag( false );
1384      }
1385    }
1386
1387    m_decProcPocAndRps = CLAUSE_8;
1388  }
1389  else if ( curPart == FINALIZE_PIC )
1390  {
1391    // -  PicOutputFlag is set as follows:
1392    if (m_curPic->isRasl() && m_noRaslOutputFlagAssocIrap[ m_curPic->getLayerId() ] )
1393    {
1394      // -  If the current picture is a RASL picture and NoRaslOutputFlag of the associated IRAP picture is equal to 1,
1395      //    PicOutputFlag is set equal to 0.
1396      m_curPic->setPicOutputFlag( false );
1397    }
1398    else
1399    {
1400      // -  Otherwise, PicOutputFlag is set equal to pic_output_flag.
1401      m_curPic->setPicOutputFlag( m_curPic->getSlice(0)->getPicOutputFlag() );
1402    }
1403
1404    // 4.  After all slices of the current picture have been decoded, the decoded picture is marked as "used for short-term reference".
1405    m_curPic->markAsUsedForShortTermReference();
1406  }
1407}
1408
1409// F.8.1.2
1410Void TAppDecTop::xF812CvsgDecodingProcess( Int decIdx )
1411{
1412  ///////////////////////////////////////////////////////////////////////////////////////
1413  //  F.8.1.2 CVSG decoding process
1414 ///////////////////////////////////////////////////////////////////////////////////////
1415
1416  // The variable TargetOlsIdx, which specifies the index to the list of the OLSs
1417  // specified by the VPS, of the target OLS, is specified as follows:
1418
1419
1420  // If some external means, not specified in this Specification, is available to set
1421  // TargetOlsIdx, TargetOlsIdx is set by the external means.
1422
1423  // For this decoder the TargetOlsIdx is always set by external means:
1424  // When m_targetOptLayerSetIdx is equal to -1,  TargetOlsIdx is set to getVpsNumLayerSetsMinus1 (which has already been done in TDecTop, since needed there for parsing)
1425  // Otherwise m_targetOptLayerSetIdx is used directly.
1426
1427  if ( m_targetOptLayerSetIdx == -1 )
1428  {
1429    m_targetOptLayerSetIdx = m_tDecTop[decIdx]->getTargetOlsIdx();
1430  }
1431  else
1432  {
1433    assert( m_tDecTop[decIdx]->getTargetOlsIdx() == m_targetOptLayerSetIdx );
1434  }
1435
1436  m_targetDecLayerSetIdx = m_vps->olsIdxToLsIdx( m_targetOptLayerSetIdx );
1437  m_targetDecLayerIdSet  = m_vps->getTargetDecLayerIdList( m_targetOptLayerSetIdx );
1438
1439
1440  if ( m_targetOptLayerSetIdx < 0 || m_targetOptLayerSetIdx >= m_vps->getNumOutputLayerSets() )
1441  {
1442    fprintf(stderr, "\ntarget output layer set index must be in the range of 0 to %d, inclusive \n", m_vps->getNumOutputLayerSets() - 1 );
1443    exit(EXIT_FAILURE);
1444  }
1445
1446  if ( !m_vps->getVpsBaseLayerAvailableFlag() )
1447  {
1448    if(  m_targetDecLayerSetIdx < m_vps->getFirstAddLayerSetIdx() || m_targetDecLayerSetIdx > m_vps->getLastAddLayerSetIdx() )
1449    {
1450      // When vps_base_layer_available_flag is equal to 0, OlsIdxToLsIdx[ TargetOlsIdx ] shall be in the range of FirstAddLayerSetIdx to LastAddLayerSetIdx, inclusive.
1451      fprintf(stderr, "\nvps_base_layer_available_flag is equal to 0, OlsIdxToLsIdx[ TargetOlsIdx ] shall be in the range of %d to %d, inclusive \n", m_vps->getFirstAddLayerSetIdx(), m_vps->getLastAddLayerSetIdx() );
1452      exit(EXIT_FAILURE);
1453    }
1454  }
1455
1456  if ( !m_vps->getVpsBaseLayerInternalFlag() && m_targetOptLayerSetIdx <= 0 )
1457  {
1458    // When vps_base_layer_internal_flag is equal to 0, TargetOlsIdx shall be greater than 0.
1459    fprintf(stderr, "\nvps_base_layer_internal_flag is equal to 0, TargetOlsIdx shall be greater than 0.\n" );
1460    exit(EXIT_FAILURE);
1461  }
1462
1463  // The variable HighestTid, which identifies the highest temporal sub-layer to be decoded,
1464  // is specified as follows:
1465
1466  Bool externalMeansSetHighestTid = ( m_iMaxTemporalLayer != -1 );
1467  if ( externalMeansSetHighestTid )
1468  {
1469    m_highestTid = m_iMaxTemporalLayer;
1470  }
1471  else
1472  {
1473    m_highestTid = m_sps->getSpsMaxSubLayersMinus1();
1474  }
1475
1476  // The variable SubPicHrdPreferredFlag is either specified by external means, or when not specified by external means, set equal to 0.
1477  // The variable SubPicHrdFlag is specified as follows:
1478  // -  If the decoding process is invoked in a bitstream conformance test as specified in clause F.13.1, SubPicHrdFlag is set as specified in clause F.13.1.
1479  // -  Otherwise, SubPicHrdFlag is set equal to ( SubPicHrdPreferredFlag  &&  sub_pic_hrd_params_present_flag ), where sub_pic_hrd_params_present_flag is found in any hrd_parameters( ) syntax structure that applies to at least one bitstream partition of the output layer set idenified by TargetOlsIdx.
1480  // -  TBD in case that needed some when.
1481
1482  // A bitstream to be decoded, BitstreamToDecode, is specified as follows:
1483  //   - Extraction is done in xExtractAndRewrite();
1484
1485  //   - SmallestLayerId is already derived in  TDecTop:: initFromActiveVps, since required for SH parsing.
1486  m_smallestLayerId = m_tDecTop[decIdx]->getSmallestLayerId();
1487
1488  // When vps_base_layer_internal_flag is equal to 0, vps_base_layer_available_flag is equal to 1,
1489  // and TargetDecLayerSetIdx is in the range of 0 to vps_num_layer_sets_minus1, inclusive,
1490  // the following applies:
1491  if ( !m_vps->getVpsBaseLayerInternalFlag() && m_vps->getVpsBaseLayerAvailableFlag() &&
1492       ( m_targetDecLayerSetIdx >= 0 && m_targetDecLayerSetIdx <= m_vps->getVpsNumLayerSetsMinus1() ) )
1493  {
1494
1495    // TBD: The size of the sub-DPB for the layer with nuh_layer_id equal to 0 is set equal to 1.
1496
1497    // TBD: The values of pic_width_in_luma_samples, pic_height_in_luma_samples, chroma_format_idc,
1498    // separate_colour_plane_flag, bit_depth_luma_minus8, bit_depth_chroma_minus8, conf_win_left_offset,
1499    // conf_win_right_offset, conf_win_top_offset, and conf_win_bottom_offset for decoded pictures
1500    // with nuh_layer_id equal to 0 are set equal to the values of pic_width_vps_in_luma_samples,
1501    // pic_height_vps_in_luma_samples, chroma_format_vps_idc, separate_colour_plane_vps_flag,
1502    // bit_depth_vps_luma_minus8, bit_depth_vps_chroma_minus8, conf_win_vps_left_offset,
1503    // conf_win_vps_right_offset, conf_win_vps_top_offset, and conf_win_vps_bottom_offset respectively,
1504    // of the vps_rep_format_idx[ 0 ]-th rep_format( ) syntax structure in the active VPS.
1505
1506    // The variable BaseLayerOutputFlag is set equal to ( TargetOptLayerIdList[ 0 ]  = =  0 ).
1507
1508    m_baseLayerOutputFlag = ( m_vps->getTargetOptLayerIdList( m_targetOptLayerSetIdx )[ 0 ] == 0 );
1509
1510    // NOTE - The BaseLayerOutputFlag for each access unit is to be sent by an external means to
1511    // the base layer decoder for controlling the output of base layer decoded pictures.
1512    // BaseLayerOutputFlag equal to 1 indicates that the base layer is an output layer.
1513    // BaseLayerOutputFlag equal to 0 indicates that the base layer is not an output layer.
1514
1515    // The variable LayerInitializedFlag[ i ] is set equal to 0 for all values of i from 0
1516    // to vps_max_layer_id, inclusive, and the variable FirstPicInLayerDecodedFlag[ i ] is set
1517    // equal to 0 for all values of i from 0 to vps_max_layer_id, inclusive.
1518
1519    for (Int i = 0; i <= m_vps->getVpsMaxLayerId(); i++ )
1520    {
1521      m_layerInitilizedFlag       [ i ] = false;
1522      m_firstPicInLayerDecodedFlag[ i ] = false;
1523    }
1524  }
1525}
1526
1527Void TAppDecTop::xC522OutputAndRemOfPicsFromDpb( )
1528{
1529  ////////////////////////////////////////////////////////////////////////////////
1530  // C.5.2.2 Output and removal of pictures from the DPB
1531  ////////////////////////////////////////////////////////////////////////////////
1532
1533//  The output and removal of pictures from the DPB before the decoding of the current picture
1534//  (but after parsing the slice header of the first slice of the current picture) happens instantaneously
1535//  when the first decoding unit of the access unit containing the current picture is removed from the CPB and proceeds as follows:
1536//  - The decoding process for RPS as specified in clause 8.3.2 is invoked.
1537
1538  Int nuhLayerId = m_curPic->getLayerId();
1539  const TComSPS* sps = m_curPic->getSlice(0)->getSPS();
1540  assert( nuhLayerId == 0 );
1541
1542  if( ( m_curPic->isIrap() && m_curPic->getNoRaslOutputFlag() == 1) && m_curPic->getDecodingOrder() != 0 )
1543  {
1544    // - If the current picture is an IRAP picture with NoRaslOutputFlag equal to 1 that is not picture 0,
1545    //   the following ordered steps are applied:
1546
1547    // 1.  The variable NoOutputOfPriorPicsFlag is derived for the decoder under test as follows:
1548    Int noOutputOfPriorPicsFlag;
1549    if( m_curPic->isCra() )
1550    {
1551      //-  If the current picture is a CRA picture, NoOutputOfPriorPicsFlag is set equal to 1
1552      // (regardless of the value of no_output_of_prior_pics_flag).
1553      noOutputOfPriorPicsFlag = true;
1554    }
1555    else if ( 0  )
1556    {
1557      // TBD
1558      //- Otherwise, if the value of pic_width_in_luma_samples, pic_height_in_luma_samples, chroma_format_idc,
1559      //  separate_colour_plane_flag, bit_depth_luma_minus8, bit_depth_chroma_minus8 or sps_max_dec_pic_buffering_minus1[ HighestTid ]
1560      //  derived from the active SPS is different from the value of pic_width_in_luma_samples, pic_height_in_luma_samples,
1561      //  chroma_format_idc, separate_colour_plane_flag, bit_depth_luma_minus8, bit_depth_chroma_minus8 or
1562      //  sps_max_dec_pic_buffering_minus1[ HighestTid ], respectively, derived from the SPS active for the preceding picture,
1563      //  NoOutputOfPriorPicsFlag may (but should not) be set to 1 by the decoder under test,
1564      //  regardless of the value of no_output_of_prior_pics_flag.
1565      //     NOTE - Although setting NoOutputOfPriorPicsFlag equal to no_output_of_prior_pics_flag is preferred under these conditions,
1566      //            the decoder under test is allowed to set NoOutputOfPriorPicsFlag to 1 in this case.
1567    }
1568    else
1569    {
1570      noOutputOfPriorPicsFlag = m_curPic->getSlice(0)->getNoOutputPriorPicsFlag();
1571    }
1572    //  2.  The value of NoOutputOfPriorPicsFlag derived for the decoder under test is applied for the HRD as follows:
1573    if (noOutputOfPriorPicsFlag)
1574    {
1575      //-  If NoOutputOfPriorPicsFlag is equal to 1, all picture storage buffers in the DPB are emptied
1576      //   without output of the pictures they contain and the DPB fullness is set equal to 0.
1577      m_dpb.emptySubDpb( nuhLayerId );
1578    }
1579    else if (!noOutputOfPriorPicsFlag)
1580    {
1581      //  -  Otherwise (NoOutputOfPriorPicsFlag is equal to 0), all picture storage buffers containing a picture that
1582      //     is marked as "not needed for output" and "unused for reference" are emptied (without output) and all non-empty
1583      //     picture storage buffers in the DPB are emptied by repeatedly invoking the "bumping" process specified in clause C.5.2.4
1584      //     and the DPB fullness is set equal to 0.
1585
1586      m_dpb.emptySubDpbNotNeedForOutputAndUnusedForRef( nuhLayerId );
1587      while( m_dpb.getSubDpb( nuhLayerId, false  )->size() != 0 )
1588      {
1589        xC524Bumping();
1590      }
1591    }
1592  }
1593  else if ( !( m_curPic->isIrap() && m_curPic->getNoRaslOutputFlag() == 0 ) )
1594  {
1595    //  -  Otherwise (the current picture is not an IRAP picture with NoRaslOutputFlag equal to 1),
1596    //     all picture storage buffers containing a picture which are marked as "not needed for output" and "unused for reference"
1597    //     are emptied (without output). For each picture storage buffer that is emptied, the DPB fullness is decremented by one.
1598
1599    m_dpb.emptySubDpbNotNeedForOutputAndUnusedForRef( nuhLayerId );
1600
1601    Bool repeat = true;
1602
1603    while( repeat )
1604    {
1605      TComSubDpb* dpb = m_dpb.getSubDpb( nuhLayerId, false );
1606      TComList<TComPic*> picsMarkedForOutput = dpb->getPicsMarkedNeedForOutput();
1607      // When one or more of the following conditions are true, the "bumping" process specified in clause C.5.2.4
1608      // is invoked repeatedly while further decrementing the DPB fullness by one for each additional picture storage buffer that
1609      // is emptied, until none of the following conditions are true:
1610
1611      // -  The number of pictures in the DPB that are marked as "needed for output" is greater
1612      //    than sps_max_num_reorder_pics[ HighestTid ].
1613      Bool cond1 = ( picsMarkedForOutput.size() > sps->getSpsMaxNumReorderPics( m_highestTid ) );
1614
1615      //  -  sps_max_latency_increase_plus1[ HighestTid ] is not equal to 0 and there is at least one picture in the DPB
1616      //     that is marked as "needed for output" for which the associated variable PicLatencyCount is greater than or equal
1617      //     to SpsMaxLatencyPictures[ HighestTid ].
1618      Bool anyPicWithGtOrEqLatencyCnt = false;
1619      for (TComList<TComPic*>::iterator itP = picsMarkedForOutput.begin(); itP != picsMarkedForOutput.end() && !anyPicWithGtOrEqLatencyCnt; itP++ )
1620      {
1621        anyPicWithGtOrEqLatencyCnt = anyPicWithGtOrEqLatencyCnt || ( (*itP)->getPicLatencyCount() >= sps->getSpsMaxLatencyPictures( m_highestTid ));
1622      }
1623      Bool cond2 = ( sps->getSpsMaxLatencyIncreasePlus1( m_highestTid ) != 0 ) && anyPicWithGtOrEqLatencyCnt;
1624
1625      //  -  The number of pictures in the DPB is greater than or equal to sps_max_dec_pic_buffering_minus1[ HighestTid ] + 1.
1626      Bool cond3 = ( dpb->size() >= ( sps->getSpsMaxDecPicBufferingMinus1( m_highestTid ) + 1 ));
1627
1628      if ( cond1 || cond2 || cond3 )
1629      {
1630        xC524Bumping();
1631      }
1632      else
1633      {
1634        repeat = false;
1635      }
1636    }
1637  }
1638}
1639
1640Void TAppDecTop::xC523PicDecMarkAddBumpAndStor()
1641{
1642  ///////////////////////////////////////////////////////////////////////////////////////
1643  // C.5.2.3 Picture decoding, marking, additional bumping and storage 
1644  ///////////////////////////////////////////////////////////////////////////////////////
1645 
1646  Int nuhLayerId = m_curPic->getLayerId();
1647  const TComSPS* sps = m_curPic->getSlice(0)->getSPS();
1648  // The processes specified in this clause happen instantaneously when the last decoding unit of access unit n containing the
1649  // current picture is removed from the CPB.
1650  if (m_curPic->getPicOutputFlag() )
1651  {
1652    // When the current picture has PicOutputFlag equal to 1, for each picture in the DPB that is marked as "needed for output"
1653    // and follows the current picture in output order, the associated variable PicLatencyCount is set equal to PicLatencyCount + 1.
1654    TComSubDpb* dpb = m_dpb.getSubDpb( nuhLayerId, false);
1655
1656    for (TComSubDpb::iterator itP = dpb->begin(); itP != dpb->end(); itP++)
1657    {
1658      TComPic* pic = (*itP);
1659      if ( pic->getOutputMark() && pic->getPOC() > m_curPic->getPOC() )
1660      {
1661        pic->setPicLatencyCount( pic->getPicLatencyCount() + 1 );
1662      }
1663    }
1664  }
1665
1666  // The current picture is considered as decoded after the last decoding unit of the picture is decoded.
1667  // The current decoded picture is stored in an empty picture storage buffer in the DPB and the following applies:
1668  m_dpb.addNewPic( m_curPic );
1669
1670
1671  if (m_curPic->getPicOutputFlag())
1672  {
1673    // - If the current decoded picture has PicOutputFlag equal to 1, it is marked as "needed for output" and its associated
1674    //   variable PicLatencyCount is set equal to 0.
1675    m_curPic->setOutputMark( true );
1676    m_curPic->setPicLatencyCount( 0 );
1677  }
1678  else if (!m_curPic->getPicOutputFlag() )
1679  {
1680    // - Otherwise (the current decoded picture has PicOutputFlag equal to 0), it is marked as "not needed for output".
1681    m_curPic->setOutputMark( false );
1682  }
1683
1684  // The current decoded picture is marked as "used for short-term reference".
1685  m_curPic->markAsUsedForShortTermReference();
1686
1687  Bool repeat = true;
1688
1689  while( repeat )
1690  {
1691    TComSubDpb* dpb = m_dpb.getSubDpb( nuhLayerId, false );
1692    TComList<TComPic*> picsMarkedForOutput = dpb->getPicsMarkedNeedForOutput();
1693
1694    // When one or more of the following conditions are true, the "bumping" process specified in clause C.5.2.4
1695    // is invoked repeatedly until none of the following conditions are true:
1696
1697    // - The number of pictures in the DPB that are marked as "needed for output" is greater than sps_max_num_reorder_pics[ HighestTid ].
1698    Bool cond1 = ( picsMarkedForOutput.size() > sps->getSpsMaxNumReorderPics( m_highestTid ) );
1699
1700    // - sps_max_latency_increase_plus1[ HighestTid ] is not equal to 0 and there is at least one picture in the DPB that is marked
1701    //   as "needed for output" for which the associated variable PicLatencyCount that is greater than or equal to
1702    //   SpsMaxLatencyPictures[ HighestTid ].
1703    Bool anyPicWithGtOrEqLatencyCnt = false;
1704    for (TComList<TComPic*>::iterator itP = picsMarkedForOutput.begin(); itP != picsMarkedForOutput.end() && !anyPicWithGtOrEqLatencyCnt; itP++ )
1705    {
1706      anyPicWithGtOrEqLatencyCnt = anyPicWithGtOrEqLatencyCnt || ( (*itP)->getPicLatencyCount() >= sps->getSpsMaxLatencyPictures( m_highestTid ));
1707    }
1708    Bool cond2 = ( sps->getSpsMaxLatencyIncreasePlus1( m_highestTid ) != 0 ) && anyPicWithGtOrEqLatencyCnt;
1709
1710    if ( cond1 || cond2 )
1711    {
1712      xC524Bumping();
1713    }
1714    else
1715    {
1716      repeat = false;
1717    }
1718  }
1719}
1720
1721Void TAppDecTop::xC524Bumping( )
1722{
1723  ////////////////////////////////////////////////////////////////////////////////
1724  // C.5.2.4 "Bumping" process
1725  ////////////////////////////////////////////////////////////////////////////////
1726
1727  // The "bumping" process consists of the following ordered steps:
1728
1729  // 1.  The picture that is first for output is selected as the one having the smallest value of PicOrderCntVal of all pictures
1730  //     in the DPB marked as "needed for output".
1731  TComPic* pic = *(m_dpb.getSubDpb( 0, false)->getPicsMarkedNeedForOutput().begin()); // pics are sorted, so take first
1732
1733  // 2.  The picture is cropped, using the conformance cropping window specified in the active SPS for the picture,
1734  //     the cropped picture is output, and the picture is marked as "not needed for output".
1735  xCropAndOutput( pic );
1736  pic->setOutputMark( false );
1737
1738  //3.  When the picture storage buffer that included the picture that was cropped and output contains a picture marked
1739  //    as "unused for reference", the picture storage buffer is emptied.
1740  if (pic->getMarkedUnUsedForReference() )
1741  {
1742    m_dpb.removePic( pic );
1743  }
1744
1745  // NOTE - For any two pictures picA and picB that belong to the same CVS and are output by the "bumping process", when picA
1746  //        is output earlier than picB, the value of PicOrderCntVal of picA is less than the value of PicOrderCntVal of picB.
1747}
1748
1749
1750Void TAppDecTop::xF813ComDecProcForACodedPic( DecProcPart curPart, Bool picPosInAuIndication )
1751{
1752  ////////////////////////////////////////////////////////////////////////////////
1753  // F.8.1.3  Common decoding process for a coded picture
1754  ////////////////////////////////////////////////////////////////////////////////
1755
1756  // PicPosInAuIndication is interpreted based on curPart.
1757  // - If curPart is equal to START_PIC               , it indicates whether the current pic is the first in the current AU.
1758  // - Otherwise (if curPart is equal to FINALIZE_PIC), it indicates whether the current pic is the last  in the current AU.
1759
1760  if (curPart == START_PIC )
1761  {
1762    Bool curPicIsFirstInAu = picPosInAuIndication;
1763
1764    Int nuhLayerId = m_curPic->getLayerId();
1765
1766    if ( !m_vps->getVpsBaseLayerInternalFlag() && m_vps->getVpsBaseLayerAvailableFlag() &&
1767      ( m_targetDecLayerSetIdx >= 0 && m_targetDecLayerSetIdx <= m_vps->getVpsNumLayerSetsMinus1() ) &&
1768      m_curPic->getSlice(0)->getTemporalId() <= m_vps->getSubLayersVpsMaxMinus1( 0 ) && curPicIsFirstInAu )
1769    {
1770      // When vps_base_layer_internal_flag is equal to 0, vps_base_layer_available_flag is equal to 1,
1771      // TargetDecLayerSetIdx is in the range of 0 to vps_num_layer_sets_minus1, inclusive,
1772      // TemporalId is less than or equal to sub_layers_vps_max_minus1[ 0 ], and the current picture
1773      // is the first coded picture of an access unit, clause F.8.1.8 is invoked prior to decoding the current picture.
1774
1775      assert( false ); //TBD
1776    }
1777
1778    //  When the current picture is an IRAP picture, the variable HandleCraAsBlaFlag is derived as specified in the following:
1779    if ( m_curPic->isIrap() )
1780    {
1781      if ( m_handleCraAsBlaFlagSetByExtMeans )
1782      {
1783        // If some external means not specified in this Specification is available to set the variable HandleCraAsBlaFlag to
1784        // a value for the current picture, the variable HandleCraAsBlaFlag is set equal to the value provided by the external means.
1785      }
1786      else
1787      {
1788        // - Otherwise, the variable HandleCraAsBlaFlag is set equal to 0.
1789        m_handleCraAsBlaFlag = false;
1790      }
1791    }
1792
1793    if ( m_curPic->isIrap() && nuhLayerId == m_smallestLayerId )
1794    {
1795      // When the current picture is an IRAP picture and has nuh_layer_id equal to SmallestLayerId, the following applies:
1796      // The variable NoClrasOutputFlag is specified as follows:
1797
1798      if( m_firstSliceInBitstream )
1799      {
1800        //  - If the current picture is the first picture in the bitstream, NoClrasOutputFlag is set equal to 1.
1801        m_curPic->setNoClrasOutputFlag(true );
1802      }
1803      else if( m_eosInLayer[ 0 ] || m_eosInLayer[ nuhLayerId ] )
1804      {
1805        //  - Otherwise, if the current picture is included in the first access unit that follows an access unit
1806        //    including an end of sequence NAL unit with nuh_layer_id equal to SmallestLayerId or 0 in decoding order,
1807        //    NoClrasOutputFlag is set equal to 1.
1808
1809        m_curPic->setNoClrasOutputFlag(true );
1810      }
1811      else if ( m_curPic->isBla() || (m_curPic->isCra() && m_handleCraAsBlaFlag ))
1812      {
1813        //  - Otherwise, if the current picture is a BLA picture or a CRA picture with HandleCraAsBlaFlag equal to 1,
1814        //    NoClrasOutputFlag is set equal to 1.
1815        m_curPic->setNoClrasOutputFlag(true );
1816      }
1817      else if ( m_curPic->isIdr() && m_curPic->getSlice(0)->getCrossLayerBlaFlag() )
1818      {
1819        //  - Otherwise, if the current picture is an IDR picture with cross_layer_bla_flag is equal to 1,
1820        //    NoClrasOutputFlag is set equal to 1.
1821        m_curPic->setNoClrasOutputFlag(true );
1822      }
1823      else if ( m_noClrasOutputFlagSetByExtMeans )
1824      {
1825        m_curPic->setNoClrasOutputFlag( m_noClrasOutputFlag );
1826        //  - Otherwise, if some external means, not specified in this Specification, is available to set NoClrasOutputFlag,
1827        //    NoClrasOutputFlag is set by the external means.
1828      }
1829      else
1830      {
1831        //  - Otherwise, NoClrasOutputFlag is set equal to 0.
1832        m_curPic->setNoClrasOutputFlag(false );
1833      }
1834
1835      //-  When NoClrasOutputFlag is equal to 1, the variable LayerInitializedFlag[ i ] is set equal to 0 for all values
1836      //  of i from 0 to vps_max_layer_id, inclusive, and the variable FirstPicInLayerDecodedFlag[ i ] is set equal to 0
1837      //  for all values of i from 0 to vps_max_layer_id, inclusive.
1838      if ( m_curPic->getNoClrasOutputFlag( ) )
1839      {
1840        for (Int i = 0; i <= m_vps->getVpsMaxLayerId(); i++)
1841        {
1842          m_layerInitilizedFlag       [i] = false;
1843          m_firstPicInLayerDecodedFlag[i] = false;
1844        }
1845      }
1846    }
1847
1848    // The variables LayerResetFlag and dolLayerId are derived as follows:
1849    Int dolLayerId = -1;
1850    if ( m_curPic->isIrap() && nuhLayerId > m_smallestLayerId )
1851    {
1852      // - If the current picture is an IRAP picture and has nuh_layer_id nuhLayerId greater than SmallestLayerId,
1853      //   the following applies:
1854
1855      if( m_eosInLayer[ nuhLayerId ] )
1856      {
1857        // -  If the current picture is the first picture, in decoding order, that follows an end of sequence NAL unit with
1858        //    nuh_layer_id equal to nuhLayerId, LayerResetFlag is set equal to 1 and dolLayerId is set equal to the nuh_layer_id
1859        //    value of the current NAL unit.
1860
1861        m_layerResetFlag = true;
1862        dolLayerId = nuhLayerId;
1863      }
1864      else  if( ( m_curPic->isCra() && m_handleCraAsBlaFlag ) ||
1865        (m_curPic->isIdr() && m_curPic->getSlice(0)->getCrossLayerBlaFlag() ) || m_curPic->isBla() )
1866      {
1867        // - Otherwise, if the current picture is a CRA picture with HandleCraAsBlaFlag equal to 1, an IDR picture with
1868        //   cross_layer_bla_flag is equal to 1 or a BLA picture, LayerResetFlag is set equal to 1 and dolLayerId is set
1869        //   equal to the nuh_layer_id value of the current NAL unit.
1870        m_layerResetFlag = true;
1871        dolLayerId = nuhLayerId;
1872      }
1873      else
1874      {
1875        // -   Otherwise, LayerResetFlag is set equal to 0.
1876        m_layerResetFlag = false;
1877      }
1878
1879      // NOTE 1 - An end of sequence NAL unit, a CRA picture with HandleCraAsBlaFlag equal to 1, an IDR picture with
1880      // cross_layer_bla_flag equal to 1, or a BLA picture, each with nuh_layer_id nuhLayerId greater than SmallestLayerId,
1881      // may be present to indicate a discontinuity of the layer with nuh_layer_id equal to nuhLayerId and its predicted layers.
1882
1883      if (m_layerResetFlag )
1884      {
1885        //When LayerResetFlag is equal to 1, the following applies:
1886        //  - The values of LayerInitializedFlag and FirstPicInLayerDecodedFlag are updated as follows:
1887
1888        for( Int i = 0; i < m_vps->getNumPredictedLayers( dolLayerId ); i++ )
1889        {
1890          Int iLayerId = m_vps->getIdPredictedLayer(  dolLayerId , i );
1891          m_layerInitilizedFlag       [ iLayerId ] = false;
1892          m_firstPicInLayerDecodedFlag[ iLayerId ] = false;
1893        }
1894
1895        //  - Each picture that is in the DPB and has nuh_layer_id equal to dolLayerId is marked as "unused for reference".
1896        m_dpb.markSubDpbAsUnusedForReference( dolLayerId );
1897
1898        //  - When NumPredictedLayers[ dolLayerId ] is greater than 0, each picture that is in the DPB and has nuh_layer_id
1899        //    equal to any value of IdPredictedLayer[ dolLayerId ][ i ] for the values of i in the range of 0 to
1900        //    NumPredictedLayers[ dolLayerId ] - 1, inclusive, is marked as "unused for reference".
1901
1902        for( Int i = 0; i <= m_vps->getNumPredictedLayers( dolLayerId )- 1; i++  )
1903        {
1904          m_dpb.markSubDpbAsUnusedForReference( m_vps->getIdPredictedLayer( dolLayerId, i ) );
1905        }
1906      }
1907    }
1908    else
1909    {
1910      // - Otherwise, LayerResetFlag is set equal to 0.
1911      m_layerResetFlag = false;
1912    }
1913
1914    if ( m_curPic->isIrap() )
1915    {
1916      // When the current picture is an IRAP picture, the following applies:
1917
1918      if ( m_curPic->isIdr() || m_curPic->isBla() || m_curPic->getDecodingOrder() == 0 || m_eosInLayer[nuhLayerId] )
1919      {
1920        // - If the current picture with a particular value of nuh_layer_id is an IDR picture, a BLA picture, the first picture
1921        //   with that particular value of nuh_layer_id in the bitstream in decoding order or the first picture with that
1922        //   particular value of nuh_layer_id that follows an end of sequence NAL unit with that particular value of nuh_layer_id
1923        //   in decoding order, the variable NoRaslOutputFlag is set equal to 1.
1924
1925        m_curPic->setNoRaslOutputFlag(  true );
1926      }
1927      else if ( m_layerInitilizedFlag[ nuhLayerId ] == 0 && xAllRefLayersInitilized( nuhLayerId ) )
1928      {
1929        // Otherwise, if LayerInitializedFlag[ nuh_layer_id ] is equal to 0 and LayerInitializedFlag[ refLayerId ] is equal to 1
1930        // for all values of refLayerId equal to IdDirectRefLayer[ nuh_layer_id ][ j ], where j is in the range of 0 to
1931        // NumDirectRefLayers[ nuh_layer_id ] - 1, inclusive, the variable NoRaslOutputFlag is set equal to 1.
1932
1933        m_curPic->setNoRaslOutputFlag(  true );
1934      }
1935      else
1936      {
1937        // - Otherwise, the variable NoRaslOutputFlag is set equal to HandleCraAsBlaFlag.
1938        m_curPic->setNoRaslOutputFlag(  m_handleCraAsBlaFlag );
1939      }
1940    }
1941
1942    // The following applies for the decoding of the current picture:
1943    if ( m_curPic->isIrap() && m_curPic->getNoRaslOutputFlag() && (
1944      ( nuhLayerId == 0 ) ||
1945      ( m_layerInitilizedFlag[ nuhLayerId ] == 0   && m_vps->getNumDirectRefLayers( nuhLayerId ) == 0  ) ||
1946      ( m_layerInitilizedFlag[ nuhLayerId ] == 0 && xAllRefLayersInitilized( nuhLayerId ) )
1947      ) )
1948    {
1949      // When the current picture is an IRAP picture with NoRaslOutputFlag equal to 1 and one of the following conditions is true,
1950      // LayerInitializedFlag[ nuh_layer_id ] is set equal to 1:
1951      // - nuh_layer_id is equal to 0.
1952      // - LayerInitializedFlag[ nuh_layer_id ] is equal to 0 and NumDirectRefLayers[ nuh_layer_id ] is equal to 0.
1953      // - LayerInitializedFlag[ nuh_layer_id ] is equal to 0 and LayerInitializedFlag[ refLayerId ] is equal to 1 for all values of
1954      //   refLayerId equal to IdDirectRefLayer[ nuh_layer_id ][ j ], where j is in the range of 0 to NumDirectRefLayers[ nuh_layer_id ] - 1, inclusive.
1955
1956      m_layerInitilizedFlag[ nuhLayerId ] = true;
1957    }
1958
1959    // The following applies for the decoding of the current picture:
1960
1961    if ( nuhLayerId == 0 )
1962    {
1963      //  If the current picture has nuh_layer_id equal to 0, the decoding process for the current picture takes as inputs the syntax elements
1964      //  and upper-case variables from clause F.7 and the decoding process for a coded picture with nuh_layer_id equal to 0 as specified in clause F.8.1.4
1965      //  is invoked.
1966
1967      xF814decProcForCodPicWithLIdZero( curPart );
1968    }
1969    else
1970    {
1971      Bool decodedPicWithLayerIdZeroProvided = false;
1972      if ( !m_vps->getVpsBaseLayerInternalFlag() && m_vps->getVpsBaseLayerAvailableFlag() &&
1973        ( m_targetDecLayerSetIdx >= 0 && m_targetDecLayerSetIdx <= m_vps->getVpsNumLayerSetsMinus1() ) &&
1974        m_curPic->getSlice(0)->getTemporalId() <= m_vps->getSubLayersVpsMaxMinus1( 0 ) && curPicIsFirstInAu
1975        && decodedPicWithLayerIdZeroProvided )
1976      {
1977        assert( false ); //TBD
1978        //TBD: Hybrid scalability
1979        //  When vps_base_layer_internal_flag is equal to 0, vps_base_layer_available_flag is equal to 1,
1980        //  TargetDecLayerSetIdx is in the range of 0 to vps_num_layer_sets_minus1, inclusive,
1981        //  TemporalId is less than or equal to sub_layers_vps_max_minus1[ 0 ], the current picture
1982        //  is the first coded picture of an access unit, and a decoded picture with nuh_layer_id equal
1983        //  to 0 is provided by external means for the current access unit, clause F.8.1.9 is invoked
1984        //  after the decoding of the slice segment header of the first slice segment, in decoding order,
1985        //  of the current picture, but prior to decoding any slice segment of the first
1986        //  coded picture of the access unit.
1987      }
1988
1989      m_decProcPocAndRps = ANNEX_F;
1990      // For the decoding of the slice segment header of the first slice segment, in decoding order, of the current picture,
1991      // the decoding process for starting the decoding of a coded picture with nuh_layer_id greater than 0 specified in
1992      // clause F.8.1.5 is invoked.  --> This is done in the loop when receiving slices.
1993
1994      // The decoding process is already selected before.
1995    }
1996  }
1997  else if( curPart == FINALIZE_PIC )
1998  {
1999    Bool curPicIsLastInAu = picPosInAuIndication;
2000
2001    if (m_curPic->getLayerId() == 0 )
2002    {
2003      xF814decProcForCodPicWithLIdZero( curPart );
2004    }
2005    else
2006    {
2007      // - After all slices of the current picture have been decoded, the decoding process for ending the decoding of a
2008      //   coded picture with nuh_layer_id greater than 0 specified in clause F.8.1.6 is invoked.
2009      xF816decProcEndDecOfCodPicLIdGrtZero( );     
2010    }
2011
2012    TComSlice* slice = m_curPic->getSlice(0);
2013    const TComVPS* vps = slice->getVPS();
2014
2015    if ( curPicIsLastInAu )
2016    {
2017      //When the current picture is the last coded picture in an access unit in BitstreamToDecode, the following steps apply after
2018      // the decoding of the current picture, prior to the decoding of the next picture:
2019
2020      //-  PicOutputFlag is updated as follows:
2021      TComPic* picAtOutputLayer = NULL;
2022      Int outputLayerId = -1;
2023
2024      // Try to find pic at output layer.
2025      if( vps->getAltOutputLayerFlag( m_targetOptLayerSetIdx ) )
2026      {
2027        // When alt_output_layer_flag is equal to 1, the target output layer set can only contain one output layer.
2028        assert( vps->getNumOutputLayersInOutputLayerSet( m_targetOptLayerSetIdx ) == 1 );
2029        outputLayerId = vps->getTargetOptLayerIdList(m_targetOptLayerSetIdx)[0];
2030        picAtOutputLayer = m_curAu.getPic( outputLayerId );
2031      }
2032
2033      if ( vps->getAltOutputLayerFlag( m_targetOptLayerSetIdx ) &&
2034        ( picAtOutputLayer == NULL || (picAtOutputLayer != NULL && !picAtOutputLayer->getPicOutputFlag() ) ) )
2035      {
2036        // If alt_output_layer_flag[ TargetOlsIdx ] is equal to 1 and the current access unit either does
2037        // not contain a picture at the output layer or contains a picture at the output layer that has PicOutputFlag equal to 0:
2038
2039        // - The list nonOutputLayerPictures is set to be the list of the pictures of the access unit with PicOutputFlag equal to 1 and
2040        //   with nuh_layer_id values among the nuh_layer_id values of the reference layers of the output layer.
2041        TComList<TComPic*> nonOutputLayerPictures;
2042        for( TComList<TComPic*>::iterator itP= m_curAu.begin();  itP != m_curAu.end() ; itP++ )
2043        {
2044          TComPic* pic = (*itP);
2045          Bool isRefernceLayerOfOutputLayer = false;
2046          for ( Int i = 0; i < vps->getNumRefLayers( outputLayerId ) && !isRefernceLayerOfOutputLayer; i++ )
2047          {
2048            if ( pic->getLayerId() == vps->getIdRefLayer(outputLayerId, i) )
2049            {
2050              isRefernceLayerOfOutputLayer = true;
2051            }
2052          }
2053
2054          if ( pic->getPicOutputFlag() && isRefernceLayerOfOutputLayer )
2055          {
2056            nonOutputLayerPictures.pushBack( pic );
2057          }
2058        }
2059
2060        if (nonOutputLayerPictures.size() != 0 )
2061        {
2062          // -  When the list nonOutputLayerPictures is not empty,
2063          //    The picture with the highest nuh_layer_id value among the list nonOutputLayerPictures is removed from the list nonOutputLayerPictures.
2064          //    As in AU the picture with the highest layer id is the last
2065          nonOutputLayerPictures.pop_back();
2066        }
2067
2068        //  -  PicOutputFlag for each picture that is included in the list nonOutputLayerPictures is set equal to 0.
2069        for( TComList<TComPic*>::iterator itP= nonOutputLayerPictures.begin();  itP != nonOutputLayerPictures.end() ; itP++ )
2070        {
2071          (*itP)->setPicOutputFlag( false );
2072        }
2073      }
2074      else
2075      {
2076        //Otherwise, PicOutputFlag for pictures that are not included in an output layer is set equal to 0.
2077        for( TComList<TComPic*>::iterator itP= m_curAu.begin();  itP != m_curAu.end() ; itP++ )
2078        {
2079          TComPic* pic = (*itP);
2080
2081          Bool includedInOutputLayer = false;
2082          for (Int i = 0 ; i < vps->getNumOutputLayersInOutputLayerSet( m_targetOptLayerSetIdx ) && !includedInOutputLayer; i++)
2083          {
2084            includedInOutputLayer = ( pic->getLayerId() ==  vps->getTargetOptLayerIdList(m_targetOptLayerSetIdx)[i]);
2085          }
2086
2087          if ( !includedInOutputLayer )
2088          {
2089            pic->setPicOutputFlag( false );
2090          }
2091        }
2092      }
2093
2094      // When vps_base_layer_internal_flag is equal to 0, vps_base_layer_available_flag is equal to 1 and
2095      // TargetDecLayerSetIdx is in the range of 0 to vps_num_layer_sets_minus1, inclusive
2096
2097      if( !vps->getVpsBaseLayerInternalFlag() && vps->getVpsBaseLayerAvailableFlag() && ( m_targetDecLayerSetIdx >= 0 && m_targetDecLayerSetIdx <= vps->getVpsNumLayerSetsMinus1()   ) )
2098      {
2099        if( !m_baseLayerOutputFlag )
2100        {
2101          // Check if base layer is a reference layer of the output layer
2102          // and if the access unit does not contain a picture at any other reference layer of the output layer
2103          Bool baseLayerIsRefOfOutputLayer = false;
2104          Bool auDoesNotContainPicAtAnyOtherRefLayerOfOptLayer = true;
2105          if ( vps->getAltOutputLayerFlag( m_targetOptLayerSetIdx ))
2106          {
2107            assert( outputLayerId >= 0 );
2108
2109            for (Int i = 0; i < vps->getNumRefLayers( outputLayerId ); i++ )
2110            {
2111              Int refLayerId = vps->getIdRefLayer(outputLayerId, i);
2112              if( refLayerId == 0 )
2113              {
2114                baseLayerIsRefOfOutputLayer = true;
2115              }
2116              else
2117              {
2118                if ( m_curAu.getPic( refLayerId ) != NULL )
2119                {
2120                  auDoesNotContainPicAtAnyOtherRefLayerOfOptLayer = false;
2121                }
2122              }
2123            }
2124          }
2125
2126          // If alt_output_layer_flag[ TargetOlsIdx ] is equal to 1, the base layer is a reference layer of the output layer,
2127          // the access unit does not contain a picture at the output layer or contains a picture at the output layer that has
2128          // PicOutputFlag equal to 0, and the access unit does not contain a picture at any other reference layer of the output layer,
2129          // BaseLayerPicOutputFlag is set equal to 1
2130
2131          if ( vps->getAltOutputLayerFlag( m_targetOptLayerSetIdx ) && baseLayerIsRefOfOutputLayer
2132            && ( ( picAtOutputLayer == NULL ) || ( picAtOutputLayer != NULL && !picAtOutputLayer->getPicOutputFlag()  ) )
2133            &&  auDoesNotContainPicAtAnyOtherRefLayerOfOptLayer )
2134          {
2135            m_baseLayerPicOutputFlag = true;
2136          }
2137          else
2138          {
2139            m_baseLayerPicOutputFlag = false;
2140          }
2141        }
2142        else
2143        {
2144          m_baseLayerPicOutputFlag = true;
2145        }
2146
2147        // NOTE 3 - The BaseLayerPicOutputFlag for each access unit is to be sent by an external means
2148        // to the base layer decoder for controlling the output of base layer decoded pictures.
2149        // BaseLayerPicOutputFlag equal to 1 for an access unit specifies that the base layer picture of the access unit is to be output.
2150        // BaseLayerPicOutputFlag equal to 0 for an access unit specifies that the base layer picture of the access unit is not to be output.
2151
2152        //  The sub-DPB for the layer with nuh_layer_id equal to 0 is set to be empty.
2153        m_dpb.emptySubDpb( 0 );
2154      }
2155
2156      // The variable AuOutputFlag that is associated with the current access unit is derived as follows:
2157
2158      // Derive if at least one picture in the current access unit has PicOutputFlag equal to 1
2159      Bool atLeastOnePicInAuWithPicOptFlagOne = false;
2160      for( TComList<TComPic*>::iterator itP= m_curAu.begin();  itP != m_curAu.end() ; itP++ )
2161      {
2162        if ( (*itP)->getPicOutputFlag() )
2163        {
2164          atLeastOnePicInAuWithPicOptFlagOne = true;
2165        }
2166      }
2167
2168      //If at least one picture in the current access unit has PicOutputFlag equal to 1
2169      if ( atLeastOnePicInAuWithPicOptFlagOne )
2170      {
2171        m_auOutputFlag = true;
2172      }
2173      else
2174      {
2175        m_auOutputFlag = false;
2176      }
2177
2178      // The variable PicLatencyCount that is associated with the current access unit is set equal to 0.
2179      m_curAu.setPicLatencyCount( 0 );
2180
2181      if ( m_auOutputFlag )
2182      {
2183        // for each access unit in the DPB
2184        // that has at least one picture marked as "needed for output" and
2185        // follows the current access unit in output order, the associated
2186        // variable PicLatencyCount is set equal to PicLatencyCount + 1.
2187
2188        TComList<TComAu*> aus = m_dpb.getAusHavingPicsMarkedForOutput(); // <-- current AU is actually not yet in DPB, but this does not matter here.
2189
2190        for(TComList<TComAu*>::iterator itA= aus.begin(); ( itA!=aus.end()); itA++)
2191        {
2192          if( m_curAu.getPoc() < (*itA)->getPoc())
2193          {
2194            (*itA)->setPicLatencyCount( (*itA)->getPicLatencyCount() + 1 );
2195          }
2196        }
2197      }
2198    }
2199  }
2200}
2201
2202Void TAppDecTop::xF814decProcForCodPicWithLIdZero( DecProcPart curPart )
2203{
2204  ////////////////////////////////////////////////////////////////////////////////
2205  // F.8.1.4 Decoding process for a coded picture with nuh_layer_id equal to 0
2206  ////////////////////////////////////////////////////////////////////////////////
2207
2208  x813decProcForCodPicWithLIdZero( curPart );
2209
2210  if (curPart == START_PIC )
2211  {
2212    m_decProcPocAndRps = ANNEX_F;
2213  }
2214  else if (curPart == FINALIZE_PIC )
2215  {
2216    if ( !m_firstPicInLayerDecodedFlag[0] )
2217    {
2218      m_firstPicInLayerDecodedFlag[0] = true;
2219    }
2220  }
2221}
2222
2223Void TAppDecTop::xF13521InitDpb()
2224{
2225  ////////////////////////////////////////////////////////////////////////////////
2226  // F.13.5.2.1 General
2227  ////////////////////////////////////////////////////////////////////////////////
2228
2229  // According to spec, no dbpSize values are given for OLS 0, however they are used in F.13.5.2.1.
2230  // This might be an issue of the spec. As workaround use sps for OLS 0 here.
2231
2232  if ( m_targetOptLayerSetIdx == 0 )
2233  { 
2234    m_maxNumReorderPics            = m_sps->getSpsMaxNumReorderPics      ( m_highestTid );
2235    m_maxLatencyIncreasePlus1      = m_sps->getSpsMaxLatencyIncreasePlus1( m_highestTid );
2236    m_maxLatencyValue              = m_sps->getSpsMaxLatencyPictures     ( m_highestTid );
2237    m_maxDecPicBufferingMinus1[0]  = m_sps->getMaxDecPicBuffering        ( m_highestTid );
2238  }
2239  else
2240  {
2241    const TComDpbSize* dpbSize = m_vps->getDpbSize();
2242    m_maxNumReorderPics       = dpbSize->getMaxVpsNumReorderPics      ( m_targetOptLayerSetIdx, m_highestTid );
2243    m_maxLatencyIncreasePlus1 = dpbSize->getMaxVpsLatencyIncreasePlus1( m_targetOptLayerSetIdx, m_highestTid );
2244    m_maxLatencyValue         = dpbSize->getVpsMaxLatencyPictures     ( m_targetOptLayerSetIdx, m_highestTid );
2245
2246    for(Int i = 0; i < MAX_NUM_LAYER_IDS; i++)
2247    {
2248      m_maxDecPicBufferingMinus1[ i ] = MIN_INT;
2249    }
2250    for( Int i = 0; i <= m_vps->getMaxLayersMinus1(); i++ )
2251    {
2252      Int currLayerId = m_vps->getLayerIdInNuh( i );
2253      for(Int layerIdx = 0 ; layerIdx < m_vps->getNumLayersInIdList( m_targetDecLayerSetIdx); layerIdx++ )
2254      {
2255        if( m_vps->getLayerSetLayerIdList( m_targetDecLayerSetIdx, layerIdx ) == currLayerId )
2256        {
2257          m_maxDecPicBufferingMinus1[currLayerId] = dpbSize->getMaxVpsDecPicBufferingMinus1( m_targetDecLayerSetIdx, layerIdx, m_highestTid );
2258        }
2259      }
2260    }
2261  }
2262}
2263
2264Void TAppDecTop::xF13522OutputAndRemOfPicsFromDpb( Bool beforePocDerivation )
2265{
2266  ////////////////////////////////////////////////////////////////////////////////
2267  // F.13.5.2.2 Output and removal of pictures from the DPB
2268  ////////////////////////////////////////////////////////////////////////////////
2269
2270  if( beforePocDerivation )
2271  {
2272    // F.13.5.2.2
2273    // Part before POC and RPS derivation.
2274
2275    if( m_curPic->getDecodingOrder() != 0 )
2276    {
2277      // When the current picture is not picture 0 in the current layer,
2278      // the output and removal of pictures in the current layer, with nuh_layer_id equal to currLayerId,
2279      // from the DPB before the decoding of the current picture, i.e., picture n, but after parsing the
2280      // slice header of the first slice of the current picture and before the invocation of the decoding
2281      // process for picture order count, happens instantaneously when the first decoding unit of the current
2282      // picture is removed from the CPB and proceeds as follows:
2283
2284      if( m_curPic->getIsPocResettingPic() )
2285      {
2286        // When the current picture is a POC resetting picture, all pictures in the DPB that do
2287        // not belong to the current access unit and that are marked as "needed for output" are
2288        // output, starting with pictures with the smallest value of PicOrderCntVal of all pictures
2289        // excluding those in the current access unit in the DPB, in ascending order of the PicOrderCntVal
2290        // values, and pictures with the same value of PicOrderCntVal are output in ascending order
2291        // of the nuh_layer_id values. When a picture is output, it is cropped using the conformance cropping
2292        // window specified in the active SPS for the picture, the cropped picture is output, and
2293        // the picture is marked as "not needed for output"
2294
2295        TComList<TComAu*>* aus = m_dpb.getAus(); // Theses are sorted by POC.
2296        for (TComList<TComAu*>::iterator itA = aus->begin(); itA != aus->end(); itA++ )
2297        {
2298          //Pictures in AUs are sorted by nuh_layer_id;
2299          for (TComAu::iterator itP = (*itA)->begin(); itP != (*itA)->end(); itP++ )
2300          {
2301            TComPic* pic = (*itP);
2302            if ( !m_curAu.containsPic( pic ) )
2303            {
2304              xCropAndOutput( pic );
2305              pic->setOutputMark( false );
2306            }
2307          }
2308        }
2309      }
2310    }
2311  }
2312  else if ( !beforePocDerivation )
2313  {
2314    //  The variable listOfSubDpbsToEmpty is derived as follows:
2315
2316    Int nuhLayerId = m_curPic->getLayerId();
2317    TComList<TComSubDpb*> listOfSubDpbsToEmpty;
2318
2319    if ( m_newVpsActivatedbyCurAu && ( m_curPic->isIrap()&& nuhLayerId == m_smallestLayerId
2320      && m_curPic->getNoRaslOutputFlag() && m_curPic->getNoClrasOutputFlag() ) )
2321    {
2322      // If a new VPS is activated by the current access unit or the current picture is IRAP picture
2323      // with nuh_layer_id equal to SmallestLayerId,   NoRaslOutputFlag equal to 1, and NoClrasOutputFlag equal to 1,
2324      // listOfSubDpbsToEmpty is set equal to all the sub-DPBs.
2325      listOfSubDpbsToEmpty = (*m_dpb.getSubDpbs());
2326    }
2327    else if (m_curPic->isIrap() && m_vps->getNumDirectRefLayers( nuhLayerId ) == 0 &&
2328      nuhLayerId > m_smallestLayerId && m_curPic->getNoRaslOutputFlag() && m_layerResetFlag  )
2329    {
2330      // Otherwise, if the current picture is an IRAP picture with any nuh_layer_id value indepLayerId
2331      // such that NumDirectRefLayers[ indepLayerId ] is equal to 0 and indepLayerId is greater than
2332      // SmallestLayerId, and with NoRaslOutputFlag equal to 1, and LayerResetFlag is equal to 1,
2333
2334      // listOfSubDpbsToEmpty is set equal to the sub-DPBs containing the current layer and the sub-DPBs
2335      // containing the predicted layers of the current layer.
2336
2337      listOfSubDpbsToEmpty.pushBack( m_dpb.getSubDpb( nuhLayerId, false  ) );
2338      for( Int i = 0; i < m_vps->getNumPredictedLayers( nuhLayerId ); i++  )
2339      {
2340        listOfSubDpbsToEmpty.pushBack( m_dpb.getSubDpb( m_vps->getIdPredictedLayer( nuhLayerId, i), false  ) );
2341      }
2342    }
2343    else
2344    {
2345      // Otherwise, crossLayerBufferEmptyFlag is set equal to 0.
2346
2347      // The SPEC seems to have an issue here. Use current subDpb as in form F.13.3.2
2348      listOfSubDpbsToEmpty.pushBack( m_dpb.getSubDpb( nuhLayerId, false  ) );
2349    }
2350
2351    // If the current picture is an IRAP picture with NoRaslOutputFlag equal to 1 and any of
2352    // the following conditions is true:
2353    //   - nuh_layer_id equal to SmallestLayerId,
2354    //   - nuh_layer_id of the current layer is greater than SmallestLayerId, and NumDirectRefLayers[ nuh_layer_id ]
2355    //     is equal to 0,
2356
2357    if ( m_curPic->isIrap() && m_curPic->getNoRaslOutputFlag() && (
2358      ( nuhLayerId == m_smallestLayerId ) ||
2359      ( ( nuhLayerId > m_smallestLayerId ) && m_vps->getNumDirectRefLayers( nuhLayerId ) == 0 ) )
2360      )
2361    {
2362      // 1. The variable NoOutputOfPriorPicsFlag is derived for the decoder under test as follows:
2363      Bool noOutputOfPriorPicsFlag;
2364      if( m_curPic->isCra() )
2365      {
2366        noOutputOfPriorPicsFlag = true;
2367        // - If the current picture is a CRA picture, NoOutputOfPriorPicsFlag is set equal to 1
2368        // (regardless of the value of no_output_of_prior_pics_flag).
2369      }
2370      else if ( false )
2371      {
2372        // TBD
2373        // - Otherwise, if the value of pic_width_in_luma_samples, pic_height_in_luma_samples,
2374        //   chroma_format_idc, bit_depth_luma_minus8, bit_depth_chroma_minus8, separate_colour_plane_flag,
2375        //   or sps_max_dec_pic_buffering_minus1[ HighestTid ] derived from the active SPS for the current
2376        //   layer is different from the value of pic_width_in_luma_samples, pic_height_in_luma_samples,
2377        //   chroma_format_idc, bit_depth_luma_minus8, bit_depth_chroma_minus8, separate_colour_plane_flag,
2378        //   or sps_max_dec_pic_buffering_minus1[ HighestTid ], respectively, derived from the SPS that
2379        //   was active for the current layer when decoding the preceding picture in the current layer,
2380        //   NoOutputOfPriorPicsFlag may (but should not) be set equal to 1 by the decoder under test,
2381        //   regardless of the value of no_output_of_prior_pics_flag.
2382        //    NOTE - Although setting NoOutputOfPriorPicsFlag equal to no_output_of_prior_pics_flag is preferred
2383        //    under these conditions, the decoder under test is allowed to set NoOutputOfPriorPicsFlag to 1 in this case.
2384        // - Otherwise, NoOutputOfPriorPicsFlag is set equal to no_output_of_prior_pics_flag.
2385
2386        // assert( 1 );
2387      }
2388      else
2389      {
2390        // - Otherwise, NoOutputOfPriorPicsFlag is set equal to no_output_of_prior_pics_flag.
2391        noOutputOfPriorPicsFlag = m_curPic->getSlice(0)->getNoOutputPriorPicsFlag();
2392      }
2393
2394      // 2. The value of NoOutputOfPriorPicsFlag derived for the decoder under test is applied for the HRD as follows:
2395      if ( !noOutputOfPriorPicsFlag )
2396      {
2397        // - If NoOutputOfPriorPicsFlag is equal to 0, all non-empty picture storage buffers in all the sub-DPBs included
2398        //   in listOfSubDpbsToEmpty are output by repeatedly invoking the "bumping" process specified in clause
2399        //   F.13.5.2.4 until all these pictures are marked as "not needed for output".
2400
2401        Bool repeat = true;
2402        while (repeat )
2403        {
2404          Bool allPicsMarkedNotNeedForOutput = true;
2405          for (TComList<TComSubDpb*>::iterator itS = listOfSubDpbsToEmpty.begin(); itS != listOfSubDpbsToEmpty.end() && allPicsMarkedNotNeedForOutput; itS++ )
2406          {
2407            allPicsMarkedNotNeedForOutput = allPicsMarkedNotNeedForOutput && ( (*itS)->areAllPicsMarkedNotNeedForOutput() );
2408          }
2409
2410          if ( !allPicsMarkedNotNeedForOutput )
2411          {
2412            xF13524Bumping( m_dpb.getAusHavingPicsMarkedForOutput() );
2413          }
2414          else
2415          {
2416            repeat = false;
2417          }
2418        }
2419      }
2420      else
2421      {
2422        // - Otherwise (NoOutputOfPriorPicsFlag is equal to 1), all picture storage buffers containing a picture
2423        //   that is marked as "not needed for output" and "unused for reference" are emptied (without output),
2424        //   all pictures that are contained in a sub-DPB included in listOfSubDpbsToEmpty are emptied, and the sub-DPB
2425        //   fullness of each sub-DPB is decremented by the number of picture storage buffers emptied in that sub-DPB.
2426        m_dpb.emptyNotNeedForOutputAndUnusedForRef();
2427
2428        for( TComList<TComSubDpb*>::iterator iS = listOfSubDpbsToEmpty.begin(); iS != listOfSubDpbsToEmpty.end(); iS++)
2429        {
2430          m_dpb.emptySubDpbs( &listOfSubDpbsToEmpty );
2431        }
2432      }
2433    }
2434    else
2435    {
2436      // -  Otherwise, all picture storage buffers that contain a picture in the current layer and that are marked as
2437      //   "not needed for output" and "unused for reference" are emptied (without output). For each picture storage buffer that is emptied,
2438      //   the sub-DPB fullness is decremented by one.
2439
2440      m_dpb.emptySubDpbNotNeedForOutputAndUnusedForRef( nuhLayerId );
2441
2442      //    When one or more of the following conditions are true, the "bumping" process specified in clause F.13.5.2.4
2443      //    is invoked repeatedly until none of the following conditions are true:
2444
2445      Bool repeat = true;
2446      while ( repeat )
2447      {
2448        TComList<TComAu*> aus = m_dpb.getAusHavingPicsMarkedForOutput();
2449
2450        // The number of access units that contain at least one decoded picture in the DPB marked
2451        // as "needed for output" is greater than MaxNumReorderPics.
2452        Bool cond1 = ( aus.size() > m_maxNumReorderPics );
2453
2454        // MaxLatencyIncreasePlus1 is not equal to 0 and there is at least one access unit
2455        // that contains at least one decoded picture in the DPB marked as "needed for output"
2456        // for which the associated variable PicLatencyCount is greater than or equal to MaxLatencyValue.
2457        Bool auWithGreaterLatencyCount = false;
2458        for(TComList<TComAu*>::iterator itA= aus.begin(); ( itA!=aus.end()) && !auWithGreaterLatencyCount ; itA++)
2459        {
2460          if ( (*itA)->getPicLatencyCount() > m_maxLatencyValue )
2461          {
2462            auWithGreaterLatencyCount = true;
2463          }
2464        }
2465
2466        Bool cond2 = (m_maxLatencyIncreasePlus1 != 0 ) && auWithGreaterLatencyCount;
2467
2468        // The number of pictures in the sub-DPB is greater than or equal to MaxDecPicBufferingMinus1 + 1.
2469        Bool cond3 = ( m_dpb.getSubDpb( nuhLayerId, false )->size() >= m_maxDecPicBufferingMinus1[ nuhLayerId ] + 1 );
2470
2471        if ( cond1  || cond2 || cond3 )
2472        {
2473          xF13524Bumping( aus );
2474        }
2475        else
2476        {
2477          repeat = false;
2478        }
2479      }
2480    }
2481  }
2482}
2483
2484Void TAppDecTop::xF13523PicDecMarkAddBumpAndStor( Bool curPicIsLastInAu )
2485{
2486  ////////////////////////////////////////////////////////////////////////////////
2487  // F.13.5.2.3 Picture decoding, marking, additional bumping and storage
2488  ////////////////////////////////////////////////////////////////////////////////
2489
2490  const TComVPS* vps = m_curPic->getSlice(0)->getVPS();
2491
2492  // The current picture is considered as decoded after the last decoding unit of
2493  // the picture is decoded. The current decoded picture is stored in an empty picture
2494  // storage buffer in the sub-DPB.
2495
2496  m_dpb.addNewPic( m_curPic );
2497
2498  if ( curPicIsLastInAu )
2499  {
2500    // When the current picture is the last picture in an access unit, the following applies
2501    // for each decoded picture with nuh_layer_id greater than or
2502    // equal to ( vps_base_layer_internal_flag ? 0 : 1 ) of the access unit:
2503
2504    for( TComList<TComPic*>::iterator itP = m_curAu.begin(); itP != m_curAu.end(); itP++ )
2505    {
2506      TComPic* pic = (*itP);
2507      if( pic->getLayerId() >= ( vps->getVpsBaseLayerInternalFlag() ? 0 : 1 ) )
2508      {
2509        if ( pic->getPicOutputFlag() )
2510        {
2511          //If the decoded picture has PicOutputFlag equal to 1, it is marked as "needed for output".
2512          pic->setOutputMark( true );
2513        }
2514        else
2515        {
2516          // Otherwise it is marked as "not needed for output".
2517          pic->setOutputMark( false );
2518        }
2519        // NOTE - Prior to investigating the conditions above, PicOutputFlag
2520        // of each picture of the access unit is updated as specified in clause F.8.1.2.
2521      }
2522    }
2523  }
2524
2525  // The current decoded picture is marked as "used for short-term reference".
2526  m_curPic->markAsUsedForShortTermReference();
2527
2528
2529  Bool repeat = true;
2530  while ( repeat )
2531  {
2532    TComList<TComAu*> aus = m_dpb.getAusHavingPicsMarkedForOutput();
2533
2534    // When one or more of the following conditions are true,
2535    // the "bumping" process specified in clause F.13.5.2.4 is invoked
2536    // repeatedly until none of the following conditions are true:
2537
2538    // - The number of access units that contain at least one decoded picture in the DPB marked
2539    //   as "needed for output" is greater than MaxNumReorderPics.
2540    Bool cond1 = ( aus.size() > m_maxNumReorderPics );
2541
2542    // - MaxLatencyIncreasePlus1 is not equal to 0 and there is at least one access unit
2543    //   that contains at least one decoded picture in the DPB marked as "needed for output"
2544    //   for which the associated variable PicLatencyCount is greater than or equal to MaxLatencyValue.
2545    Bool auWithGreaterLatencyCount = false;
2546    for(TComList<TComAu*>::iterator itA= aus.begin(); ( itA!=aus.end()) && !auWithGreaterLatencyCount ; itA++)
2547    {
2548      if ( (*itA)->getPicLatencyCount() > m_maxLatencyValue )
2549      {
2550        auWithGreaterLatencyCount = true;
2551      }
2552    }
2553
2554    Bool cond2 = (m_maxLatencyIncreasePlus1 != 0 ) && auWithGreaterLatencyCount;
2555
2556    if ( cond1  || cond2 )
2557    {
2558      xF13524Bumping( aus );
2559    }
2560    else
2561    {
2562      repeat = false;
2563    }
2564  }
2565}
2566
2567Void TAppDecTop::xF13524Bumping( TComList<TComAu*> aus )
2568{
2569  ////////////////////////////////////////////////////////////////////////////////
2570  // F.13.5.2.4 "Bumping" process
2571  ////////////////////////////////////////////////////////////////////////////////
2572
2573  // The picture or pictures that are first for output are selected as the ones having the
2574  // smallest value of PicOrderCntVal of all pictures in the DPB marked as "needed for output".
2575
2576  assert( !aus.empty() );
2577
2578  // Create copy, since original AU from DBP is modified when removing pic.
2579  TComAu auWithSmallestPoc = *((*aus.begin())); // List is sorted, hence the AU with smallest POC is the first.
2580
2581  for(TComAu::iterator itP= auWithSmallestPoc.begin(); ( itP!=auWithSmallestPoc.end() ); itP++)
2582  {
2583    TComPic* pic = (*itP);
2584
2585    if (pic->getOutputMark() )
2586    {
2587      // Each of these pictures is, in ascending nuh_layer_id order, cropped,
2588      // using the conformance cropping window specified in the active SPS for the picture,
2589      // the cropped picture is output, and the picture is marked as "not needed for output".
2590
2591      // pictures are sorted in the AU in ascending nuh_layer_id order.
2592
2593
2594      xCropAndOutput( pic );
2595      pic->setOutputMark( false );
2596
2597      // Each picture storage buffer that contains a picture marked as "unused for reference"
2598      // and that was one of the pictures cropped and output is emptied and the fullness of
2599      // the associated sub-DPB is decremented by one.
2600
2601      if (pic->getMarkedUnUsedForReference() )
2602      {
2603        m_dpb.removePic( pic );
2604      }
2605    }
2606  }
2607}
2608
2609Void TAppDecTop::xF816decProcEndDecOfCodPicLIdGrtZero()
2610{
2611  ////////////////////////////////////////////////////////////////////////////////
2612  // F.8.1.6  Decoding process for ending the decoding of a coded picture with nuh_layer_id greater than 0
2613  ////////////////////////////////////////////////////////////////////////////////
2614
2615  const TComSlice* slice = m_curPic->getSlice( 0 );
2616  const Int nuhLayerId   = m_curPic->getLayerId();
2617
2618  assert(  nuhLayerId != 0 );
2619
2620  //The marking of decoded pictures is modified as specified in the following:
2621  for (Int i = 0; i < m_curPic->getDecodedRps()->m_numActiveRefLayerPics0;i++ )
2622  {
2623    m_curPic->getDecodedRps()->m_refPicSetInterLayer0[i]->markAsUsedForShortTermReference();
2624  }
2625
2626  for (Int i = 0; i < m_curPic->getDecodedRps()->m_numActiveRefLayerPics1;i++ )
2627  {
2628    m_curPic->getDecodedRps()->m_refPicSetInterLayer1[i]->markAsUsedForShortTermReference();
2629  }
2630
2631  // PicOutputFlag is set as follows:
2632  if ( !m_layerInitilizedFlag[ nuhLayerId ] )
2633  {
2634    // - If LayerInitializedFlag[ nuh_layer_id ] is equal to 0, PicOutputFlag is set equal to 0.
2635    m_curPic->setPicOutputFlag( false );
2636  }
2637  else if (m_curPic->isRasl( ) && m_noRaslOutputFlagAssocIrap[ nuhLayerId] )
2638  {
2639    // - Otherwise, if the current picture is a RASL picture and NoRaslOutputFlag of the associated IRAP picture is equal to 1,
2640    //   PicOutputFlag is set equal to 0.
2641
2642    m_curPic->setPicOutputFlag( false );
2643  }
2644  else
2645  {
2646    // - Otherwise, PicOutputFlag is set equal to pic_output_flag.
2647    m_curPic->setPicOutputFlag( slice->getPicOutputFlag() );
2648  }
2649
2650  // The decoded picture is marked as "used for short-term reference".
2651  m_curPic->markAsUsedForShortTermReference();
2652
2653  if ( !m_firstPicInLayerDecodedFlag[ nuhLayerId ] )
2654  {
2655    // When FirstPicInLayerDecodedFlag[ nuh_layer_id ] is equal to 0, FirstPicInLayerDecodedFlag[ nuh_layer_id ] is set equal to 1.
2656    m_firstPicInLayerDecodedFlag[ nuhLayerId ] = true;
2657  }
2658}
2659
2660TDecTop* TAppDecTop::xGetDecoder( InputNALUnit& nalu )
2661{
2662  return m_tDecTop[ xGetDecoderIdx( nalu.m_nuhLayerId )];
2663}
2664
2665
2666Int TAppDecTop::xGetDecoderIdx( Int layerId, Bool createFlag /*= false */ )
2667{
2668  Int decIdx = -1;
2669
2670  if ( layerId > MAX_NUM_LAYER_IDS-1 )
2671  {
2672    return decIdx;
2673  }
2674
2675  if ( m_layerIdToDecIdx[ layerId ] != -1 )
2676  {
2677    decIdx = m_layerIdToDecIdx[ layerId ];
2678  }
2679  else
2680  {
2681    assert ( createFlag );
2682    assert( m_numDecoders < MAX_NUM_LAYERS );
2683
2684    decIdx = m_numDecoders;
2685
2686    // Init decoder
2687    m_tDecTop[ decIdx ] =  new TDecTop;
2688    m_tDecTop[ decIdx ]->create();
2689    m_tDecTop[ decIdx ]->init( );
2690    m_tDecTop[ decIdx ]->setLayerId( layerId );
2691    m_tDecTop[ decIdx ]->setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
2692#if MCTS_ENC_CHECK
2693    m_tDecTop[ decIdx ]->setTMctsCheckEnabled( m_tmctsCheck );
2694#endif
2695    m_tDecTop[ decIdx ]->setDpb( &m_dpb );
2696    m_tDecTop[ decIdx ]->setTargetOlsIdx( m_targetOptLayerSetIdx );
2697    m_tDecTop[ decIdx ]->setFirstPicInLayerDecodedFlag( m_firstPicInLayerDecodedFlag );
2698    m_tDecTop[ decIdx ]->setPocDecrementedInDPBFlag   ( m_pocDecrementedInDpbFlag    );
2699    m_tDecTop[ decIdx ]->setLastPresentPocResetIdc    ( m_lastPresentPocResetIdc );
2700#if O0043_BEST_EFFORT_DECODING
2701    m_cTDecTop[ decIdx ]->setForceDecodeBitDepth(m_forceDecodeBitDepth);
2702#endif
2703    if (!m_outputDecodedSEIMessagesFilename.empty())
2704    {
2705      std::ostream &os=m_seiMessageFileStream.is_open() ? m_seiMessageFileStream : std::cout;
2706      m_tDecTop[ decIdx ]->setDecodedSEIMessageOutputStream(&os);
2707    }
2708#if NH_3D
2709   m_tDecTop[ decIdx ]->setCamParsCollector( &m_cCamParsCollector );
2710#endif
2711
2712    // append pic list of new decoder to PicLists
2713
2714    // create recon file related stuff
2715    TChar* pchTempFilename = NULL;
2716    if ( !m_reconFileName.empty() )
2717    {
2718      TChar buffer[4];
2719      sprintf(buffer,"_%i", layerId );
2720      assert ( !m_reconFileName.empty() );
2721      xAppendToFileNameEnd( m_reconFileName.c_str() , buffer, pchTempFilename );
2722      assert( m_pchReconFiles.size() == m_numDecoders );
2723    }
2724
2725    m_pchReconFiles.push_back( pchTempFilename );
2726
2727    m_tVideoIOYuvReconFile[ decIdx ] = new TVideoIOYuv;
2728    m_reconOpen           [ decIdx ] = false;
2729
2730    // set others
2731    m_layerIdToDecIdx     [ layerId ] = decIdx;
2732
2733    m_numDecoders++;
2734  };
2735  return decIdx;
2736
2737}
2738
2739Int TAppDecTop::xPreDecodePoc( InputNALUnit& nalu )
2740{ 
2741  // - According to F.7.4.2.4.4, the POC of the current picture is required to detect whether it is the first in a new AU
2742  // - F.8.1.3 needs to know if the current picture is the first of an AU
2743  //   actually before its POC has been decoded.
2744
2745  // Thus, in the software implementation the processes can not be invoked in the same order as in the Spec.
2746  // For this, this function decodes the POC before invoking F.8.1.3. However, this is done without
2747  // altering member variables
2748
2749  // Do some stuff from F.8.1.3 required for POC derivation, which is not depending on AU detection.
2750  TDecTop* dec          = xGetDecoder( nalu ); 
2751  TComSlice* slicePilot = dec->getSlicePilot(); 
2752  Int nuhLayerId        = nalu.m_nuhLayerId; 
2753  Int smallestLayerId   = dec->getSmallestLayerId();
2754
2755  Int handleCraAsBlaFlag; 
2756  if ( nalu.isIrap() )
2757  {
2758    if ( !m_handleCraAsBlaFlagSetByExtMeans )
2759    {
2760      handleCraAsBlaFlag = false;
2761    }
2762  }
2763
2764  Bool firstPicInLayerDecodedFlag = m_firstPicInLayerDecodedFlag[ nalu.m_nuhLayerId ];
2765 
2766  if ( nalu.isIrap() && nuhLayerId == smallestLayerId )
2767  {
2768    Int noClrasOutputFlag;
2769    if( m_firstSliceInBitstream )
2770    {
2771      noClrasOutputFlag = true; 
2772    }
2773    else if( m_eosInLayer[ 0 ] || m_eosInLayer[ nuhLayerId ] )
2774    {
2775      noClrasOutputFlag = true;
2776    }
2777    else if ( nalu.isBla() || (nalu.isCra() && handleCraAsBlaFlag ))
2778    {
2779      noClrasOutputFlag = true; 
2780    }
2781    else if ( nalu.isIdr() && slicePilot->getCrossLayerBlaFlag() )
2782    {
2783      noClrasOutputFlag = true; 
2784    }
2785    else if ( m_noClrasOutputFlagSetByExtMeans )
2786    {
2787      noClrasOutputFlag = m_noClrasOutputFlag; 
2788    }
2789    else
2790    {     
2791      noClrasOutputFlag  = false;
2792    }
2793
2794    if( noClrasOutputFlag )
2795    {
2796      firstPicInLayerDecodedFlag = false; 
2797    }   
2798  }
2799
2800  // Derive POC
2801  return dec->preDecodePoc(firstPicInLayerDecodedFlag, m_newPicIsFstPicOfAllLayOfPocResetPer, m_newPicIsPocResettingPic );
2802}
2803
2804Bool TAppDecTop::xDetectNewAu( InputNALUnit& nalu )
2805{
2806  TDecTop*        dec        = xGetDecoder( nalu );
2807  TComSlice*      slicePilot = dec->getSlicePilot();
2808  const TComVPS*  vps        = slicePilot->getVPS();
2809
2810  Bool firstVclNaluOfAu;
2811
2812  if (m_curPic == NULL )
2813  {
2814    // No picture decoded yet, so we have a new AU.
2815    firstVclNaluOfAu = true; 
2816  }
2817  else
2818  {
2819    if ( !vps->getVpsExtensionFlag() )
2820    {
2821      // Decoding according to clause 8, hence one pic per AU.
2822      firstVclNaluOfAu = slicePilot->getFirstSliceSegementInPicFlag();
2823    }
2824    else
2825    {
2826      if ( dec->getTargetOlsIdx() == 0 )
2827      {
2828        // Only the base layer is decoded, hence one pic per AU.
2829        firstVclNaluOfAu = slicePilot->getFirstSliceSegementInPicFlag();
2830      }
2831      else
2832      {
2833        // F.7.4.2.4.4  Order of NAL units and coded pictures and association to access units   
2834        //  An access unit consists of one or more coded pictures, each with a distinct value of
2835        //  nuh_layer_id, and zero or more non-VCL NAL units.
2836
2837        //  A VCL NAL unit is the first VCL NAL unit of an access unit, when all of the following conditions are true:
2838        //  -  first_slice_segment_in_pic_flag is equal to 1.
2839        //  -  At least one of the following conditions is true:
2840        //     - The previous picture in decoding order belongs to a different POC resetting period
2841        //       than the picture containing the VCL NAL unit.
2842        Bool prevPicDiffPocResetPeriod = m_newPicIsFstPicOfAllLayOfPocResetPer; 
2843
2844        //     - PicOrderCntVal derived for the VCL NAL unit differs from the PicOrderCntVal of the
2845        //       previous picture in decoding order.
2846        Bool prevPicDiffPoc = ( xPreDecodePoc( nalu ) != m_curPic->getPOC() );
2847
2848        if( slicePilot->getFirstSliceSegementInPicFlag() && ( prevPicDiffPocResetPeriod || prevPicDiffPoc ) )
2849        {
2850          firstVclNaluOfAu = true;
2851        }
2852        else
2853        {
2854          firstVclNaluOfAu = false;
2855        }
2856      }
2857    }
2858  }
2859  return firstVclNaluOfAu;
2860}
2861
2862Void TAppDecTop::xDetectNewPocResettingPeriod( InputNALUnit& nalu )
2863{
2864  TDecTop* dec  = xGetDecoder( nalu );
2865  dec->inferPocResetPeriodId();
2866
2867
2868  Int pocResetIdc         = dec->getSlicePilot()->getPocResetIdc();
2869  Int newPocResetPeriodId = dec->getSlicePilot()->getPocResetPeriodId();
2870
2871  Int curPocResetPeriodId = ( m_curPic != NULL)  ? m_curPic->getPocResetPeriodId() : MIN_INT; 
2872
2873  // Check if new picture starts a new poc resetting period.
2874  if(  ( pocResetIdc == 1 || pocResetIdc == 2 ) &&  ( curPocResetPeriodId != newPocResetPeriodId ) )
2875  {
2876    for (Int i = 0; i < MAX_NUM_LAYER_IDS; i++ )
2877    {
2878      m_firstPicInPocResettingPeriodReceived[ i ] = false;
2879    }
2880    m_newPicIsFstPicOfAllLayOfPocResetPer = true;
2881  }
2882  else
2883  {
2884    m_newPicIsFstPicOfAllLayOfPocResetPer = false;
2885  }
2886
2887  // Check if current picture is a poc resetting picture (thus the first picture of this layer within the POC resetting period.
2888  if ( !m_firstPicInPocResettingPeriodReceived[ nalu.m_nuhLayerId ] )
2889  {
2890    m_newPicIsPocResettingPic = true;
2891    m_firstPicInPocResettingPeriodReceived[ nalu.m_nuhLayerId ] = true;
2892  }
2893  else
2894  {
2895    m_newPicIsPocResettingPic = false;
2896  }
2897
2898}
2899
2900Bool TAppDecTop::xAllRefLayersInitilized( Int curLayerId )
2901{
2902  Bool allRefLayersInitilizedFlag = true;
2903  for (Int i = 0; i < m_vps->getNumDirectRefLayers( curLayerId  ); i++ )
2904  {
2905    Int refLayerId = m_vps->getIdDirectRefLayer( curLayerId, i );
2906    allRefLayersInitilizedFlag = allRefLayersInitilizedFlag && m_layerInitilizedFlag[ refLayerId ];
2907  }
2908
2909  return allRefLayersInitilizedFlag;
2910}
2911
2912Void TAppDecTop::xInitFileIO()
2913{
2914  m_bitstreamFile.open(m_bitstreamFileName.c_str(), ifstream::in | ifstream::binary);
2915
2916  if ( !m_bitstreamFile)
2917  {
2918    fprintf(stderr, "\nUnable to open bitstream file `%s' for reading\n", m_bitstreamFileName.c_str());
2919    exit(EXIT_FAILURE);
2920  }
2921
2922  if (!m_outputDecodedSEIMessagesFilename.empty() && m_outputDecodedSEIMessagesFilename!="-")
2923  {
2924    m_seiMessageFileStream.open(m_outputDecodedSEIMessagesFilename.c_str(), std::ios::out);
2925    if (!m_seiMessageFileStream.is_open() || !m_seiMessageFileStream.good())
2926    {
2927      fprintf(stderr, "\nUnable to open file `%s' for writing decoded SEI messages\n", m_outputDecodedSEIMessagesFilename.c_str());
2928      exit(EXIT_FAILURE);
2929    }
2930  }
2931
2932#if NH_3D
2933  if( m_pchScaleOffsetFile )
2934  {
2935    m_pScaleOffsetFile = ::fopen( m_pchScaleOffsetFile, "wt" );
2936    if (!m_pScaleOffsetFile)
2937    {
2938      fprintf(stderr, "\nUnable to open file `%s' for writing decoded Camera Parameters messages\n", m_pchScaleOffsetFile);
2939      exit(EXIT_FAILURE);
2940    }
2941  }
2942#endif
2943}
2944
2945Void TAppDecTop::xOpenReconFile( TComPic* curPic )
2946{
2947  Int decIdx = xGetDecoderIdx( curPic->getLayerId() );
2948
2949  if ( !m_reconFileName.empty() && !m_reconOpen[decIdx] )
2950  {
2951    const BitDepths &bitDepths= curPic->getPicSym()->getSPS().getBitDepths(); // use bit depths of first reconstructed picture.
2952    for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
2953    {
2954      if (m_outputBitDepth[channelType] == 0)
2955      {
2956        m_outputBitDepth[channelType] = bitDepths.recon[channelType];
2957      }
2958    }
2959
2960    m_tVideoIOYuvReconFile[decIdx]->open( m_pchReconFiles[decIdx], true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon ); // write mode
2961    m_reconOpen[decIdx] = true;
2962  }
2963}
2964
2965Void TAppDecTop::xFlushOutput()
2966{
2967  Bool repeat = true;
2968  while ( repeat )
2969  {
2970    if( m_decProcCvsg == ANNEX_F )
2971    {
2972      TComList<TComAu*> aus = m_dpb.getAusHavingPicsMarkedForOutput();
2973      if ( !aus.empty() )
2974      {
2975        xF13524Bumping( aus );
2976      }     
2977      else
2978      {
2979        repeat = false;
2980      }
2981    }     
2982    else if( m_decProcCvsg == CLAUSE_8 )
2983    {
2984      TComList<TComPic*> picsMarkedForOutput = m_dpb.getSubDpb( 0, false )->getPicsMarkedNeedForOutput();
2985      if (!picsMarkedForOutput.empty())
2986      {
2987        xC524Bumping();
2988      }
2989      else
2990      {
2991        repeat = false; 
2992      }
2993    }
2994  }
2995}
2996
2997Void TAppDecTop::xCropAndOutput( TComPic* curPic )
2998{
2999
3000  if ( m_printPicOutput )
3001  {
3002    std::cout << "  Output picture: ";
3003    curPic->print( 2 );
3004    std::cout << std::endl;
3005  }
3006
3007  assert( !curPic->getHasGeneratedRefPics() );
3008  assert( !curPic->getIsGenerated()         );
3009
3010  Int decIdx = xGetDecoderIdx( curPic->getLayerId() );
3011
3012  if (!m_reconOpen[ decIdx ])
3013  {
3014    xOpenReconFile( curPic );
3015  }
3016
3017  if ( m_pchReconFiles[ decIdx ] )
3018  {
3019    const Window &conf    = curPic->getConformanceWindow();
3020    const Window  defDisp = m_respectDefDispWindow ? curPic->getDefDisplayWindow() : Window();
3021
3022    assert( conf   .getScaledFlag() );
3023    assert( defDisp.getScaledFlag() );
3024
3025    m_tVideoIOYuvReconFile[decIdx]->write( curPic->getPicYuvRec(),
3026      m_outputColourSpaceConvert,
3027      conf.getWindowLeftOffset()   + defDisp.getWindowLeftOffset(),
3028      conf.getWindowRightOffset()  + defDisp.getWindowRightOffset(),
3029      conf.getWindowTopOffset()    + defDisp.getWindowTopOffset(),
3030      conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(),
3031#if NH_3D
3032      m_depth420OutputFlag && curPic->getIsDepth() ? CHROMA_420 : NUM_CHROMA_FORMAT
3033#else
3034      NUM_CHROMA_FORMAT
3035#endif
3036      , m_bClipOutputVideoToRec709Range);
3037  }
3038}
3039
3040UInt TAppDecTop::getNumberOfChecksumErrorsDetected() const
3041{
3042  UInt numOfChecksumErrors = 0;
3043  for (Int i = 0; i < m_numDecoders; i++ )
3044  {
3045    numOfChecksumErrors += getNumberOfChecksumErrorsDetected( i );
3046  }
3047  return numOfChecksumErrors;
3048}
3049
3050#endif
3051
3052Void TAppDecTop::xOutputColourRemapPic(TComPic* pcPic)
3053{
3054  const TComSPS &sps=pcPic->getPicSym()->getSPS();
3055  SEIMessages colourRemappingInfo = getSeisByType(pcPic->getSEIs(), SEI::COLOUR_REMAPPING_INFO );
3056  SEIColourRemappingInfo *seiColourRemappingInfo = ( colourRemappingInfo.size() > 0 ) ? (SEIColourRemappingInfo*) *(colourRemappingInfo.begin()) : NULL;
3057
3058  if (colourRemappingInfo.size() > 1)
3059  {
3060    printf ("Warning: Got multiple Colour Remapping Information SEI messages. Using first.");
3061  }
3062  if (seiColourRemappingInfo)
3063  {
3064    applyColourRemapping(*pcPic->getPicYuvRec(), *seiColourRemappingInfo, sps);
3065
3066    // save the last CRI SEI received
3067    if (m_pcSeiColourRemappingInfoPrevious == NULL)
3068    {
3069      m_pcSeiColourRemappingInfoPrevious = new SEIColourRemappingInfo();
3070    }
3071    m_pcSeiColourRemappingInfoPrevious->copyFrom(*seiColourRemappingInfo);
3072  }
3073  else  // using the last CRI SEI received
3074  {
3075    // TODO: prevent persistence of CRI SEI across C(L)VS.
3076    if (m_pcSeiColourRemappingInfoPrevious != NULL)
3077    {
3078      if (m_pcSeiColourRemappingInfoPrevious->m_colourRemapPersistenceFlag == false)
3079      {
3080        printf("Warning No SEI-CRI message is present for the current picture, persistence of the CRI is not managed\n");
3081      }
3082      applyColourRemapping(*pcPic->getPicYuvRec(), *m_pcSeiColourRemappingInfoPrevious, sps);
3083    }
3084  }
3085}
3086
3087// compute lut from SEI
3088// use at lutPoints points aligned on a power of 2 value
3089// SEI Lut must be in ascending values of coded Values
3090static std::vector<Int>
3091initColourRemappingInfoLut(const Int                                          bitDepth_in,     // bit-depth of the input values of the LUT
3092                           const Int                                          nbDecimalValues, // Position of the fixed point
3093                           const std::vector<SEIColourRemappingInfo::CRIlut> &lut,
3094                           const Int                                          maxValue, // maximum output value
3095                           const Int                                          lutOffset)
3096{
3097  const Int lutPoints = (1 << bitDepth_in) + 1 ;
3098  std::vector<Int> retLut(lutPoints);
3099
3100  // missing values: need to define default values before first definition (check codedValue[0] == 0)
3101  Int iTargetPrev = (lut.size() && lut[0].codedValue == 0) ? lut[0].targetValue: 0;
3102  Int startPivot = (lut.size())? ((lut[0].codedValue == 0)? 1: 0): 1;
3103  Int iCodedPrev  = 0;
3104  // set max value with the coded bit-depth
3105  // + ((1 << nbDecimalValues) - 1) is for the added bits
3106  const Int maxValueFixedPoint = (maxValue << nbDecimalValues) + ((1 << nbDecimalValues) - 1);
3107
3108  Int iValue = 0;
3109
3110  for ( Int iPivot=startPivot ; iPivot < (Int)lut.size(); iPivot++ )
3111  {
3112    Int iCodedNext  = lut[iPivot].codedValue;
3113    Int iTargetNext = lut[iPivot].targetValue;
3114
3115    // ensure correct bit depth and avoid overflow in lut address
3116    Int iCodedNext_bitDepth = std::min(iCodedNext, (1 << bitDepth_in));
3117
3118    const Int divValue =  (iCodedNext - iCodedPrev > 0)? (iCodedNext - iCodedPrev): 1;
3119    const Int lutValInit = (lutOffset + iTargetPrev) << nbDecimalValues;
3120    const Int roundValue = divValue / 2;
3121    for ( ; iValue<iCodedNext_bitDepth; iValue++ )
3122    {
3123      Int value = iValue;
3124      Int interpol = ((((value-iCodedPrev) * (iTargetNext - iTargetPrev)) << nbDecimalValues) + roundValue) / divValue;               
3125      retLut[iValue]  = std::min(lutValInit + interpol , maxValueFixedPoint);
3126    }
3127    iCodedPrev  = iCodedNext;
3128    iTargetPrev = iTargetNext;
3129  }
3130  // fill missing values if necessary
3131  if(iCodedPrev < (1 << bitDepth_in)+1)
3132  {
3133    Int iCodedNext  = (1 << bitDepth_in);
3134    Int iTargetNext = (1 << bitDepth_in) - 1;
3135
3136    const Int divValue =  (iCodedNext - iCodedPrev > 0)? (iCodedNext - iCodedPrev): 1;
3137    const Int lutValInit = (lutOffset + iTargetPrev) << nbDecimalValues;
3138    const Int roundValue = divValue / 2;
3139
3140    for ( ; iValue<=iCodedNext; iValue++ )
3141    {
3142      Int value = iValue;
3143      Int interpol = ((((value-iCodedPrev) * (iTargetNext - iTargetPrev)) << nbDecimalValues) + roundValue) / divValue; 
3144      retLut[iValue]  = std::min(lutValInit + interpol , maxValueFixedPoint);
3145    }
3146  }
3147  return retLut;
3148}
3149
3150static Void
3151initColourRemappingInfoLuts(std::vector<Int>      (&preLut)[3],
3152                            std::vector<Int>      (&postLut)[3],
3153                            SEIColourRemappingInfo &pCriSEI,
3154                            const Int               maxBitDepth)
3155{
3156  Int internalBitDepth = pCriSEI.m_colourRemapBitDepth;
3157  for ( Int c=0 ; c<3 ; c++ )
3158  {
3159    std::sort(pCriSEI.m_preLut[c].begin(), pCriSEI.m_preLut[c].end()); // ensure preLut is ordered in ascending values of codedValues   
3160    preLut[c] = initColourRemappingInfoLut(pCriSEI.m_colourRemapInputBitDepth, maxBitDepth - pCriSEI.m_colourRemapInputBitDepth, pCriSEI.m_preLut[c], ((1 << internalBitDepth) - 1), 0); //Fill preLut
3161
3162    std::sort(pCriSEI.m_postLut[c].begin(), pCriSEI.m_postLut[c].end()); // ensure postLut is ordered in ascending values of codedValues       
3163    postLut[c] = initColourRemappingInfoLut(pCriSEI.m_colourRemapBitDepth, maxBitDepth - pCriSEI.m_colourRemapBitDepth, pCriSEI.m_postLut[c], (1 << internalBitDepth) - 1, 0); //Fill postLut
3164  }
3165}
3166
3167// apply lut.
3168// Input lut values are aligned on power of 2 boundaries
3169static Int
3170applyColourRemappingInfoLut1D(Int inVal, const std::vector<Int> &lut, const Int inValPrecisionBits)
3171{
3172  const Int roundValue = (inValPrecisionBits)? 1 << (inValPrecisionBits - 1): 0;
3173  inVal = std::min(std::max(0, inVal), (Int)(((lut.size()-1) << inValPrecisionBits)));
3174  Int index  = (Int) std::min((inVal >> inValPrecisionBits), (Int)(lut.size()-2));
3175  Int outVal = (( inVal - (index<<inValPrecisionBits) ) * (lut[index+1] - lut[index]) + roundValue) >> inValPrecisionBits;
3176  outVal +=  lut[index] ;
3177
3178  return outVal;
3179} 
3180
3181static Int
3182applyColourRemappingInfoMatrix(const Int (&colourRemapCoeffs)[3], const Int postOffsetShift, const Int p0, const Int p1, const Int p2, const Int offset)
3183{
3184  Int YUVMat = (colourRemapCoeffs[0]* p0 + colourRemapCoeffs[1]* p1 + colourRemapCoeffs[2]* p2  + offset) >> postOffsetShift;
3185  return YUVMat;
3186}
3187
3188static Void
3189setColourRemappingInfoMatrixOffset(Int (&matrixOffset)[3], Int offset0, Int offset1, Int offset2)
3190{
3191  matrixOffset[0] = offset0;
3192  matrixOffset[1] = offset1;
3193  matrixOffset[2] = offset2;
3194}
3195
3196static Void
3197setColourRemappingInfoMatrixOffsets(      Int  (&matrixInputOffset)[3],
3198                                          Int  (&matrixOutputOffset)[3],
3199                                    const Int  bitDepth,
3200                                    const Bool crInputFullRangeFlag,
3201                                    const Int  crInputMatrixCoefficients,
3202                                    const Bool crFullRangeFlag,
3203                                    const Int  crMatrixCoefficients)
3204{
3205  // set static matrix offsets
3206  Int crInputOffsetLuma = (crInputFullRangeFlag)? 0:-(16 << (bitDepth-8));
3207  Int crOffsetLuma = (crFullRangeFlag)? 0:(16 << (bitDepth-8));
3208  Int crInputOffsetChroma = 0;
3209  Int crOffsetChroma = 0;
3210
3211  switch(crInputMatrixCoefficients)
3212  {
3213    case MATRIX_COEFFICIENTS_RGB:
3214      crInputOffsetChroma = 0;
3215      if(!crInputFullRangeFlag)
3216      {
3217        fprintf(stderr, "WARNING: crInputMatrixCoefficients set to MATRIX_COEFFICIENTS_RGB and crInputFullRangeFlag not set\n");
3218        crInputOffsetLuma = 0;
3219      }
3220      break;
3221    case MATRIX_COEFFICIENTS_UNSPECIFIED:
3222    case MATRIX_COEFFICIENTS_BT709:
3223    case MATRIX_COEFFICIENTS_BT2020_NON_CONSTANT_LUMINANCE:
3224      crInputOffsetChroma = -(1 << (bitDepth-1));
3225      break;
3226    default:
3227      fprintf(stderr, "WARNING: crInputMatrixCoefficients set to undefined value: %d\n", crInputMatrixCoefficients);
3228  }
3229
3230  switch(crMatrixCoefficients)
3231  {
3232    case MATRIX_COEFFICIENTS_RGB:
3233      crOffsetChroma = 0;
3234      if(!crFullRangeFlag)
3235      {
3236        fprintf(stderr, "WARNING: crMatrixCoefficients set to MATRIX_COEFFICIENTS_RGB and crInputFullRangeFlag not set\n");
3237        crOffsetLuma = 0;
3238      }
3239      break;
3240    case MATRIX_COEFFICIENTS_UNSPECIFIED:
3241    case MATRIX_COEFFICIENTS_BT709:
3242    case MATRIX_COEFFICIENTS_BT2020_NON_CONSTANT_LUMINANCE:
3243      crOffsetChroma = (1 << (bitDepth-1));
3244      break;
3245    default:
3246      fprintf(stderr, "WARNING: crMatrixCoefficients set to undefined value: %d\n", crMatrixCoefficients);
3247  }
3248
3249  setColourRemappingInfoMatrixOffset(matrixInputOffset, crInputOffsetLuma, crInputOffsetChroma, crInputOffsetChroma);
3250  setColourRemappingInfoMatrixOffset(matrixOutputOffset, crOffsetLuma, crOffsetChroma, crOffsetChroma);
3251}
3252
3253Void TAppDecTop::applyColourRemapping(const TComPicYuv& pic, SEIColourRemappingInfo& criSEI, const TComSPS &activeSPS)
3254{ 
3255  const Int maxBitDepth = 16;
3256
3257  // create colour remapped picture
3258  if( !criSEI.m_colourRemapCancelFlag && pic.getChromaFormat()!=CHROMA_400) // 4:0:0 not supported.
3259  {
3260    const Int          iHeight         = pic.getHeight(COMPONENT_Y);
3261    const Int          iWidth          = pic.getWidth(COMPONENT_Y);
3262    const ChromaFormat chromaFormatIDC = pic.getChromaFormat();
3263
3264    TComPicYuv picYuvColourRemapped;
3265    picYuvColourRemapped.createWithoutCUInfo( iWidth, iHeight, chromaFormatIDC );
3266
3267    const Int  iStrideIn   = pic.getStride(COMPONENT_Y);
3268    const Int  iCStrideIn  = pic.getStride(COMPONENT_Cb);
3269    const Int  iStrideOut  = picYuvColourRemapped.getStride(COMPONENT_Y);
3270    const Int  iCStrideOut = picYuvColourRemapped.getStride(COMPONENT_Cb);
3271    const Bool b444        = ( pic.getChromaFormat() == CHROMA_444 );
3272    const Bool b422        = ( pic.getChromaFormat() == CHROMA_422 );
3273    const Bool b420        = ( pic.getChromaFormat() == CHROMA_420 );
3274
3275    std::vector<Int> preLut[3];
3276    std::vector<Int> postLut[3];
3277    Int matrixInputOffset[3];
3278    Int matrixOutputOffset[3];
3279    const Pel *YUVIn[MAX_NUM_COMPONENT];
3280    Pel *YUVOut[MAX_NUM_COMPONENT];
3281    YUVIn[COMPONENT_Y]  = pic.getAddr(COMPONENT_Y);
3282    YUVIn[COMPONENT_Cb] = pic.getAddr(COMPONENT_Cb);
3283    YUVIn[COMPONENT_Cr] = pic.getAddr(COMPONENT_Cr);
3284    YUVOut[COMPONENT_Y]  = picYuvColourRemapped.getAddr(COMPONENT_Y);
3285    YUVOut[COMPONENT_Cb] = picYuvColourRemapped.getAddr(COMPONENT_Cb);
3286    YUVOut[COMPONENT_Cr] = picYuvColourRemapped.getAddr(COMPONENT_Cr);
3287
3288    const Int bitDepth = criSEI.m_colourRemapBitDepth;
3289    BitDepths        bitDepthsCriFile;
3290    bitDepthsCriFile.recon[CHANNEL_TYPE_LUMA]   = bitDepth;
3291    bitDepthsCriFile.recon[CHANNEL_TYPE_CHROMA] = bitDepth; // Different bitdepth is not implemented
3292
3293    const Int postOffsetShift = criSEI.m_log2MatrixDenom;
3294    const Int matrixRound = 1 << (postOffsetShift - 1);
3295    const Int postLutInputPrecision = (maxBitDepth - criSEI.m_colourRemapBitDepth);
3296
3297    if ( ! criSEI.m_colourRemapVideoSignalInfoPresentFlag ) // setting default
3298    {
3299      setColourRemappingInfoMatrixOffsets(matrixInputOffset, matrixOutputOffset, maxBitDepth,
3300          activeSPS.getVuiParameters()->getVideoFullRangeFlag(), activeSPS.getVuiParameters()->getMatrixCoefficients(),
3301          activeSPS.getVuiParameters()->getVideoFullRangeFlag(), activeSPS.getVuiParameters()->getMatrixCoefficients());
3302    }
3303    else
3304    {
3305      setColourRemappingInfoMatrixOffsets(matrixInputOffset, matrixOutputOffset, maxBitDepth,
3306          activeSPS.getVuiParameters()->getVideoFullRangeFlag(), activeSPS.getVuiParameters()->getMatrixCoefficients(),
3307          criSEI.m_colourRemapFullRangeFlag, criSEI.m_colourRemapMatrixCoefficients);
3308    }
3309
3310    // add matrix rounding to output matrix offsets
3311    matrixOutputOffset[0] = (matrixOutputOffset[0] << postOffsetShift) + matrixRound;
3312    matrixOutputOffset[1] = (matrixOutputOffset[1] << postOffsetShift) + matrixRound;
3313    matrixOutputOffset[2] = (matrixOutputOffset[2] << postOffsetShift) + matrixRound;
3314
3315    // Merge   matrixInputOffset and matrixOutputOffset to matrixOutputOffset
3316    matrixOutputOffset[0] += applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[0], 0, matrixInputOffset[0], matrixInputOffset[1], matrixInputOffset[2], 0);
3317    matrixOutputOffset[1] += applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[1], 0, matrixInputOffset[0], matrixInputOffset[1], matrixInputOffset[2], 0);
3318    matrixOutputOffset[2] += applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[2], 0, matrixInputOffset[0], matrixInputOffset[1], matrixInputOffset[2], 0);
3319
3320    // rescaling output: include CRI/output frame difference
3321    const Int scaleShiftOut_neg = abs(bitDepth - maxBitDepth);
3322    const Int scaleOut_round = 1 << (scaleShiftOut_neg-1);
3323
3324    initColourRemappingInfoLuts(preLut, postLut, criSEI, maxBitDepth);
3325
3326    assert(pic.getChromaFormat() != CHROMA_400);
3327    const Int hs = pic.getComponentScaleX(ComponentID(COMPONENT_Cb));
3328    const Int maxOutputValue = (1 << bitDepth) - 1;
3329
3330    for( Int y = 0; y < iHeight; y++ )
3331    {
3332      for( Int x = 0; x < iWidth; x++ )
3333      {
3334        const Int xc = (x>>hs);
3335        Bool computeChroma = b444 || ((b422 || !(y&1)) && !(x&1));
3336
3337        Int YUVPre_0 = applyColourRemappingInfoLut1D(YUVIn[COMPONENT_Y][x], preLut[0], 0);
3338        Int YUVPre_1 = applyColourRemappingInfoLut1D(YUVIn[COMPONENT_Cb][xc], preLut[1], 0);
3339        Int YUVPre_2 = applyColourRemappingInfoLut1D(YUVIn[COMPONENT_Cr][xc], preLut[2], 0);
3340
3341        Int YUVMat_0 = applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[0], postOffsetShift, YUVPre_0, YUVPre_1, YUVPre_2, matrixOutputOffset[0]);
3342        Int YUVLutB_0 = applyColourRemappingInfoLut1D(YUVMat_0, postLut[0], postLutInputPrecision);
3343        YUVOut[COMPONENT_Y][x] = std::min(maxOutputValue, (YUVLutB_0 + scaleOut_round) >> scaleShiftOut_neg);
3344
3345        if( computeChroma )
3346        {
3347          Int YUVMat_1 = applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[1], postOffsetShift, YUVPre_0, YUVPre_1, YUVPre_2, matrixOutputOffset[1]);
3348          Int YUVLutB_1 = applyColourRemappingInfoLut1D(YUVMat_1, postLut[1], postLutInputPrecision);
3349          YUVOut[COMPONENT_Cb][xc] = std::min(maxOutputValue, (YUVLutB_1 + scaleOut_round) >> scaleShiftOut_neg);
3350
3351          Int YUVMat_2 = applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[2], postOffsetShift, YUVPre_0, YUVPre_1, YUVPre_2, matrixOutputOffset[2]);
3352          Int YUVLutB_2 = applyColourRemappingInfoLut1D(YUVMat_2, postLut[2], postLutInputPrecision);
3353          YUVOut[COMPONENT_Cr][xc] = std::min(maxOutputValue, (YUVLutB_2 + scaleOut_round) >> scaleShiftOut_neg);
3354        }
3355      }
3356
3357      YUVIn[COMPONENT_Y]  += iStrideIn;
3358      YUVOut[COMPONENT_Y] += iStrideOut;
3359      if( !(b420 && !(y&1)) )
3360      {
3361         YUVIn[COMPONENT_Cb]  += iCStrideIn;
3362         YUVIn[COMPONENT_Cr]  += iCStrideIn;
3363         YUVOut[COMPONENT_Cb] += iCStrideOut;
3364         YUVOut[COMPONENT_Cr] += iCStrideOut;
3365      }
3366    }
3367    //Write remapped picture in display order
3368    picYuvColourRemapped.dump( m_colourRemapSEIFileName, bitDepthsCriFile, true );
3369    picYuvColourRemapped.destroy();
3370  }
3371}
3372//! \}
Note: See TracBrowser for help on using the repository browser.