source: 3DVCSoftware/branches/0.1-poznan-univ/source/Lib/TLibDecoder/TDecGop.cpp @ 165

Last change on this file since 165 was 2, checked in by hhi, 13 years ago

inital import

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