source: 3DVCSoftware/branches/0.3-poznan-univ/source/Lib/TLibDecoder/TDecGop.cpp @ 34

Last change on this file since 34 was 28, checked in by poznan-univ, 13 years ago

Poznan Tools

  • Encoding only disoccluded CUs in depended views
  • Depth based motion prediction
  • Texture QP adjustment based on depth data
  • Nonlinear depth representation
  • Property svn:eol-style set to native
File size: 12.9 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-2011, 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 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
35
36/** \file     TDecGop.cpp
37    \brief    GOP decoder class
38*/
39
40extern bool g_md5_mismatch; ///< top level flag to signal when there is a decode problem
41
42#include "TDecGop.h"
43#include "TDecCAVLC.h"
44#include "TDecSbac.h"
45#include "TDecBinCoder.h"
46#include "TDecBinCoderCABAC.h"
47#include "../libmd5/MD5.h"
48#include "../TLibCommon/SEI.h"
49
50#include <time.h>
51
52static void calcAndPrintMD5Status(TComPicYuv& pic, const SEImessages* seis);
53
54// ====================================================================================================================
55// Constructor / destructor / initialization / destroy
56// ====================================================================================================================
57
58TDecGop::TDecGop()
59{
60  m_iGopSize = 0;
61  m_dDecTime = 0;
62}
63
64TDecGop::~TDecGop()
65{
66 
67}
68
69Void TDecGop::create()
70{
71 
72}
73
74
75Void TDecGop::destroy()
76{
77
78}
79
80Void TDecGop::init( TDecEntropy*            pcEntropyDecoder, 
81                   TDecSbac*               pcSbacDecoder, 
82                   TDecBinCABAC*           pcBinCABAC,
83                   TDecCavlc*              pcCavlcDecoder, 
84                   TDecSlice*              pcSliceDecoder, 
85                   TComLoopFilter*         pcLoopFilter, 
86                   TComAdaptiveLoopFilter* pcAdaptiveLoopFilter, 
87#if MTK_SAO
88                   TComSampleAdaptiveOffset* pcSAO
89#endif             
90#if DEPTH_MAP_GENERATION
91                  ,TComDepthMapGenerator*  pcDepthMapGenerator
92#endif
93#if HHI_INTER_VIEW_RESIDUAL_PRED
94                  ,TComResidualGenerator*  pcResidualGenerator
95#endif
96                  )
97{
98  m_pcEntropyDecoder      = pcEntropyDecoder;
99  m_pcSbacDecoder         = pcSbacDecoder;
100  m_pcBinCABAC            = pcBinCABAC;
101  m_pcCavlcDecoder        = pcCavlcDecoder;
102  m_pcSliceDecoder        = pcSliceDecoder;
103  m_pcLoopFilter          = pcLoopFilter;
104  m_pcAdaptiveLoopFilter  = pcAdaptiveLoopFilter;
105#if MTK_SAO
106  m_pcSAO  = pcSAO;
107#endif
108#if DEPTH_MAP_GENERATION
109  m_pcDepthMapGenerator   = pcDepthMapGenerator;
110#endif
111#if HHI_INTER_VIEW_RESIDUAL_PRED
112  m_pcResidualGenerator   = pcResidualGenerator;
113#endif
114}
115
116// ====================================================================================================================
117// Public member functions
118// ====================================================================================================================
119
120Void TDecGop::decompressGop (Bool bEos, TComBitstream* pcBitstream, TComPic*& rpcPic, Bool bExecuteDeblockAndAlf)
121{
122  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
123
124  //-- For time output for each slice
125  long iBeforeTime = clock();
126 
127  UInt uiStartCUAddr   = pcSlice->getEntropySliceCurStartCUAddr();
128#if MTK_NONCROSS_INLOOP_FILTER
129  static Bool  bFirst = true;
130  static UInt  uiILSliceCount;
131  static UInt* puiILSliceStartLCU;
132  if (!bExecuteDeblockAndAlf)
133  {
134    if(bFirst)
135    {
136      uiILSliceCount = 0;
137      if(!pcSlice->getSPS()->getLFCrossSliceBoundaryFlag())
138      {
139        puiILSliceStartLCU = new UInt[rpcPic->getNumCUsInFrame() +1];
140      }
141      bFirst = false;
142    }
143   
144    if(!pcSlice->getSPS()->getLFCrossSliceBoundaryFlag())
145    {
146      UInt uiSliceStartCuAddr = pcSlice->getSliceCurStartCUAddr();
147      if(uiSliceStartCuAddr == uiStartCUAddr)
148      {
149        puiILSliceStartLCU[uiILSliceCount] = uiSliceStartCuAddr;
150        uiILSliceCount++;
151      }
152    }
153#endif //MTK_NONCROSS_INLOOP_FILTER
154
155    UInt iSymbolMode = pcSlice->getSymbolMode();
156    if (iSymbolMode)
157    {
158      m_pcSbacDecoder->init( (TDecBinIf*)m_pcBinCABAC );
159      m_pcEntropyDecoder->setEntropyDecoder (m_pcSbacDecoder);
160    }
161    else
162    {
163      m_pcEntropyDecoder->setEntropyDecoder (m_pcCavlcDecoder);
164    }
165   
166    m_pcEntropyDecoder->setBitstream      (pcBitstream);
167    m_pcEntropyDecoder->resetEntropy      (pcSlice);
168   
169    if (uiStartCUAddr==0)  // decode ALF params only from first slice header
170    {
171#if MTK_SAO
172      if( rpcPic->getSlice(0)->getSPS()->getUseSAO() )
173      { 
174        m_pcSAO->InitSao(&m_cSaoParam);
175        m_pcEntropyDecoder->decodeSaoParam(&m_cSaoParam);
176      }
177#endif
178
179      if ( rpcPic->getSlice(0)->getSPS()->getUseALF() )
180      {
181#if TSB_ALF_HEADER
182        m_pcAdaptiveLoopFilter->setNumCUsInFrame(rpcPic);
183#endif
184        m_pcAdaptiveLoopFilter->allocALFParam(&m_cAlfParam);
185        m_pcEntropyDecoder->decodeAlfParam( &m_cAlfParam );
186      }
187    }
188   
189#if DEPTH_MAP_GENERATION
190    // init view component and predict virtual depth map
191    if( uiStartCUAddr == 0 )
192    {
193      m_pcDepthMapGenerator->initViewComponent( rpcPic );
194      m_pcDepthMapGenerator->predictDepthMap  ( rpcPic );
195#if HHI_INTER_VIEW_RESIDUAL_PRED
196      m_pcResidualGenerator->initViewComponent( rpcPic );
197#endif
198    }
199#endif
200
201#if POZNAN_MP
202        if( uiStartCUAddr == 0 )
203    {
204#if POZNAN_MP_USE_DEPTH_MAP_GENERATION
205          pcSlice->getMP()->setDepthMapGenerator(m_pcDepthMapGenerator);
206#endif
207      pcSlice->getMP()->pairMultiview(rpcPic);
208        }
209#endif
210
211    // decode slice
212    m_pcSliceDecoder->decompressSlice(pcBitstream, rpcPic);
213   
214    m_dDecTime += (double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
215  }
216  else
217  {
218#if HHI_INTER_VIEW_RESIDUAL_PRED
219    // set residual picture
220    m_pcResidualGenerator->setRecResidualPic( rpcPic );
221#endif
222#if DEPTH_MAP_GENERATION
223    // update virtual depth map
224    m_pcDepthMapGenerator->updateDepthMap( rpcPic );
225#endif
226
227    // deblocking filter
228    m_pcLoopFilter->setCfg(pcSlice->getLoopFilterDisable(), 0, 0);
229    m_pcLoopFilter->loopFilterPic( rpcPic );
230#if MTK_SAO
231    {
232      if( rpcPic->getSlice(0)->getSPS()->getUseSAO())
233      {
234        m_pcSAO->SAOProcess(rpcPic, &m_cSaoParam);
235      }
236    }
237#endif
238    // adaptive loop filter
239    if( pcSlice->getSPS()->getUseALF() )
240    {
241#if MTK_NONCROSS_INLOOP_FILTER 
242      if(pcSlice->getSPS()->getLFCrossSliceBoundaryFlag())
243      {
244        m_pcAdaptiveLoopFilter->setUseNonCrossAlf(false);
245      }
246      else
247      {
248        puiILSliceStartLCU[uiILSliceCount] = rpcPic->getNumCUsInFrame();
249        m_pcAdaptiveLoopFilter->setUseNonCrossAlf( (uiILSliceCount > 1) );
250        if(m_pcAdaptiveLoopFilter->getUseNonCrossAlf())
251        {
252          m_pcAdaptiveLoopFilter->setNumSlicesInPic( uiILSliceCount );
253          m_pcAdaptiveLoopFilter->createSlice();
254          for(UInt i=0; i< uiILSliceCount ; i++)
255          {
256            (*m_pcAdaptiveLoopFilter)[i].create(rpcPic, i, puiILSliceStartLCU[i], puiILSliceStartLCU[i+1]-1);
257          }
258        }
259      }
260#endif
261      m_pcAdaptiveLoopFilter->ALFProcess(rpcPic, &m_cAlfParam);
262#if MTK_NONCROSS_INLOOP_FILTER
263      if(m_pcAdaptiveLoopFilter->getUseNonCrossAlf())
264      {
265        m_pcAdaptiveLoopFilter->destroySlice();
266      }
267#endif
268      m_pcAdaptiveLoopFilter->freeALFParam(&m_cAlfParam);
269    }
270   
271/*#if AMVP_BUFFERCOMPRESS
272    rpcPic->compressMotion(); // move to end of access unit
273#endif */
274   
275    //-- For time output for each slice
276    if(rpcPic->getViewIdx()!=-1)
277    {
278      if( !pcSlice->getSPS()->isDepth())
279      {
280        printf("\nView \t\t%4d\t POC %4d ( %c-SLICE, QP%3d ) ",
281                        rpcPic->getViewIdx(),
282                        pcSlice->getPOC(),
283                        pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B',
284                        pcSlice->getSliceQp() );
285      }
286      else
287      {
288        printf("\nDepth View \t%4d\t POC %4d ( %c-SLICE, QP%3d ) ",
289                              rpcPic->getViewIdx(),
290                              pcSlice->getPOC(),
291                              pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B',
292                              pcSlice->getSliceQp() );
293      }
294    }
295    else
296      printf("\nPOC %4d ( %c-SLICE, QP%3d ) ",
297             pcSlice->getPOC(),
298             pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B',
299             pcSlice->getSliceQp() );
300   
301    m_dDecTime += (double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
302    printf ("[DT %6.3f] ", m_dDecTime );
303    m_dDecTime  = 0;
304   
305    for (Int iRefList = 0; iRefList < 2; iRefList++)
306    {
307      printf ("[L%d ", iRefList);
308      for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
309      {
310        if( pcSlice->getViewIdx() != pcSlice->getRefViewIdx( RefPicList(iRefList), iRefIndex ) )
311        {
312          printf( "V%d", pcSlice->getRefViewIdx( RefPicList(iRefList), iRefIndex ) );
313          if( pcSlice->getPOC() != pcSlice->getRefPOC( RefPicList(iRefList), iRefIndex ) )
314            printf( "(%d)", pcSlice->getRefPOC( RefPicList(iRefList), iRefIndex ) );
315          printf( " " );
316        }
317        else
318          printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
319      }
320      printf ("] ");
321    }
322#if DCM_COMB_LIST
323    if(pcSlice->getNumRefIdx(REF_PIC_LIST_C)>0 && !pcSlice->getNoBackPredFlag())
324    {
325      printf ("[LC ");
326      for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(REF_PIC_LIST_C); iRefIndex++)
327      {
328        if( pcSlice->getViewIdx() != pcSlice->getRefViewIdx( (RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex) ) )
329        {
330          printf( "V%d", pcSlice->getRefViewIdx( (RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex) ) );
331          if( pcSlice->getPOC() != pcSlice->getRefPOC( (RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex) ) )
332            printf( "(%d)", pcSlice->getRefPOC( (RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex) ) );
333          printf( " " );
334        }
335        else
336          printf ("%d ", pcSlice->getRefPOC((RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex)));
337      }
338      printf ("] ");
339    }
340#endif
341#if FIXED_ROUNDING_FRAME_MEMORY
342    rpcPic->getPicYuvRec()->xFixedRoundingPic();
343#endif
344
345    if (m_pictureDigestEnabled) {
346      calcAndPrintMD5Status(*rpcPic->getPicYuvRec(), rpcPic->getSEIs());
347    }
348
349    rpcPic->setReconMark(true);
350#if MTK_NONCROSS_INLOOP_FILTER
351    uiILSliceCount = 0;
352#endif
353  }
354}
355
356/**
357 * Calculate and print MD5 for @pic, compare to picture_digest SEI if
358 * present in @seis.  @seis may be NULL.  MD5 is printed to stdout, in
359 * a manner suitable for the status line. Theformat is:
360 *  [MD5:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,(yyy)]
361 * Where, x..x is the md5
362 *        yyy has the following meanings:
363 *            OK          - calculated MD5 matches the SEI message
364 *            ***ERROR*** - calculated MD5 does not match the SEI message
365 *            unk         - no SEI message was available for comparison
366 */
367static void calcAndPrintMD5Status(TComPicYuv& pic, const SEImessages* seis)
368{
369  /* calculate MD5sum for entire reconstructed picture */
370  unsigned char recon_digest[16];
371  calcMD5(pic, recon_digest);
372
373  /* compare digest against received version */
374  const char* md5_ok = "(unk)";
375  bool md5_mismatch = false;
376
377  if (seis && seis->picture_digest)
378  {
379    md5_ok = "(OK)";
380    for (unsigned i = 0; i < 16; i++)
381    {
382      if (recon_digest[i] != seis->picture_digest->digest[i])
383      {
384        md5_ok = "(***ERROR***)";
385        md5_mismatch = true;
386      }
387    }
388  }
389
390  printf("[MD5:%s,%s] ", digestToString(recon_digest), md5_ok);
391  if (md5_mismatch)
392  {
393    g_md5_mismatch = true;
394    printf("[rxMD5:%s] ", digestToString(seis->picture_digest->digest));
395  }
396}
Note: See TracBrowser for help on using the repository browser.