source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 100

Last change on this file since 100 was 100, checked in by tech, 13 years ago

Adopted modifications:

  • disparity vector generation (A0097)
  • inter-view motion prediction modification (A0049)
  • simplification of disparity vector derivation (A0126)
  • region boundary chain coding (A0070)
  • residual skip intra (A0087)
  • VSO modification (A0033/A0093)

+ Clean ups + Bug fixes

Update of cfg files (A0033 modification 2)

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