source: SHVCSoftware/branches/SHM-3.0-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 462

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

fix active ref layers for JCTVC_M0259_LAMBDAREFINEMENT

  • Property svn:eol-style set to native
File size: 79.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 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && 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_ppcTEncTop[layerId]->getNumActiveRefLayers() && 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#if !REMOVE_COL_PICTURE_SIGNALING
506    rpcSlice->setAltColIndicationFlag(rpcSlice->getMFMEnabledFlag());
507#endif
508#endif
509  }
510
511#endif
512}
513
514#if RATE_CONTROL_LAMBDA_DOMAIN
515Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
516{
517  TComSlice* slice = pic->getSlice(0);
518
519  // store lambda
520  slice->setSliceQp( sliceQP );
521  slice->setSliceQpBase ( sliceQP );
522  m_pcRdCost ->setLambda( lambda );
523#if WEIGHTED_CHROMA_DISTORTION
524  // for RDO
525  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
526  Double weight;
527  Int qpc;
528  Int chromaQPOffset;
529
530  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
531  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
532  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
533  m_pcRdCost->setCbDistortionWeight(weight);
534
535  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
536  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
537  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
538  m_pcRdCost->setCrDistortionWeight(weight);
539#endif
540
541#if RDOQ_CHROMA_LAMBDA
542  // for RDOQ
543  m_pcTrQuant->setLambda( lambda, lambda / weight );
544#else
545  m_pcTrQuant->setLambda( lambda );
546#endif
547
548#if SAO_CHROMA_LAMBDA
549  // For SAO
550  slice   ->setLambda( lambda, lambda / weight );
551#else
552  slice   ->setLambda( lambda );
553#endif
554}
555#else
556/**
557 - lambda re-computation based on rate control QP
558 */
559Void TEncSlice::xLamdaRecalculation(Int changeQP, Int idGOP, Int depth, SliceType eSliceType, TComSPS* pcSPS, TComSlice* pcSlice)
560{
561  Int qp;
562  Double recalQP= (Double)changeQP;
563  Double origQP = (Double)recalQP;
564  Double lambda;
565
566  // pre-compute lambda and QP values for all possible QP candidates
567  for ( Int deltqQpIdx = 0; deltqQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; deltqQpIdx++ )
568  {
569    // compute QP value
570    recalQP = origQP + ((deltqQpIdx+1)>>1)*(deltqQpIdx%2 ? -1 : 1);
571
572    // compute lambda value
573    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
574    Int    SHIFT_QP = 12;
575    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
576#if FULL_NBIT
577    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
578#else
579    Int    bitdepth_luma_qp_scale = 0;
580#endif
581    Double qp_temp = (Double) recalQP + bitdepth_luma_qp_scale - SHIFT_QP;
582#if FULL_NBIT
583    Double qp_temp_orig = (Double) recalQP - SHIFT_QP;
584#endif
585    // Case #1: I or P-slices (key-frame)
586    Double dQPFactor = m_pcCfg->getGOPEntry(idGOP).m_QPFactor;
587    if ( eSliceType==I_SLICE )
588    {
589      dQPFactor=0.57*dLambda_scale;
590    }
591    lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
592
593    if ( depth>0 )
594    {
595#if FULL_NBIT
596      lambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
597#else
598      lambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
599#endif
600    }
601
602    // if hadamard is used in ME process
603    if ( !m_pcCfg->getUseHADME() )
604    {
605      lambda *= 0.95;
606    }
607
608    qp = max( -pcSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
609
610    m_pdRdPicLambda[deltqQpIdx] = lambda;
611    m_pdRdPicQp    [deltqQpIdx] = recalQP;
612    m_piRdPicQp    [deltqQpIdx] = qp;
613  }
614
615  // obtain dQP = 0 case
616  lambda  = m_pdRdPicLambda[0];
617  recalQP = m_pdRdPicQp    [0];
618  qp      = m_piRdPicQp    [0];
619
620  if( pcSlice->getSliceType( ) != I_SLICE )
621  {
622    lambda *= m_pcCfg->getLambdaModifier( depth );
623  }
624
625  // store lambda
626  m_pcRdCost ->setLambda( lambda );
627#if WEIGHTED_CHROMA_DISTORTION
628  // for RDO
629  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
630  Double weight = 1.0;
631  Int qpc;
632  Int chromaQPOffset;
633
634  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
635  qpc = Clip3( 0, 57, qp + chromaQPOffset);
636  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
637  m_pcRdCost->setCbDistortionWeight(weight);
638
639  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
640  qpc = Clip3( 0, 57, qp + chromaQPOffset);
641  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
642  m_pcRdCost->setCrDistortionWeight(weight);
643#endif
644
645#if RDOQ_CHROMA_LAMBDA
646  // for RDOQ
647  m_pcTrQuant->setLambda( lambda, lambda / weight );   
648#else
649  m_pcTrQuant->setLambda( lambda );
650#endif
651
652#if SAO_CHROMA_LAMBDA
653  // For SAO
654  pcSlice   ->setLambda( lambda, lambda / weight ); 
655#else
656  pcSlice   ->setLambda( lambda );
657#endif
658}
659#endif
660// ====================================================================================================================
661// Public member functions
662// ====================================================================================================================
663
664Void TEncSlice::setSearchRange( TComSlice* pcSlice )
665{
666  Int iCurrPOC = pcSlice->getPOC();
667  Int iRefPOC;
668  Int iGOPSize = m_pcCfg->getGOPSize();
669  Int iOffset = (iGOPSize >> 1);
670  Int iMaxSR = m_pcCfg->getSearchRange();
671  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
672 
673  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
674  {
675    //RefPicList e = (RefPicList)iDir;
676    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
677    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
678    {
679      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
680      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
681      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
682    }
683  }
684}
685
686/**
687 - multi-loop slice encoding for different slice QP
688 .
689 \param rpcPic    picture class
690 */
691Void TEncSlice::precompressSlice( TComPic*& rpcPic )
692{
693  // if deltaQP RD is not used, simply return
694  if ( m_pcCfg->getDeltaQpRD() == 0 )
695  {
696    return;
697  }
698
699#if RATE_CONTROL_LAMBDA_DOMAIN
700  if ( m_pcCfg->getUseRateCtrl() )
701  {
702    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
703    assert(0);
704  }
705#endif
706 
707  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
708  Double     dPicRdCostBest = MAX_DOUBLE;
709  UInt       uiQpIdxBest = 0;
710 
711  Double dFrameLambda;
712#if FULL_NBIT
713  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
714#else
715  Int    SHIFT_QP = 12;
716#endif
717 
718  // set frame lambda
719  if (m_pcCfg->getGOPSize() > 1)
720  {
721    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
722  }
723  else
724  {
725    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
726  }
727  m_pcRdCost      ->setFrameLambda(dFrameLambda);
728 
729  // for each QP candidate
730  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
731  {
732    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
733#if ADAPTIVE_QP_SELECTION
734    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
735#endif
736    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
737#if WEIGHTED_CHROMA_DISTORTION
738    // for RDO
739    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
740    Int iQP = m_piRdPicQp    [uiQpIdx];
741    Double weight = 1.0;
742    Int qpc;
743    Int chromaQPOffset;
744
745    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
746    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
747    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
748    m_pcRdCost->setCbDistortionWeight(weight);
749
750    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
751    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
752    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
753    m_pcRdCost->setCrDistortionWeight(weight);
754#endif
755
756#if RDOQ_CHROMA_LAMBDA
757    // for RDOQ
758    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
759#else
760    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
761#endif
762#if SAO_CHROMA_LAMBDA
763    // For SAO
764    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
765#else
766    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
767#endif
768   
769    // try compress
770    compressSlice   ( rpcPic );
771   
772    Double dPicRdCost;
773    UInt64 uiPicDist        = m_uiPicDist;
774    UInt64 uiALFBits        = 0;
775   
776    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
777   
778    // compute RD cost and choose the best
779    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
780   
781    if ( dPicRdCost < dPicRdCostBest )
782    {
783      uiQpIdxBest    = uiQpIdx;
784      dPicRdCostBest = dPicRdCost;
785    }
786  }
787 
788  // set best values
789  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
790#if ADAPTIVE_QP_SELECTION
791  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
792#endif
793  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
794#if WEIGHTED_CHROMA_DISTORTION
795  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
796  Int iQP = m_piRdPicQp    [uiQpIdxBest];
797  Double weight = 1.0;
798  Int qpc;
799  Int chromaQPOffset;
800
801  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
802  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
803  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
804  m_pcRdCost->setCbDistortionWeight(weight);
805
806  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
807  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
808  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
809  m_pcRdCost->setCrDistortionWeight(weight);
810#endif
811
812#if RDOQ_CHROMA_LAMBDA
813  // for RDOQ
814  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
815#else
816  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
817#endif
818#if SAO_CHROMA_LAMBDA
819  // For SAO
820  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
821#else
822  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
823#endif
824}
825
826/** \param rpcPic   picture class
827 */
828#if RATE_CONTROL_INTRA
829Void TEncSlice::calCostSliceI(TComPic*& rpcPic)
830{
831  UInt    uiCUAddr;
832  UInt    uiStartCUAddr;
833  UInt    uiBoundingCUAddr;
834  Int     iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;;
835  Double  iSumHadSlice = 0;
836
837  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
838  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
839  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
840
841  UInt uiEncCUOrder;
842  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
843  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
844       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
845       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
846  {
847    // initialize CU encoder
848    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
849    pcCU->initCU( rpcPic, uiCUAddr );
850
851    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
852    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
853
854    iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height);
855
856    (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift;
857    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra;
858
859  }
860  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
861}
862#endif
863
864Void TEncSlice::compressSlice( TComPic*& rpcPic )
865{
866  UInt  uiCUAddr;
867  UInt   uiStartCUAddr;
868  UInt   uiBoundingCUAddr;
869  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
870  TEncBinCABAC* pppcRDSbacCoder = NULL;
871  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
872  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
873 
874  // initialize cost values
875  m_uiPicTotalBits  = 0;
876  m_dPicRdCost      = 0;
877  m_uiPicDist       = 0;
878 
879  // set entropy coder
880  if( m_pcCfg->getUseSBACRD() )
881  {
882    m_pcSbacCoder->init( m_pcBinCABAC );
883    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
884    m_pcEntropyCoder->resetEntropy      ();
885    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
886    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
887    pppcRDSbacCoder->setBinCountingEnableFlag( false );
888    pppcRDSbacCoder->setBinsCoded( 0 );
889  }
890  else
891  {
892    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
893    m_pcEntropyCoder->resetEntropy      ();
894    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
895  }
896 
897  //------------------------------------------------------------------------------
898  //  Weighted Prediction parameters estimation.
899  //------------------------------------------------------------------------------
900  // calculate AC/DC values for current picture
901  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
902  {
903    xCalcACDCParamSlice(pcSlice);
904  }
905
906  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
907
908  if ( bWp_explicit )
909  {
910    //------------------------------------------------------------------------------
911    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
912    //------------------------------------------------------------------------------
913    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
914    {
915      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
916    }
917
918    xEstimateWPParamSlice( pcSlice );
919    pcSlice->initWpScaling();
920
921    // check WP on/off
922    xCheckWPEnable( pcSlice );
923  }
924
925#if ADAPTIVE_QP_SELECTION
926  if( m_pcCfg->getUseAdaptQpSelect() )
927  {
928    m_pcTrQuant->clearSliceARLCnt();
929    if(pcSlice->getSliceType()!=I_SLICE)
930    {
931      Int qpBase = pcSlice->getSliceQpBase();
932      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
933    }
934  }
935#endif
936  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
937  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
938  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
939  Int  iNumSubstreams = 1;
940  UInt uiTilesAcross  = 0;
941
942  if( m_pcCfg->getUseSBACRD() )
943  {
944    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
945    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
946    delete[] m_pcBufferSbacCoders;
947    delete[] m_pcBufferBinCoderCABACs;
948    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
949    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
950    for (Int ui = 0; ui < uiTilesAcross; ui++)
951    {
952      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
953    }
954    for (UInt ui = 0; ui < uiTilesAcross; ui++)
955    {
956      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
957    }
958
959    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
960    {
961      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
962    }
963  }
964  //if( m_pcCfg->getUseSBACRD() )
965  {
966    delete[] m_pcBufferLowLatSbacCoders;
967    delete[] m_pcBufferLowLatBinCoderCABACs;
968    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
969    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
970    for (Int ui = 0; ui < uiTilesAcross; ui++)
971    {
972      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
973    }
974    for (UInt ui = 0; ui < uiTilesAcross; ui++)
975      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
976  }
977  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
978  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
979  UInt uiCol=0, uiLin=0, uiSubStrm=0;
980  UInt uiTileCol      = 0;
981  UInt uiTileStartLCU = 0;
982  UInt uiTileLCUX     = 0;
983
984  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
985  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
986  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
987  if( depSliceSegmentsEnabled )
988  {
989    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
990    {
991      if( m_pcCfg->getWaveFrontsynchro() )
992      {
993        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
994        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
995        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
996        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
997        uiLin     = uiCUAddr / uiWidthInLCUs;
998        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
999          + uiLin%iNumSubstreamsPerTile;
1000        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1001        {
1002          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1003          uiCol     = uiCUAddr % uiWidthInLCUs;
1004          if(uiCol==uiTileStartLCU)
1005          {
1006            CTXMem[0]->loadContexts(m_pcSbacCoder);
1007          }
1008        }
1009      }
1010      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1011      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1012    }
1013    else
1014    {
1015      if(m_pcCfg->getWaveFrontsynchro())
1016      {
1017        CTXMem[1]->loadContexts(m_pcSbacCoder);
1018      }
1019      CTXMem[0]->loadContexts(m_pcSbacCoder);
1020    }
1021  }
1022  // for every CU in slice
1023  UInt uiEncCUOrder;
1024  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1025       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1026       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1027  {
1028    // initialize CU encoder
1029    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1030    pcCU->initCU( rpcPic, uiCUAddr );
1031
1032#if !RATE_CONTROL_LAMBDA_DOMAIN
1033    if(m_pcCfg->getUseRateCtrl())
1034    {
1035      if(m_pcRateCtrl->calculateUnitQP())
1036      {
1037        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
1038      }
1039    }
1040#endif
1041    // inherit from TR if necessary, select substream to use.
1042    if( m_pcCfg->getUseSBACRD() )
1043    {
1044      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1045      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1046      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1047      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1048      uiCol     = uiCUAddr % uiWidthInLCUs;
1049      uiLin     = uiCUAddr / uiWidthInLCUs;
1050      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1051      {
1052        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1053        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1054        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1055                      + uiLin%iNumSubstreamsPerTile;
1056      }
1057      else
1058      {
1059        // dependent tiles => substreams are "per frame".
1060        uiSubStrm = uiLin % iNumSubstreams;
1061      }
1062      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1063      {
1064        // We'll sync if the TR is available.
1065        TComDataCU *pcCUUp = pcCU->getCUAbove();
1066        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1067        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1068        TComDataCU *pcCUTR = NULL;
1069        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1070        {
1071          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1072        }
1073        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1074             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1075             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1076             )
1077           )
1078        {
1079          // TR not available.
1080        }
1081        else
1082        {
1083          // TR is available, we use it.
1084          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1085        }
1086      }
1087      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1088    }
1089
1090    // reset the entropy coder
1091    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1092        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1093        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1094        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1095    {
1096      SliceType sliceType = pcSlice->getSliceType();
1097      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1098      {
1099        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1100      }
1101      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1102      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1103      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1104      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1105    }
1106    // if RD based on SBAC is used
1107    if( m_pcCfg->getUseSBACRD() )
1108    {
1109      // set go-on entropy coder
1110      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1111      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1112     
1113      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1114
1115#if RATE_CONTROL_LAMBDA_DOMAIN
1116      Double oldLambda = m_pcRdCost->getLambda();
1117      if ( m_pcCfg->getUseRateCtrl() )
1118      {
1119        Int estQP        = pcSlice->getSliceQp();
1120        Double estLambda = -1.0;
1121        Double bpp       = -1.0;
1122
1123#if M0036_RC_IMPROVEMENT
1124        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1125#else
1126        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1127#endif
1128        {
1129          estQP = pcSlice->getSliceQp();
1130        }
1131        else
1132        {
1133#if RATE_CONTROL_INTRA
1134          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1135          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1136          {
1137            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1138          }
1139          else
1140          {
1141            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1142            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1143          }
1144#else
1145          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1146          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1147          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1148#endif
1149
1150          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1151
1152          m_pcRdCost->setLambda(estLambda);
1153#if M0036_RC_IMPROVEMENT
1154#if RDOQ_CHROMA_LAMBDA
1155          // set lambda for RDOQ
1156          Double weight=m_pcRdCost->getChromaWeight();
1157          m_pcTrQuant->setLambda( estLambda, estLambda / weight );
1158#else
1159          m_pcTrQuant->setLambda( estLambda );
1160#endif
1161#endif
1162        }
1163
1164        m_pcRateCtrl->setRCQP( estQP );
1165        pcCU->getSlice()->setSliceQpBase( estQP );
1166      }
1167#endif
1168
1169      // run CU encoder
1170      m_pcCuEncoder->compressCU( pcCU );
1171
1172#if !TICKET_1090_FIX
1173#if RATE_CONTROL_LAMBDA_DOMAIN
1174      if ( m_pcCfg->getUseRateCtrl() )
1175      {
1176#if !M0036_RC_IMPROVEMENT
1177        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1178        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1179        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1180        Double MAD = (Double)SAD / (Double)(height * width);
1181        MAD = MAD * MAD;
1182        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1183#endif
1184
1185        Int actualQP        = g_RCInvalidQPValue;
1186        Double actualLambda = m_pcRdCost->getLambda();
1187        Int actualBits      = pcCU->getTotalBits();
1188        Int numberOfEffectivePixels    = 0;
1189        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1190        {
1191          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1192          {
1193            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1194            break;
1195          }
1196        }
1197
1198        if ( numberOfEffectivePixels == 0 )
1199        {
1200          actualQP = g_RCInvalidQPValue;
1201        }
1202        else
1203        {
1204          actualQP = pcCU->getQP( 0 );
1205        }
1206        m_pcRdCost->setLambda(oldLambda);
1207#if RATE_CONTROL_INTRA
1208        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1209          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1210#else
1211        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1212#endif
1213      }
1214#endif
1215#endif
1216     
1217      // restore entropy coder to an initial stage
1218      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1219      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1220      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1221      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1222      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1223      m_pcBitCounter->resetBits();
1224      pppcRDSbacCoder->setBinsCoded( 0 );
1225      m_pcCuEncoder->encodeCU( pcCU );
1226
1227      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1228      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1229      {
1230        pcSlice->setNextSlice( true );
1231        break;
1232      }
1233      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1234      {
1235        pcSlice->setNextSliceSegment( true );
1236        break;
1237      }
1238      if( m_pcCfg->getUseSBACRD() )
1239      {
1240         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1241       
1242         //Store probabilties of second LCU in line into buffer
1243         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1244        {
1245          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1246        }
1247      }
1248
1249#if TICKET_1090_FIX
1250#if RATE_CONTROL_LAMBDA_DOMAIN
1251      if ( m_pcCfg->getUseRateCtrl() )
1252      {
1253#if !M0036_RC_IMPROVEMENT
1254        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1255        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1256        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1257        Double MAD = (Double)SAD / (Double)(height * width);
1258        MAD = MAD * MAD;
1259        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1260#endif
1261
1262        Int actualQP        = g_RCInvalidQPValue;
1263        Double actualLambda = m_pcRdCost->getLambda();
1264        Int actualBits      = pcCU->getTotalBits();
1265        Int numberOfEffectivePixels    = 0;
1266        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1267        {
1268          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1269          {
1270            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1271            break;
1272          }
1273        }
1274
1275        if ( numberOfEffectivePixels == 0 )
1276        {
1277          actualQP = g_RCInvalidQPValue;
1278        }
1279        else
1280        {
1281          actualQP = pcCU->getQP( 0 );
1282        }
1283        m_pcRdCost->setLambda(oldLambda);
1284
1285#if RATE_CONTROL_INTRA
1286        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1287          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1288#else
1289        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1290#endif
1291      }
1292#endif
1293#endif
1294    }
1295    // other case: encodeCU is not called
1296    else
1297    {
1298      m_pcCuEncoder->compressCU( pcCU );
1299      m_pcCuEncoder->encodeCU( pcCU );
1300      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1301      {
1302        pcSlice->setNextSlice( true );
1303        break;
1304      }
1305      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1306      {
1307        pcSlice->setNextSliceSegment( true );
1308        break;
1309      }
1310    }
1311   
1312    m_uiPicTotalBits += pcCU->getTotalBits();
1313    m_dPicRdCost     += pcCU->getTotalCost();
1314    m_uiPicDist      += pcCU->getTotalDistortion();
1315#if !RATE_CONTROL_LAMBDA_DOMAIN
1316    if(m_pcCfg->getUseRateCtrl())
1317    {
1318      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1319      m_pcRateCtrl->updataRCUnitStatus();
1320    }
1321#endif
1322  }
1323  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1324  {
1325    pcSlice->setNextSlice( true );
1326  }
1327  if( depSliceSegmentsEnabled )
1328  {
1329    if (m_pcCfg->getWaveFrontsynchro())
1330    {
1331      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1332    }
1333     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1334  }
1335  xRestoreWPparam( pcSlice );
1336#if !RATE_CONTROL_LAMBDA_DOMAIN
1337  if(m_pcCfg->getUseRateCtrl())
1338  {
1339    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1340  }
1341#endif
1342}
1343
1344/**
1345 \param  rpcPic        picture class
1346 \retval rpcBitstream  bitstream class
1347 */
1348Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1349{
1350  UInt       uiCUAddr;
1351  UInt       uiStartCUAddr;
1352  UInt       uiBoundingCUAddr;
1353  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1354
1355  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1356  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1357  // choose entropy coder
1358  {
1359    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1360    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1361  }
1362 
1363  m_pcCuEncoder->setBitCounter( NULL );
1364  m_pcBitCounter = NULL;
1365  // Appropriate substream bitstream is switched later.
1366  // for every CU
1367#if ENC_DEC_TRACE
1368  g_bJustDoIt = g_bEncDecTraceEnable;
1369#endif
1370  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1371  DTRACE_CABAC_T( "\tPOC: " );
1372  DTRACE_CABAC_V( rpcPic->getPOC() );
1373  DTRACE_CABAC_T( "\n" );
1374#if ENC_DEC_TRACE
1375  g_bJustDoIt = g_bEncDecTraceDisable;
1376#endif
1377
1378  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1379  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1380  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1381  UInt uiBitsOriginallyInSubstreams = 0;
1382  {
1383    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1384    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1385    {
1386      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1387    }
1388   
1389    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1390    {
1391      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1392    }
1393
1394    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1395    {
1396      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1397    }
1398  }
1399
1400  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1401  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1402  UInt uiTileCol      = 0;
1403  UInt uiTileStartLCU = 0;
1404  UInt uiTileLCUX     = 0;
1405  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1406  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1407                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1408                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1409  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1410  if( depSliceSegmentsEnabled )
1411  {
1412    if( pcSlice->isNextSlice()||
1413        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1414    {
1415      if(m_pcCfg->getWaveFrontsynchro())
1416      {
1417        CTXMem[1]->loadContexts(m_pcSbacCoder);
1418      }
1419      CTXMem[0]->loadContexts(m_pcSbacCoder);
1420    }
1421    else
1422    {
1423      if(m_pcCfg->getWaveFrontsynchro())
1424      {
1425        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1426        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1427        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1428        uiLin     = uiCUAddr / uiWidthInLCUs;
1429        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1430          + uiLin%iNumSubstreamsPerTile;
1431        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1432        {
1433          uiCol     = uiCUAddr % uiWidthInLCUs;
1434          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1435          if(uiCol==uiTileLCUX)
1436          {
1437            CTXMem[0]->loadContexts(m_pcSbacCoder);
1438          }
1439        }
1440      }
1441      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1442    }
1443  }
1444
1445  UInt uiEncCUOrder;
1446  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1447       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1448       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1449  {
1450    if( m_pcCfg->getUseSBACRD() )
1451    {
1452      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1453      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1454      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1455      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1456      uiCol     = uiCUAddr % uiWidthInLCUs;
1457      uiLin     = uiCUAddr / uiWidthInLCUs;
1458      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1459      {
1460        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1461        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1462        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1463                      + uiLin%iNumSubstreamsPerTile;
1464      }
1465      else
1466      {
1467        // dependent tiles => substreams are "per frame".
1468        uiSubStrm = uiLin % iNumSubstreams;
1469      }
1470
1471      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1472      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1473      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1474      {
1475        // We'll sync if the TR is available.
1476        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1477        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1478        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1479        TComDataCU *pcCUTR = NULL;
1480        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1481        {
1482          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1483        }
1484        if ( (true/*bEnforceSliceRestriction*/ &&
1485             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1486             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1487             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1488             ))
1489           )
1490        {
1491          // TR not available.
1492        }
1493        else
1494        {
1495          // TR is available, we use it.
1496          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1497        }
1498      }
1499      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1500    }
1501    // reset the entropy coder
1502    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1503        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1504        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1505        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1506    {
1507      {
1508        // We're crossing into another tile, tiles are independent.
1509        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1510        // have to perform it here.
1511        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1512        {
1513          ; // do nothing.
1514        }
1515        else
1516        {
1517          SliceType sliceType  = pcSlice->getSliceType();
1518          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1519          {
1520            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1521          }
1522          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1523          // Byte-alignment in slice_data() when new tile
1524          pcSubstreams[uiSubStrm].writeByteAlignment();
1525        }
1526      }
1527      {
1528        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1529        UInt uiAccumulatedSubstreamLength = 0;
1530        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1531        {
1532          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1533        }
1534        // add bits coded in previous dependent slices + bits coded so far
1535        // add number of emulation prevention byte count in the tile
1536        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1537      }
1538    }
1539
1540    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1541    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1542    {
1543      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1544      Int iNumCuInWidth     = saoParam->numCuInWidth;
1545      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1546      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1547      Int rx = uiCUAddr % iNumCuInWidth;
1548      Int ry = uiCUAddr / iNumCuInWidth;
1549      Int allowMergeLeft = 1;
1550      Int allowMergeUp   = 1;
1551      if (rx!=0)
1552      {
1553        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1554        {
1555          allowMergeLeft = 0;
1556        }
1557      }
1558      if (ry!=0)
1559      {
1560        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1561        {
1562          allowMergeUp = 0;
1563        }
1564      }
1565      Int addr = pcCU->getAddr();
1566      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1567      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1568      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1569      {
1570        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1571        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1572        if (allowMergeLeft)
1573        {
1574          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1575        }
1576        else
1577        {
1578          mergeLeft = 0;
1579        }
1580        if(mergeLeft == 0)
1581        {
1582          if (allowMergeUp)
1583          {
1584            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1585          }
1586          else
1587          {
1588            mergeUp = 0;
1589          }
1590          if(mergeUp == 0)
1591          {
1592            for (Int compIdx=0;compIdx<3;compIdx++)
1593            {
1594            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1595              {
1596                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1597              }
1598            }
1599          }
1600        }
1601      }
1602    }
1603    else if (pcSlice->getSPS()->getUseSAO())
1604    {
1605      Int addr = pcCU->getAddr();
1606      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1607      for (Int cIdx=0; cIdx<3; cIdx++)
1608      {
1609        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1610        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1611        {
1612          saoLcuParam->mergeUpFlag   = 0;
1613          saoLcuParam->mergeLeftFlag = 0;
1614          saoLcuParam->subTypeIdx    = 0;
1615          saoLcuParam->typeIdx       = -1;
1616          saoLcuParam->offset[0]     = 0;
1617          saoLcuParam->offset[1]     = 0;
1618          saoLcuParam->offset[2]     = 0;
1619          saoLcuParam->offset[3]     = 0;
1620        }
1621      }
1622    }
1623#if ENC_DEC_TRACE
1624    g_bJustDoIt = g_bEncDecTraceEnable;
1625#endif
1626    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1627      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1628    {
1629      m_pcCuEncoder->encodeCU( pcCU );
1630    }
1631    else
1632    {
1633      m_pcCuEncoder->encodeCU( pcCU );
1634    }
1635#if ENC_DEC_TRACE
1636    g_bJustDoIt = g_bEncDecTraceDisable;
1637#endif   
1638    if( m_pcCfg->getUseSBACRD() )
1639    {
1640       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1641       
1642
1643       //Store probabilties of second LCU in line into buffer
1644       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1645      {
1646        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1647      }
1648    }
1649  }
1650  if( depSliceSegmentsEnabled )
1651  {
1652    if (m_pcCfg->getWaveFrontsynchro())
1653    {
1654      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1655    }
1656    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1657  }
1658#if ADAPTIVE_QP_SELECTION
1659  if( m_pcCfg->getUseAdaptQpSelect() )
1660  {
1661    m_pcTrQuant->storeSliceQpNext(pcSlice);
1662  }
1663#endif
1664  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1665  {
1666    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1667    {
1668      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1669    }
1670    else
1671    {
1672      m_pcEntropyCoder->determineCabacInitIdx();
1673    }
1674  }
1675}
1676
1677/** Determines the starting and bounding LCU address of current slice / dependent slice
1678 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1679 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1680 */
1681Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1682{
1683  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1684  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1685  UInt tileIdxIncrement;
1686  UInt tileIdx;
1687  UInt tileWidthInLcu;
1688  UInt tileHeightInLcu;
1689  UInt tileTotalCount;
1690
1691  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1692  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1693  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1694  if (bEncodeSlice) 
1695  {
1696    UInt uiCUAddrIncrement;
1697    switch (m_pcCfg->getSliceMode())
1698    {
1699    case FIXED_NUMBER_OF_LCU:
1700      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1701      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1702      break;
1703    case FIXED_NUMBER_OF_BYTES:
1704      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1705      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1706      break;
1707    case FIXED_NUMBER_OF_TILES:
1708      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1709        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1710        );
1711      uiCUAddrIncrement        = 0;
1712      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1713
1714      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1715      {
1716        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1717        {
1718          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1719          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1720          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1721        }
1722      }
1723
1724      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1725      break;
1726    default:
1727      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1728      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1729      break;
1730    } 
1731    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1732    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1733    {
1734      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1735    }
1736    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1737  }
1738  else
1739  {
1740    UInt uiCUAddrIncrement     ;
1741    switch (m_pcCfg->getSliceMode())
1742    {
1743    case FIXED_NUMBER_OF_LCU:
1744      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1745      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1746      break;
1747    case FIXED_NUMBER_OF_TILES:
1748      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1749        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1750        );
1751      uiCUAddrIncrement        = 0;
1752      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1753
1754      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1755      {
1756        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1757        {
1758          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1759          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1760          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1761        }
1762      }
1763
1764      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1765      break;
1766    default:
1767      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1768      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1769      break;
1770    } 
1771    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1772    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1773    {
1774      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1775    }
1776    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1777  }
1778
1779  Bool tileBoundary = false;
1780  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1781      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1782  {
1783    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1784    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1785    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1786    UInt tileBoundingCUAddrSlice = 0;
1787    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1788    {
1789      lcuEncAddr++;
1790      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1791    }
1792    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1793   
1794    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1795    {
1796      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1797      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1798      tileBoundary = true;
1799    }
1800  }
1801
1802  // Dependent slice
1803  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1804  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1805  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1806  if (bEncodeSlice) 
1807  {
1808    UInt uiCUAddrIncrement;
1809    switch (m_pcCfg->getSliceSegmentMode())
1810    {
1811    case FIXED_NUMBER_OF_LCU:
1812      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1813      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1814      break;
1815    case FIXED_NUMBER_OF_BYTES:
1816      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1817      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1818      break;
1819    case FIXED_NUMBER_OF_TILES:
1820      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1821        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1822        );
1823      uiCUAddrIncrement        = 0;
1824      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1825
1826      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1827      {
1828        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1829        {
1830          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1831          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1832          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1833        }
1834      }
1835      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1836      break;
1837    default:
1838      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1839      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1840      break;
1841    } 
1842    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1843    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1844    {
1845      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1846    }
1847    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1848  }
1849  else
1850  {
1851    UInt uiCUAddrIncrement;
1852    switch (m_pcCfg->getSliceSegmentMode())
1853    {
1854    case FIXED_NUMBER_OF_LCU:
1855      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1856      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1857      break;
1858    case FIXED_NUMBER_OF_TILES:
1859      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1860        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1861        );
1862      uiCUAddrIncrement        = 0;
1863      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1864
1865      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1866      {
1867        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1868        {
1869          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1870          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1871          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1872        }
1873      }
1874      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1875      break;
1876    default:
1877      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1878      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1879      break;
1880    } 
1881    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1882    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1883    {
1884      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1885    }
1886    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1887  }
1888  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1889    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1890  {
1891    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1892    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1893    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1894    UInt tileBoundingCUAddrSlice = 0;
1895    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1896    {
1897      lcuEncAddr++;
1898      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1899    }
1900    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1901
1902    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1903    {
1904      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1905      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1906      tileBoundary = true;
1907    }
1908  }
1909
1910  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1911  {
1912    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1913    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1914  }
1915
1916  //calculate real dependent slice start address
1917  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1918  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1919  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1920  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1921  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1922  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1923  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1924  {
1925    uiInternalAddress++;
1926    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1927    {
1928      uiInternalAddress=0;
1929      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1930    }
1931    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1932    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1933  }
1934  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1935 
1936  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1937  startCUAddrSliceSegment=uiRealStartAddress;
1938 
1939  //calculate real slice start address
1940  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1941  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1942  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1943  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1944  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1945  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1946  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1947  {
1948    uiInternalAddress++;
1949    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1950    {
1951      uiInternalAddress=0;
1952      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1953    }
1954    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1955    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1956  }
1957  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1958 
1959  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1960  uiStartCUAddrSlice=uiRealStartAddress;
1961 
1962  // Make a joint decision based on reconstruction and dependent slice bounds
1963  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1964  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1965
1966
1967  if (!bEncodeSlice)
1968  {
1969    // 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
1970    // first. Set the flags accordingly.
1971    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1972      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1973      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1974      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1975      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1976      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1977      || tileBoundary
1978)
1979    {
1980      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1981      {
1982        pcSlice->setNextSlice       ( true );
1983        pcSlice->setNextSliceSegment( false );
1984      }
1985      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1986      {
1987        pcSlice->setNextSlice       ( false );
1988        pcSlice->setNextSliceSegment( true );
1989      }
1990      else
1991      {
1992        pcSlice->setNextSlice       ( true );
1993        pcSlice->setNextSliceSegment( true );
1994      }
1995    }
1996    else
1997    {
1998      pcSlice->setNextSlice       ( false );
1999      pcSlice->setNextSliceSegment( false );
2000    }
2001  }
2002}
2003
2004Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
2005{
2006  return 4.2005*log(lambda) + 13.7122;
2007}
2008
2009#if JCTVC_M0259_LAMBDAREFINEMENT
2010Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
2011{
2012  double tmp = beta * pow( 2.0 , deltaQP / 6 );
2013  double gamma = tmp / ( tmp + 1 );
2014  return( gamma );
2015}
2016#endif
2017//! \}
Note: See TracBrowser for help on using the repository browser.