source: 3DVCSoftware/branches/HTM-DEV-0.1-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 367

Last change on this file since 367 was 367, checked in by tech, 11 years ago

Further minor cleanups.

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