source: 3DVCSoftware/branches/HTM-9.0-dev0/source/App/TAppDecoder/TAppDecTop.cpp @ 1417

Last change on this file since 1417 was 730, checked in by tech, 11 years ago

MV HEVC 6 HLS changes.

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