source: 3DVCSoftware/trunk/source/Lib/TLibDecoder/TDecGop.cpp @ 788

Last change on this file since 788 was 655, checked in by tech, 11 years ago

Merged 8.1-Cleanup@654

  • Property svn:eol-style set to native
File size: 12.7 KB
RevLine 
[5]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
[56]4 * granted under this license. 
[5]5 *
[608]6 * Copyright (c) 2010-2013, ITU/ISO/IEC
[5]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.
[56]17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
[5]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 */
[2]33
34/** \file     TDecGop.cpp
35    \brief    GOP decoder class
36*/
37
38#include "TDecGop.h"
39#include "TDecCAVLC.h"
40#include "TDecSbac.h"
41#include "TDecBinCoder.h"
42#include "TDecBinCoderCABAC.h"
[56]43#include "libmd5/MD5.h"
44#include "TLibCommon/SEI.h"
[2]45
46#include <time.h>
47
[608]48extern Bool g_md5_mismatch; ///< top level flag to signal when there is a decode problem
49
[56]50//! \ingroup TLibDecoder
51//! \{
[608]52static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI);
[2]53// ====================================================================================================================
54// Constructor / destructor / initialization / destroy
55// ====================================================================================================================
56
57TDecGop::TDecGop()
58{
59  m_dDecTime = 0;
[56]60  m_pcSbacDecoders = NULL;
61  m_pcBinCABACs = NULL;
[2]62}
63
64TDecGop::~TDecGop()
65{
66 
67}
68
69Void TDecGop::create()
70{
71 
72}
73
74
75Void TDecGop::destroy()
76{
77}
78
79Void TDecGop::init( TDecEntropy*            pcEntropyDecoder, 
80                   TDecSbac*               pcSbacDecoder, 
81                   TDecBinCABAC*           pcBinCABAC,
82                   TDecCavlc*              pcCavlcDecoder, 
83                   TDecSlice*              pcSliceDecoder, 
[608]84                   TComLoopFilter*         pcLoopFilter,
85                   TComSampleAdaptiveOffset* pcSAO
[56]86                   )
[2]87{
88  m_pcEntropyDecoder      = pcEntropyDecoder;
89  m_pcSbacDecoder         = pcSbacDecoder;
90  m_pcBinCABAC            = pcBinCABAC;
91  m_pcCavlcDecoder        = pcCavlcDecoder;
92  m_pcSliceDecoder        = pcSliceDecoder;
93  m_pcLoopFilter          = pcLoopFilter;
94  m_pcSAO  = pcSAO;
95}
96
[56]97
[2]98// ====================================================================================================================
[56]99// Private member functions
100// ====================================================================================================================
101// ====================================================================================================================
[2]102// Public member functions
103// ====================================================================================================================
104
[608]105Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic)
[2]106{
107  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
[56]108  // Table of extracted substreams.
109  // These must be deallocated AND their internal fifos, too.
110  TComInputBitstream **ppcSubstreams = NULL;
[2]111
112  //-- For time output for each slice
113  long iBeforeTime = clock();
114 
[608]115  UInt uiStartCUAddr   = pcSlice->getSliceSegmentCurStartCUAddr();
[56]116
[608]117  UInt uiSliceStartCuAddr = pcSlice->getSliceCurStartCUAddr();
118  if(uiSliceStartCuAddr == uiStartCUAddr)
[2]119  {
[608]120    m_sliceStartCUAddress.push_back(uiSliceStartCuAddr);
121  }
[56]122
[608]123  m_pcSbacDecoder->init( (TDecBinIf*)m_pcBinCABAC );
124  m_pcEntropyDecoder->setEntropyDecoder (m_pcSbacDecoder);
[56]125
[608]126  UInt uiNumSubstreams = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcSlice->getNumEntryPointOffsets()+1 : pcSlice->getPPS()->getNumSubstreams();
[56]127
[608]128  // init each couple {EntropyDecoder, Substream}
129  UInt *puiSubstreamSizes = pcSlice->getSubstreamSizes();
130  ppcSubstreams    = new TComInputBitstream*[uiNumSubstreams];
131  m_pcSbacDecoders = new TDecSbac[uiNumSubstreams];
132  m_pcBinCABACs    = new TDecBinCABAC[uiNumSubstreams];
133  for ( UInt ui = 0 ; ui < uiNumSubstreams ; ui++ )
134  {
135    m_pcSbacDecoders[ui].init(&m_pcBinCABACs[ui]);
136    ppcSubstreams[ui] = pcBitstream->extractSubstream(ui+1 < uiNumSubstreams ? puiSubstreamSizes[ui] : pcBitstream->getNumBitsLeft());
137  }
[2]138
[608]139  for ( UInt ui = 0 ; ui+1 < uiNumSubstreams; ui++ )
140  {
141    m_pcEntropyDecoder->setEntropyDecoder ( &m_pcSbacDecoders[uiNumSubstreams - 1 - ui] );
142    m_pcEntropyDecoder->setBitstream      (  ppcSubstreams   [uiNumSubstreams - 1 - ui] );
[2]143    m_pcEntropyDecoder->resetEntropy      (pcSlice);
[608]144  }
[56]145
[608]146  m_pcEntropyDecoder->setEntropyDecoder ( m_pcSbacDecoder  );
147  m_pcEntropyDecoder->setBitstream      ( ppcSubstreams[0] );
148  m_pcEntropyDecoder->resetEntropy      (pcSlice);
[2]149
[608]150  if(uiSliceStartCuAddr == uiStartCUAddr)
151  {
152    m_LFCrossSliceBoundaryFlag.push_back( pcSlice->getLFCrossSliceBoundaryFlag());
153  }
154#if H_3D_NBDV
155  if(pcSlice->getViewIndex() && !pcSlice->getIsDepth()) //Notes from QC: this condition shall be changed once the configuration is completed, e.g. in pcSlice->getSPS()->getMultiviewMvPredMode() || ARP in prev. HTM. Remove this comment once it is done.
156  {
157    Int iColPoc = pcSlice->getRefPOC(RefPicList(1-pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx());
158    rpcPic->setNumDdvCandPics(rpcPic->getDisCandRefPictures(iColPoc));
159  }
[655]160
[608]161  if(pcSlice->getViewIndex() && !pcSlice->getIsDepth() && !pcSlice->isIntra()) //Notes from QC: this condition shall be changed once the configuration is completed, e.g. in pcSlice->getSPS()->getMultiviewMvPredMode() || ARP in prev. HTM. Remove this comment once it is done.
162  {
163    rpcPic->checkTemporalIVRef();
164  }
[655]165
[608]166  if(pcSlice->getIsDepth())
167  {
168    rpcPic->checkTextureRef();
169  }
[5]170#endif
[608]171#if H_3D
172  pcSlice->setDepthToDisparityLUTs(); 
[189]173#endif
[608]174  m_pcSbacDecoders[0].load(m_pcSbacDecoder);
175  m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders);
176  m_pcEntropyDecoder->setBitstream(  ppcSubstreams[uiNumSubstreams-1] );
177  // deallocate all created substreams, including internal buffers.
178  for (UInt ui = 0; ui < uiNumSubstreams; ui++)
179  {
180    ppcSubstreams[ui]->deleteFifo();
181    delete ppcSubstreams[ui];
182  }
183  delete[] ppcSubstreams;
184  delete[] m_pcSbacDecoders; m_pcSbacDecoders = NULL;
185  delete[] m_pcBinCABACs; m_pcBinCABACs = NULL;
[56]186
[608]187  m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
188}
189
190Void TDecGop::filterPicture(TComPic*& rpcPic)
191{
192  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
193
194  //-- For time output for each slice
195  long iBeforeTime = clock();
196
197  // deblocking filter
198  Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
199  m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
200  m_pcLoopFilter->loopFilterPic( rpcPic );
201
202  if(pcSlice->getSPS()->getUseSAO())
203  {
204    m_sliceStartCUAddress.push_back(rpcPic->getNumCUsInFrame()* rpcPic->getNumPartInCU());
205    rpcPic->createNonDBFilterInfo(m_sliceStartCUAddress, 0, &m_LFCrossSliceBoundaryFlag, rpcPic->getPicSym()->getNumTiles(), bLFCrossTileBoundary);
206  }
207
208  if( pcSlice->getSPS()->getUseSAO() )
209  {
[56]210    {
[608]211      SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam();
212      saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
213      saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma();
214      m_pcSAO->setSaoLcuBasedOptimization(1);
215      m_pcSAO->createPicSaoInfo(rpcPic);
216      m_pcSAO->SAOProcess(saoParam);
217      m_pcSAO->PCMLFDisableProcess(rpcPic);
218      m_pcSAO->destroyPicSaoInfo();
[56]219    }
[2]220  }
[608]221
222  if(pcSlice->getSPS()->getUseSAO())
[2]223  {
[608]224    rpcPic->destroyNonDBFilterInfo();
225  }
[655]226#if H_3D
[608]227  rpcPic->compressMotion(2); 
[5]228#endif
[608]229#if !H_3D
230  rpcPic->compressMotion(); 
[5]231#endif
[608]232  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
233  if (!pcSlice->isReferenced()) c += 32;
[56]234
[608]235  //-- For time output for each slice
236#if H_MV
237  printf("\nLayer %2d   POC %4d TId: %1d ( %c-SLICE, QP%3d ) ", pcSlice->getLayerId(),
238                                                              pcSlice->getPOC(),
239                                                              pcSlice->getTLayer(),
240                                                              c,
241                                                              pcSlice->getSliceQp() );
[443]242#else
[608]243  printf("\nPOC %4d TId: %1d ( %c-SLICE, QP%3d ) ", pcSlice->getPOC(),
244                                                    pcSlice->getTLayer(),
245                                                    c,
246                                                    pcSlice->getSliceQp() );
[443]247#endif
[56]248
[608]249  m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
250  printf ("[DT %6.3f] ", m_dDecTime );
251  m_dDecTime  = 0;
[56]252
[608]253  for (Int iRefList = 0; iRefList < 2; iRefList++)
254  {
255    printf ("[L%d ", iRefList);
256    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
[2]257    {
[608]258#if H_MV
259      if( pcSlice->getLayerId() != pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) )
[2]260      {
[608]261        printf( "V%d ", pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) );
[2]262      }
[608]263      else
[2]264      {
[608]265#endif
266      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
267#if H_MV
[2]268      }
[608]269#endif
[2]270    }
[608]271    printf ("] ");
272  }
273  if (m_decodedPictureHashSEIEnabled)
274  {
275    SEIMessages pictureHashes = getSeisByType(rpcPic->getSEIs(), SEI::DECODED_PICTURE_HASH );
276    const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL;
277    if (pictureHashes.size() > 1)
[56]278    {
[608]279      printf ("Warning: Got multiple decoded picture hash SEI messages. Using first.");
[2]280    }
[608]281    calcAndPrintHashStatus(*rpcPic->getPicYuvRec(), hash);
282  }
[2]283
[608]284  rpcPic->setOutputMark(true);
285  rpcPic->setReconMark(true);
286  m_sliceStartCUAddress.clear();
287  m_LFCrossSliceBoundaryFlag.clear();
[2]288}
289
290/**
[608]291 * Calculate and print hash for pic, compare to picture_digest SEI if
292 * present in seis.  seis may be NULL.  Hash is printed to stdout, in
[2]293 * a manner suitable for the status line. Theformat is:
[608]294 *  [Hash_type:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,(yyy)]
295 * Where, x..x is the hash
[2]296 *        yyy has the following meanings:
[608]297 *            OK          - calculated hash matches the SEI message
298 *            ***ERROR*** - calculated hash does not match the SEI message
[2]299 *            unk         - no SEI message was available for comparison
300 */
[608]301static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI)
[2]302{
303  /* calculate MD5sum for entire reconstructed picture */
[608]304  UChar recon_digest[3][16];
305  Int numChar=0;
306  const Char* hashType = "\0";
[2]307
[608]308  if (pictureHashSEI)
309  {
310    switch (pictureHashSEI->method)
311    {
312    case SEIDecodedPictureHash::MD5:
313      {
314        hashType = "MD5";
315        calcMD5(pic, recon_digest);
316        numChar = 16;
317        break;
318      }
319    case SEIDecodedPictureHash::CRC:
320      {
321        hashType = "CRC";
322        calcCRC(pic, recon_digest);
323        numChar = 2;
324        break;
325      }
326    case SEIDecodedPictureHash::CHECKSUM:
327      {
328        hashType = "Checksum";
329        calcChecksum(pic, recon_digest);
330        numChar = 4;
331        break;
332      }
333    default:
334      {
335        assert (!"unknown hash type");
336      }
337    }
338  }
339
[2]340  /* compare digest against received version */
[608]341  const Char* ok = "(unk)";
342  Bool mismatch = false;
[2]343
[608]344  if (pictureHashSEI)
[2]345  {
[608]346    ok = "(OK)";
347    for(Int yuvIdx = 0; yuvIdx < 3; yuvIdx++)
[2]348    {
[608]349      for (UInt i = 0; i < numChar; i++)
[2]350      {
[608]351        if (recon_digest[yuvIdx][i] != pictureHashSEI->digest[yuvIdx][i])
352        {
353          ok = "(***ERROR***)";
354          mismatch = true;
355        }
[2]356      }
357    }
358  }
359
[608]360  printf("[%s:%s,%s] ", hashType, digestToString(recon_digest, numChar), ok);
361
362  if (mismatch)
[2]363  {
364    g_md5_mismatch = true;
[608]365    printf("[rx%s:%s] ", hashType, digestToString(pictureHashSEI->digest, numChar));
[2]366  }
367}
[56]368//! \}
Note: See TracBrowser for help on using the repository browser.