source: 3DVCSoftware/branches/HTM-13.1-dev0/source/Lib/TLibEncoder/TEncSlice.cpp @ 1314

Last change on this file since 1314 was 1175, checked in by tech, 10 years ago

Added direct dependency type for qtl.
Updated cfg files.
updated copy right headers.

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