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

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