source: SHVCSoftware/branches/SHM-4.0-dev/source/App/TAppDecoder/TAppDecTop.cpp @ 852

Last change on this file since 852 was 468, checked in by nokia, 11 years ago

Integration of O0194: Support different bit-depth values for different layers, enable weighted prediction for ILR for color gamut scalability.

  • Property svn:eol-style set to native
File size: 31.4 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  }
497
498#else
499  m_cTDecTop.init();
500  m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
501#endif
502}
503
504/** \param pcListPic list of pictures to be written to file
505\todo            DYN_REF_FREE should be revised
506*/
507#if SVC_EXTENSION
508Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt layerId, UInt tId )
509#else
510Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
511#endif
512{
513  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
514  Int numPicsNotYetDisplayed = 0;
515
516  while (iterPic != pcListPic->end())
517  {
518    TComPic* pcPic = *(iterPic);
519#if SVC_EXTENSION
520    if(pcPic->getOutputMark() && pcPic->getPOC() > m_aiPOCLastDisplay[layerId])
521#else
522    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
523#endif
524    {
525      numPicsNotYetDisplayed++;
526    }
527    iterPic++;
528  }
529  iterPic   = pcListPic->begin();
530  if (numPicsNotYetDisplayed>2)
531  {
532    iterPic++;
533  }
534
535  TComPic* pcPic = *(iterPic);
536  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
537  {
538    TComList<TComPic*>::iterator endPic   = pcListPic->end();
539    endPic--;
540    iterPic   = pcListPic->begin();
541    while (iterPic != endPic)
542    {
543      TComPic* pcPicTop = *(iterPic);
544      iterPic++;
545      TComPic* pcPicBottom = *(iterPic);
546
547#if SVC_EXTENSION
548      if ( pcPicTop->getOutputMark() && (numPicsNotYetDisplayed >  pcPicTop->getNumReorderPics(tId) && !(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1)
549        && pcPicBottom->getOutputMark() && (numPicsNotYetDisplayed >  pcPicBottom->getNumReorderPics(tId) && (pcPicTop->getPOC() == m_aiPOCLastDisplay[layerId]+1 || m_aiPOCLastDisplay[layerId]<0)))
550#else
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_iPOCLastDisplay+1 || m_iPOCLastDisplay<0)))
553#endif
554      {
555        // write to file
556        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
557#if SVC_EXTENSION
558        if ( m_pchReconFile[layerId] )
559        {
560          const Window &conf = pcPicTop->getConformanceWindow();
561          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
562          const Bool isTff = pcPicTop->isTopField();
563#if REPN_FORMAT_IN_VPS
564          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
565          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
566          m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
567            conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
568            conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
569            conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
570            conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset(), isTff );
571
572#else
573#if O0194_DIFFERENT_BITDEPTH_EL_BL
574          // Compile time bug-fix
575          m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
576#else
577          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
578#endif
579            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
580            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
581            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
582            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
583#endif
584        }
585
586        // update POC of display order
587        m_aiPOCLastDisplay[layerId] = pcPicBottom->getPOC();
588#else
589        if ( m_pchReconFile )
590        {
591          const Window &conf = pcPicTop->getConformanceWindow();
592          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
593          const Bool isTff = pcPicTop->isTopField();
594          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
595            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
596            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
597            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
598            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
599        }
600
601        // update POC of display order
602        m_iPOCLastDisplay = pcPicBottom->getPOC();
603#endif
604
605        // erase non-referenced picture in the reference picture list after display
606        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
607        {
608#if !DYN_REF_FREE
609          pcPicTop->setReconMark(false);
610
611          // mark it should be extended later
612          pcPicTop->getPicYuvRec()->setBorderExtension( false );
613
614#else
615          pcPicTop->destroy();
616          pcListPic->erase( iterPic );
617          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
618          continue;
619#endif
620        }
621        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
622        {
623#if !DYN_REF_FREE
624          pcPicBottom->setReconMark(false);
625
626          // mark it should be extended later
627          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
628
629#else
630          pcPicBottom->destroy();
631          pcListPic->erase( iterPic );
632          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
633          continue;
634#endif
635        }
636        pcPicTop->setOutputMark(false);
637        pcPicBottom->setOutputMark(false);
638      }
639    }
640  }
641  else if (!pcPic->isField()) //Frame Decoding
642  {
643    iterPic = pcListPic->begin();
644    while (iterPic != pcListPic->end())
645    {
646      pcPic = *(iterPic);
647
648#if SVC_EXTENSION
649      if ( pcPic->getOutputMark() && (numPicsNotYetDisplayed >  pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_aiPOCLastDisplay[layerId]))
650#else
651      if ( pcPic->getOutputMark() && (numPicsNotYetDisplayed >  pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_iPOCLastDisplay))
652#endif
653      {
654        // write to file
655        numPicsNotYetDisplayed--;
656#if SVC_EXTENSION
657        if ( m_pchReconFile[layerId] )
658        {
659          const Window &conf = pcPic->getConformanceWindow();
660          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
661#if REPN_FORMAT_IN_VPS
662          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
663          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
664          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(),
665            conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
666            conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
667            conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
668            conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
669
670#else
671          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(),
672            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
673            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
674            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
675            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
676#endif
677        }
678
679        // update POC of display order
680        m_aiPOCLastDisplay[layerId] = pcPic->getPOC();
681#else
682        if ( m_pchReconFile )
683        {
684#if SYNTAX_OUTPUT
685          const Window &conf = pcPic->getConformanceWindow();
686          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
687          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
688            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
689            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
690            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
691            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
692#endif
693        }
694
695        // update POC of display order
696        m_iPOCLastDisplay = pcPic->getPOC();
697#endif
698
699        // erase non-referenced picture in the reference picture list after display
700        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
701        {
702#if !DYN_REF_FREE
703          pcPic->setReconMark(false);
704
705          // mark it should be extended later
706          pcPic->getPicYuvRec()->setBorderExtension( false );
707
708#else
709          pcPic->destroy();
710          pcListPic->erase( iterPic );
711          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
712          continue;
713#endif
714        }
715        pcPic->setOutputMark(false);
716      }
717
718      iterPic++;
719    }
720  }
721}
722
723/** \param pcListPic list of pictures to be written to file
724    \todo            DYN_REF_FREE should be revised
725 */
726#if SVC_EXTENSION
727Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, UInt layerId )
728#else
729Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
730#endif
731{
732  if(!pcListPic)
733  {
734    return;
735  }
736  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
737
738  iterPic   = pcListPic->begin();
739  TComPic* pcPic = *(iterPic);
740
741  if (pcPic->isField()) //Field Decoding
742  {
743    TComList<TComPic*>::iterator endPic   = pcListPic->end();
744    endPic--;
745    TComPic *pcPicTop, *pcPicBottom = NULL;
746    while (iterPic != endPic)
747    {
748      pcPicTop = *(iterPic);
749      iterPic++;
750      pcPicBottom = *(iterPic);
751
752      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
753      {
754        // write to file
755#if SVC_EXTENSION
756        if ( m_pchReconFile[layerId] )
757        {
758          const Window &conf = pcPicTop->getConformanceWindow();
759          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
760          const Bool isTff = pcPicTop->isTopField();
761#if REPN_FORMAT_IN_VPS
762          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
763          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
764          m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
765            conf.getWindowLeftOffset()  *xScal + defDisp.getWindowLeftOffset(),
766            conf.getWindowRightOffset() *xScal + defDisp.getWindowRightOffset(),
767            conf.getWindowTopOffset()   *yScal + defDisp.getWindowTopOffset(),
768            conf.getWindowBottomOffset()*yScal + defDisp.getWindowBottomOffset(), isTff );
769
770#else
771#if O0194_DIFFERENT_BITDEPTH_EL_BL
772          // Compile time bug-fix
773          m_acTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
774#else
775          m_cTVideoIOYuvReconFile[layerId].write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
776#endif
777            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
778            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
779            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
780            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
781#endif
782        }
783
784        // update POC of display order
785        m_aiPOCLastDisplay[layerId] = pcPicBottom->getPOC();
786#else
787        if ( m_pchReconFile )
788        {
789          const Window &conf = pcPicTop->getConformanceWindow();
790          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
791          const Bool isTff = pcPicTop->isTopField();
792          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
793            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
794            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
795            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
796            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), isTff );
797        }
798
799        // update POC of display order
800        m_iPOCLastDisplay = pcPicBottom->getPOC();
801#endif
802
803        // erase non-referenced picture in the reference picture list after display
804        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
805        {
806#if !DYN_REF_FREE
807          pcPicTop->setReconMark(false);
808
809          // mark it should be extended later
810          pcPicTop->getPicYuvRec()->setBorderExtension( false );
811
812#else
813          pcPicTop->destroy();
814          pcListPic->erase( iterPic );
815          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
816          continue;
817#endif
818        }
819        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
820        {
821#if !DYN_REF_FREE
822          pcPicBottom->setReconMark(false);
823
824          // mark it should be extended later
825          pcPicBottom->getPicYuvRec()->setBorderExtension( false );
826
827#else
828          pcPicBottom->destroy();
829          pcListPic->erase( iterPic );
830          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
831          continue;
832#endif
833        }
834        pcPicTop->setOutputMark(false);
835        pcPicBottom->setOutputMark(false);
836
837#if !DYN_REF_FREE
838        if(pcPicTop)
839        {
840          pcPicTop->destroy();
841          delete pcPicTop;
842          pcPicTop = NULL;
843        }
844#endif
845      }
846    }
847    if(pcPicBottom)
848    {
849      pcPicBottom->destroy();
850      delete pcPicBottom;
851      pcPicBottom = NULL;
852    }
853  }
854  else //Frame decoding
855  {
856    while (iterPic != pcListPic->end())
857    {
858      pcPic = *(iterPic);
859
860      if ( pcPic->getOutputMark() )
861      {
862        // write to file
863#if SVC_EXTENSION
864        if ( m_pchReconFile[layerId] )
865        {
866          const Window &conf = pcPic->getConformanceWindow();
867          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
868#if REPN_FORMAT_IN_VPS
869          UInt chromaFormatIdc = pcPic->getSlice(0)->getChromaFormatIdc();
870          Int xScal =  TComSPS::getWinUnitX( chromaFormatIdc ), yScal = TComSPS::getWinUnitY( chromaFormatIdc );
871          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(),
872            conf.getWindowLeftOffset()  *xScal + defDisp.getWindowLeftOffset(),
873            conf.getWindowRightOffset() *xScal + defDisp.getWindowRightOffset(),
874            conf.getWindowTopOffset()   *yScal + defDisp.getWindowTopOffset(),
875            conf.getWindowBottomOffset()*yScal + defDisp.getWindowBottomOffset() );
876
877#else
878          m_acTVideoIOYuvReconFile[layerId].write( pcPic->getPicYuvRec(),
879            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
880            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
881            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
882            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
883#endif
884        }
885
886        // update POC of display order
887        m_aiPOCLastDisplay[layerId] = pcPic->getPOC();
888#else
889        if ( m_pchReconFile )
890        {
891          const Window &conf = pcPic->getConformanceWindow();
892          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
893          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
894            conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
895            conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
896            conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
897            conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
898        }
899
900        // update POC of display order
901        m_iPOCLastDisplay = pcPic->getPOC();
902#endif
903
904        // erase non-referenced picture in the reference picture list after display
905        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
906        {
907#if !DYN_REF_FREE
908          pcPic->setReconMark(false);
909
910          // mark it should be extended later
911          pcPic->getPicYuvRec()->setBorderExtension( false );
912
913#else
914          pcPic->destroy();
915          pcListPic->erase( iterPic );
916          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
917          continue;
918#endif
919        }
920        pcPic->setOutputMark(false);
921      }
922#if !SVC_EXTENSION
923#if !DYN_REF_FREE
924      if(pcPic)
925      {
926        pcPic->destroy();
927        delete pcPic;
928        pcPic = NULL;
929      }
930#endif
931#endif
932      iterPic++;
933    }
934  }
935#if SVC_EXTENSION
936  m_aiPOCLastDisplay[layerId] = -MAX_INT;
937#else
938  pcListPic->clear();
939  m_iPOCLastDisplay = -MAX_INT;
940#endif
941}
942
943/** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
944 */
945Bool TAppDecTop::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
946{
947  if ( m_targetDecLayerIdSet.size() == 0 ) // By default, the set is empty, meaning all LayerIds are allowed
948  {
949    return true;
950  }
951  for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
952  {
953    if ( nalu->m_reservedZero6Bits == (*it) )
954    {
955      return true;
956    }
957  }
958  return false;
959}
960
961//! \}
Note: See TracBrowser for help on using the repository browser.