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

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

Merged HTM-10.0-dev0@871. (MV-HEVC 7 HLS)

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