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

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

Merged branch/9.2-dev0@722.

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