source: 3DVCSoftware/branches/HTM-5.1-dev1-Hisilicon/source/Lib/TLibEncoder/TEncSlice.cpp @ 236

Last change on this file since 236 was 210, checked in by tech, 12 years ago

Reintegrated /branches/HTM-5.0-dev0 rev. 207.

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