source: SHVCSoftware/branches/SHM-4.1-dev/source/App/TAppDecoder/TAppDecTop.cpp @ 526

Last change on this file since 526 was 521, checked in by qualcomm, 12 years ago

JCTVC-O0217: Output layer set index at the decoder (MACRO: OUTPUT_LAYER_SET_INDEX)

Patch includes output layer set index inference at the decoder.

From: Adarsh K. Ramasubramonian <aramasub@…>

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