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

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

Merged branch 12.2-dev0@1123

  • Property svn:eol-style set to native
File size: 77.9 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6* Copyright (c) 2010-2014, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSlice.h"
40#include <math.h>
41
42//! \ingroup TLibEncoder
43//! \{
44
45// ====================================================================================================================
46// Constructor / destructor / create / destroy
47// ====================================================================================================================
48
49TEncSlice::TEncSlice()
50{
51  m_apcPicYuvPred = NULL;
52  m_apcPicYuvResi = NULL;
53 
54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57  m_pcBufferSbacCoders    = NULL;
58  m_pcBufferBinCoderCABACs  = NULL;
59  m_pcBufferLowLatSbacCoders    = NULL;
60  m_pcBufferLowLatBinCoderCABACs  = NULL;
61}
62
63TEncSlice::~TEncSlice()
64{
65  for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
66  {
67    delete (*i);
68  }
69}
70
71Void TEncSlice::initCtxMem(  UInt i )               
72{   
73  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
74  {
75    delete (*j);
76  }
77  CTXMem.clear(); 
78  CTXMem.resize(i); 
79}
80
81Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
82{
83  // create prediction picture
84  if ( m_apcPicYuvPred == NULL )
85  {
86    m_apcPicYuvPred  = new TComPicYuv;
87    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
88  }
89 
90  // create residual picture
91  if( m_apcPicYuvResi == NULL )
92  {
93    m_apcPicYuvResi  = new TComPicYuv;
94    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
95  }
96}
97
98Void TEncSlice::destroy()
99{
100  // destroy prediction picture
101  if ( m_apcPicYuvPred )
102  {
103    m_apcPicYuvPred->destroy();
104    delete m_apcPicYuvPred;
105    m_apcPicYuvPred  = NULL;
106  }
107 
108  // destroy residual picture
109  if ( m_apcPicYuvResi )
110  {
111    m_apcPicYuvResi->destroy();
112    delete m_apcPicYuvResi;
113    m_apcPicYuvResi  = NULL;
114  }
115 
116  // free lambda and QP arrays
117  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
118  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
119  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
120
121  if ( m_pcBufferSbacCoders )
122  {
123    delete[] m_pcBufferSbacCoders;
124  }
125  if ( m_pcBufferBinCoderCABACs )
126  {
127    delete[] m_pcBufferBinCoderCABACs;
128  }
129  if ( m_pcBufferLowLatSbacCoders )
130    delete[] m_pcBufferLowLatSbacCoders;
131  if ( m_pcBufferLowLatBinCoderCABACs )
132    delete[] m_pcBufferLowLatBinCoderCABACs;
133}
134
135Void TEncSlice::init( TEncTop* pcEncTop )
136{
137  m_pcCfg             = pcEncTop;
138  m_pcListPic         = pcEncTop->getListPic();
139 
140  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
141  m_pcCuEncoder       = pcEncTop->getCuEncoder();
142  m_pcPredSearch      = pcEncTop->getPredSearch();
143 
144  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
145  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
146  m_pcSbacCoder       = pcEncTop->getSbacCoder();
147  m_pcBinCABAC        = pcEncTop->getBinCABAC();
148  m_pcTrQuant         = pcEncTop->getTrQuant();
149 
150  m_pcBitCounter      = pcEncTop->getBitCounter();
151  m_pcRdCost          = pcEncTop->getRdCost();
152  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
153  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
154 
155  // create lambda and QP arrays
156  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
157  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
158  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
159#if KWU_RC_MADPRED_E0227
160  if(m_pcCfg->getUseRateCtrl())
161  {
162    m_pcRateCtrl        = pcEncTop->getRateCtrl();
163  }
164  else
165  {
166    m_pcRateCtrl        = NULL;
167  }
168#else
169  m_pcRateCtrl        = pcEncTop->getRateCtrl();
170#endif
171}
172
173/**
174 - non-referenced frame marking
175 - QP computation based on temporal structure
176 - lambda computation based on QP
177 - set temporal layer ID and the parameter sets
178 .
179 \param pcPic         picture class
180 \param pocLast       POC of last picture
181 \param pocCurr       current POC
182 \param iNumPicRcvd   number of received pictures
183 \param iTimeOffset   POC offset for hierarchical structure
184 \param iDepth        temporal layer depth
185 \param rpcSlice      slice header class
186 \param pSPS          SPS associated with the slice
187 \param pPPS          PPS associated with the slice
188 */
189#if H_MV
190Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, TComSPS* pSPS, TComPPS *pPPS, Int layerId, bool isField )
191#else
192Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, bool isField )
193#endif
194{
195  Double dQP;
196  Double dLambda;
197 
198  rpcSlice = pcPic->getSlice(0);
199
200#if H_MV
201  rpcSlice->setVPS( pVPS ); 
202
203  rpcSlice->setLayerId     ( layerId );
204  rpcSlice->setViewId      ( pVPS->getViewId      ( layerId ) );   
205  rpcSlice->setViewIndex   ( pVPS->getViewIndex   ( layerId ) );
206#if H_3D
207  rpcSlice->setIsDepth     ( pVPS->getDepthId     ( layerId ) != 0 );   
208#endif
209#endif
210  rpcSlice->setSPS( pSPS );
211  rpcSlice->setPPS( pPPS );
212  rpcSlice->setSliceBits(0);
213  rpcSlice->setPic( pcPic );
214  rpcSlice->initSlice();
215  rpcSlice->setPicOutputFlag( true );
216  rpcSlice->setPOC( pocCurr );
217#if 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#if ALGIN_J0107_J0059
617  rpcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()   + ( ( rpcSlice->getMpiFlag( ) || rpcSlice->getIvMvPredFlag( ) || rpcSlice->getViewSynthesisPredFlag( )   ) ? 1 : 0 ));
618#else
619  rpcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()   + ( ( rpcSlice->getMpiFlag( ) || rpcSlice->getIvMvPredFlag( ) ) ? 1 : 0 ));
620#endif
621#else
622  if(rpcSlice->getIsDepth())
623  {
624    rpcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()   + ( ( rpcSlice->getVPS()->getMPIFlag( rpcSlice->getLayerIdInVps() ) || rpcSlice->getVPS()->getIvMvPredFlag( rpcSlice->getLayerIdInVps() ) ) ? 1 : 0 ) );
625  }
626  else
627  {
628#if MTK_MRG_LIST_SIZE_CLEANUP_J0059
629    rpcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()   + ( rpcSlice->getVPS()->getIvMvPredFlag( rpcSlice->getLayerIdInVps() )  || rpcSlice->getVPS()->getViewSynthesisPredFlag( rpcSlice->getLayerIdInVps() ) ? 1 : 0 ) );
630#else
631    rpcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()   + ( rpcSlice->getVPS()->getIvMvPredFlag( rpcSlice->getLayerIdInVps() ) ? 1 : 0 ) );
632#endif
633  }
634#endif
635#else
636  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
637#endif
638  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
639}
640
641Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
642{
643  TComSlice* slice = pic->getSlice(0);
644
645  // store lambda
646  slice->setSliceQp( sliceQP );
647#if ADAPTIVE_QP_SELECTION
648  slice->setSliceQpBase ( sliceQP );
649#endif
650  m_pcRdCost ->setLambda( lambda );
651  // for RDO
652  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
653  Double weight[2] = { 1.0, 1.0 };
654  Int qpc;
655  Int chromaQPOffset;
656
657  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
658  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
659  weight[0] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
660  m_pcRdCost->setCbDistortionWeight(weight[0]);
661
662  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
663  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
664  weight[1] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
665  m_pcRdCost->setCrDistortionWeight(weight[1]);
666
667  const Double lambdaArray[3] = {lambda, (lambda / weight[0]), (lambda / weight[1])};
668
669#if RDOQ_CHROMA_LAMBDA
670  // for RDOQ
671  m_pcTrQuant->setLambdas( lambdaArray );
672#else
673  m_pcTrQuant->setLambda( lambda );
674#endif
675
676  // For SAO
677  slice->setLambdas( lambdaArray );
678}
679// ====================================================================================================================
680// Public member functions
681// ====================================================================================================================
682
683Void TEncSlice::setSearchRange( TComSlice* pcSlice )
684{
685  Int iCurrPOC = pcSlice->getPOC();
686  Int iRefPOC;
687  Int iGOPSize = m_pcCfg->getGOPSize();
688  Int iOffset = (iGOPSize >> 1);
689  Int iMaxSR = m_pcCfg->getSearchRange();
690  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
691 
692  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
693  {
694    //RefPicList e = (RefPicList)iDir;
695    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
696    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
697    {
698      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
699      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
700      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
701    }
702  }
703}
704
705/**
706 - multi-loop slice encoding for different slice QP
707 .
708 \param rpcPic    picture class
709 */
710Void TEncSlice::precompressSlice( TComPic*& rpcPic )
711{
712  // if deltaQP RD is not used, simply return
713  if ( m_pcCfg->getDeltaQpRD() == 0 )
714  {
715    return;
716  }
717
718  if ( m_pcCfg->getUseRateCtrl() )
719  {
720    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
721    assert(0);
722  }
723 
724  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
725  Double     dPicRdCostBest = MAX_DOUBLE;
726  UInt       uiQpIdxBest = 0;
727 
728  Double dFrameLambda;
729#if FULL_NBIT
730  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
731#else
732  Int    SHIFT_QP = 12;
733#endif
734 
735  // set frame lambda
736  if (m_pcCfg->getGOPSize() > 1)
737  {
738    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
739  }
740  else
741  {
742    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
743  }
744  m_pcRdCost      ->setFrameLambda(dFrameLambda);
745 
746  // for each QP candidate
747  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
748  {
749    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
750#if ADAPTIVE_QP_SELECTION
751    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
752#endif
753    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
754    // for RDO
755    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
756    Int iQP = m_piRdPicQp    [uiQpIdx];
757    Double weight[2] = { 1.0, 1.0 };
758    Int qpc;
759    Int chromaQPOffset;
760
761    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
762    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
763    weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
764    m_pcRdCost->setCbDistortionWeight(weight[0]);
765
766    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
767    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
768    weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
769    m_pcRdCost->setCrDistortionWeight(weight[1]);
770
771    const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])};
772#if RDOQ_CHROMA_LAMBDA
773    // for RDOQ
774    m_pcTrQuant->setLambdas( lambdaArray );
775#else
776    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
777#endif
778    // For SAO
779    pcSlice->setLambdas( lambdaArray );
780   
781    // try compress
782    compressSlice   ( rpcPic );
783   
784    Double dPicRdCost;
785#if H_3D_VSO
786    Dist64 uiPicDist        = m_uiPicDist;
787#else
788    UInt64 uiPicDist        = m_uiPicDist;
789#endif
790    UInt64 uiALFBits        = 0;
791   
792    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
793   
794    // compute RD cost and choose the best
795    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
796#if H_3D
797    // Above calculation need to be fixed for VSO, including frameLambda value.
798#endif
799   
800    if ( dPicRdCost < dPicRdCostBest )
801    {
802      uiQpIdxBest    = uiQpIdx;
803      dPicRdCostBest = dPicRdCost;
804    }
805  }
806 
807  // set best values
808  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
809#if ADAPTIVE_QP_SELECTION
810  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
811#endif
812  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
813  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
814  Int iQP = m_piRdPicQp    [uiQpIdxBest];
815  Double weight[2] = { 1.0, 1.0 };
816  Int qpc;
817  Int chromaQPOffset;
818
819  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
820  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
821  weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
822  m_pcRdCost->setCbDistortionWeight(weight[0]);
823
824  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
825  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
826  weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
827  m_pcRdCost->setCrDistortionWeight(weight[1]);
828
829  const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])};
830#if RDOQ_CHROMA_LAMBDA
831  // for RDOQ
832  m_pcTrQuant->setLambdas( lambdaArray );
833#else
834  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
835#endif
836  // For SAO
837  pcSlice->setLambdas( lambdaArray );
838}
839
840/** \param rpcPic   picture class
841 */
842Void TEncSlice::calCostSliceI(TComPic*& rpcPic)
843{
844  UInt    uiCUAddr;
845  UInt    uiStartCUAddr;
846  UInt    uiBoundingCUAddr;
847  Int     iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;;
848  Double  iSumHadSlice = 0;
849
850  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
851  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
852  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
853
854  UInt uiEncCUOrder;
855  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
856  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
857       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
858       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
859  {
860    // initialize CU encoder
861    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
862    pcCU->initCU( rpcPic, uiCUAddr );
863
864    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
865    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
866
867    iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height);
868
869    (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift;
870    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra;
871
872  }
873  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
874}
875
876Void TEncSlice::compressSlice( TComPic*& rpcPic )
877{
878  UInt  uiCUAddr;
879  UInt   uiStartCUAddr;
880  UInt   uiBoundingCUAddr;
881  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
882  TEncBinCABAC* pppcRDSbacCoder = NULL;
883  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
884  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
885 
886  // initialize cost values
887  m_uiPicTotalBits  = 0;
888  m_dPicRdCost      = 0;
889  m_uiPicDist       = 0;
890 
891  // set entropy coder
892    m_pcSbacCoder->init( m_pcBinCABAC );
893    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
894    m_pcEntropyCoder->resetEntropy      ();
895    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
896    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
897    pppcRDSbacCoder->setBinCountingEnableFlag( false );
898    pppcRDSbacCoder->setBinsCoded( 0 );
899 
900  //------------------------------------------------------------------------------
901  //  Weighted Prediction parameters estimation.
902  //------------------------------------------------------------------------------
903  // calculate AC/DC values for current picture
904  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
905  {
906    xCalcACDCParamSlice(pcSlice);
907  }
908
909  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
910
911  if ( bWp_explicit )
912  {
913    //------------------------------------------------------------------------------
914    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
915    //------------------------------------------------------------------------------
916    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
917    {
918      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
919    }
920
921    xEstimateWPParamSlice( pcSlice );
922    pcSlice->initWpScaling();
923
924    // check WP on/off
925    xCheckWPEnable( pcSlice );
926  }
927
928#if ADAPTIVE_QP_SELECTION
929  if( m_pcCfg->getUseAdaptQpSelect() )
930  {
931    m_pcTrQuant->clearSliceARLCnt();
932    if(pcSlice->getSliceType()!=I_SLICE)
933    {
934      Int qpBase = pcSlice->getSliceQpBase();
935      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
936    }
937  }
938#endif
939  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
940  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
941  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
942  Int  iNumSubstreams = 1;
943  UInt uiTilesAcross  = 0;
944#if H_3D_IC
945  if ( pcEncTop->getViewIndex() && pcEncTop->getUseIC() &&
946       !( ( pcSlice->getSliceType() == P_SLICE && pcSlice->getPPS()->getUseWP() ) || ( pcSlice->getSliceType() == B_SLICE && pcSlice->getPPS()->getWPBiPred() ) )
947     )
948  {
949    pcSlice ->xSetApplyIC(pcEncTop->getUseICLowLatencyEnc());
950    if ( pcSlice->getApplyIC() )
951    {
952      pcSlice->setIcSkipParseFlag( pcSlice->getPOC() % m_pcCfg->getIntraPeriod() != 0 );
953    }
954  }
955#endif
956    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
957    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
958    delete[] m_pcBufferSbacCoders;
959    delete[] m_pcBufferBinCoderCABACs;
960    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
961    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
962    for (Int ui = 0; ui < uiTilesAcross; ui++)
963    {
964      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
965    }
966    for (UInt ui = 0; ui < uiTilesAcross; ui++)
967    {
968      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
969    }
970
971    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
972    {
973      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
974    }
975    delete[] m_pcBufferLowLatSbacCoders;
976    delete[] m_pcBufferLowLatBinCoderCABACs;
977    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
978    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
979    for (Int ui = 0; ui < uiTilesAcross; ui++)
980    {
981      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
982    }
983    for (UInt ui = 0; ui < uiTilesAcross; ui++)
984      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
985
986  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
987  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
988  UInt uiCol=0, uiLin=0, uiSubStrm=0;
989  UInt uiTileCol      = 0;
990  UInt uiTileStartLCU = 0;
991  UInt uiTileLCUX     = 0;
992  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
993  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
994  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
995  if( depSliceSegmentsEnabled )
996  {
997    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
998    {
999      if( m_pcCfg->getWaveFrontsynchro() )
1000      {
1001        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1002        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1003        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1004        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
1005        uiLin     = uiCUAddr / uiWidthInLCUs;
1006        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
1007          + uiLin%iNumSubstreamsPerTile;
1008        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1009        {
1010          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1011          uiCol     = uiCUAddr % uiWidthInLCUs;
1012          if(uiCol==uiTileStartLCU)
1013          {
1014            CTXMem[0]->loadContexts(m_pcSbacCoder);
1015          }
1016        }
1017      }
1018      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1019      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1020    }
1021    else
1022    {
1023      if(m_pcCfg->getWaveFrontsynchro())
1024      {
1025        CTXMem[1]->loadContexts(m_pcSbacCoder);
1026      }
1027      CTXMem[0]->loadContexts(m_pcSbacCoder);
1028    }
1029  }
1030#if LGE_DEFAULT_DV_J0046 && !SEC_ARP_VIEW_REF_CHECK_J0037 && !SEC_DBBP_VIEW_REF_CHECK_J0037
1031  pcSlice->setDefaultRefViewIdx( -1 );
1032  pcSlice->setDefaultRefViewIdxAvailableFlag( false ); 
1033
1034  Int valid = 0;
1035  Int viewIndex = 0;
1036  for( UInt uiBId = 0; uiBId < pcSlice->getViewIndex() && valid==0; uiBId++ )
1037  {
1038      UInt        uiBaseId    = uiBId;
1039      TComPic*    pcBasePic   = pcSlice->getIvPic( false, uiBaseId );
1040      for( Int iRefListId = 0; ( iRefListId < (pcSlice->isInterB()? 2:1) ) && !pcSlice->isIntra() && valid==0; iRefListId++ )
1041      {
1042          RefPicList  eRefPicListTest = RefPicList( iRefListId );
1043          Int         iNumRefPics = pcSlice->getNumRefIdx( eRefPicListTest ) ;
1044          for( Int iRefIndex = 0; iRefIndex < iNumRefPics; iRefIndex++ )
1045          { 
1046              if(pcBasePic->getPOC() == pcSlice->getRefPic( eRefPicListTest, iRefIndex )->getPOC() 
1047                  && pcBasePic->getViewIndex() == pcSlice->getRefPic( eRefPicListTest, iRefIndex )->getViewIndex())
1048              {
1049                  valid=1;
1050                  viewIndex = uiBaseId;
1051                  break;
1052              }
1053          }
1054      }
1055  }
1056  if( valid )
1057  {
1058      pcSlice->setDefaultRefViewIdx( viewIndex );
1059      pcSlice->setDefaultRefViewIdxAvailableFlag( true );   
1060  }
1061#endif
1062
1063  // for every CU in slice
1064#if H_3D
1065  Int iLastPosY = -1;
1066#endif
1067  UInt uiEncCUOrder;
1068  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1069       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1070       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1071  {
1072    // initialize CU encoder
1073    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1074    pcCU->initCU( rpcPic, uiCUAddr );
1075#if H_3D_VSO
1076    if ( m_pcRdCost->getUseRenModel() )
1077    {
1078      // updated renderer model if necessary
1079      Int iCurPosX;
1080      Int iCurPosY; 
1081      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
1082      if ( iCurPosY != iLastPosY )
1083      {
1084        iLastPosY = iCurPosY;         
1085        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY );
1086      }
1087    }
1088#endif
1089    // inherit from TR if necessary, select substream to use.
1090      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1091      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1092      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1093      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1094      uiCol     = uiCUAddr % uiWidthInLCUs;
1095      uiLin     = uiCUAddr / uiWidthInLCUs;
1096      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1097      {
1098        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1099        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1100        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1101                      + uiLin%iNumSubstreamsPerTile;
1102      }
1103      else
1104      {
1105        // dependent tiles => substreams are "per frame".
1106        uiSubStrm = uiLin % iNumSubstreams;
1107      }
1108      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1109      {
1110        // We'll sync if the TR is available.
1111        TComDataCU *pcCUUp = pcCU->getCUAbove();
1112        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1113        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1114        TComDataCU *pcCUTR = NULL;
1115        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1116        {
1117          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1118        }
1119        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1120             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1121             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1122             )
1123           )
1124        {
1125          // TR not available.
1126        }
1127        else
1128        {
1129          // TR is available, we use it.
1130          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1131        }
1132      }
1133      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1134
1135    // reset the entropy coder
1136    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1137        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1138        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1139        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1140    {
1141      SliceType sliceType = pcSlice->getSliceType();
1142      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1143      {
1144        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1145      }
1146      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1147      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1148      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1149      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1150    }
1151
1152      // set go-on entropy coder
1153      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1154      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1155     
1156      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1157
1158      Double oldLambda = m_pcRdCost->getLambda();
1159      if ( m_pcCfg->getUseRateCtrl() )
1160      {
1161        Int estQP        = pcSlice->getSliceQp();
1162        Double estLambda = -1.0;
1163        Double bpp       = -1.0;
1164
1165        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1166        {
1167          estQP = pcSlice->getSliceQp();
1168        }
1169        else
1170        {
1171#if KWU_RC_MADPRED_E0227
1172          if(pcSlice->getLayerId() != 0 && m_pcCfg->getUseDepthMADPred() && !pcSlice->getIsDepth())
1173          {
1174            Double zn, zf, focallength, position, camShift;
1175            Double basePos;
1176            Bool bInterpolated;
1177            Int direction = pcSlice->getViewId() - pcCU->getSlice()->getIvPic(false, 0)->getViewId();
1178            Int disparity;
1179
1180            pcEncTop->getCamParam()->xGetZNearZFar(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), zn, zf);
1181            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[0], pcSlice->getPOC(), focallength, basePos, camShift, bInterpolated);
1182            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), focallength, position, camShift, bInterpolated);
1183            bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBppforInterView( m_pcRateCtrl->getPicList(), pcCU,
1184              basePos, position, focallength, zn, zf, (direction > 0 ? 1 : -1), &disparity );
1185          }
1186          else
1187          {
1188#endif
1189          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1190          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1191          {
1192            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1193          }
1194          else
1195          {
1196            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1197            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1198          }
1199#if KWU_RC_MADPRED_E0227
1200          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1201          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1202#endif
1203          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1204
1205          m_pcRdCost->setLambda(estLambda);
1206#if RDOQ_CHROMA_LAMBDA
1207          // set lambda for RDOQ
1208          Double weight=m_pcRdCost->getChromaWeight();
1209        const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
1210        m_pcTrQuant->setLambdas( lambdaArray );
1211#else
1212          m_pcTrQuant->setLambda( estLambda );
1213#endif
1214        }
1215
1216        m_pcRateCtrl->setRCQP( estQP );
1217#if ADAPTIVE_QP_SELECTION
1218        pcCU->getSlice()->setSliceQpBase( estQP );
1219#endif
1220      }
1221      // run CU encoder
1222      m_pcCuEncoder->compressCU( pcCU );
1223
1224      // restore entropy coder to an initial stage
1225      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1226      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1227      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1228      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1229      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1230      m_pcBitCounter->resetBits();
1231      pppcRDSbacCoder->setBinsCoded( 0 );
1232      m_pcCuEncoder->encodeCU( pcCU );
1233
1234      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1235      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1236      {
1237        pcSlice->setNextSlice( true );
1238        break;
1239      }
1240      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1241      {
1242        pcSlice->setNextSliceSegment( true );
1243        break;
1244      }
1245       
1246    ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1247         //Store probabilties of second LCU in line into buffer
1248         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1249        {
1250          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1251        }
1252
1253      if ( m_pcCfg->getUseRateCtrl() )
1254      {
1255#if KWU_RC_MADPRED_E0227
1256        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1257        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1258        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1259        Double MAD = (Double)SAD / (Double)(height * width);
1260        MAD = MAD * MAD;
1261        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1262#endif
1263
1264        Int actualQP        = g_RCInvalidQPValue;
1265        Double actualLambda = m_pcRdCost->getLambda();
1266        Int actualBits      = pcCU->getTotalBits();
1267        Int numberOfEffectivePixels    = 0;
1268        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1269        {
1270          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1271          {
1272            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1273            break;
1274          }
1275        }
1276
1277        if ( numberOfEffectivePixels == 0 )
1278        {
1279          actualQP = g_RCInvalidQPValue;
1280        }
1281        else
1282        {
1283          actualQP = pcCU->getQP( 0 );
1284        }
1285        m_pcRdCost->setLambda(oldLambda);
1286
1287        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1288          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1289    }
1290   
1291    m_uiPicTotalBits += pcCU->getTotalBits();
1292    m_dPicRdCost     += pcCU->getTotalCost();
1293    m_uiPicDist      += pcCU->getTotalDistortion();
1294  }
1295  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1296  {
1297    pcSlice->setNextSlice( true );
1298  }
1299  if(m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES || m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES)
1300  {
1301    if(pcSlice->getSliceCurEndCUAddr()<=pcSlice->getSliceSegmentCurEndCUAddr())
1302    {
1303       pcSlice->setNextSlice( true );
1304    }
1305    else
1306    {
1307       pcSlice->setNextSliceSegment( true );
1308    }
1309  }
1310  if( depSliceSegmentsEnabled )
1311  {
1312    if (m_pcCfg->getWaveFrontsynchro())
1313    {
1314      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1315    }
1316     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1317  }
1318  xRestoreWPparam( pcSlice );
1319}
1320
1321/**
1322 \param  rpcPic        picture class
1323 \retval rpcBitstream  bitstream class
1324 */
1325Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1326{
1327  UInt       uiCUAddr;
1328  UInt       uiStartCUAddr;
1329  UInt       uiBoundingCUAddr;
1330  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1331
1332  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1333  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1334  // choose entropy coder
1335  {
1336    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1337    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1338  }
1339 
1340  m_pcCuEncoder->setBitCounter( NULL );
1341  m_pcBitCounter = NULL;
1342  // Appropriate substream bitstream is switched later.
1343  // for every CU
1344#if ENC_DEC_TRACE
1345  g_bJustDoIt = g_bEncDecTraceEnable;
1346#endif
1347  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1348  DTRACE_CABAC_T( "\tPOC: " );
1349  DTRACE_CABAC_V( rpcPic->getPOC() );
1350#if H_MV_ENC_DEC_TRAC
1351  DTRACE_CABAC_T( " Layer: " );
1352  DTRACE_CABAC_V( rpcPic->getLayerId() );
1353#endif
1354  DTRACE_CABAC_T( "\n" );
1355#if ENC_DEC_TRACE
1356  g_bJustDoIt = g_bEncDecTraceDisable;
1357#endif
1358
1359  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1360  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1361  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1362  UInt uiBitsOriginallyInSubstreams = 0;
1363  {
1364    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1365    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1366    {
1367      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1368    }
1369   
1370    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1371    {
1372      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1373    }
1374
1375    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1376    {
1377      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1378    }
1379  }
1380
1381  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1382  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1383  UInt uiTileCol      = 0;
1384  UInt uiTileStartLCU = 0;
1385  UInt uiTileLCUX     = 0;
1386  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1387  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1388                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1389                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1390  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1391  if( depSliceSegmentsEnabled )
1392  {
1393    if( pcSlice->isNextSlice()||
1394        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1395    {
1396      if(m_pcCfg->getWaveFrontsynchro())
1397      {
1398        CTXMem[1]->loadContexts(m_pcSbacCoder);
1399      }
1400      CTXMem[0]->loadContexts(m_pcSbacCoder);
1401    }
1402    else
1403    {
1404      if(m_pcCfg->getWaveFrontsynchro())
1405      {
1406        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1407        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1408        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1409        uiLin     = uiCUAddr / uiWidthInLCUs;
1410        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1411          + uiLin%iNumSubstreamsPerTile;
1412        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1413        {
1414          uiCol     = uiCUAddr % uiWidthInLCUs;
1415          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1416          if(uiCol==uiTileLCUX)
1417          {
1418            CTXMem[0]->loadContexts(m_pcSbacCoder);
1419          }
1420        }
1421      }
1422      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1423    }
1424  }
1425
1426  UInt uiEncCUOrder;
1427  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1428       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1429       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1430  {
1431      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1432      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1433      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1434      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1435      uiCol     = uiCUAddr % uiWidthInLCUs;
1436      uiLin     = uiCUAddr / uiWidthInLCUs;
1437      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1438      {
1439        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1440        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1441        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1442                      + uiLin%iNumSubstreamsPerTile;
1443      }
1444      else
1445      {
1446        // dependent tiles => substreams are "per frame".
1447        uiSubStrm = uiLin % iNumSubstreams;
1448      }
1449
1450      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1451      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1452      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1453      {
1454        // We'll sync if the TR is available.
1455        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1456        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1457        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1458        TComDataCU *pcCUTR = NULL;
1459        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1460        {
1461          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1462        }
1463        if ( (true/*bEnforceSliceRestriction*/ &&
1464             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1465             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1466             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1467             ))
1468           )
1469        {
1470          // TR not available.
1471        }
1472        else
1473        {
1474          // TR is available, we use it.
1475          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1476        }
1477      }
1478      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1479
1480    // reset the entropy coder
1481    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1482        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1483        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1484        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1485    {
1486      {
1487        // We're crossing into another tile, tiles are independent.
1488        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1489        // have to perform it here.
1490        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1491        {
1492          ; // do nothing.
1493        }
1494        else
1495        {
1496          SliceType sliceType  = pcSlice->getSliceType();
1497          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1498          {
1499            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1500          }
1501          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1502          // Byte-alignment in slice_data() when new tile
1503          pcSubstreams[uiSubStrm].writeByteAlignment();
1504        }
1505      }
1506      {
1507        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1508        UInt uiAccumulatedSubstreamLength = 0;
1509        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1510        {
1511          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1512        }
1513        // add bits coded in previous dependent slices + bits coded so far
1514        // add number of emulation prevention byte count in the tile
1515        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1516      }
1517    }
1518
1519#if H_3D_QTLPC
1520    rpcPic->setReduceBitsFlag(true);
1521#endif
1522    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1523    if ( pcSlice->getSPS()->getUseSAO() )
1524    {
1525      if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
1526      {
1527        SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[uiCUAddr];
1528        Bool sliceEnabled[NUM_SAO_COMPONENTS];
1529        sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
1530        sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
1531
1532        Bool leftMergeAvail = false;
1533        Bool aboveMergeAvail= false;
1534        //merge left condition
1535        Int rx = (uiCUAddr % uiWidthInLCUs);
1536        if(rx > 0)
1537        {
1538          leftMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-1);
1539        }
1540
1541        //merge up condition
1542        Int ry = (uiCUAddr / uiWidthInLCUs);
1543        if(ry > 0)
1544      {
1545          aboveMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-uiWidthInLCUs);
1546        }
1547
1548        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail);
1549      }
1550    }
1551#if ENC_DEC_TRACE
1552    g_bJustDoIt = g_bEncDecTraceEnable;
1553#endif
1554    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1555      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1556    {
1557      m_pcCuEncoder->encodeCU( pcCU );
1558    }
1559    else
1560    {
1561      m_pcCuEncoder->encodeCU( pcCU );
1562    }
1563#if ENC_DEC_TRACE
1564    g_bJustDoIt = g_bEncDecTraceDisable;
1565#endif   
1566       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1567       
1568
1569       //Store probabilties of second LCU in line into buffer
1570       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1571      {
1572        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1573      }
1574#if H_3D_QTLPC
1575    rpcPic->setReduceBitsFlag(false);
1576#endif
1577  }
1578  if( depSliceSegmentsEnabled )
1579  {
1580    if (m_pcCfg->getWaveFrontsynchro())
1581    {
1582      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1583    }
1584    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1585  }
1586#if ADAPTIVE_QP_SELECTION
1587  if( m_pcCfg->getUseAdaptQpSelect() )
1588  {
1589    m_pcTrQuant->storeSliceQpNext(pcSlice);
1590  }
1591#endif
1592  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1593  {
1594    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1595    {
1596      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1597    }
1598    else
1599    {
1600      m_pcEntropyCoder->determineCabacInitIdx();
1601    }
1602  }
1603}
1604
1605/** Determines the starting and bounding LCU address of current slice / dependent slice
1606 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1607 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1608 */
1609Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1610{
1611  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1612  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1613  UInt tileIdxIncrement;
1614  UInt tileIdx;
1615  UInt tileWidthInLcu;
1616  UInt tileHeightInLcu;
1617  UInt tileTotalCount;
1618
1619  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1620  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1621  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1622  if (bEncodeSlice) 
1623  {
1624    UInt uiCUAddrIncrement;
1625    switch (m_pcCfg->getSliceMode())
1626    {
1627    case FIXED_NUMBER_OF_LCU:
1628      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1629      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1630      break;
1631    case FIXED_NUMBER_OF_BYTES:
1632      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1633      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1634      break;
1635    case FIXED_NUMBER_OF_TILES:
1636      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1637        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1638        );
1639      uiCUAddrIncrement        = 0;
1640      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1641
1642      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1643      {
1644        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1645        {
1646          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1647          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1648          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1649        }
1650      }
1651
1652      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1653      break;
1654    default:
1655      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1656      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1657      break;
1658    } 
1659    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1660    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1661    {
1662      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1663    }
1664    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1665  }
1666  else
1667  {
1668    UInt uiCUAddrIncrement     ;
1669    switch (m_pcCfg->getSliceMode())
1670    {
1671    case FIXED_NUMBER_OF_LCU:
1672      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1673      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1674      break;
1675    case FIXED_NUMBER_OF_TILES:
1676      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1677        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1678        );
1679      uiCUAddrIncrement        = 0;
1680      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1681
1682      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1683      {
1684        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1685        {
1686          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1687          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1688          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1689        }
1690      }
1691
1692      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1693      break;
1694    default:
1695      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1696      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1697      break;
1698    } 
1699    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1700    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1701    {
1702      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1703    }
1704    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1705  }
1706
1707  Bool tileBoundary = false;
1708  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1709      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1710  {
1711    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1712    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1713    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1714    UInt tileBoundingCUAddrSlice = 0;
1715    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1716    {
1717      lcuEncAddr++;
1718      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1719    }
1720    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1721   
1722    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1723    {
1724      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1725      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1726      tileBoundary = true;
1727    }
1728  }
1729
1730  // Dependent slice
1731  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1732  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1733  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1734  if (bEncodeSlice) 
1735  {
1736    UInt uiCUAddrIncrement;
1737    switch (m_pcCfg->getSliceSegmentMode())
1738    {
1739    case FIXED_NUMBER_OF_LCU:
1740      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1741      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1742      break;
1743    case FIXED_NUMBER_OF_BYTES:
1744      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1745      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1746      break;
1747    case FIXED_NUMBER_OF_TILES:
1748      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1749        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1750        );
1751      uiCUAddrIncrement        = 0;
1752      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1753
1754      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1755      {
1756        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1757        {
1758          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1759          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1760          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1761        }
1762      }
1763      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1764      break;
1765    default:
1766      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1767      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1768      break;
1769    } 
1770    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1771    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1772    {
1773      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1774    }
1775    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1776  }
1777  else
1778  {
1779    UInt uiCUAddrIncrement;
1780    switch (m_pcCfg->getSliceSegmentMode())
1781    {
1782    case FIXED_NUMBER_OF_LCU:
1783      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1784      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1785      break;
1786    case FIXED_NUMBER_OF_TILES:
1787      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1788        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1789        );
1790      uiCUAddrIncrement        = 0;
1791      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1792
1793      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1794      {
1795        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1796        {
1797          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1798          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1799          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1800        }
1801      }
1802      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1803      break;
1804    default:
1805      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1806      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1807      break;
1808    } 
1809    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1810    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1811    {
1812      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1813    }
1814    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1815  }
1816  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1817    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1818  {
1819    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1820    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1821    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1822    UInt tileBoundingCUAddrSlice = 0;
1823    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1824    {
1825      lcuEncAddr++;
1826      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1827    }
1828    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1829
1830    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1831    {
1832      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1833      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1834      tileBoundary = true;
1835    }
1836  }
1837
1838  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1839  {
1840    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1841    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1842  }
1843
1844  //calculate real dependent slice start address
1845  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1846  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1847  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1848  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1849  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1850  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1851  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1852  {
1853    uiInternalAddress++;
1854    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1855    {
1856      uiInternalAddress=0;
1857      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1858    }
1859    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1860    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1861  }
1862  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1863 
1864  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1865  startCUAddrSliceSegment=uiRealStartAddress;
1866 
1867  //calculate real slice start address
1868  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1869  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1870  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1871  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1872  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1873  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1874  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1875  {
1876    uiInternalAddress++;
1877    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1878    {
1879      uiInternalAddress=0;
1880      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1881    }
1882    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1883    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1884  }
1885  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1886 
1887  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1888  uiStartCUAddrSlice=uiRealStartAddress;
1889 
1890  // Make a joint decision based on reconstruction and dependent slice bounds
1891  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1892  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1893
1894
1895  if (!bEncodeSlice)
1896  {
1897    // 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
1898    // first. Set the flags accordingly.
1899    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1900      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1901      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1902      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1903      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1904      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1905      || tileBoundary
1906)
1907    {
1908      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1909      {
1910        pcSlice->setNextSlice       ( true );
1911        pcSlice->setNextSliceSegment( false );
1912      }
1913      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1914      {
1915        pcSlice->setNextSlice       ( false );
1916        pcSlice->setNextSliceSegment( true );
1917      }
1918      else
1919      {
1920        pcSlice->setNextSlice       ( true );
1921        pcSlice->setNextSliceSegment( true );
1922      }
1923    }
1924    else
1925    {
1926      pcSlice->setNextSlice       ( false );
1927      pcSlice->setNextSliceSegment( false );
1928    }
1929  }
1930}
1931
1932Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1933{
1934  return 4.2005*log(lambda) + 13.7122;
1935}
1936
1937//! \}
Note: See TracBrowser for help on using the repository browser.