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

Last change on this file since 601 was 532, checked in by seregin, 11 years ago

update to HM-12.1 base

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