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

Last change on this file since 1156 was 1133, checked in by tech, 10 years ago

Merged 13.0-dev0@1132

  • Cleanup
  • TICKET083_IVPFLAG_FIX
  • Property svn:eol-style set to native
File size: 75.7 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-2014, 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 <math.h>
41
42//! \ingroup TLibEncoder
43//! \{
44
45// ====================================================================================================================
46// Constructor / destructor / create / destroy
47// ====================================================================================================================
48
49TEncSlice::TEncSlice()
50{
51  m_apcPicYuvPred = NULL;
52  m_apcPicYuvResi = NULL;
53 
54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57  m_pcBufferSbacCoders    = NULL;
58  m_pcBufferBinCoderCABACs  = NULL;
59  m_pcBufferLowLatSbacCoders    = NULL;
60  m_pcBufferLowLatBinCoderCABACs  = NULL;
61}
62
63TEncSlice::~TEncSlice()
64{
65  for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
66  {
67    delete (*i);
68  }
69}
70
71Void TEncSlice::initCtxMem(  UInt i )               
72{   
73  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
74  {
75    delete (*j);
76  }
77  CTXMem.clear(); 
78  CTXMem.resize(i); 
79}
80
81Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
82{
83  // create prediction picture
84  if ( m_apcPicYuvPred == NULL )
85  {
86    m_apcPicYuvPred  = new TComPicYuv;
87    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
88  }
89 
90  // create residual picture
91  if( m_apcPicYuvResi == NULL )
92  {
93    m_apcPicYuvResi  = new TComPicYuv;
94    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
95  }
96}
97
98Void TEncSlice::destroy()
99{
100  // destroy prediction picture
101  if ( m_apcPicYuvPred )
102  {
103    m_apcPicYuvPred->destroy();
104    delete m_apcPicYuvPred;
105    m_apcPicYuvPred  = NULL;
106  }
107 
108  // destroy residual picture
109  if ( m_apcPicYuvResi )
110  {
111    m_apcPicYuvResi->destroy();
112    delete m_apcPicYuvResi;
113    m_apcPicYuvResi  = NULL;
114  }
115 
116  // free lambda and QP arrays
117  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
118  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
119  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
120
121  if ( m_pcBufferSbacCoders )
122  {
123    delete[] m_pcBufferSbacCoders;
124  }
125  if ( m_pcBufferBinCoderCABACs )
126  {
127    delete[] m_pcBufferBinCoderCABACs;
128  }
129  if ( m_pcBufferLowLatSbacCoders )
130    delete[] m_pcBufferLowLatSbacCoders;
131  if ( m_pcBufferLowLatBinCoderCABACs )
132    delete[] m_pcBufferLowLatBinCoderCABACs;
133}
134
135Void TEncSlice::init( TEncTop* pcEncTop )
136{
137  m_pcCfg             = pcEncTop;
138  m_pcListPic         = pcEncTop->getListPic();
139 
140  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
141  m_pcCuEncoder       = pcEncTop->getCuEncoder();
142  m_pcPredSearch      = pcEncTop->getPredSearch();
143 
144  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
145  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
146  m_pcSbacCoder       = pcEncTop->getSbacCoder();
147  m_pcBinCABAC        = pcEncTop->getBinCABAC();
148  m_pcTrQuant         = pcEncTop->getTrQuant();
149 
150  m_pcBitCounter      = pcEncTop->getBitCounter();
151  m_pcRdCost          = pcEncTop->getRdCost();
152  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
153  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
154 
155  // create lambda and QP arrays
156  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
157  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
158  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
159#if KWU_RC_MADPRED_E0227
160  if(m_pcCfg->getUseRateCtrl())
161  {
162    m_pcRateCtrl        = pcEncTop->getRateCtrl();
163  }
164  else
165  {
166    m_pcRateCtrl        = NULL;
167  }
168#else
169  m_pcRateCtrl        = pcEncTop->getRateCtrl();
170#endif
171}
172
173/**
174 - non-referenced frame marking
175 - QP computation based on temporal structure
176 - lambda computation based on QP
177 - set temporal layer ID and the parameter sets
178 .
179 \param pcPic         picture class
180 \param pocLast       POC of last picture
181 \param pocCurr       current POC
182 \param iNumPicRcvd   number of received pictures
183 \param iTimeOffset   POC offset for hierarchical structure
184 \param iDepth        temporal layer depth
185 \param rpcSlice      slice header class
186 \param pSPS          SPS associated with the slice
187 \param pPPS          PPS associated with the slice
188 */
189#if H_MV
190Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, TComSPS* pSPS, TComPPS *pPPS, Int layerId, bool isField )
191#else
192Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, bool isField )
193#endif
194{
195  Double dQP;
196  Double dLambda;
197 
198  rpcSlice = pcPic->getSlice(0);
199
200#if H_MV
201  rpcSlice->setVPS( pVPS ); 
202
203  rpcSlice->setLayerId     ( layerId );
204  rpcSlice->setViewId      ( pVPS->getViewId      ( layerId ) );   
205  rpcSlice->setViewIndex   ( pVPS->getViewIndex   ( layerId ) );
206#if H_3D
207  rpcSlice->setIsDepth     ( pVPS->getDepthId     ( layerId ) != 0 );   
208#endif
209#endif
210  rpcSlice->setSPS( pSPS );
211  rpcSlice->setPPS( pPPS );
212  rpcSlice->setSliceBits(0);
213  rpcSlice->setPic( pcPic );
214  rpcSlice->initSlice();
215  rpcSlice->setPicOutputFlag( true );
216  rpcSlice->setPOC( pocCurr );
217#if H_3D
218  rpcSlice->init3dToolParameters(); 
219#endif
220#if H_3D_IC
221  rpcSlice->setApplyIC( false );
222#endif
223  // depth computation based on GOP size
224  Int depth;
225  {
226#if FIX_FIELD_DEPTH   
227    Int poc = rpcSlice->getPOC();
228    if(isField)
229    {
230      poc = (poc/2)%(m_pcCfg->getGOPSize()/2);
231    }
232    else
233    {
234      poc = poc%m_pcCfg->getGOPSize();   
235    }
236#else
237    Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
238#endif
239    if ( poc == 0 )
240    {
241      depth = 0;
242    }
243    else
244    {
245      Int step = m_pcCfg->getGOPSize();
246      depth    = 0;
247      for( Int i=step>>1; i>=1; i>>=1 )
248      {
249        for ( Int j=i; j<m_pcCfg->getGOPSize(); j+=step )
250        {
251          if ( j == poc )
252          {
253            i=0;
254            break;
255          }
256        }
257        step >>= 1;
258        depth++;
259      }
260    }
261#if FIX_FIELD_DEPTH 
262#if HARMONIZE_GOP_FIRST_FIELD_COUPLE
263    if(poc != 0)
264    {
265#endif
266    if(isField && rpcSlice->getPOC()%2 == 1)
267    {
268      depth ++;
269    }
270#if HARMONIZE_GOP_FIRST_FIELD_COUPLE
271  }
272#endif
273#endif
274  }
275 
276  // slice type
277#if H_MV
278  SliceType eSliceTypeBaseView;
279  if( pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0 )
280  {
281    eSliceTypeBaseView = I_SLICE;
282  }
283  else
284  {
285    eSliceTypeBaseView = B_SLICE;
286  }
287  SliceType eSliceType = eSliceTypeBaseView;
288  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
289  {
290    eSliceType = B_SLICE; 
291  }
292#else
293  SliceType eSliceType;
294 
295  eSliceType=B_SLICE;
296#if EFFICIENT_FIELD_IRAP
297  if(!(isField && pocLast == 1))
298  {
299#endif // EFFICIENT_FIELD_IRAP
300#if ALLOW_RECOVERY_POINT_AS_RAP
301  if(m_pcCfg->getDecodingRefreshType() == 3)
302  {
303    eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0             || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
304  }
305  else
306  {
307    eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
308  }
309#else
310  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
311#endif
312#if EFFICIENT_FIELD_IRAP
313  }
314#endif
315#endif
316 
317  rpcSlice->setSliceType    ( eSliceType );
318
319  // ------------------------------------------------------------------------------------------------------------------
320  // Non-referenced frame marking
321  // ------------------------------------------------------------------------------------------------------------------
322 
323  if(pocLast == 0)
324  {
325    rpcSlice->setTemporalLayerNonReferenceFlag(false);
326  }
327  else
328  {
329#if 0 // Check this! H_MV
330    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_refPic);
331#else
332    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
333#endif
334  }
335  rpcSlice->setReferenced(true);
336 
337  // ------------------------------------------------------------------------------------------------------------------
338  // QP setting
339  // ------------------------------------------------------------------------------------------------------------------
340 
341  dQP = m_pcCfg->getQP();
342  if(eSliceType!=I_SLICE)
343  {
344    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
345    {
346#if H_MV
347      dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset;
348#else
349      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
350#endif
351    }
352  }
353 
354  // modify QP
355  Int* pdQPs = m_pcCfg->getdQPs();
356  if ( pdQPs )
357  {
358    dQP += pdQPs[ rpcSlice->getPOC() ];
359  }
360  // ------------------------------------------------------------------------------------------------------------------
361  // Lambda computation
362  // ------------------------------------------------------------------------------------------------------------------
363 
364  Int iQP;
365  Double dOrigQP = dQP;
366
367  // pre-compute lambda and QP values for all possible QP candidates
368  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
369  {
370    // compute QP value
371    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
372   
373    // compute lambda value
374    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
375    Int    SHIFT_QP = 12;
376    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
377#if FULL_NBIT
378    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
379#else
380    Int    bitdepth_luma_qp_scale = 0;
381#endif
382    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
383#if FULL_NBIT
384    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
385#endif
386    // Case #1: I or P-slices (key-frame)
387#if H_MV
388    Double dQPFactor;
389    if( eSliceType != I_SLICE ) 
390    {
391      dQPFactor = m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPFactor;
392    }
393    else
394#else
395    Double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
396    if ( eSliceType==I_SLICE )
397#endif
398    {
399      dQPFactor=0.57*dLambda_scale;
400    }
401    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
402
403    if ( depth>0 )
404    {
405#if FULL_NBIT
406        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
407#else
408        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
409#endif
410    }
411   
412    // if hadamard is used in ME process
413    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
414    {
415      dLambda *= 0.95;
416    }
417   
418    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
419
420    m_pdRdPicLambda[iDQpIdx] = dLambda;
421    m_pdRdPicQp    [iDQpIdx] = dQP;
422    m_piRdPicQp    [iDQpIdx] = iQP;
423  }
424 
425  // obtain dQP = 0 case
426  dLambda = m_pdRdPicLambda[0];
427  dQP     = m_pdRdPicQp    [0];
428  iQP     = m_piRdPicQp    [0];
429 
430  if( rpcSlice->getSliceType( ) != I_SLICE )
431  {
432#if H_MV
433    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_temporalId );
434#else
435    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
436#endif
437  }
438
439  // store lambda
440  m_pcRdCost ->setLambda( dLambda );
441
442#if H_3D_VSO
443  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->getIsDepth() );
444  m_pcRdCost->setLambdaVSO          ( dLambda * m_pcCfg->getLambdaScaleVSO() );
445
446  // Should be moved to TEncTop
447 
448  // SAIT_VSO_EST_A0033
449  m_pcRdCost->setDisparityCoeff( m_pcCfg->getDispCoeff() );
450
451  // LGE_WVSO_A0119
452  if( m_pcCfg->getUseWVSO() && m_pcCfg->getIsDepth() )
453  {
454    m_pcRdCost->setDWeight  ( m_pcCfg->getDWeight()   );
455    m_pcRdCost->setVSOWeight( m_pcCfg->getVSOWeight() );
456    m_pcRdCost->setVSDWeight( m_pcCfg->getVSDWeight() );
457  }
458
459#endif
460
461// for RDO
462  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
463  Double weight[2] = { 1.0, 1.0 };
464  Int qpc;
465  Int chromaQPOffset;
466
467  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
468  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
469  weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
470  m_pcRdCost->setCbDistortionWeight(weight[0]);
471
472  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
473  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
474  weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
475  m_pcRdCost->setCrDistortionWeight(weight[1]);
476
477  const Double lambdaArray[3] = {dLambda, (dLambda / weight[0]), (dLambda / weight[1])};
478
479#if RDOQ_CHROMA_LAMBDA
480// for RDOQ
481  m_pcTrQuant->setLambdas( lambdaArray );
482#else
483  m_pcTrQuant->setLambda( dLambda );
484#endif
485
486// For SAO
487  rpcSlice->setLambdas( lambdaArray );
488 
489#if HB_LAMBDA_FOR_LDC
490  // restore original slice type
491#if H_MV
492  eSliceType = eSliceTypeBaseView;
493  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
494  {
495    eSliceType = B_SLICE;
496  }
497#else
498#if EFFICIENT_FIELD_IRAP
499  if(!(isField && pocLast == 1))
500  {
501#endif // EFFICIENT_FIELD_IRAP
502#if ALLOW_RECOVERY_POINT_AS_RAP
503  if(m_pcCfg->getDecodingRefreshType() == 3)
504  {
505    eSliceType = (pocLast == 0 || (pocCurr)           % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
506
507  }
508  else
509  {
510  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
511  }
512#else
513  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
514#endif
515#if EFFICIENT_FIELD_IRAP
516  }
517#endif // EFFICIENT_FIELD_IRAP
518#endif
519
520  rpcSlice->setSliceType        ( eSliceType );
521#endif
522 
523  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
524  {
525    dQP = xGetQPValueAccordingToLambda( dLambda );
526    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );   
527  }
528
529  rpcSlice->setSliceQp          ( iQP );
530#if ADAPTIVE_QP_SELECTION
531  rpcSlice->setSliceQpBase      ( iQP );
532#endif
533  rpcSlice->setSliceQpDelta     ( 0 );
534  rpcSlice->setSliceQpDeltaCb   ( 0 );
535  rpcSlice->setSliceQpDeltaCr   ( 0 );
536#if H_MV
537  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
538  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
539#else
540  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
541  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
542#endif
543
544  if ( m_pcCfg->getDeblockingFilterMetric() )
545  {
546    rpcSlice->setDeblockingFilterOverrideFlag(true);
547    rpcSlice->setDeblockingFilterDisable(false);
548    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
549    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
550  } else
551  if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
552  {
553    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
554    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
555    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
556    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
557    if ( !rpcSlice->getDeblockingFilterDisable())
558    {
559      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
560      {
561#if H_MV
562        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
563        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
564        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
565        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
566#else
567        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
568        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
569        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
570        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
571#endif
572      }
573      else
574      {
575      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
576      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
577      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
578      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
579      }
580    }
581  }
582  else
583  {
584    rpcSlice->setDeblockingFilterOverrideFlag( false );
585    rpcSlice->setDeblockingFilterDisable( false );
586    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
587    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
588  }
589
590  rpcSlice->setDepth            ( depth );
591 
592#if H_MV
593  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
594#else
595  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
596#endif
597  if(eSliceType==I_SLICE)
598  {
599    pcPic->setTLayer(0);
600  }
601  rpcSlice->setTLayer( pcPic->getTLayer() );
602
603  assert( m_apcPicYuvPred );
604  assert( m_apcPicYuvResi );
605 
606  pcPic->setPicYuvPred( m_apcPicYuvPred );
607  pcPic->setPicYuvResi( m_apcPicYuvResi );
608  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
609  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
610  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
611  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
612#if H_3D_IV_MERGE
613  rpcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()   + ( ( rpcSlice->getMpiFlag( ) || rpcSlice->getIvMvPredFlag( ) || rpcSlice->getViewSynthesisPredFlag( )   ) ? 1 : 0 ));
614#else
615  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
616#endif
617  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
618}
619
620Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
621{
622  TComSlice* slice = pic->getSlice(0);
623
624  // store lambda
625  slice->setSliceQp( sliceQP );
626#if ADAPTIVE_QP_SELECTION
627  slice->setSliceQpBase ( sliceQP );
628#endif
629  m_pcRdCost ->setLambda( lambda );
630  // for RDO
631  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
632  Double weight[2] = { 1.0, 1.0 };
633  Int qpc;
634  Int chromaQPOffset;
635
636  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
637  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
638  weight[0] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
639  m_pcRdCost->setCbDistortionWeight(weight[0]);
640
641  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
642  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
643  weight[1] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
644  m_pcRdCost->setCrDistortionWeight(weight[1]);
645
646  const Double lambdaArray[3] = {lambda, (lambda / weight[0]), (lambda / weight[1])};
647
648#if RDOQ_CHROMA_LAMBDA
649  // for RDOQ
650  m_pcTrQuant->setLambdas( lambdaArray );
651#else
652  m_pcTrQuant->setLambda( lambda );
653#endif
654
655  // For SAO
656  slice->setLambdas( lambdaArray );
657}
658// ====================================================================================================================
659// Public member functions
660// ====================================================================================================================
661
662Void TEncSlice::setSearchRange( TComSlice* pcSlice )
663{
664  Int iCurrPOC = pcSlice->getPOC();
665  Int iRefPOC;
666  Int iGOPSize = m_pcCfg->getGOPSize();
667  Int iOffset = (iGOPSize >> 1);
668  Int iMaxSR = m_pcCfg->getSearchRange();
669  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
670 
671  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
672  {
673    //RefPicList e = (RefPicList)iDir;
674    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
675    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
676    {
677      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
678      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
679      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
680    }
681  }
682}
683
684/**
685 - multi-loop slice encoding for different slice QP
686 .
687 \param rpcPic    picture class
688 */
689Void TEncSlice::precompressSlice( TComPic*& rpcPic )
690{
691  // if deltaQP RD is not used, simply return
692  if ( m_pcCfg->getDeltaQpRD() == 0 )
693  {
694    return;
695  }
696
697  if ( m_pcCfg->getUseRateCtrl() )
698  {
699    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
700    assert(0);
701  }
702 
703  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
704  Double     dPicRdCostBest = MAX_DOUBLE;
705  UInt       uiQpIdxBest = 0;
706 
707  Double dFrameLambda;
708#if FULL_NBIT
709  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
710#else
711  Int    SHIFT_QP = 12;
712#endif
713 
714  // set frame lambda
715  if (m_pcCfg->getGOPSize() > 1)
716  {
717    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
718  }
719  else
720  {
721    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
722  }
723  m_pcRdCost      ->setFrameLambda(dFrameLambda);
724 
725  // for each QP candidate
726  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
727  {
728    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
729#if ADAPTIVE_QP_SELECTION
730    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
731#endif
732    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
733    // for RDO
734    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
735    Int iQP = m_piRdPicQp    [uiQpIdx];
736    Double weight[2] = { 1.0, 1.0 };
737    Int qpc;
738    Int chromaQPOffset;
739
740    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
741    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
742    weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
743    m_pcRdCost->setCbDistortionWeight(weight[0]);
744
745    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
746    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
747    weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
748    m_pcRdCost->setCrDistortionWeight(weight[1]);
749
750    const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])};
751#if RDOQ_CHROMA_LAMBDA
752    // for RDOQ
753    m_pcTrQuant->setLambdas( lambdaArray );
754#else
755    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
756#endif
757    // For SAO
758    pcSlice->setLambdas( lambdaArray );
759   
760    // try compress
761    compressSlice   ( rpcPic );
762   
763    Double dPicRdCost;
764#if H_3D_VSO
765    Dist64 uiPicDist        = m_uiPicDist;
766#else
767    UInt64 uiPicDist        = m_uiPicDist;
768#endif
769    UInt64 uiALFBits        = 0;
770   
771    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
772   
773    // compute RD cost and choose the best
774    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
775#if H_3D
776    // Above calculation need to be fixed for VSO, including frameLambda value.
777#endif
778   
779    if ( dPicRdCost < dPicRdCostBest )
780    {
781      uiQpIdxBest    = uiQpIdx;
782      dPicRdCostBest = dPicRdCost;
783    }
784  }
785 
786  // set best values
787  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
788#if ADAPTIVE_QP_SELECTION
789  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
790#endif
791  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
792  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
793  Int iQP = m_piRdPicQp    [uiQpIdxBest];
794  Double weight[2] = { 1.0, 1.0 };
795  Int qpc;
796  Int chromaQPOffset;
797
798  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
799  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
800  weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
801  m_pcRdCost->setCbDistortionWeight(weight[0]);
802
803  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
804  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
805  weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
806  m_pcRdCost->setCrDistortionWeight(weight[1]);
807
808  const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])};
809#if RDOQ_CHROMA_LAMBDA
810  // for RDOQ
811  m_pcTrQuant->setLambdas( lambdaArray );
812#else
813  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
814#endif
815  // For SAO
816  pcSlice->setLambdas( lambdaArray );
817}
818
819/** \param rpcPic   picture class
820 */
821Void TEncSlice::calCostSliceI(TComPic*& rpcPic)
822{
823  UInt    uiCUAddr;
824  UInt    uiStartCUAddr;
825  UInt    uiBoundingCUAddr;
826  Int     iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;;
827  Double  iSumHadSlice = 0;
828
829  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
830  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
831  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
832
833  UInt uiEncCUOrder;
834  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
835  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
836       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
837       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
838  {
839    // initialize CU encoder
840    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
841    pcCU->initCU( rpcPic, uiCUAddr );
842
843    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
844    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
845
846    iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height);
847
848    (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift;
849    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra;
850
851  }
852  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
853}
854
855Void TEncSlice::compressSlice( TComPic*& rpcPic )
856{
857  UInt  uiCUAddr;
858  UInt   uiStartCUAddr;
859  UInt   uiBoundingCUAddr;
860  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
861  TEncBinCABAC* pppcRDSbacCoder = NULL;
862  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
863  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
864 
865  // initialize cost values
866  m_uiPicTotalBits  = 0;
867  m_dPicRdCost      = 0;
868  m_uiPicDist       = 0;
869 
870  // set entropy coder
871    m_pcSbacCoder->init( m_pcBinCABAC );
872    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
873    m_pcEntropyCoder->resetEntropy      ();
874    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
875    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
876    pppcRDSbacCoder->setBinCountingEnableFlag( false );
877    pppcRDSbacCoder->setBinsCoded( 0 );
878 
879  //------------------------------------------------------------------------------
880  //  Weighted Prediction parameters estimation.
881  //------------------------------------------------------------------------------
882  // calculate AC/DC values for current picture
883  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
884  {
885    xCalcACDCParamSlice(pcSlice);
886  }
887
888  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
889
890  if ( bWp_explicit )
891  {
892    //------------------------------------------------------------------------------
893    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
894    //------------------------------------------------------------------------------
895    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
896    {
897      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
898    }
899
900    xEstimateWPParamSlice( pcSlice );
901    pcSlice->initWpScaling();
902
903    // check WP on/off
904    xCheckWPEnable( pcSlice );
905  }
906
907#if ADAPTIVE_QP_SELECTION
908  if( m_pcCfg->getUseAdaptQpSelect() )
909  {
910    m_pcTrQuant->clearSliceARLCnt();
911    if(pcSlice->getSliceType()!=I_SLICE)
912    {
913      Int qpBase = pcSlice->getSliceQpBase();
914      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
915    }
916  }
917#endif
918  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
919  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
920  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
921  Int  iNumSubstreams = 1;
922  UInt uiTilesAcross  = 0;
923#if H_3D_IC
924  if ( pcEncTop->getViewIndex() && pcEncTop->getUseIC() &&
925       !( ( pcSlice->getSliceType() == P_SLICE && pcSlice->getPPS()->getUseWP() ) || ( pcSlice->getSliceType() == B_SLICE && pcSlice->getPPS()->getWPBiPred() ) )
926     )
927  {
928    pcSlice ->xSetApplyIC(pcEncTop->getUseICLowLatencyEnc());
929    if ( pcSlice->getApplyIC() )
930    {
931      pcSlice->setIcSkipParseFlag( pcSlice->getPOC() % m_pcCfg->getIntraPeriod() != 0 );
932    }
933  }
934#endif
935    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
936    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
937    delete[] m_pcBufferSbacCoders;
938    delete[] m_pcBufferBinCoderCABACs;
939    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
940    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
941    for (Int ui = 0; ui < uiTilesAcross; ui++)
942    {
943      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
944    }
945    for (UInt ui = 0; ui < uiTilesAcross; ui++)
946    {
947      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
948    }
949
950    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
951    {
952      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
953    }
954    delete[] m_pcBufferLowLatSbacCoders;
955    delete[] m_pcBufferLowLatBinCoderCABACs;
956    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
957    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
958    for (Int ui = 0; ui < uiTilesAcross; ui++)
959    {
960      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
961    }
962    for (UInt ui = 0; ui < uiTilesAcross; ui++)
963      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
964
965  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
966  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
967  UInt uiCol=0, uiLin=0, uiSubStrm=0;
968  UInt uiTileCol      = 0;
969  UInt uiTileStartLCU = 0;
970  UInt uiTileLCUX     = 0;
971  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
972  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
973  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
974  if( depSliceSegmentsEnabled )
975  {
976    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
977    {
978      if( m_pcCfg->getWaveFrontsynchro() )
979      {
980        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
981        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
982        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
983        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
984        uiLin     = uiCUAddr / uiWidthInLCUs;
985        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
986          + uiLin%iNumSubstreamsPerTile;
987        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
988        {
989          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
990          uiCol     = uiCUAddr % uiWidthInLCUs;
991          if(uiCol==uiTileStartLCU)
992          {
993            CTXMem[0]->loadContexts(m_pcSbacCoder);
994          }
995        }
996      }
997      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
998      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
999    }
1000    else
1001    {
1002      if(m_pcCfg->getWaveFrontsynchro())
1003      {
1004        CTXMem[1]->loadContexts(m_pcSbacCoder);
1005      }
1006      CTXMem[0]->loadContexts(m_pcSbacCoder);
1007    }
1008  }
1009
1010  // for every CU in slice
1011#if H_3D
1012  Int iLastPosY = -1;
1013#endif
1014  UInt uiEncCUOrder;
1015  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1016       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1017       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1018  {
1019    // initialize CU encoder
1020    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1021    pcCU->initCU( rpcPic, uiCUAddr );
1022#if H_3D_VSO
1023    if ( m_pcRdCost->getUseRenModel() )
1024    {
1025      // updated renderer model if necessary
1026      Int iCurPosX;
1027      Int iCurPosY; 
1028      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
1029      if ( iCurPosY != iLastPosY )
1030      {
1031        iLastPosY = iCurPosY;         
1032        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY );
1033      }
1034    }
1035#endif
1036    // inherit from TR if necessary, select substream to use.
1037      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1038      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1039      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1040      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1041      uiCol     = uiCUAddr % uiWidthInLCUs;
1042      uiLin     = uiCUAddr / uiWidthInLCUs;
1043      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1044      {
1045        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1046        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1047        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1048                      + uiLin%iNumSubstreamsPerTile;
1049      }
1050      else
1051      {
1052        // dependent tiles => substreams are "per frame".
1053        uiSubStrm = uiLin % iNumSubstreams;
1054      }
1055      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1056      {
1057        // We'll sync if the TR is available.
1058        TComDataCU *pcCUUp = pcCU->getCUAbove();
1059        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1060        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1061        TComDataCU *pcCUTR = NULL;
1062        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1063        {
1064          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1065        }
1066        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1067             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1068             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1069             )
1070           )
1071        {
1072          // TR not available.
1073        }
1074        else
1075        {
1076          // TR is available, we use it.
1077          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1078        }
1079      }
1080      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1081
1082    // reset the entropy coder
1083    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1084        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1085        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1086        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1087    {
1088      SliceType sliceType = pcSlice->getSliceType();
1089      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1090      {
1091        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1092      }
1093      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1094      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1095      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1096      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1097    }
1098
1099      // set go-on entropy coder
1100      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1101      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1102     
1103      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1104
1105      Double oldLambda = m_pcRdCost->getLambda();
1106      if ( m_pcCfg->getUseRateCtrl() )
1107      {
1108        Int estQP        = pcSlice->getSliceQp();
1109        Double estLambda = -1.0;
1110        Double bpp       = -1.0;
1111
1112        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1113        {
1114          estQP = pcSlice->getSliceQp();
1115        }
1116        else
1117        {
1118#if KWU_RC_MADPRED_E0227
1119          if(pcSlice->getLayerId() != 0 && m_pcCfg->getUseDepthMADPred() && !pcSlice->getIsDepth())
1120          {
1121            Double zn, zf, focallength, position, camShift;
1122            Double basePos;
1123            Bool bInterpolated;
1124            Int direction = pcSlice->getViewId() - pcCU->getSlice()->getIvPic(false, 0)->getViewId();
1125            Int disparity;
1126
1127            pcEncTop->getCamParam()->xGetZNearZFar(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), zn, zf);
1128            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[0], pcSlice->getPOC(), focallength, basePos, camShift, bInterpolated);
1129            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), focallength, position, camShift, bInterpolated);
1130            bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBppforInterView( m_pcRateCtrl->getPicList(), pcCU,
1131              basePos, position, focallength, zn, zf, (direction > 0 ? 1 : -1), &disparity );
1132          }
1133          else
1134          {
1135#endif
1136          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1137          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1138          {
1139            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1140          }
1141          else
1142          {
1143            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1144            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1145          }
1146#if KWU_RC_MADPRED_E0227
1147          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1148          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1149#endif
1150          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1151
1152          m_pcRdCost->setLambda(estLambda);
1153#if RDOQ_CHROMA_LAMBDA
1154          // set lambda for RDOQ
1155          Double weight=m_pcRdCost->getChromaWeight();
1156        const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
1157        m_pcTrQuant->setLambdas( lambdaArray );
1158#else
1159          m_pcTrQuant->setLambda( estLambda );
1160#endif
1161        }
1162
1163        m_pcRateCtrl->setRCQP( estQP );
1164#if ADAPTIVE_QP_SELECTION
1165        pcCU->getSlice()->setSliceQpBase( estQP );
1166#endif
1167      }
1168      // run CU encoder
1169      m_pcCuEncoder->compressCU( pcCU );
1170
1171      // restore entropy coder to an initial stage
1172      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1173      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1174      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1175      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1176      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1177      m_pcBitCounter->resetBits();
1178      pppcRDSbacCoder->setBinsCoded( 0 );
1179      m_pcCuEncoder->encodeCU( pcCU );
1180
1181      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1182      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1183      {
1184        pcSlice->setNextSlice( true );
1185        break;
1186      }
1187      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1188      {
1189        pcSlice->setNextSliceSegment( true );
1190        break;
1191      }
1192       
1193    ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1194         //Store probabilties of second LCU in line into buffer
1195         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1196        {
1197          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1198        }
1199
1200      if ( m_pcCfg->getUseRateCtrl() )
1201      {
1202#if KWU_RC_MADPRED_E0227
1203        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1204        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1205        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1206        Double MAD = (Double)SAD / (Double)(height * width);
1207        MAD = MAD * MAD;
1208        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1209#endif
1210
1211        Int actualQP        = g_RCInvalidQPValue;
1212        Double actualLambda = m_pcRdCost->getLambda();
1213        Int actualBits      = pcCU->getTotalBits();
1214        Int numberOfEffectivePixels    = 0;
1215        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1216        {
1217          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1218          {
1219            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1220            break;
1221          }
1222        }
1223
1224        if ( numberOfEffectivePixels == 0 )
1225        {
1226          actualQP = g_RCInvalidQPValue;
1227        }
1228        else
1229        {
1230          actualQP = pcCU->getQP( 0 );
1231        }
1232        m_pcRdCost->setLambda(oldLambda);
1233
1234        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1235          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1236    }
1237   
1238    m_uiPicTotalBits += pcCU->getTotalBits();
1239    m_dPicRdCost     += pcCU->getTotalCost();
1240    m_uiPicDist      += pcCU->getTotalDistortion();
1241  }
1242  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1243  {
1244    pcSlice->setNextSlice( true );
1245  }
1246  if(m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES || m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES)
1247  {
1248    if(pcSlice->getSliceCurEndCUAddr()<=pcSlice->getSliceSegmentCurEndCUAddr())
1249    {
1250       pcSlice->setNextSlice( true );
1251    }
1252    else
1253    {
1254       pcSlice->setNextSliceSegment( true );
1255    }
1256  }
1257  if( depSliceSegmentsEnabled )
1258  {
1259    if (m_pcCfg->getWaveFrontsynchro())
1260    {
1261      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1262    }
1263     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1264  }
1265  xRestoreWPparam( pcSlice );
1266}
1267
1268/**
1269 \param  rpcPic        picture class
1270 \retval rpcBitstream  bitstream class
1271 */
1272Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1273{
1274  UInt       uiCUAddr;
1275  UInt       uiStartCUAddr;
1276  UInt       uiBoundingCUAddr;
1277  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1278
1279  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1280  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1281  // choose entropy coder
1282  {
1283    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1284    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1285  }
1286 
1287  m_pcCuEncoder->setBitCounter( NULL );
1288  m_pcBitCounter = NULL;
1289  // Appropriate substream bitstream is switched later.
1290  // for every CU
1291#if ENC_DEC_TRACE
1292  g_bJustDoIt = g_bEncDecTraceEnable;
1293#endif
1294  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1295  DTRACE_CABAC_T( "\tPOC: " );
1296  DTRACE_CABAC_V( rpcPic->getPOC() );
1297#if H_MV_ENC_DEC_TRAC
1298  DTRACE_CABAC_T( " Layer: " );
1299  DTRACE_CABAC_V( rpcPic->getLayerId() );
1300#endif
1301  DTRACE_CABAC_T( "\n" );
1302#if ENC_DEC_TRACE
1303  g_bJustDoIt = g_bEncDecTraceDisable;
1304#endif
1305
1306  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1307  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1308  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1309  UInt uiBitsOriginallyInSubstreams = 0;
1310  {
1311    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1312    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1313    {
1314      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1315    }
1316   
1317    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1318    {
1319      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1320    }
1321
1322    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1323    {
1324      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1325    }
1326  }
1327
1328  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1329  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1330  UInt uiTileCol      = 0;
1331  UInt uiTileStartLCU = 0;
1332  UInt uiTileLCUX     = 0;
1333  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1334  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1335                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1336                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1337  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1338  if( depSliceSegmentsEnabled )
1339  {
1340    if( pcSlice->isNextSlice()||
1341        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1342    {
1343      if(m_pcCfg->getWaveFrontsynchro())
1344      {
1345        CTXMem[1]->loadContexts(m_pcSbacCoder);
1346      }
1347      CTXMem[0]->loadContexts(m_pcSbacCoder);
1348    }
1349    else
1350    {
1351      if(m_pcCfg->getWaveFrontsynchro())
1352      {
1353        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1354        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1355        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1356        uiLin     = uiCUAddr / uiWidthInLCUs;
1357        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1358          + uiLin%iNumSubstreamsPerTile;
1359        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1360        {
1361          uiCol     = uiCUAddr % uiWidthInLCUs;
1362          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1363          if(uiCol==uiTileLCUX)
1364          {
1365            CTXMem[0]->loadContexts(m_pcSbacCoder);
1366          }
1367        }
1368      }
1369      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1370    }
1371  }
1372
1373  UInt uiEncCUOrder;
1374  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1375       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1376       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1377  {
1378      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1379      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1380      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1381      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1382      uiCol     = uiCUAddr % uiWidthInLCUs;
1383      uiLin     = uiCUAddr / uiWidthInLCUs;
1384      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1385      {
1386        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1387        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1388        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1389                      + uiLin%iNumSubstreamsPerTile;
1390      }
1391      else
1392      {
1393        // dependent tiles => substreams are "per frame".
1394        uiSubStrm = uiLin % iNumSubstreams;
1395      }
1396
1397      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1398      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1399      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1400      {
1401        // We'll sync if the TR is available.
1402        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1403        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1404        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1405        TComDataCU *pcCUTR = NULL;
1406        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1407        {
1408          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1409        }
1410        if ( (true/*bEnforceSliceRestriction*/ &&
1411             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1412             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1413             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1414             ))
1415           )
1416        {
1417          // TR not available.
1418        }
1419        else
1420        {
1421          // TR is available, we use it.
1422          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1423        }
1424      }
1425      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1426
1427    // reset the entropy coder
1428    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1429        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1430        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1431        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1432    {
1433      {
1434        // We're crossing into another tile, tiles are independent.
1435        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1436        // have to perform it here.
1437        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1438        {
1439          ; // do nothing.
1440        }
1441        else
1442        {
1443          SliceType sliceType  = pcSlice->getSliceType();
1444          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1445          {
1446            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1447          }
1448          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1449          // Byte-alignment in slice_data() when new tile
1450          pcSubstreams[uiSubStrm].writeByteAlignment();
1451        }
1452      }
1453      {
1454        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1455        UInt uiAccumulatedSubstreamLength = 0;
1456        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1457        {
1458          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1459        }
1460        // add bits coded in previous dependent slices + bits coded so far
1461        // add number of emulation prevention byte count in the tile
1462        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1463      }
1464    }
1465
1466#if H_3D_QTLPC
1467    rpcPic->setReduceBitsFlag(true);
1468#endif
1469    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1470    if ( pcSlice->getSPS()->getUseSAO() )
1471    {
1472      if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
1473      {
1474        SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[uiCUAddr];
1475        Bool sliceEnabled[NUM_SAO_COMPONENTS];
1476        sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
1477        sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
1478
1479        Bool leftMergeAvail = false;
1480        Bool aboveMergeAvail= false;
1481        //merge left condition
1482        Int rx = (uiCUAddr % uiWidthInLCUs);
1483        if(rx > 0)
1484        {
1485          leftMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-1);
1486        }
1487
1488        //merge up condition
1489        Int ry = (uiCUAddr / uiWidthInLCUs);
1490        if(ry > 0)
1491      {
1492          aboveMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-uiWidthInLCUs);
1493        }
1494
1495        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail);
1496      }
1497    }
1498#if ENC_DEC_TRACE
1499    g_bJustDoIt = g_bEncDecTraceEnable;
1500#endif
1501    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1502      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1503    {
1504      m_pcCuEncoder->encodeCU( pcCU );
1505    }
1506    else
1507    {
1508      m_pcCuEncoder->encodeCU( pcCU );
1509    }
1510#if ENC_DEC_TRACE
1511    g_bJustDoIt = g_bEncDecTraceDisable;
1512#endif   
1513       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1514       
1515
1516       //Store probabilties of second LCU in line into buffer
1517       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1518      {
1519        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1520      }
1521#if H_3D_QTLPC
1522    rpcPic->setReduceBitsFlag(false);
1523#endif
1524  }
1525  if( depSliceSegmentsEnabled )
1526  {
1527    if (m_pcCfg->getWaveFrontsynchro())
1528    {
1529      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1530    }
1531    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1532  }
1533#if ADAPTIVE_QP_SELECTION
1534  if( m_pcCfg->getUseAdaptQpSelect() )
1535  {
1536    m_pcTrQuant->storeSliceQpNext(pcSlice);
1537  }
1538#endif
1539  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1540  {
1541    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1542    {
1543      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1544    }
1545    else
1546    {
1547      m_pcEntropyCoder->determineCabacInitIdx();
1548    }
1549  }
1550}
1551
1552/** Determines the starting and bounding LCU address of current slice / dependent slice
1553 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1554 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1555 */
1556Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1557{
1558  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1559  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1560  UInt tileIdxIncrement;
1561  UInt tileIdx;
1562  UInt tileWidthInLcu;
1563  UInt tileHeightInLcu;
1564  UInt tileTotalCount;
1565
1566  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1567  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1568  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1569  if (bEncodeSlice) 
1570  {
1571    UInt uiCUAddrIncrement;
1572    switch (m_pcCfg->getSliceMode())
1573    {
1574    case FIXED_NUMBER_OF_LCU:
1575      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1576      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1577      break;
1578    case FIXED_NUMBER_OF_BYTES:
1579      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1580      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1581      break;
1582    case FIXED_NUMBER_OF_TILES:
1583      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1584        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1585        );
1586      uiCUAddrIncrement        = 0;
1587      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1588
1589      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1590      {
1591        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1592        {
1593          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1594          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1595          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1596        }
1597      }
1598
1599      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1600      break;
1601    default:
1602      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1603      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1604      break;
1605    } 
1606    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1607    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1608    {
1609      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1610    }
1611    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1612  }
1613  else
1614  {
1615    UInt uiCUAddrIncrement     ;
1616    switch (m_pcCfg->getSliceMode())
1617    {
1618    case FIXED_NUMBER_OF_LCU:
1619      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1620      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1621      break;
1622    case FIXED_NUMBER_OF_TILES:
1623      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1624        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1625        );
1626      uiCUAddrIncrement        = 0;
1627      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1628
1629      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1630      {
1631        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1632        {
1633          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1634          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1635          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1636        }
1637      }
1638
1639      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1640      break;
1641    default:
1642      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1643      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1644      break;
1645    } 
1646    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1647    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1648    {
1649      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1650    }
1651    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1652  }
1653
1654  Bool tileBoundary = false;
1655  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1656      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1657  {
1658    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1659    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1660    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1661    UInt tileBoundingCUAddrSlice = 0;
1662    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1663    {
1664      lcuEncAddr++;
1665      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1666    }
1667    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1668   
1669    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1670    {
1671      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1672      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1673      tileBoundary = true;
1674    }
1675  }
1676
1677  // Dependent slice
1678  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1679  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1680  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1681  if (bEncodeSlice) 
1682  {
1683    UInt uiCUAddrIncrement;
1684    switch (m_pcCfg->getSliceSegmentMode())
1685    {
1686    case FIXED_NUMBER_OF_LCU:
1687      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1688      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1689      break;
1690    case FIXED_NUMBER_OF_BYTES:
1691      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1692      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1693      break;
1694    case FIXED_NUMBER_OF_TILES:
1695      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1696        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1697        );
1698      uiCUAddrIncrement        = 0;
1699      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1700
1701      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1702      {
1703        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1704        {
1705          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1706          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1707          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1708        }
1709      }
1710      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1711      break;
1712    default:
1713      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1714      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1715      break;
1716    } 
1717    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1718    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1719    {
1720      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1721    }
1722    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1723  }
1724  else
1725  {
1726    UInt uiCUAddrIncrement;
1727    switch (m_pcCfg->getSliceSegmentMode())
1728    {
1729    case FIXED_NUMBER_OF_LCU:
1730      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1731      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1732      break;
1733    case FIXED_NUMBER_OF_TILES:
1734      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1735        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1736        );
1737      uiCUAddrIncrement        = 0;
1738      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1739
1740      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1741      {
1742        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1743        {
1744          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1745          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1746          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1747        }
1748      }
1749      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1750      break;
1751    default:
1752      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1753      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1754      break;
1755    } 
1756    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1757    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1758    {
1759      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1760    }
1761    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1762  }
1763  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1764    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1765  {
1766    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1767    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1768    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1769    UInt tileBoundingCUAddrSlice = 0;
1770    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1771    {
1772      lcuEncAddr++;
1773      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1774    }
1775    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1776
1777    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1778    {
1779      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1780      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1781      tileBoundary = true;
1782    }
1783  }
1784
1785  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1786  {
1787    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1788    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1789  }
1790
1791  //calculate real dependent slice start address
1792  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1793  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1794  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1795  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1796  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1797  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1798  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1799  {
1800    uiInternalAddress++;
1801    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1802    {
1803      uiInternalAddress=0;
1804      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1805    }
1806    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1807    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1808  }
1809  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1810 
1811  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1812  startCUAddrSliceSegment=uiRealStartAddress;
1813 
1814  //calculate real slice start address
1815  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1816  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1817  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1818  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1819  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1820  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1821  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1822  {
1823    uiInternalAddress++;
1824    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1825    {
1826      uiInternalAddress=0;
1827      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1828    }
1829    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1830    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1831  }
1832  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1833 
1834  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1835  uiStartCUAddrSlice=uiRealStartAddress;
1836 
1837  // Make a joint decision based on reconstruction and dependent slice bounds
1838  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1839  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1840
1841
1842  if (!bEncodeSlice)
1843  {
1844    // 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
1845    // first. Set the flags accordingly.
1846    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1847      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1848      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1849      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1850      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1851      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1852      || tileBoundary
1853)
1854    {
1855      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1856      {
1857        pcSlice->setNextSlice       ( true );
1858        pcSlice->setNextSliceSegment( false );
1859      }
1860      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1861      {
1862        pcSlice->setNextSlice       ( false );
1863        pcSlice->setNextSliceSegment( true );
1864      }
1865      else
1866      {
1867        pcSlice->setNextSlice       ( true );
1868        pcSlice->setNextSliceSegment( true );
1869      }
1870    }
1871    else
1872    {
1873      pcSlice->setNextSlice       ( false );
1874      pcSlice->setNextSliceSegment( false );
1875    }
1876  }
1877}
1878
1879Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1880{
1881  return 4.2005*log(lambda) + 13.7122;
1882}
1883
1884//! \}
Note: See TracBrowser for help on using the repository browser.