source: 3DVCSoftware/branches/HTM-10.0rc1-dev0/source/App/TAppDecoder/TAppDecTop.cpp @ 838

Last change on this file since 838 was 838, checked in by tech, 10 years ago

Further fixes.

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