source: 3DVCSoftware/branches/HTM-8.2-dev0-Cleanup/source/App/TAppDecoder/TAppDecTop.cpp @ 651

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

Update to HM 12.0.

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