source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 612

Last change on this file since 612 was 608, checked in by tech, 11 years ago

Merged DEV-2.0-dev0@604.

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