source: 3DVCSoftware/branches/HTM-5.1-dev0/source/Lib/TLibEncoder/TEncSlice.cpp @ 292

Last change on this file since 292 was 292, checked in by tech, 11 years ago

Removed macros related to IV motion parameter prediction.

  • Property svn:eol-style set to native
File size: 66.2 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 INTER_VIEW_VECTOR_SCALING_C0115
193  rpcSlice->setViewOrderIdx(m_pcCfg->getViewOrderIdx());    // will be changed to view_id
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 H3D_IVMP
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 || H3D_IVMP )
472  #if ( HHI_MPI && H3D_IVMP )
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 H3D_IVMP
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 H3D_IVMP
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 
779#if !LGE_ILLUCOMP_DEPTH_C0046
780      && !pcEncTop->isDepthCoder() 
781#endif
782      && pcEncTop->getUseIC())   // DCP of ViewID 0 is not available
783  {
784    pcSlice ->xSetApplyIC();
785  }
786#endif
787
788  if( m_pcCfg->getUseSBACRD() )
789  {
790    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
791    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
792    delete[] m_pcBufferSbacCoders;
793    delete[] m_pcBufferBinCoderCABACs;
794    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
795    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
796    for (int ui = 0; ui < uiTilesAcross; ui++)
797    {
798      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
799    }
800    for (UInt ui = 0; ui < uiTilesAcross; ui++)
801    {
802      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
803    }
804
805    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
806    {
807      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
808    }
809  }
810  //if( m_pcCfg->getUseSBACRD() )
811  {
812    delete[] m_pcBufferLowLatSbacCoders;
813    delete[] m_pcBufferLowLatBinCoderCABACs;
814    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
815    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
816    for (int ui = 0; ui < uiTilesAcross; ui++)
817    {
818      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
819    }
820    for (UInt ui = 0; ui < uiTilesAcross; ui++)
821      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
822  }
823
824#if MERL_VSP_C0152
825  // Send Depth/Texture pointers to slice level
826  pcSlice->setBWVSPLUTParam(m_aiShiftLUT, m_iShiftPrec);
827  pcSlice->setRefPicBaseTxt(m_pPicBaseTxt);
828  pcSlice->setRefPicBaseDepth(m_pPicBaseDepth);
829#endif
830
831  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
832  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
833  UInt uiCol=0, uiLin=0, uiSubStrm=0;
834#if !REMOVE_TILE_DEPENDENCE
835  Int  iBreakDep      = 0;
836#endif
837  UInt uiTileCol      = 0;
838  UInt uiTileStartLCU = 0;
839  UInt uiTileLCUX     = 0;
840#if !QC_MVHEVC_B0046
841  Int iLastPosY = -1;
842#endif
843  // for every CU in slice
844  UInt uiEncCUOrder;
845  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
846  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
847       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
848       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
849  {
850    // initialize CU encoder
851    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
852    pcCU->initCU( rpcPic, uiCUAddr );
853#if !QC_MVHEVC_B0046
854    if ( m_pcRdCost->getUseRenModel() )
855    {
856      // updated renderer model if necessary
857      Int iCurPosX;
858      Int iCurPosY; 
859      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
860      if ( iCurPosY != iLastPosY )
861      {
862        iLastPosY = iCurPosY; 
863       
864        m_pcGOPEncoder->getEncTop()->getEncTop()->setupRenModel( rpcPic->getCurrSlice()->getPOC() , rpcPic->getCurrSlice()->getSPS()->getViewId(), rpcPic->getCurrSlice()->getSPS()->isDepth() ? 1 : 0, iCurPosY );
865      }
866    }   
867#endif
868    // inherit from TR if necessary, select substream to use.
869    if( m_pcCfg->getUseSBACRD() )
870    {
871#if !REMOVE_TILE_DEPENDENCE
872      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
873#endif
874      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
875      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
876      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
877      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
878      uiCol     = uiCUAddr % uiWidthInLCUs;
879      uiLin     = uiCUAddr / uiWidthInLCUs;
880#if !REMOVE_TILE_DEPENDENCE
881#if WPP_SIMPLIFICATION
882      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
883#else
884      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
885#endif
886#else
887#if WPP_SIMPLIFICATION
888      if (pcSlice->getPPS()->getNumSubstreams() > 1)
889#else
890      if (pcSlice->getPPS()->getEntropyCodingSynchro())
891#endif
892#endif
893      {
894        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
895        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
896        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
897                      + uiLin%iNumSubstreamsPerTile;
898      }
899      else
900      {
901        // dependent tiles => substreams are "per frame".
902        uiSubStrm = uiLin % iNumSubstreams;
903      }
904#if WPP_SIMPLIFICATION
905      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
906#else
907      if ( pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX) )
908#endif
909      {
910        // We'll sync if the TR is available.
911        TComDataCU *pcCUUp = pcCU->getCUAbove();
912        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
913        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
914        TComDataCU *pcCUTR = NULL;
915#if WPP_SIMPLIFICATION
916        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
917        {
918          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
919        }
920#else
921        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
922        {
923          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
924        }
925#endif
926        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
927             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
928#if !REMOVE_TILE_DEPENDENCE
929             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
930#else
931             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
932#endif
933             )||
934             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
935             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
936#if !REMOVE_TILE_DEPENDENCE
937             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
938#else
939             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
940#endif
941             )
942           )
943        {
944          // TR not available.
945        }
946        else
947        {
948          // TR is available, we use it.
949          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
950        }
951      }
952      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
953    }
954
955    // reset the entropy coder
956    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
957        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
958        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
959    {
960#if CABAC_INIT_FLAG
961      SliceType sliceType = pcSlice->getSliceType();
962      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
963      {
964        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
965      }
966      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
967      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
968      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
969      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
970#else
971      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp(), false );
972      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
973      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp() );
974      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
975#endif
976    }
977#if !REMOVE_TILE_DEPENDENCE
978    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
979    {
980      // Synchronize cabac probabilities with LCU among Tiles
981      if( (uiTileLCUX != 0) &&
982          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
983      { 
984        TComDataCU *pcCULeft = pcCU->getCULeft();
985        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
986
987        if ( (true/*bEnforceSliceRestriction*/ &&
988              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
989               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
990              )
991             )||
992             (true/*bEnforceEntropySliceRestriction*/ &&
993              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
994               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
995              )
996             )
997           )
998        {
999          // Left not available.
1000        }
1001        else
1002        {
1003          // Left is available, we use it.
1004          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
1005          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1006        }
1007      }
1008    }
1009#endif
1010    // if RD based on SBAC is used
1011    if( m_pcCfg->getUseSBACRD() )
1012    {
1013      // set go-on entropy coder
1014      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1015      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1016     
1017      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1018      // run CU encoder
1019      m_pcCuEncoder->compressCU( pcCU );
1020     
1021      // restore entropy coder to an initial stage
1022      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1023      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1024      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1025      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1026      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1027      m_pcBitCounter->resetBits();
1028      pppcRDSbacCoder->setBinsCoded( 0 );
1029      m_pcCuEncoder->encodeCU( pcCU );
1030
1031      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1032      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1033      {
1034        pcSlice->setNextSlice( true );
1035        break;
1036      }
1037      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1038      {
1039        pcSlice->setNextEntropySlice( true );
1040        break;
1041      }
1042      if( m_pcCfg->getUseSBACRD() )
1043      {
1044         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1045       
1046         //Store probabilties of second LCU in line into buffer
1047#if WPP_SIMPLIFICATION
1048        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
1049#else
1050        if (pcSlice->getPPS()->getEntropyCodingSynchro() && uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro())
1051#endif
1052        {
1053          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1054        }
1055      }
1056#if !REMOVE_TILE_DEPENDENCE
1057      if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1058      {
1059         //Store probabilties for next tile
1060        if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1061            (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1062        {
1063          m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1064        }
1065      }
1066#endif
1067    }
1068    // other case: encodeCU is not called
1069    else
1070    {
1071      m_pcCuEncoder->compressCU( pcCU );
1072      m_pcCuEncoder->encodeCU( pcCU );
1073      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1074      {
1075        pcSlice->setNextSlice( true );
1076        break;
1077      }
1078      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1079      {
1080        pcSlice->setNextEntropySlice( true );
1081        break;
1082      }
1083    }
1084   
1085    m_uiPicTotalBits += pcCU->getTotalBits();
1086    m_dPicRdCost     += pcCU->getTotalCost();
1087    m_uiPicDist      += pcCU->getTotalDistortion();
1088  }
1089  xRestoreWPparam( pcSlice );
1090}
1091
1092/**
1093 \param  rpcPic        picture class
1094 \retval rpcBitstream  bitstream class
1095 */
1096Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
1097{
1098  UInt       uiCUAddr;
1099  UInt       uiStartCUAddr;
1100  UInt       uiBoundingCUAddr;
1101  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1102
1103  uiStartCUAddr=pcSlice->getEntropySliceCurStartCUAddr();
1104  uiBoundingCUAddr=pcSlice->getEntropySliceCurEndCUAddr();
1105  // choose entropy coder
1106  {
1107    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1108    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1109  }
1110 
1111  m_pcCuEncoder->setBitCounter( NULL );
1112  m_pcBitCounter = NULL;
1113  // Appropriate substream bitstream is switched later.
1114  // for every CU
1115#if ENC_DEC_TRACE
1116  g_bJustDoIt = g_bEncDecTraceEnable;
1117#endif
1118  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1119  DTRACE_CABAC_T( "\tPOC: " );
1120  DTRACE_CABAC_V( rpcPic->getPOC() );
1121  DTRACE_CABAC_T( "\n" );
1122#if ENC_DEC_TRACE
1123  g_bJustDoIt = g_bEncDecTraceDisable;
1124#endif
1125
1126  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1127  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1128  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1129  UInt uiBitsOriginallyInSubstreams = 0;
1130  {
1131    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1132    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1133    {
1134      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1135    }
1136   
1137    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1138    {
1139      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1140    }
1141
1142    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1143    {
1144      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1145    }
1146  }
1147
1148  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1149  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1150#if !REMOVE_TILE_DEPENDENCE
1151  Int  iBreakDep      = 0;
1152#endif
1153  UInt uiTileCol      = 0;
1154  UInt uiTileStartLCU = 0;
1155  UInt uiTileLCUX     = 0;
1156
1157  UInt uiEncCUOrder;
1158
1159  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1160                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1161                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1162  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1163       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1164       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1165  {
1166    if( m_pcCfg->getUseSBACRD() )
1167    {
1168#if !REMOVE_TILE_DEPENDENCE
1169      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
1170#endif
1171      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1172      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1173      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1174      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1175      uiCol     = uiCUAddr % uiWidthInLCUs;
1176      uiLin     = uiCUAddr / uiWidthInLCUs;
1177#if !REMOVE_TILE_DEPENDENCE
1178#if WPP_SIMPLIFICATION
1179      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
1180#else
1181      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
1182#endif
1183#else
1184#if WPP_SIMPLIFICATION
1185      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1186#else
1187      if (pcSlice->getPPS()->getEntropyCodingSynchro())
1188#endif
1189#endif
1190      {
1191        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1192        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1193        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1194                      + uiLin%iNumSubstreamsPerTile;
1195      }
1196      else
1197      {
1198        // dependent tiles => substreams are "per frame".
1199        uiSubStrm = uiLin % iNumSubstreams;
1200      }
1201
1202      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1203
1204      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1205#if WPP_SIMPLIFICATION
1206      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1207#else
1208      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX))
1209#endif
1210      {
1211        // We'll sync if the TR is available.
1212        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1213        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1214        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1215        TComDataCU *pcCUTR = NULL;
1216#if WPP_SIMPLIFICATION
1217        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1218        {
1219          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1220        }
1221#else
1222        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
1223        {
1224          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
1225        }
1226#endif
1227        if ( (true/*bEnforceSliceRestriction*/ &&
1228             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1229             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1230#if !REMOVE_TILE_DEPENDENCE
1231             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1232#else
1233             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1234#endif
1235             ))||
1236             (true/*bEnforceEntropySliceRestriction*/ &&
1237             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1238             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
1239#if !REMOVE_TILE_DEPENDENCE
1240             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1241#else
1242             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1243#endif
1244             ))
1245           )
1246        {
1247          // TR not available.
1248        }
1249        else
1250        {
1251          // TR is available, we use it.
1252          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1253        }
1254      }
1255      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1256    }
1257    // reset the entropy coder
1258    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1259        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1260        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1261    {
1262      Int iTileIdx            = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr);
1263      Bool bWriteTileMarker   = false;
1264      // check if current iTileIdx should have a marker
1265      for (Int iEntryIdx=0; iEntryIdx<m_pcCfg->getMaxTileMarkerEntryPoints()-1; iEntryIdx++)
1266      {
1267        bWriteTileMarker = ( (((Int)((iEntryIdx+1)*m_pcCfg->getMaxTileMarkerOffset()+0.5)) == iTileIdx ) && iEntryIdx < (m_pcCfg->getMaxTileMarkerEntryPoints()-1)) ? true : false;
1268        if (bWriteTileMarker)
1269        {
1270          break;
1271        }
1272      }
1273      {
1274        // We're crossing into another tile, tiles are independent.
1275        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1276        // have to perform it here.
1277#if WPP_SIMPLIFICATION
1278        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1279#else
1280        if (pcSlice->getPPS()->getEntropyCodingSynchro())
1281#endif
1282        {
1283          ; // do nothing.
1284        }
1285        else
1286        {
1287#if CABAC_INIT_FLAG
1288          SliceType sliceType  = pcSlice->getSliceType();
1289          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
1290          {
1291            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1292          }
1293          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1294#else
1295          m_pcEntropyCoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
1296#endif
1297          pcSubstreams[uiSubStrm].write( 1, 1 );
1298          pcSubstreams[uiSubStrm].writeAlignZero();
1299        }
1300      }
1301      {
1302        // Write TileMarker into the appropriate substream (nothing has been written to it yet).
1303        if (m_pcCfg->getTileMarkerFlag() && bWriteTileMarker)
1304        {
1305          // Log locations where tile markers are to be inserted during emulation prevention
1306          UInt uiMarkerCount = pcSubstreams[uiSubStrm].getTileMarkerLocationCount();
1307          pcSubstreams[uiSubStrm].setTileMarkerLocation     ( uiMarkerCount, pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3 );
1308          pcSubstreams[uiSubStrm].setTileMarkerLocationCount( uiMarkerCount + 1 );
1309          // Write tile index
1310          m_pcEntropyCoder->writeTileMarker(iTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx()); // Tile index
1311        }
1312
1313       
1314        UInt uiAccumulatedSubstreamLength = 0;
1315        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1316        {
1317          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1318        }
1319        UInt uiLocationCount = pcSlice->getTileLocationCount();
1320        // add bits coded in previous entropy slices + bits coded so far
1321        pcSlice->setTileLocation( uiLocationCount, (pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3 ); 
1322        pcSlice->setTileLocationCount( uiLocationCount + 1 );
1323      }
1324    }
1325
1326#if OL_QTLIMIT_PREDCODING_B0068
1327    rpcPic->setReduceBitsFlag(true);
1328#endif
1329
1330    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1331#if !REMOVE_TILE_DEPENDENCE
1332    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1333    {   
1334      // Synchronize cabac probabilities with LCU among Tiles
1335      if( (uiTileLCUX != 0) &&
1336          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
1337      {
1338        TComDataCU *pcCULeft = pcCU->getCULeft();
1339        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1340
1341        if ( (true/*bEnforceSliceRestriction*/ &&
1342              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1343               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
1344              )
1345             )||
1346             (true/*bEnforceEntropySliceRestriction*/ &&
1347              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1348               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
1349              )
1350             )
1351           )
1352        {
1353          // Left not available.
1354        }
1355        else
1356        {
1357          // Left is available, we use it.
1358          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
1359          m_pcSbacCoder->loadContexts(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1360        }
1361      }
1362    }
1363#endif
1364
1365#if SAO_UNIT_INTERLEAVING
1366    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
1367    {
1368      Int iNumCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
1369      Int iCUAddrInSlice    = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU());
1370      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1371      Int rx = uiCUAddr % iNumCuInWidth;
1372      Int ry = uiCUAddr / iNumCuInWidth;
1373      m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
1374    }
1375#endif
1376#if ENC_DEC_TRACE
1377    g_bJustDoIt = g_bEncDecTraceEnable;
1378#endif
1379    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && 
1380      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1381    {
1382      m_pcCuEncoder->encodeCU( pcCU, true );
1383    }
1384    else
1385    {
1386      m_pcCuEncoder->encodeCU( pcCU );
1387    }
1388#if ENC_DEC_TRACE
1389    g_bJustDoIt = g_bEncDecTraceDisable;
1390#endif   
1391    if( m_pcCfg->getUseSBACRD() )
1392    {
1393       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1394       
1395
1396       //Store probabilties of second LCU in line into buffer
1397#if WPP_SIMPLIFICATION
1398      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1399#else
1400      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro()))
1401#endif
1402      {
1403        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1404      }
1405    }
1406#if !REMOVE_TILE_DEPENDENCE
1407    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1408    {
1409      pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1410       //Store probabilties for next tile
1411      if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1412          (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1413      {
1414        m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1415      }
1416    }
1417#endif
1418
1419#if OL_QTLIMIT_PREDCODING_B0068
1420    rpcPic->setReduceBitsFlag(false);
1421#endif
1422
1423  }
1424
1425#if ADAPTIVE_QP_SELECTION
1426  if( m_pcCfg->getUseAdaptQpSelect() )
1427  {
1428    m_pcTrQuant->storeSliceQpNext(pcSlice);
1429  }
1430#endif
1431#if CABAC_INIT_FLAG
1432  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1433  {
1434    m_pcEntropyCoder->determineCabacInitIdx();
1435  }
1436#endif
1437}
1438
1439/** Determines the starting and bounding LCU address of current slice / entropy slice
1440 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1441 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1442 */
1443Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1444{
1445  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1446  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1447#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1448  UInt tileIdxIncrement;
1449  UInt tileIdx;
1450  UInt tileWidthInLcu;
1451  UInt tileHeightInLcu;
1452  UInt tileTotalCount;
1453#endif
1454
1455  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1456  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1457  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1458  if (bEncodeSlice) 
1459  {
1460    UInt uiCUAddrIncrement;
1461    switch (m_pcCfg->getSliceMode())
1462    {
1463    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1464      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1465      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1466      break;
1467    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1468      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1469      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1470      break;
1471#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1472    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1473      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1474        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1475        );
1476      uiCUAddrIncrement        = 0;
1477      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1478
1479      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1480      {
1481        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1482        {
1483          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1484          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1485          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1486        }
1487      }
1488
1489      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1490      break;
1491#endif
1492    default:
1493      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1494      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1495      break;
1496    } 
1497    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1498  }
1499  else
1500  {
1501    UInt uiCUAddrIncrement     ;
1502    switch (m_pcCfg->getSliceMode())
1503    {
1504    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1505      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1506      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1507      break;
1508#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1509    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1510      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1511        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1512        );
1513      uiCUAddrIncrement        = 0;
1514      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1515
1516      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1517      {
1518        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1519        {
1520          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1521          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1522          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1523        }
1524      }
1525
1526      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1527      break;
1528#endif
1529    default:
1530      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1531      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1532      break;
1533    } 
1534    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1535  }
1536
1537#if COMPLETE_SLICES_IN_TILE
1538  Bool tileBoundary = false;
1539  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) && 
1540      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1541  {
1542    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1543    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1544    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1545    UInt tileBoundingCUAddrSlice = 0;
1546    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1547    {
1548      lcuEncAddr++;
1549      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1550    }
1551    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1552   
1553    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1554    {
1555      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1556      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1557      tileBoundary = true;
1558    }
1559  }
1560#endif
1561
1562  // Entropy slice
1563  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
1564  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
1565  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
1566  if (bEncodeSlice) 
1567  {
1568    UInt uiCUAddrIncrement;
1569    switch (m_pcCfg->getEntropySliceMode())
1570    {
1571    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1572      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1573      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1574      break;
1575    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
1576      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1577      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
1578      break;
1579    default:
1580      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1581      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1582      break;
1583    } 
1584    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1585  }
1586  else
1587  {
1588    UInt uiCUAddrIncrement;
1589    switch (m_pcCfg->getEntropySliceMode())
1590    {
1591    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1592      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1593      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1594      break;
1595    default:
1596      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1597      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1598      break;
1599    } 
1600    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1601  }
1602  if(uiBoundingCUAddrEntropySlice>uiBoundingCUAddrSlice)
1603  {
1604    uiBoundingCUAddrEntropySlice = uiBoundingCUAddrSlice;
1605    pcSlice->setEntropySliceCurEndCUAddr(uiBoundingCUAddrSlice);
1606  }
1607  //calculate real entropy slice start address
1608  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1609  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1610  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1611  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1612  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1613  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1614  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1615  {
1616    uiInternalAddress++;
1617    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1618    {
1619      uiInternalAddress=0;
1620      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1621    }
1622    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1623    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1624  }
1625  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1626 
1627  pcSlice->setEntropySliceCurStartCUAddr(uiRealStartAddress);
1628  uiStartCUAddrEntropySlice=uiRealStartAddress;
1629 
1630  //calculate real slice start address
1631  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1632  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1633  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1634  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1635  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1636  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1637  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1638  {
1639    uiInternalAddress++;
1640    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1641    {
1642      uiInternalAddress=0;
1643      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1644    }
1645    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1646    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1647  }
1648  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1649 
1650  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1651  uiStartCUAddrSlice=uiRealStartAddress;
1652 
1653  // Make a joint decision based on reconstruction and entropy slice bounds
1654  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
1655  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
1656
1657
1658  if (!bEncodeSlice)
1659  {
1660    // 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
1661    // first. Set the flags accordingly.
1662    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1663      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1664      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1665#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1666      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1667      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1668#endif
1669#if COMPLETE_SLICES_IN_TILE
1670      || tileBoundary
1671#endif
1672)
1673    {
1674      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
1675      {
1676        pcSlice->setNextSlice       ( true );
1677        pcSlice->setNextEntropySlice( false );
1678      }
1679      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
1680      {
1681        pcSlice->setNextSlice       ( false );
1682        pcSlice->setNextEntropySlice( true );
1683      }
1684      else
1685      {
1686        pcSlice->setNextSlice       ( true );
1687        pcSlice->setNextEntropySlice( true );
1688      }
1689    }
1690    else
1691    {
1692      pcSlice->setNextSlice       ( false );
1693      pcSlice->setNextEntropySlice( false );
1694    }
1695  }
1696}
1697//! \}
Note: See TracBrowser for help on using the repository browser.