source: SHVCSoftware/branches/SHM-2.1-multilayers-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 260

Last change on this file since 260 was 260, checked in by seregin, 11 years ago

TMVP setting fix, encoder speed up fix, and other minor corrections

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