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

Last change on this file since 1245 was 1196, checked in by tech, 10 years ago

Merged 14.0-dev0@1187.

  • Property svn:eol-style set to native
File size: 75.5 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 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
610  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
611#endif
612  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
613}
614
615Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
616{
617  TComSlice* slice = pic->getSlice(0);
618
619  // store lambda
620  slice->setSliceQp( sliceQP );
621#if ADAPTIVE_QP_SELECTION
622  slice->setSliceQpBase ( sliceQP );
623#endif
624  m_pcRdCost ->setLambda( lambda );
625  // for RDO
626  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
627  Double weight[2] = { 1.0, 1.0 };
628  Int qpc;
629  Int chromaQPOffset;
630
631  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
632  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
633  weight[0] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
634  m_pcRdCost->setCbDistortionWeight(weight[0]);
635
636  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
637  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
638  weight[1] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
639  m_pcRdCost->setCrDistortionWeight(weight[1]);
640
641  const Double lambdaArray[3] = {lambda, (lambda / weight[0]), (lambda / weight[1])};
642
643#if RDOQ_CHROMA_LAMBDA
644  // for RDOQ
645  m_pcTrQuant->setLambdas( lambdaArray );
646#else
647  m_pcTrQuant->setLambda( lambda );
648#endif
649
650  // For SAO
651  slice->setLambdas( lambdaArray );
652}
653// ====================================================================================================================
654// Public member functions
655// ====================================================================================================================
656
657Void TEncSlice::setSearchRange( TComSlice* pcSlice )
658{
659  Int iCurrPOC = pcSlice->getPOC();
660  Int iRefPOC;
661  Int iGOPSize = m_pcCfg->getGOPSize();
662  Int iOffset = (iGOPSize >> 1);
663  Int iMaxSR = m_pcCfg->getSearchRange();
664  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
665 
666  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
667  {
668    //RefPicList e = (RefPicList)iDir;
669    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
670    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
671    {
672      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
673      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
674      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
675    }
676  }
677}
678
679/**
680 - multi-loop slice encoding for different slice QP
681 .
682 \param rpcPic    picture class
683 */
684Void TEncSlice::precompressSlice( TComPic*& rpcPic )
685{
686  // if deltaQP RD is not used, simply return
687  if ( m_pcCfg->getDeltaQpRD() == 0 )
688  {
689    return;
690  }
691
692  if ( m_pcCfg->getUseRateCtrl() )
693  {
694    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
695    assert(0);
696  }
697 
698  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
699  Double     dPicRdCostBest = MAX_DOUBLE;
700  UInt       uiQpIdxBest = 0;
701 
702  Double dFrameLambda;
703#if FULL_NBIT
704  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
705#else
706  Int    SHIFT_QP = 12;
707#endif
708 
709  // set frame lambda
710  if (m_pcCfg->getGOPSize() > 1)
711  {
712    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
713  }
714  else
715  {
716    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
717  }
718  m_pcRdCost      ->setFrameLambda(dFrameLambda);
719 
720  // for each QP candidate
721  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
722  {
723    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
724#if ADAPTIVE_QP_SELECTION
725    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
726#endif
727    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
728    // for RDO
729    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
730    Int iQP = m_piRdPicQp    [uiQpIdx];
731    Double weight[2] = { 1.0, 1.0 };
732    Int qpc;
733    Int chromaQPOffset;
734
735    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
736    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
737    weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
738    m_pcRdCost->setCbDistortionWeight(weight[0]);
739
740    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
741    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
742    weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
743    m_pcRdCost->setCrDistortionWeight(weight[1]);
744
745    const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])};
746#if RDOQ_CHROMA_LAMBDA
747    // for RDOQ
748    m_pcTrQuant->setLambdas( lambdaArray );
749#else
750    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
751#endif
752    // For SAO
753    pcSlice->setLambdas( lambdaArray );
754   
755    // try compress
756    compressSlice   ( rpcPic );
757   
758    Double dPicRdCost;
759#if H_3D_VSO
760    Dist64 uiPicDist        = m_uiPicDist;
761#else
762    UInt64 uiPicDist        = m_uiPicDist;
763#endif
764    UInt64 uiALFBits        = 0;
765   
766    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
767   
768    // compute RD cost and choose the best
769    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
770#if H_3D
771    // Above calculation need to be fixed for VSO, including frameLambda value.
772#endif
773   
774    if ( dPicRdCost < dPicRdCostBest )
775    {
776      uiQpIdxBest    = uiQpIdx;
777      dPicRdCostBest = dPicRdCost;
778    }
779  }
780 
781  // set best values
782  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
783#if ADAPTIVE_QP_SELECTION
784  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
785#endif
786  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
787  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
788  Int iQP = m_piRdPicQp    [uiQpIdxBest];
789  Double weight[2] = { 1.0, 1.0 };
790  Int qpc;
791  Int chromaQPOffset;
792
793  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
794  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
795  weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
796  m_pcRdCost->setCbDistortionWeight(weight[0]);
797
798  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
799  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
800  weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
801  m_pcRdCost->setCrDistortionWeight(weight[1]);
802
803  const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])};
804#if RDOQ_CHROMA_LAMBDA
805  // for RDOQ
806  m_pcTrQuant->setLambdas( lambdaArray );
807#else
808  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
809#endif
810  // For SAO
811  pcSlice->setLambdas( lambdaArray );
812}
813
814/** \param rpcPic   picture class
815 */
816Void TEncSlice::calCostSliceI(TComPic*& rpcPic)
817{
818  UInt    uiCUAddr;
819  UInt    uiStartCUAddr;
820  UInt    uiBoundingCUAddr;
821  Int     iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;;
822  Double  iSumHadSlice = 0;
823
824  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
825  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
826  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
827
828  UInt uiEncCUOrder;
829  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
830  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
831       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
832       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
833  {
834    // initialize CU encoder
835    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
836    pcCU->initCU( rpcPic, uiCUAddr );
837
838    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
839    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
840
841    iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height);
842
843    (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift;
844    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra;
845
846  }
847  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
848}
849
850Void TEncSlice::compressSlice( TComPic*& rpcPic )
851{
852  UInt  uiCUAddr;
853  UInt   uiStartCUAddr;
854  UInt   uiBoundingCUAddr;
855  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
856  TEncBinCABAC* pppcRDSbacCoder = NULL;
857  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
858  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
859 
860  // initialize cost values
861  m_uiPicTotalBits  = 0;
862  m_dPicRdCost      = 0;
863  m_uiPicDist       = 0;
864 
865  // set entropy coder
866    m_pcSbacCoder->init( m_pcBinCABAC );
867    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
868    m_pcEntropyCoder->resetEntropy      ();
869    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
870    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
871    pppcRDSbacCoder->setBinCountingEnableFlag( false );
872    pppcRDSbacCoder->setBinsCoded( 0 );
873 
874  //------------------------------------------------------------------------------
875  //  Weighted Prediction parameters estimation.
876  //------------------------------------------------------------------------------
877  // calculate AC/DC values for current picture
878  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
879  {
880    xCalcACDCParamSlice(pcSlice);
881  }
882
883  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
884
885  if ( bWp_explicit )
886  {
887    //------------------------------------------------------------------------------
888    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
889    //------------------------------------------------------------------------------
890    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
891    {
892      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
893    }
894
895    xEstimateWPParamSlice( pcSlice );
896    pcSlice->initWpScaling();
897
898    // check WP on/off
899    xCheckWPEnable( pcSlice );
900  }
901
902#if ADAPTIVE_QP_SELECTION
903  if( m_pcCfg->getUseAdaptQpSelect() )
904  {
905    m_pcTrQuant->clearSliceARLCnt();
906    if(pcSlice->getSliceType()!=I_SLICE)
907    {
908      Int qpBase = pcSlice->getSliceQpBase();
909      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
910    }
911  }
912#endif
913  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
914  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
915  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
916  Int  iNumSubstreams = 1;
917  UInt uiTilesAcross  = 0;
918#if H_3D_IC
919  if ( pcEncTop->getViewIndex() && pcEncTop->getUseIC() &&
920       !( ( pcSlice->getSliceType() == P_SLICE && pcSlice->getPPS()->getUseWP() ) || ( pcSlice->getSliceType() == B_SLICE && pcSlice->getPPS()->getWPBiPred() ) )
921     )
922  {
923    pcSlice ->xSetApplyIC(pcEncTop->getUseICLowLatencyEnc());
924    if ( pcSlice->getApplyIC() )
925    {
926      pcSlice->setIcSkipParseFlag( pcSlice->getPOC() % m_pcCfg->getIntraPeriod() != 0 );
927    }
928  }
929#endif
930    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
931    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
932    delete[] m_pcBufferSbacCoders;
933    delete[] m_pcBufferBinCoderCABACs;
934    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
935    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
936    for (Int ui = 0; ui < uiTilesAcross; ui++)
937    {
938      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
939    }
940    for (UInt ui = 0; ui < uiTilesAcross; ui++)
941    {
942      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
943    }
944
945    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
946    {
947      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
948    }
949    delete[] m_pcBufferLowLatSbacCoders;
950    delete[] m_pcBufferLowLatBinCoderCABACs;
951    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
952    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
953    for (Int ui = 0; ui < uiTilesAcross; ui++)
954    {
955      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
956    }
957    for (UInt ui = 0; ui < uiTilesAcross; ui++)
958      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
959
960  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
961  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
962  UInt uiCol=0, uiLin=0, uiSubStrm=0;
963  UInt uiTileCol      = 0;
964  UInt uiTileStartLCU = 0;
965  UInt uiTileLCUX     = 0;
966  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
967  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
968  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
969  if( depSliceSegmentsEnabled )
970  {
971    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
972    {
973      if( m_pcCfg->getWaveFrontsynchro() )
974      {
975        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
976        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
977        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
978        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
979        uiLin     = uiCUAddr / uiWidthInLCUs;
980        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
981          + uiLin%iNumSubstreamsPerTile;
982        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
983        {
984          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
985          uiCol     = uiCUAddr % uiWidthInLCUs;
986          if(uiCol==uiTileStartLCU)
987          {
988            CTXMem[0]->loadContexts(m_pcSbacCoder);
989          }
990        }
991      }
992      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
993      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
994    }
995    else
996    {
997      if(m_pcCfg->getWaveFrontsynchro())
998      {
999        CTXMem[1]->loadContexts(m_pcSbacCoder);
1000      }
1001      CTXMem[0]->loadContexts(m_pcSbacCoder);
1002    }
1003  }
1004
1005  // for every CU in slice
1006#if H_3D
1007  Int iLastPosY = -1;
1008#endif
1009  UInt uiEncCUOrder;
1010  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1011       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1012       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1013  {
1014    // initialize CU encoder
1015    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1016    pcCU->initCU( rpcPic, uiCUAddr );
1017#if H_3D_VSO
1018    if ( m_pcRdCost->getUseRenModel() )
1019    {
1020      // updated renderer model if necessary
1021      Int iCurPosX;
1022      Int iCurPosY; 
1023      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
1024      if ( iCurPosY != iLastPosY )
1025      {
1026        iLastPosY = iCurPosY;         
1027        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY );
1028      }
1029    }
1030#endif
1031    // inherit from TR if necessary, select substream to use.
1032      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1033      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1034      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1035      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1036      uiCol     = uiCUAddr % uiWidthInLCUs;
1037      uiLin     = uiCUAddr / uiWidthInLCUs;
1038      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1039      {
1040        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1041        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1042        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1043                      + uiLin%iNumSubstreamsPerTile;
1044      }
1045      else
1046      {
1047        // dependent tiles => substreams are "per frame".
1048        uiSubStrm = uiLin % iNumSubstreams;
1049      }
1050      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1051      {
1052        // We'll sync if the TR is available.
1053        TComDataCU *pcCUUp = pcCU->getCUAbove();
1054        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1055        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1056        TComDataCU *pcCUTR = NULL;
1057        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1058        {
1059          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1060        }
1061        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1062             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1063             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1064             )
1065           )
1066        {
1067          // TR not available.
1068        }
1069        else
1070        {
1071          // TR is available, we use it.
1072          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1073        }
1074      }
1075      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1076
1077    // reset the entropy coder
1078    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1079        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1080        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1081        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1082    {
1083      SliceType sliceType = pcSlice->getSliceType();
1084      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1085      {
1086        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1087      }
1088      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1089      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1090      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1091      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1092    }
1093
1094      // set go-on entropy coder
1095      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1096      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1097     
1098      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1099
1100      Double oldLambda = m_pcRdCost->getLambda();
1101      if ( m_pcCfg->getUseRateCtrl() )
1102      {
1103        Int estQP        = pcSlice->getSliceQp();
1104        Double estLambda = -1.0;
1105        Double bpp       = -1.0;
1106
1107        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1108        {
1109          estQP = pcSlice->getSliceQp();
1110        }
1111        else
1112        {
1113#if KWU_RC_MADPRED_E0227
1114          if(pcSlice->getLayerId() != 0 && m_pcCfg->getUseDepthMADPred() && !pcSlice->getIsDepth())
1115          {
1116            Double zn, zf, focallength, position, camShift;
1117            Double basePos;
1118            Bool bInterpolated;
1119            Int direction = pcSlice->getViewId() - pcCU->getSlice()->getIvPic(false, 0)->getViewId();
1120            Int disparity;
1121
1122            pcEncTop->getCamParam()->xGetZNearZFar(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), zn, zf);
1123            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[0], pcSlice->getPOC(), focallength, basePos, camShift, bInterpolated);
1124            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), focallength, position, camShift, bInterpolated);
1125            bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBppforInterView( m_pcRateCtrl->getPicList(), pcCU,
1126              basePos, position, focallength, zn, zf, (direction > 0 ? 1 : -1), &disparity );
1127          }
1128          else
1129          {
1130#endif
1131          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1132          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1133          {
1134            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1135          }
1136          else
1137          {
1138            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1139            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1140          }
1141#if KWU_RC_MADPRED_E0227
1142          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1143          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1144#endif
1145          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1146
1147          m_pcRdCost->setLambda(estLambda);
1148#if RDOQ_CHROMA_LAMBDA
1149          // set lambda for RDOQ
1150          Double weight=m_pcRdCost->getChromaWeight();
1151        const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
1152        m_pcTrQuant->setLambdas( lambdaArray );
1153#else
1154          m_pcTrQuant->setLambda( estLambda );
1155#endif
1156        }
1157
1158        m_pcRateCtrl->setRCQP( estQP );
1159#if ADAPTIVE_QP_SELECTION
1160        pcCU->getSlice()->setSliceQpBase( estQP );
1161#endif
1162      }
1163      // run CU encoder
1164      m_pcCuEncoder->compressCU( pcCU );
1165
1166      // restore entropy coder to an initial stage
1167      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1168      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1169      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1170      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1171      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1172      m_pcBitCounter->resetBits();
1173      pppcRDSbacCoder->setBinsCoded( 0 );
1174      m_pcCuEncoder->encodeCU( pcCU );
1175
1176      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1177      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1178      {
1179        pcSlice->setNextSlice( true );
1180        break;
1181      }
1182      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1183      {
1184        pcSlice->setNextSliceSegment( true );
1185        break;
1186      }
1187       
1188    ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1189         //Store probabilties of second LCU in line into buffer
1190         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1191        {
1192          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1193        }
1194
1195      if ( m_pcCfg->getUseRateCtrl() )
1196      {
1197#if KWU_RC_MADPRED_E0227
1198        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1199        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1200        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1201        Double MAD = (Double)SAD / (Double)(height * width);
1202        MAD = MAD * MAD;
1203        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1204#endif
1205
1206        Int actualQP        = g_RCInvalidQPValue;
1207        Double actualLambda = m_pcRdCost->getLambda();
1208        Int actualBits      = pcCU->getTotalBits();
1209        Int numberOfEffectivePixels    = 0;
1210        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1211        {
1212          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1213          {
1214            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1215            break;
1216          }
1217        }
1218
1219        if ( numberOfEffectivePixels == 0 )
1220        {
1221          actualQP = g_RCInvalidQPValue;
1222        }
1223        else
1224        {
1225          actualQP = pcCU->getQP( 0 );
1226        }
1227        m_pcRdCost->setLambda(oldLambda);
1228
1229        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1230          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1231    }
1232   
1233    m_uiPicTotalBits += pcCU->getTotalBits();
1234    m_dPicRdCost     += pcCU->getTotalCost();
1235    m_uiPicDist      += pcCU->getTotalDistortion();
1236  }
1237  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1238  {
1239    pcSlice->setNextSlice( true );
1240  }
1241  if(m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES || m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES)
1242  {
1243    if(pcSlice->getSliceCurEndCUAddr()<=pcSlice->getSliceSegmentCurEndCUAddr())
1244    {
1245       pcSlice->setNextSlice( true );
1246    }
1247    else
1248    {
1249       pcSlice->setNextSliceSegment( true );
1250    }
1251  }
1252  if( depSliceSegmentsEnabled )
1253  {
1254    if (m_pcCfg->getWaveFrontsynchro())
1255    {
1256      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1257    }
1258     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1259  }
1260  xRestoreWPparam( pcSlice );
1261}
1262
1263/**
1264 \param  rpcPic        picture class
1265 \retval rpcBitstream  bitstream class
1266 */
1267Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1268{
1269  UInt       uiCUAddr;
1270  UInt       uiStartCUAddr;
1271  UInt       uiBoundingCUAddr;
1272  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1273
1274  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1275  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1276  // choose entropy coder
1277  {
1278    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1279    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1280  }
1281 
1282  m_pcCuEncoder->setBitCounter( NULL );
1283  m_pcBitCounter = NULL;
1284  // Appropriate substream bitstream is switched later.
1285  // for every CU
1286#if ENC_DEC_TRACE
1287  g_bJustDoIt = g_bEncDecTraceEnable;
1288#endif
1289  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1290  DTRACE_CABAC_T( "\tPOC: " );
1291  DTRACE_CABAC_V( rpcPic->getPOC() );
1292#if H_MV_ENC_DEC_TRAC
1293  DTRACE_CABAC_T( " Layer: " );
1294  DTRACE_CABAC_V( rpcPic->getLayerId() );
1295#endif
1296  DTRACE_CABAC_T( "\n" );
1297#if ENC_DEC_TRACE
1298  g_bJustDoIt = g_bEncDecTraceDisable;
1299#endif
1300
1301  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1302  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1303  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1304  UInt uiBitsOriginallyInSubstreams = 0;
1305  {
1306    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1307    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1308    {
1309      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1310    }
1311   
1312    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1313    {
1314      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1315    }
1316
1317    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1318    {
1319      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1320    }
1321  }
1322
1323  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1324  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1325  UInt uiTileCol      = 0;
1326  UInt uiTileStartLCU = 0;
1327  UInt uiTileLCUX     = 0;
1328  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1329  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1330                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1331                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1332  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1333  if( depSliceSegmentsEnabled )
1334  {
1335    if( pcSlice->isNextSlice()||
1336        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1337    {
1338      if(m_pcCfg->getWaveFrontsynchro())
1339      {
1340        CTXMem[1]->loadContexts(m_pcSbacCoder);
1341      }
1342      CTXMem[0]->loadContexts(m_pcSbacCoder);
1343    }
1344    else
1345    {
1346      if(m_pcCfg->getWaveFrontsynchro())
1347      {
1348        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1349        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1350        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1351        uiLin     = uiCUAddr / uiWidthInLCUs;
1352        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1353          + uiLin%iNumSubstreamsPerTile;
1354        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1355        {
1356          uiCol     = uiCUAddr % uiWidthInLCUs;
1357          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1358          if(uiCol==uiTileLCUX)
1359          {
1360            CTXMem[0]->loadContexts(m_pcSbacCoder);
1361          }
1362        }
1363      }
1364      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1365    }
1366  }
1367
1368  UInt uiEncCUOrder;
1369  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1370       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1371       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1372  {
1373      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1374      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1375      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1376      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1377      uiCol     = uiCUAddr % uiWidthInLCUs;
1378      uiLin     = uiCUAddr / uiWidthInLCUs;
1379      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1380      {
1381        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1382        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1383        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1384                      + uiLin%iNumSubstreamsPerTile;
1385      }
1386      else
1387      {
1388        // dependent tiles => substreams are "per frame".
1389        uiSubStrm = uiLin % iNumSubstreams;
1390      }
1391
1392      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1393      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1394      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1395      {
1396        // We'll sync if the TR is available.
1397        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1398        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1399        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1400        TComDataCU *pcCUTR = NULL;
1401        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1402        {
1403          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1404        }
1405        if ( (true/*bEnforceSliceRestriction*/ &&
1406             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1407             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1408             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1409             ))
1410           )
1411        {
1412          // TR not available.
1413        }
1414        else
1415        {
1416          // TR is available, we use it.
1417          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1418        }
1419      }
1420      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1421
1422    // reset the entropy coder
1423    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1424        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1425        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1426        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1427    {
1428      {
1429        // We're crossing into another tile, tiles are independent.
1430        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1431        // have to perform it here.
1432        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1433        {
1434          ; // do nothing.
1435        }
1436        else
1437        {
1438          SliceType sliceType  = pcSlice->getSliceType();
1439          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1440          {
1441            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1442          }
1443          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1444          // Byte-alignment in slice_data() when new tile
1445          pcSubstreams[uiSubStrm].writeByteAlignment();
1446        }
1447      }
1448      {
1449        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1450        UInt uiAccumulatedSubstreamLength = 0;
1451        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1452        {
1453          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1454        }
1455        // add bits coded in previous dependent slices + bits coded so far
1456        // add number of emulation prevention byte count in the tile
1457        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1458      }
1459    }
1460
1461#if H_3D_QTLPC
1462    rpcPic->setReduceBitsFlag(true);
1463#endif
1464    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1465    if ( pcSlice->getSPS()->getUseSAO() )
1466    {
1467      if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
1468      {
1469        SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[uiCUAddr];
1470        Bool sliceEnabled[NUM_SAO_COMPONENTS];
1471        sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
1472        sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
1473
1474        Bool leftMergeAvail = false;
1475        Bool aboveMergeAvail= false;
1476        //merge left condition
1477        Int rx = (uiCUAddr % uiWidthInLCUs);
1478        if(rx > 0)
1479        {
1480          leftMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-1);
1481        }
1482
1483        //merge up condition
1484        Int ry = (uiCUAddr / uiWidthInLCUs);
1485        if(ry > 0)
1486      {
1487          aboveMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-uiWidthInLCUs);
1488        }
1489
1490        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail);
1491      }
1492    }
1493#if ENC_DEC_TRACE
1494    g_bJustDoIt = g_bEncDecTraceEnable;
1495#endif
1496    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1497      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1498    {
1499      m_pcCuEncoder->encodeCU( pcCU );
1500    }
1501    else
1502    {
1503      m_pcCuEncoder->encodeCU( pcCU );
1504    }
1505#if ENC_DEC_TRACE
1506    g_bJustDoIt = g_bEncDecTraceDisable;
1507#endif   
1508       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1509       
1510
1511       //Store probabilties of second LCU in line into buffer
1512       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1513      {
1514        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1515      }
1516#if H_3D_QTLPC
1517    rpcPic->setReduceBitsFlag(false);
1518#endif
1519  }
1520  if( depSliceSegmentsEnabled )
1521  {
1522    if (m_pcCfg->getWaveFrontsynchro())
1523    {
1524      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1525    }
1526    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1527  }
1528#if ADAPTIVE_QP_SELECTION
1529  if( m_pcCfg->getUseAdaptQpSelect() )
1530  {
1531    m_pcTrQuant->storeSliceQpNext(pcSlice);
1532  }
1533#endif
1534  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1535  {
1536    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1537    {
1538      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1539    }
1540    else
1541    {
1542      m_pcEntropyCoder->determineCabacInitIdx();
1543    }
1544  }
1545}
1546
1547/** Determines the starting and bounding LCU address of current slice / dependent slice
1548 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1549 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1550 */
1551Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1552{
1553  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1554  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1555  UInt tileIdxIncrement;
1556  UInt tileIdx;
1557  UInt tileWidthInLcu;
1558  UInt tileHeightInLcu;
1559  UInt tileTotalCount;
1560
1561  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1562  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1563  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1564  if (bEncodeSlice) 
1565  {
1566    UInt uiCUAddrIncrement;
1567    switch (m_pcCfg->getSliceMode())
1568    {
1569    case FIXED_NUMBER_OF_LCU:
1570      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1571      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1572      break;
1573    case FIXED_NUMBER_OF_BYTES:
1574      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1575      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1576      break;
1577    case FIXED_NUMBER_OF_TILES:
1578      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1579        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1580        );
1581      uiCUAddrIncrement        = 0;
1582      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1583
1584      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1585      {
1586        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1587        {
1588          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1589          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1590          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1591        }
1592      }
1593
1594      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1595      break;
1596    default:
1597      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1598      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1599      break;
1600    } 
1601    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1602    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1603    {
1604      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1605    }
1606    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1607  }
1608  else
1609  {
1610    UInt uiCUAddrIncrement     ;
1611    switch (m_pcCfg->getSliceMode())
1612    {
1613    case FIXED_NUMBER_OF_LCU:
1614      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1615      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1616      break;
1617    case FIXED_NUMBER_OF_TILES:
1618      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1619        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1620        );
1621      uiCUAddrIncrement        = 0;
1622      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1623
1624      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1625      {
1626        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1627        {
1628          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1629          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1630          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1631        }
1632      }
1633
1634      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1635      break;
1636    default:
1637      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1638      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1639      break;
1640    } 
1641    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1642    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1643    {
1644      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1645    }
1646    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1647  }
1648
1649  Bool tileBoundary = false;
1650  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1651      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1652  {
1653    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1654    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1655    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1656    UInt tileBoundingCUAddrSlice = 0;
1657    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1658    {
1659      lcuEncAddr++;
1660      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1661    }
1662    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1663   
1664    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1665    {
1666      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1667      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1668      tileBoundary = true;
1669    }
1670  }
1671
1672  // Dependent slice
1673  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1674  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1675  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1676  if (bEncodeSlice) 
1677  {
1678    UInt uiCUAddrIncrement;
1679    switch (m_pcCfg->getSliceSegmentMode())
1680    {
1681    case FIXED_NUMBER_OF_LCU:
1682      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1683      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1684      break;
1685    case FIXED_NUMBER_OF_BYTES:
1686      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1687      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1688      break;
1689    case FIXED_NUMBER_OF_TILES:
1690      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1691        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1692        );
1693      uiCUAddrIncrement        = 0;
1694      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1695
1696      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1697      {
1698        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1699        {
1700          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1701          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1702          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1703        }
1704      }
1705      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1706      break;
1707    default:
1708      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1709      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1710      break;
1711    } 
1712    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1713    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1714    {
1715      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1716    }
1717    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1718  }
1719  else
1720  {
1721    UInt uiCUAddrIncrement;
1722    switch (m_pcCfg->getSliceSegmentMode())
1723    {
1724    case FIXED_NUMBER_OF_LCU:
1725      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1726      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1727      break;
1728    case FIXED_NUMBER_OF_TILES:
1729      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1730        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1731        );
1732      uiCUAddrIncrement        = 0;
1733      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1734
1735      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1736      {
1737        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1738        {
1739          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1740          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1741          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1742        }
1743      }
1744      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1745      break;
1746    default:
1747      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1748      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1749      break;
1750    } 
1751    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1752    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1753    {
1754      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1755    }
1756    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1757  }
1758  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1759    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1760  {
1761    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1762    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1763    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1764    UInt tileBoundingCUAddrSlice = 0;
1765    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1766    {
1767      lcuEncAddr++;
1768      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1769    }
1770    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1771
1772    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1773    {
1774      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1775      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1776      tileBoundary = true;
1777    }
1778  }
1779
1780  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1781  {
1782    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1783    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1784  }
1785
1786  //calculate real dependent slice start address
1787  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1788  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1789  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1790  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1791  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1792  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1793  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1794  {
1795    uiInternalAddress++;
1796    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1797    {
1798      uiInternalAddress=0;
1799      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1800    }
1801    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1802    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1803  }
1804  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1805 
1806  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1807  startCUAddrSliceSegment=uiRealStartAddress;
1808 
1809  //calculate real slice start address
1810  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1811  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1812  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1813  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1814  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1815  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1816  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1817  {
1818    uiInternalAddress++;
1819    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1820    {
1821      uiInternalAddress=0;
1822      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1823    }
1824    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1825    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1826  }
1827  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1828 
1829  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1830  uiStartCUAddrSlice=uiRealStartAddress;
1831 
1832  // Make a joint decision based on reconstruction and dependent slice bounds
1833  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1834  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1835
1836
1837  if (!bEncodeSlice)
1838  {
1839    // 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
1840    // first. Set the flags accordingly.
1841    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1842      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1843      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1844      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1845      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1846      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1847      || tileBoundary
1848)
1849    {
1850      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1851      {
1852        pcSlice->setNextSlice       ( true );
1853        pcSlice->setNextSliceSegment( false );
1854      }
1855      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1856      {
1857        pcSlice->setNextSlice       ( false );
1858        pcSlice->setNextSliceSegment( true );
1859      }
1860      else
1861      {
1862        pcSlice->setNextSlice       ( true );
1863        pcSlice->setNextSliceSegment( true );
1864      }
1865    }
1866    else
1867    {
1868      pcSlice->setNextSlice       ( false );
1869      pcSlice->setNextSliceSegment( false );
1870    }
1871  }
1872}
1873
1874Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1875{
1876  return 4.2005*log(lambda) + 13.7122;
1877}
1878
1879//! \}
Note: See TracBrowser for help on using the repository browser.