source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2/source/Lib/TLibDecoder/TDecGop.cpp @ 476

Last change on this file since 476 was 476, checked in by mediatek-htm, 11 years ago

Integration of 3D-HEVC merge related coding tools:
Inter-view motion merge candidate
HHI_INTER_VIEW_MOTION_PRED
SAIT_IMPROV_MOTION_PRED_M24829, improved inter-view motion vector prediction
QC_MRG_CANS_B0048 , JCT3V-B0048, B0086, B0069
OL_DISMV_POS_B0069 , different pos for disparity MV candidate, B0069
MTK_INTERVIEW_MERGE_A0049 , second part
QC_AMVP_MRG_UNIFY_IVCAN_C0051
TEXTURE MERGING CANDIDATE , JCT3V-C0137

Notes: Two configurations are added:
PredDepthMapGen : 1
MultiviewMvPred : 7

From: yiwen.chen@… (MediaTek)

  • Property svn:eol-style set to native
File size: 12.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-2013, 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#if H_3D_IV_MERGE
87                    ,TComDepthMapGenerator*  pcDepthMapGenerator
88#endif
89                   )
90{
91  m_pcEntropyDecoder      = pcEntropyDecoder;
92  m_pcSbacDecoder         = pcSbacDecoder;
93  m_pcBinCABAC            = pcBinCABAC;
94  m_pcCavlcDecoder        = pcCavlcDecoder;
95  m_pcSliceDecoder        = pcSliceDecoder;
96  m_pcLoopFilter          = pcLoopFilter;
97  m_pcSAO  = pcSAO;
98#if H_3D_IV_MERGE
99  m_pcDepthMapGenerator   = pcDepthMapGenerator;
100#endif
101}
102
103
104// ====================================================================================================================
105// Private member functions
106// ====================================================================================================================
107// ====================================================================================================================
108// Public member functions
109// ====================================================================================================================
110
111Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic)
112{
113  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
114  // Table of extracted substreams.
115  // These must be deallocated AND their internal fifos, too.
116  TComInputBitstream **ppcSubstreams = NULL;
117
118  //-- For time output for each slice
119  long iBeforeTime = clock();
120 
121  UInt uiStartCUAddr   = pcSlice->getSliceSegmentCurStartCUAddr();
122
123  UInt uiSliceStartCuAddr = pcSlice->getSliceCurStartCUAddr();
124  if(uiSliceStartCuAddr == uiStartCUAddr)
125  {
126    m_sliceStartCUAddress.push_back(uiSliceStartCuAddr);
127  }
128
129  m_pcSbacDecoder->init( (TDecBinIf*)m_pcBinCABAC );
130  m_pcEntropyDecoder->setEntropyDecoder (m_pcSbacDecoder);
131
132  UInt uiNumSubstreams = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcSlice->getNumEntryPointOffsets()+1 : pcSlice->getPPS()->getNumSubstreams();
133
134  // init each couple {EntropyDecoder, Substream}
135  UInt *puiSubstreamSizes = pcSlice->getSubstreamSizes();
136  ppcSubstreams    = new TComInputBitstream*[uiNumSubstreams];
137  m_pcSbacDecoders = new TDecSbac[uiNumSubstreams];
138  m_pcBinCABACs    = new TDecBinCABAC[uiNumSubstreams];
139  for ( UInt ui = 0 ; ui < uiNumSubstreams ; ui++ )
140  {
141    m_pcSbacDecoders[ui].init(&m_pcBinCABACs[ui]);
142    ppcSubstreams[ui] = pcBitstream->extractSubstream(ui+1 < uiNumSubstreams ? puiSubstreamSizes[ui] : pcBitstream->getNumBitsLeft());
143  }
144
145  for ( UInt ui = 0 ; ui+1 < uiNumSubstreams; ui++ )
146  {
147    m_pcEntropyDecoder->setEntropyDecoder ( &m_pcSbacDecoders[uiNumSubstreams - 1 - ui] );
148    m_pcEntropyDecoder->setBitstream      (  ppcSubstreams   [uiNumSubstreams - 1 - ui] );
149    m_pcEntropyDecoder->resetEntropy      (pcSlice);
150  }
151
152  m_pcEntropyDecoder->setEntropyDecoder ( m_pcSbacDecoder  );
153  m_pcEntropyDecoder->setBitstream      ( ppcSubstreams[0] );
154  m_pcEntropyDecoder->resetEntropy      (pcSlice);
155
156  if(uiSliceStartCuAddr == uiStartCUAddr)
157  {
158    m_LFCrossSliceBoundaryFlag.push_back( pcSlice->getLFCrossSliceBoundaryFlag());
159  }
160
161#if H_3D_IV_MERGE
162  if( uiStartCUAddr == 0 )
163  {
164    m_pcDepthMapGenerator->initViewComponent( rpcPic );
165  }
166#endif
167
168#if H_3D_NBDV
169  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.
170  {
171    Int iColPoc = pcSlice->getRefPOC(RefPicList(1-pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx());
172    rpcPic->setNumDdvCandPics(rpcPic->getDisCandRefPictures(iColPoc));
173  }
174#endif
175  m_pcSbacDecoders[0].load(m_pcSbacDecoder);
176  m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders);
177  m_pcEntropyDecoder->setBitstream(  ppcSubstreams[uiNumSubstreams-1] );
178  // deallocate all created substreams, including internal buffers.
179  for (UInt ui = 0; ui < uiNumSubstreams; ui++)
180  {
181    ppcSubstreams[ui]->deleteFifo();
182    delete ppcSubstreams[ui];
183  }
184  delete[] ppcSubstreams;
185  delete[] m_pcSbacDecoders; m_pcSbacDecoders = NULL;
186  delete[] m_pcBinCABACs; m_pcBinCABACs = NULL;
187
188  m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
189}
190
191Void TDecGop::filterPicture(TComPic*& rpcPic)
192{
193  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
194
195  //-- For time output for each slice
196  long iBeforeTime = clock();
197
198  // deblocking filter
199  Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
200  m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
201  m_pcLoopFilter->loopFilterPic( rpcPic );
202
203  if(pcSlice->getSPS()->getUseSAO())
204  {
205    m_sliceStartCUAddress.push_back(rpcPic->getNumCUsInFrame()* rpcPic->getNumPartInCU());
206    rpcPic->createNonDBFilterInfo(m_sliceStartCUAddress, 0, &m_LFCrossSliceBoundaryFlag, rpcPic->getPicSym()->getNumTiles(), bLFCrossTileBoundary);
207  }
208
209  if( pcSlice->getSPS()->getUseSAO() )
210  {
211    {
212      SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam();
213      saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
214      saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma();
215      m_pcSAO->setSaoLcuBasedOptimization(1);
216      m_pcSAO->createPicSaoInfo(rpcPic);
217      m_pcSAO->SAOProcess(saoParam);
218      m_pcSAO->PCMLFDisableProcess(rpcPic);
219      m_pcSAO->destroyPicSaoInfo();
220    }
221  }
222
223  if(pcSlice->getSPS()->getUseSAO())
224  {
225    rpcPic->destroyNonDBFilterInfo();
226  }
227
228#if !H_3D
229  rpcPic->compressMotion(); 
230#endif
231  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
232  if (!pcSlice->isReferenced()) c += 32;
233
234  //-- For time output for each slice
235#if H_MV
236  printf("\nLayer %2d   POC %4d TId: %1d ( %c-SLICE, QP%3d ) ", pcSlice->getLayerId(),
237                                                              pcSlice->getPOC(),
238                                                              pcSlice->getTLayer(),
239                                                              c,
240                                                              pcSlice->getSliceQp() );
241#else
242  printf("\nPOC %4d TId: %1d ( %c-SLICE, QP%3d ) ", pcSlice->getPOC(),
243                                                    pcSlice->getTLayer(),
244                                                    c,
245                                                    pcSlice->getSliceQp() );
246#endif
247
248  m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
249  printf ("[DT %6.3f] ", m_dDecTime );
250  m_dDecTime  = 0;
251
252  for (Int iRefList = 0; iRefList < 2; iRefList++)
253  {
254    printf ("[L%d ", iRefList);
255    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
256    {
257#if H_MV
258      if( pcSlice->getLayerId() != pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) )
259      {
260        printf( "V%d ", pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) );
261      }
262      else
263      {
264#endif
265      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
266#if H_MV
267      }
268#endif
269    }
270    printf ("] ");
271  }
272  if (m_decodedPictureHashSEIEnabled)
273  {
274    SEIMessages pictureHashes = getSeisByType(rpcPic->getSEIs(), SEI::DECODED_PICTURE_HASH );
275    const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL;
276    if (pictureHashes.size() > 1)
277    {
278      printf ("Warning: Got multiple decoded picture hash SEI messages. Using first.");
279    }
280    calcAndPrintHashStatus(*rpcPic->getPicYuvRec(), hash);
281  }
282
283  rpcPic->setOutputMark(true);
284  rpcPic->setReconMark(true);
285  m_sliceStartCUAddress.clear();
286  m_LFCrossSliceBoundaryFlag.clear();
287}
288
289/**
290 * Calculate and print hash for pic, compare to picture_digest SEI if
291 * present in seis.  seis may be NULL.  Hash is printed to stdout, in
292 * a manner suitable for the status line. Theformat is:
293 *  [Hash_type:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,(yyy)]
294 * Where, x..x is the hash
295 *        yyy has the following meanings:
296 *            OK          - calculated hash matches the SEI message
297 *            ***ERROR*** - calculated hash does not match the SEI message
298 *            unk         - no SEI message was available for comparison
299 */
300static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI)
301{
302  /* calculate MD5sum for entire reconstructed picture */
303  UChar recon_digest[3][16];
304  Int numChar=0;
305  const Char* hashType = "\0";
306
307  if (pictureHashSEI)
308  {
309    switch (pictureHashSEI->method)
310    {
311    case SEIDecodedPictureHash::MD5:
312      {
313        hashType = "MD5";
314        calcMD5(pic, recon_digest);
315        numChar = 16;
316        break;
317      }
318    case SEIDecodedPictureHash::CRC:
319      {
320        hashType = "CRC";
321        calcCRC(pic, recon_digest);
322        numChar = 2;
323        break;
324      }
325    case SEIDecodedPictureHash::CHECKSUM:
326      {
327        hashType = "Checksum";
328        calcChecksum(pic, recon_digest);
329        numChar = 4;
330        break;
331      }
332    default:
333      {
334        assert (!"unknown hash type");
335      }
336    }
337  }
338
339  /* compare digest against received version */
340  const Char* ok = "(unk)";
341  Bool mismatch = false;
342
343  if (pictureHashSEI)
344  {
345    ok = "(OK)";
346    for(Int yuvIdx = 0; yuvIdx < 3; yuvIdx++)
347    {
348      for (UInt i = 0; i < numChar; i++)
349      {
350        if (recon_digest[yuvIdx][i] != pictureHashSEI->digest[yuvIdx][i])
351        {
352          ok = "(***ERROR***)";
353          mismatch = true;
354        }
355      }
356    }
357  }
358
359  printf("[%s:%s,%s] ", hashType, digestToString(recon_digest, numChar), ok);
360
361  if (mismatch)
362  {
363    g_md5_mismatch = true;
364    printf("[rx%s:%s] ", hashType, digestToString(pictureHashSEI->digest, numChar));
365  }
366}
367//! \}
Note: See TracBrowser for help on using the repository browser.