source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 980

Last change on this file since 980 was 976, checked in by tech, 10 years ago
  • Merged 11.1-dev0@975. (Clean ups)
  • Added coding results.
  • Changed version number.
  • 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-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  // for every CU in slice
1014#if H_3D
1015  Int iLastPosY = -1;
1016#endif
1017  UInt uiEncCUOrder;
1018  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1019       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1020       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1021  {
1022    // initialize CU encoder
1023    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1024    pcCU->initCU( rpcPic, uiCUAddr );
1025#if H_3D_VSO
1026    if ( m_pcRdCost->getUseRenModel() )
1027    {
1028      // updated renderer model if necessary
1029      Int iCurPosX;
1030      Int iCurPosY; 
1031      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
1032      if ( iCurPosY != iLastPosY )
1033      {
1034        iLastPosY = iCurPosY;         
1035        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY );
1036      }
1037    }
1038#endif
1039    // inherit from TR if necessary, select substream to use.
1040      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1041      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1042      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1043      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1044      uiCol     = uiCUAddr % uiWidthInLCUs;
1045      uiLin     = uiCUAddr / uiWidthInLCUs;
1046      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1047      {
1048        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1049        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1050        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1051                      + uiLin%iNumSubstreamsPerTile;
1052      }
1053      else
1054      {
1055        // dependent tiles => substreams are "per frame".
1056        uiSubStrm = uiLin % iNumSubstreams;
1057      }
1058      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1059      {
1060        // We'll sync if the TR is available.
1061        TComDataCU *pcCUUp = pcCU->getCUAbove();
1062        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1063        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1064        TComDataCU *pcCUTR = NULL;
1065        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1066        {
1067          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1068        }
1069        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1070             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1071             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1072             )
1073           )
1074        {
1075          // TR not available.
1076        }
1077        else
1078        {
1079          // TR is available, we use it.
1080          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1081        }
1082      }
1083      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1084
1085    // reset the entropy coder
1086    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1087        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1088        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1089        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1090    {
1091      SliceType sliceType = pcSlice->getSliceType();
1092      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1093      {
1094        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1095      }
1096      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1097      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1098      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1099      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1100    }
1101
1102      // set go-on entropy coder
1103      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1104      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1105     
1106      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1107
1108      Double oldLambda = m_pcRdCost->getLambda();
1109      if ( m_pcCfg->getUseRateCtrl() )
1110      {
1111        Int estQP        = pcSlice->getSliceQp();
1112        Double estLambda = -1.0;
1113        Double bpp       = -1.0;
1114
1115        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1116        {
1117          estQP = pcSlice->getSliceQp();
1118        }
1119        else
1120        {
1121#if KWU_RC_MADPRED_E0227
1122          if(pcSlice->getLayerId() != 0 && m_pcCfg->getUseDepthMADPred() && !pcSlice->getIsDepth())
1123          {
1124            Double zn, zf, focallength, position, camShift;
1125            Double basePos;
1126            Bool bInterpolated;
1127            Int direction = pcSlice->getViewId() - pcCU->getSlice()->getIvPic(false, 0)->getViewId();
1128            Int disparity;
1129
1130            pcEncTop->getCamParam()->xGetZNearZFar(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), zn, zf);
1131            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[0], pcSlice->getPOC(), focallength, basePos, camShift, bInterpolated);
1132            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), focallength, position, camShift, bInterpolated);
1133            bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBppforInterView( m_pcRateCtrl->getPicList(), pcCU,
1134              basePos, position, focallength, zn, zf, (direction > 0 ? 1 : -1), &disparity );
1135          }
1136          else
1137          {
1138#endif
1139          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1140          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1141          {
1142            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1143          }
1144          else
1145          {
1146            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1147            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1148          }
1149#if KWU_RC_MADPRED_E0227
1150          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1151          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1152#endif
1153          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1154
1155          m_pcRdCost->setLambda(estLambda);
1156#if RDOQ_CHROMA_LAMBDA
1157          // set lambda for RDOQ
1158          Double weight=m_pcRdCost->getChromaWeight();
1159        const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
1160        m_pcTrQuant->setLambdas( lambdaArray );
1161#else
1162          m_pcTrQuant->setLambda( estLambda );
1163#endif
1164        }
1165
1166        m_pcRateCtrl->setRCQP( estQP );
1167#if ADAPTIVE_QP_SELECTION
1168        pcCU->getSlice()->setSliceQpBase( estQP );
1169#endif
1170      }
1171
1172      // run CU encoder
1173      m_pcCuEncoder->compressCU( pcCU );
1174
1175      // restore entropy coder to an initial stage
1176      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1177      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1178      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1179      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1180      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1181      m_pcBitCounter->resetBits();
1182      pppcRDSbacCoder->setBinsCoded( 0 );
1183      m_pcCuEncoder->encodeCU( pcCU );
1184
1185      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1186      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1187      {
1188        pcSlice->setNextSlice( true );
1189        break;
1190      }
1191      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1192      {
1193        pcSlice->setNextSliceSegment( true );
1194        break;
1195      }
1196       
1197    ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1198         //Store probabilties of second LCU in line into buffer
1199         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1200        {
1201          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1202        }
1203
1204      if ( m_pcCfg->getUseRateCtrl() )
1205      {
1206#if KWU_RC_MADPRED_E0227
1207        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1208        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1209        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1210        Double MAD = (Double)SAD / (Double)(height * width);
1211        MAD = MAD * MAD;
1212        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1213#endif
1214
1215        Int actualQP        = g_RCInvalidQPValue;
1216        Double actualLambda = m_pcRdCost->getLambda();
1217        Int actualBits      = pcCU->getTotalBits();
1218        Int numberOfEffectivePixels    = 0;
1219        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1220        {
1221          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1222          {
1223            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1224            break;
1225          }
1226        }
1227
1228        if ( numberOfEffectivePixels == 0 )
1229        {
1230          actualQP = g_RCInvalidQPValue;
1231        }
1232        else
1233        {
1234          actualQP = pcCU->getQP( 0 );
1235        }
1236        m_pcRdCost->setLambda(oldLambda);
1237
1238        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1239          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1240    }
1241   
1242    m_uiPicTotalBits += pcCU->getTotalBits();
1243    m_dPicRdCost     += pcCU->getTotalCost();
1244    m_uiPicDist      += pcCU->getTotalDistortion();
1245  }
1246  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1247  {
1248    pcSlice->setNextSlice( true );
1249  }
1250  if(m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES || m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES)
1251  {
1252    if(pcSlice->getSliceCurEndCUAddr()<=pcSlice->getSliceSegmentCurEndCUAddr())
1253    {
1254       pcSlice->setNextSlice( true );
1255    }
1256    else
1257    {
1258       pcSlice->setNextSliceSegment( true );
1259    }
1260  }
1261  if( depSliceSegmentsEnabled )
1262  {
1263    if (m_pcCfg->getWaveFrontsynchro())
1264    {
1265      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1266    }
1267     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1268  }
1269  xRestoreWPparam( pcSlice );
1270}
1271
1272/**
1273 \param  rpcPic        picture class
1274 \retval rpcBitstream  bitstream class
1275 */
1276Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1277{
1278  UInt       uiCUAddr;
1279  UInt       uiStartCUAddr;
1280  UInt       uiBoundingCUAddr;
1281  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1282
1283  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1284  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1285  // choose entropy coder
1286  {
1287    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1288    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1289  }
1290 
1291  m_pcCuEncoder->setBitCounter( NULL );
1292  m_pcBitCounter = NULL;
1293  // Appropriate substream bitstream is switched later.
1294  // for every CU
1295#if ENC_DEC_TRACE
1296  g_bJustDoIt = g_bEncDecTraceEnable;
1297#endif
1298  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1299  DTRACE_CABAC_T( "\tPOC: " );
1300  DTRACE_CABAC_V( rpcPic->getPOC() );
1301#if H_MV_ENC_DEC_TRAC
1302  DTRACE_CABAC_T( " Layer: " );
1303  DTRACE_CABAC_V( rpcPic->getLayerId() );
1304#endif
1305  DTRACE_CABAC_T( "\n" );
1306#if ENC_DEC_TRACE
1307  g_bJustDoIt = g_bEncDecTraceDisable;
1308#endif
1309
1310  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1311  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1312  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1313  UInt uiBitsOriginallyInSubstreams = 0;
1314  {
1315    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1316    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1317    {
1318      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1319    }
1320   
1321    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1322    {
1323      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1324    }
1325
1326    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1327    {
1328      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1329    }
1330  }
1331
1332  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1333  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1334  UInt uiTileCol      = 0;
1335  UInt uiTileStartLCU = 0;
1336  UInt uiTileLCUX     = 0;
1337  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1338  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1339                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1340                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1341  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1342  if( depSliceSegmentsEnabled )
1343  {
1344    if( pcSlice->isNextSlice()||
1345        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1346    {
1347      if(m_pcCfg->getWaveFrontsynchro())
1348      {
1349        CTXMem[1]->loadContexts(m_pcSbacCoder);
1350      }
1351      CTXMem[0]->loadContexts(m_pcSbacCoder);
1352    }
1353    else
1354    {
1355      if(m_pcCfg->getWaveFrontsynchro())
1356      {
1357        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1358        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1359        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1360        uiLin     = uiCUAddr / uiWidthInLCUs;
1361        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1362          + uiLin%iNumSubstreamsPerTile;
1363        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1364        {
1365          uiCol     = uiCUAddr % uiWidthInLCUs;
1366          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1367          if(uiCol==uiTileLCUX)
1368          {
1369            CTXMem[0]->loadContexts(m_pcSbacCoder);
1370          }
1371        }
1372      }
1373      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1374    }
1375  }
1376
1377  UInt uiEncCUOrder;
1378  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1379       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1380       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1381  {
1382      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1383      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1384      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1385      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1386      uiCol     = uiCUAddr % uiWidthInLCUs;
1387      uiLin     = uiCUAddr / uiWidthInLCUs;
1388      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1389      {
1390        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1391        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1392        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1393                      + uiLin%iNumSubstreamsPerTile;
1394      }
1395      else
1396      {
1397        // dependent tiles => substreams are "per frame".
1398        uiSubStrm = uiLin % iNumSubstreams;
1399      }
1400
1401      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1402      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1403      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1404      {
1405        // We'll sync if the TR is available.
1406        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1407        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1408        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1409        TComDataCU *pcCUTR = NULL;
1410        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1411        {
1412          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1413        }
1414        if ( (true/*bEnforceSliceRestriction*/ &&
1415             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1416             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1417             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1418             ))
1419           )
1420        {
1421          // TR not available.
1422        }
1423        else
1424        {
1425          // TR is available, we use it.
1426          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1427        }
1428      }
1429      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1430
1431    // reset the entropy coder
1432    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1433        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1434        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1435        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1436    {
1437      {
1438        // We're crossing into another tile, tiles are independent.
1439        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1440        // have to perform it here.
1441        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1442        {
1443          ; // do nothing.
1444        }
1445        else
1446        {
1447          SliceType sliceType  = pcSlice->getSliceType();
1448          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1449          {
1450            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1451          }
1452          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1453          // Byte-alignment in slice_data() when new tile
1454          pcSubstreams[uiSubStrm].writeByteAlignment();
1455        }
1456      }
1457      {
1458        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1459        UInt uiAccumulatedSubstreamLength = 0;
1460        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1461        {
1462          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1463        }
1464        // add bits coded in previous dependent slices + bits coded so far
1465        // add number of emulation prevention byte count in the tile
1466        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1467      }
1468    }
1469
1470#if H_3D_QTLPC
1471    rpcPic->setReduceBitsFlag(true);
1472#endif
1473    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1474    if ( pcSlice->getSPS()->getUseSAO() )
1475    {
1476      if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
1477      {
1478        SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[uiCUAddr];
1479        Bool sliceEnabled[NUM_SAO_COMPONENTS];
1480        sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
1481        sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
1482
1483        Bool leftMergeAvail = false;
1484        Bool aboveMergeAvail= false;
1485        //merge left condition
1486        Int rx = (uiCUAddr % uiWidthInLCUs);
1487        if(rx > 0)
1488        {
1489          leftMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-1);
1490        }
1491
1492        //merge up condition
1493        Int ry = (uiCUAddr / uiWidthInLCUs);
1494        if(ry > 0)
1495      {
1496          aboveMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-uiWidthInLCUs);
1497        }
1498
1499        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail);
1500      }
1501    }
1502#if ENC_DEC_TRACE
1503    g_bJustDoIt = g_bEncDecTraceEnable;
1504#endif
1505    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1506      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1507    {
1508      m_pcCuEncoder->encodeCU( pcCU );
1509    }
1510    else
1511    {
1512      m_pcCuEncoder->encodeCU( pcCU );
1513    }
1514#if ENC_DEC_TRACE
1515    g_bJustDoIt = g_bEncDecTraceDisable;
1516#endif   
1517       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1518       
1519
1520       //Store probabilties of second LCU in line into buffer
1521       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1522      {
1523        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1524      }
1525#if H_3D_QTLPC
1526    rpcPic->setReduceBitsFlag(false);
1527#endif
1528  }
1529  if( depSliceSegmentsEnabled )
1530  {
1531    if (m_pcCfg->getWaveFrontsynchro())
1532    {
1533      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1534    }
1535    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1536  }
1537#if ADAPTIVE_QP_SELECTION
1538  if( m_pcCfg->getUseAdaptQpSelect() )
1539  {
1540    m_pcTrQuant->storeSliceQpNext(pcSlice);
1541  }
1542#endif
1543  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1544  {
1545    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1546    {
1547      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1548    }
1549    else
1550    {
1551      m_pcEntropyCoder->determineCabacInitIdx();
1552    }
1553  }
1554}
1555
1556/** Determines the starting and bounding LCU address of current slice / dependent slice
1557 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1558 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1559 */
1560Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1561{
1562  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1563  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1564  UInt tileIdxIncrement;
1565  UInt tileIdx;
1566  UInt tileWidthInLcu;
1567  UInt tileHeightInLcu;
1568  UInt tileTotalCount;
1569
1570  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1571  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1572  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1573  if (bEncodeSlice) 
1574  {
1575    UInt uiCUAddrIncrement;
1576    switch (m_pcCfg->getSliceMode())
1577    {
1578    case FIXED_NUMBER_OF_LCU:
1579      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1580      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1581      break;
1582    case FIXED_NUMBER_OF_BYTES:
1583      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1584      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1585      break;
1586    case FIXED_NUMBER_OF_TILES:
1587      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1588        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1589        );
1590      uiCUAddrIncrement        = 0;
1591      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1592
1593      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1594      {
1595        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1596        {
1597          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1598          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1599          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1600        }
1601      }
1602
1603      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1604      break;
1605    default:
1606      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1607      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1608      break;
1609    } 
1610    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1611    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1612    {
1613      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1614    }
1615    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1616  }
1617  else
1618  {
1619    UInt uiCUAddrIncrement     ;
1620    switch (m_pcCfg->getSliceMode())
1621    {
1622    case FIXED_NUMBER_OF_LCU:
1623      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1624      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1625      break;
1626    case FIXED_NUMBER_OF_TILES:
1627      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1628        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1629        );
1630      uiCUAddrIncrement        = 0;
1631      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1632
1633      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1634      {
1635        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1636        {
1637          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1638          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1639          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1640        }
1641      }
1642
1643      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1644      break;
1645    default:
1646      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1647      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1648      break;
1649    } 
1650    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1651    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1652    {
1653      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1654    }
1655    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1656  }
1657
1658  Bool tileBoundary = false;
1659  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1660      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1661  {
1662    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1663    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1664    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1665    UInt tileBoundingCUAddrSlice = 0;
1666    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1667    {
1668      lcuEncAddr++;
1669      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1670    }
1671    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1672   
1673    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1674    {
1675      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1676      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1677      tileBoundary = true;
1678    }
1679  }
1680
1681  // Dependent slice
1682  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1683  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1684  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1685  if (bEncodeSlice) 
1686  {
1687    UInt uiCUAddrIncrement;
1688    switch (m_pcCfg->getSliceSegmentMode())
1689    {
1690    case FIXED_NUMBER_OF_LCU:
1691      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1692      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1693      break;
1694    case FIXED_NUMBER_OF_BYTES:
1695      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1696      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1697      break;
1698    case FIXED_NUMBER_OF_TILES:
1699      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1700        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1701        );
1702      uiCUAddrIncrement        = 0;
1703      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1704
1705      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1706      {
1707        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1708        {
1709          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1710          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1711          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1712        }
1713      }
1714      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1715      break;
1716    default:
1717      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1718      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1719      break;
1720    } 
1721    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1722    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1723    {
1724      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1725    }
1726    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1727  }
1728  else
1729  {
1730    UInt uiCUAddrIncrement;
1731    switch (m_pcCfg->getSliceSegmentMode())
1732    {
1733    case FIXED_NUMBER_OF_LCU:
1734      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1735      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1736      break;
1737    case FIXED_NUMBER_OF_TILES:
1738      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1739        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1740        );
1741      uiCUAddrIncrement        = 0;
1742      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1743
1744      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1745      {
1746        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1747        {
1748          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1749          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1750          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1751        }
1752      }
1753      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1754      break;
1755    default:
1756      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1757      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1758      break;
1759    } 
1760    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1761    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1762    {
1763      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1764    }
1765    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1766  }
1767  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1768    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1769  {
1770    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1771    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1772    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1773    UInt tileBoundingCUAddrSlice = 0;
1774    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1775    {
1776      lcuEncAddr++;
1777      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1778    }
1779    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1780
1781    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1782    {
1783      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1784      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1785      tileBoundary = true;
1786    }
1787  }
1788
1789  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1790  {
1791    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1792    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1793  }
1794
1795  //calculate real dependent slice start address
1796  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1797  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1798  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1799  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1800  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1801  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1802  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1803  {
1804    uiInternalAddress++;
1805    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1806    {
1807      uiInternalAddress=0;
1808      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1809    }
1810    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1811    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1812  }
1813  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1814 
1815  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1816  startCUAddrSliceSegment=uiRealStartAddress;
1817 
1818  //calculate real slice start address
1819  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1820  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1821  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1822  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1823  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1824  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1825  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1826  {
1827    uiInternalAddress++;
1828    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1829    {
1830      uiInternalAddress=0;
1831      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1832    }
1833    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1834    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1835  }
1836  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1837 
1838  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1839  uiStartCUAddrSlice=uiRealStartAddress;
1840 
1841  // Make a joint decision based on reconstruction and dependent slice bounds
1842  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1843  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1844
1845
1846  if (!bEncodeSlice)
1847  {
1848    // 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
1849    // first. Set the flags accordingly.
1850    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1851      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1852      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1853      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1854      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1855      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1856      || tileBoundary
1857)
1858    {
1859      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1860      {
1861        pcSlice->setNextSlice       ( true );
1862        pcSlice->setNextSliceSegment( false );
1863      }
1864      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1865      {
1866        pcSlice->setNextSlice       ( false );
1867        pcSlice->setNextSliceSegment( true );
1868      }
1869      else
1870      {
1871        pcSlice->setNextSlice       ( true );
1872        pcSlice->setNextSliceSegment( true );
1873      }
1874    }
1875    else
1876    {
1877      pcSlice->setNextSlice       ( false );
1878      pcSlice->setNextSliceSegment( false );
1879    }
1880  }
1881}
1882
1883Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1884{
1885  return 4.2005*log(lambda) + 13.7122;
1886}
1887
1888//! \}
Note: See TracBrowser for help on using the repository browser.