source: 3DVCSoftware/branches/HTM-5.1-dev3-Mediatek/source/Lib/TLibEncoder/TEncSlice.cpp @ 441

Last change on this file since 441 was 231, checked in by mitsubishi-htm, 12 years ago

-Integration of JCT3V-C0152 & JCT3V-C0131
-This check-in enable C0131 only

  • Property svn:eol-style set to native
File size: 65.8 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 && !pcEncTop->isDepthCoder() && pcEncTop->getUseIC())   // DCP of ViewID 0 is not available
773  {
774    pcSlice ->xSetApplyIC();
775  }
776#endif
777
778  if( m_pcCfg->getUseSBACRD() )
779  {
780    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
781    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
782    delete[] m_pcBufferSbacCoders;
783    delete[] m_pcBufferBinCoderCABACs;
784    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
785    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
786    for (int ui = 0; ui < uiTilesAcross; ui++)
787    {
788      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
789    }
790    for (UInt ui = 0; ui < uiTilesAcross; ui++)
791    {
792      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
793    }
794
795    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
796    {
797      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
798    }
799  }
800  //if( m_pcCfg->getUseSBACRD() )
801  {
802    delete[] m_pcBufferLowLatSbacCoders;
803    delete[] m_pcBufferLowLatBinCoderCABACs;
804    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
805    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
806    for (int ui = 0; ui < uiTilesAcross; ui++)
807    {
808      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
809    }
810    for (UInt ui = 0; ui < uiTilesAcross; ui++)
811      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
812  }
813
814#if MERL_VSP_C0152
815  // Send Depth/Texture pointers to slice level
816  pcSlice->setBWVSPLUTParam(m_aiShiftLUT, m_iShiftPrec);
817  pcSlice->setRefPicBaseTxt(m_pPicBaseTxt);
818  pcSlice->setRefPicBaseDepth(m_pPicBaseDepth);
819#endif
820
821  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
822  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
823  UInt uiCol=0, uiLin=0, uiSubStrm=0;
824#if !REMOVE_TILE_DEPENDENCE
825  Int  iBreakDep      = 0;
826#endif
827  UInt uiTileCol      = 0;
828  UInt uiTileStartLCU = 0;
829  UInt uiTileLCUX     = 0;
830#if !QC_MVHEVC_B0046
831  Int iLastPosY = -1;
832#endif
833  // for every CU in slice
834  UInt uiEncCUOrder;
835  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
836  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
837       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
838       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
839  {
840    // initialize CU encoder
841    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
842    pcCU->initCU( rpcPic, uiCUAddr );
843#if !QC_MVHEVC_B0046
844    if ( m_pcRdCost->getUseRenModel() )
845    {
846      // updated renderer model if necessary
847      Int iCurPosX;
848      Int iCurPosY; 
849      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
850      if ( iCurPosY != iLastPosY )
851      {
852        iLastPosY = iCurPosY; 
853       
854        m_pcGOPEncoder->getEncTop()->getEncTop()->setupRenModel( rpcPic->getCurrSlice()->getPOC() , rpcPic->getCurrSlice()->getSPS()->getViewId(), rpcPic->getCurrSlice()->getSPS()->isDepth() ? 1 : 0, iCurPosY );
855      }
856    }   
857#endif
858    // inherit from TR if necessary, select substream to use.
859    if( m_pcCfg->getUseSBACRD() )
860    {
861#if !REMOVE_TILE_DEPENDENCE
862      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
863#endif
864      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
865      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
866      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
867      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
868      uiCol     = uiCUAddr % uiWidthInLCUs;
869      uiLin     = uiCUAddr / uiWidthInLCUs;
870#if !REMOVE_TILE_DEPENDENCE
871#if WPP_SIMPLIFICATION
872      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
873#else
874      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
875#endif
876#else
877#if WPP_SIMPLIFICATION
878      if (pcSlice->getPPS()->getNumSubstreams() > 1)
879#else
880      if (pcSlice->getPPS()->getEntropyCodingSynchro())
881#endif
882#endif
883      {
884        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
885        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
886        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
887                      + uiLin%iNumSubstreamsPerTile;
888      }
889      else
890      {
891        // dependent tiles => substreams are "per frame".
892        uiSubStrm = uiLin % iNumSubstreams;
893      }
894#if WPP_SIMPLIFICATION
895      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
896#else
897      if ( pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX) )
898#endif
899      {
900        // We'll sync if the TR is available.
901        TComDataCU *pcCUUp = pcCU->getCUAbove();
902        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
903        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
904        TComDataCU *pcCUTR = NULL;
905#if WPP_SIMPLIFICATION
906        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
907        {
908          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
909        }
910#else
911        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
912        {
913          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
914        }
915#endif
916        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
917             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
918#if !REMOVE_TILE_DEPENDENCE
919             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
920#else
921             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
922#endif
923             )||
924             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
925             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
926#if !REMOVE_TILE_DEPENDENCE
927             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
928#else
929             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
930#endif
931             )
932           )
933        {
934          // TR not available.
935        }
936        else
937        {
938          // TR is available, we use it.
939          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
940        }
941      }
942      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
943    }
944
945    // reset the entropy coder
946    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
947        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
948        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
949    {
950#if CABAC_INIT_FLAG
951      SliceType sliceType = pcSlice->getSliceType();
952      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
953      {
954        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
955      }
956      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
957      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
958      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
959      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
960#else
961      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp(), false );
962      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
963      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp() );
964      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
965#endif
966    }
967#if !REMOVE_TILE_DEPENDENCE
968    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
969    {
970      // Synchronize cabac probabilities with LCU among Tiles
971      if( (uiTileLCUX != 0) &&
972          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
973      { 
974        TComDataCU *pcCULeft = pcCU->getCULeft();
975        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
976
977        if ( (true/*bEnforceSliceRestriction*/ &&
978              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
979               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
980              )
981             )||
982             (true/*bEnforceEntropySliceRestriction*/ &&
983              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
984               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
985              )
986             )
987           )
988        {
989          // Left not available.
990        }
991        else
992        {
993          // Left is available, we use it.
994          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
995          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
996        }
997      }
998    }
999#endif
1000    // if RD based on SBAC is used
1001    if( m_pcCfg->getUseSBACRD() )
1002    {
1003      // set go-on entropy coder
1004      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1005      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1006     
1007      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1008      // run CU encoder
1009      m_pcCuEncoder->compressCU( pcCU );
1010     
1011      // restore entropy coder to an initial stage
1012      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1013      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1014      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1015      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1016      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1017      m_pcBitCounter->resetBits();
1018      pppcRDSbacCoder->setBinsCoded( 0 );
1019      m_pcCuEncoder->encodeCU( pcCU );
1020
1021      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1022      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1023      {
1024        pcSlice->setNextSlice( true );
1025        break;
1026      }
1027      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1028      {
1029        pcSlice->setNextEntropySlice( true );
1030        break;
1031      }
1032      if( m_pcCfg->getUseSBACRD() )
1033      {
1034         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1035       
1036         //Store probabilties of second LCU in line into buffer
1037#if WPP_SIMPLIFICATION
1038        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
1039#else
1040        if (pcSlice->getPPS()->getEntropyCodingSynchro() && uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro())
1041#endif
1042        {
1043          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1044        }
1045      }
1046#if !REMOVE_TILE_DEPENDENCE
1047      if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1048      {
1049         //Store probabilties for next tile
1050        if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1051            (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1052        {
1053          m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1054        }
1055      }
1056#endif
1057    }
1058    // other case: encodeCU is not called
1059    else
1060    {
1061      m_pcCuEncoder->compressCU( pcCU );
1062      m_pcCuEncoder->encodeCU( pcCU );
1063      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1064      {
1065        pcSlice->setNextSlice( true );
1066        break;
1067      }
1068      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1069      {
1070        pcSlice->setNextEntropySlice( true );
1071        break;
1072      }
1073    }
1074   
1075    m_uiPicTotalBits += pcCU->getTotalBits();
1076    m_dPicRdCost     += pcCU->getTotalCost();
1077    m_uiPicDist      += pcCU->getTotalDistortion();
1078  }
1079  xRestoreWPparam( pcSlice );
1080}
1081
1082/**
1083 \param  rpcPic        picture class
1084 \retval rpcBitstream  bitstream class
1085 */
1086Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
1087{
1088  UInt       uiCUAddr;
1089  UInt       uiStartCUAddr;
1090  UInt       uiBoundingCUAddr;
1091  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1092
1093  uiStartCUAddr=pcSlice->getEntropySliceCurStartCUAddr();
1094  uiBoundingCUAddr=pcSlice->getEntropySliceCurEndCUAddr();
1095  // choose entropy coder
1096  {
1097    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1098    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1099  }
1100 
1101  m_pcCuEncoder->setBitCounter( NULL );
1102  m_pcBitCounter = NULL;
1103  // Appropriate substream bitstream is switched later.
1104  // for every CU
1105#if ENC_DEC_TRACE
1106  g_bJustDoIt = g_bEncDecTraceEnable;
1107#endif
1108  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1109  DTRACE_CABAC_T( "\tPOC: " );
1110  DTRACE_CABAC_V( rpcPic->getPOC() );
1111  DTRACE_CABAC_T( "\n" );
1112#if ENC_DEC_TRACE
1113  g_bJustDoIt = g_bEncDecTraceDisable;
1114#endif
1115
1116  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1117  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1118  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1119  UInt uiBitsOriginallyInSubstreams = 0;
1120  {
1121    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1122    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1123    {
1124      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1125    }
1126   
1127    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1128    {
1129      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1130    }
1131
1132    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1133    {
1134      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1135    }
1136  }
1137
1138  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1139  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1140#if !REMOVE_TILE_DEPENDENCE
1141  Int  iBreakDep      = 0;
1142#endif
1143  UInt uiTileCol      = 0;
1144  UInt uiTileStartLCU = 0;
1145  UInt uiTileLCUX     = 0;
1146
1147  UInt uiEncCUOrder;
1148
1149  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1150                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1151                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1152  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1153       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1154       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1155  {
1156    if( m_pcCfg->getUseSBACRD() )
1157    {
1158#if !REMOVE_TILE_DEPENDENCE
1159      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
1160#endif
1161      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1162      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1163      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1164      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1165      uiCol     = uiCUAddr % uiWidthInLCUs;
1166      uiLin     = uiCUAddr / uiWidthInLCUs;
1167#if !REMOVE_TILE_DEPENDENCE
1168#if WPP_SIMPLIFICATION
1169      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
1170#else
1171      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
1172#endif
1173#else
1174#if WPP_SIMPLIFICATION
1175      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1176#else
1177      if (pcSlice->getPPS()->getEntropyCodingSynchro())
1178#endif
1179#endif
1180      {
1181        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1182        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1183        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1184                      + uiLin%iNumSubstreamsPerTile;
1185      }
1186      else
1187      {
1188        // dependent tiles => substreams are "per frame".
1189        uiSubStrm = uiLin % iNumSubstreams;
1190      }
1191
1192      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1193
1194      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1195#if WPP_SIMPLIFICATION
1196      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1197#else
1198      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX))
1199#endif
1200      {
1201        // We'll sync if the TR is available.
1202        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1203        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1204        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1205        TComDataCU *pcCUTR = NULL;
1206#if WPP_SIMPLIFICATION
1207        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1208        {
1209          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1210        }
1211#else
1212        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
1213        {
1214          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
1215        }
1216#endif
1217        if ( (true/*bEnforceSliceRestriction*/ &&
1218             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1219             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1220#if !REMOVE_TILE_DEPENDENCE
1221             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1222#else
1223             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1224#endif
1225             ))||
1226             (true/*bEnforceEntropySliceRestriction*/ &&
1227             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1228             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
1229#if !REMOVE_TILE_DEPENDENCE
1230             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1231#else
1232             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1233#endif
1234             ))
1235           )
1236        {
1237          // TR not available.
1238        }
1239        else
1240        {
1241          // TR is available, we use it.
1242          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1243        }
1244      }
1245      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1246    }
1247    // reset the entropy coder
1248    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1249        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1250        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1251    {
1252      Int iTileIdx            = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr);
1253      Bool bWriteTileMarker   = false;
1254      // check if current iTileIdx should have a marker
1255      for (Int iEntryIdx=0; iEntryIdx<m_pcCfg->getMaxTileMarkerEntryPoints()-1; iEntryIdx++)
1256      {
1257        bWriteTileMarker = ( (((Int)((iEntryIdx+1)*m_pcCfg->getMaxTileMarkerOffset()+0.5)) == iTileIdx ) && iEntryIdx < (m_pcCfg->getMaxTileMarkerEntryPoints()-1)) ? true : false;
1258        if (bWriteTileMarker)
1259        {
1260          break;
1261        }
1262      }
1263      {
1264        // We're crossing into another tile, tiles are independent.
1265        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1266        // have to perform it here.
1267#if WPP_SIMPLIFICATION
1268        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1269#else
1270        if (pcSlice->getPPS()->getEntropyCodingSynchro())
1271#endif
1272        {
1273          ; // do nothing.
1274        }
1275        else
1276        {
1277#if CABAC_INIT_FLAG
1278          SliceType sliceType  = pcSlice->getSliceType();
1279          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
1280          {
1281            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1282          }
1283          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1284#else
1285          m_pcEntropyCoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
1286#endif
1287          pcSubstreams[uiSubStrm].write( 1, 1 );
1288          pcSubstreams[uiSubStrm].writeAlignZero();
1289        }
1290      }
1291      {
1292        // Write TileMarker into the appropriate substream (nothing has been written to it yet).
1293        if (m_pcCfg->getTileMarkerFlag() && bWriteTileMarker)
1294        {
1295          // Log locations where tile markers are to be inserted during emulation prevention
1296          UInt uiMarkerCount = pcSubstreams[uiSubStrm].getTileMarkerLocationCount();
1297          pcSubstreams[uiSubStrm].setTileMarkerLocation     ( uiMarkerCount, pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3 );
1298          pcSubstreams[uiSubStrm].setTileMarkerLocationCount( uiMarkerCount + 1 );
1299          // Write tile index
1300          m_pcEntropyCoder->writeTileMarker(iTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx()); // Tile index
1301        }
1302
1303       
1304        UInt uiAccumulatedSubstreamLength = 0;
1305        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1306        {
1307          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1308        }
1309        UInt uiLocationCount = pcSlice->getTileLocationCount();
1310        // add bits coded in previous entropy slices + bits coded so far
1311        pcSlice->setTileLocation( uiLocationCount, (pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3 ); 
1312        pcSlice->setTileLocationCount( uiLocationCount + 1 );
1313      }
1314    }
1315
1316#if OL_QTLIMIT_PREDCODING_B0068
1317    rpcPic->setReduceBitsFlag(true);
1318#endif
1319
1320    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1321#if !REMOVE_TILE_DEPENDENCE
1322    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1323    {   
1324      // Synchronize cabac probabilities with LCU among Tiles
1325      if( (uiTileLCUX != 0) &&
1326          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
1327      {
1328        TComDataCU *pcCULeft = pcCU->getCULeft();
1329        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1330
1331        if ( (true/*bEnforceSliceRestriction*/ &&
1332              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1333               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
1334              )
1335             )||
1336             (true/*bEnforceEntropySliceRestriction*/ &&
1337              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1338               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
1339              )
1340             )
1341           )
1342        {
1343          // Left not available.
1344        }
1345        else
1346        {
1347          // Left is available, we use it.
1348          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
1349          m_pcSbacCoder->loadContexts(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1350        }
1351      }
1352    }
1353#endif
1354
1355#if SAO_UNIT_INTERLEAVING
1356    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
1357    {
1358      Int iNumCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
1359      Int iCUAddrInSlice    = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU());
1360      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1361      Int rx = uiCUAddr % iNumCuInWidth;
1362      Int ry = uiCUAddr / iNumCuInWidth;
1363      m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
1364    }
1365#endif
1366#if ENC_DEC_TRACE
1367    g_bJustDoIt = g_bEncDecTraceEnable;
1368#endif
1369    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && 
1370      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1371    {
1372      m_pcCuEncoder->encodeCU( pcCU, true );
1373    }
1374    else
1375    {
1376      m_pcCuEncoder->encodeCU( pcCU );
1377    }
1378#if ENC_DEC_TRACE
1379    g_bJustDoIt = g_bEncDecTraceDisable;
1380#endif   
1381    if( m_pcCfg->getUseSBACRD() )
1382    {
1383       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1384       
1385
1386       //Store probabilties of second LCU in line into buffer
1387#if WPP_SIMPLIFICATION
1388      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1389#else
1390      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro()))
1391#endif
1392      {
1393        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1394      }
1395    }
1396#if !REMOVE_TILE_DEPENDENCE
1397    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1398    {
1399      pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1400       //Store probabilties for next tile
1401      if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1402          (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1403      {
1404        m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1405      }
1406    }
1407#endif
1408
1409#if OL_QTLIMIT_PREDCODING_B0068
1410    rpcPic->setReduceBitsFlag(false);
1411#endif
1412
1413  }
1414
1415#if ADAPTIVE_QP_SELECTION
1416  if( m_pcCfg->getUseAdaptQpSelect() )
1417  {
1418    m_pcTrQuant->storeSliceQpNext(pcSlice);
1419  }
1420#endif
1421#if CABAC_INIT_FLAG
1422  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1423  {
1424    m_pcEntropyCoder->determineCabacInitIdx();
1425  }
1426#endif
1427}
1428
1429/** Determines the starting and bounding LCU address of current slice / entropy slice
1430 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1431 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1432 */
1433Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1434{
1435  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1436  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1437#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1438  UInt tileIdxIncrement;
1439  UInt tileIdx;
1440  UInt tileWidthInLcu;
1441  UInt tileHeightInLcu;
1442  UInt tileTotalCount;
1443#endif
1444
1445  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1446  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1447  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1448  if (bEncodeSlice) 
1449  {
1450    UInt uiCUAddrIncrement;
1451    switch (m_pcCfg->getSliceMode())
1452    {
1453    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1454      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1455      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1456      break;
1457    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1458      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1459      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1460      break;
1461#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1462    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1463      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1464        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1465        );
1466      uiCUAddrIncrement        = 0;
1467      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1468
1469      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1470      {
1471        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1472        {
1473          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1474          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1475          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1476        }
1477      }
1478
1479      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1480      break;
1481#endif
1482    default:
1483      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1484      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1485      break;
1486    } 
1487    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1488  }
1489  else
1490  {
1491    UInt uiCUAddrIncrement     ;
1492    switch (m_pcCfg->getSliceMode())
1493    {
1494    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1495      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1496      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1497      break;
1498#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1499    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1500      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1501        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1502        );
1503      uiCUAddrIncrement        = 0;
1504      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1505
1506      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1507      {
1508        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1509        {
1510          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1511          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1512          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1513        }
1514      }
1515
1516      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1517      break;
1518#endif
1519    default:
1520      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1521      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1522      break;
1523    } 
1524    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1525  }
1526
1527#if COMPLETE_SLICES_IN_TILE
1528  Bool tileBoundary = false;
1529  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) && 
1530      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1531  {
1532    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1533    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1534    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1535    UInt tileBoundingCUAddrSlice = 0;
1536    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1537    {
1538      lcuEncAddr++;
1539      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1540    }
1541    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1542   
1543    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1544    {
1545      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1546      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1547      tileBoundary = true;
1548    }
1549  }
1550#endif
1551
1552  // Entropy slice
1553  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
1554  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
1555  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
1556  if (bEncodeSlice) 
1557  {
1558    UInt uiCUAddrIncrement;
1559    switch (m_pcCfg->getEntropySliceMode())
1560    {
1561    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1562      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1563      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1564      break;
1565    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
1566      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1567      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
1568      break;
1569    default:
1570      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1571      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1572      break;
1573    } 
1574    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1575  }
1576  else
1577  {
1578    UInt uiCUAddrIncrement;
1579    switch (m_pcCfg->getEntropySliceMode())
1580    {
1581    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1582      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1583      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1584      break;
1585    default:
1586      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1587      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1588      break;
1589    } 
1590    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1591  }
1592  if(uiBoundingCUAddrEntropySlice>uiBoundingCUAddrSlice)
1593  {
1594    uiBoundingCUAddrEntropySlice = uiBoundingCUAddrSlice;
1595    pcSlice->setEntropySliceCurEndCUAddr(uiBoundingCUAddrSlice);
1596  }
1597  //calculate real entropy slice start address
1598  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1599  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1600  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1601  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1602  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1603  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1604  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1605  {
1606    uiInternalAddress++;
1607    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1608    {
1609      uiInternalAddress=0;
1610      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1611    }
1612    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1613    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1614  }
1615  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1616 
1617  pcSlice->setEntropySliceCurStartCUAddr(uiRealStartAddress);
1618  uiStartCUAddrEntropySlice=uiRealStartAddress;
1619 
1620  //calculate real slice start address
1621  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1622  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1623  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1624  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1625  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1626  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1627  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1628  {
1629    uiInternalAddress++;
1630    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1631    {
1632      uiInternalAddress=0;
1633      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1634    }
1635    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1636    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1637  }
1638  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1639 
1640  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1641  uiStartCUAddrSlice=uiRealStartAddress;
1642 
1643  // Make a joint decision based on reconstruction and entropy slice bounds
1644  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
1645  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
1646
1647
1648  if (!bEncodeSlice)
1649  {
1650    // 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
1651    // first. Set the flags accordingly.
1652    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1653      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1654      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1655#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1656      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1657      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1658#endif
1659#if COMPLETE_SLICES_IN_TILE
1660      || tileBoundary
1661#endif
1662)
1663    {
1664      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
1665      {
1666        pcSlice->setNextSlice       ( true );
1667        pcSlice->setNextEntropySlice( false );
1668      }
1669      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
1670      {
1671        pcSlice->setNextSlice       ( false );
1672        pcSlice->setNextEntropySlice( true );
1673      }
1674      else
1675      {
1676        pcSlice->setNextSlice       ( true );
1677        pcSlice->setNextEntropySlice( true );
1678      }
1679    }
1680    else
1681    {
1682      pcSlice->setNextSlice       ( false );
1683      pcSlice->setNextEntropySlice( false );
1684    }
1685  }
1686}
1687//! \}
Note: See TracBrowser for help on using the repository browser.