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

Last change on this file since 81 was 77, checked in by tech, 12 years ago

Merged with branch/HTM-3.0Samsung REV74 including:

  • restricted residual prediction m24766
  • Inter-view residual prediction m24938
  • VPS concept m24714,m24878, m24945,m24896, m2491
  • reference list modification, restriction on IDR m24876, m24874
  • depth based motion parameter prediction m24829

Fixed bugs:

  • interview prediction
  • VSO

Added:

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