source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibDecoder/TDecGop.cpp @ 1502

Last change on this file since 1502 was 1502, checked in by seregin, 8 years ago

infer parameters in SPS after activation, fixing chroma scaling for non 4:2:0

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