source: 3DVCSoftware/branches/HTM-8.2-dev0-MediaTek/source/Lib/TLibEncoder/TEncSlice.cpp @ 633

Last change on this file since 633 was 622, checked in by tech, 11 years ago

Merged 8.0-dev0@621 (MV-HEVC 5 HLS).

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