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

Last change on this file since 56 was 56, checked in by hschwarz, 12 years ago

updated trunk (move to HM6.1)

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