source: 3DVCSoftware/branches/HTM-12.2-dev2-Samsung/source/Lib/TLibEncoder/TEncSlice.cpp @ 1417

Last change on this file since 1417 was 1100, checked in by samsung-htm, 10 years ago

Integration of JCT3V-J0037 (Item1 and Item4)

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