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

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