source: 3DVCSoftware/branches/HTM-9.1-dev0-ZTE/source/App/TAppDecoder/TAppDecTop.cpp

Last change on this file was 738, checked in by tech, 11 years ago

Merged HTM-9.0-dev0@731. (MV-HEVC 6 HLS)

  • Property svn:eol-style set to native
File size: 28.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-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
267        if ( nalu.isSlice() && firstSlice )
268#endif
269        {
270          layerIdCurrPic = nalu.m_layerId; 
271#if H_3D
272          pocCurrPic     = m_tDecTop[decIdx]->getCurrPoc(); 
273#endif
274          decIdxCurrPic  = decIdx; 
275          firstSlice     = false; 
276        }
277
278        if ( bNewPicture || !bitstreamFile )
279        { 
280          layerIdCurrPic    = nalu.m_layerId; 
281#if H_3D         
282          pocLastPic        = pocCurrPic; 
283          pocCurrPic        = m_tDecTop[decIdx]->getCurrPoc(); 
284#endif         
285          decIdxLastPic     = decIdxCurrPic; 
286          decIdxCurrPic     = decIdx; 
287#if H_3D
288          allLayersDecoded = ( pocCurrPic != pocLastPic );
289#endif
290        }
291#else
292      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
293      {
294        bNewPicture = false;
295      }
296      else
297      {
298        bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
299#endif
300        if (bNewPicture)
301        {
302          bitstreamFile.clear();
303          /* location points to the current nalunit payload[1] due to the
304           * need for the annexB parser to read three extra bytes.
305           * [1] except for the first NAL unit in the file
306           *     (but bNewPicture doesn't happen then) */
307          bitstreamFile.seekg(location-streamoff(3));
308          bytestream.reset();
309#if ENC_DEC_TRACE
310#if H_MV_ENC_DEC_TRAC
311          const Bool resetCounter = false; 
312          if ( resetCounter )
313          {
314            g_nSymbolCounter  = symCount; // Only reset counter SH becomes traced twice
315          }
316          else
317          {
318            g_disableHLSTrace = true;     // Trancing of second parsing of SH is not carried out
319          }         
320#else
321          g_nSymbolCounter = symCount;
322#endif
323#endif
324        }
325      }
326    }
327    if (bNewPicture || !bitstreamFile)
328    {
329#if H_MV
330      assert( decIdxLastPic != -1 ); 
331      m_tDecTop[decIdxLastPic]->endPicDecoding(poc, pcListPic, m_targetDecLayerIdSet );
332#else
333      m_cTDecTop.executeLoopFilters(poc, pcListPic);
334#endif
335    }
336#if H_3D
337    if ( allLayersDecoded || !bitstreamFile )
338    {
339      for( Int dI = 0; dI < m_numDecoders; dI++ )
340      {
341        TComPic* picLastCoded = m_ivPicLists.getPic( m_tDecTop[dI]->getLayerId(), pocLastPic );
342        assert( picLastCoded != NULL );       
343        picLastCoded->compressMotion(1);
344      }
345    }
346#endif
347
348    if( pcListPic )
349    {
350#if H_MV
351      if ( m_pchReconFiles[decIdxLastPic] && !m_reconOpen[decIdxLastPic] )
352#else
353      if ( m_pchReconFile && !openedReconFile  )
354#endif
355      {
356        if (!m_outputBitDepthY) { m_outputBitDepthY = g_bitDepthY; }
357        if (!m_outputBitDepthC) { m_outputBitDepthC = g_bitDepthC; }
358
359#if H_MV
360        m_tVideoIOYuvReconFile[decIdxLastPic]->open( m_pchReconFiles[decIdxLastPic], true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
361        m_reconOpen[decIdxLastPic] = true;
362      }
363      if ( bNewPicture && newSliceDiffPoc && 
364#else
365        m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
366        openedReconFile  = true;
367      }
368      if ( bNewPicture && 
369#endif
370           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
371            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
372            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
373            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
374            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
375      {
376#if H_MV
377        xFlushOutput( pcListPic, decIdxLastPic );
378#else
379        xFlushOutput( pcListPic );
380#endif
381      }
382      // write reconstruction to file
383      if(bNewPicture)
384      {
385#if H_MV
386        xWriteOutput( pcListPic, decIdxLastPic, nalu.m_temporalId );
387      }
388    }
389  }
390
391#if H_3D
392  if( m_cCamParsCollector.isInitialized() )
393  {
394    m_cCamParsCollector.setSlice( 0 );
395  }
396#endif
397  for(UInt decIdx = 0; decIdx < m_numDecoders; decIdx++)
398  {
399    xFlushOutput( m_tDecTop[decIdx]->getListPic(), decIdx );
400  }
401#else
402        xWriteOutput( pcListPic, nalu.m_temporalId );
403      }
404    }
405  }
406 
407  xFlushOutput( pcListPic );
408  // delete buffers
409  m_cTDecTop.deletePicBuffer();
410#endif
411     
412  // destroy internal classes
413  xDestroyDecLib();
414}
415
416// ====================================================================================================================
417// Protected member functions
418// ====================================================================================================================
419
420Void TAppDecTop::xCreateDecLib()
421{
422#if H_MV
423  // initialize global variables
424  initROM(); 
425#if H_3D_DIM_DMM
426  initWedgeLists();
427#endif
428#else
429  // create decoder class
430  m_cTDecTop.create();
431#endif
432}
433
434Void TAppDecTop::xDestroyDecLib()
435{
436#if H_MV
437  // destroy ROM
438  destroyROM();
439
440  for(Int decIdx = 0; decIdx < m_numDecoders ; decIdx++)
441  {
442    if( m_tVideoIOYuvReconFile[decIdx] )
443    {
444      m_tVideoIOYuvReconFile[decIdx]->close();
445      delete m_tVideoIOYuvReconFile[decIdx]; 
446      m_tVideoIOYuvReconFile[decIdx] = NULL ;
447    }
448
449    if( m_tDecTop[decIdx] )
450    {
451      m_tDecTop[decIdx]->deletePicBuffer();
452      m_tDecTop[decIdx]->destroy() ;
453    }
454    delete m_tDecTop[decIdx] ; 
455    m_tDecTop[decIdx] = NULL ;
456  }
457#else
458  if ( m_pchReconFile )
459  {
460    m_cTVideoIOYuvReconFile. close();
461  }
462 
463  // destroy decoder class
464  m_cTDecTop.destroy();
465#endif
466#if H_3D
467  m_cCamParsCollector.uninit();
468  if( m_pScaleOffsetFile ) 
469  { 
470    ::fclose( m_pScaleOffsetFile ); 
471  }
472#endif
473}
474
475Void TAppDecTop::xInitDecLib()
476{
477#if !H_MV
478  // initialize decoder class
479  m_cTDecTop.init();
480  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
481#endif
482}
483
484/** \param pcListPic list of pictures to be written to file
485    \todo            DYN_REF_FREE should be revised
486 */
487#if H_MV
488Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, Int decIdx, Int tId )
489#else
490Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
491#endif
492{
493  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
494  Int numPicsNotYetDisplayed = 0;
495 
496  while (iterPic != pcListPic->end())
497  {
498    TComPic* pcPic = *(iterPic);
499#if H_MV
500    if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[decIdx])
501#else
502    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
503#endif
504    {
505      numPicsNotYetDisplayed++;
506    }
507    iterPic++;
508  }
509  iterPic   = pcListPic->begin();
510  if (numPicsNotYetDisplayed>2)
511  {
512    iterPic++;
513  }
514 
515  TComPic* pcPic = *(iterPic);
516  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
517  {
518    TComList<TComPic*>::iterator endPic   = pcListPic->end();
519    endPic--;
520    iterPic   = pcListPic->begin();
521    while (iterPic != endPic)
522    {
523      TComPic* pcPicTop = *(iterPic);
524      iterPic++;
525      TComPic* pcPicBottom = *(iterPic);
526     
527#if H_MV
528      if ( pcPicTop->getOutputMark() && (numPicsNotYetDisplayed >  pcPicTop->getNumReorderPics(tId) && !(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1)
529          && pcPicBottom->getOutputMark() && (numPicsNotYetDisplayed >  pcPicBottom->getNumReorderPics(tId) && (pcPicTop->getPOC() == m_pocLastDisplay[decIdx]+1 || m_pocLastDisplay[decIdx]<0)))
530#else
531      if ( pcPicTop->getOutputMark() && (numPicsNotYetDisplayed >  pcPicTop->getNumReorderPics(tId) && !(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1)
532          && pcPicBottom->getOutputMark() && (numPicsNotYetDisplayed >  pcPicBottom->getNumReorderPics(tId) && (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay<0)))
533#endif
534      {
535        // write to file
536        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
537#if H_MV
538      if ( m_pchReconFiles[decIdx] )
539#else
540        if ( m_pchReconFile )
541#endif
542        {
543          const Window &conf = pcPicTop->getConformanceWindow();
544          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
545
546          const Bool isTff = pcPicTop->isTopField();
547#if H_MV
548        assert( conf   .getScaledFlag() );
549        assert( defDisp.getScaledFlag() );
550        m_tVideoIOYuvReconFile[decIdx]->write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
551#else
552          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
553#endif
554                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
555                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
556                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
557                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
558        }
559       
560        // update POC of display order
561#if H_MV
562        m_pocLastDisplay[decIdx] = pcPic->getPOC();
563#else
564        m_iPOCLastDisplay = pcPicBottom->getPOC();
565#endif
566       
567        // erase non-referenced picture in the reference picture list after display
568        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
569        {
570#if !DYN_REF_FREE
571          pcPicTop->setReconMark(false);
572         
573          // mark it should be extended later
574          pcPicTop->getPicYuvRec()->setBorderExtension( false );
575         
576#else
577          pcPicTop->destroy();
578          pcListPic->erase( iterPic );
579          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
580          continue;
581#endif
582        }
583        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
584        {
585#if !DYN_REF_FREE
586          pcPicBottom->setReconMark(false);
587         
588          // mark it should be extended later
589          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
590         
591#else
592          pcPicBottom->destroy();
593          pcListPic->erase( iterPic );
594          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
595          continue;
596#endif
597        }
598        pcPicTop->setOutputMark(false);
599        pcPicBottom->setOutputMark(false);
600      }
601    }
602  }
603  else if (!pcPic->isField()) //Frame Decoding
604  {
605    iterPic = pcListPic->begin();
606    while (iterPic != pcListPic->end())
607    {
608      pcPic = *(iterPic);
609
610#if H_MV
611      if ( pcPic->getOutputMark() && (numPicsNotYetDisplayed >  pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_pocLastDisplay[decIdx]))
612#else     
613      if ( pcPic->getOutputMark() && (numPicsNotYetDisplayed >  pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_iPOCLastDisplay))
614#endif
615      {
616        // write to file
617        numPicsNotYetDisplayed--;
618#if H_MV
619      if ( m_pchReconFiles[decIdx] )
620#else
621        if ( m_pchReconFile )
622#endif
623        {
624          const Window &conf = pcPic->getConformanceWindow();
625          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
626#if H_MV
627        assert( conf   .getScaledFlag() );
628        assert( defDisp.getScaledFlag() );
629        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
630#else
631          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
632#endif
633                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
634                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
635                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
636                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
637        }
638       
639        // update POC of display order
640#if H_MV
641        m_pocLastDisplay[decIdx] = pcPic->getPOC();
642#else
643        m_iPOCLastDisplay = pcPic->getPOC();
644#endif
645       
646        // erase non-referenced picture in the reference picture list after display
647        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
648        {
649#if !DYN_REF_FREE
650          pcPic->setReconMark(false);
651         
652          // mark it should be extended later
653          pcPic->getPicYuvRec()->setBorderExtension( false );
654         
655#else
656          pcPic->destroy();
657          pcListPic->erase( iterPic );
658          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
659          continue;
660#endif
661        }
662        pcPic->setOutputMark(false);
663      }
664     
665      iterPic++;
666    }
667  }
668}
669/** \param pcListPic list of pictures to be written to file
670    \todo            DYN_REF_FREE should be revised
671 */
672#if H_MV
673Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int decIdx )
674#else
675Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
676#endif
677{
678  if(!pcListPic)
679  {
680    return;
681  }
682  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
683 
684  iterPic   = pcListPic->begin();
685  TComPic* pcPic = *(iterPic);
686 
687  if (pcPic->isField()) //Field Decoding
688  {
689    TComList<TComPic*>::iterator endPic   = pcListPic->end();
690    endPic--;
691    TComPic *pcPicTop, *pcPicBottom = NULL;
692    while (iterPic != endPic)
693    {
694      pcPicTop = *(iterPic);
695      iterPic++;
696      pcPicBottom = *(iterPic);
697     
698      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
699      {
700        // write to file
701#if H_MV
702      if ( m_pchReconFiles[decIdx] )
703#else
704        if ( m_pchReconFile )
705#endif
706        {
707          const Window &conf = pcPicTop->getConformanceWindow();
708          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
709          const Bool isTff = pcPicTop->isTopField();
710#if H_MV
711        assert( conf   .getScaledFlag() );
712        assert( defDisp.getScaledFlag() );
713        m_tVideoIOYuvReconFile[decIdx]->write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
714#else
715          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
716#endif
717                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
718                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
719                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
720                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
721        }
722       
723        // update POC of display order
724#if H_MV
725      m_pocLastDisplay[decIdx] = pcPic->getPOC();
726#else
727      m_iPOCLastDisplay = pcPicBottom->getPOC();
728#endif       
729        // erase non-referenced picture in the reference picture list after display
730        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
731        {
732#if !DYN_REF_FREE
733          pcPicTop->setReconMark(false);
734         
735          // mark it should be extended later
736          pcPicTop->getPicYuvRec()->setBorderExtension( false );
737         
738#else
739          pcPicTop->destroy();
740          pcListPic->erase( iterPic );
741          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
742          continue;
743#endif
744        }
745        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
746        {
747#if !DYN_REF_FREE
748          pcPicBottom->setReconMark(false);
749         
750          // mark it should be extended later
751          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
752         
753#else
754          pcPicBottom->destroy();
755          pcListPic->erase( iterPic );
756          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
757          continue;
758#endif
759        }
760        pcPicTop->setOutputMark(false);
761        pcPicBottom->setOutputMark(false);
762       
763#if !DYN_REF_FREE
764        if(pcPicTop)
765        {
766          pcPicTop->destroy();
767          delete pcPicTop;
768          pcPicTop = NULL;
769        }
770#endif
771      }
772    }
773    if(pcPicBottom)
774    {
775      pcPicBottom->destroy();
776      delete pcPicBottom;
777      pcPicBottom = NULL;
778    }
779  }
780  else //Frame decoding
781  {
782    while (iterPic != pcListPic->end())
783    {
784      pcPic = *(iterPic);
785     
786      if ( pcPic->getOutputMark() )
787      {
788        // write to file
789#if H_MV
790      if ( m_pchReconFiles[decIdx] )
791#else
792        if ( m_pchReconFile )
793#endif
794        {
795          const Window &conf = pcPic->getConformanceWindow();
796          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
797#if H_MV
798        assert( conf   .getScaledFlag() );
799        assert( defDisp.getScaledFlag() );
800        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
801#else
802          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
803#endif
804                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
805                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
806                                        conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
807                                        conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
808        }
809       
810        // update POC of display order
811#if H_MV
812      m_pocLastDisplay[decIdx] = pcPic->getPOC();
813#else
814        m_iPOCLastDisplay = pcPic->getPOC();
815#endif
816       
817        // erase non-referenced picture in the reference picture list after display
818        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
819        {
820#if !DYN_REF_FREE
821          pcPic->setReconMark(false);
822         
823          // mark it should be extended later
824          pcPic->getPicYuvRec()->setBorderExtension( false );
825         
826#else
827          pcPic->destroy();
828          pcListPic->erase( iterPic );
829          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
830          continue;
831#endif
832        }
833        pcPic->setOutputMark(false);
834      }
835#if !H_MV
836#if !DYN_REF_FREE
837      if(pcPic)
838      {
839        pcPic->destroy();
840        delete pcPic;
841        pcPic = NULL;
842      }
843#endif   
844#endif
845      iterPic++;
846    }
847  }
848#if H_MV
849  m_pocLastDisplay[decIdx] = -MAX_INT;
850#else
851  pcListPic->clear();
852  m_iPOCLastDisplay = -MAX_INT;
853#endif
854}
855
856/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
857 */
858Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
859{
860  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
861  {
862    return true;
863  }
864  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
865  {
866#if H_MV
867    if ( nalu->m_layerId == (*it) )
868#else
869    if ( nalu->m_reservedZero6Bits == (*it) )
870#endif
871    {
872      return true;
873    }
874  }
875  return false;
876}
877
878#if H_MV
879Int TAppDecTop::xGetDecoderIdx( Int layerId, Bool createFlag /*= false */ )
880{
881  Int decIdx = -1; 
882
883#if H_MV_6_LAYER_ID_32
884  if ( layerId > MAX_NUM_LAYER_IDS-1 ) 
885  {
886    return decIdx; 
887  }
888#endif
889
890  if ( m_layerIdToDecIdx[ layerId ] != -1 ) 
891  {     
892    decIdx = m_layerIdToDecIdx[ layerId ]; 
893  }
894  else
895  {     
896    assert ( createFlag ); 
897    assert( m_numDecoders < MAX_NUM_LAYERS ); 
898
899    decIdx = m_numDecoders; 
900
901    // Init decoder
902    m_tDecTop[ decIdx ] =  new TDecTop;
903    m_tDecTop[ decIdx ]->create();
904    m_tDecTop[ decIdx ]->init( );
905    m_tDecTop[ decIdx ]->setLayerId( layerId );
906    m_tDecTop[ decIdx ]->setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
907    m_tDecTop[ decIdx ]->setIvPicLists( &m_ivPicLists ); 
908#if H_MV_LAYER_WISE_STARTUP
909    m_tDecTop[ decIdx ]->setLayerInitilizedFlags( m_layerInitilizedFlags );
910#endif
911
912#if H_3D
913   m_tDecTop[ decIdx ]->setCamParsCollector( &m_cCamParsCollector );
914#endif
915
916    // append pic list of new decoder to PicLists
917    assert( m_ivPicLists.size() == m_numDecoders );
918    m_ivPicLists.push_back( m_tDecTop[ decIdx ]->getListPic() );
919
920    // create recon file related stuff     
921    Char* pchTempFilename = NULL;
922    if ( m_pchReconFile )
923    {     
924      Char buffer[4];     
925      sprintf(buffer,"_%i", layerId );
926      assert ( m_pchReconFile ); 
927      xAppendToFileNameEnd( m_pchReconFile , buffer, pchTempFilename );
928      assert( m_pchReconFiles.size() == m_numDecoders );
929    }
930
931    m_pchReconFiles.push_back( pchTempFilename );   
932
933    m_tVideoIOYuvReconFile[ decIdx ] = new TVideoIOYuv;
934    m_reconOpen           [ decIdx ] = false;
935
936    // set others
937    m_pocLastDisplay      [ decIdx ] = -MAX_INT;
938    m_layerIdToDecIdx     [ layerId ] = decIdx; 
939
940    m_numDecoders++; 
941  };
942  return decIdx;
943}
944#endif
945//! \}
Note: See TracBrowser for help on using the repository browser.