source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 872

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

merge with SHM-6-dev

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