source: 3DVCSoftware/branches/HTM-10.0rc1-dev0/source/App/TAppDecoder/TAppDecTop.cpp @ 837

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

Merged HM 13.0. (No yet checked).

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