source: 3DVCSoftware/branches/HTM-6.2-dev1-Sharp/source/Lib/TLibEncoder/TEncSlice.cpp @ 374

Last change on this file since 374 was 374, checked in by sharpjp-htm, 12 years ago

D0060: Removal of IC's parsing dependency

  • Property svn:eol-style set to native
File size: 59.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#if FIX_LGE_WP_FOR_3D_C0223
680  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc());
681
682  if ( bWp_explicit )
683  {
684    //------------------------------------------------------------------------------
685    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
686    //------------------------------------------------------------------------------
687    if ( pcSlice->getSliceMode()==2 || pcSlice->getEntropySliceMode()==2 )
688    {
689      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
690    }
691    xEstimateWPParamSlice( pcSlice );
692    pcSlice->initWpScaling();
693#if !FIX_LGE_WP_FOR_3D_C0223 // Interim fix for encoder/decoder mismatch of non-fade sequence
694    // check WP on/off
695    xCheckWPEnable( pcSlice );
696#endif
697  }
698#else
699
700  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==1);
701  Bool bWp_implicit = (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==2);
702
703  if ( bWp_explicit || bWp_implicit )
704  {
705    //------------------------------------------------------------------------------
706    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
707    //------------------------------------------------------------------------------
708    if ( pcSlice->getSliceMode()==2 || pcSlice->getEntropySliceMode()==2 )
709    {
710      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
711    }
712
713    if( bWp_explicit )
714    {
715      xEstimateWPParamSlice( pcSlice );
716    }
717   
718    pcSlice->initWpScaling();
719
720    // check WP on/off
721    if( bWp_explicit )
722    {
723      xCheckWPEnable( pcSlice );
724    }
725  }
726#endif
727#if ADAPTIVE_QP_SELECTION
728  if( m_pcCfg->getUseAdaptQpSelect() )
729  {
730    m_pcTrQuant->clearSliceARLCnt();
731    if(pcSlice->getSliceType()!=I_SLICE)
732    {
733      Int qpBase = pcSlice->getSliceQpBase();
734      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
735    }
736  }
737#endif
738  // initialize ALF parameters
739  m_pcEntropyCoder->setAlfCtrl(false);
740  m_pcEntropyCoder->setMaxAlfCtrlDepth(0); //unnecessary
741 
742#if SAIT_VSO_EST_A0033
743 if( m_pcCfg->getUseVSO() )
744 {
745
746   Int frameWidth = m_pcCfg->getSourceWidth();
747   Pel* pVideoRec = m_pcRdCost->getVideoRecPicYuv()->getLumaAddr();
748   Int iVideoRecStride = m_pcRdCost->getVideoRecPicYuv()->getStride();
749
750   Pel* pDepthOrg = m_pcRdCost->getDepthPicYuv()->getLumaAddr();
751   Int iDepthOrgStride = m_pcRdCost->getDepthPicYuv()->getStride();
752
753   for( Int y = 0 ; y < m_pcCfg->getSourceHeight() ; y++ )
754   {
755     pVideoRec[-1] = pVideoRec[0];
756     pVideoRec[frameWidth] = pVideoRec[frameWidth-1];
757     pDepthOrg[-1] = pDepthOrg[0];
758     pDepthOrg[frameWidth] = pDepthOrg[frameWidth-1];
759
760     pVideoRec += iVideoRecStride;
761     pDepthOrg += iDepthOrgStride;
762   }
763 }
764#endif
765
766  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
767  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
768  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
769  Int  iNumSubstreams = 1;
770  UInt uiTilesAcross  = 0;
771
772#if LGE_ILLUCOMP_B0045
773  if (pcEncTop->getViewId() != 0 
774#if !LGE_ILLUCOMP_DEPTH_C0046
775      && !pcEncTop->isDepthCoder() 
776#endif
777      && pcEncTop->getUseIC())   // DCP of ViewID 0 is not available
778  {
779    pcSlice ->xSetApplyIC();
780#if SHARP_ILLUCOMP_PARSE_D0060
781    if (pcSlice->getApplyIC())
782    {
783      pcSlice->setIcSkipParseFlag(rpcPic->getCurrSlice()->getPOC() % m_pcCfg->getIntraPeriod() != 0);
784    }
785#endif
786  }
787#endif
788
789  if( m_pcCfg->getUseSBACRD() )
790  {
791    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
792    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
793    delete[] m_pcBufferSbacCoders;
794    delete[] m_pcBufferBinCoderCABACs;
795    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
796    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
797    for (int ui = 0; ui < uiTilesAcross; ui++)
798    {
799      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
800    }
801    for (UInt ui = 0; ui < uiTilesAcross; ui++)
802    {
803      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
804    }
805
806    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
807    {
808      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
809    }
810  }
811  //if( m_pcCfg->getUseSBACRD() )
812  {
813    delete[] m_pcBufferLowLatSbacCoders;
814    delete[] m_pcBufferLowLatBinCoderCABACs;
815    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
816    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
817    for (int ui = 0; ui < uiTilesAcross; ui++)
818    {
819      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
820    }
821    for (UInt ui = 0; ui < uiTilesAcross; ui++)
822      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
823  }
824
825#if MERL_VSP_C0152
826  // Send Depth/Texture pointers to slice level
827  pcSlice->setBWVSPLUTParam(m_aiShiftLUT, m_iShiftPrec);
828  pcSlice->setRefPicBaseTxt(m_pPicBaseTxt);
829  pcSlice->setRefPicBaseDepth(m_pPicBaseDepth);
830#endif
831
832  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
833  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
834  UInt uiCol=0, uiLin=0, uiSubStrm=0;
835  UInt uiTileCol      = 0;
836  UInt uiTileStartLCU = 0;
837  UInt uiTileLCUX     = 0;
838#if !QC_MVHEVC_B0046
839  Int iLastPosY = -1;
840#endif
841  // for every CU in slice
842  UInt uiEncCUOrder;
843  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
844  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
845       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
846       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
847  {
848    // initialize CU encoder
849    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
850    pcCU->initCU( rpcPic, uiCUAddr );
851#if !QC_MVHEVC_B0046
852    if ( m_pcRdCost->getUseRenModel() )
853    {
854      // updated renderer model if necessary
855      Int iCurPosX;
856      Int iCurPosY; 
857      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
858      if ( iCurPosY != iLastPosY )
859      {
860        iLastPosY = iCurPosY; 
861       
862        m_pcGOPEncoder->getEncTop()->getEncTop()->setupRenModel( rpcPic->getCurrSlice()->getPOC() , rpcPic->getCurrSlice()->getSPS()->getViewId(), rpcPic->getCurrSlice()->getSPS()->isDepth() ? 1 : 0, iCurPosY );
863      }
864    }   
865#endif
866    // inherit from TR if necessary, select substream to use.
867    if( m_pcCfg->getUseSBACRD() )
868    {
869      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
870      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
871      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
872      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
873      uiCol     = uiCUAddr % uiWidthInLCUs;
874      uiLin     = uiCUAddr / uiWidthInLCUs;
875      if (pcSlice->getPPS()->getNumSubstreams() > 1)
876      {
877        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
878        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
879        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
880                      + uiLin%iNumSubstreamsPerTile;
881      }
882      else
883      {
884        // dependent tiles => substreams are "per frame".
885        uiSubStrm = uiLin % iNumSubstreams;
886      }
887      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
888      {
889        // We'll sync if the TR is available.
890        TComDataCU *pcCUUp = pcCU->getCUAbove();
891        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
892        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
893        TComDataCU *pcCUTR = NULL;
894        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
895        {
896          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
897        }
898        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
899             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
900             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
901             )||
902             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
903             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
904             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
905             )
906           )
907        {
908          // TR not available.
909        }
910        else
911        {
912          // TR is available, we use it.
913          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
914        }
915      }
916      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
917    }
918
919    // reset the entropy coder
920    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
921        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
922        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
923    {
924#if CABAC_INIT_FLAG
925      SliceType sliceType = pcSlice->getSliceType();
926      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
927      {
928        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
929      }
930      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
931      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
932      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
933      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
934#else
935      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp(), false );
936      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
937      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp() );
938      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
939#endif
940    }
941    // if RD based on SBAC is used
942    if( m_pcCfg->getUseSBACRD() )
943    {
944      // set go-on entropy coder
945      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
946      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
947     
948      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
949      // run CU encoder
950      m_pcCuEncoder->compressCU( pcCU );
951     
952      // restore entropy coder to an initial stage
953      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
954      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
955      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
956      m_pcBitCounter = &pcBitCounters[uiSubStrm];
957      pppcRDSbacCoder->setBinCountingEnableFlag( true );
958      m_pcBitCounter->resetBits();
959      pppcRDSbacCoder->setBinsCoded( 0 );
960      m_pcCuEncoder->encodeCU( pcCU );
961
962      pppcRDSbacCoder->setBinCountingEnableFlag( false );
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()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
969      {
970        pcSlice->setNextEntropySlice( true );
971        break;
972      }
973      if( m_pcCfg->getUseSBACRD() )
974      {
975         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
976       
977         //Store probabilties of second LCU in line into buffer
978        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
979        {
980          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
981        }
982      }
983    }
984    // other case: encodeCU is not called
985    else
986    {
987      m_pcCuEncoder->compressCU( pcCU );
988      m_pcCuEncoder->encodeCU( pcCU );
989      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
990      {
991        pcSlice->setNextSlice( true );
992        break;
993      }
994      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
995      {
996        pcSlice->setNextEntropySlice( true );
997        break;
998      }
999    }
1000   
1001    m_uiPicTotalBits += pcCU->getTotalBits();
1002    m_dPicRdCost     += pcCU->getTotalCost();
1003    m_uiPicDist      += pcCU->getTotalDistortion();
1004  }
1005  xRestoreWPparam( pcSlice );
1006}
1007
1008/**
1009 \param  rpcPic        picture class
1010 \retval rpcBitstream  bitstream class
1011 */
1012Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
1013{
1014  UInt       uiCUAddr;
1015  UInt       uiStartCUAddr;
1016  UInt       uiBoundingCUAddr;
1017  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1018
1019  uiStartCUAddr=pcSlice->getEntropySliceCurStartCUAddr();
1020  uiBoundingCUAddr=pcSlice->getEntropySliceCurEndCUAddr();
1021  // choose entropy coder
1022  {
1023    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1024    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1025  }
1026 
1027  m_pcCuEncoder->setBitCounter( NULL );
1028  m_pcBitCounter = NULL;
1029  // Appropriate substream bitstream is switched later.
1030  // for every CU
1031#if ENC_DEC_TRACE
1032  g_bJustDoIt = g_bEncDecTraceEnable;
1033#endif
1034  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1035  DTRACE_CABAC_T( "\tPOC: " );
1036  DTRACE_CABAC_V( rpcPic->getPOC() );
1037  DTRACE_CABAC_T( "\n" );
1038#if ENC_DEC_TRACE
1039  g_bJustDoIt = g_bEncDecTraceDisable;
1040#endif
1041
1042  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1043  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1044  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1045  UInt uiBitsOriginallyInSubstreams = 0;
1046  {
1047    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1048    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1049    {
1050      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1051    }
1052   
1053    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1054    {
1055      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1056    }
1057
1058    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1059    {
1060      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1061    }
1062  }
1063
1064  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1065  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1066  UInt uiTileCol      = 0;
1067  UInt uiTileStartLCU = 0;
1068  UInt uiTileLCUX     = 0;
1069
1070  UInt uiEncCUOrder;
1071
1072  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1073                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1074                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1075  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1076       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1077       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1078  {
1079    if( m_pcCfg->getUseSBACRD() )
1080    {
1081      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1082      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1083      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1084      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1085      uiCol     = uiCUAddr % uiWidthInLCUs;
1086      uiLin     = uiCUAddr / uiWidthInLCUs;
1087      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1088      {
1089        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1090        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1091        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1092                      + uiLin%iNumSubstreamsPerTile;
1093      }
1094      else
1095      {
1096        // dependent tiles => substreams are "per frame".
1097        uiSubStrm = uiLin % iNumSubstreams;
1098      }
1099
1100      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1101
1102      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1103      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1104      {
1105        // We'll sync if the TR is available.
1106        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1107        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1108        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1109        TComDataCU *pcCUTR = NULL;
1110        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1111        {
1112          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1113        }
1114        if ( (true/*bEnforceSliceRestriction*/ &&
1115             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1116             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1117             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1118             ))||
1119             (true/*bEnforceEntropySliceRestriction*/ &&
1120             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1121             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
1122             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1123             ))
1124           )
1125        {
1126          // TR not available.
1127        }
1128        else
1129        {
1130          // TR is available, we use it.
1131          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1132        }
1133      }
1134      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1135    }
1136    // reset the entropy coder
1137    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1138        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1139        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1140    {
1141      Int iTileIdx            = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr);
1142      Bool bWriteTileMarker   = false;
1143      // check if current iTileIdx should have a marker
1144      for (Int iEntryIdx=0; iEntryIdx<m_pcCfg->getMaxTileMarkerEntryPoints()-1; iEntryIdx++)
1145      {
1146        bWriteTileMarker = ( (((Int)((iEntryIdx+1)*m_pcCfg->getMaxTileMarkerOffset()+0.5)) == iTileIdx ) && iEntryIdx < (m_pcCfg->getMaxTileMarkerEntryPoints()-1)) ? true : false;
1147        if (bWriteTileMarker)
1148        {
1149          break;
1150        }
1151      }
1152      {
1153        // We're crossing into another tile, tiles are independent.
1154        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1155        // have to perform it here.
1156        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1157        {
1158          ; // do nothing.
1159        }
1160        else
1161        {
1162#if CABAC_INIT_FLAG
1163          SliceType sliceType  = pcSlice->getSliceType();
1164          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
1165          {
1166            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1167          }
1168          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1169#else
1170          m_pcEntropyCoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
1171#endif
1172          pcSubstreams[uiSubStrm].write( 1, 1 );
1173          pcSubstreams[uiSubStrm].writeAlignZero();
1174        }
1175      }
1176      {
1177        // Write TileMarker into the appropriate substream (nothing has been written to it yet).
1178        if (m_pcCfg->getTileMarkerFlag() && bWriteTileMarker)
1179        {
1180          // Log locations where tile markers are to be inserted during emulation prevention
1181          UInt uiMarkerCount = pcSubstreams[uiSubStrm].getTileMarkerLocationCount();
1182          pcSubstreams[uiSubStrm].setTileMarkerLocation     ( uiMarkerCount, pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3 );
1183          pcSubstreams[uiSubStrm].setTileMarkerLocationCount( uiMarkerCount + 1 );
1184          // Write tile index
1185          m_pcEntropyCoder->writeTileMarker(iTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx()); // Tile index
1186        }
1187
1188       
1189        UInt uiAccumulatedSubstreamLength = 0;
1190        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1191        {
1192          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1193        }
1194        UInt uiLocationCount = pcSlice->getTileLocationCount();
1195        // add bits coded in previous entropy slices + bits coded so far
1196        pcSlice->setTileLocation( uiLocationCount, (pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3 ); 
1197        pcSlice->setTileLocationCount( uiLocationCount + 1 );
1198      }
1199    }
1200
1201#if H3D_QTL
1202    rpcPic->setReduceBitsFlag(true);
1203#endif
1204
1205    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1206
1207    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
1208    {
1209      Int iNumCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
1210      Int iCUAddrInSlice    = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU());
1211      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1212      Int rx = uiCUAddr % iNumCuInWidth;
1213      Int ry = uiCUAddr / iNumCuInWidth;
1214      m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
1215    }
1216#if ENC_DEC_TRACE
1217    g_bJustDoIt = g_bEncDecTraceEnable;
1218#endif
1219    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && 
1220      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1221    {
1222      m_pcCuEncoder->encodeCU( pcCU, true );
1223    }
1224    else
1225    {
1226      m_pcCuEncoder->encodeCU( pcCU );
1227    }
1228#if ENC_DEC_TRACE
1229    g_bJustDoIt = g_bEncDecTraceDisable;
1230#endif   
1231    if( m_pcCfg->getUseSBACRD() )
1232    {
1233       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1234       
1235
1236       //Store probabilties of second LCU in line into buffer
1237      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1238      {
1239        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1240      }
1241    }
1242
1243#if H3D_QTL
1244    rpcPic->setReduceBitsFlag(false);
1245#endif
1246
1247  }
1248
1249#if ADAPTIVE_QP_SELECTION
1250  if( m_pcCfg->getUseAdaptQpSelect() )
1251  {
1252    m_pcTrQuant->storeSliceQpNext(pcSlice);
1253  }
1254#endif
1255#if CABAC_INIT_FLAG
1256  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1257  {
1258    m_pcEntropyCoder->determineCabacInitIdx();
1259  }
1260#endif
1261}
1262
1263/** Determines the starting and bounding LCU address of current slice / entropy slice
1264 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1265 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1266 */
1267Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1268{
1269  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1270  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1271  UInt tileIdxIncrement;
1272  UInt tileIdx;
1273  UInt tileWidthInLcu;
1274  UInt tileHeightInLcu;
1275  UInt tileTotalCount;
1276
1277  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1278  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1279  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1280  if (bEncodeSlice) 
1281  {
1282    UInt uiCUAddrIncrement;
1283    switch (m_pcCfg->getSliceMode())
1284    {
1285    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1286      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1287      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1288      break;
1289    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1290      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1291      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1292      break;
1293    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1294      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1295        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1296        );
1297      uiCUAddrIncrement        = 0;
1298      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1299
1300      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1301      {
1302        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1303        {
1304          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1305          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1306          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1307        }
1308      }
1309
1310      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1311      break;
1312    default:
1313      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1314      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1315      break;
1316    } 
1317    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1318  }
1319  else
1320  {
1321    UInt uiCUAddrIncrement     ;
1322    switch (m_pcCfg->getSliceMode())
1323    {
1324    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1325      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1326      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1327      break;
1328    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1329      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1330        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1331        );
1332      uiCUAddrIncrement        = 0;
1333      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1334
1335      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1336      {
1337        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1338        {
1339          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1340          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1341          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1342        }
1343      }
1344
1345      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1346      break;
1347    default:
1348      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1349      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1350      break;
1351    } 
1352    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1353  }
1354
1355  Bool tileBoundary = false;
1356  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) && 
1357      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1358  {
1359    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1360    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1361    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1362    UInt tileBoundingCUAddrSlice = 0;
1363    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1364    {
1365      lcuEncAddr++;
1366      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1367    }
1368    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1369   
1370    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1371    {
1372      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1373      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1374      tileBoundary = true;
1375    }
1376  }
1377
1378  // Entropy slice
1379  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
1380  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
1381  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
1382  if (bEncodeSlice) 
1383  {
1384    UInt uiCUAddrIncrement;
1385    switch (m_pcCfg->getEntropySliceMode())
1386    {
1387    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1388      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1389      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1390      break;
1391    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
1392      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1393      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
1394      break;
1395    default:
1396      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1397      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1398      break;
1399    } 
1400    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1401  }
1402  else
1403  {
1404    UInt uiCUAddrIncrement;
1405    switch (m_pcCfg->getEntropySliceMode())
1406    {
1407    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1408      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1409      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1410      break;
1411    default:
1412      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1413      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1414      break;
1415    } 
1416    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1417  }
1418  if(uiBoundingCUAddrEntropySlice>uiBoundingCUAddrSlice)
1419  {
1420    uiBoundingCUAddrEntropySlice = uiBoundingCUAddrSlice;
1421    pcSlice->setEntropySliceCurEndCUAddr(uiBoundingCUAddrSlice);
1422  }
1423  //calculate real entropy slice start address
1424  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1425  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1426  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1427  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1428  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1429  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1430  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1431  {
1432    uiInternalAddress++;
1433    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1434    {
1435      uiInternalAddress=0;
1436      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1437    }
1438    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1439    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1440  }
1441  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1442 
1443  pcSlice->setEntropySliceCurStartCUAddr(uiRealStartAddress);
1444  uiStartCUAddrEntropySlice=uiRealStartAddress;
1445 
1446  //calculate real slice start address
1447  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1448  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1449  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1450  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1451  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1452  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1453  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1454  {
1455    uiInternalAddress++;
1456    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1457    {
1458      uiInternalAddress=0;
1459      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1460    }
1461    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1462    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1463  }
1464  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1465 
1466  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1467  uiStartCUAddrSlice=uiRealStartAddress;
1468 
1469  // Make a joint decision based on reconstruction and entropy slice bounds
1470  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
1471  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
1472
1473
1474  if (!bEncodeSlice)
1475  {
1476    // 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
1477    // first. Set the flags accordingly.
1478    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1479      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1480      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1481      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1482      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1483      || tileBoundary
1484)
1485    {
1486      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
1487      {
1488        pcSlice->setNextSlice       ( true );
1489        pcSlice->setNextEntropySlice( false );
1490      }
1491      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
1492      {
1493        pcSlice->setNextSlice       ( false );
1494        pcSlice->setNextEntropySlice( true );
1495      }
1496      else
1497      {
1498        pcSlice->setNextSlice       ( true );
1499        pcSlice->setNextEntropySlice( true );
1500      }
1501    }
1502    else
1503    {
1504      pcSlice->setNextSlice       ( false );
1505      pcSlice->setNextEntropySlice( false );
1506    }
1507  }
1508}
1509//! \}
Note: See TracBrowser for help on using the repository browser.