source: 3DVCSoftware/branches/HTM-14.0-MV-draft-3/source/Lib/TLibDecoder/TDecGop.cpp

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

Removed 3D-HEVC.

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