source: 3DVCSoftware/branches/HTM-4.0-Orange/source/Lib/TLibEncoder/TEncSlice.cpp @ 142

Last change on this file since 142 was 117, checked in by tech, 12 years ago

Cleanup

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