source: SHVCSoftware/trunk/source/Lib/TLibDecoder/TDecGop.cpp @ 959

Last change on this file since 959 was 906, checked in by seregin, 10 years ago

merge SHM-dev

  • Property svn:eol-style set to native
File size: 19.7 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
4 * granted under this license. 
5 *
[595]6 * Copyright (c) 2010-2014, 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"
47#endif
48
49#include <time.h>
50
51extern Bool g_md5_mismatch; ///< top level flag to signal when there is a decode problem
52
53//! \ingroup TLibDecoder
54//! \{
55static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI);
[906]56#if Q0074_COLOUR_REMAPPING_SEI
57static Void applyColourRemapping(TComPicYuv& pic, const SEIColourRemappingInfo* colourRemappingInfoSEI, UInt layerId=0 );
58static std::vector<SEIColourRemappingInfo> storeCriSEI; //Persistent Colour Remapping Information SEI
59#endif
[313]60// ====================================================================================================================
61// Constructor / destructor / initialization / destroy
62// ====================================================================================================================
63
64TDecGop::TDecGop()
65{
66  m_dDecTime = 0;
67  m_pcSbacDecoders = NULL;
68  m_pcBinCABACs = NULL;
69}
70
71TDecGop::~TDecGop()
72{
73 
74}
75
76#if SVC_EXTENSION
77Void TDecGop::create(UInt layerId)
78{
79  m_layerId = layerId;
80}
81#else
82Void TDecGop::create()
83{
84 
85}
86#endif
87
88Void TDecGop::destroy()
89{
90}
91#if SVC_EXTENSION
92Void TDecGop::init(TDecTop**               ppcDecTop,
93                   TDecEntropy*            pcEntropyDecoder,
94#else
95Void TDecGop::init( TDecEntropy*            pcEntropyDecoder, 
96#endif
97                   TDecSbac*               pcSbacDecoder, 
98                   TDecBinCABAC*           pcBinCABAC,
99                   TDecCavlc*              pcCavlcDecoder, 
100                   TDecSlice*              pcSliceDecoder, 
101                   TComLoopFilter*         pcLoopFilter,
102                   TComSampleAdaptiveOffset* pcSAO
103                   )
104{
105  m_pcEntropyDecoder      = pcEntropyDecoder;
106  m_pcSbacDecoder         = pcSbacDecoder;
107  m_pcBinCABAC            = pcBinCABAC;
108  m_pcCavlcDecoder        = pcCavlcDecoder;
109  m_pcSliceDecoder        = pcSliceDecoder;
110  m_pcLoopFilter          = pcLoopFilter;
111  m_pcSAO  = pcSAO;
112#if SVC_EXTENSION   
113  m_ppcTDecTop            = ppcDecTop;
114#endif
115}
116
117
118// ====================================================================================================================
119// Private member functions
120// ====================================================================================================================
121// ====================================================================================================================
122// Public member functions
123// ====================================================================================================================
124
125Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic)
126{
127  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
128  // Table of extracted substreams.
129  // These must be deallocated AND their internal fifos, too.
130  TComInputBitstream **ppcSubstreams = NULL;
131
132  //-- For time output for each slice
133  long iBeforeTime = clock();
134  m_pcSbacDecoder->init( (TDecBinIf*)m_pcBinCABAC );
135  m_pcEntropyDecoder->setEntropyDecoder (m_pcSbacDecoder);
136
137  UInt uiNumSubstreams = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcSlice->getNumEntryPointOffsets()+1 : pcSlice->getPPS()->getNumSubstreams();
138
139  // init each couple {EntropyDecoder, Substream}
140  UInt *puiSubstreamSizes = pcSlice->getSubstreamSizes();
141  ppcSubstreams    = new TComInputBitstream*[uiNumSubstreams];
142  m_pcSbacDecoders = new TDecSbac[uiNumSubstreams];
143  m_pcBinCABACs    = new TDecBinCABAC[uiNumSubstreams];
144  for ( UInt ui = 0 ; ui < uiNumSubstreams ; ui++ )
145  {
146    m_pcSbacDecoders[ui].init(&m_pcBinCABACs[ui]);
147    ppcSubstreams[ui] = pcBitstream->extractSubstream(ui+1 < uiNumSubstreams ? puiSubstreamSizes[ui] : pcBitstream->getNumBitsLeft());
148  }
149
150  for ( UInt ui = 0 ; ui+1 < uiNumSubstreams; ui++ )
151  {
152    m_pcEntropyDecoder->setEntropyDecoder ( &m_pcSbacDecoders[uiNumSubstreams - 1 - ui] );
153    m_pcEntropyDecoder->setBitstream      (  ppcSubstreams   [uiNumSubstreams - 1 - ui] );
154    m_pcEntropyDecoder->resetEntropy      (pcSlice);
155  }
156
157  m_pcEntropyDecoder->setEntropyDecoder ( m_pcSbacDecoder  );
158  m_pcEntropyDecoder->setBitstream      ( ppcSubstreams[0] );
159  m_pcEntropyDecoder->resetEntropy      (pcSlice);
160  m_pcSbacDecoders[0].load(m_pcSbacDecoder);
161  m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders);
162  m_pcEntropyDecoder->setBitstream(  ppcSubstreams[uiNumSubstreams-1] );
163  // deallocate all created substreams, including internal buffers.
164  for (UInt ui = 0; ui < uiNumSubstreams; ui++)
165  {
166    ppcSubstreams[ui]->deleteFifo();
167    delete ppcSubstreams[ui];
168  }
169  delete[] ppcSubstreams;
170  delete[] m_pcSbacDecoders; m_pcSbacDecoders = NULL;
171  delete[] m_pcBinCABACs; m_pcBinCABACs = NULL;
172
173  m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
174}
175
176Void TDecGop::filterPicture(TComPic*& rpcPic)
177{
178  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
179
180  //-- For time output for each slice
181  long iBeforeTime = clock();
182
183  // deblocking filter
184  Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
185  m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
186  m_pcLoopFilter->loopFilterPic( rpcPic );
187  if( pcSlice->getSPS()->getUseSAO() )
188  {
[540]189    m_pcSAO->reconstructBlkSAOParams(rpcPic, rpcPic->getPicSym()->getSAOBlkParam());
190    m_pcSAO->SAOProcess(rpcPic);
191    m_pcSAO->PCMLFDisableProcess(rpcPic);
[313]192  }
193  rpcPic->compressMotion(); 
194  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
195  if (!pcSlice->isReferenced()) c += 32;
196
197  //-- For time output for each slice
198#if SVC_EXTENSION
[588]199  printf("\nPOC %4d LId: %1d TId: %1d ( %c-SLICE %s, QP%3d ) ", pcSlice->getPOC(),
[313]200                                                    rpcPic->getLayerId(),
201                                                    pcSlice->getTLayer(),
202                                                    c,
[588]203                                                    NaluToStr( pcSlice->getNalUnitType() ).data(),
[313]204                                                    pcSlice->getSliceQp() );
205#else
206  printf("\nPOC %4d TId: %1d ( %c-SLICE, QP%3d ) ", pcSlice->getPOC(),
207                                                    pcSlice->getTLayer(),
208                                                    c,
209                                                    pcSlice->getSliceQp() );
210#endif
211  m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
212  printf ("[DT %6.3f] ", m_dDecTime );
213  m_dDecTime  = 0;
214
215  for (Int iRefList = 0; iRefList < 2; iRefList++)
216  {
217    printf ("[L%d ", iRefList);
218    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
219    {
[442]220#if SVC_EXTENSION
221#if VPS_EXTN_DIRECT_REF_LAYERS
[313]222      if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR( m_layerId ) )
223      {
[906]224        UInt refLayerId = pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId();
225        UInt refLayerIdc = pcSlice->getReferenceLayerIdc(refLayerId);
226        assert( g_posScalingFactor[refLayerIdc][0] );
227        assert( g_posScalingFactor[refLayerIdc][1] );
228
229        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]230      }
231      else
[442]232      {
233        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
234      }
[313]235#endif
[442]236      if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() )
237      {
238        printf( "c" );
239      }
240
241      printf( " " );
242#else
[313]243      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
[442]244#endif
[313]245    }
246    printf ("] ");
247  }
248  if (m_decodedPictureHashSEIEnabled)
249  {
250    SEIMessages pictureHashes = getSeisByType(rpcPic->getSEIs(), SEI::DECODED_PICTURE_HASH );
251    const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL;
252    if (pictureHashes.size() > 1)
253    {
254      printf ("Warning: Got multiple decoded picture hash SEI messages. Using first.");
255    }
256    calcAndPrintHashStatus(*rpcPic->getPicYuvRec(), hash);
257  }
[906]258#if Q0074_COLOUR_REMAPPING_SEI
259  if (m_colourRemapSEIEnabled)
260  {
261    SEIMessages colourRemappingInfo = getSeisByType(rpcPic->getSEIs(), SEI::COLOUR_REMAPPING_INFO );
262    const SEIColourRemappingInfo *seiColourRemappingInfo = ( colourRemappingInfo.size() > 0 ) ? (SEIColourRemappingInfo*) *(colourRemappingInfo.begin()) : NULL;
263    if (colourRemappingInfo.size() > 1)
264    {
265      printf ("Warning: Got multiple Colour Remapping Information SEI messages. Using first.");
266    }
267    applyColourRemapping(*rpcPic->getPicYuvRec(), seiColourRemappingInfo
268#if SVC_EXTENSION
269     , rpcPic->getLayerId()
270#endif
271     );
272  }
273#endif
[313]274
[713]275#if SETTING_PIC_OUTPUT_MARK
276  rpcPic->setOutputMark(rpcPic->getSlice(0)->getPicOutputFlag() ? true : false);
277#else
[313]278  rpcPic->setOutputMark(true);
[713]279#endif
[313]280  rpcPic->setReconMark(true);
281}
282
283/**
284 * Calculate and print hash for pic, compare to picture_digest SEI if
285 * present in seis.  seis may be NULL.  Hash is printed to stdout, in
286 * a manner suitable for the status line. Theformat is:
287 *  [Hash_type:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,(yyy)]
288 * Where, x..x is the hash
289 *        yyy has the following meanings:
290 *            OK          - calculated hash matches the SEI message
291 *            ***ERROR*** - calculated hash does not match the SEI message
292 *            unk         - no SEI message was available for comparison
293 */
294static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI)
295{
296  /* calculate MD5sum for entire reconstructed picture */
297  UChar recon_digest[3][16];
298  Int numChar=0;
299  const Char* hashType = "\0";
300
301  if (pictureHashSEI)
302  {
303    switch (pictureHashSEI->method)
304    {
305    case SEIDecodedPictureHash::MD5:
306      {
307        hashType = "MD5";
308        calcMD5(pic, recon_digest);
309        numChar = 16;
310        break;
311      }
312    case SEIDecodedPictureHash::CRC:
313      {
314        hashType = "CRC";
315        calcCRC(pic, recon_digest);
316        numChar = 2;
317        break;
318      }
319    case SEIDecodedPictureHash::CHECKSUM:
320      {
321        hashType = "Checksum";
322        calcChecksum(pic, recon_digest);
323        numChar = 4;
324        break;
325      }
326    default:
327      {
328        assert (!"unknown hash type");
329      }
330    }
331  }
332
333  /* compare digest against received version */
334  const Char* ok = "(unk)";
335  Bool mismatch = false;
336
337  if (pictureHashSEI)
338  {
339    ok = "(OK)";
340    for(Int yuvIdx = 0; yuvIdx < 3; yuvIdx++)
341    {
342      for (UInt i = 0; i < numChar; i++)
343      {
344        if (recon_digest[yuvIdx][i] != pictureHashSEI->digest[yuvIdx][i])
345        {
346          ok = "(***ERROR***)";
347          mismatch = true;
348        }
349      }
350    }
351  }
352
353  printf("[%s:%s,%s] ", hashType, digestToString(recon_digest, numChar), ok);
354
355  if (mismatch)
356  {
357    g_md5_mismatch = true;
358    printf("[rx%s:%s] ", hashType, digestToString(pictureHashSEI->digest, numChar));
359  }
360}
[906]361
362#if Q0074_COLOUR_REMAPPING_SEI
363Void xInitColourRemappingLut( const Int bitDepthY, const Int bitDepthC, std::vector<Int>(&preLut)[3], std::vector<Int>(&postLut)[3], const SEIColourRemappingInfo* const pCriSEI )
364{
365  for ( Int c=0 ; c<3 ; c++ )
366  { 
367    Int bitDepth = c ? bitDepthC : bitDepthY ;
368    preLut[c].resize(1 << bitDepth);
369    postLut[c].resize(1 << pCriSEI->m_colourRemapBitDepth);
370   
371    Int bitDepthDiff = pCriSEI->m_colourRemapBitDepth - bitDepth;
372    Int iShift1 = (bitDepthDiff>0) ? bitDepthDiff : 0; //bit scale from bitdepth to ColourRemapBitdepth (manage only case colourRemapBitDepth>= bitdepth)
373    if( bitDepthDiff<0 )
374      printf ("Warning: CRI SEI - colourRemapBitDepth (%d) <bitDepth (%d) - case not handled\n", pCriSEI->m_colourRemapBitDepth, bitDepth);
375    bitDepthDiff = pCriSEI->m_colourRemapBitDepth - pCriSEI->m_colourRemapInputBitDepth;
376    Int iShift2 = (bitDepthDiff>0) ? bitDepthDiff : 0; //bit scale from ColourRemapInputBitdepth to ColourRemapBitdepth (manage only case colourRemapBitDepth>= colourRemapInputBitDepth)
377    if( bitDepthDiff<0 )
378      printf ("Warning: CRI SEI - colourRemapBitDepth (%d) <colourRemapInputBitDepth (%d) - case not handled\n", pCriSEI->m_colourRemapBitDepth, pCriSEI->m_colourRemapInputBitDepth);
379
380    //Fill preLut
381    for ( Int k=0 ; k<(1<<bitDepth) ; k++ )
382    {
383      Int iSample = k << iShift1 ;
384      for ( Int iPivot=0 ; iPivot<=pCriSEI->m_preLutNumValMinus1[c] ; iPivot++ )
385      {
386        Int iCodedPrev  = pCriSEI->m_preLutCodedValue[c][iPivot]    << iShift2; //Coded in CRInputBitdepth
387        Int iCodedNext  = pCriSEI->m_preLutCodedValue[c][iPivot+1]  << iShift2; //Coded in CRInputBitdepth
388        Int iTargetPrev = pCriSEI->m_preLutTargetValue[c][iPivot];              //Coded in CRBitdepth
389        Int iTargetNext = pCriSEI->m_preLutTargetValue[c][iPivot+1];            //Coded in CRBitdepth
390        if ( iCodedPrev <= iSample && iSample <= iCodedNext )
391        {
392          Float fInterpol = (Float)( (iCodedNext - iSample)*iTargetPrev + (iSample - iCodedPrev)*iTargetNext ) * 1.f / (Float)(iCodedNext - iCodedPrev);
393          preLut[c][k]  = (Int)( 0.5f + fInterpol );
394          iPivot = pCriSEI->m_preLutNumValMinus1[c] + 1;
395        }
396      }
397    }
398   
399    //Fill postLut
400    for ( Int k=0 ; k<(1<<pCriSEI->m_colourRemapBitDepth) ; k++ )
401    {
402      Int iSample = k;
403      for ( Int iPivot=0 ; iPivot<=pCriSEI->m_postLutNumValMinus1[c] ; iPivot++ )
404      {
405        Int iCodedPrev  = pCriSEI->m_postLutCodedValue[c][iPivot];    //Coded in CRBitdepth
406        Int iCodedNext  = pCriSEI->m_postLutCodedValue[c][iPivot+1];  //Coded in CRBitdepth
407        Int iTargetPrev = pCriSEI->m_postLutTargetValue[c][iPivot];   //Coded in CRBitdepth
408        Int iTargetNext = pCriSEI->m_postLutTargetValue[c][iPivot+1]; //Coded in CRBitdepth
409        if ( iCodedPrev <= iSample && iSample <= iCodedNext )
410        {
411          Float fInterpol =  (Float)( (iCodedNext - iSample)*iTargetPrev + (iSample - iCodedPrev)*iTargetNext ) * 1.f / (Float)(iCodedNext - iCodedPrev) ;
412          postLut[c][k]  = (Int)( 0.5f + fInterpol );
413          iPivot = pCriSEI->m_postLutNumValMinus1[c] + 1;
414        }
415      }
416    }
417  }
418}
419
420static void applyColourRemapping(TComPicYuv& pic, const SEIColourRemappingInfo* pCriSEI, UInt layerId )
421{ 
422  if( !storeCriSEI.size() )
423#if SVC_EXTENSION
424    storeCriSEI.resize(MAX_LAYERS);
425#else
426    storeCriSEI.resize(1);
427#endif
428
429  if ( pCriSEI ) //if a CRI SEI has just been retrieved, keep it in memory (persistence management)
430    storeCriSEI[layerId] = *pCriSEI;
431
432  if( !storeCriSEI[layerId].m_colourRemapCancelFlag )
433  {
434    Int iHeight  = pic.getHeight();
435    Int iWidth   = pic.getWidth();
436    Int iStride  = pic.getStride();
437    Int iCStride = pic.getCStride();
438
439    Pel *YUVIn[3], *YUVOut[3];
440    YUVIn[0] = pic.getLumaAddr();
441    YUVIn[1] = pic.getCbAddr();
442    YUVIn[2] = pic.getCrAddr();
443   
444    TComPicYuv picColourRemapped;
445#if SVC_EXTENSION
446#if AUXILIARY_PICTURES
447    picColourRemapped.create( pic.getWidth(), pic.getHeight(), pic.getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL );
448#else
449    picColourRemapped.create( pic.getWidth(), pic.getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL );
450#endif
451#else
452    picColourRemapped.create( pic.getWidth(), pic.getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
453#endif
454    YUVOut[0] = picColourRemapped.getLumaAddr();
455    YUVOut[1] = picColourRemapped.getCbAddr();
456    YUVOut[2] = picColourRemapped.getCrAddr();
457
458#if SVC_EXTENSION
459    Int bitDepthY = g_bitDepthYLayer[layerId];
460    Int bitDepthC = g_bitDepthCLayer[layerId];
461
462    assert( g_bitDepthY == bitDepthY );
463    assert( g_bitDepthC == bitDepthC );
464#else
465    Int bitDepthY = g_bitDepthY;
466    Int bitDepthC = g_bitDepthC;
467#endif
468
469    std::vector<Int> preLut[3];
470    std::vector<Int> postLut[3];
471    xInitColourRemappingLut( bitDepthY, bitDepthC, preLut, postLut, &storeCriSEI[layerId] );
472   
473    Int roundingOffset = (storeCriSEI[layerId].m_log2MatrixDenom==0) ? 0 : (1 << (storeCriSEI[layerId].m_log2MatrixDenom - 1));
474
475    for( Int y = 0; y < iHeight ; y++ )
476    {
477      for( Int x = 0; x < iWidth ; x++ )
478      {
479        Int YUVPre[3], YUVMat[3];
480        YUVPre[0] = preLut[0][ YUVIn[0][x]   ];
481        YUVPre[1] = preLut[1][ YUVIn[1][x>>1] ];
482        YUVPre[2] = preLut[2][ YUVIn[2][x>>1] ];
483
484        YUVMat[0] = ( storeCriSEI[layerId].m_colourRemapCoeffs[0][0]*YUVPre[0]
485                    + storeCriSEI[layerId].m_colourRemapCoeffs[0][1]*YUVPre[1] 
486                    + storeCriSEI[layerId].m_colourRemapCoeffs[0][2]*YUVPre[2] 
487                    + roundingOffset ) >> ( storeCriSEI[layerId].m_log2MatrixDenom );
488        YUVMat[0] = Clip3( 0, (1<<storeCriSEI[layerId].m_colourRemapBitDepth)-1, YUVMat[0] );
489        YUVOut[0][x] = postLut[0][ YUVMat[0] ];
490
491        if( (y&1) && (x&1) )
492        {
493          for(Int c=1 ; c<3 ; c++)
494          {
495            YUVMat[c] = ( storeCriSEI[layerId].m_colourRemapCoeffs[c][0]*YUVPre[0] 
496                        + storeCriSEI[layerId].m_colourRemapCoeffs[c][1]*YUVPre[1] 
497                        + storeCriSEI[layerId].m_colourRemapCoeffs[c][2]*YUVPre[2] 
498                        + roundingOffset ) >> ( storeCriSEI[layerId].m_log2MatrixDenom );
499            YUVMat[c] = Clip3( 0, (1<<storeCriSEI[layerId].m_colourRemapBitDepth)-1, YUVMat[c] );
500            YUVOut[c][x>>1] = postLut[c][ YUVMat[c] ];   
501          }
502        }
503      }
504      YUVIn[0]  += iStride;
505      YUVOut[0] += iStride;
506      if( y&1 )
507      {
508        YUVIn[1]  += iCStride;
509        YUVIn[2]  += iCStride;
510        YUVOut[1] += iCStride;
511        YUVOut[2] += iCStride;
512      }
513    }
514
515    //Write remapped picture in decoding order
516    Char  cTemp[255];
517    sprintf(cTemp, "seiColourRemappedPic_L%d_%dx%d_%dbits.yuv", layerId, iWidth, iHeight, storeCriSEI[layerId].m_colourRemapBitDepth );
518    picColourRemapped.dump( cTemp, true, storeCriSEI[layerId].m_colourRemapBitDepth );
519
520    picColourRemapped.destroy();
521
522    storeCriSEI[layerId].m_colourRemapCancelFlag = !storeCriSEI[layerId].m_colourRemapPersistenceFlag; //Handling persistence
523  }
524}
525#endif
[313]526//! \}
Note: See TracBrowser for help on using the repository browser.