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

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

use only highest layer as a BL for IntraBL

File size: 81.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 ( m_pcCfg->getDeblockingFilterMetric() )
428  {
429    rpcSlice->setDeblockingFilterOverrideFlag(true);
430    rpcSlice->setDeblockingFilterDisable(false);
431    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
432    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
433  } else
434  if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
435  {
436    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
437    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
438    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
439    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
440    if ( !rpcSlice->getDeblockingFilterDisable())
441    {
442      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
443      {
444        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
445        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
446        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
447        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
448      }
449      else
450      {
451      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
452      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
453      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
454      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
455      }
456    }
457  }
458  else
459  {
460    rpcSlice->setDeblockingFilterOverrideFlag( false );
461    rpcSlice->setDeblockingFilterDisable( false );
462    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
463    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
464  }
465
466  rpcSlice->setDepth            ( depth );
467 
468  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
469  if(eSliceType==I_SLICE)
470  {
471    pcPic->setTLayer(0);
472  }
473  rpcSlice->setTLayer( pcPic->getTLayer() );
474
475  assert( m_apcPicYuvPred );
476  assert( m_apcPicYuvResi );
477 
478  pcPic->setPicYuvPred( m_apcPicYuvPred );
479  pcPic->setPicYuvResi( m_apcPicYuvResi );
480  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
481  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
482  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
483  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
484  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
485  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
486
487#if SVC_EXTENSION && REF_IDX_FRAMEWORK
488  if( layerId > 0 )
489  {
490#if JCTVC_M0458_INTERLAYER_RPS_SIG
491    if( rpcSlice->getNumILRRefIdx() > 0 )
492    {
493      rpcSlice->setActiveNumILRRefIdx( m_ppcTEncTop[layerId]->getNumActiveRefLayers() );
494      for( Int i = 0; i < rpcSlice->getActiveNumILRRefIdx(); i++ )
495      {
496        rpcSlice->setInterLayerPredLayerIdc( m_ppcTEncTop[layerId]->getPredLayerId(i), i );
497      }
498      rpcSlice->setInterLayerPredEnabledFlag(1);
499    }
500#else
501    rpcSlice->setNumILRRefIdx( rpcSlice->getVPS()->getNumDirectRefLayers( layerId ) );
502#endif
503#if M0457_COL_PICTURE_SIGNALING
504    rpcSlice->setMFMEnabledFlag(m_ppcTEncTop[layerId]->getMFMEnabledFlag());
505    rpcSlice->setAltColIndicationFlag(rpcSlice->getMFMEnabledFlag());
506#endif
507  }
508
509#endif
510}
511
512#if RATE_CONTROL_LAMBDA_DOMAIN
513Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
514{
515  TComSlice* slice = pic->getSlice(0);
516
517  // store lambda
518  slice->setSliceQp( sliceQP );
519  slice->setSliceQpBase ( sliceQP );
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 */
826#if RATE_CONTROL_INTRA
827Void TEncSlice::calCostSliceI(TComPic*& rpcPic)
828{
829  UInt    uiCUAddr;
830  UInt    uiStartCUAddr;
831  UInt    uiBoundingCUAddr;
832  Int     iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;;
833  Double  iSumHadSlice = 0;
834
835  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
836  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
837  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
838
839  UInt uiEncCUOrder;
840  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
841  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
842       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
843       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
844  {
845    // initialize CU encoder
846    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
847    pcCU->initCU( rpcPic, uiCUAddr );
848
849    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
850    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
851
852    iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height);
853
854    (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift;
855    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra;
856
857  }
858  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
859}
860#endif
861
862Void TEncSlice::compressSlice( TComPic*& rpcPic )
863{
864  UInt  uiCUAddr;
865  UInt   uiStartCUAddr;
866  UInt   uiBoundingCUAddr;
867  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
868  TEncBinCABAC* pppcRDSbacCoder = NULL;
869  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
870  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
871 
872  // initialize cost values
873  m_uiPicTotalBits  = 0;
874  m_dPicRdCost      = 0;
875  m_uiPicDist       = 0;
876 
877  // set entropy coder
878  if( m_pcCfg->getUseSBACRD() )
879  {
880    m_pcSbacCoder->init( m_pcBinCABAC );
881    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
882    m_pcEntropyCoder->resetEntropy      ();
883    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
884    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
885    pppcRDSbacCoder->setBinCountingEnableFlag( false );
886    pppcRDSbacCoder->setBinsCoded( 0 );
887  }
888  else
889  {
890    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
891    m_pcEntropyCoder->resetEntropy      ();
892    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
893  }
894 
895  //------------------------------------------------------------------------------
896  //  Weighted Prediction parameters estimation.
897  //------------------------------------------------------------------------------
898  // calculate AC/DC values for current picture
899  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
900  {
901    xCalcACDCParamSlice(pcSlice);
902  }
903
904  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
905
906  if ( bWp_explicit )
907  {
908    //------------------------------------------------------------------------------
909    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
910    //------------------------------------------------------------------------------
911    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
912    {
913      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
914    }
915
916    xEstimateWPParamSlice( pcSlice );
917    pcSlice->initWpScaling();
918
919    // check WP on/off
920    xCheckWPEnable( pcSlice );
921  }
922
923#if ADAPTIVE_QP_SELECTION
924  if( m_pcCfg->getUseAdaptQpSelect() )
925  {
926    m_pcTrQuant->clearSliceARLCnt();
927    if(pcSlice->getSliceType()!=I_SLICE)
928    {
929      Int qpBase = pcSlice->getSliceQpBase();
930      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
931    }
932  }
933#endif
934  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
935  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
936  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
937  Int  iNumSubstreams = 1;
938  UInt uiTilesAcross  = 0;
939
940  if( m_pcCfg->getUseSBACRD() )
941  {
942    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
943    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
944    delete[] m_pcBufferSbacCoders;
945    delete[] m_pcBufferBinCoderCABACs;
946    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
947    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
948    for (Int ui = 0; ui < uiTilesAcross; ui++)
949    {
950      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
951    }
952    for (UInt ui = 0; ui < uiTilesAcross; ui++)
953    {
954      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
955    }
956
957    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
958    {
959      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
960    }
961  }
962  //if( m_pcCfg->getUseSBACRD() )
963  {
964    delete[] m_pcBufferLowLatSbacCoders;
965    delete[] m_pcBufferLowLatBinCoderCABACs;
966    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
967    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
968    for (Int ui = 0; ui < uiTilesAcross; ui++)
969    {
970      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
971    }
972    for (UInt ui = 0; ui < uiTilesAcross; ui++)
973      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
974  }
975  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
976  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
977  UInt uiCol=0, uiLin=0, uiSubStrm=0;
978  UInt uiTileCol      = 0;
979  UInt uiTileStartLCU = 0;
980  UInt uiTileLCUX     = 0;
981
982#if INTRA_BL
983  m_pcCuEncoder->setBaseRecPic( rpcPic->getLayerId() > 0 ? rpcPic->getFullPelBaseRec(rpcPic->getLayerId()-1) : NULL);
984#endif
985
986  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
987  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
988  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
989  if( depSliceSegmentsEnabled )
990  {
991    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
992    {
993      if( m_pcCfg->getWaveFrontsynchro() )
994      {
995        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
996        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
997        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
998        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
999        uiLin     = uiCUAddr / uiWidthInLCUs;
1000        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
1001          + uiLin%iNumSubstreamsPerTile;
1002        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1003        {
1004          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1005          uiCol     = uiCUAddr % uiWidthInLCUs;
1006          if(uiCol==uiTileStartLCU)
1007          {
1008            CTXMem[0]->loadContexts(m_pcSbacCoder);
1009          }
1010        }
1011      }
1012      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1013      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1014    }
1015    else
1016    {
1017      if(m_pcCfg->getWaveFrontsynchro())
1018      {
1019        CTXMem[1]->loadContexts(m_pcSbacCoder);
1020      }
1021      CTXMem[0]->loadContexts(m_pcSbacCoder);
1022    }
1023  }
1024  // for every CU in slice
1025  UInt uiEncCUOrder;
1026  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1027       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1028       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1029  {
1030    // initialize CU encoder
1031    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1032    pcCU->initCU( rpcPic, uiCUAddr );
1033
1034#if !RATE_CONTROL_LAMBDA_DOMAIN
1035    if(m_pcCfg->getUseRateCtrl())
1036    {
1037      if(m_pcRateCtrl->calculateUnitQP())
1038      {
1039        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
1040      }
1041    }
1042#endif
1043    // inherit from TR if necessary, select substream to use.
1044    if( m_pcCfg->getUseSBACRD() )
1045    {
1046      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1047      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1048      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1049      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1050      uiCol     = uiCUAddr % uiWidthInLCUs;
1051      uiLin     = uiCUAddr / uiWidthInLCUs;
1052      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1053      {
1054        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1055        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1056        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1057                      + uiLin%iNumSubstreamsPerTile;
1058      }
1059      else
1060      {
1061        // dependent tiles => substreams are "per frame".
1062        uiSubStrm = uiLin % iNumSubstreams;
1063      }
1064      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1065      {
1066        // We'll sync if the TR is available.
1067        TComDataCU *pcCUUp = pcCU->getCUAbove();
1068        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1069        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1070        TComDataCU *pcCUTR = NULL;
1071        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1072        {
1073          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1074        }
1075        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1076             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1077             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1078             )
1079           )
1080        {
1081          // TR not available.
1082        }
1083        else
1084        {
1085          // TR is available, we use it.
1086          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1087        }
1088      }
1089      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1090    }
1091
1092    // reset the entropy coder
1093    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1094        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1095        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1096        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1097    {
1098      SliceType sliceType = pcSlice->getSliceType();
1099      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1100      {
1101        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1102      }
1103      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1104      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1105      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1106      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1107    }
1108    // if RD based on SBAC is used
1109    if( m_pcCfg->getUseSBACRD() )
1110    {
1111      // set go-on entropy coder
1112      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1113      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1114     
1115      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1116
1117#if RATE_CONTROL_LAMBDA_DOMAIN
1118      Double oldLambda = m_pcRdCost->getLambda();
1119      if ( m_pcCfg->getUseRateCtrl() )
1120      {
1121        Int estQP        = pcSlice->getSliceQp();
1122        Double estLambda = -1.0;
1123        Double bpp       = -1.0;
1124
1125#if M0036_RC_IMPROVEMENT
1126        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1127#else
1128        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1129#endif
1130        {
1131          estQP = pcSlice->getSliceQp();
1132        }
1133        else
1134        {
1135#if RATE_CONTROL_INTRA
1136          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1137          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1138          {
1139            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1140          }
1141          else
1142          {
1143            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1144            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1145          }
1146#else
1147          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1148          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1149          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1150#endif
1151
1152          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1153
1154          m_pcRdCost->setLambda(estLambda);
1155#if M0036_RC_IMPROVEMENT
1156#if RDOQ_CHROMA_LAMBDA
1157          // set lambda for RDOQ
1158          Double weight=m_pcRdCost->getChromaWeight();
1159          m_pcTrQuant->setLambda( estLambda, estLambda / weight );
1160#else
1161          m_pcTrQuant->setLambda( estLambda );
1162#endif
1163#endif
1164        }
1165
1166        m_pcRateCtrl->setRCQP( estQP );
1167        pcCU->getSlice()->setSliceQpBase( estQP );
1168      }
1169#endif
1170
1171      // run CU encoder
1172      m_pcCuEncoder->compressCU( pcCU );
1173
1174#if !TICKET_1090_FIX
1175#if RATE_CONTROL_LAMBDA_DOMAIN
1176      if ( m_pcCfg->getUseRateCtrl() )
1177      {
1178#if !M0036_RC_IMPROVEMENT
1179        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1180        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1181        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1182        Double MAD = (Double)SAD / (Double)(height * width);
1183        MAD = MAD * MAD;
1184        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1185#endif
1186
1187        Int actualQP        = g_RCInvalidQPValue;
1188        Double actualLambda = m_pcRdCost->getLambda();
1189        Int actualBits      = pcCU->getTotalBits();
1190        Int numberOfEffectivePixels    = 0;
1191        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1192        {
1193          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1194          {
1195            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1196            break;
1197          }
1198        }
1199
1200        if ( numberOfEffectivePixels == 0 )
1201        {
1202          actualQP = g_RCInvalidQPValue;
1203        }
1204        else
1205        {
1206          actualQP = pcCU->getQP( 0 );
1207        }
1208        m_pcRdCost->setLambda(oldLambda);
1209#if RATE_CONTROL_INTRA
1210        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1211          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1212#else
1213        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1214#endif
1215      }
1216#endif
1217#endif
1218     
1219      // restore entropy coder to an initial stage
1220      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1221      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1222      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1223      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1224      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1225      m_pcBitCounter->resetBits();
1226      pppcRDSbacCoder->setBinsCoded( 0 );
1227      m_pcCuEncoder->encodeCU( pcCU );
1228
1229      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1230      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1231      {
1232        pcSlice->setNextSlice( true );
1233        break;
1234      }
1235      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1236      {
1237        pcSlice->setNextSliceSegment( true );
1238        break;
1239      }
1240      if( m_pcCfg->getUseSBACRD() )
1241      {
1242         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1243       
1244         //Store probabilties of second LCU in line into buffer
1245         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1246        {
1247          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1248        }
1249      }
1250
1251#if TICKET_1090_FIX
1252#if RATE_CONTROL_LAMBDA_DOMAIN
1253      if ( m_pcCfg->getUseRateCtrl() )
1254      {
1255#if !M0036_RC_IMPROVEMENT
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#if RATE_CONTROL_INTRA
1288        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1289          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1290#else
1291        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1292#endif
1293      }
1294#endif
1295#endif
1296    }
1297    // other case: encodeCU is not called
1298    else
1299    {
1300      m_pcCuEncoder->compressCU( pcCU );
1301      m_pcCuEncoder->encodeCU( pcCU );
1302      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1303      {
1304        pcSlice->setNextSlice( true );
1305        break;
1306      }
1307      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1308      {
1309        pcSlice->setNextSliceSegment( true );
1310        break;
1311      }
1312    }
1313   
1314    m_uiPicTotalBits += pcCU->getTotalBits();
1315    m_dPicRdCost     += pcCU->getTotalCost();
1316    m_uiPicDist      += pcCU->getTotalDistortion();
1317#if !RATE_CONTROL_LAMBDA_DOMAIN
1318    if(m_pcCfg->getUseRateCtrl())
1319    {
1320      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1321      m_pcRateCtrl->updataRCUnitStatus();
1322    }
1323#endif
1324  }
1325  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1326  {
1327    pcSlice->setNextSlice( true );
1328  }
1329  if( depSliceSegmentsEnabled )
1330  {
1331    if (m_pcCfg->getWaveFrontsynchro())
1332    {
1333      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1334    }
1335     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1336  }
1337  xRestoreWPparam( pcSlice );
1338#if !RATE_CONTROL_LAMBDA_DOMAIN
1339  if(m_pcCfg->getUseRateCtrl())
1340  {
1341    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1342  }
1343#endif
1344}
1345
1346/**
1347 \param  rpcPic        picture class
1348 \retval rpcBitstream  bitstream class
1349 */
1350Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1351{
1352  UInt       uiCUAddr;
1353  UInt       uiStartCUAddr;
1354  UInt       uiBoundingCUAddr;
1355  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1356
1357  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1358  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1359  // choose entropy coder
1360  {
1361    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1362    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1363  }
1364 
1365  m_pcCuEncoder->setBitCounter( NULL );
1366  m_pcBitCounter = NULL;
1367  // Appropriate substream bitstream is switched later.
1368  // for every CU
1369#if ENC_DEC_TRACE
1370  g_bJustDoIt = g_bEncDecTraceEnable;
1371#endif
1372  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1373  DTRACE_CABAC_T( "\tPOC: " );
1374  DTRACE_CABAC_V( rpcPic->getPOC() );
1375  DTRACE_CABAC_T( "\n" );
1376#if ENC_DEC_TRACE
1377  g_bJustDoIt = g_bEncDecTraceDisable;
1378#endif
1379
1380  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1381  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1382  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1383  UInt uiBitsOriginallyInSubstreams = 0;
1384  {
1385    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1386    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1387    {
1388      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1389    }
1390   
1391    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1392    {
1393      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1394    }
1395
1396    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1397    {
1398      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1399    }
1400  }
1401
1402  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1403  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1404  UInt uiTileCol      = 0;
1405  UInt uiTileStartLCU = 0;
1406  UInt uiTileLCUX     = 0;
1407  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1408  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1409                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1410                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1411  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1412  if( depSliceSegmentsEnabled )
1413  {
1414    if( pcSlice->isNextSlice()||
1415        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1416    {
1417      if(m_pcCfg->getWaveFrontsynchro())
1418      {
1419        CTXMem[1]->loadContexts(m_pcSbacCoder);
1420      }
1421      CTXMem[0]->loadContexts(m_pcSbacCoder);
1422    }
1423    else
1424    {
1425      if(m_pcCfg->getWaveFrontsynchro())
1426      {
1427        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1428        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1429        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1430        uiLin     = uiCUAddr / uiWidthInLCUs;
1431        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1432          + uiLin%iNumSubstreamsPerTile;
1433        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1434        {
1435          uiCol     = uiCUAddr % uiWidthInLCUs;
1436          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1437          if(uiCol==uiTileLCUX)
1438          {
1439            CTXMem[0]->loadContexts(m_pcSbacCoder);
1440          }
1441        }
1442      }
1443      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1444    }
1445  }
1446
1447  UInt uiEncCUOrder;
1448  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1449       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1450       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1451  {
1452    if( m_pcCfg->getUseSBACRD() )
1453    {
1454      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1455      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1456      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1457      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1458      uiCol     = uiCUAddr % uiWidthInLCUs;
1459      uiLin     = uiCUAddr / uiWidthInLCUs;
1460      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1461      {
1462        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1463        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1464        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1465                      + uiLin%iNumSubstreamsPerTile;
1466      }
1467      else
1468      {
1469        // dependent tiles => substreams are "per frame".
1470        uiSubStrm = uiLin % iNumSubstreams;
1471      }
1472
1473      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1474      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1475      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1476      {
1477        // We'll sync if the TR is available.
1478        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1479        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1480        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1481        TComDataCU *pcCUTR = NULL;
1482        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1483        {
1484          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1485        }
1486        if ( (true/*bEnforceSliceRestriction*/ &&
1487             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1488             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1489             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1490             ))
1491           )
1492        {
1493          // TR not available.
1494        }
1495        else
1496        {
1497          // TR is available, we use it.
1498          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1499        }
1500      }
1501      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1502    }
1503    // reset the entropy coder
1504    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1505        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1506        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1507        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1508    {
1509      {
1510        // We're crossing into another tile, tiles are independent.
1511        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1512        // have to perform it here.
1513        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1514        {
1515          ; // do nothing.
1516        }
1517        else
1518        {
1519          SliceType sliceType  = pcSlice->getSliceType();
1520          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1521          {
1522            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1523          }
1524          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1525          // Byte-alignment in slice_data() when new tile
1526          pcSubstreams[uiSubStrm].writeByteAlignment();
1527        }
1528      }
1529      {
1530        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1531        UInt uiAccumulatedSubstreamLength = 0;
1532        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1533        {
1534          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1535        }
1536        // add bits coded in previous dependent slices + bits coded so far
1537        // add number of emulation prevention byte count in the tile
1538        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1539      }
1540    }
1541
1542    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1543    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1544    {
1545      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1546      Int iNumCuInWidth     = saoParam->numCuInWidth;
1547      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1548      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1549      Int rx = uiCUAddr % iNumCuInWidth;
1550      Int ry = uiCUAddr / iNumCuInWidth;
1551      Int allowMergeLeft = 1;
1552      Int allowMergeUp   = 1;
1553      if (rx!=0)
1554      {
1555        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1556        {
1557          allowMergeLeft = 0;
1558        }
1559      }
1560      if (ry!=0)
1561      {
1562        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1563        {
1564          allowMergeUp = 0;
1565        }
1566      }
1567      Int addr = pcCU->getAddr();
1568      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1569      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1570      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1571      {
1572        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1573        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1574        if (allowMergeLeft)
1575        {
1576          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1577        }
1578        else
1579        {
1580          mergeLeft = 0;
1581        }
1582        if(mergeLeft == 0)
1583        {
1584          if (allowMergeUp)
1585          {
1586            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1587          }
1588          else
1589          {
1590            mergeUp = 0;
1591          }
1592          if(mergeUp == 0)
1593          {
1594            for (Int compIdx=0;compIdx<3;compIdx++)
1595            {
1596            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1597              {
1598                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1599              }
1600            }
1601          }
1602        }
1603      }
1604    }
1605    else if (pcSlice->getSPS()->getUseSAO())
1606    {
1607      Int addr = pcCU->getAddr();
1608      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1609      for (Int cIdx=0; cIdx<3; cIdx++)
1610      {
1611        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1612        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1613        {
1614          saoLcuParam->mergeUpFlag   = 0;
1615          saoLcuParam->mergeLeftFlag = 0;
1616          saoLcuParam->subTypeIdx    = 0;
1617          saoLcuParam->typeIdx       = -1;
1618          saoLcuParam->offset[0]     = 0;
1619          saoLcuParam->offset[1]     = 0;
1620          saoLcuParam->offset[2]     = 0;
1621          saoLcuParam->offset[3]     = 0;
1622        }
1623      }
1624    }
1625#if ENC_DEC_TRACE
1626    g_bJustDoIt = g_bEncDecTraceEnable;
1627#endif
1628    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1629      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1630    {
1631      m_pcCuEncoder->encodeCU( pcCU );
1632    }
1633    else
1634    {
1635      m_pcCuEncoder->encodeCU( pcCU );
1636    }
1637#if ENC_DEC_TRACE
1638    g_bJustDoIt = g_bEncDecTraceDisable;
1639#endif   
1640    if( m_pcCfg->getUseSBACRD() )
1641    {
1642       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1643       
1644
1645       //Store probabilties of second LCU in line into buffer
1646       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1647      {
1648        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1649      }
1650    }
1651  }
1652  if( depSliceSegmentsEnabled )
1653  {
1654    if (m_pcCfg->getWaveFrontsynchro())
1655    {
1656      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1657    }
1658    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1659  }
1660#if ADAPTIVE_QP_SELECTION
1661  if( m_pcCfg->getUseAdaptQpSelect() )
1662  {
1663    m_pcTrQuant->storeSliceQpNext(pcSlice);
1664  }
1665#endif
1666  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1667  {
1668    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1669    {
1670      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1671    }
1672    else
1673    {
1674      m_pcEntropyCoder->determineCabacInitIdx();
1675    }
1676  }
1677}
1678
1679/** Determines the starting and bounding LCU address of current slice / dependent slice
1680 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1681 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1682 */
1683Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1684{
1685  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1686  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1687  UInt tileIdxIncrement;
1688  UInt tileIdx;
1689  UInt tileWidthInLcu;
1690  UInt tileHeightInLcu;
1691  UInt tileTotalCount;
1692
1693  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1694  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1695  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1696  if (bEncodeSlice) 
1697  {
1698    UInt uiCUAddrIncrement;
1699    switch (m_pcCfg->getSliceMode())
1700    {
1701    case FIXED_NUMBER_OF_LCU:
1702      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1703      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1704      break;
1705    case FIXED_NUMBER_OF_BYTES:
1706      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1707      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1708      break;
1709    case FIXED_NUMBER_OF_TILES:
1710      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1711        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1712        );
1713      uiCUAddrIncrement        = 0;
1714      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1715
1716      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1717      {
1718        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1719        {
1720          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1721          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1722          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1723        }
1724      }
1725
1726      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1727      break;
1728    default:
1729      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1730      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1731      break;
1732    } 
1733    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1734    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1735    {
1736      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1737    }
1738    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1739  }
1740  else
1741  {
1742    UInt uiCUAddrIncrement     ;
1743    switch (m_pcCfg->getSliceMode())
1744    {
1745    case FIXED_NUMBER_OF_LCU:
1746      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1747      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1748      break;
1749    case FIXED_NUMBER_OF_TILES:
1750      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1751        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1752        );
1753      uiCUAddrIncrement        = 0;
1754      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1755
1756      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1757      {
1758        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1759        {
1760          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1761          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1762          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1763        }
1764      }
1765
1766      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1767      break;
1768    default:
1769      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1770      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1771      break;
1772    } 
1773    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1774    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1775    {
1776      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1777    }
1778    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1779  }
1780
1781  Bool tileBoundary = false;
1782  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1783      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1784  {
1785    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1786    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1787    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1788    UInt tileBoundingCUAddrSlice = 0;
1789    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1790    {
1791      lcuEncAddr++;
1792      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1793    }
1794    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1795   
1796    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1797    {
1798      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1799      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1800      tileBoundary = true;
1801    }
1802  }
1803
1804  // Dependent slice
1805  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1806  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1807  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1808  if (bEncodeSlice) 
1809  {
1810    UInt uiCUAddrIncrement;
1811    switch (m_pcCfg->getSliceSegmentMode())
1812    {
1813    case FIXED_NUMBER_OF_LCU:
1814      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1815      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1816      break;
1817    case FIXED_NUMBER_OF_BYTES:
1818      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1819      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1820      break;
1821    case FIXED_NUMBER_OF_TILES:
1822      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1823        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1824        );
1825      uiCUAddrIncrement        = 0;
1826      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1827
1828      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1829      {
1830        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1831        {
1832          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1833          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1834          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1835        }
1836      }
1837      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1838      break;
1839    default:
1840      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1841      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1842      break;
1843    } 
1844    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1845    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1846    {
1847      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1848    }
1849    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1850  }
1851  else
1852  {
1853    UInt uiCUAddrIncrement;
1854    switch (m_pcCfg->getSliceSegmentMode())
1855    {
1856    case FIXED_NUMBER_OF_LCU:
1857      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1858      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1859      break;
1860    case FIXED_NUMBER_OF_TILES:
1861      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1862        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1863        );
1864      uiCUAddrIncrement        = 0;
1865      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1866
1867      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1868      {
1869        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1870        {
1871          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1872          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1873          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1874        }
1875      }
1876      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1877      break;
1878    default:
1879      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1880      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1881      break;
1882    } 
1883    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1884    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1885    {
1886      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1887    }
1888    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1889  }
1890  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1891    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1892  {
1893    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1894    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1895    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1896    UInt tileBoundingCUAddrSlice = 0;
1897    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1898    {
1899      lcuEncAddr++;
1900      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1901    }
1902    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1903
1904    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1905    {
1906      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1907      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1908      tileBoundary = true;
1909    }
1910  }
1911
1912  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1913  {
1914    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1915    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1916  }
1917
1918  //calculate real dependent slice start address
1919  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1920  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1921  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1922  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1923  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1924  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1925  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1926  {
1927    uiInternalAddress++;
1928    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1929    {
1930      uiInternalAddress=0;
1931      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1932    }
1933    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1934    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1935  }
1936  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1937 
1938  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1939  startCUAddrSliceSegment=uiRealStartAddress;
1940 
1941  //calculate real slice start address
1942  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1943  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1944  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1945  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1946  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1947  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1948  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1949  {
1950    uiInternalAddress++;
1951    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1952    {
1953      uiInternalAddress=0;
1954      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1955    }
1956    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1957    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1958  }
1959  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1960 
1961  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1962  uiStartCUAddrSlice=uiRealStartAddress;
1963 
1964  // Make a joint decision based on reconstruction and dependent slice bounds
1965  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1966  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1967
1968
1969  if (!bEncodeSlice)
1970  {
1971    // 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
1972    // first. Set the flags accordingly.
1973    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1974      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1975      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1976      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1977      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1978      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1979      || tileBoundary
1980)
1981    {
1982      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1983      {
1984        pcSlice->setNextSlice       ( true );
1985        pcSlice->setNextSliceSegment( false );
1986      }
1987      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1988      {
1989        pcSlice->setNextSlice       ( false );
1990        pcSlice->setNextSliceSegment( true );
1991      }
1992      else
1993      {
1994        pcSlice->setNextSlice       ( true );
1995        pcSlice->setNextSliceSegment( true );
1996      }
1997    }
1998    else
1999    {
2000      pcSlice->setNextSlice       ( false );
2001      pcSlice->setNextSliceSegment( false );
2002    }
2003  }
2004}
2005
2006Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
2007{
2008  return 4.2005*log(lambda) + 13.7122;
2009}
2010
2011#if JCTVC_M0259_LAMBDAREFINEMENT
2012Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
2013{
2014  double tmp = beta * pow( 2.0 , deltaQP / 6 );
2015  double gamma = tmp / ( tmp + 1 );
2016  return( gamma );
2017}
2018#endif
2019//! \}
Note: See TracBrowser for help on using the repository browser.