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

Last change on this file since 900 was 884, checked in by tech, 11 years ago

Merged HTM-10.1-dev0@883. (MV-HEVC 7 HLS)

  • Property svn:eol-style set to native
File size: 28.7 KB
RevLine 
[5]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
[56]4 * granted under this license. 
[5]5 *
[872]6* Copyright (c) 2010-2014, ITU/ISO/IEC
[5]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.
[56]17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
[5]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 */
[2]33
34/** \file     TAppDecTop.cpp
35    \brief    Decoder application class
36*/
37
38#include <list>
[56]39#include <vector>
[2]40#include <stdio.h>
41#include <fcntl.h>
42#include <assert.h>
43
44#include "TAppDecTop.h"
[56]45#include "TLibDecoder/AnnexBread.h"
46#include "TLibDecoder/NALread.h"
[2]47
[56]48//! \ingroup TAppDecoder
49//! \{
[2]50
51// ====================================================================================================================
52// Constructor / destructor / initialization / destroy
53// ====================================================================================================================
54
55TAppDecTop::TAppDecTop()
[608]56#if !H_MV
57: m_iPOCLastDisplay(-MAX_INT)
58#else
59: m_numDecoders( 0 )
60#endif
[2]61{
[608]62#if H_MV
[738]63  for (Int i = 0; i < MAX_NUM_LAYER_IDS; i++) 
64  {
65    m_layerIdToDecIdx[i] = -1; 
66    m_layerInitilizedFlags[i] = false; 
67  }
[608]68#endif
69#if H_3D
70    m_pScaleOffsetFile  = 0;
71#endif
[2]72}
73
74Void TAppDecTop::create()
75{
76}
77
78Void TAppDecTop::destroy()
79{
[608]80  if (m_pchBitstreamFile)
81  {
82    free (m_pchBitstreamFile);
83    m_pchBitstreamFile = NULL;
84  }
85#if H_MV
86  for (Int decIdx = 0; decIdx < m_numDecoders; decIdx++)
87  {
88    if (m_pchReconFiles[decIdx])
89    {
90      free (m_pchReconFiles[decIdx]);
91      m_pchReconFiles[decIdx] = NULL;
92    }
93  }
94#endif
95  if (m_pchReconFile)
96  {
97    free (m_pchReconFile);
98    m_pchReconFile = NULL;
99  }
100#if H_3D
101  if (m_pchScaleOffsetFile)
102  {
103    free (m_pchScaleOffsetFile);
104    m_pchScaleOffsetFile = NULL; 
105  }
106#endif
[2]107}
108
109// ====================================================================================================================
110// Public member functions
111// ====================================================================================================================
112
113/**
114 - create internal class
115 - initialize internal class
116 - until the end of the bitstream, call decoding function in TDecTop class
117 - delete allocated buffers
118 - destroy internal class
119 .
120 */
121Void TAppDecTop::decode()
122{
[608]123  Int                 poc;
124#if H_MV
125  poc = -1; 
[77]126#endif
[608]127  TComList<TComPic*>* pcListPic = NULL;
[210]128
[56]129  ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
130  if (!bitstreamFile)
131  {
132    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
133    exit(EXIT_FAILURE);
134  }
[2]135
[608]136#if H_3D
[56]137  if( m_pchScaleOffsetFile ) 
138  { 
139    m_pScaleOffsetFile = ::fopen( m_pchScaleOffsetFile, "wt" ); 
140    AOF( m_pScaleOffsetFile ); 
141  }
[608]142#endif
[56]143  InputByteStream bytestream(bitstreamFile);
144
[608]145  // create & initialize internal classes
146  xCreateDecLib();
147  xInitDecLib  ();
148#if !H_MV
149  m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
150
151  // main decoder loop
[655]152  Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
[608]153#else
154#if H_3D
155  Int  pocCurrPic        = -MAX_INT;     
156  Int  pocLastPic        = -MAX_INT;   
157#endif
158
159  Int  layerIdCurrPic    = 0; 
160
161  Int  decIdxLastPic     = 0; 
162  Int  decIdxCurrPic     = 0; 
163
164  Bool firstSlice        = true; 
165#endif
[872]166  Bool loopFiltered      = false;
167
[56]168  while (!!bitstreamFile)
[2]169  {
[56]170    /* location serves to work around a design fault in the decoder, whereby
171     * the process of reading a new slice that is the first slice of a new frame
172     * requires the TDecTop::decode() method to be called again with the same
173     * nal unit. */
174    streampos location = bitstreamFile.tellg();
[608]175#if H_MV
176#if ENC_DEC_TRACE
177    Int64 symCount = g_nSymbolCounter;
178#endif
179#endif
[56]180    AnnexBStats stats = AnnexBStats();
181    vector<uint8_t> nalUnit;
182    InputNALUnit nalu;
183    byteStreamNALUnit(bytestream, nalUnit, stats);
184
185    // call actual decoding function
[608]186    Bool bNewPicture = false;
187#if H_MV
188    Bool newSliceDiffPoc   = false;
189    Bool newSliceDiffLayer = false;
[738]190    Bool sliceSkippedFlag = false; 
[608]191#if H_3D
192    Bool allLayersDecoded  = false;     
193#endif
194#endif
[56]195    if (nalUnit.empty())
[2]196    {
[56]197      /* this can happen if the following occur:
198       *  - empty input file
199       *  - two back-to-back start_code_prefixes
200       *  - start_code_prefix immediately followed by EOF
201       */
202      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
[2]203    }
204    else
205    {
[56]206      read(nalu, nalUnit);
[608]207#if H_MV     
[872]208      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) 
209          || !isNaluWithinTargetDecLayerIdSet(&nalu)
210          || nalu.m_layerId > MAX_NUM_LAYER_IDS-1
211          || (nalu.m_nalUnitType == NAL_UNIT_VPS && nalu.m_layerId > 0)           
212          || (nalu.m_nalUnitType == NAL_UNIT_EOB && nalu.m_layerId > 0)           
213         ) 
[77]214      {
[608]215        bNewPicture = false;
[738]216        if ( !bitstreamFile )
217        {
218          decIdxLastPic     = decIdxCurrPic; 
219        }
[77]220      }
[210]221      else
[608]222      { 
[738]223        Int decIdx     = xGetDecoderIdx( nalu.m_layerId , true );     
[608]224        newSliceDiffLayer = nalu.isSlice() && ( nalu.m_layerId != layerIdCurrPic ) && !firstSlice;
[738]225        newSliceDiffPoc   = m_tDecTop[decIdx]->decode(nalu, m_iSkipFrame, m_pocLastDisplay[decIdx], newSliceDiffLayer, sliceSkippedFlag );
[608]226        // decode function only returns true when all of the following conditions are true
227        // - poc in particular layer changes
228        // - nalu does not belong to first slice in layer
229        // - nalu.isSlice() == true     
230
[738]231        // Update TargetDecLayerIdList only when not specified by layer id file, specification by file might actually out of conformance.
232        if (nalu.m_nalUnitType == NAL_UNIT_VPS && m_targetDecLayerIdSetFileEmpty )
233        {
234          TComVPS* vps = m_tDecTop[decIdx]->getPrefetchedVPS(); 
235          if ( m_targetOptLayerSetIdx == -1 )
236          {
237            // Not normative! Corresponds to specification by "External Means". (Should be set equal to 0, when no external means available. )
238            m_targetOptLayerSetIdx = vps->getVpsNumLayerSetsMinus1(); 
239          }
240
[872]241          if ( m_targetOptLayerSetIdx < 0 || m_targetOptLayerSetIdx >= vps->getNumOutputLayerSets() )
242          {
243            fprintf(stderr, "\ntarget output layer set index must be in the range of 0 to %d, inclusive \n", vps->getNumOutputLayerSets() - 1 );           
244            exit(EXIT_FAILURE);
245          }
[738]246          m_targetDecLayerIdSet = vps->getTargetDecLayerIdList( m_targetOptLayerSetIdx ); 
247        }
[872]248
249#if H_3D
250        if (nalu.m_nalUnitType == NAL_UNIT_VPS )
[884]251        {                 
[872]252          m_cCamParsCollector.init( m_pScaleOffsetFile, m_tDecTop[decIdx]->getPrefetchedVPS() );
253        }       
254#endif
[738]255        bNewPicture       = ( newSliceDiffLayer || newSliceDiffPoc ) && !sliceSkippedFlag; 
256        if ( nalu.isSlice() && firstSlice && !sliceSkippedFlag )       
[210]257        {
[608]258          layerIdCurrPic = nalu.m_layerId; 
259#if H_3D
260          pocCurrPic     = m_tDecTop[decIdx]->getCurrPoc(); 
261#endif
262          decIdxCurrPic  = decIdx; 
263          firstSlice     = false; 
[210]264        }
[608]265
266        if ( bNewPicture || !bitstreamFile )
267        { 
268          layerIdCurrPic    = nalu.m_layerId; 
269#if H_3D         
270          pocLastPic        = pocCurrPic; 
271          pocCurrPic        = m_tDecTop[decIdx]->getCurrPoc(); 
272#endif         
273          decIdxLastPic     = decIdxCurrPic; 
274          decIdxCurrPic     = decIdx; 
275#if H_3D
276          allLayersDecoded = ( pocCurrPic != pocLastPic );
277#endif
[210]278        }
279#else
[608]280      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
[210]281      {
[655]282        bNewPicture = false;
[210]283      }
[608]284      else
[2]285      {
[608]286        bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
[56]287#endif
[608]288        if (bNewPicture)
[42]289        {
[56]290          bitstreamFile.clear();
291          /* location points to the current nalunit payload[1] due to the
292           * need for the annexB parser to read three extra bytes.
293           * [1] except for the first NAL unit in the file
294           *     (but bNewPicture doesn't happen then) */
295          bitstreamFile.seekg(location-streamoff(3));
296          bytestream.reset();
[872]297#if H_MV_ENC_DEC_TRAC
[608]298#if ENC_DEC_TRACE
299          const Bool resetCounter = false; 
300          if ( resetCounter )
301          {
302            g_nSymbolCounter  = symCount; // Only reset counter SH becomes traced twice
[210]303          }
[608]304          else
305          {
[872]306            g_disableHLSTrace = true;     // Tracing of second parsing of SH is not carried out
307          }     
[210]308#endif
[608]309#endif
[42]310        }
311      }
[56]312    }
[872]313    if (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS )
[56]314    {
[872]315      if (!loopFiltered || bitstreamFile)
316      {
[608]317#if H_MV
[872]318        assert( decIdxLastPic != -1 ); 
319        m_tDecTop[decIdxLastPic]->endPicDecoding(poc, pcListPic, m_targetDecLayerIdSet );
[608]320#else
[872]321        m_cTDecTop.executeLoopFilters(poc, pcListPic);
[608]322#endif
[872]323      }
324      loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
[56]325    }
[608]326#if H_3D
327    if ( allLayersDecoded || !bitstreamFile )
[56]328    {
[608]329      for( Int dI = 0; dI < m_numDecoders; dI++ )
330      {
331        TComPic* picLastCoded = m_ivPicLists.getPic( m_tDecTop[dI]->getLayerId(), pocLastPic );
332        assert( picLastCoded != NULL );       
333        picLastCoded->compressMotion(1);
334      }
335    }
336#endif
337
338    if( pcListPic )
339    {
340#if H_MV
341      if ( m_pchReconFiles[decIdxLastPic] && !m_reconOpen[decIdxLastPic] )
342#else
[655]343      if ( m_pchReconFile && !openedReconFile  )
[608]344#endif
[2]345      {
[608]346        if (!m_outputBitDepthY) { m_outputBitDepthY = g_bitDepthY; }
347        if (!m_outputBitDepthC) { m_outputBitDepthC = g_bitDepthC; }
348
349#if H_MV
350        m_tVideoIOYuvReconFile[decIdxLastPic]->open( m_pchReconFiles[decIdxLastPic], true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
351        m_reconOpen[decIdxLastPic] = true;
[2]352      }
[608]353      if ( bNewPicture && newSliceDiffPoc && 
354#else
355        m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
[655]356        openedReconFile  = true;
[608]357      }
358      if ( bNewPicture && 
359#endif
360           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
361            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
362            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
363            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
364            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
365      {
366#if H_MV
367        xFlushOutput( pcListPic, decIdxLastPic );
368#else
369        xFlushOutput( pcListPic );
370#endif
371      }
[872]372      if (nalu.m_nalUnitType == NAL_UNIT_EOS)
373      {
374#if H_MV
375        xFlushOutput( pcListPic, decIdxLastPic );
376#else
377        xFlushOutput( pcListPic );
378#endif
379      }
[56]380      // write reconstruction to file
[608]381      if(bNewPicture)
[2]382      {
[608]383#if H_MV
384        xWriteOutput( pcListPic, decIdxLastPic, nalu.m_temporalId );
[2]385      }
386    }
[608]387  }
388
389#if H_3D
[57]390  if( m_cCamParsCollector.isInitialized() )
391  {
392    m_cCamParsCollector.setSlice( 0 );
393  }
[608]394#endif
395  for(UInt decIdx = 0; decIdx < m_numDecoders; decIdx++)
[2]396  {
[608]397    xFlushOutput( m_tDecTop[decIdx]->getListPic(), decIdx );
398  }
399#else
400        xWriteOutput( pcListPic, nalu.m_temporalId );
401      }
402    }
403  }
404 
405  xFlushOutput( pcListPic );
406  // delete buffers
407  m_cTDecTop.deletePicBuffer();
408#endif
409     
410  // destroy internal classes
[2]411  xDestroyDecLib();
412}
413
414// ====================================================================================================================
415// Protected member functions
416// ====================================================================================================================
417
[608]418Void TAppDecTop::xCreateDecLib()
419{
420#if H_MV
421  // initialize global variables
422  initROM(); 
423#if H_3D_DIM_DMM
424  initWedgeLists();
425#endif
426#else
427  // create decoder class
428  m_cTDecTop.create();
429#endif
430}
431
[2]432Void TAppDecTop::xDestroyDecLib()
433{
[608]434#if H_MV
435  // destroy ROM
436  destroyROM();
[2]437
[608]438  for(Int decIdx = 0; decIdx < m_numDecoders ; decIdx++)
[2]439  {
[608]440    if( m_tVideoIOYuvReconFile[decIdx] )
[56]441    {
[608]442      m_tVideoIOYuvReconFile[decIdx]->close();
443      delete m_tVideoIOYuvReconFile[decIdx]; 
444      m_tVideoIOYuvReconFile[decIdx] = NULL ;
[56]445    }
[2]446
[608]447    if( m_tDecTop[decIdx] )
[56]448    {
[608]449      m_tDecTop[decIdx]->deletePicBuffer();
450      m_tDecTop[decIdx]->destroy() ;
[56]451    }
[608]452    delete m_tDecTop[decIdx] ; 
453    m_tDecTop[decIdx] = NULL ;
[2]454  }
[608]455#else
456  if ( m_pchReconFile )
457  {
458    m_cTVideoIOYuvReconFile. close();
459  }
460 
461  // destroy decoder class
462  m_cTDecTop.destroy();
463#endif
464#if H_3D
[57]465  m_cCamParsCollector.uninit();
466  if( m_pScaleOffsetFile ) 
467  { 
468    ::fclose( m_pScaleOffsetFile ); 
469  }
[608]470#endif
[56]471}
[2]472
[608]473Void TAppDecTop::xInitDecLib()
[56]474{
[608]475#if !H_MV
476  // initialize decoder class
477  m_cTDecTop.init();
478  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
479#endif
480}
481
482/** \param pcListPic list of pictures to be written to file
483    \todo            DYN_REF_FREE should be revised
484 */
485#if H_MV
486Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, Int decIdx, Int tId )
487#else
488Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
489#endif
490{
[872]491
492  if (pcListPic->empty())
493  {
494    return;
495  }
496
[56]497  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
[655]498  Int numPicsNotYetDisplayed = 0;
499 
[56]500  while (iterPic != pcListPic->end())
[2]501  {
[56]502    TComPic* pcPic = *(iterPic);
[608]503#if H_MV
504    if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[decIdx])
505#else
506    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
507#endif
[56]508    {
[655]509      numPicsNotYetDisplayed++;
[56]510    }
511    iterPic++;
[2]512  }
[56]513  iterPic   = pcListPic->begin();
[655]514  if (numPicsNotYetDisplayed>2)
515  {
516    iterPic++;
517  }
[56]518 
[655]519  TComPic* pcPic = *(iterPic);
520  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
[2]521  {
[655]522    TComList<TComPic*>::iterator endPic   = pcListPic->end();
523    endPic--;
524    iterPic   = pcListPic->begin();
525    while (iterPic != endPic)
526    {
527      TComPic* pcPicTop = *(iterPic);
528      iterPic++;
529      TComPic* pcPicBottom = *(iterPic);
530     
[608]531#if H_MV
[655]532      if ( pcPicTop->getOutputMark() && (numPicsNotYetDisplayed >  pcPicTop->getNumReorderPics(tId) && !(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1)
533          && pcPicBottom->getOutputMark() && (numPicsNotYetDisplayed >  pcPicBottom->getNumReorderPics(tId) && (pcPicTop->getPOC() == m_pocLastDisplay[decIdx]+1 || m_pocLastDisplay[decIdx]<0)))
[608]534#else
[655]535      if ( pcPicTop->getOutputMark() && (numPicsNotYetDisplayed >  pcPicTop->getNumReorderPics(tId) && !(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1)
536          && pcPicBottom->getOutputMark() && (numPicsNotYetDisplayed >  pcPicBottom->getNumReorderPics(tId) && (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay<0)))
[608]537#endif
[655]538      {
539        // write to file
540        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
[608]541#if H_MV
542      if ( m_pchReconFiles[decIdx] )
543#else
[655]544        if ( m_pchReconFile )
[608]545#endif
[655]546        {
547          const Window &conf = pcPicTop->getConformanceWindow();
548          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
549
550          const Bool isTff = pcPicTop->isTopField();
[608]551#if H_MV
[622]552        assert( conf   .getScaledFlag() );
553        assert( defDisp.getScaledFlag() );
[655]554        m_tVideoIOYuvReconFile[decIdx]->write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
555#else
556          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
[622]557#endif
[655]558                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
559                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
560                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
561                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
562        }
563       
564        // update POC of display order
565#if H_MV
566        m_pocLastDisplay[decIdx] = pcPic->getPOC();
[608]567#else
[655]568        m_iPOCLastDisplay = pcPicBottom->getPOC();
[608]569#endif
[655]570       
571        // erase non-referenced picture in the reference picture list after display
572        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
573        {
574#if !DYN_REF_FREE
575          pcPicTop->setReconMark(false);
576         
577          // mark it should be extended later
578          pcPicTop->getPicYuvRec()->setBorderExtension( false );
579         
580#else
581          pcPicTop->destroy();
582          pcListPic->erase( iterPic );
583          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
584          continue;
585#endif
586        }
587        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
588        {
589#if !DYN_REF_FREE
590          pcPicBottom->setReconMark(false);
591         
592          // mark it should be extended later
593          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
594         
595#else
596          pcPicBottom->destroy();
597          pcListPic->erase( iterPic );
598          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
599          continue;
600#endif
601        }
602        pcPicTop->setOutputMark(false);
603        pcPicBottom->setOutputMark(false);
[56]604      }
[655]605    }
606  }
607  else if (!pcPic->isField()) //Frame Decoding
608  {
609    iterPic = pcListPic->begin();
610    while (iterPic != pcListPic->end())
611    {
612      pcPic = *(iterPic);
613
[608]614#if H_MV
[655]615      if ( pcPic->getOutputMark() && (numPicsNotYetDisplayed >  pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_pocLastDisplay[decIdx]))
616#else     
617      if ( pcPic->getOutputMark() && (numPicsNotYetDisplayed >  pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_iPOCLastDisplay))
618#endif
619      {
620        // write to file
621        numPicsNotYetDisplayed--;
622#if H_MV
623      if ( m_pchReconFiles[decIdx] )
[608]624#else
[655]625        if ( m_pchReconFile )
[608]626#endif
[655]627        {
628          const Window &conf = pcPic->getConformanceWindow();
629          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
630#if H_MV
631        assert( conf   .getScaledFlag() );
632        assert( defDisp.getScaledFlag() );
633        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
634#else
635          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
636#endif
637                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
638                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
639                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
640                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
641        }
[56]642       
[655]643        // update POC of display order
644#if H_MV
645        m_pocLastDisplay[decIdx] = pcPic->getPOC();
646#else
647        m_iPOCLastDisplay = pcPic->getPOC();
648#endif
[56]649       
[655]650        // erase non-referenced picture in the reference picture list after display
651        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
652        {
653#if !DYN_REF_FREE
654          pcPic->setReconMark(false);
655         
656          // mark it should be extended later
657          pcPic->getPicYuvRec()->setBorderExtension( false );
658         
[56]659#else
[655]660          pcPic->destroy();
661          pcListPic->erase( iterPic );
662          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
663          continue;
[56]664#endif
[655]665        }
666        pcPic->setOutputMark(false);
[56]667      }
[655]668     
669      iterPic++;
[56]670    }
[2]671  }
672}
673/** \param pcListPic list of pictures to be written to file
674    \todo            DYN_REF_FREE should be revised
675 */
[608]676#if H_MV
677Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int decIdx )
678#else
679Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
680#endif
[2]681{
[872]682  if(!pcListPic || pcListPic->empty())
[56]683  {
684    return;
[655]685  }
[2]686  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
[655]687 
[56]688  iterPic   = pcListPic->begin();
[655]689  TComPic* pcPic = *(iterPic);
[56]690 
[655]691  if (pcPic->isField()) //Field Decoding
[2]692  {
[655]693    TComList<TComPic*>::iterator endPic   = pcListPic->end();
694    endPic--;
695    TComPic *pcPicTop, *pcPicBottom = NULL;
696    while (iterPic != endPic)
[2]697    {
[655]698      pcPicTop = *(iterPic);
699      iterPic++;
700      pcPicBottom = *(iterPic);
701     
702      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
703      {
704        // write to file
[608]705#if H_MV
706      if ( m_pchReconFiles[decIdx] )
707#else
[655]708        if ( m_pchReconFile )
[608]709#endif
[655]710        {
711          const Window &conf = pcPicTop->getConformanceWindow();
712          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
713          const Bool isTff = pcPicTop->isTopField();
[608]714#if H_MV
[622]715        assert( conf   .getScaledFlag() );
716        assert( defDisp.getScaledFlag() );
[655]717        m_tVideoIOYuvReconFile[decIdx]->write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
718#else
719          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
[622]720#endif
[655]721                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
722                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
723                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
724                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
725        }
726       
727        // update POC of display order
728#if H_MV
729      m_pocLastDisplay[decIdx] = pcPic->getPOC();
[608]730#else
[655]731      m_iPOCLastDisplay = pcPicBottom->getPOC();
732#endif       
733        // erase non-referenced picture in the reference picture list after display
734        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
735        {
736#if !DYN_REF_FREE
737          pcPicTop->setReconMark(false);
738         
739          // mark it should be extended later
740          pcPicTop->getPicYuvRec()->setBorderExtension( false );
741         
742#else
743          pcPicTop->destroy();
744          pcListPic->erase( iterPic );
745          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
746          continue;
[608]747#endif
[655]748        }
749        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
750        {
751#if !DYN_REF_FREE
752          pcPicBottom->setReconMark(false);
753         
754          // mark it should be extended later
755          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
756         
757#else
758          pcPicBottom->destroy();
759          pcListPic->erase( iterPic );
760          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
761          continue;
762#endif
763        }
764        pcPicTop->setOutputMark(false);
765        pcPicBottom->setOutputMark(false);
766       
767#if !DYN_REF_FREE
768        if(pcPicTop)
769        {
770          pcPicTop->destroy();
771          delete pcPicTop;
772          pcPicTop = NULL;
773        }
774#endif
[2]775      }
[655]776    }
777    if(pcPicBottom)
778    {
779      pcPicBottom->destroy();
780      delete pcPicBottom;
781      pcPicBottom = NULL;
782    }
783  }
784  else //Frame decoding
785  {
786    while (iterPic != pcListPic->end())
787    {
788      pcPic = *(iterPic);
[56]789     
[655]790      if ( pcPic->getOutputMark() )
791      {
792        // write to file
[608]793#if H_MV
[655]794      if ( m_pchReconFiles[decIdx] )
795#else
796        if ( m_pchReconFile )
797#endif
798        {
799          const Window &conf = pcPic->getConformanceWindow();
800          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
801#if H_MV
802        assert( conf   .getScaledFlag() );
803        assert( defDisp.getScaledFlag() );
804        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
805#else
806          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
807#endif
808                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
809                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
810                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
811                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
812        }
813       
814        // update POC of display order
815#if H_MV
[608]816      m_pocLastDisplay[decIdx] = pcPic->getPOC();
817#else
[655]818        m_iPOCLastDisplay = pcPic->getPOC();
[608]819#endif
[655]820       
821        // erase non-referenced picture in the reference picture list after display
822        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
823        {
[56]824#if !DYN_REF_FREE
[655]825          pcPic->setReconMark(false);
826         
827          // mark it should be extended later
828          pcPic->getPicYuvRec()->setBorderExtension( false );
829         
[56]830#else
[655]831          pcPic->destroy();
832          pcListPic->erase( iterPic );
833          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
834          continue;
[56]835#endif
[655]836        }
837        pcPic->setOutputMark(false);
[2]838      }
[608]839#if !H_MV
840#if !DYN_REF_FREE
[655]841      if(pcPic)
842      {
843        pcPic->destroy();
844        delete pcPic;
845        pcPic = NULL;
846      }
847#endif   
848#endif
849      iterPic++;
[608]850    }
[2]851  }
[608]852#if H_MV
853  m_pocLastDisplay[decIdx] = -MAX_INT;
854#else
[56]855  pcListPic->clear();
[608]856  m_iPOCLastDisplay = -MAX_INT;
857#endif
[2]858}
[608]859
860/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
861 */
862Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
[2]863{
[608]864  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
[2]865  {
[608]866    return true;
[2]867  }
[608]868  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
869  {
870#if H_MV
871    if ( nalu->m_layerId == (*it) )
[81]872#else
[608]873    if ( nalu->m_reservedZero6Bits == (*it) )
[81]874#endif
[56]875    {
[608]876      return true;
[56]877    }
878  }
[608]879  return false;
[2]880}
881
[608]882#if H_MV
883Int TAppDecTop::xGetDecoderIdx( Int layerId, Bool createFlag /*= false */ )
884{
885  Int decIdx = -1; 
[738]886
887  if ( layerId > MAX_NUM_LAYER_IDS-1 ) 
888  {
889    return decIdx; 
890  }
891
[608]892  if ( m_layerIdToDecIdx[ layerId ] != -1 ) 
893  {     
894    decIdx = m_layerIdToDecIdx[ layerId ]; 
[210]895  }
896  else
[608]897  {     
898    assert ( createFlag ); 
899    assert( m_numDecoders < MAX_NUM_LAYERS ); 
[210]900
[608]901    decIdx = m_numDecoders; 
902
903    // Init decoder
904    m_tDecTop[ decIdx ] =  new TDecTop;
905    m_tDecTop[ decIdx ]->create();
906    m_tDecTop[ decIdx ]->init( );
907    m_tDecTop[ decIdx ]->setLayerId( layerId );
908    m_tDecTop[ decIdx ]->setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
909    m_tDecTop[ decIdx ]->setIvPicLists( &m_ivPicLists ); 
[738]910    m_tDecTop[ decIdx ]->setLayerInitilizedFlags( m_layerInitilizedFlags );
911
[608]912#if H_3D
913   m_tDecTop[ decIdx ]->setCamParsCollector( &m_cCamParsCollector );
[210]914#endif
[2]915
[608]916    // append pic list of new decoder to PicLists
917    assert( m_ivPicLists.size() == m_numDecoders );
918    m_ivPicLists.push_back( m_tDecTop[ decIdx ]->getListPic() );
[2]919
[608]920    // create recon file related stuff     
921    Char* pchTempFilename = NULL;
922    if ( m_pchReconFile )
923    {     
924      Char buffer[4];     
925      sprintf(buffer,"_%i", layerId );
926      assert ( m_pchReconFile ); 
927      xAppendToFileNameEnd( m_pchReconFile , buffer, pchTempFilename );
928      assert( m_pchReconFiles.size() == m_numDecoders );
[2]929    }
[210]930
[608]931    m_pchReconFiles.push_back( pchTempFilename );   
[296]932
[608]933    m_tVideoIOYuvReconFile[ decIdx ] = new TVideoIOYuv;
934    m_reconOpen           [ decIdx ] = false;
[443]935
[608]936    // set others
937    m_pocLastDisplay      [ decIdx ] = -MAX_INT;
938    m_layerIdToDecIdx     [ layerId ] = decIdx; 
[296]939
[608]940    m_numDecoders++; 
941  };
942  return decIdx;
[296]943}
944#endif
[56]945//! \}
Note: See TracBrowser for help on using the repository browser.