source: 3DVCSoftware/branches/HTM-5.1-dev2-Mediatek/source/Lib/TLibEncoder/TEncSlice.cpp @ 852

Last change on this file since 852 was 254, checked in by mediatek-htm, 12 years ago

Integration of JCT3V-C0137

The added texture merging candidate is controlled by the MACRO "MTK_DEPTH_MERGE_TEXTURE_CANDIDATE_C0137"

From MediaTek
yiwen.chen@…

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