source: 3DVCSoftware/branches/HTM-10.0-dev0/source/Lib/TLibDecoder/TDecGop.cpp @ 852

Last change on this file since 852 was 852, checked in by tech, 10 years ago

Update HM-12.0 -> HM-13.0.

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