source: SHVCSoftware/branches/SHM-3.1-dev/source/App/TAppDecoder/TAppDecTop.cpp @ 582

Last change on this file since 582 was 440, checked in by seregin, 11 years ago

set IRAP alignment flag to false for AVC BL

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