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

Last change on this file since 1136 was 1089, checked in by seregin, 9 years ago

Patch provided by Hiron Franck <franck.hiron@…> to complete implementation of the CRI (Colour remapping info) with the following features:

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