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

Last change on this file since 1335 was 1319, checked in by seregin, 9 years ago

port rev 4394

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