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

Last change on this file since 964 was 964, checked in by tech, 10 years ago
  • Merged 11.0-dev0@963. (Update to HM 14.0 + MV-HEVC Draft 8 HLS)
  • Added coding results.
  • Changed version number.
  • Property svn:eol-style set to native
File size: 35.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6* Copyright (c) 2010-2014, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TAppDecTop.cpp
35    \brief    Decoder application class
36*/
37
38#include <list>
39#include <vector>
40#include <stdio.h>
41#include <fcntl.h>
42#include <assert.h>
43
44#include "TAppDecTop.h"
45#include "TLibDecoder/AnnexBread.h"
46#include "TLibDecoder/NALread.h"
47
48//! \ingroup TAppDecoder
49//! \{
50
51// ====================================================================================================================
52// Constructor / destructor / initialization / destroy
53// ====================================================================================================================
54
55TAppDecTop::TAppDecTop()
56#if !H_MV
57: m_iPOCLastDisplay(-MAX_INT)
58#else
59: m_numDecoders( 0 )
60#endif
61{
62#if H_MV
63  for (Int i = 0; i < MAX_NUM_LAYER_IDS; i++) 
64  {
65    m_layerIdToDecIdx[i] = -1; 
66    m_layerInitilizedFlags[i] = false; 
67  }
68#endif
69#if H_3D
70    m_pScaleOffsetFile  = 0;
71#endif
72
73#if H_MV_HLS_7_VPS_P0300_27
74    m_markedForOutput = false; 
75#endif
76
77}
78
79Void TAppDecTop::create()
80{
81}
82
83Void TAppDecTop::destroy()
84{
85  if (m_pchBitstreamFile)
86  {
87    free (m_pchBitstreamFile);
88    m_pchBitstreamFile = NULL;
89  }
90#if H_MV
91  for (Int decIdx = 0; decIdx < m_numDecoders; decIdx++)
92  {
93    if (m_pchReconFiles[decIdx])
94    {
95      free (m_pchReconFiles[decIdx]);
96      m_pchReconFiles[decIdx] = NULL;
97    }
98  }
99#endif
100  if (m_pchReconFile)
101  {
102    free (m_pchReconFile);
103    m_pchReconFile = NULL;
104  }
105#if H_3D
106  if (m_pchScaleOffsetFile)
107  {
108    free (m_pchScaleOffsetFile);
109    m_pchScaleOffsetFile = NULL; 
110  }
111#endif
112}
113
114// ====================================================================================================================
115// Public member functions
116// ====================================================================================================================
117
118/**
119 - create internal class
120 - initialize internal class
121 - until the end of the bitstream, call decoding function in TDecTop class
122 - delete allocated buffers
123 - destroy internal class
124 .
125 */
126Void TAppDecTop::decode()
127{
128  Int                 poc;
129#if H_MV
130  poc = -1; 
131#endif
132  TComList<TComPic*>* pcListPic = NULL;
133
134  ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
135  if (!bitstreamFile)
136  {
137    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
138    exit(EXIT_FAILURE);
139  }
140
141#if H_3D
142  if( m_pchScaleOffsetFile ) 
143  { 
144    m_pScaleOffsetFile = ::fopen( m_pchScaleOffsetFile, "wt" ); 
145    AOF( m_pScaleOffsetFile ); 
146  }
147#endif
148  InputByteStream bytestream(bitstreamFile);
149
150  // create & initialize internal classes
151  xCreateDecLib();
152  xInitDecLib  ();
153#if !H_MV
154  m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
155
156  // main decoder loop
157  Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
158#else
159
160  Int  pocCurrPic        = -MAX_INT;     
161  Int  pocLastPic        = -MAX_INT;   
162
163#if H_MV_HLS_7_VPS_P0300_27
164  Int  layerIdLastPic    = -MAX_INT; 
165#endif
166  Int  layerIdCurrPic    = 0; 
167
168  Int  decIdxLastPic     = 0; 
169  Int  decIdxCurrPic     = 0; 
170
171  Bool firstSlice        = true; 
172#endif
173  Bool loopFiltered      = false;
174
175  while (!!bitstreamFile)
176  {
177    /* location serves to work around a design fault in the decoder, whereby
178     * the process of reading a new slice that is the first slice of a new frame
179     * requires the TDecTop::decode() method to be called again with the same
180     * nal unit. */
181    streampos location = bitstreamFile.tellg();
182#if H_MV
183#if ENC_DEC_TRACE
184    Int64 symCount = g_nSymbolCounter;
185#endif
186#endif
187    AnnexBStats stats = AnnexBStats();
188    vector<uint8_t> nalUnit;
189    InputNALUnit nalu;
190    byteStreamNALUnit(bytestream, nalUnit, stats);
191
192    // call actual decoding function
193    Bool bNewPicture = false;
194#if H_MV
195    Bool newSliceDiffPoc   = false;
196    Bool newSliceDiffLayer = false;
197    Bool sliceSkippedFlag  = false; 
198    Bool allLayersDecoded  = false;     
199#endif
200    if (nalUnit.empty())
201    {
202      /* this can happen if the following occur:
203       *  - empty input file
204       *  - two back-to-back start_code_prefixes
205       *  - start_code_prefix immediately followed by EOF
206       */
207      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
208    }
209    else
210    {
211      read(nalu, nalUnit);
212#if H_MV     
213      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) 
214          || !isNaluWithinTargetDecLayerIdSet(&nalu)
215          || nalu.m_layerId > MAX_NUM_LAYER_IDS-1
216          || (nalu.m_nalUnitType == NAL_UNIT_VPS && nalu.m_layerId > 0)           
217          || (nalu.m_nalUnitType == NAL_UNIT_EOB && nalu.m_layerId > 0)   
218#if H_MV_HLS_8_MIS_Q0177_47
219          || (nalu.m_nalUnitType == NAL_UNIT_EOS && nalu.m_layerId > 0)   
220#endif
221         ) 
222      {
223        bNewPicture = false;
224        if ( !bitstreamFile )
225        {
226          decIdxLastPic     = decIdxCurrPic; 
227        }
228      }
229      else
230      { 
231        Int decIdx     = xGetDecoderIdx( nalu.m_layerId , true );     
232        newSliceDiffLayer = nalu.isSlice() && ( nalu.m_layerId != layerIdCurrPic ) && !firstSlice;
233        newSliceDiffPoc   = m_tDecTop[decIdx]->decode(nalu, m_iSkipFrame, m_pocLastDisplay[decIdx], newSliceDiffLayer, sliceSkippedFlag );
234        // decode function only returns true when all of the following conditions are true
235        // - poc in particular layer changes
236        // - nalu does not belong to first slice in layer
237        // - nalu.isSlice() == true     
238
239#if H_MV_HLS_7_VPS_P0300_27
240        if ( nalu.m_nalUnitType == NAL_UNIT_VPS )
241        {
242          m_vps = m_tDecTop[decIdx]->getPrefetchedVPS(); 
243          if ( m_targetDecLayerIdSetFileEmpty )
244          {
245            TComVPS* vps = m_vps; 
246#else
247        // Update TargetDecLayerIdList only when not specified by layer id file, specification by file might actually out of conformance.
248        if (nalu.m_nalUnitType == NAL_UNIT_VPS && m_targetDecLayerIdSetFileEmpty )
249        {
250          TComVPS* vps = m_tDecTop[decIdx]->getPrefetchedVPS(); 
251#endif
252          if ( m_targetOptLayerSetIdx == -1 )
253          {
254            // Not normative! Corresponds to specification by "External Means". (Should be set equal to 0, when no external means available. )
255            m_targetOptLayerSetIdx = vps->getVpsNumLayerSetsMinus1(); 
256          }
257#if H_MV_HLS_8_HRD_Q0102_08
258          for (Int dI = 0; dI < m_numDecoders; dI++ )
259          {
260            m_tDecTop[decIdx]->setTargetOptLayerSetIdx( m_targetOptLayerSetIdx ); 
261          }
262#endif
263
264          if ( m_targetOptLayerSetIdx < 0 || m_targetOptLayerSetIdx >= vps->getNumOutputLayerSets() )
265          {
266            fprintf(stderr, "\ntarget output layer set index must be in the range of 0 to %d, inclusive \n", vps->getNumOutputLayerSets() - 1 );           
267            exit(EXIT_FAILURE);
268          }
269          m_targetDecLayerIdSet = vps->getTargetDecLayerIdList( m_targetOptLayerSetIdx ); 
270        }
271#if H_MV_HLS_7_VPS_P0300_27
272      }
273#endif
274#if H_3D
275        if (nalu.m_nalUnitType == NAL_UNIT_VPS )
276        {                 
277          m_cCamParsCollector.init( m_pScaleOffsetFile, m_tDecTop[decIdx]->getPrefetchedVPS() );
278        }       
279#endif
280        bNewPicture       = ( newSliceDiffLayer || newSliceDiffPoc ) && !sliceSkippedFlag; 
281        if ( nalu.isSlice() && firstSlice && !sliceSkippedFlag )       
282        {
283          layerIdCurrPic = nalu.m_layerId; 
284          pocCurrPic     = m_tDecTop[decIdx]->getCurrPoc(); 
285          decIdxCurrPic  = decIdx; 
286          firstSlice     = false; 
287        }
288
289        if ( bNewPicture || !bitstreamFile )
290        { 
291#if H_MV_HLS_7_VPS_P0300_27
292          layerIdLastPic    = layerIdCurrPic; 
293#endif
294          layerIdCurrPic    = nalu.m_layerId; 
295          pocLastPic        = pocCurrPic; 
296          pocCurrPic        = m_tDecTop[decIdx]->getCurrPoc(); 
297          decIdxLastPic     = decIdxCurrPic; 
298          decIdxCurrPic     = decIdx; 
299          allLayersDecoded = ( pocCurrPic != pocLastPic );
300        }
301#else
302      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
303      {
304        bNewPicture = false;
305      }
306      else
307      {
308        bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
309#endif
310        if (bNewPicture)
311        {
312          bitstreamFile.clear();
313          /* location points to the current nalunit payload[1] due to the
314           * need for the annexB parser to read three extra bytes.
315           * [1] except for the first NAL unit in the file
316           *     (but bNewPicture doesn't happen then) */
317          bitstreamFile.seekg(location-streamoff(3));
318          bytestream.reset();
319#if H_MV_ENC_DEC_TRAC
320#if ENC_DEC_TRACE
321          const Bool resetCounter = false; 
322          if ( resetCounter )
323          {
324            g_nSymbolCounter  = symCount; // Only reset counter SH becomes traced twice
325          }
326          else
327          {
328            g_disableHLSTrace = true;     // Tracing of second parsing of SH is not carried out
329          }     
330#endif
331#endif
332        }
333      }
334    }
335    if (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS )
336    {
337      if (!loopFiltered || bitstreamFile)
338      {
339#if H_MV
340        assert( decIdxLastPic != -1 ); 
341        m_tDecTop[decIdxLastPic]->endPicDecoding(poc, pcListPic, m_targetDecLayerIdSet );
342#if H_MV_HLS_7_VPS_P0300_27
343        xMarkForOutput( allLayersDecoded, poc, layerIdLastPic ); 
344#endif
345#else
346        m_cTDecTop.executeLoopFilters(poc, pcListPic);
347#endif
348      }
349      loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
350    }
351#if !FIX_WRITING_OUTPUT
352#if SETTING_NO_OUT_PIC_PRIOR
353    if (bNewPicture && m_cTDecTop.getIsNoOutputPriorPics())
354    {
355      m_cTDecTop.checkNoOutputPriorPics( pcListPic );
356    }
357#endif
358#endif
359#if H_3D
360    if ( allLayersDecoded || !bitstreamFile )
361    {
362      for( Int dI = 0; dI < m_numDecoders; dI++ )
363      {
364        TComPic* picLastCoded = m_ivPicLists.getPic( m_tDecTop[dI]->getLayerId(), pocLastPic );
365        assert( picLastCoded != NULL );       
366        picLastCoded->compressMotion(1);
367      }
368    }
369#endif
370
371    if( pcListPic )
372    {
373#if H_MV
374      if ( m_pchReconFiles[decIdxLastPic] && !m_reconOpen[decIdxLastPic] )
375#else
376      if ( m_pchReconFile && !openedReconFile  )
377#endif
378      {
379        if (!m_outputBitDepthY) { m_outputBitDepthY = g_bitDepthY; }
380        if (!m_outputBitDepthC) { m_outputBitDepthC = g_bitDepthC; }
381
382#if H_MV
383        m_tVideoIOYuvReconFile[decIdxLastPic]->open( m_pchReconFiles[decIdxLastPic], true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
384        m_reconOpen[decIdxLastPic] = true;
385      }
386#if FIX_WRITING_OUTPUT
387      // write reconstruction to file
388      if( bNewPicture )
389      {
390        // Bumping after picture has been decoded
391#if ENC_DEC_TRACE
392        g_bJustDoIt = true; 
393        writeToTraceFile( "Bumping after decoding \n", g_decTracePicOutput  );         
394        g_bJustDoIt = false; 
395#endif
396        xWriteOutput( pcListPic, decIdxLastPic, nalu.m_temporalId );
397      }
398#if SETTING_NO_OUT_PIC_PRIOR
399      if ( (bNewPicture || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) && m_tDecTop[decIdxLastPic]->getNoOutputPriorPicsFlag() )
400      {
401        m_tDecTop[decIdxLastPic]->checkNoOutputPriorPics( pcListPic );
402        m_tDecTop[decIdxLastPic]->setNoOutputPriorPicsFlag (false);
403      }
404#endif
405#endif
406      if ( bNewPicture && newSliceDiffPoc && 
407#else
408        m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
409        openedReconFile  = true;
410      }
411#if FIX_WRITING_OUTPUT
412      // write reconstruction to file
413      if( bNewPicture )
414      {
415        xWriteOutput( pcListPic, nalu.m_temporalId );
416      }
417#if SETTING_NO_OUT_PIC_PRIOR
418      if ( (bNewPicture || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) && m_cTDecTop.getNoOutputPriorPicsFlag() )
419      {
420        m_cTDecTop.checkNoOutputPriorPics( pcListPic );
421        m_cTDecTop.setNoOutputPriorPicsFlag (false);
422      }
423#endif
424#endif
425      if ( bNewPicture && 
426#endif
427           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
428            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
429            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
430            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
431            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
432      {
433#if H_MV
434        xFlushOutput( pcListPic, decIdxLastPic );
435#else
436        xFlushOutput( pcListPic );
437#endif
438      }
439      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
440      {
441#if H_MV
442#if FIX_OUTPUT_EOS
443        xWriteOutput( pcListPic, decIdxLastPic, nalu.m_temporalId );
444#else
445        xFlushOutput( pcListPic, decIdxLastPic );
446#endif
447#else
448#if FIX_OUTPUT_EOS
449        xWriteOutput( pcListPic, nalu.m_temporalId );
450#else
451        xFlushOutput( pcListPic );
452#endif
453
454#endif
455      }
456      // write reconstruction to file -- for additional bumping as defined in C.5.2.3
457#if H_MV
458      // Above comment seems to be wrong
459#endif
460#if FIX_WRITING_OUTPUT
461      if(!bNewPicture && nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL_N && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL31)
462#else
463      if(bNewPicture)
464#endif
465      {
466#if H_MV       
467        // Bumping after reference picture set has been applied (here after first vcl nalu.
468#if ENC_DEC_TRACE
469        g_bJustDoIt = true; 
470        writeToTraceFile( "Bumping after reference picture set has been applied \n", g_decTracePicOutput  );         
471        g_bJustDoIt = false; 
472#endif
473
474        xWriteOutput( m_tDecTop[decIdxCurrPic]->getListPic(), decIdxCurrPic, nalu.m_temporalId );
475#else
476        xWriteOutput( pcListPic, nalu.m_temporalId );
477#endif
478      }
479    }
480  }
481#if H_MV
482#if H_3D
483  if( m_cCamParsCollector.isInitialized() )
484  {
485    m_cCamParsCollector.setSlice( 0 );
486  }
487#endif
488  for(UInt decIdx = 0; decIdx < m_numDecoders; decIdx++)
489  {
490    xFlushOutput( m_tDecTop[decIdx]->getListPic(), decIdx );
491  }
492#else 
493  xFlushOutput( pcListPic );
494  // delete buffers
495  m_cTDecTop.deletePicBuffer();
496#endif
497     
498  // destroy internal classes
499  xDestroyDecLib();
500}
501
502// ====================================================================================================================
503// Protected member functions
504// ====================================================================================================================
505
506Void TAppDecTop::xCreateDecLib()
507{
508#if H_MV
509  // initialize global variables
510  initROM(); 
511#if H_3D_DIM_DMM
512  initWedgeLists();
513#endif
514#else
515  // create decoder class
516  m_cTDecTop.create();
517#endif
518}
519
520Void TAppDecTop::xDestroyDecLib()
521{
522#if H_MV
523  // destroy ROM
524  destroyROM();
525
526  for(Int decIdx = 0; decIdx < m_numDecoders ; decIdx++)
527  {
528    if( m_tVideoIOYuvReconFile[decIdx] )
529    {
530      m_tVideoIOYuvReconFile[decIdx]->close();
531      delete m_tVideoIOYuvReconFile[decIdx]; 
532      m_tVideoIOYuvReconFile[decIdx] = NULL ;
533    }
534
535    if( m_tDecTop[decIdx] )
536    {
537      m_tDecTop[decIdx]->deletePicBuffer();
538      m_tDecTop[decIdx]->destroy() ;
539    }
540    delete m_tDecTop[decIdx] ; 
541    m_tDecTop[decIdx] = NULL ;
542  }
543#else
544  if ( m_pchReconFile )
545  {
546    m_cTVideoIOYuvReconFile. close();
547  }
548 
549  // destroy decoder class
550  m_cTDecTop.destroy();
551#endif
552#if H_3D
553  m_cCamParsCollector.uninit();
554  if( m_pScaleOffsetFile ) 
555  { 
556    ::fclose( m_pScaleOffsetFile ); 
557  }
558#endif
559}
560
561Void TAppDecTop::xInitDecLib()
562{
563#if !H_MV
564  // initialize decoder class
565  m_cTDecTop.init();
566  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
567#endif
568}
569
570/** \param pcListPic list of pictures to be written to file
571    \todo            DYN_REF_FREE should be revised
572 */
573#if H_MV
574Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, Int decIdx, Int tId )
575#else
576Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
577#endif
578{
579
580  if (pcListPic->empty())
581  {
582    return;
583  }
584
585  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
586  Int numPicsNotYetDisplayed = 0;
587  Int dpbFullness = 0;
588#if H_MV
589  // preliminary fix
590  TComSPS* activeSPS = m_tDecTop[0]->getActiveSPS();
591#else
592  TComSPS* activeSPS = m_cTDecTop.getActiveSPS();
593#endif
594  UInt numReorderPicsHighestTid;
595  UInt maxDecPicBufferingHighestTid;
596  UInt maxNrSublayers = activeSPS->getMaxTLayers();
597
598  if(m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers)
599  {
600    numReorderPicsHighestTid = activeSPS->getNumReorderPics(maxNrSublayers-1);
601    maxDecPicBufferingHighestTid =  activeSPS->getMaxDecPicBuffering(maxNrSublayers-1); 
602  }
603  else
604  {
605    numReorderPicsHighestTid = activeSPS->getNumReorderPics(m_iMaxTemporalLayer);
606    maxDecPicBufferingHighestTid = activeSPS->getMaxDecPicBuffering(m_iMaxTemporalLayer); 
607  }
608 
609  while (iterPic != pcListPic->end())
610  {
611    TComPic* pcPic = *(iterPic);
612#if H_MV
613    if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[decIdx])
614#else
615    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
616#endif
617    {
618      numPicsNotYetDisplayed++;
619      dpbFullness++;
620    }
621    else if(pcPic->getSlice( 0 )->isReferenced())
622    {
623      dpbFullness++;
624    }
625    iterPic++;
626  }
627  iterPic   = pcListPic->begin();
628  if (numPicsNotYetDisplayed>2)
629  {
630    iterPic++;
631  }
632 
633  TComPic* pcPic = *(iterPic);
634  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
635  {
636    TComList<TComPic*>::iterator endPic   = pcListPic->end();
637    endPic--;
638    iterPic   = pcListPic->begin();
639    while (iterPic != endPic)
640    {
641      TComPic* pcPicTop = *(iterPic);
642      iterPic++;
643      TComPic* pcPicBottom = *(iterPic);
644     
645#if H_MV
646      if ( pcPicTop->getOutputMark() && (numPicsNotYetDisplayed >  pcPicTop->getNumReorderPics(tId) && !(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1)
647          && pcPicBottom->getOutputMark() && (numPicsNotYetDisplayed >  pcPicBottom->getNumReorderPics(tId) && (pcPicTop->getPOC() == m_pocLastDisplay[decIdx]+1 || m_pocLastDisplay[decIdx]<0)))
648#else
649      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
650          (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
651          (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&
652          (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay < 0))
653#endif
654      {
655        // write to file
656        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
657#if H_MV
658      if ( m_pchReconFiles[decIdx] )
659#else
660        if ( m_pchReconFile )
661#endif
662        {
663          const Window &conf = pcPicTop->getConformanceWindow();
664          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
665
666          const Bool isTff = pcPicTop->isTopField();
667#if H_MV
668        assert( conf   .getScaledFlag() );
669        assert( defDisp.getScaledFlag() );
670#if ENC_DEC_TRACE
671        g_bJustDoIt = true; 
672        writeToTraceFile( "OutputPic Poc"   , pcPic->getPOC    (), g_decTracePicOutput  ); 
673        writeToTraceFile( "OutputPic LayerId", pcPic->getLayerId(), g_decTracePicOutput );         
674        g_bJustDoIt = false; 
675#endif
676        m_tVideoIOYuvReconFile[decIdx]->write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
677#else
678          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
679#endif
680                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
681                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
682                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
683                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
684        }
685       
686        // update POC of display order
687#if H_MV
688        m_pocLastDisplay[decIdx] = pcPic->getPOC();
689#else
690        m_iPOCLastDisplay = pcPicBottom->getPOC();
691#endif
692       
693        // erase non-referenced picture in the reference picture list after display
694        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
695        {
696#if !DYN_REF_FREE
697          pcPicTop->setReconMark(false);
698         
699          // mark it should be extended later
700          pcPicTop->getPicYuvRec()->setBorderExtension( false );
701         
702#else
703          pcPicTop->destroy();
704          pcListPic->erase( iterPic );
705          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
706          continue;
707#endif
708        }
709        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
710        {
711#if !DYN_REF_FREE
712          pcPicBottom->setReconMark(false);
713         
714          // mark it should be extended later
715          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
716         
717#else
718          pcPicBottom->destroy();
719          pcListPic->erase( iterPic );
720          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
721          continue;
722#endif
723        }
724        pcPicTop->setOutputMark(false);
725        pcPicBottom->setOutputMark(false);
726      }
727    }
728  }
729  else if (!pcPic->isField()) //Frame Decoding
730  {
731    iterPic = pcListPic->begin();
732    while (iterPic != pcListPic->end())
733    {
734      pcPic = *(iterPic);
735
736#if H_MV
737      if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[decIdx] &&
738        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
739#else     
740      if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay &&
741        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
742#endif
743      {
744        // write to file
745        numPicsNotYetDisplayed--;
746        if(pcPic->getSlice(0)->isReferenced() == false)
747        {
748          dpbFullness--;
749        }
750#if H_MV
751      if ( m_pchReconFiles[decIdx] )
752#else
753        if ( m_pchReconFile )
754#endif
755        {
756          const Window &conf = pcPic->getConformanceWindow();
757          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
758#if H_MV
759        assert( conf   .getScaledFlag() );
760        assert( defDisp.getScaledFlag() );
761#if ENC_DEC_TRACE
762        g_bJustDoIt = true; 
763        writeToTraceFile( "OutputPic Poc"   , pcPic->getPOC    (), g_decTracePicOutput  ); 
764        writeToTraceFile( "OutputPic LayerId", pcPic->getLayerId(), g_decTracePicOutput );         
765        g_bJustDoIt = false; 
766#endif
767        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
768#else
769          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
770#endif
771                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
772                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
773                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
774                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
775        }
776       
777        // update POC of display order
778#if H_MV
779        m_pocLastDisplay[decIdx] = pcPic->getPOC();
780#else
781        m_iPOCLastDisplay = pcPic->getPOC();
782#endif
783       
784        // erase non-referenced picture in the reference picture list after display
785        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
786        {
787#if !DYN_REF_FREE
788          pcPic->setReconMark(false);
789         
790          // mark it should be extended later
791          pcPic->getPicYuvRec()->setBorderExtension( false );
792         
793#else
794          pcPic->destroy();
795          pcListPic->erase( iterPic );
796          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
797          continue;
798#endif
799        }
800        pcPic->setOutputMark(false);
801#if H_MV_HLS_7_VPS_P0300_27
802        pcPic->setPicOutputFlag(false);
803#endif
804      }
805     
806      iterPic++;
807    }
808  }
809}
810/** \param pcListPic list of pictures to be written to file
811    \todo            DYN_REF_FREE should be revised
812 */
813#if H_MV
814Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int decIdx )
815#else
816Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
817#endif
818{
819  if(!pcListPic || pcListPic->empty())
820  {
821    return;
822  }
823  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
824 
825  iterPic   = pcListPic->begin();
826  TComPic* pcPic = *(iterPic);
827 
828  if (pcPic->isField()) //Field Decoding
829  {
830    TComList<TComPic*>::iterator endPic   = pcListPic->end();
831    endPic--;
832    TComPic *pcPicTop, *pcPicBottom = NULL;
833    while (iterPic != endPic)
834    {
835      pcPicTop = *(iterPic);
836      iterPic++;
837      pcPicBottom = *(iterPic);
838     
839      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
840      {
841        // write to file
842#if H_MV
843      if ( m_pchReconFiles[decIdx] )
844#else
845        if ( m_pchReconFile )
846#endif
847        {
848          const Window &conf = pcPicTop->getConformanceWindow();
849          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
850          const Bool isTff = pcPicTop->isTopField();
851#if H_MV
852        assert( conf   .getScaledFlag() );
853        assert( defDisp.getScaledFlag() );
854#if ENC_DEC_TRACE
855        g_bJustDoIt = true; 
856        writeToTraceFile( "OutputPic Poc"   , pcPic->getPOC    (), g_decTracePicOutput  ); 
857        writeToTraceFile( "OutputPic LayerId", pcPic->getLayerId(), g_decTracePicOutput );         
858        g_bJustDoIt = false; 
859#endif
860        m_tVideoIOYuvReconFile[decIdx]->write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
861#else
862          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
863#endif
864                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
865                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
866                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
867                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
868        }
869       
870        // update POC of display order
871#if H_MV
872      m_pocLastDisplay[decIdx] = pcPic->getPOC();
873#else
874      m_iPOCLastDisplay = pcPicBottom->getPOC();
875#endif       
876        // erase non-referenced picture in the reference picture list after display
877        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
878        {
879#if !DYN_REF_FREE
880          pcPicTop->setReconMark(false);
881         
882          // mark it should be extended later
883          pcPicTop->getPicYuvRec()->setBorderExtension( false );
884         
885#else
886          pcPicTop->destroy();
887          pcListPic->erase( iterPic );
888          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
889          continue;
890#endif
891        }
892        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
893        {
894#if !DYN_REF_FREE
895          pcPicBottom->setReconMark(false);
896         
897          // mark it should be extended later
898          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
899         
900#else
901          pcPicBottom->destroy();
902          pcListPic->erase( iterPic );
903          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
904          continue;
905#endif
906        }
907        pcPicTop->setOutputMark(false);
908        pcPicBottom->setOutputMark(false);
909       
910#if !DYN_REF_FREE
911        if(pcPicTop)
912        {
913          pcPicTop->destroy();
914          delete pcPicTop;
915          pcPicTop = NULL;
916        }
917#endif
918      }
919    }
920    if(pcPicBottom)
921    {
922      pcPicBottom->destroy();
923      delete pcPicBottom;
924      pcPicBottom = NULL;
925    }
926  }
927  else //Frame decoding
928  {
929    while (iterPic != pcListPic->end())
930    {
931      pcPic = *(iterPic);
932     
933      if ( pcPic->getOutputMark() )
934      {
935        // write to file
936#if H_MV
937      if ( m_pchReconFiles[decIdx] )
938#else
939        if ( m_pchReconFile )
940#endif
941        {
942          const Window &conf = pcPic->getConformanceWindow();
943          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
944#if H_MV
945        assert( conf   .getScaledFlag() );
946        assert( defDisp.getScaledFlag() );
947#if ENC_DEC_TRACE
948        g_bJustDoIt = true; 
949        writeToTraceFile( "OutputPic Poc"   , pcPic->getPOC    (), g_decTracePicOutput  ); 
950        writeToTraceFile( "OutputPic LayerId", pcPic->getLayerId(), g_decTracePicOutput );         
951        g_bJustDoIt = false; 
952#endif
953        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
954#else
955          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
956#endif
957                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
958                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
959                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
960                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
961        }
962       
963        // update POC of display order
964#if H_MV
965      m_pocLastDisplay[decIdx] = pcPic->getPOC();
966#else
967        m_iPOCLastDisplay = pcPic->getPOC();
968#endif
969       
970        // erase non-referenced picture in the reference picture list after display
971        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
972        {
973#if !DYN_REF_FREE
974          pcPic->setReconMark(false);
975         
976          // mark it should be extended later
977          pcPic->getPicYuvRec()->setBorderExtension( false );
978         
979#else
980          pcPic->destroy();
981          pcListPic->erase( iterPic );
982          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
983          continue;
984#endif
985        }
986        pcPic->setOutputMark(false);
987#if H_MV_HLS_7_VPS_P0300_27
988        pcPic->setPicOutputFlag(false);
989#endif
990      }
991#if !H_MV
992#if !DYN_REF_FREE
993      if(pcPic)
994      {
995        pcPic->destroy();
996        delete pcPic;
997        pcPic = NULL;
998      }
999#endif   
1000#endif
1001      iterPic++;
1002    }
1003  }
1004#if H_MV
1005  m_pocLastDisplay[decIdx] = -MAX_INT;
1006#else
1007  pcListPic->clear();
1008  m_iPOCLastDisplay = -MAX_INT;
1009#endif
1010}
1011
1012/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
1013 */
1014Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
1015{
1016  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
1017  {
1018    return true;
1019  }
1020  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
1021  {
1022#if H_MV
1023    if ( nalu->m_layerId == (*it) )
1024#else
1025    if ( nalu->m_reservedZero6Bits == (*it) )
1026#endif
1027    {
1028      return true;
1029    }
1030  }
1031  return false;
1032}
1033
1034#if H_MV
1035Int TAppDecTop::xGetDecoderIdx( Int layerId, Bool createFlag /*= false */ )
1036{
1037  Int decIdx = -1; 
1038
1039  if ( layerId > MAX_NUM_LAYER_IDS-1 ) 
1040  {
1041    return decIdx; 
1042  }
1043
1044  if ( m_layerIdToDecIdx[ layerId ] != -1 ) 
1045  {     
1046    decIdx = m_layerIdToDecIdx[ layerId ]; 
1047  }
1048  else
1049  {     
1050    assert ( createFlag ); 
1051    assert( m_numDecoders < MAX_NUM_LAYERS ); 
1052
1053    decIdx = m_numDecoders; 
1054
1055    // Init decoder
1056    m_tDecTop[ decIdx ] =  new TDecTop;
1057    m_tDecTop[ decIdx ]->create();
1058    m_tDecTop[ decIdx ]->init( );
1059    m_tDecTop[ decIdx ]->setLayerId( layerId );
1060    m_tDecTop[ decIdx ]->setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
1061    m_tDecTop[ decIdx ]->setIvPicLists( &m_ivPicLists ); 
1062    m_tDecTop[ decIdx ]->setLayerInitilizedFlags( m_layerInitilizedFlags );
1063#if    H_MV_HLS_8_HRD_Q0102_08
1064    m_tDecTop[ decIdx ]->setTargetOptLayerSetIdx( m_targetOptLayerSetIdx );   
1065#endif
1066
1067#if H_3D
1068   m_tDecTop[ decIdx ]->setCamParsCollector( &m_cCamParsCollector );
1069#endif
1070
1071    // append pic list of new decoder to PicLists
1072    assert( m_ivPicLists.size() == m_numDecoders );
1073    m_ivPicLists.push_back( m_tDecTop[ decIdx ]->getListPic() );
1074
1075    // create recon file related stuff     
1076    Char* pchTempFilename = NULL;
1077    if ( m_pchReconFile )
1078    {     
1079      Char buffer[4];     
1080      sprintf(buffer,"_%i", layerId );
1081      assert ( m_pchReconFile ); 
1082      xAppendToFileNameEnd( m_pchReconFile , buffer, pchTempFilename );
1083      assert( m_pchReconFiles.size() == m_numDecoders );
1084    }
1085
1086    m_pchReconFiles.push_back( pchTempFilename );   
1087
1088    m_tVideoIOYuvReconFile[ decIdx ] = new TVideoIOYuv;
1089    m_reconOpen           [ decIdx ] = false;
1090
1091    // set others
1092    m_pocLastDisplay      [ decIdx ] = -MAX_INT;
1093    m_layerIdToDecIdx     [ layerId ] = decIdx; 
1094
1095    m_numDecoders++; 
1096  };
1097  return decIdx;
1098
1099}
1100
1101
1102#if H_MV_HLS_7_VPS_P0300_27
1103Void TAppDecTop::xMarkForOutput( Bool allLayersDecoded, Int pocLastPic, Int layerIdLastPic )
1104{ 
1105  vector<Int> targetOptLayerIdList = m_vps->getTargetOptLayerIdList( m_targetOptLayerSetIdx );
1106
1107  if (m_vps->getAltOutputLayerFlagVar( m_targetOptLayerSetIdx ) )
1108  {
1109    assert( targetOptLayerIdList.size() == 1 ); 
1110    Int targetLayerId = targetOptLayerIdList[0];     
1111
1112    TComPic* curPic = m_ivPicLists.getPic( layerIdLastPic, pocLastPic );
1113    assert( curPic != NULL );
1114
1115    if ( layerIdLastPic == targetLayerId )
1116    {
1117      if ( curPic->getPicOutputFlag() )
1118      {
1119        curPic->setOutputMark( true );
1120      }
1121      else
1122      {       
1123        xMarkAltOutPic( targetLayerId, pocLastPic ); 
1124      }
1125      m_markedForOutput = true; 
1126    }
1127    else if ( ( layerIdLastPic > targetLayerId || allLayersDecoded ) && !m_markedForOutput )
1128    {
1129      xMarkAltOutPic( targetLayerId, pocLastPic );
1130    }
1131
1132    if ( allLayersDecoded )
1133    {
1134      m_markedForOutput = false; 
1135    }
1136  }
1137  else
1138  { 
1139    for( Int dI = 0; dI < m_numDecoders; dI++ )
1140    {     
1141      Int layerId = m_tDecTop[dI]->getLayerId(); 
1142      TComPic* curPic = m_ivPicLists.getPic( layerId, pocLastPic );
1143      if ( curPic != NULL )
1144      {
1145        if ( curPic->getReconMark() )
1146        {
1147          Bool isTargetOptLayer = std::find(targetOptLayerIdList.begin(), targetOptLayerIdList.end(), layerId) != targetOptLayerIdList.end();
1148          curPic->setOutputMark( isTargetOptLayer ? curPic->getPicOutputFlag() : false ); 
1149        }
1150      }
1151    }
1152  }
1153}
1154#endif
1155#endif
1156//! \}
Note: See TracBrowser for help on using the repository browser.