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

Last change on this file since 710 was 655, checked in by tech, 11 years ago

Merged 8.1-Cleanup@654

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