source: 3DVCSoftware/branches/HTM-6.0-Mediatek/source/Lib/TLibEncoder/TEncSlice.cpp @ 303

Last change on this file since 303 was 303, checked in by mediatek-htm, 11 years ago

Added FCO_FIX, FCO_FIX_SPS_CHANGE, and FCO_DVP_REFINE_C0132_C0170 macros to support FCO.
The new macros are default disabled in CTC.

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