source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 125

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

copy from HM-10.0-dev-SHM

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