source: 3DVCSoftware/branches/HTM-5.1-dev1-LG/source/Lib/TLibEncoder/TEncSlice.cpp @ 253

Last change on this file since 253 was 253, checked in by lg, 11 years ago

Integration of JCT3V-C0046

  • Property svn:eol-style set to native
File size: 65.7 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-2012, 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 "../../App/TAppEncoder/TAppEncTop.h"
41#include <math.h>
42
43//! \ingroup TLibEncoder
44//! \{
45
46// ====================================================================================================================
47// Constructor / destructor / create / destroy
48// ====================================================================================================================
49
50TEncSlice::TEncSlice()
51{
52  m_apcPicYuvPred = NULL;
53  m_apcPicYuvResi = NULL;
54 
55  m_pdRdPicLambda = NULL;
56  m_pdRdPicQp     = NULL;
57  m_piRdPicQp     = NULL;
58  m_pcBufferSbacCoders    = NULL;
59  m_pcBufferBinCoderCABACs  = NULL;
60  m_pcBufferLowLatSbacCoders    = NULL;
61  m_pcBufferLowLatBinCoderCABACs  = NULL;
62}
63
64TEncSlice::~TEncSlice()
65{
66}
67
68Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
69{
70  // create prediction picture
71  if ( m_apcPicYuvPred == NULL )
72  {
73    m_apcPicYuvPred  = new TComPicYuv;
74    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
75  }
76 
77  // create residual picture
78  if( m_apcPicYuvResi == NULL )
79  {
80    m_apcPicYuvResi  = new TComPicYuv;
81    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
82  }
83}
84
85Void TEncSlice::destroy()
86{
87  // destroy prediction picture
88  if ( m_apcPicYuvPred )
89  {
90    m_apcPicYuvPred->destroy();
91    delete m_apcPicYuvPred;
92    m_apcPicYuvPred  = NULL;
93  }
94 
95  // destroy residual picture
96  if ( m_apcPicYuvResi )
97  {
98    m_apcPicYuvResi->destroy();
99    delete m_apcPicYuvResi;
100    m_apcPicYuvResi  = NULL;
101  }
102 
103  // free lambda and QP arrays
104  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
105  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
106  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
107
108  if ( m_pcBufferSbacCoders )
109  {
110    delete[] m_pcBufferSbacCoders;
111  }
112  if ( m_pcBufferBinCoderCABACs )
113  {
114    delete[] m_pcBufferBinCoderCABACs;
115  }
116  if ( m_pcBufferLowLatSbacCoders )
117    delete[] m_pcBufferLowLatSbacCoders;
118  if ( m_pcBufferLowLatBinCoderCABACs )
119    delete[] m_pcBufferLowLatBinCoderCABACs;
120}
121
122Void TEncSlice::init( TEncTop* pcEncTop )
123{
124  m_pcCfg             = pcEncTop;
125  m_pcListPic         = pcEncTop->getListPic();
126 
127  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
128  m_pcCuEncoder       = pcEncTop->getCuEncoder();
129  m_pcPredSearch      = pcEncTop->getPredSearch();
130 
131  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
132  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
133  m_pcSbacCoder       = pcEncTop->getSbacCoder();
134  m_pcBinCABAC        = pcEncTop->getBinCABAC();
135  m_pcTrQuant         = pcEncTop->getTrQuant();
136 
137  m_pcBitCounter      = pcEncTop->getBitCounter();
138  m_pcRdCost          = pcEncTop->getRdCost();
139  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
140  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
141 
142  // create lambda and QP arrays
143  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
144  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
145  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
146}
147
148/**
149 - non-referenced frame marking
150 - QP computation based on temporal structure
151 - lambda computation based on QP
152 - set temporal layer ID and the parameter sets
153 .
154 \param pcPic         picture class
155 \param iPOCLast      POC of last picture
156 \param uiPOCCurr     current POC
157 \param iNumPicRcvd   number of received pictures
158 \param iTimeOffset   POC offset for hierarchical structure
159 \param iDepth        temporal layer depth
160 \param rpcSlice      slice header class
161 \param pSPS          SPS associated with the slice
162 \param pPPS          PPS associated with the slice
163 */
164#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
165Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS * pVPS, TComSPS* pSPS, TComPPS *pPPS )
166#else
167Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
168#endif
169{
170  Double dQP;
171  Double dLambda;
172 
173  rpcSlice = pcPic->getSlice(0);
174#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
175  rpcSlice->setVPS( pVPS );
176#endif
177  rpcSlice->setSPS( pSPS );
178  rpcSlice->setPPS( pPPS );
179  rpcSlice->setSliceBits(0);
180  rpcSlice->setPic( pcPic );
181  rpcSlice->initSlice();
182  rpcSlice->initTiles();
183#if H0388
184  rpcSlice->setPicOutputFlag( true );
185#endif
186  rpcSlice->setPOC( uiPOCCurr );
187 
188#if SONY_COLPIC_AVAILABILITY
189  rpcSlice->setViewOrderIdx(m_pcCfg->getViewOrderIdx());
190#endif
191#if LGE_ILLUCOMP_B0045
192  rpcSlice->setApplyIC(false);
193#endif
194  // set mutliview parameters
195  rpcSlice->initMultiviewSlice( pcPic->getCodedScale(), pcPic->getCodedOffset() );
196
197  // depth computation based on GOP size
198  int iDepth;
199  {
200    Int i, j;
201    Int iPOC = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
202    if ( iPOC == 0 )
203    {
204      iDepth = 0;
205    }
206    else
207    {
208      Int iStep = m_pcCfg->getGOPSize();
209      iDepth    = 0;
210      for( i=iStep>>1; i>=1; i>>=1 )
211      {
212        for ( j=i; j<m_pcCfg->getGOPSize(); j+=iStep )
213        {
214          if ( j == iPOC )
215          {
216            i=0;
217            break;
218          }
219        }
220        iStep>>=1;
221        iDepth++;
222      }
223    }
224  }
225 
226  // slice type
227  SliceType eSliceTypeBaseView;
228  if( iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0 )
229  {
230    eSliceTypeBaseView = I_SLICE;
231  }
232  else
233  {
234    eSliceTypeBaseView = B_SLICE;
235  }
236  SliceType eSliceType = eSliceTypeBaseView;
237  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
238  {
239    eSliceType = B_SLICE; 
240  }
241  rpcSlice->setSliceType( eSliceType );
242 
243  // ------------------------------------------------------------------------------------------------------------------
244  // Non-referenced frame marking
245  // ------------------------------------------------------------------------------------------------------------------
246  rpcSlice->setReferenced( m_pcCfg->getGOPEntry(iGOPid).m_refPic );
247  if( eSliceTypeBaseView == I_SLICE )
248  {
249    rpcSlice->setReferenced(true);
250  }
251 
252  // ------------------------------------------------------------------------------------------------------------------
253  // QP setting
254  // ------------------------------------------------------------------------------------------------------------------
255 
256  dQP = m_pcCfg->getQP();
257  if( eSliceType != I_SLICE )
258  {
259#if LOSSLESS_CODING
260#if H0736_AVC_STYLE_QP_RANGE
261    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
262#else
263    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == 0 ) && (rpcSlice->getSPS()->getUseLossless())))
264#endif
265#endif
266    {
267    dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset;
268    }
269  }
270 
271  // modify QP
272  Int* pdQPs = m_pcCfg->getdQPs();
273  if ( pdQPs )
274  {
275    dQP += pdQPs[ rpcSlice->getPOC() ];
276  }
277 
278  // ------------------------------------------------------------------------------------------------------------------
279  // Lambda computation
280  // ------------------------------------------------------------------------------------------------------------------
281 
282  Int iQP;
283  Double dOrigQP = dQP;
284
285  // pre-compute lambda and QP values for all possible QP candidates
286  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
287  {
288    // compute QP value
289    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
290   
291    // compute lambda value
292    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
293    Int    SHIFT_QP = 12;
294    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
295#if FULL_NBIT
296    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
297#else
298    Int    bitdepth_luma_qp_scale = 0;
299#endif
300    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
301#if FULL_NBIT
302    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
303#endif
304    // Case #1: I or P-slices (key-frame)
305    Double dQPFactor;
306    if( eSliceType != I_SLICE ) 
307    {
308      dQPFactor = m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPFactor;
309    }
310    else
311    {
312      dQPFactor = 0.57 * dLambda_scale;
313    }
314
315    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
316
317    if ( iDepth>0 )
318    {
319#if FULL_NBIT
320        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
321#else
322        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
323#endif
324    }
325   
326    // if hadamard is used in ME process
327    if ( !m_pcCfg->getUseHADME() )
328    {
329      dLambda *= 0.95;
330    }
331   
332#if H0736_AVC_STYLE_QP_RANGE
333    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
334#else
335    iQP = max( MIN_QP, min( MAX_QP, (Int)floor( dQP + 0.5 ) ) );
336#endif
337
338    m_pdRdPicLambda[iDQpIdx] = dLambda;
339    m_pdRdPicQp    [iDQpIdx] = dQP;
340    m_piRdPicQp    [iDQpIdx] = iQP;
341  }
342 
343  // obtain dQP = 0 case
344  dLambda = m_pdRdPicLambda[0];
345  dQP     = m_pdRdPicQp    [0];
346  iQP     = m_piRdPicQp    [0];
347 
348  if( rpcSlice->getSliceType( ) != I_SLICE )
349  {
350    dLambda *= m_pcCfg->getLambdaModifier( iDepth );
351  }
352
353  // store lambda
354  m_pcRdCost ->setLambda( dLambda );
355#if WEIGHTED_CHROMA_DISTORTION
356// for RDO
357  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
358#if H0736_AVC_STYLE_QP_RANGE
359  Double weight = 1.0;
360  if(iQP >= 0)
361  {
362    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
363  }
364#else
365  Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
366#endif
367  m_pcRdCost ->setChromaDistortionWeight( weight );     
368#endif
369
370#if HHI_VSO
371  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->isDepthCoder()  );
372  m_pcRdCost->setLambdaVSO( dLambda * m_pcCfg->getLambdaScaleVSO() );
373#endif
374
375#if SAIT_VSO_EST_A0033
376  m_pcRdCost->setDisparityCoeff( m_pcCfg->getDispCoeff() );
377#endif
378#if LGE_WVSO_A0119
379  if( m_pcCfg->getUseWVSO() && m_pcCfg->isDepthCoder() )
380  {
381
382    Int iDWeight, iVSOWeight, iVSDWeight;
383    iDWeight = m_pcCfg->getDWeight();
384    iVSOWeight = m_pcCfg->getVSOWeight();
385    iVSDWeight = m_pcCfg->getVSDWeight();
386
387    m_pcRdCost->setDWeight( iDWeight );
388    m_pcRdCost->setVSOWeight( iVSOWeight );
389    m_pcRdCost->setVSDWeight( iVSDWeight );
390
391  }
392#endif
393#if RDOQ_CHROMA_LAMBDA
394// for RDOQ
395  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
396#else
397  m_pcTrQuant->setLambda( dLambda );
398#endif
399
400#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
401// For ALF or SAO
402  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
403#else
404  rpcSlice   ->setLambda( dLambda );
405#endif
406 
407#if HHI_INTER_VIEW_MOTION_PRED
408  m_pcRdCost ->setLambdaMVReg ( dLambda * m_pcCfg->getMultiviewMvRegLambdaScale() );
409#endif
410 
411#if HB_LAMBDA_FOR_LDC
412  // restore original slice type
413  eSliceType = eSliceTypeBaseView;
414  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
415  {
416    eSliceType = B_SLICE;
417  }
418  rpcSlice->setSliceType( eSliceType );
419#endif
420 
421  rpcSlice->setSliceQp          ( iQP );
422#if ADAPTIVE_QP_SELECTION
423  rpcSlice->setSliceQpBase      ( iQP );
424#endif
425  rpcSlice->setSliceQpDelta     ( 0 );
426  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
427  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
428 
429  rpcSlice->setLoopFilterOffsetInAPS( m_pcCfg->getLoopFilterOffsetInAPS() );
430#if DBL_CONTROL
431  if (rpcSlice->getPPS()->getDeblockingFilterControlPresent())
432  {
433#endif
434    rpcSlice->setInheritDblParamFromAPS( m_pcCfg->getLoopFilterOffsetInAPS() ? 1 : 0 );
435    rpcSlice->setLoopFilterDisable( m_pcCfg->getLoopFilterDisable() );
436    if ( !rpcSlice->getLoopFilterDisable())
437    {
438      rpcSlice->setLoopFilterBetaOffset( m_pcCfg->getLoopFilterBetaOffset() );
439      rpcSlice->setLoopFilterTcOffset( m_pcCfg->getLoopFilterTcOffset() );
440    }
441#if DBL_CONTROL
442  }
443#endif
444
445  rpcSlice->setDepth            ( iDepth );
446 
447  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
448  if( eSliceType == I_SLICE )
449  {
450    pcPic->setTLayer(0);
451  }
452  rpcSlice->setTLayer( pcPic->getTLayer() );
453#if !H0566_TLA
454  rpcSlice->setTLayerSwitchingFlag( pPPS->getTLayerSwitchingFlag( pcPic->getTLayer() ) );
455#endif
456
457  assert( m_apcPicYuvPred );
458  assert( m_apcPicYuvResi );
459 
460  pcPic->setPicYuvPred( m_apcPicYuvPred );
461  pcPic->setPicYuvResi( m_apcPicYuvResi );
462  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
463  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
464  rpcSlice->setEntropySliceMode     ( m_pcCfg->getEntropySliceMode()     );
465  rpcSlice->setEntropySliceArgument ( m_pcCfg->getEntropySliceArgument() );
466
467#if ( HHI_MPI || HHI_INTER_VIEW_MOTION_PRED )
468  #if ( HHI_MPI && HHI_INTER_VIEW_MOTION_PRED )
469  const int iExtraMergeCandidates = ( pSPS->getUseMVI() || pSPS->getMultiviewMvPredMode() ) ? 1 : 0;
470  #elif HHI_MPI
471  const int iExtraMergeCandidates = pSPS->getUseMVI() ? 1 : 0;
472  #else
473  const int iExtraMergeCandidates = pSPS->getMultiviewMvPredMode() ? 1 : 0;
474  #endif
475  rpcSlice->setMaxNumMergeCand      (MRG_MAX_NUM_CANDS_SIGNALED+iExtraMergeCandidates);
476#else
477  rpcSlice->setMaxNumMergeCand      (MRG_MAX_NUM_CANDS_SIGNALED);
478#endif
479  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPredIdc() );
480}
481
482// ====================================================================================================================
483// Public member functions
484// ====================================================================================================================
485
486Void TEncSlice::setSearchRange( TComSlice* pcSlice )
487{
488  Int iCurrPOC = pcSlice->getPOC();
489  Int iRefPOC;
490  Int iGOPSize = m_pcCfg->getGOPSize();
491  Int iOffset = (iGOPSize >> 1);
492  Int iMaxSR = m_pcCfg->getSearchRange();
493  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
494 
495  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
496  {
497    RefPicList e = (RefPicList)iDir;
498    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
499    {
500      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
501      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
502      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
503    }
504  }
505}
506
507/**
508 - multi-loop slice encoding for different slice QP
509 .
510 \param rpcPic    picture class
511 */
512Void TEncSlice::precompressSlice( TComPic*& rpcPic )
513{
514  // if deltaQP RD is not used, simply return
515  if ( m_pcCfg->getDeltaQpRD() == 0 )
516  {
517    return;
518  }
519 
520  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
521  Double     dPicRdCostBest = MAX_DOUBLE;
522  UInt       uiQpIdxBest = 0;
523 
524  Double dFrameLambda;
525#if FULL_NBIT
526  Int    SHIFT_QP = 12 + 6 * (g_uiBitDepth - 8);
527#else
528  Int    SHIFT_QP = 12;
529#endif
530 
531  // set frame lambda
532  if (m_pcCfg->getGOPSize() > 1)
533  {
534    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
535  }
536  else
537  {
538    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
539  }
540  m_pcRdCost      ->setFrameLambda(dFrameLambda);
541 
542  // for each QP candidate
543  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
544  {
545    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
546#if ADAPTIVE_QP_SELECTION
547    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
548#endif
549    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
550#if WEIGHTED_CHROMA_DISTORTION
551    // for RDO
552    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
553    int iQP = m_piRdPicQp    [uiQpIdx];
554#if H0736_AVC_STYLE_QP_RANGE
555    Double weight = 1.0;
556    if(iQP >= 0)
557    {
558      weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
559    }
560#else
561    Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
562#endif
563    m_pcRdCost    ->setChromaDistortionWeight( weight );     
564#endif
565
566#if RDOQ_CHROMA_LAMBDA
567    // for RDOQ
568    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
569#else
570    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
571#endif
572#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
573    // For ALF or SAO
574    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
575#else
576    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
577#endif
578#if HHI_INTER_VIEW_MOTION_PRED
579    m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdx] * m_pcCfg->getMultiviewMvRegLambdaScale() );
580#endif
581   
582    // try compress
583    compressSlice   ( rpcPic );
584   
585    Double dPicRdCost;
586    UInt64 uiPicDist        = m_uiPicDist;
587    UInt64 uiALFBits        = 0;
588   
589    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
590   
591    // compute RD cost and choose the best
592    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
593   
594    if ( dPicRdCost < dPicRdCostBest )
595    {
596      uiQpIdxBest    = uiQpIdx;
597      dPicRdCostBest = dPicRdCost;
598    }
599  }
600 
601  // set best values
602  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
603#if ADAPTIVE_QP_SELECTION
604  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
605#endif
606  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
607#if WEIGHTED_CHROMA_DISTORTION
608  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
609  int iQP = m_piRdPicQp    [uiQpIdxBest];
610#if H0736_AVC_STYLE_QP_RANGE
611  Double weight = 1.0;
612  if(iQP >= 0)
613  {
614    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
615  }
616#else
617  Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
618#endif
619  m_pcRdCost ->setChromaDistortionWeight( weight );     
620#endif
621
622#if RDOQ_CHROMA_LAMBDA
623  // for RDOQ
624  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
625#else
626  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
627#endif
628#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
629  // For ALF or SAO
630  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
631#else
632  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
633#endif
634#if HHI_INTER_VIEW_MOTION_PRED
635  m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdxBest] * m_pcCfg->getMultiviewMvRegLambdaScale() );
636#endif
637}
638
639/** \param rpcPic   picture class
640 */
641Void TEncSlice::compressSlice( TComPic*& rpcPic )
642{
643  UInt  uiCUAddr;
644  UInt   uiStartCUAddr;
645  UInt   uiBoundingCUAddr;
646  rpcPic->getSlice(getSliceIdx())->setEntropySliceCounter(0);
647  TEncBinCABAC* pppcRDSbacCoder = NULL;
648  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
649  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
650#if LG_ZEROINTRADEPTHRESI_A0087
651  rpcPic->setIntraPeriod(this->m_pcCfg->getIntraPeriod());
652#endif
653 
654  // initialize cost values
655  m_uiPicTotalBits  = 0;
656  m_dPicRdCost      = 0;
657  m_uiPicDist       = 0;
658 
659#if CABAC_INIT_FLAG && FIX_POZNAN_CABAC_INIT_FLAG
660  Bool bReset =(pcSlice->getPOC() == 0) || 
661    (pcSlice->getPOC() % m_pcCfg->getIntraPeriod() == 0) ||
662    (pcSlice->getPPS()->getEncPrevPOC() % m_pcCfg->getIntraPeriod() == 0) ||
663    (pcSlice->getPOC()/m_pcCfg->getIntraPeriod() > pcSlice->getPPS()->getEncPrevPOC()/m_pcCfg->getIntraPeriod()) ||
664    (m_pcGOPEncoder->getGOPSize() == 0);
665
666  if ( bReset && pcSlice->getPPS()->getCabacInitPresentFlag())
667  {
668    pcSlice->getPPS()->setEncCABACTableIdx(pcSlice->getSliceType()); // reset cabac initialization table index
669  };
670#endif
671
672  // set entropy coder
673  if( m_pcCfg->getUseSBACRD() )
674  {
675    m_pcSbacCoder->init( m_pcBinCABAC );
676    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
677    m_pcEntropyCoder->resetEntropy      ();
678    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
679    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
680    pppcRDSbacCoder->setBinCountingEnableFlag( false );
681    pppcRDSbacCoder->setBinsCoded( 0 );
682  }
683  else
684  {
685    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
686    m_pcEntropyCoder->resetEntropy      ();
687    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
688  }
689 
690  //------------------------------------------------------------------------------
691  //  Weighted Prediction parameters estimation.
692  //------------------------------------------------------------------------------
693  // calculate AC/DC values for current picture
694  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPredIdc() )
695  {
696    xCalcACDCParamSlice(pcSlice);
697  }
698
699  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==1);
700  Bool bWp_implicit = (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==2);
701
702  if ( bWp_explicit || bWp_implicit )
703  {
704    //------------------------------------------------------------------------------
705    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
706    //------------------------------------------------------------------------------
707    if ( pcSlice->getSliceMode()==2 || pcSlice->getEntropySliceMode()==2 )
708    {
709      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
710    }
711
712    if( bWp_explicit )
713    {
714      xEstimateWPParamSlice( pcSlice );
715    }
716   
717    pcSlice->initWpScaling();
718
719    // check WP on/off
720    if( bWp_explicit )
721    {
722      xCheckWPEnable( pcSlice );
723    }
724  }
725
726#if ADAPTIVE_QP_SELECTION
727  if( m_pcCfg->getUseAdaptQpSelect() )
728  {
729    m_pcTrQuant->clearSliceARLCnt();
730    if(pcSlice->getSliceType()!=I_SLICE)
731    {
732      Int qpBase = pcSlice->getSliceQpBase();
733      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
734    }
735  }
736#endif
737  // initialize ALF parameters
738  m_pcEntropyCoder->setAlfCtrl(false);
739  m_pcEntropyCoder->setMaxAlfCtrlDepth(0); //unnecessary
740 
741#if SAIT_VSO_EST_A0033
742 if( m_pcCfg->getUseVSO() )
743 {
744
745   Int frameWidth = m_pcCfg->getSourceWidth();
746   Pel* pVideoRec = m_pcRdCost->getVideoRecPicYuv()->getLumaAddr();
747   Int iVideoRecStride = m_pcRdCost->getVideoRecPicYuv()->getStride();
748
749   Pel* pDepthOrg = m_pcRdCost->getDepthPicYuv()->getLumaAddr();
750   Int iDepthOrgStride = m_pcRdCost->getDepthPicYuv()->getStride();
751
752   for( Int y = 0 ; y < m_pcCfg->getSourceHeight() ; y++ )
753   {
754     pVideoRec[-1] = pVideoRec[0];
755     pVideoRec[frameWidth] = pVideoRec[frameWidth-1];
756     pDepthOrg[-1] = pDepthOrg[0];
757     pDepthOrg[frameWidth] = pDepthOrg[frameWidth-1];
758
759     pVideoRec += iVideoRecStride;
760     pDepthOrg += iDepthOrgStride;
761   }
762 }
763#endif
764
765  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
766  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
767  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
768  Int  iNumSubstreams = 1;
769  UInt uiTilesAcross  = 0;
770
771#if LGE_ILLUCOMP_B0045
772  if (pcEncTop->getViewId() != 0 
773#if !LGE_ILLUCOMP_DEPTH_C0046
774      && !pcEncTop->isDepthCoder() 
775#endif
776      && pcEncTop->getUseIC())   // DCP of ViewID 0 is not available
777  {
778    pcSlice ->xSetApplyIC();
779  }
780#endif
781
782  if( m_pcCfg->getUseSBACRD() )
783  {
784    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
785    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
786    delete[] m_pcBufferSbacCoders;
787    delete[] m_pcBufferBinCoderCABACs;
788    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
789    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
790    for (int ui = 0; ui < uiTilesAcross; ui++)
791    {
792      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
793    }
794    for (UInt ui = 0; ui < uiTilesAcross; ui++)
795    {
796      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
797    }
798
799    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
800    {
801      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
802    }
803  }
804  //if( m_pcCfg->getUseSBACRD() )
805  {
806    delete[] m_pcBufferLowLatSbacCoders;
807    delete[] m_pcBufferLowLatBinCoderCABACs;
808    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
809    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
810    for (int ui = 0; ui < uiTilesAcross; ui++)
811    {
812      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
813    }
814    for (UInt ui = 0; ui < uiTilesAcross; ui++)
815      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
816  }
817  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
818  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
819  UInt uiCol=0, uiLin=0, uiSubStrm=0;
820#if !REMOVE_TILE_DEPENDENCE
821  Int  iBreakDep      = 0;
822#endif
823  UInt uiTileCol      = 0;
824  UInt uiTileStartLCU = 0;
825  UInt uiTileLCUX     = 0;
826#if !QC_MVHEVC_B0046
827  Int iLastPosY = -1;
828#endif
829  // for every CU in slice
830  UInt uiEncCUOrder;
831  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
832  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
833       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
834       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
835  {
836    // initialize CU encoder
837    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
838    pcCU->initCU( rpcPic, uiCUAddr );
839#if !QC_MVHEVC_B0046
840    if ( m_pcRdCost->getUseRenModel() )
841    {
842      // updated renderer model if necessary
843      Int iCurPosX;
844      Int iCurPosY; 
845      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
846      if ( iCurPosY != iLastPosY )
847      {
848        iLastPosY = iCurPosY; 
849       
850        m_pcGOPEncoder->getEncTop()->getEncTop()->setupRenModel( rpcPic->getCurrSlice()->getPOC() , rpcPic->getCurrSlice()->getSPS()->getViewId(), rpcPic->getCurrSlice()->getSPS()->isDepth() ? 1 : 0, iCurPosY );
851      }
852    }   
853#endif
854    // inherit from TR if necessary, select substream to use.
855    if( m_pcCfg->getUseSBACRD() )
856    {
857#if !REMOVE_TILE_DEPENDENCE
858      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
859#endif
860      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
861      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
862      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
863      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
864      uiCol     = uiCUAddr % uiWidthInLCUs;
865      uiLin     = uiCUAddr / uiWidthInLCUs;
866#if !REMOVE_TILE_DEPENDENCE
867#if WPP_SIMPLIFICATION
868      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
869#else
870      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
871#endif
872#else
873#if WPP_SIMPLIFICATION
874      if (pcSlice->getPPS()->getNumSubstreams() > 1)
875#else
876      if (pcSlice->getPPS()->getEntropyCodingSynchro())
877#endif
878#endif
879      {
880        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
881        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
882        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
883                      + uiLin%iNumSubstreamsPerTile;
884      }
885      else
886      {
887        // dependent tiles => substreams are "per frame".
888        uiSubStrm = uiLin % iNumSubstreams;
889      }
890#if WPP_SIMPLIFICATION
891      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
892#else
893      if ( pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX) )
894#endif
895      {
896        // We'll sync if the TR is available.
897        TComDataCU *pcCUUp = pcCU->getCUAbove();
898        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
899        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
900        TComDataCU *pcCUTR = NULL;
901#if WPP_SIMPLIFICATION
902        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
903        {
904          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
905        }
906#else
907        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
908        {
909          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
910        }
911#endif
912        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
913             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
914#if !REMOVE_TILE_DEPENDENCE
915             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
916#else
917             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
918#endif
919             )||
920             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
921             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
922#if !REMOVE_TILE_DEPENDENCE
923             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
924#else
925             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
926#endif
927             )
928           )
929        {
930          // TR not available.
931        }
932        else
933        {
934          // TR is available, we use it.
935          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
936        }
937      }
938      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
939    }
940
941    // reset the entropy coder
942    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
943        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
944        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
945    {
946#if CABAC_INIT_FLAG
947      SliceType sliceType = pcSlice->getSliceType();
948      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
949      {
950        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
951      }
952      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
953      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
954      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
955      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
956#else
957      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp(), false );
958      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
959      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp() );
960      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
961#endif
962    }
963#if !REMOVE_TILE_DEPENDENCE
964    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
965    {
966      // Synchronize cabac probabilities with LCU among Tiles
967      if( (uiTileLCUX != 0) &&
968          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
969      { 
970        TComDataCU *pcCULeft = pcCU->getCULeft();
971        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
972
973        if ( (true/*bEnforceSliceRestriction*/ &&
974              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
975               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
976              )
977             )||
978             (true/*bEnforceEntropySliceRestriction*/ &&
979              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
980               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
981              )
982             )
983           )
984        {
985          // Left not available.
986        }
987        else
988        {
989          // Left is available, we use it.
990          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
991          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
992        }
993      }
994    }
995#endif
996    // if RD based on SBAC is used
997    if( m_pcCfg->getUseSBACRD() )
998    {
999      // set go-on entropy coder
1000      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1001      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1002     
1003      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1004      // run CU encoder
1005      m_pcCuEncoder->compressCU( pcCU );
1006     
1007      // restore entropy coder to an initial stage
1008      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1009      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1010      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1011      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1012      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1013      m_pcBitCounter->resetBits();
1014      pppcRDSbacCoder->setBinsCoded( 0 );
1015      m_pcCuEncoder->encodeCU( pcCU );
1016
1017      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1018      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1019      {
1020        pcSlice->setNextSlice( true );
1021        break;
1022      }
1023      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1024      {
1025        pcSlice->setNextEntropySlice( true );
1026        break;
1027      }
1028      if( m_pcCfg->getUseSBACRD() )
1029      {
1030         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1031       
1032         //Store probabilties of second LCU in line into buffer
1033#if WPP_SIMPLIFICATION
1034        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
1035#else
1036        if (pcSlice->getPPS()->getEntropyCodingSynchro() && uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro())
1037#endif
1038        {
1039          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1040        }
1041      }
1042#if !REMOVE_TILE_DEPENDENCE
1043      if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1044      {
1045         //Store probabilties for next tile
1046        if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1047            (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1048        {
1049          m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1050        }
1051      }
1052#endif
1053    }
1054    // other case: encodeCU is not called
1055    else
1056    {
1057      m_pcCuEncoder->compressCU( pcCU );
1058      m_pcCuEncoder->encodeCU( pcCU );
1059      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1060      {
1061        pcSlice->setNextSlice( true );
1062        break;
1063      }
1064      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1065      {
1066        pcSlice->setNextEntropySlice( true );
1067        break;
1068      }
1069    }
1070   
1071    m_uiPicTotalBits += pcCU->getTotalBits();
1072    m_dPicRdCost     += pcCU->getTotalCost();
1073    m_uiPicDist      += pcCU->getTotalDistortion();
1074  }
1075  xRestoreWPparam( pcSlice );
1076}
1077
1078/**
1079 \param  rpcPic        picture class
1080 \retval rpcBitstream  bitstream class
1081 */
1082Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
1083{
1084  UInt       uiCUAddr;
1085  UInt       uiStartCUAddr;
1086  UInt       uiBoundingCUAddr;
1087  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1088
1089  uiStartCUAddr=pcSlice->getEntropySliceCurStartCUAddr();
1090  uiBoundingCUAddr=pcSlice->getEntropySliceCurEndCUAddr();
1091  // choose entropy coder
1092  {
1093    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1094    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1095  }
1096 
1097  m_pcCuEncoder->setBitCounter( NULL );
1098  m_pcBitCounter = NULL;
1099  // Appropriate substream bitstream is switched later.
1100  // for every CU
1101#if ENC_DEC_TRACE
1102  g_bJustDoIt = g_bEncDecTraceEnable;
1103#endif
1104  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1105  DTRACE_CABAC_T( "\tPOC: " );
1106  DTRACE_CABAC_V( rpcPic->getPOC() );
1107  DTRACE_CABAC_T( "\n" );
1108#if ENC_DEC_TRACE
1109  g_bJustDoIt = g_bEncDecTraceDisable;
1110#endif
1111
1112  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1113  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1114  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1115  UInt uiBitsOriginallyInSubstreams = 0;
1116  {
1117    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1118    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1119    {
1120      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1121    }
1122   
1123    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1124    {
1125      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1126    }
1127
1128    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1129    {
1130      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1131    }
1132  }
1133
1134  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1135  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1136#if !REMOVE_TILE_DEPENDENCE
1137  Int  iBreakDep      = 0;
1138#endif
1139  UInt uiTileCol      = 0;
1140  UInt uiTileStartLCU = 0;
1141  UInt uiTileLCUX     = 0;
1142
1143  UInt uiEncCUOrder;
1144  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1145                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1146                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1147  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1148       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1149       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1150  {
1151    if( m_pcCfg->getUseSBACRD() )
1152    {
1153#if !REMOVE_TILE_DEPENDENCE
1154      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
1155#endif
1156      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1157      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1158      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1159      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1160      uiCol     = uiCUAddr % uiWidthInLCUs;
1161      uiLin     = uiCUAddr / uiWidthInLCUs;
1162#if !REMOVE_TILE_DEPENDENCE
1163#if WPP_SIMPLIFICATION
1164      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
1165#else
1166      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
1167#endif
1168#else
1169#if WPP_SIMPLIFICATION
1170      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1171#else
1172      if (pcSlice->getPPS()->getEntropyCodingSynchro())
1173#endif
1174#endif
1175      {
1176        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1177        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1178        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1179                      + uiLin%iNumSubstreamsPerTile;
1180      }
1181      else
1182      {
1183        // dependent tiles => substreams are "per frame".
1184        uiSubStrm = uiLin % iNumSubstreams;
1185      }
1186
1187      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1188
1189      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1190#if WPP_SIMPLIFICATION
1191      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1192#else
1193      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX))
1194#endif
1195      {
1196        // We'll sync if the TR is available.
1197        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1198        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1199        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1200        TComDataCU *pcCUTR = NULL;
1201#if WPP_SIMPLIFICATION
1202        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1203        {
1204          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1205        }
1206#else
1207        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
1208        {
1209          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
1210        }
1211#endif
1212        if ( (true/*bEnforceSliceRestriction*/ &&
1213             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1214             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1215#if !REMOVE_TILE_DEPENDENCE
1216             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1217#else
1218             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1219#endif
1220             ))||
1221             (true/*bEnforceEntropySliceRestriction*/ &&
1222             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1223             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
1224#if !REMOVE_TILE_DEPENDENCE
1225             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1226#else
1227             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1228#endif
1229             ))
1230           )
1231        {
1232          // TR not available.
1233        }
1234        else
1235        {
1236          // TR is available, we use it.
1237          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1238        }
1239      }
1240      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1241    }
1242    // reset the entropy coder
1243    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1244        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1245        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1246    {
1247      Int iTileIdx            = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr);
1248      Bool bWriteTileMarker   = false;
1249      // check if current iTileIdx should have a marker
1250      for (Int iEntryIdx=0; iEntryIdx<m_pcCfg->getMaxTileMarkerEntryPoints()-1; iEntryIdx++)
1251      {
1252        bWriteTileMarker = ( (((Int)((iEntryIdx+1)*m_pcCfg->getMaxTileMarkerOffset()+0.5)) == iTileIdx ) && iEntryIdx < (m_pcCfg->getMaxTileMarkerEntryPoints()-1)) ? true : false;
1253        if (bWriteTileMarker)
1254        {
1255          break;
1256        }
1257      }
1258      {
1259        // We're crossing into another tile, tiles are independent.
1260        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1261        // have to perform it here.
1262#if WPP_SIMPLIFICATION
1263        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1264#else
1265        if (pcSlice->getPPS()->getEntropyCodingSynchro())
1266#endif
1267        {
1268          ; // do nothing.
1269        }
1270        else
1271        {
1272#if CABAC_INIT_FLAG
1273          SliceType sliceType  = pcSlice->getSliceType();
1274          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
1275          {
1276            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1277          }
1278          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1279#else
1280          m_pcEntropyCoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
1281#endif
1282          pcSubstreams[uiSubStrm].write( 1, 1 );
1283          pcSubstreams[uiSubStrm].writeAlignZero();
1284        }
1285      }
1286      {
1287        // Write TileMarker into the appropriate substream (nothing has been written to it yet).
1288        if (m_pcCfg->getTileMarkerFlag() && bWriteTileMarker)
1289        {
1290          // Log locations where tile markers are to be inserted during emulation prevention
1291          UInt uiMarkerCount = pcSubstreams[uiSubStrm].getTileMarkerLocationCount();
1292          pcSubstreams[uiSubStrm].setTileMarkerLocation     ( uiMarkerCount, pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3 );
1293          pcSubstreams[uiSubStrm].setTileMarkerLocationCount( uiMarkerCount + 1 );
1294          // Write tile index
1295          m_pcEntropyCoder->writeTileMarker(iTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx()); // Tile index
1296        }
1297
1298       
1299        UInt uiAccumulatedSubstreamLength = 0;
1300        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1301        {
1302          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1303        }
1304        UInt uiLocationCount = pcSlice->getTileLocationCount();
1305        // add bits coded in previous entropy slices + bits coded so far
1306        pcSlice->setTileLocation( uiLocationCount, (pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3 ); 
1307        pcSlice->setTileLocationCount( uiLocationCount + 1 );
1308      }
1309    }
1310
1311#if OL_QTLIMIT_PREDCODING_B0068
1312    rpcPic->setReduceBitsFlag(true);
1313#endif
1314
1315    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1316#if !REMOVE_TILE_DEPENDENCE
1317    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1318    {   
1319      // Synchronize cabac probabilities with LCU among Tiles
1320      if( (uiTileLCUX != 0) &&
1321          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
1322      {
1323        TComDataCU *pcCULeft = pcCU->getCULeft();
1324        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1325
1326        if ( (true/*bEnforceSliceRestriction*/ &&
1327              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1328               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
1329              )
1330             )||
1331             (true/*bEnforceEntropySliceRestriction*/ &&
1332              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1333               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
1334              )
1335             )
1336           )
1337        {
1338          // Left not available.
1339        }
1340        else
1341        {
1342          // Left is available, we use it.
1343          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
1344          m_pcSbacCoder->loadContexts(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1345        }
1346      }
1347    }
1348#endif
1349
1350#if SAO_UNIT_INTERLEAVING
1351    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
1352    {
1353      Int iNumCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
1354      Int iCUAddrInSlice    = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU());
1355      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1356      Int rx = uiCUAddr % iNumCuInWidth;
1357      Int ry = uiCUAddr / iNumCuInWidth;
1358      m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
1359    }
1360#endif
1361#if ENC_DEC_TRACE
1362    g_bJustDoIt = g_bEncDecTraceEnable;
1363#endif
1364    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && 
1365      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1366    {
1367      m_pcCuEncoder->encodeCU( pcCU, true );
1368    }
1369    else
1370    {
1371      m_pcCuEncoder->encodeCU( pcCU );
1372    }
1373#if ENC_DEC_TRACE
1374    g_bJustDoIt = g_bEncDecTraceDisable;
1375#endif   
1376    if( m_pcCfg->getUseSBACRD() )
1377    {
1378       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1379       
1380
1381       //Store probabilties of second LCU in line into buffer
1382#if WPP_SIMPLIFICATION
1383      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1384#else
1385      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro()))
1386#endif
1387      {
1388        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1389      }
1390    }
1391#if !REMOVE_TILE_DEPENDENCE
1392    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1393    {
1394      pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1395       //Store probabilties for next tile
1396      if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1397          (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1398      {
1399        m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1400      }
1401    }
1402#endif
1403
1404#if OL_QTLIMIT_PREDCODING_B0068
1405    rpcPic->setReduceBitsFlag(false);
1406#endif
1407
1408  }
1409
1410#if ADAPTIVE_QP_SELECTION
1411  if( m_pcCfg->getUseAdaptQpSelect() )
1412  {
1413    m_pcTrQuant->storeSliceQpNext(pcSlice);
1414  }
1415#endif
1416#if CABAC_INIT_FLAG
1417  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1418  {
1419    m_pcEntropyCoder->determineCabacInitIdx();
1420  }
1421#endif
1422}
1423
1424/** Determines the starting and bounding LCU address of current slice / entropy slice
1425 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1426 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1427 */
1428Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1429{
1430  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1431  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1432#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1433  UInt tileIdxIncrement;
1434  UInt tileIdx;
1435  UInt tileWidthInLcu;
1436  UInt tileHeightInLcu;
1437  UInt tileTotalCount;
1438#endif
1439
1440  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1441  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1442  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1443  if (bEncodeSlice) 
1444  {
1445    UInt uiCUAddrIncrement;
1446    switch (m_pcCfg->getSliceMode())
1447    {
1448    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1449      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1450      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1451      break;
1452    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1453      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1454      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1455      break;
1456#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1457    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1458      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1459        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1460        );
1461      uiCUAddrIncrement        = 0;
1462      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1463
1464      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1465      {
1466        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1467        {
1468          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1469          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1470          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1471        }
1472      }
1473
1474      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1475      break;
1476#endif
1477    default:
1478      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1479      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1480      break;
1481    } 
1482    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1483  }
1484  else
1485  {
1486    UInt uiCUAddrIncrement     ;
1487    switch (m_pcCfg->getSliceMode())
1488    {
1489    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1490      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1491      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1492      break;
1493#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1494    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1495      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1496        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1497        );
1498      uiCUAddrIncrement        = 0;
1499      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1500
1501      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1502      {
1503        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1504        {
1505          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1506          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1507          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1508        }
1509      }
1510
1511      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1512      break;
1513#endif
1514    default:
1515      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1516      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1517      break;
1518    } 
1519    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1520  }
1521
1522#if COMPLETE_SLICES_IN_TILE
1523  Bool tileBoundary = false;
1524  if ((m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE || m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE) && 
1525      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1526  {
1527    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1528    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1529    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1530    UInt tileBoundingCUAddrSlice = 0;
1531    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1532    {
1533      lcuEncAddr++;
1534      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1535    }
1536    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1537   
1538    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1539    {
1540      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1541      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1542      tileBoundary = true;
1543    }
1544  }
1545#endif
1546
1547  // Entropy slice
1548  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
1549  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
1550  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
1551  if (bEncodeSlice) 
1552  {
1553    UInt uiCUAddrIncrement;
1554    switch (m_pcCfg->getEntropySliceMode())
1555    {
1556    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1557      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1558      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1559      break;
1560    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
1561      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1562      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
1563      break;
1564    default:
1565      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1566      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1567      break;
1568    } 
1569    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1570  }
1571  else
1572  {
1573    UInt uiCUAddrIncrement;
1574    switch (m_pcCfg->getEntropySliceMode())
1575    {
1576    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1577      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1578      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1579      break;
1580    default:
1581      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1582      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1583      break;
1584    } 
1585    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1586  }
1587  if(uiBoundingCUAddrEntropySlice>uiBoundingCUAddrSlice)
1588  {
1589    uiBoundingCUAddrEntropySlice = uiBoundingCUAddrSlice;
1590    pcSlice->setEntropySliceCurEndCUAddr(uiBoundingCUAddrSlice);
1591  }
1592  //calculate real entropy slice start address
1593  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1594  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1595  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1596  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1597  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1598  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1599  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1600  {
1601    uiInternalAddress++;
1602    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1603    {
1604      uiInternalAddress=0;
1605      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1606    }
1607    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1608    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1609  }
1610  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1611 
1612  pcSlice->setEntropySliceCurStartCUAddr(uiRealStartAddress);
1613  uiStartCUAddrEntropySlice=uiRealStartAddress;
1614 
1615  //calculate real slice start address
1616  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1617  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1618  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1619  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1620  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1621  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1622  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1623  {
1624    uiInternalAddress++;
1625    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1626    {
1627      uiInternalAddress=0;
1628      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1629    }
1630    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1631    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1632  }
1633  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1634 
1635  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1636  uiStartCUAddrSlice=uiRealStartAddress;
1637 
1638  // Make a joint decision based on reconstruction and entropy slice bounds
1639  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
1640  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
1641
1642
1643  if (!bEncodeSlice)
1644  {
1645    // 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
1646    // first. Set the flags accordingly.
1647    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1648      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1649      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1650#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1651      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1652      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1653#endif
1654#if COMPLETE_SLICES_IN_TILE
1655      || tileBoundary
1656#endif
1657)
1658    {
1659      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
1660      {
1661        pcSlice->setNextSlice       ( true );
1662        pcSlice->setNextEntropySlice( false );
1663      }
1664      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
1665      {
1666        pcSlice->setNextSlice       ( false );
1667        pcSlice->setNextEntropySlice( true );
1668      }
1669      else
1670      {
1671        pcSlice->setNextSlice       ( true );
1672        pcSlice->setNextEntropySlice( true );
1673      }
1674    }
1675    else
1676    {
1677      pcSlice->setNextSlice       ( false );
1678      pcSlice->setNextEntropySlice( false );
1679    }
1680  }
1681}
1682//! \}
Note: See TracBrowser for help on using the repository browser.