source: SHVCSoftware/branches/SHM-4.0-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 466

Last change on this file since 466 was 466, checked in by nokia, 11 years ago

Integration of O0194: Support different bit-depth values for different layers, enable weighted prediction for ILR for color gamut scalability.

  • Property svn:eol-style set to native
File size: 81.7 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     TEncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSlice.h"
40#include <math.h>
41
42//! \ingroup TLibEncoder
43//! \{
44
45// ====================================================================================================================
46// Constructor / destructor / create / destroy
47// ====================================================================================================================
48
49TEncSlice::TEncSlice()
50{
51  m_apcPicYuvPred = NULL;
52  m_apcPicYuvResi = NULL;
53
54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57  m_pcBufferSbacCoders    = NULL;
58  m_pcBufferBinCoderCABACs  = NULL;
59  m_pcBufferLowLatSbacCoders    = NULL;
60  m_pcBufferLowLatBinCoderCABACs  = NULL;
61}
62
63TEncSlice::~TEncSlice()
64{
65  for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
66  {
67    delete (*i);
68  }
69}
70
71Void TEncSlice::initCtxMem(  UInt i )
72{
73  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
74  {
75    delete (*j);
76  }
77  CTXMem.clear();
78  CTXMem.resize(i);
79}
80
81Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
82{
83  // create prediction picture
84  if ( m_apcPicYuvPred == NULL )
85  {
86    m_apcPicYuvPred  = new TComPicYuv;
87    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
88  }
89
90  // create residual picture
91  if( m_apcPicYuvResi == NULL )
92  {
93    m_apcPicYuvResi  = new TComPicYuv;
94    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
95  }
96}
97
98Void TEncSlice::destroy()
99{
100  // destroy prediction picture
101  if ( m_apcPicYuvPred )
102  {
103    m_apcPicYuvPred->destroy();
104    delete m_apcPicYuvPred;
105    m_apcPicYuvPred  = NULL;
106  }
107
108  // destroy residual picture
109  if ( m_apcPicYuvResi )
110  {
111    m_apcPicYuvResi->destroy();
112    delete m_apcPicYuvResi;
113    m_apcPicYuvResi  = NULL;
114  }
115
116  // free lambda and QP arrays
117  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
118  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
119  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
120
121  if ( m_pcBufferSbacCoders )
122  {
123    delete[] m_pcBufferSbacCoders;
124  }
125  if ( m_pcBufferBinCoderCABACs )
126  {
127    delete[] m_pcBufferBinCoderCABACs;
128  }
129  if ( m_pcBufferLowLatSbacCoders )
130    delete[] m_pcBufferLowLatSbacCoders;
131  if ( m_pcBufferLowLatBinCoderCABACs )
132    delete[] m_pcBufferLowLatBinCoderCABACs;
133}
134
135Void TEncSlice::init( TEncTop* pcEncTop )
136{
137  m_pcCfg             = pcEncTop;
138  m_pcListPic         = pcEncTop->getListPic();
139#if SVC_EXTENSION
140  m_ppcTEncTop        = pcEncTop->getLayerEnc();
141#endif
142  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
143  m_pcCuEncoder       = pcEncTop->getCuEncoder();
144  m_pcPredSearch      = pcEncTop->getPredSearch();
145
146  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
147  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
148  m_pcSbacCoder       = pcEncTop->getSbacCoder();
149  m_pcBinCABAC        = pcEncTop->getBinCABAC();
150  m_pcTrQuant         = pcEncTop->getTrQuant();
151
152  m_pcBitCounter      = pcEncTop->getBitCounter();
153  m_pcRdCost          = pcEncTop->getRdCost();
154  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
155  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
156
157  // create lambda and QP arrays
158  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
159  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
160  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
161  m_pcRateCtrl        = pcEncTop->getRateCtrl();
162}
163
164/**
165 - non-referenced frame marking
166 - QP computation based on temporal structure
167 - lambda computation based on QP
168 - set temporal layer ID and the parameter sets
169 .
170 \param pcPic         picture class
171 \param pocLast       POC of last picture
172 \param pocCurr       current POC
173 \param iNumPicRcvd   number of received pictures
174 \param iTimeOffset   POC offset for hierarchical structure
175 \param iDepth        temporal layer depth
176 \param rpcSlice      slice header class
177 \param pSPS          SPS associated with the slice
178 \param pPPS          PPS associated with the slice
179 */
180#if SVC_EXTENSION
181//\param vps          VPS associated with the slice
182Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, TComVPS *vps, Bool isField )
183#else
184Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, Bool isField )
185#endif
186{
187  Double dQP;
188  Double dLambda;
189
190  rpcSlice = pcPic->getSlice(0);
191  rpcSlice->setSPS( pSPS );
192  rpcSlice->setPPS( pPPS );
193  rpcSlice->setSliceBits(0);
194  rpcSlice->setPic( pcPic );
195#if SVC_EXTENSION
196  UInt layerId = pcPic->getLayerId();
197  rpcSlice->setVPS( vps );
198  rpcSlice->initSlice( layerId );
199#else
200  rpcSlice->initSlice();
201#endif
202  rpcSlice->setPicOutputFlag( true );
203  rpcSlice->setPOC( pocCurr );
204
205  // depth computation based on GOP size
206  Int depth;
207  {
208    Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
209    if ( poc == 0 )
210    {
211      depth = 0;
212    }
213    else
214    {
215      Int step = m_pcCfg->getGOPSize();
216      depth    = 0;
217      for( Int i=step>>1; i>=1; i>>=1 )
218      {
219        for ( Int j=i; j<m_pcCfg->getGOPSize(); j+=step )
220        {
221          if ( j == poc )
222          {
223            i=0;
224            break;
225          }
226        }
227        step >>= 1;
228        depth++;
229      }
230    }
231  }
232
233  // slice type
234  SliceType eSliceType;
235
236  eSliceType=B_SLICE;
237  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
238
239  rpcSlice->setSliceType    ( eSliceType );
240
241  // ------------------------------------------------------------------------------------------------------------------
242  // Non-referenced frame marking
243  // ------------------------------------------------------------------------------------------------------------------
244
245  if(pocLast == 0)
246  {
247    rpcSlice->setTemporalLayerNonReferenceFlag(false);
248  }
249  else
250  {
251    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
252  }
253  rpcSlice->setReferenced(true);
254
255  // ------------------------------------------------------------------------------------------------------------------
256  // QP setting
257  // ------------------------------------------------------------------------------------------------------------------
258
259  dQP = m_pcCfg->getQP();
260  if(eSliceType!=I_SLICE)
261  {
262#if REPN_FORMAT_IN_VPS
263    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless())))
264#else
265    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless())))
266#endif
267    {
268      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
269    }
270  }
271
272  // modify QP
273  Int* pdQPs = m_pcCfg->getdQPs();
274  if ( pdQPs )
275  {
276    dQP += pdQPs[ rpcSlice->getPOC() ];
277  }
278#if !RATE_CONTROL_LAMBDA_DOMAIN
279  if ( m_pcCfg->getUseRateCtrl())
280  {
281    dQP = m_pcRateCtrl->getFrameQP(rpcSlice->isReferenced(), rpcSlice->getPOC());
282  }
283#endif
284  // ------------------------------------------------------------------------------------------------------------------
285  // Lambda computation
286  // ------------------------------------------------------------------------------------------------------------------
287
288  Int iQP;
289  Double dOrigQP = dQP;
290
291  // pre-compute lambda and QP values for all possible QP candidates
292  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
293  {
294    // compute QP value
295    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
296
297    // compute lambda value
298    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
299    Int    SHIFT_QP = 12;
300
301    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
302
303#if FULL_NBIT
304    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
305#else
306    Int    bitdepth_luma_qp_scale = 0;
307#endif
308    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
309#if FULL_NBIT
310    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
311#endif
312    // Case #1: I or P-slices (key-frame)
313    Double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
314    if ( eSliceType==I_SLICE )
315    {
316      dQPFactor=0.57*dLambda_scale;
317    }
318    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
319
320    if ( depth>0 )
321    {
322#if FULL_NBIT
323        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
324#else
325        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
326#endif
327    }
328
329    // if hadamard is used in ME process
330    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
331    {
332      dLambda *= 0.95;
333    }
334
335#if REPN_FORMAT_IN_VPS
336    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
337#else
338    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
339#endif
340
341    m_pdRdPicLambda[iDQpIdx] = dLambda;
342    m_pdRdPicQp    [iDQpIdx] = dQP;
343    m_piRdPicQp    [iDQpIdx] = iQP;
344  }
345
346  // obtain dQP = 0 case
347  dLambda = m_pdRdPicLambda[0];
348  dQP     = m_pdRdPicQp    [0];
349  iQP     = m_piRdPicQp    [0];
350
351  if( rpcSlice->getSliceType( ) != I_SLICE )
352  {
353    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
354  }
355
356#if JCTVC_M0259_LAMBDAREFINEMENT
357  if( rpcSlice->getLayerId() > 0 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && depth >= 3 && m_pcCfg->getGOPSize() == ( 1 << depth ) )
358  {
359    Int nCurLayer = rpcSlice->getLayerId();
360    Double gamma = xCalEnhLambdaFactor( m_ppcTEncTop[nCurLayer-1]->getQP() - m_ppcTEncTop[nCurLayer]->getQP() ,
361      1.0 * m_ppcTEncTop[nCurLayer]->getSourceWidth() * m_ppcTEncTop[nCurLayer]->getSourceHeight()
362      / m_ppcTEncTop[nCurLayer-1]->getSourceWidth() / m_ppcTEncTop[nCurLayer-1]->getSourceHeight() );
363    dLambda *= gamma;
364  }
365#endif
366
367  // store lambda
368  m_pcRdCost ->setLambda( dLambda );
369#if WEIGHTED_CHROMA_DISTORTION
370// for RDO
371  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
372  Double weight = 1.0;
373  Int qpc;
374  Int chromaQPOffset;
375
376  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
377  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
378  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
379  m_pcRdCost->setCbDistortionWeight(weight);
380
381  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
382  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
383  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
384#if JCTVC_M0259_LAMBDAREFINEMENT
385  if( rpcSlice->getLayerId() > 0 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && m_pcCfg->getGOPSize() >= 8 && rpcSlice->isIntra() == false && depth == 0 )
386  {
387    dLambda *= 1.1;
388    weight *= 1.15;
389  }
390#endif
391  m_pcRdCost->setCrDistortionWeight(weight);
392#endif
393
394#if RDOQ_CHROMA_LAMBDA
395// for RDOQ
396  m_pcTrQuant->setLambda( dLambda, dLambda / weight );
397#else
398  m_pcTrQuant->setLambda( dLambda );
399#endif
400
401#if SAO_CHROMA_LAMBDA
402// For SAO
403  rpcSlice   ->setLambda( dLambda, dLambda / weight );
404#else
405  rpcSlice   ->setLambda( dLambda );
406#endif
407
408#if HB_LAMBDA_FOR_LDC
409  // restore original slice type
410  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
411
412#if SVC_EXTENSION
413  if(m_pcCfg->getLayerId() > 0)
414  {
415    eSliceType=B_SLICE;
416  }
417#endif
418  rpcSlice->setSliceType        ( eSliceType );
419#endif
420
421  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
422  {
423    dQP = xGetQPValueAccordingToLambda( dLambda );
424#if REPN_FORMAT_IN_VPS
425    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
426#else
427    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
428#endif
429  }
430
431  rpcSlice->setSliceQp          ( iQP );
432#if ADAPTIVE_QP_SELECTION
433  rpcSlice->setSliceQpBase      ( iQP );
434#endif
435  rpcSlice->setSliceQpDelta     ( 0 );
436  rpcSlice->setSliceQpDeltaCb   ( 0 );
437  rpcSlice->setSliceQpDeltaCr   ( 0 );
438  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
439  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
440
441  if ( m_pcCfg->getDeblockingFilterMetric() )
442  {
443    rpcSlice->setDeblockingFilterOverrideFlag(true);
444    rpcSlice->setDeblockingFilterDisable(false);
445    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
446    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
447  } else
448  if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
449  {
450    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
451    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
452    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
453    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
454    if ( !rpcSlice->getDeblockingFilterDisable())
455    {
456      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
457      {
458        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
459        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
460        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
461        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
462      }
463      else
464      {
465      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
466      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
467      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
468      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
469      }
470    }
471  }
472  else
473  {
474    rpcSlice->setDeblockingFilterOverrideFlag( false );
475    rpcSlice->setDeblockingFilterDisable( false );
476    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
477    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
478  }
479
480  rpcSlice->setDepth            ( depth );
481
482  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
483#if TEMP_SCALABILITY_FIX
484  if((eSliceType==I_SLICE) || (rpcSlice->getPOC() == 0))
485#else
486  if(eSliceType==I_SLICE)
487#endif
488  {
489    pcPic->setTLayer(0);
490  }
491  rpcSlice->setTLayer( pcPic->getTLayer() );
492
493  assert( m_apcPicYuvPred );
494  assert( m_apcPicYuvResi );
495
496  pcPic->setPicYuvPred( m_apcPicYuvPred );
497  pcPic->setPicYuvResi( m_apcPicYuvResi );
498  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
499  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
500  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
501  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
502  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
503  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
504
505#if SVC_EXTENSION
506  if( layerId > 0 )
507  {
508#if JCTVC_M0458_INTERLAYER_RPS_SIG
509    if( rpcSlice->getNumILRRefIdx() > 0 )
510    {
511      rpcSlice->setActiveNumILRRefIdx( m_ppcTEncTop[layerId]->getNumActiveRefLayers() );
512      for( Int i = 0; i < rpcSlice->getActiveNumILRRefIdx(); i++ )
513      {
514        rpcSlice->setInterLayerPredLayerIdc( m_ppcTEncTop[layerId]->getPredLayerId(i), i );
515      }
516      rpcSlice->setInterLayerPredEnabledFlag(1);
517    }
518#else
519    rpcSlice->setNumILRRefIdx( rpcSlice->getVPS()->getNumDirectRefLayers( layerId ) );
520#endif
521#if M0457_COL_PICTURE_SIGNALING
522    rpcSlice->setMFMEnabledFlag(m_ppcTEncTop[layerId]->getMFMEnabledFlag());
523#if !REMOVE_COL_PICTURE_SIGNALING
524    rpcSlice->setAltColIndicationFlag(rpcSlice->getMFMEnabledFlag());
525#endif
526#endif
527  }
528
529#endif
530}
531
532#if RATE_CONTROL_LAMBDA_DOMAIN
533Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
534{
535  TComSlice* slice = pic->getSlice(0);
536
537  // store lambda
538  slice->setSliceQp( sliceQP );
539  slice->setSliceQpBase ( sliceQP );
540  m_pcRdCost ->setLambda( lambda );
541#if WEIGHTED_CHROMA_DISTORTION
542  // for RDO
543  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
544  Double weight;
545  Int qpc;
546  Int chromaQPOffset;
547
548  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
549  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
550  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
551  m_pcRdCost->setCbDistortionWeight(weight);
552
553  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
554  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
555  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
556  m_pcRdCost->setCrDistortionWeight(weight);
557#endif
558
559#if RDOQ_CHROMA_LAMBDA
560  // for RDOQ
561  m_pcTrQuant->setLambda( lambda, lambda / weight );
562#else
563  m_pcTrQuant->setLambda( lambda );
564#endif
565
566#if SAO_CHROMA_LAMBDA
567  // For SAO
568  slice   ->setLambda( lambda, lambda / weight );
569#else
570  slice   ->setLambda( lambda );
571#endif
572}
573#else
574/**
575 - lambda re-computation based on rate control QP
576 */
577Void TEncSlice::xLamdaRecalculation(Int changeQP, Int idGOP, Int depth, SliceType eSliceType, TComSPS* pcSPS, TComSlice* pcSlice)
578{
579  Int qp;
580  Double recalQP= (Double)changeQP;
581  Double origQP = (Double)recalQP;
582  Double lambda;
583
584  // pre-compute lambda and QP values for all possible QP candidates
585  for ( Int deltqQpIdx = 0; deltqQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; deltqQpIdx++ )
586  {
587    // compute QP value
588    recalQP = origQP + ((deltqQpIdx+1)>>1)*(deltqQpIdx%2 ? -1 : 1);
589
590    // compute lambda value
591    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
592    Int    SHIFT_QP = 12;
593    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
594#if FULL_NBIT
595    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
596#else
597    Int    bitdepth_luma_qp_scale = 0;
598#endif
599    Double qp_temp = (Double) recalQP + bitdepth_luma_qp_scale - SHIFT_QP;
600#if FULL_NBIT
601    Double qp_temp_orig = (Double) recalQP - SHIFT_QP;
602#endif
603    // Case #1: I or P-slices (key-frame)
604    Double dQPFactor = m_pcCfg->getGOPEntry(idGOP).m_QPFactor;
605    if ( eSliceType==I_SLICE )
606    {
607      dQPFactor=0.57*dLambda_scale;
608    }
609    lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
610
611    if ( depth>0 )
612    {
613#if FULL_NBIT
614      lambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
615#else
616      lambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
617#endif
618    }
619
620    // if hadamard is used in ME process
621    if ( !m_pcCfg->getUseHADME() )
622    {
623      lambda *= 0.95;
624    }
625
626#if REPN_FORMAT_IN_VPS
627    qp = max( -pcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
628#else
629    qp = max( -pcSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
630#endif
631
632    m_pdRdPicLambda[deltqQpIdx] = lambda;
633    m_pdRdPicQp    [deltqQpIdx] = recalQP;
634    m_piRdPicQp    [deltqQpIdx] = qp;
635  }
636
637  // obtain dQP = 0 case
638  lambda  = m_pdRdPicLambda[0];
639  recalQP = m_pdRdPicQp    [0];
640  qp      = m_piRdPicQp    [0];
641
642  if( pcSlice->getSliceType( ) != I_SLICE )
643  {
644    lambda *= m_pcCfg->getLambdaModifier( depth );
645  }
646
647  // store lambda
648  m_pcRdCost ->setLambda( lambda );
649#if WEIGHTED_CHROMA_DISTORTION
650  // for RDO
651  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
652  Double weight = 1.0;
653  Int qpc;
654  Int chromaQPOffset;
655
656  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
657  qpc = Clip3( 0, 57, qp + chromaQPOffset);
658  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
659  m_pcRdCost->setCbDistortionWeight(weight);
660
661  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
662  qpc = Clip3( 0, 57, qp + chromaQPOffset);
663  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
664  m_pcRdCost->setCrDistortionWeight(weight);
665#endif
666
667#if RDOQ_CHROMA_LAMBDA
668  // for RDOQ
669  m_pcTrQuant->setLambda( lambda, lambda / weight );
670#else
671  m_pcTrQuant->setLambda( lambda );
672#endif
673
674#if SAO_CHROMA_LAMBDA
675  // For SAO
676  pcSlice   ->setLambda( lambda, lambda / weight );
677#else
678  pcSlice   ->setLambda( lambda );
679#endif
680}
681#endif
682// ====================================================================================================================
683// Public member functions
684// ====================================================================================================================
685
686Void TEncSlice::setSearchRange( TComSlice* pcSlice )
687{
688  Int iCurrPOC = pcSlice->getPOC();
689  Int iRefPOC;
690  Int iGOPSize = m_pcCfg->getGOPSize();
691  Int iOffset = (iGOPSize >> 1);
692  Int iMaxSR = m_pcCfg->getSearchRange();
693  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
694
695  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
696  {
697    //RefPicList e = (RefPicList)iDir;
698    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
699    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
700    {
701      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
702      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
703      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
704    }
705  }
706}
707
708/**
709 - multi-loop slice encoding for different slice QP
710 .
711 \param rpcPic    picture class
712 */
713Void TEncSlice::precompressSlice( TComPic*& rpcPic )
714{
715  // if deltaQP RD is not used, simply return
716  if ( m_pcCfg->getDeltaQpRD() == 0 )
717  {
718    return;
719  }
720
721#if RATE_CONTROL_LAMBDA_DOMAIN
722  if ( m_pcCfg->getUseRateCtrl() )
723  {
724    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
725    assert(0);
726  }
727#endif
728
729  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
730  Double     dPicRdCostBest = MAX_DOUBLE;
731  UInt       uiQpIdxBest = 0;
732
733  Double dFrameLambda;
734#if FULL_NBIT
735  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
736#else
737  Int    SHIFT_QP = 12;
738#endif
739
740  // set frame lambda
741  if (m_pcCfg->getGOPSize() > 1)
742  {
743    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
744  }
745  else
746  {
747    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
748  }
749  m_pcRdCost      ->setFrameLambda(dFrameLambda);
750
751  // for each QP candidate
752  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
753  {
754    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
755#if ADAPTIVE_QP_SELECTION
756    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
757#endif
758    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
759#if WEIGHTED_CHROMA_DISTORTION
760    // for RDO
761    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
762    Int iQP = m_piRdPicQp    [uiQpIdx];
763    Double weight = 1.0;
764    Int qpc;
765    Int chromaQPOffset;
766
767    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
768    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
769    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
770    m_pcRdCost->setCbDistortionWeight(weight);
771
772    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
773    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
774    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
775    m_pcRdCost->setCrDistortionWeight(weight);
776#endif
777
778#if RDOQ_CHROMA_LAMBDA
779    // for RDOQ
780    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
781#else
782    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
783#endif
784#if SAO_CHROMA_LAMBDA
785    // For SAO
786    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
787#else
788    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
789#endif
790
791    // try compress
792    compressSlice   ( rpcPic );
793
794    Double dPicRdCost;
795    UInt64 uiPicDist        = m_uiPicDist;
796    UInt64 uiALFBits        = 0;
797
798    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
799
800    // compute RD cost and choose the best
801    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
802
803    if ( dPicRdCost < dPicRdCostBest )
804    {
805      uiQpIdxBest    = uiQpIdx;
806      dPicRdCostBest = dPicRdCost;
807    }
808  }
809
810  // set best values
811  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
812#if ADAPTIVE_QP_SELECTION
813  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
814#endif
815  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
816#if WEIGHTED_CHROMA_DISTORTION
817  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
818  Int iQP = m_piRdPicQp    [uiQpIdxBest];
819  Double weight = 1.0;
820  Int qpc;
821  Int chromaQPOffset;
822
823  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
824  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
825  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
826  m_pcRdCost->setCbDistortionWeight(weight);
827
828  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
829  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
830  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
831  m_pcRdCost->setCrDistortionWeight(weight);
832#endif
833
834#if RDOQ_CHROMA_LAMBDA
835  // for RDOQ
836  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight );
837#else
838  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
839#endif
840#if SAO_CHROMA_LAMBDA
841  // For SAO
842  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight );
843#else
844  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
845#endif
846}
847
848/** \param rpcPic   picture class
849 */
850#if RATE_CONTROL_INTRA
851Void TEncSlice::calCostSliceI(TComPic*& rpcPic)
852{
853  UInt    uiCUAddr;
854  UInt    uiStartCUAddr;
855  UInt    uiBoundingCUAddr;
856  Int     iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;;
857  Double  iSumHadSlice = 0;
858
859  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
860  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
861  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
862
863  UInt uiEncCUOrder;
864  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
865  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
866       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
867       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
868  {
869    // initialize CU encoder
870    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
871    pcCU->initCU( rpcPic, uiCUAddr );
872
873#if REPN_FORMAT_IN_VPS
874    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
875    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(), pcSlice->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
876#else
877    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
878    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
879#endif
880
881    iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height);
882
883    (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift;
884    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra;
885
886  }
887  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
888}
889#endif
890
891Void TEncSlice::compressSlice( TComPic*& rpcPic )
892{
893  UInt  uiCUAddr;
894  UInt   uiStartCUAddr;
895  UInt   uiBoundingCUAddr;
896  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
897  TEncBinCABAC* pppcRDSbacCoder = NULL;
898  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
899  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
900
901  // initialize cost values
902  m_uiPicTotalBits  = 0;
903  m_dPicRdCost      = 0;
904  m_uiPicDist       = 0;
905
906  // set entropy coder
907  if( m_pcCfg->getUseSBACRD() )
908  {
909    m_pcSbacCoder->init( m_pcBinCABAC );
910    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
911    m_pcEntropyCoder->resetEntropy      ();
912    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
913    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
914    pppcRDSbacCoder->setBinCountingEnableFlag( false );
915    pppcRDSbacCoder->setBinsCoded( 0 );
916  }
917  else
918  {
919    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
920    m_pcEntropyCoder->resetEntropy      ();
921    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
922  }
923
924  //------------------------------------------------------------------------------
925  //  Weighted Prediction parameters estimation.
926  //------------------------------------------------------------------------------
927  // calculate AC/DC values for current picture
928  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
929  {
930    xCalcACDCParamSlice(pcSlice);
931  }
932#if O0194_WEIGHTED_PREDICTION_CGS
933  else{
934    // Calculate for the base layer to be used in EL as Inter layer reference
935    xCalcACDCParamSlice(pcSlice);
936    wpACDCParam * temp_weightACDCParam;
937
938    pcSlice->getWpAcDcParam(temp_weightACDCParam);
939    g_refWeightACDCParam = (void *) temp_weightACDCParam;
940  }
941#endif
942
943  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
944
945  if ( bWp_explicit )
946  {
947    //------------------------------------------------------------------------------
948    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
949    //------------------------------------------------------------------------------
950    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
951    {
952      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
953    }
954
955    xEstimateWPParamSlice( pcSlice );
956    pcSlice->initWpScaling();
957
958    // check WP on/off
959    xCheckWPEnable( pcSlice );
960  }
961
962#if ADAPTIVE_QP_SELECTION
963  if( m_pcCfg->getUseAdaptQpSelect() )
964  {
965    m_pcTrQuant->clearSliceARLCnt();
966    if(pcSlice->getSliceType()!=I_SLICE)
967    {
968      Int qpBase = pcSlice->getSliceQpBase();
969      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
970    }
971  }
972#endif
973  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
974  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
975  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
976  Int  iNumSubstreams = 1;
977  UInt uiTilesAcross  = 0;
978
979  if( m_pcCfg->getUseSBACRD() )
980  {
981    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
982    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
983    delete[] m_pcBufferSbacCoders;
984    delete[] m_pcBufferBinCoderCABACs;
985    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
986    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
987    for (Int ui = 0; ui < uiTilesAcross; ui++)
988    {
989      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
990    }
991    for (UInt ui = 0; ui < uiTilesAcross; ui++)
992    {
993      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
994    }
995
996    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
997    {
998      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
999    }
1000  }
1001  //if( m_pcCfg->getUseSBACRD() )
1002  {
1003    delete[] m_pcBufferLowLatSbacCoders;
1004    delete[] m_pcBufferLowLatBinCoderCABACs;
1005    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
1006    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
1007    for (Int ui = 0; ui < uiTilesAcross; ui++)
1008    {
1009      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
1010    }
1011    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1012      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
1013  }
1014  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1015  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
1016  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1017  UInt uiTileCol      = 0;
1018  UInt uiTileStartLCU = 0;
1019  UInt uiTileLCUX     = 0;
1020
1021  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1022  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
1023  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1024  if( depSliceSegmentsEnabled )
1025  {
1026    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
1027    {
1028      if( m_pcCfg->getWaveFrontsynchro() )
1029      {
1030        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1031        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1032        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1033        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
1034        uiLin     = uiCUAddr / uiWidthInLCUs;
1035        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
1036          + uiLin%iNumSubstreamsPerTile;
1037        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1038        {
1039          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1040          uiCol     = uiCUAddr % uiWidthInLCUs;
1041          if(uiCol==uiTileStartLCU)
1042          {
1043            CTXMem[0]->loadContexts(m_pcSbacCoder);
1044          }
1045        }
1046      }
1047      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1048      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1049    }
1050    else
1051    {
1052      if(m_pcCfg->getWaveFrontsynchro())
1053      {
1054        CTXMem[1]->loadContexts(m_pcSbacCoder);
1055      }
1056      CTXMem[0]->loadContexts(m_pcSbacCoder);
1057    }
1058  }
1059  // for every CU in slice
1060  UInt uiEncCUOrder;
1061  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1062       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1063       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1064  {
1065    // initialize CU encoder
1066    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1067    pcCU->initCU( rpcPic, uiCUAddr );
1068
1069#if !RATE_CONTROL_LAMBDA_DOMAIN
1070    if(m_pcCfg->getUseRateCtrl())
1071    {
1072      if(m_pcRateCtrl->calculateUnitQP())
1073      {
1074        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
1075      }
1076    }
1077#endif
1078    // inherit from TR if necessary, select substream to use.
1079    if( m_pcCfg->getUseSBACRD() )
1080    {
1081      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1082      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1083      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1084      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1085      uiCol     = uiCUAddr % uiWidthInLCUs;
1086      uiLin     = uiCUAddr / uiWidthInLCUs;
1087      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1088      {
1089        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1090        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1091        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1092                      + uiLin%iNumSubstreamsPerTile;
1093      }
1094      else
1095      {
1096        // dependent tiles => substreams are "per frame".
1097        uiSubStrm = uiLin % iNumSubstreams;
1098      }
1099      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1100      {
1101        // We'll sync if the TR is available.
1102        TComDataCU *pcCUUp = pcCU->getCUAbove();
1103        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1104        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1105        TComDataCU *pcCUTR = NULL;
1106        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1107        {
1108          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1109        }
1110        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
1111             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1112             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1113             )
1114           )
1115        {
1116          // TR not available.
1117        }
1118        else
1119        {
1120          // TR is available, we use it.
1121          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1122        }
1123      }
1124      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1125    }
1126
1127    // reset the entropy coder
1128    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1129        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1130        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1131        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1132    {
1133      SliceType sliceType = pcSlice->getSliceType();
1134      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1135      {
1136        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1137      }
1138      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1139      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1140      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1141      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1142    }
1143    // if RD based on SBAC is used
1144    if( m_pcCfg->getUseSBACRD() )
1145    {
1146      // set go-on entropy coder
1147      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1148      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1149
1150      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1151
1152#if RATE_CONTROL_LAMBDA_DOMAIN
1153      Double oldLambda = m_pcRdCost->getLambda();
1154      if ( m_pcCfg->getUseRateCtrl() )
1155      {
1156        Int estQP        = pcSlice->getSliceQp();
1157        Double estLambda = -1.0;
1158        Double bpp       = -1.0;
1159
1160#if M0036_RC_IMPROVEMENT
1161        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1162#else
1163        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1164#endif
1165        {
1166          estQP = pcSlice->getSliceQp();
1167        }
1168        else
1169        {
1170#if RATE_CONTROL_INTRA
1171          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1172          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1173          {
1174            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1175          }
1176          else
1177          {
1178            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1179            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1180          }
1181#else
1182          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1183          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1184          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1185#endif
1186
1187#if REPN_FORMAT_IN_VPS
1188          estQP     = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, estQP );
1189#else
1190          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1191#endif
1192
1193          m_pcRdCost->setLambda(estLambda);
1194#if M0036_RC_IMPROVEMENT
1195#if RDOQ_CHROMA_LAMBDA
1196          // set lambda for RDOQ
1197          Double weight=m_pcRdCost->getChromaWeight();
1198          m_pcTrQuant->setLambda( estLambda, estLambda / weight );
1199#else
1200          m_pcTrQuant->setLambda( estLambda );
1201#endif
1202#endif
1203        }
1204
1205        m_pcRateCtrl->setRCQP( estQP );
1206        pcCU->getSlice()->setSliceQpBase( estQP );
1207      }
1208#endif
1209
1210      // run CU encoder
1211      m_pcCuEncoder->compressCU( pcCU );
1212
1213#if !TICKET_1090_FIX
1214#if RATE_CONTROL_LAMBDA_DOMAIN
1215      if ( m_pcCfg->getUseRateCtrl() )
1216      {
1217#if !M0036_RC_IMPROVEMENT
1218        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1219#if REPN_FORMAT_IN_VPS
1220        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1221        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->>getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1222#else
1223        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1224        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1225#endif
1226        Double MAD = (Double)SAD / (Double)(height * width);
1227        MAD = MAD * MAD;
1228        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1229#endif
1230
1231        Int actualQP        = g_RCInvalidQPValue;
1232        Double actualLambda = m_pcRdCost->getLambda();
1233        Int actualBits      = pcCU->getTotalBits();
1234        Int numberOfEffectivePixels    = 0;
1235        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1236        {
1237          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1238          {
1239            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1240            break;
1241          }
1242        }
1243
1244        if ( numberOfEffectivePixels == 0 )
1245        {
1246          actualQP = g_RCInvalidQPValue;
1247        }
1248        else
1249        {
1250          actualQP = pcCU->getQP( 0 );
1251        }
1252        m_pcRdCost->setLambda(oldLambda);
1253#if RATE_CONTROL_INTRA
1254        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
1255          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1256#else
1257        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1258#endif
1259      }
1260#endif
1261#endif
1262
1263      // restore entropy coder to an initial stage
1264      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1265      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1266      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1267      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1268      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1269      m_pcBitCounter->resetBits();
1270      pppcRDSbacCoder->setBinsCoded( 0 );
1271      m_pcCuEncoder->encodeCU( pcCU );
1272
1273      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1274      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1275      {
1276        pcSlice->setNextSlice( true );
1277        break;
1278      }
1279      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1280      {
1281        pcSlice->setNextSliceSegment( true );
1282        break;
1283      }
1284      if( m_pcCfg->getUseSBACRD() )
1285      {
1286         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1287
1288         //Store probabilties of second LCU in line into buffer
1289         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1290        {
1291          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1292        }
1293      }
1294
1295#if TICKET_1090_FIX
1296#if RATE_CONTROL_LAMBDA_DOMAIN
1297      if ( m_pcCfg->getUseRateCtrl() )
1298      {
1299#if !M0036_RC_IMPROVEMENT
1300        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1301#if REPN_FORMAT_IN_VPS
1302        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1303        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1304#else
1305        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1306        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1307#endif
1308        Double MAD = (Double)SAD / (Double)(height * width);
1309        MAD = MAD * MAD;
1310        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1311#endif
1312
1313        Int actualQP        = g_RCInvalidQPValue;
1314        Double actualLambda = m_pcRdCost->getLambda();
1315        Int actualBits      = pcCU->getTotalBits();
1316        Int numberOfEffectivePixels    = 0;
1317        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1318        {
1319          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1320          {
1321            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1322            break;
1323          }
1324        }
1325
1326        if ( numberOfEffectivePixels == 0 )
1327        {
1328          actualQP = g_RCInvalidQPValue;
1329        }
1330        else
1331        {
1332          actualQP = pcCU->getQP( 0 );
1333        }
1334        m_pcRdCost->setLambda(oldLambda);
1335
1336#if RATE_CONTROL_INTRA
1337        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
1338          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1339#else
1340        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1341#endif
1342      }
1343#endif
1344#endif
1345    }
1346    // other case: encodeCU is not called
1347    else
1348    {
1349      m_pcCuEncoder->compressCU( pcCU );
1350      m_pcCuEncoder->encodeCU( pcCU );
1351      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1352      {
1353        pcSlice->setNextSlice( true );
1354        break;
1355      }
1356      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1357      {
1358        pcSlice->setNextSliceSegment( true );
1359        break;
1360      }
1361    }
1362
1363    m_uiPicTotalBits += pcCU->getTotalBits();
1364    m_dPicRdCost     += pcCU->getTotalCost();
1365    m_uiPicDist      += pcCU->getTotalDistortion();
1366#if !RATE_CONTROL_LAMBDA_DOMAIN
1367    if(m_pcCfg->getUseRateCtrl())
1368    {
1369      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1370      m_pcRateCtrl->updataRCUnitStatus();
1371    }
1372#endif
1373  }
1374  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1375  {
1376    pcSlice->setNextSlice( true );
1377  }
1378  if( depSliceSegmentsEnabled )
1379  {
1380    if (m_pcCfg->getWaveFrontsynchro())
1381    {
1382      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1383    }
1384     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1385  }
1386  xRestoreWPparam( pcSlice );
1387#if !RATE_CONTROL_LAMBDA_DOMAIN
1388  if(m_pcCfg->getUseRateCtrl())
1389  {
1390    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1391  }
1392#endif
1393}
1394
1395/**
1396 \param  rpcPic        picture class
1397 \retval rpcBitstream  bitstream class
1398 */
1399Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1400{
1401  UInt       uiCUAddr;
1402  UInt       uiStartCUAddr;
1403  UInt       uiBoundingCUAddr;
1404  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1405
1406  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1407  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1408  // choose entropy coder
1409  {
1410    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1411    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1412  }
1413
1414  m_pcCuEncoder->setBitCounter( NULL );
1415  m_pcBitCounter = NULL;
1416  // Appropriate substream bitstream is switched later.
1417  // for every CU
1418#if ENC_DEC_TRACE
1419  g_bJustDoIt = g_bEncDecTraceEnable;
1420#endif
1421  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1422  DTRACE_CABAC_T( "\tPOC: " );
1423  DTRACE_CABAC_V( rpcPic->getPOC() );
1424  DTRACE_CABAC_T( "\n" );
1425#if ENC_DEC_TRACE
1426  g_bJustDoIt = g_bEncDecTraceDisable;
1427#endif
1428
1429  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1430  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1431  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1432  UInt uiBitsOriginallyInSubstreams = 0;
1433  {
1434    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1435    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1436    {
1437      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1438    }
1439
1440    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1441    {
1442      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1443    }
1444
1445    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1446    {
1447      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1448    }
1449  }
1450
1451  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1452  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1453  UInt uiTileCol      = 0;
1454  UInt uiTileStartLCU = 0;
1455  UInt uiTileLCUX     = 0;
1456  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1457  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1458                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1459                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1460  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1461  if( depSliceSegmentsEnabled )
1462  {
1463    if( pcSlice->isNextSlice()||
1464        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1465    {
1466      if(m_pcCfg->getWaveFrontsynchro())
1467      {
1468        CTXMem[1]->loadContexts(m_pcSbacCoder);
1469      }
1470      CTXMem[0]->loadContexts(m_pcSbacCoder);
1471    }
1472    else
1473    {
1474      if(m_pcCfg->getWaveFrontsynchro())
1475      {
1476        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1477        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1478        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1479        uiLin     = uiCUAddr / uiWidthInLCUs;
1480        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1481          + uiLin%iNumSubstreamsPerTile;
1482        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1483        {
1484          uiCol     = uiCUAddr % uiWidthInLCUs;
1485          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1486          if(uiCol==uiTileLCUX)
1487          {
1488            CTXMem[0]->loadContexts(m_pcSbacCoder);
1489          }
1490        }
1491      }
1492      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1493    }
1494  }
1495
1496  UInt uiEncCUOrder;
1497  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1498       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1499       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1500  {
1501    if( m_pcCfg->getUseSBACRD() )
1502    {
1503      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1504      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1505      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1506      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1507      uiCol     = uiCUAddr % uiWidthInLCUs;
1508      uiLin     = uiCUAddr / uiWidthInLCUs;
1509      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1510      {
1511        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1512        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1513        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1514                      + uiLin%iNumSubstreamsPerTile;
1515      }
1516      else
1517      {
1518        // dependent tiles => substreams are "per frame".
1519        uiSubStrm = uiLin % iNumSubstreams;
1520      }
1521
1522      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1523      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1524      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1525      {
1526        // We'll sync if the TR is available.
1527        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1528        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1529        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1530        TComDataCU *pcCUTR = NULL;
1531        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1532        {
1533          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1534        }
1535        if ( (true/*bEnforceSliceRestriction*/ &&
1536             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
1537             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1538             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1539             ))
1540           )
1541        {
1542          // TR not available.
1543        }
1544        else
1545        {
1546          // TR is available, we use it.
1547          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1548        }
1549      }
1550      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1551    }
1552    // reset the entropy coder
1553    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1554        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1555        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1556        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1557    {
1558      {
1559        // We're crossing into another tile, tiles are independent.
1560        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1561        // have to perform it here.
1562        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1563        {
1564          ; // do nothing.
1565        }
1566        else
1567        {
1568          SliceType sliceType  = pcSlice->getSliceType();
1569          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1570          {
1571            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1572          }
1573          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1574          // Byte-alignment in slice_data() when new tile
1575          pcSubstreams[uiSubStrm].writeByteAlignment();
1576        }
1577      }
1578      {
1579        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1580        UInt uiAccumulatedSubstreamLength = 0;
1581        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1582        {
1583          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1584        }
1585        // add bits coded in previous dependent slices + bits coded so far
1586        // add number of emulation prevention byte count in the tile
1587        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1588      }
1589    }
1590
1591    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1592    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1593    {
1594      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1595      Int iNumCuInWidth     = saoParam->numCuInWidth;
1596      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1597      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1598      Int rx = uiCUAddr % iNumCuInWidth;
1599      Int ry = uiCUAddr / iNumCuInWidth;
1600      Int allowMergeLeft = 1;
1601      Int allowMergeUp   = 1;
1602      if (rx!=0)
1603      {
1604        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1605        {
1606          allowMergeLeft = 0;
1607        }
1608      }
1609      if (ry!=0)
1610      {
1611        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1612        {
1613          allowMergeUp = 0;
1614        }
1615      }
1616      Int addr = pcCU->getAddr();
1617      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1618      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1619      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1620      {
1621        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1622        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1623        if (allowMergeLeft)
1624        {
1625          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft);
1626        }
1627        else
1628        {
1629          mergeLeft = 0;
1630        }
1631        if(mergeLeft == 0)
1632        {
1633          if (allowMergeUp)
1634          {
1635            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1636          }
1637          else
1638          {
1639            mergeUp = 0;
1640          }
1641          if(mergeUp == 0)
1642          {
1643            for (Int compIdx=0;compIdx<3;compIdx++)
1644            {
1645            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1646              {
1647                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1648              }
1649            }
1650          }
1651        }
1652      }
1653    }
1654    else if (pcSlice->getSPS()->getUseSAO())
1655    {
1656      Int addr = pcCU->getAddr();
1657      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1658      for (Int cIdx=0; cIdx<3; cIdx++)
1659      {
1660        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1661        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1662        {
1663          saoLcuParam->mergeUpFlag   = 0;
1664          saoLcuParam->mergeLeftFlag = 0;
1665          saoLcuParam->subTypeIdx    = 0;
1666          saoLcuParam->typeIdx       = -1;
1667          saoLcuParam->offset[0]     = 0;
1668          saoLcuParam->offset[1]     = 0;
1669          saoLcuParam->offset[2]     = 0;
1670          saoLcuParam->offset[3]     = 0;
1671        }
1672      }
1673    }
1674#if ENC_DEC_TRACE
1675    g_bJustDoIt = g_bEncDecTraceEnable;
1676#endif
1677    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1678      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1679    {
1680      m_pcCuEncoder->encodeCU( pcCU );
1681    }
1682    else
1683    {
1684      m_pcCuEncoder->encodeCU( pcCU );
1685    }
1686#if ENC_DEC_TRACE
1687    g_bJustDoIt = g_bEncDecTraceDisable;
1688#endif
1689    if( m_pcCfg->getUseSBACRD() )
1690    {
1691       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1692
1693
1694       //Store probabilties of second LCU in line into buffer
1695       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1696      {
1697        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1698      }
1699    }
1700  }
1701  if( depSliceSegmentsEnabled )
1702  {
1703    if (m_pcCfg->getWaveFrontsynchro())
1704    {
1705      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1706    }
1707    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1708  }
1709#if ADAPTIVE_QP_SELECTION
1710  if( m_pcCfg->getUseAdaptQpSelect() )
1711  {
1712    m_pcTrQuant->storeSliceQpNext(pcSlice);
1713  }
1714#endif
1715  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1716  {
1717    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1718    {
1719      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1720    }
1721    else
1722    {
1723      m_pcEntropyCoder->determineCabacInitIdx();
1724    }
1725  }
1726}
1727
1728/** Determines the starting and bounding LCU address of current slice / dependent slice
1729 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1730 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1731 */
1732Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1733{
1734  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1735  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1736  UInt tileIdxIncrement;
1737  UInt tileIdx;
1738  UInt tileWidthInLcu;
1739  UInt tileHeightInLcu;
1740  UInt tileTotalCount;
1741
1742  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1743  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1744  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1745  if (bEncodeSlice)
1746  {
1747    UInt uiCUAddrIncrement;
1748    switch (m_pcCfg->getSliceMode())
1749    {
1750    case FIXED_NUMBER_OF_LCU:
1751      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1752      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1753      break;
1754    case FIXED_NUMBER_OF_BYTES:
1755      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1756      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1757      break;
1758    case FIXED_NUMBER_OF_TILES:
1759      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1760        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1761        );
1762      uiCUAddrIncrement        = 0;
1763      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1764
1765      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1766      {
1767        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1768        {
1769          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1770          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1771          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1772        }
1773      }
1774
1775      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1776      break;
1777    default:
1778      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1779      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1780      break;
1781    }
1782    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1783    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1784    {
1785      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1786    }
1787    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1788  }
1789  else
1790  {
1791    UInt uiCUAddrIncrement     ;
1792    switch (m_pcCfg->getSliceMode())
1793    {
1794    case FIXED_NUMBER_OF_LCU:
1795      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1796      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1797      break;
1798    case FIXED_NUMBER_OF_TILES:
1799      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1800        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1801        );
1802      uiCUAddrIncrement        = 0;
1803      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1804
1805      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1806      {
1807        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1808        {
1809          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1810          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1811          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1812        }
1813      }
1814
1815      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1816      break;
1817    default:
1818      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1819      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1820      break;
1821    }
1822    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1823    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1824    {
1825      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1826    }
1827    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1828  }
1829
1830  Bool tileBoundary = false;
1831  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) &&
1832      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1833  {
1834    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1835    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1836    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1837    UInt tileBoundingCUAddrSlice = 0;
1838    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1839    {
1840      lcuEncAddr++;
1841      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1842    }
1843    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1844
1845    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1846    {
1847      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1848      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1849      tileBoundary = true;
1850    }
1851  }
1852
1853  // Dependent slice
1854  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1855  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1856  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1857  if (bEncodeSlice)
1858  {
1859    UInt uiCUAddrIncrement;
1860    switch (m_pcCfg->getSliceSegmentMode())
1861    {
1862    case FIXED_NUMBER_OF_LCU:
1863      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1864      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1865      break;
1866    case FIXED_NUMBER_OF_BYTES:
1867      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1868      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1869      break;
1870    case FIXED_NUMBER_OF_TILES:
1871      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1872        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1873        );
1874      uiCUAddrIncrement        = 0;
1875      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1876
1877      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1878      {
1879        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1880        {
1881          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1882          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1883          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1884        }
1885      }
1886      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1887      break;
1888    default:
1889      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1890      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1891      break;
1892    }
1893    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1894    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1895    {
1896      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1897    }
1898    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1899  }
1900  else
1901  {
1902    UInt uiCUAddrIncrement;
1903    switch (m_pcCfg->getSliceSegmentMode())
1904    {
1905    case FIXED_NUMBER_OF_LCU:
1906      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1907      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1908      break;
1909    case FIXED_NUMBER_OF_TILES:
1910      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1911        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1912        );
1913      uiCUAddrIncrement        = 0;
1914      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1915
1916      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1917      {
1918        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1919        {
1920          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1921          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1922          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1923        }
1924      }
1925      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1926      break;
1927    default:
1928      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1929      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1930      break;
1931    }
1932    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1933    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1934    {
1935      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1936    }
1937    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1938  }
1939  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) &&
1940    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1941  {
1942    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1943    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1944    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1945    UInt tileBoundingCUAddrSlice = 0;
1946    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1947    {
1948      lcuEncAddr++;
1949      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1950    }
1951    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1952
1953    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1954    {
1955      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1956      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1957      tileBoundary = true;
1958    }
1959  }
1960
1961  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1962  {
1963    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1964    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1965  }
1966
1967  //calculate real dependent slice start address
1968  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1969  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1970  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1971  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1972#if REPN_FORMAT_IN_VPS
1973  UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
1974  UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
1975#else
1976  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1977  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1978#endif
1979  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1980  {
1981    uiInternalAddress++;
1982    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1983    {
1984      uiInternalAddress=0;
1985      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1986    }
1987    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1988    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1989  }
1990  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1991
1992  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1993  startCUAddrSliceSegment=uiRealStartAddress;
1994
1995  //calculate real slice start address
1996  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1997  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1998  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1999  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2000#if REPN_FORMAT_IN_VPS
2001  uiWidth = pcSlice->getPicWidthInLumaSamples();
2002  uiHeight = pcSlice->getPicHeightInLumaSamples();
2003#else
2004  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
2005  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
2006#endif
2007  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
2008  {
2009    uiInternalAddress++;
2010    if(uiInternalAddress>=rpcPic->getNumPartInCU())
2011    {
2012      uiInternalAddress=0;
2013      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
2014    }
2015    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2016    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2017  }
2018  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
2019
2020  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
2021  uiStartCUAddrSlice=uiRealStartAddress;
2022
2023  // Make a joint decision based on reconstruction and dependent slice bounds
2024  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
2025  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
2026
2027
2028  if (!bEncodeSlice)
2029  {
2030    // For fixed number of LCU within an entropy and reconstruction slice we already know whether we will encounter end of entropy and/or reconstruction slice
2031    // first. Set the flags accordingly.
2032    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2033      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2034      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0)
2035      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2036      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0)
2037      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
2038      || tileBoundary
2039)
2040    {
2041      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
2042      {
2043        pcSlice->setNextSlice       ( true );
2044        pcSlice->setNextSliceSegment( false );
2045      }
2046      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
2047      {
2048        pcSlice->setNextSlice       ( false );
2049        pcSlice->setNextSliceSegment( true );
2050      }
2051      else
2052      {
2053        pcSlice->setNextSlice       ( true );
2054        pcSlice->setNextSliceSegment( true );
2055      }
2056    }
2057    else
2058    {
2059      pcSlice->setNextSlice       ( false );
2060      pcSlice->setNextSliceSegment( false );
2061    }
2062  }
2063}
2064
2065Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
2066{
2067  return 4.2005*log(lambda) + 13.7122;
2068}
2069
2070#if JCTVC_M0259_LAMBDAREFINEMENT
2071Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
2072{
2073  double tmp = beta * pow( 2.0 , deltaQP / 6 );
2074  double gamma = tmp / ( tmp + 1 );
2075  return( gamma );
2076}
2077#endif
2078//! \}
Note: See TracBrowser for help on using the repository browser.