source: SHVCSoftware/branches/SHM-3.0-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 323

Last change on this file since 323 was 321, checked in by seregin, 12 years ago

remove INTRA_BL

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