source: 3DVCSoftware/branches/HTM-3.1-LG/source/Lib/TLibEncoder/TEncSlice.cpp @ 97

Last change on this file since 97 was 97, checked in by lg, 12 years ago

Implemented the Region boundary chain coding (A0070) and R/D selection between Non-Zero Residual and All-Zero Residual Intra Coding (A0087) with macro: "LGE_EDGE_INTRA" and "LG_ZEROINTRADEPTHRESI_M26039"

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