source: 3DVCSoftware/branches/HTM-4.1-dev2-Mediatek/source/Lib/TLibEncoder/TEncSlice.cpp @ 160

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