source: 3DVCSoftware/branches/HTM-15.2-dev/source/App/TAppDecoder/TAppDecTop.cpp @ 1373

Last change on this file since 1373 was 1373, checked in by tech, 8 years ago

Macro fixes.

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