source: 3DVCSoftware/branches/HTM-14.0-MV-draft-3/source/App/TAppDecoder/TAppDecTop.cpp @ 1417

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

Removed 3D-HEVC.

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