source: 3DVCSoftware/trunk/source/App/TAppDecoder/TAppDecTop.cpp @ 56

Last change on this file since 56 was 56, checked in by hschwarz, 13 years ago

updated trunk (move to HM6.1)

  • Property svn:eol-style set to native
File size: 15.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-2012, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TAppDecTop.cpp
35    \brief    Decoder application class
36*/
37
38#include <list>
39#include <vector>
40#include <stdio.h>
41#include <fcntl.h>
42#include <assert.h>
43
44#include "TAppDecTop.h"
45#include "TLibDecoder/AnnexBread.h"
46#include "TLibDecoder/NALread.h"
47
48//! \ingroup TAppDecoder
49//! \{
50
51// ====================================================================================================================
52// Constructor / destructor / initialization / destroy
53// ====================================================================================================================
54
55TAppDecTop::TAppDecTop()
56{
57  ::memset (m_abDecFlag, 0, sizeof (m_abDecFlag));
58  m_useDepth = false;
59}
60
61Void TAppDecTop::create()
62{
63}
64
65Void TAppDecTop::destroy()
66{
67}
68
69// ====================================================================================================================
70// Public member functions
71// ====================================================================================================================
72
73/**
74 - create internal class
75 - initialize internal class
76 - until the end of the bitstream, call decoding function in TDecTop class
77 - delete allocated buffers
78 - destroy internal class
79 .
80 */
81Void TAppDecTop::decode()
82{
83  increaseNumberOfViews( 1 );
84#if SONY_COLPIC_AVAILABILITY
85  m_tDecTop[0]->setViewOrderIdx(0);
86#endif
87  Int                 viewDepthId = 0;
88  Int                 previousViewDepthId  = 0;
89  UInt                uiPOC[MAX_VIEW_NUM*2];
90  TComList<TComPic*>* pcListPic[MAX_VIEW_NUM*2];
91  Bool                newPicture[MAX_VIEW_NUM*2];
92  Bool                previousPictureDecoded = false;
93  for( Int i = 0; i < MAX_VIEW_NUM*2; i++ )
94  {
95    uiPOC[i] = 0;
96    pcListPic[i] = NULL;
97    newPicture[i] = false;
98  }
99
100  ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
101  if (!bitstreamFile)
102  {
103    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
104    exit(EXIT_FAILURE);
105  }
106
107  if( m_pchScaleOffsetFile ) 
108  { 
109    m_pScaleOffsetFile = ::fopen( m_pchScaleOffsetFile, "wt" ); 
110    AOF( m_pScaleOffsetFile ); 
111  }
112  m_cCamParsCollector.init( m_pScaleOffsetFile );
113
114  InputByteStream bytestream(bitstreamFile);
115
116  while (!!bitstreamFile)
117  {
118    /* location serves to work around a design fault in the decoder, whereby
119     * the process of reading a new slice that is the first slice of a new frame
120     * requires the TDecTop::decode() method to be called again with the same
121     * nal unit. */
122    streampos location = bitstreamFile.tellg();
123    AnnexBStats stats = AnnexBStats();
124    vector<uint8_t> nalUnit;
125    InputNALUnit nalu;
126    byteStreamNALUnit(bytestream, nalUnit, stats);
127
128    // call actual decoding function
129    if (nalUnit.empty())
130    {
131      /* this can happen if the following occur:
132       *  - empty input file
133       *  - two back-to-back start_code_prefixes
134       *  - start_code_prefix immediately followed by EOF
135       */
136      fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");
137    }
138    else
139    {
140      read(nalu, nalUnit);
141      Int viewId = nalu.m_viewId;
142      Int depth = nalu.m_isDepth ? 1 : 0;
143      viewDepthId = viewId * 2 + depth;   // coding order T0D0T1D1T2D2
144      newPicture[viewDepthId] = false;
145      if( viewDepthId >= m_tDecTop.size() )     
146      {
147        increaseNumberOfViews( viewDepthId +1 );
148      }
149      if(m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer)
150      {
151        previousPictureDecoded = false; 
152      }
153      if(m_tDecTop.size() > 1 && (viewDepthId != previousViewDepthId) && previousPictureDecoded )
154      {
155        m_tDecTop[previousViewDepthId]->executeDeblockAndAlf(uiPOC[previousViewDepthId], pcListPic[previousViewDepthId], m_iSkipFrame, m_pocLastDisplay[previousViewDepthId]);
156      } 
157      if( ( viewDepthId == 0 && (viewDepthId != previousViewDepthId) ) || m_tDecTop.size() == 1 )
158      {
159#if HHI_INTER_VIEW_RESIDUAL_PRED
160        for( Int i = 0; i < m_tDecTop.size(); i++ )
161        {
162          m_tDecTop[i]->deleteExtraPicBuffers( uiPOC[i] );
163        }
164#endif
165        for( Int i = 0; i < m_tDecTop.size(); i++ )
166        {
167          m_tDecTop[i]->compressMotion( uiPOC[i] );
168        }
169      }   
170      if( !(m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) )
171      {
172        newPicture[viewDepthId] = m_tDecTop[viewDepthId]->decode(nalu, m_iSkipFrame, m_pocLastDisplay[viewDepthId]);
173        if (newPicture[viewDepthId])
174        {
175          bitstreamFile.clear();
176          /* location points to the current nalunit payload[1] due to the
177           * need for the annexB parser to read three extra bytes.
178           * [1] except for the first NAL unit in the file
179           *     (but bNewPicture doesn't happen then) */
180          bitstreamFile.seekg(location-streamoff(3));
181          bytestream.reset();
182        }
183        if( nalu.isSlice() )
184        {
185          previousPictureDecoded = true;
186        }
187      }
188    }
189    if( ( (newPicture[viewDepthId] || !bitstreamFile) && m_tDecTop.size() == 1) || (!bitstreamFile && previousPictureDecoded == true) ) 
190    {
191      m_tDecTop[viewDepthId]->executeDeblockAndAlf(uiPOC[viewDepthId], pcListPic[viewDepthId], m_iSkipFrame, m_pocLastDisplay[viewDepthId]);
192    }
193    if( pcListPic[viewDepthId] )
194    {
195      if( newPicture[viewDepthId] && (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDV && m_tDecTop[viewDepthId]->getNalUnitTypeBaseView() == NAL_UNIT_CODED_SLICE_IDR)) )
196      {
197        xFlushOutput( pcListPic[viewDepthId], viewDepthId );
198      }
199      // write reconstruction to file
200      if(newPicture[viewDepthId])
201      {
202#if H0567_DPB_PARAMETERS_PER_TEMPORAL_LAYER
203        xWriteOutput( pcListPic[viewDepthId], viewDepthId, nalu.m_temporalId );
204#else
205        xWriteOutput( pcListPic[viewDepthId], viewDepthId );
206#endif
207      }
208    }
209    previousViewDepthId = viewDepthId;
210  } 
211  // last frame
212  for( Int viewDepthIdx = 0; viewDepthIdx < m_tDecTop.size(); viewDepthIdx++ )
213  {
214    xFlushOutput( pcListPic[viewDepthIdx], viewDepthIdx );
215  } 
216  xDestroyDecLib();
217}
218
219// ====================================================================================================================
220// Protected member functions
221// ====================================================================================================================
222
223Void TAppDecTop::xDestroyDecLib()
224{
225
226  for(Int viewDepthIdx=0; viewDepthIdx<m_tVideoIOYuvReconFile.size() ; viewDepthIdx++)
227  {
228    if( m_tVideoIOYuvReconFile[viewDepthIdx] )
229    {
230      m_tVideoIOYuvReconFile[viewDepthIdx]->close();
231      delete m_tVideoIOYuvReconFile[viewDepthIdx]; 
232      m_tVideoIOYuvReconFile[viewDepthIdx] = NULL ;
233    }
234  }
235
236  for(Int viewDepthIdx=0; viewDepthIdx<m_tDecTop.size() ; viewDepthIdx++)
237  {
238    if( m_tDecTop[viewDepthIdx] )
239    {
240      if( !m_useDepth && (viewDepthIdx % 2 == 1) )
241      {
242      }
243      else
244      {
245        m_tDecTop[viewDepthIdx]->deletePicBuffer();
246        m_tDecTop[viewDepthIdx]->destroy() ;
247      }
248      delete m_tDecTop[viewDepthIdx] ; 
249      m_tDecTop[viewDepthIdx] = NULL ;
250    }
251  }
252}
253
254#if H0567_DPB_PARAMETERS_PER_TEMPORAL_LAYER
255Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, Int viewDepthId, UInt tId )
256#else
257Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, Int viewDepthId )
258#endif
259{
260  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
261  Int not_displayed = 0;
262
263  while (iterPic != pcListPic->end())
264  {
265    TComPic* pcPic = *(iterPic);
266    if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[viewDepthId])
267    {
268       not_displayed++;
269    }
270    iterPic++;
271  }
272  iterPic   = pcListPic->begin();
273 
274  while (iterPic != pcListPic->end())
275  {
276    TComPic* pcPic = *(iterPic);
277#if PIC_CROPPING
278    TComSPS *sps = pcPic->getSlice(0)->getSPS();
279#endif
280   
281#if H0567_DPB_PARAMETERS_PER_TEMPORAL_LAYER
282    if ( pcPic->getOutputMark() && (not_displayed >  pcPic->getSlice(0)->getSPS()->getNumReorderPics(tId) && pcPic->getPOC() > m_pocLastDisplay[viewDepthId]))
283#else
284    if ( pcPic->getOutputMark() && (not_displayed >  pcPic->getSlice(0)->getSPS()->getNumReorderFrames() && pcPic->getPOC() > m_pocLastDisplay[viewDepthId]))
285#endif
286    {
287      // write to file
288       not_displayed--;
289      if ( m_pchReconFile )
290      {
291#if PIC_CROPPING
292        m_tVideoIOYuvReconFile[viewDepthId]->write( pcPic->getPicYuvRec(), sps->getPicCropLeftOffset(), sps->getPicCropRightOffset(), sps->getPicCropTopOffset(), sps->getPicCropBottomOffset() );
293#else
294        m_tVideoIOYuvReconFile[viewDepthId]->write( pcPic->getPicYuvRec(), pcPic->getSlice(0)->getSPS()->getPad() );
295#endif
296      }
297     
298      // update POC of display order
299      m_pocLastDisplay[viewDepthId] = pcPic->getPOC();
300     
301      // erase non-referenced picture in the reference picture list after display
302      if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
303      {
304#if !DYN_REF_FREE
305        pcPic->setReconMark(false);
306       
307        // mark it should be extended later
308        pcPic->getPicYuvRec()->setBorderExtension( false );
309       
310#else
311        pcPic->destroy();
312        pcListPic->erase( iterPic );
313        iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
314        continue;
315#endif
316      }
317      pcPic->setOutputMark(false);
318    }
319   
320    iterPic++;
321  }
322}
323
324/** \param pcListPic list of pictures to be written to file
325    \todo            DYN_REF_FREE should be revised
326 */
327Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int viewDepthId )
328{
329  if(!pcListPic)
330  {
331    return;
332  } 
333  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
334
335  iterPic   = pcListPic->begin();
336 
337  while (iterPic != pcListPic->end())
338  {
339    TComPic* pcPic = *(iterPic);
340#if PIC_CROPPING
341    TComSPS *sps = pcPic->getSlice(0)->getSPS();
342#endif
343
344    if ( pcPic->getOutputMark() )
345    {
346      // write to file
347      if ( m_pchReconFile )
348      {
349#if PIC_CROPPING
350        m_tVideoIOYuvReconFile[viewDepthId]->write( pcPic->getPicYuvRec(), sps->getPicCropLeftOffset(), sps->getPicCropRightOffset(), sps->getPicCropTopOffset(), sps->getPicCropBottomOffset() );
351#else
352        m_tVideoIOYuvReconFile[viewDepthId]->write( pcPic->getPicYuvRec(), pcPic->getSlice(0)->getSPS()->getPad() );
353#endif
354      }
355     
356      // update POC of display order
357      m_pocLastDisplay[viewDepthId] = pcPic->getPOC();
358     
359      // erase non-referenced picture in the reference picture list after display
360      if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
361      {
362#if !DYN_REF_FREE
363        pcPic->setReconMark(false);
364       
365        // mark it should be extended later
366        pcPic->getPicYuvRec()->setBorderExtension( false );
367       
368#else
369        pcPic->destroy();
370        pcListPic->erase( iterPic );
371        iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
372        continue;
373#endif
374      }
375      pcPic->setOutputMark(false);
376    }
377   
378    iterPic++;
379  }
380  pcListPic->clear();
381  m_pocLastDisplay[viewDepthId] = -MAX_INT;
382}
383
384Void  TAppDecTop::increaseNumberOfViews  ( Int newNumberOfViewDepth )
385{
386  if ( m_outputBitDepth == 0 )
387  {
388    m_outputBitDepth = g_uiBitDepth + g_uiBitIncrement;
389  }
390  Int viewId = (newNumberOfViewDepth-1)>>1;   // coding order T0D0T1D1T2D2
391  Bool isDepth = ((newNumberOfViewDepth % 2) == 0);  // coding order T0D0T1D1T2D2
392  if( isDepth )
393    m_useDepth = true;
394  while( m_tVideoIOYuvReconFile.size() < newNumberOfViewDepth)
395  {
396    m_tVideoIOYuvReconFile.push_back(new TVideoIOYuv);
397    Char buffer[4];
398    sprintf(buffer,"_%i", (Int)(m_tVideoIOYuvReconFile.size()-1) / 2 );
399    Char* nextFilename = NULL;
400    if( (m_tVideoIOYuvReconFile.size() % 2) == 0 )
401    {
402      Char* pchTempFilename = NULL;
403      xAppendToFileNameEnd( m_pchReconFile, "_depth", pchTempFilename);
404      xAppendToFileNameEnd( pchTempFilename, buffer, nextFilename);
405      free ( pchTempFilename );
406    }
407    else
408    {
409      xAppendToFileNameEnd( m_pchReconFile, buffer, nextFilename);
410    }
411    if( isDepth || ( !isDepth && (m_tVideoIOYuvReconFile.size() % 2) == 1 ) )
412    {
413      m_tVideoIOYuvReconFile.back()->open( nextFilename, true, m_outputBitDepth, g_uiBitDepth + g_uiBitIncrement );
414    }
415      free ( nextFilename );
416  }
417  while( m_pocLastDisplay.size() < newNumberOfViewDepth )
418  {
419    m_pocLastDisplay.push_back(-MAX_INT+m_iSkipFrame);
420  }
421  while( m_tDecTop.size() < newNumberOfViewDepth)
422  {
423    m_tDecTop.push_back(new TDecTop);
424    if( isDepth || ( !isDepth && (m_tVideoIOYuvReconFile.size() % 2) == 1 ) )
425    {
426      m_tDecTop.back()->create();
427      m_tDecTop.back()->init( this, newNumberOfViewDepth == 1);
428      m_tDecTop.back()->setViewId( viewId );
429      m_tDecTop.back()->setIsDepth( isDepth );
430      m_tDecTop.back()->setPictureDigestEnabled(m_pictureDigestEnabled);
431    }
432  }
433}
434
435TDecTop* TAppDecTop::getTDecTop( Int viewId, Bool isDepth )
436{ 
437  return m_tDecTop[(isDepth ? 1 : 0) + viewId * 2];  // coding order T0D0T1D1T2D2
438} 
439
440std::vector<TComPic*> TAppDecTop::getInterViewRefPics( Int viewId, Int poc, Bool isDepth, TComSPS* sps )
441{
442  std::vector<TComPic*> apcRefPics( sps->getNumberOfUsableInterViewRefs(), (TComPic*)NULL );
443  for( Int k = 0; k < sps->getNumberOfUsableInterViewRefs(); k++ )
444  {
445    TComPic* pcRefPic = xGetPicFromView( sps->getUsableInterViewRef( k ) + viewId, poc, isDepth );
446    assert( pcRefPic != NULL );
447    apcRefPics[k] = pcRefPic;
448  }
449  return apcRefPics;
450}
451
452TComPic* TAppDecTop::xGetPicFromView( Int viewId, Int poc, Bool isDepth )
453{
454  assert( ( viewId >= 0 ) );
455
456  TComList<TComPic*>* apcListPic = getTDecTop( viewId, isDepth )->getListPic();
457  TComPic* pcPic = NULL;
458  for( TComList<TComPic*>::iterator it=apcListPic->begin(); it!=apcListPic->end(); it++ )
459  {
460    if( (*it)->getPOC() == poc )
461    {
462      pcPic = *it;
463      break;
464    }
465  }
466  return pcPic;
467}
468//! \}
Note: See TracBrowser for help on using the repository browser.