source: 3DVCSoftware/branches/HTM-4.0-Nokia/source/Lib/TLibEncoder/TEncSlice.cpp @ 449

Last change on this file since 449 was 139, checked in by nokia, 12 years ago

3DV-HTM v4.0: FCO

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