source: SHVCSoftware/branches/SHM-2.0-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 138

Last change on this file since 138 was 133, checked in by seregin, 12 years ago

update to HM10.1

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