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

Last change on this file since 296 was 296, checked in by tech, 11 years ago

Reintegrated branch 5.1-dev0 rev. 295.

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