source: 3DVCSoftware/branches/HTM-16.1-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 1401

Last change on this file since 1401 was 1401, checked in by tech, 8 years ago

Exchange copy right dates.

  • Property svn:eol-style set to native
File size: 53.3 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-2016, 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// ====================================================================================================================
48TEncSlice::TEncSlice()
49 : m_encCABACTableIdx(I_SLICE)
50{
51  m_apcPicYuvPred = NULL;
52  m_apcPicYuvResi = NULL;
53
54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57}
58
59TEncSlice::~TEncSlice()
60{
61}
62
63Void TEncSlice::create( Int iWidth, Int iHeight, ChromaFormat chromaFormat, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
64{
65  // create prediction picture
66  if ( m_apcPicYuvPred == NULL )
67  {
68    m_apcPicYuvPred  = new TComPicYuv;
69    m_apcPicYuvPred->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth, true );
70  }
71
72  // create residual picture
73  if( m_apcPicYuvResi == NULL )
74  {
75    m_apcPicYuvResi  = new TComPicYuv;
76    m_apcPicYuvResi->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth, true );
77  }
78}
79
80Void TEncSlice::destroy()
81{
82  // destroy prediction picture
83  if ( m_apcPicYuvPred )
84  {
85    m_apcPicYuvPred->destroy();
86    delete m_apcPicYuvPred;
87    m_apcPicYuvPred  = NULL;
88  }
89
90  // destroy residual picture
91  if ( m_apcPicYuvResi )
92  {
93    m_apcPicYuvResi->destroy();
94    delete m_apcPicYuvResi;
95    m_apcPicYuvResi  = NULL;
96  }
97
98  // free lambda and QP arrays
99  if ( m_pdRdPicLambda )
100  {
101    xFree( m_pdRdPicLambda );
102    m_pdRdPicLambda = NULL;
103  }
104  if ( m_pdRdPicQp )
105  {
106    xFree( m_pdRdPicQp );
107    m_pdRdPicQp = NULL;
108  }
109  if ( m_piRdPicQp )
110  {
111    xFree( m_piRdPicQp );
112    m_piRdPicQp = NULL;
113  }
114}
115
116Void TEncSlice::init( TEncTop* pcEncTop )
117{
118  m_pcCfg             = pcEncTop;
119  m_pcListPic         = pcEncTop->getListPic();
120
121  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
122  m_pcCuEncoder       = pcEncTop->getCuEncoder();
123  m_pcPredSearch      = pcEncTop->getPredSearch();
124
125  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
126  m_pcSbacCoder       = pcEncTop->getSbacCoder();
127  m_pcBinCABAC        = pcEncTop->getBinCABAC();
128  m_pcTrQuant         = pcEncTop->getTrQuant();
129
130  m_pcRdCost          = pcEncTop->getRdCost();
131  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
132  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
133
134  // create lambda and QP arrays
135  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
136  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
137  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
138#if KWU_RC_MADPRED_E0227
139  if(m_pcCfg->getUseRateCtrl())
140  {
141    m_pcRateCtrl        = pcEncTop->getRateCtrl();
142  }
143  else
144  {
145    m_pcRateCtrl        = NULL;
146  }
147#else
148  m_pcRateCtrl        = pcEncTop->getRateCtrl();
149#endif
150
151}
152
153
154
155Void
156TEncSlice::setUpLambda(TComSlice* slice, const Double dLambda, Int iQP)
157{
158  // store lambda
159  m_pcRdCost ->setLambda( dLambda, slice->getSPS()->getBitDepths() );
160
161  // for RDO
162  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
163  Double dLambdas[MAX_NUM_COMPONENT] = { dLambda };
164  for(UInt compIdx=1; compIdx<MAX_NUM_COMPONENT; compIdx++)
165  {
166    const ComponentID compID=ComponentID(compIdx);
167    Int chromaQPOffset = slice->getPPS()->getQpOffset(compID) + slice->getSliceChromaQpDelta(compID);
168    Int qpc=(iQP + chromaQPOffset < 0) ? iQP : getScaledChromaQP(iQP + chromaQPOffset, m_pcCfg->getChromaFormatIdc());
169    Double tmpWeight = pow( 2.0, (iQP-qpc)/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
170    m_pcRdCost->setDistortionWeight(compID, tmpWeight);
171    dLambdas[compIdx]=dLambda/tmpWeight;
172  }
173
174#if RDOQ_CHROMA_LAMBDA
175// for RDOQ
176  m_pcTrQuant->setLambdas( dLambdas );
177#else
178  m_pcTrQuant->setLambda( dLambda );
179#endif
180
181// For SAO
182  slice   ->setLambdas( dLambdas );
183}
184
185
186
187/**
188 - non-referenced frame marking
189 - QP computation based on temporal structure
190 - lambda computation based on QP
191 - set temporal layer ID and the parameter sets
192 .
193 \param pcPic         picture class
194 \param pocLast       POC of last picture
195 \param pocCurr       current POC
196 \param iNumPicRcvd   number of received pictures
197 \param iGOPid        POC offset for hierarchical structure
198 \param rpcSlice      slice header class
199 \param isField       true for field coding
200 */
201
202#if NH_MV
203Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, Int layerId, bool isField )
204#else
205Void TEncSlice::initEncSlice( TComPic* pcPic, const Int pocLast, const Int pocCurr, const Int iGOPid, TComSlice*& rpcSlice, const Bool isField )
206#endif
207{
208  Double dQP;
209  Double dLambda;
210
211  rpcSlice = pcPic->getSlice(0);
212
213#if NH_MV
214  rpcSlice->setVPS( pVPS ); 
215
216  rpcSlice->setLayerId     ( layerId );
217  rpcSlice->setViewId      ( pVPS->getViewId      ( layerId ) );   
218  rpcSlice->setViewIndex   ( pVPS->getViewIndex   ( layerId ) );
219#if NH_3D
220  rpcSlice->setIsDepth     ( pVPS->getDepthId     ( layerId ) != 0 );   
221#endif
222#endif
223  rpcSlice->setSliceBits(0);
224  rpcSlice->setPic( pcPic );
225  rpcSlice->initSlice();
226  rpcSlice->setPicOutputFlag( true );
227  rpcSlice->setPOC( pocCurr );
228#if NH_3D_IC
229  rpcSlice->setApplyIC( false );
230#endif
231  // depth computation based on GOP size
232  Int depth;
233  {
234
235    Int poc = rpcSlice->getPOC();
236    if(isField)
237    {
238      poc = (poc/2) % (m_pcCfg->getGOPSize()/2);
239    }
240    else
241    {
242      poc = poc % m_pcCfg->getGOPSize();   
243    }
244    if ( poc == 0 )
245    {
246      depth = 0;
247    }
248    else
249    {
250      Int step = m_pcCfg->getGOPSize();
251      depth    = 0;
252      for( Int i=step>>1; i>=1; i>>=1 )
253      {
254        for ( Int j=i; j<m_pcCfg->getGOPSize(); j+=step )
255        {
256          if ( j == poc )
257          {
258            i=0;
259            break;
260          }
261        }
262        step >>= 1;
263        depth++;
264      }
265    }
266
267    if(m_pcCfg->getHarmonizeGopFirstFieldCoupleEnabled() && poc != 0)
268    {
269      if (isField && ((rpcSlice->getPOC() % 2) == 1))
270      {
271        depth ++;
272      }
273    }
274  }
275
276  // slice type
277#if NH_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(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled())
297  {
298    if(m_pcCfg->getDecodingRefreshType() == 3)
299    {
300      eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0             || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
301    }
302    else
303    {
304      eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
305    }
306  }
307#endif
308  rpcSlice->setSliceType    ( eSliceType );
309
310  // ------------------------------------------------------------------------------------------------------------------
311  // Non-referenced frame marking
312  // ------------------------------------------------------------------------------------------------------------------
313
314  if(pocLast == 0)
315  {
316    rpcSlice->setTemporalLayerNonReferenceFlag(false);
317  }
318  else
319  {
320#if NH_MV
321#if 0 // Check this! NH_MV
322    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_refPic);
323#else
324    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
325#endif
326#else
327    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
328#endif
329  }
330  rpcSlice->setReferenced(true);
331
332  // ------------------------------------------------------------------------------------------------------------------
333  // QP setting
334  // ------------------------------------------------------------------------------------------------------------------
335
336  dQP = m_pcCfg->getQP();
337  if(eSliceType!=I_SLICE)
338  {
339    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA) ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
340    {
341#if NH_MV
342      dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset;
343#else
344      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
345#endif
346    }
347  }
348
349  // modify QP
350  Int* pdQPs = m_pcCfg->getdQPs();
351  if ( pdQPs )
352  {
353    dQP += pdQPs[ rpcSlice->getPOC() ];
354  }
355
356  if (m_pcCfg->getCostMode()==COST_LOSSLESS_CODING)
357  {
358    dQP=LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP;
359    m_pcCfg->setDeltaQpRD(0);
360  }
361
362  // ------------------------------------------------------------------------------------------------------------------
363  // Lambda computation
364  // ------------------------------------------------------------------------------------------------------------------
365
366  Int iQP;
367  Double dOrigQP = dQP;
368
369  // pre-compute lambda and QP values for all possible QP candidates
370  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
371  {
372    // compute QP value
373    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
374
375    // compute lambda value
376    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
377    Int    SHIFT_QP = 12;
378
379#if FULL_NBIT
380    Int    bitdepth_luma_qp_scale = 6 * (rpcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
381#else
382    Int    bitdepth_luma_qp_scale = 0;
383#endif
384    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
385#if FULL_NBIT
386    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
387#endif
388    // Case #1: I or P-slices (key-frame)
389#if NH_MV
390    Double dQPFactor;
391    if( eSliceType != I_SLICE ) 
392    {
393      dQPFactor = m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPFactor;
394    }
395    else
396#else
397    Double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
398    if ( eSliceType==I_SLICE )
399#endif
400    {
401      if (m_pcCfg->getIntraQpFactor()>=0.0 && m_pcCfg->getGOPEntry(iGOPid).m_sliceType != I_SLICE)
402      {
403        dQPFactor=m_pcCfg->getIntraQpFactor();
404      }
405      else
406      {
407        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
408       
409        dQPFactor=0.57*dLambda_scale;
410      }
411    }
412    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
413
414    if ( depth>0 )
415    {
416#if FULL_NBIT
417        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
418#else
419        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
420#endif
421    }
422
423    // if hadamard is used in ME process
424    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
425    {
426      dLambda *= 0.95;
427    }
428
429    iQP = max( -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
430
431    m_pdRdPicLambda[iDQpIdx] = dLambda;
432    m_pdRdPicQp    [iDQpIdx] = dQP;
433    m_piRdPicQp    [iDQpIdx] = iQP;
434  }
435
436  // obtain dQP = 0 case
437  dLambda = m_pdRdPicLambda[0];
438  dQP     = m_pdRdPicQp    [0];
439  iQP     = m_piRdPicQp    [0];
440
441
442#if NH_MV
443  const Int temporalId=m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_temporalId;
444#else
445  const Int temporalId=m_pcCfg->getGOPEntry(iGOPid).m_temporalId;
446#endif
447  const std::vector<Double> &intraLambdaModifiers=m_pcCfg->getIntraLambdaModifier();
448
449  Double lambdaModifier;
450  if( rpcSlice->getSliceType( ) != I_SLICE || intraLambdaModifiers.empty())
451  {
452    lambdaModifier = m_pcCfg->getLambdaModifier( temporalId );
453  }
454  else
455  {
456    lambdaModifier = intraLambdaModifiers[ (temporalId < intraLambdaModifiers.size()) ? temporalId : (intraLambdaModifiers.size()-1) ];
457  }
458
459  dLambda *= lambdaModifier;
460  setUpLambda(rpcSlice, dLambda, iQP);
461
462#if NH_3D_VSO
463  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && ( m_pcCfg->getIsDepth() || m_pcCfg->getIsAuxDepth() ) );
464  m_pcRdCost->setLambdaVSO          ( dLambda * m_pcCfg->getLambdaScaleVSO() );
465
466  // Should be moved to TEncTop
467 
468  // SAIT_VSO_EST_A0033
469  m_pcRdCost->setDisparityCoeff( m_pcCfg->getDispCoeff() );
470
471  // LGE_WVSO_A0119
472  if( m_pcCfg->getUseWVSO() && ( m_pcCfg->getIsDepth() || m_pcCfg->getIsAuxDepth() ) )
473  {
474    m_pcRdCost->setDWeight  ( m_pcCfg->getDWeight()   );
475    m_pcRdCost->setVSOWeight( m_pcCfg->getVSOWeight() );
476    m_pcRdCost->setVSDWeight( m_pcCfg->getVSDWeight() );
477  }
478
479#endif
480
481  if (m_pcCfg->getFastMEForGenBLowDelayEnabled())
482  {
483  // restore original slice type
484#if NH_MV
485  eSliceType = eSliceTypeBaseView;
486  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
487  {
488    eSliceType = B_SLICE;
489  }
490#else
491    if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled())
492  {
493    if(m_pcCfg->getDecodingRefreshType() == 3)
494    {
495      eSliceType = (pocLast == 0 || (pocCurr)                     % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
496    }
497    else
498    {
499      eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
500
501    }
502  }
503#endif
504
505  rpcSlice->setSliceType        ( eSliceType );
506}
507
508  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
509  {
510    dQP = xGetQPValueAccordingToLambda( dLambda );
511    iQP = max( -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
512  }
513
514  rpcSlice->setSliceQp           ( iQP );
515#if ADAPTIVE_QP_SELECTION
516  rpcSlice->setSliceQpBase       ( iQP );
517#endif
518  rpcSlice->setSliceQpDelta      ( 0 );
519  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
520  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
521  rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() );
522#if NH_MV
523  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
524  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
525#else
526  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
527  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
528#endif
529
530  if ( m_pcCfg->getDeblockingFilterMetric() )
531  {
532    rpcSlice->setDeblockingFilterOverrideFlag(true);
533    rpcSlice->setDeblockingFilterDisable(false);
534    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
535    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
536  }
537  else if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
538  {
539    rpcSlice->setDeblockingFilterOverrideFlag( rpcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() );
540    rpcSlice->setDeblockingFilterDisable( rpcSlice->getPPS()->getPicDisableDeblockingFilterFlag() );
541    if ( !rpcSlice->getDeblockingFilterDisable())
542    {
543      if ( rpcSlice->getDeblockingFilterOverrideFlag() && eSliceType!=I_SLICE)
544      {
545#if NH_MV
546        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
547        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
548#else
549        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
550        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
551#endif
552      }
553      else
554      {
555        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
556        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
557      }
558    }
559  }
560  else
561  {
562    rpcSlice->setDeblockingFilterOverrideFlag( false );
563    rpcSlice->setDeblockingFilterDisable( false );
564    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
565    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
566  }
567
568  rpcSlice->setDepth            ( depth );
569
570  pcPic->setTLayer( temporalId );
571  if(eSliceType==I_SLICE)
572  {
573    pcPic->setTLayer(0);
574  }
575  rpcSlice->setTLayer( pcPic->getTLayer() );
576
577  assert( m_apcPicYuvPred );
578  assert( m_apcPicYuvResi );
579
580  pcPic->setPicYuvPred( m_apcPicYuvPred );
581  pcPic->setPicYuvResi( m_apcPicYuvResi );
582  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
583  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
584  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
585  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
586#if NH_3D_IV_MERGE
587#else
588  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
589#endif
590}
591
592Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
593{
594  TComSlice* slice = pic->getSlice(0);
595
596  // store lambda
597  slice->setSliceQp( sliceQP );
598#if ADAPTIVE_QP_SELECTION
599  slice->setSliceQpBase ( sliceQP );
600#endif
601  setUpLambda(slice, lambda, sliceQP);
602}
603
604// ====================================================================================================================
605// Public member functions
606// ====================================================================================================================
607
608//! set adaptive search range based on poc difference
609Void TEncSlice::setSearchRange( TComSlice* pcSlice )
610{
611  Int iCurrPOC = pcSlice->getPOC();
612  Int iRefPOC;
613  Int iGOPSize = m_pcCfg->getGOPSize();
614  Int iOffset = (iGOPSize >> 1);
615  Int iMaxSR = m_pcCfg->getSearchRange();
616  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
617
618  for (Int iDir = 0; iDir < iNumPredDir; iDir++)
619  {
620    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
621    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
622    {
623      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
624      Int newSearchRange = Clip3(m_pcCfg->getMinSearchWindow(), iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
625      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, newSearchRange);
626    }
627  }
628}
629
630/**
631 Multi-loop slice encoding for different slice QP
632
633 \param pcPic    picture class
634 */
635Void TEncSlice::precompressSlice( TComPic* pcPic )
636{
637  // if deltaQP RD is not used, simply return
638  if ( m_pcCfg->getDeltaQpRD() == 0 )
639  {
640    return;
641  }
642
643  if ( m_pcCfg->getUseRateCtrl() )
644  {
645    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
646    assert(0);
647    return;
648  }
649
650  TComSlice* pcSlice        = pcPic->getSlice(getSliceIdx());
651
652  if (pcSlice->getDependentSliceSegmentFlag())
653  {
654    // if this is a dependent slice segment, then it was optimised
655    // when analysing the entire slice.
656    return;
657  }
658
659  if (pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES)
660  {
661    // TODO: investigate use of average cost per CTU so that this Slice Mode can be used.
662    printf( "\nUnable to optimise Slice-level QP if Slice Mode is set to FIXED_NUMBER_OF_BYTES\n" );
663    assert(0);
664    return;
665  }
666
667
668  Double     dPicRdCostBest = MAX_DOUBLE;
669  UInt       uiQpIdxBest = 0;
670
671  Double dFrameLambda;
672#if FULL_NBIT
673  Int    SHIFT_QP = 12 + 6 * (pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
674#else
675  Int    SHIFT_QP = 12;
676#endif
677
678  // set frame lambda
679  if (m_pcCfg->getGOPSize() > 1)
680  {
681    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
682  }
683  else
684  {
685    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
686  }
687  m_pcRdCost      ->setFrameLambda(dFrameLambda);
688
689  // for each QP candidate
690  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
691  {
692    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
693#if ADAPTIVE_QP_SELECTION
694    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
695#endif
696    setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdx], m_piRdPicQp    [uiQpIdx]);
697
698    // try compress
699    compressSlice   ( pcPic, true, m_pcCfg->getFastDeltaQp());
700
701#if NH_3D_VSO
702    Dist64 uiPicDist        = m_uiPicDist;
703#else
704    UInt64 uiPicDist        = m_uiPicDist; // Distortion, as calculated by compressSlice.
705    // NOTE: This distortion is the chroma-weighted SSE distortion for the slice.
706    //       Previously a standard SSE distortion was calculated (for the entire frame).
707    //       Which is correct?
708
709    // TODO: Update loop filter, SAO and distortion calculation to work on one slice only.
710    // m_pcGOPEncoder->preLoopFilterPicAll( pcPic, uiPicDist );
711
712#endif
713
714    // compute RD cost and choose the best
715#if NH_3D_VSO
716    Double dPicRdCost = m_pcRdCost->calcRdCost( (Double)m_uiPicTotalBits, uiPicDist, DF_SSE_FRAME);
717#else
718    Double dPicRdCost = m_pcRdCost->calcRdCost( (Double)m_uiPicTotalBits, (Double)uiPicDist, DF_SSE_FRAME);
719#endif
720#if H_3D
721    // Above calculation need to be fixed for VSO, including frameLambda value.
722#endif
723
724    if ( dPicRdCost < dPicRdCostBest )
725    {
726      uiQpIdxBest    = uiQpIdx;
727      dPicRdCostBest = dPicRdCost;
728    }
729  }
730
731  // set best values
732  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
733#if ADAPTIVE_QP_SELECTION
734  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
735#endif
736  setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdxBest], m_piRdPicQp    [uiQpIdxBest]);
737}
738
739Void TEncSlice::calCostSliceI(TComPic* pcPic) // TODO: this only analyses the first slice segment. What about the others?
740{
741  Double            iSumHadSlice      = 0;
742  TComSlice * const pcSlice           = pcPic->getSlice(getSliceIdx());
743  const TComSPS    &sps               = *(pcSlice->getSPS());
744  const Int         shift             = sps.getBitDepth(CHANNEL_TYPE_LUMA)-8;
745  const Int         offset            = (shift>0)?(1<<(shift-1)):0;
746
747  pcSlice->setSliceSegmentBits(0);
748
749  UInt startCtuTsAddr, boundingCtuTsAddr;
750  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );
751
752  for( UInt ctuTsAddr = startCtuTsAddr, ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
753       ctuTsAddr < boundingCtuTsAddr;
754       ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(++ctuTsAddr) )
755  {
756    // initialize CU encoder
757    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
758    pCtu->initCtu( pcPic, ctuRsAddr );
759
760    Int height  = min( sps.getMaxCUHeight(),sps.getPicHeightInLumaSamples() - ctuRsAddr / pcPic->getFrameWidthInCtus() * sps.getMaxCUHeight() );
761    Int width   = min( sps.getMaxCUWidth(), sps.getPicWidthInLumaSamples()  - ctuRsAddr % pcPic->getFrameWidthInCtus() * sps.getMaxCUWidth() );
762
763    Int iSumHad = m_pcCuEncoder->updateCtuDataISlice(pCtu, width, height);
764
765    (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra=(iSumHad+offset)>>shift;
766    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra;
767
768  }
769  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
770}
771
772/** \param pcPic   picture class
773 */
774Void TEncSlice::compressSlice( TComPic* pcPic, const Bool bCompressEntireSlice, const Bool bFastDeltaQP )
775{
776  // if bCompressEntireSlice is true, then the entire slice (not slice segment) is compressed,
777  //   effectively disabling the slice-segment-mode.
778
779  UInt   startCtuTsAddr;
780  UInt   boundingCtuTsAddr;
781  TComSlice* const pcSlice            = pcPic->getSlice(getSliceIdx());
782  pcSlice->setSliceSegmentBits(0);
783  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );
784  if (bCompressEntireSlice)
785  {
786    boundingCtuTsAddr = pcSlice->getSliceCurEndCtuTsAddr();
787    pcSlice->setSliceSegmentCurEndCtuTsAddr(boundingCtuTsAddr);
788  }
789
790  // initialize cost values - these are used by precompressSlice (they should be parameters).
791  m_uiPicTotalBits  = 0;
792  m_dPicRdCost      = 0; // NOTE: This is a write-only variable!
793  m_uiPicDist       = 0;
794
795  m_pcEntropyCoder->setEntropyCoder   ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
796  m_pcEntropyCoder->resetEntropy      ( pcSlice );
797
798  TEncBinCABAC* pRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
799  pRDSbacCoder->setBinCountingEnableFlag( false );
800  pRDSbacCoder->setBinsCoded( 0 );
801
802  TComBitCounter  tempBitCounter;
803  const UInt      frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus();
804 
805  m_pcCuEncoder->setFastDeltaQp(bFastDeltaQP);
806
807  //------------------------------------------------------------------------------
808  //  Weighted Prediction parameters estimation.
809  //------------------------------------------------------------------------------
810  // calculate AC/DC values for current picture
811  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
812  {
813    xCalcACDCParamSlice(pcSlice);
814  }
815
816  const Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
817
818  if ( bWp_explicit )
819  {
820    //------------------------------------------------------------------------------
821    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
822    //------------------------------------------------------------------------------
823    if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES )
824    {
825      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
826    }
827
828    xEstimateWPParamSlice( pcSlice, m_pcCfg->getWeightedPredictionMethod() );
829    pcSlice->initWpScaling(pcSlice->getSPS());
830
831    // check WP on/off
832    xCheckWPEnable( pcSlice );
833  }
834
835#if ADAPTIVE_QP_SELECTION
836  if( m_pcCfg->getUseAdaptQpSelect() && !(pcSlice->getDependentSliceSegmentFlag()))
837  {
838    // TODO: this won't work with dependent slices: they do not have their own QP. Check fix to mask clause execution with && !(pcSlice->getDependentSliceSegmentFlag())
839    m_pcTrQuant->clearSliceARLCnt(); // TODO: this looks wrong for multiple slices - the results of all but the last slice will be cleared before they are used (all slices compressed, and then all slices encoded)
840    if(pcSlice->getSliceType()!=I_SLICE)
841    {
842      Int qpBase = pcSlice->getSliceQpBase();
843      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
844    }
845  }
846#endif
847
848#if NH_3D_IC
849  if ( m_pcCfg->getViewIndex() && m_pcCfg->getUseIC() &&
850       !( ( pcSlice->getSliceType() == P_SLICE && pcSlice->getPPS()->getUseWP() ) || ( pcSlice->getSliceType() == B_SLICE && pcSlice->getPPS()->getWPBiPred() ) )
851     )
852  {
853    pcSlice ->xSetApplyIC(m_pcCfg->getUseICLowLatencyEnc());
854    if ( pcSlice->getApplyIC() )
855    {
856      pcSlice->setIcSkipParseFlag( pcSlice->getPOC() % m_pcCfg->getIntraPeriod() != 0 );
857    }
858  }
859#endif
860
861
862
863  // Adjust initial state if this is the start of a dependent slice.
864  {
865    const UInt      ctuRsAddr               = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
866    const UInt      currentTileIdx          = pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
867    const TComTile *pCurrentTile            = pcPic->getPicSym()->getTComTile(currentTileIdx);
868    const UInt      firstCtuRsAddrOfTile    = pCurrentTile->getFirstCtuRsAddr();
869    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
870    {
871      // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.
872      if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getEntropyCodingSyncEnabledFlag() )
873      {
874        m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState );
875      }
876    }
877  }
878
879  // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
880#if NH_3D_VSO
881  Int iLastPosY = -1;
882#endif
883
884  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
885  {
886    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
887    // initialize CTU encoder
888    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
889    pCtu->initCtu( pcPic, ctuRsAddr );
890#if NH_3D_VSO
891    if ( m_pcRdCost->getUseRenModel() )
892    {
893      // updated renderer model if necessary
894      Int iCurPosX;
895      Int iCurPosY; 
896      pCtu->getPosInPic(0, iCurPosX, iCurPosY );
897      if ( iCurPosY != iLastPosY )
898      {
899        iLastPosY = iCurPosY;         
900        TEncTop* pcEncTop = (TEncTop*) m_pcCfg; // Fix this later.
901        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() || pcSlice->getVPS()->getAuxId( pcSlice->getLayerId()  ) ? 1 : 0, iCurPosY, pcSlice->getSPS()->getMaxCUHeight() );
902      }
903    }
904#endif
905
906    // update CABAC state
907    const UInt firstCtuRsAddrOfTile = pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))->getFirstCtuRsAddr();
908    const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
909    const UInt ctuXPosInCtus  = ctuRsAddr % frameWidthInCtus;
910   
911    if (ctuRsAddr == firstCtuRsAddrOfTile)
912    {
913      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
914    }
915    else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getEntropyCodingSyncEnabledFlag())
916    {
917      // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).
918      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
919      // Sync if the Top-Right is available.
920      TComDataCU *pCtuUp = pCtu->getCtuAbove();
921      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
922      {
923        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
924        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
925        {
926          // Top-Right is available, we use it.
927          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_entropyCodingSyncContextState );
928        }
929      }
930    }
931
932    // set go-on entropy coder (used for all trial encodings - the cu encoder and encoder search also have a copy of the same pointer)
933    m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder );
934    m_pcEntropyCoder->setBitstream( &tempBitCounter );
935    tempBitCounter.resetBits();
936    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); // this copy is not strictly necessary here, but indicates that the GoOnSbacCoder
937                                                                     // is reset to a known state before every decision process.
938
939    ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
940
941    Double oldLambda = m_pcRdCost->getLambda();
942    if ( m_pcCfg->getUseRateCtrl() )
943    {
944      Int estQP        = pcSlice->getSliceQp();
945      Double estLambda = -1.0;
946      Double bpp       = -1.0;
947
948      if ( ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
949      {
950        estQP = pcSlice->getSliceQp();
951      }
952      else
953      {
954#if KWU_RC_MADPRED_E0227
955          if(pcSlice->getLayerId() != 0 && m_pcCfg->getUseDepthMADPred() && !pcSlice->getIsDepth())
956          {
957            Double zn, zf, focallength, position, camShift;
958            Double basePos;
959            Bool bInterpolated;
960            Int direction = pcSlice->getViewId() - pcCU->getSlice()->getIvPic(false, 0)->getViewId();
961            Int disparity;
962
963            pcEncTop->getCamParam()->xGetZNearZFar(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), zn, zf);
964            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[0], pcSlice->getPOC(), focallength, basePos, camShift, bInterpolated);
965            pcEncTop->getCamParam()->xGetGeometryData(pcEncTop->getCamParam()->getBaseViewNumbers()[pcSlice->getViewIndex()], pcSlice->getPOC(), focallength, position, camShift, bInterpolated);
966            bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBppforInterView( m_pcRateCtrl->getPicList(), pcCU,
967              basePos, position, focallength, zn, zf, (direction > 0 ? 1 : -1), &disparity );
968          }
969          else
970          {
971#endif
972        bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
973        if ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE)
974        {
975          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
976        }
977        else
978        {
979          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
980          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
981        }
982#if KWU_RC_MADPRED_E0227
983          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
984          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
985#endif
986
987        estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );
988
989        m_pcRdCost->setLambda(estLambda, pcSlice->getSPS()->getBitDepths());
990
991#if RDOQ_CHROMA_LAMBDA
992        // set lambda for RDOQ
993        const Double chromaLambda = estLambda / m_pcRdCost->getChromaWeight();
994        const Double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };
995        m_pcTrQuant->setLambdas( lambdaArray );
996#else
997        m_pcTrQuant->setLambda( estLambda );
998#endif
999      }
1000
1001      m_pcRateCtrl->setRCQP( estQP );
1002#if ADAPTIVE_QP_SELECTION
1003      pCtu->getSlice()->setSliceQpBase( estQP );
1004#endif
1005    }
1006
1007    // run CTU trial encoder
1008    m_pcCuEncoder->compressCtu( pCtu );
1009
1010
1011    // All CTU decisions have now been made. Restore entropy coder to an initial stage, ready to make a true encode,
1012    // which will result in the state of the contexts being correct. It will also count up the number of bits coded,
1013    // which is used if there is a limit of the number of bytes per slice-segment.
1014
1015    m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1016    m_pcEntropyCoder->setBitstream( &tempBitCounter );
1017    pRDSbacCoder->setBinCountingEnableFlag( true );
1018    m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetBits();
1019    pRDSbacCoder->setBinsCoded( 0 );
1020
1021    // encode CTU and calculate the true bit counters.
1022    m_pcCuEncoder->encodeCtu( pCtu );
1023
1024
1025    pRDSbacCoder->setBinCountingEnableFlag( false );
1026
1027    const Int numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
1028
1029    // Calculate if this CTU puts us over slice bit size.
1030    // cannot terminate if current slice/slice-segment would be 0 Ctu in size,
1031    const UInt validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0);
1032    // Set slice end parameter
1033    if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3))
1034    {
1035      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
1036      pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
1037      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
1038    }
1039    else if((!bCompressEntireSlice) && pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3))
1040    {
1041      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
1042      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
1043    }
1044
1045    if (boundingCtuTsAddr <= ctuTsAddr)
1046    {
1047      break;
1048    }
1049
1050    pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );
1051    pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits);
1052
1053    // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
1054    if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getEntropyCodingSyncEnabledFlag())
1055    {
1056      m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
1057    }
1058
1059
1060    if ( m_pcCfg->getUseRateCtrl() )
1061    {
1062#if KWU_RC_MADPRED_E0227
1063        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1064        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1065        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1066        Double MAD = (Double)SAD / (Double)(height * width);
1067        MAD = MAD * MAD;
1068        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1069#endif
1070
1071      Int actualQP        = g_RCInvalidQPValue;
1072      Double actualLambda = m_pcRdCost->getLambda();
1073      Int actualBits      = pCtu->getTotalBits();
1074      Int numberOfEffectivePixels    = 0;
1075      for ( Int idx = 0; idx < pcPic->getNumPartitionsInCtu(); idx++ )
1076      {
1077        if ( pCtu->getPredictionMode( idx ) != NUMBER_OF_PREDICTION_MODES && ( !pCtu->isSkipped( idx ) ) )
1078        {
1079          numberOfEffectivePixels = numberOfEffectivePixels + 16;
1080          break;
1081        }
1082      }
1083
1084      if ( numberOfEffectivePixels == 0 )
1085      {
1086        actualQP = g_RCInvalidQPValue;
1087      }
1088      else
1089      {
1090        actualQP = pCtu->getQP( 0 );
1091      }
1092      m_pcRdCost->setLambda(oldLambda, pcSlice->getSPS()->getBitDepths());
1093      m_pcRateCtrl->getRCPic()->updateAfterCTU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
1094                                                pCtu->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1095    }
1096
1097    m_uiPicTotalBits += pCtu->getTotalBits();
1098    m_dPicRdCost     += pCtu->getTotalCost();
1099    m_uiPicDist      += pCtu->getTotalDistortion();
1100  }
1101
1102  // store context state at the end of this slice-segment, in case the next slice is a dependent slice and continues using the CABAC contexts.
1103  if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() )
1104  {
1105    m_lastSliceSegmentEndContextState.loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1106  }
1107
1108  // stop use of temporary bit counter object.
1109  m_pppcRDSbacCoder[0][CI_CURR_BEST]->setBitstream(NULL);
1110  m_pcRDGoOnSbacCoder->setBitstream(NULL); // stop use of tempBitCounter.
1111
1112  // TODO: optimise cabac_init during compress slice to improve multi-slice operation
1113  //if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1114  //{
1115  //  m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx();
1116  //}
1117  //else
1118  //{
1119  //  m_encCABACTableIdx = pcSlice->getSliceType();
1120  //}
1121}
1122
1123Void TEncSlice::encodeSlice   ( TComPic* pcPic, TComOutputBitstream* pcSubstreams, UInt &numBinsCoded )
1124{
1125  TComSlice *const pcSlice           = pcPic->getSlice(getSliceIdx());
1126
1127  const UInt startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1128  const UInt boundingCtuTsAddr       = pcSlice->getSliceSegmentCurEndCtuTsAddr();
1129
1130  const UInt frameWidthInCtus        = pcPic->getPicSym()->getFrameWidthInCtus();
1131  const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1132  const Bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
1133
1134  // initialise entropy coder for the slice
1135  m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1136  m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder );
1137  m_pcEntropyCoder->resetEntropy    ( pcSlice );
1138
1139  numBinsCoded = 0;
1140  m_pcBinCABAC->setBinCountingEnableFlag( true );
1141  m_pcBinCABAC->setBinsCoded(0);
1142
1143#if ENC_DEC_TRACE
1144  g_bJustDoIt = g_bEncDecTraceEnable;
1145#endif
1146#if NH_MV_ENC_DEC_TRAC
1147#if ENC_DEC_TRACE
1148  incSymbolCounter();
1149#endif
1150  DTRACE_CABAC_VL( g_nSymbolCounter );
1151#else
1152  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1153#endif
1154  DTRACE_CABAC_T( "\tPOC: " );
1155  DTRACE_CABAC_V( pcPic->getPOC() );
1156#if NH_MV_ENC_DEC_TRAC
1157  DTRACE_CABAC_T( " Layer: " );
1158  DTRACE_CABAC_V( pcPic->getLayerId() );
1159#endif
1160  DTRACE_CABAC_T( "\n" );
1161#if ENC_DEC_TRACE
1162  g_bJustDoIt = g_bEncDecTraceDisable;
1163#endif
1164
1165
1166  if (depSliceSegmentsEnabled)
1167  {
1168    // modify initial contexts with previous slice segment if this is a dependent slice.
1169    const UInt ctuRsAddr        = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr );
1170    const UInt currentTileIdx=pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
1171    const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(currentTileIdx);
1172    const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();
1173
1174    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
1175    {
1176      if( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled )
1177      {
1178        m_pcSbacCoder->loadContexts(&m_lastSliceSegmentEndContextState);
1179      }
1180    }
1181  }
1182
1183  // for every CTU in the slice segment...
1184
1185  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
1186  {
1187    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
1188    const TComTile &currentTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr)));
1189    const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
1190    const UInt tileXPosInCtus       = firstCtuRsAddrOfTile % frameWidthInCtus;
1191    const UInt tileYPosInCtus       = firstCtuRsAddrOfTile / frameWidthInCtus;
1192    const UInt ctuXPosInCtus        = ctuRsAddr % frameWidthInCtus;
1193    const UInt ctuYPosInCtus        = ctuRsAddr / frameWidthInCtus;
1194    const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice);
1195    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
1196
1197    m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1198
1199    // set up CABAC contexts' state for this CTU
1200    if (ctuRsAddr == firstCtuRsAddrOfTile)
1201    {
1202      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1203      {
1204        m_pcEntropyCoder->resetEntropy(pcSlice);
1205      }
1206    }
1207    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
1208    {
1209      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
1210      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1211      {
1212        m_pcEntropyCoder->resetEntropy(pcSlice);
1213      }
1214      TComDataCU *pCtuUp = pCtu->getCtuAbove();
1215      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
1216      {
1217        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
1218        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
1219        {
1220          // Top-right is available, so use it.
1221          m_pcSbacCoder->loadContexts( &m_entropyCodingSyncContextState );
1222        }
1223      }
1224    }
1225
1226#if NH_3D_QTLPC
1227    pcPic->setReduceBitsFlag(true);
1228#endif
1229    if ( pcSlice->getSPS()->getUseSAO() )
1230    {
1231      Bool bIsSAOSliceEnabled = false;
1232      Bool sliceEnabled[MAX_NUM_COMPONENT];
1233      for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
1234      {
1235        ComponentID compId=ComponentID(comp);
1236        sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents());
1237        if (sliceEnabled[compId])
1238        {
1239          bIsSAOSliceEnabled=true;
1240        }
1241      }
1242      if (bIsSAOSliceEnabled)
1243      {
1244        SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr];
1245
1246        Bool leftMergeAvail = false;
1247        Bool aboveMergeAvail= false;
1248        //merge left condition
1249        Int rx = (ctuRsAddr % frameWidthInCtus);
1250        if(rx > 0)
1251        {
1252          leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1);
1253        }
1254
1255        //merge up condition
1256        Int ry = (ctuRsAddr / frameWidthInCtus);
1257        if(ry > 0)
1258        {
1259          aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus);
1260        }
1261
1262        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, pcPic->getPicSym()->getSPS().getBitDepths(), sliceEnabled, leftMergeAvail, aboveMergeAvail);
1263      }
1264    }
1265
1266#if ENC_DEC_TRACE
1267    g_bJustDoIt = g_bEncDecTraceEnable;
1268#endif
1269      m_pcCuEncoder->encodeCtu( pCtu );
1270#if ENC_DEC_TRACE
1271    g_bJustDoIt = g_bEncDecTraceDisable;
1272#endif
1273
1274    //Store probabilities of second CTU in line into buffer
1275    if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled)
1276    {
1277      m_entropyCodingSyncContextState.loadContexts( m_pcSbacCoder );
1278    }
1279
1280    // terminate the sub-stream, if required (end of slice-segment, end of tile, end of wavefront-CTU-row):
1281    if (ctuTsAddr+1 == boundingCtuTsAddr ||
1282         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() &&
1283          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled)
1284         )
1285       )
1286    {
1287      m_pcEntropyCoder->encodeTerminatingBit(1);
1288      m_pcEntropyCoder->encodeSliceFinish();
1289      // Byte-alignment in slice_data() when new tile
1290      pcSubstreams[uiSubStrm].writeByteAlignment();
1291
1292      // write sub-stream size
1293      if (ctuTsAddr+1 != boundingCtuTsAddr)
1294      {
1295        pcSlice->addSubstreamSize( (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations() );
1296      }
1297    }
1298#if NH_3D_QTLPC
1299    pcPic->setReduceBitsFlag(false);
1300#endif
1301  } // CTU-loop
1302
1303  if( depSliceSegmentsEnabled )
1304  {
1305    m_lastSliceSegmentEndContextState.loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1306  }
1307
1308#if ADAPTIVE_QP_SELECTION
1309  if( m_pcCfg->getUseAdaptQpSelect() )
1310  {
1311    m_pcTrQuant->storeSliceQpNext(pcSlice); // TODO: this will only be storing the adaptive QP state of the very last slice-segment that is not dependent in the frame... Perhaps this should be moved to the compress slice loop.
1312  }
1313#endif
1314
1315  if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1316  {
1317    m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx(pcSlice);
1318  }
1319  else
1320  {
1321    m_encCABACTableIdx = pcSlice->getSliceType();
1322  }
1323 
1324  numBinsCoded = m_pcBinCABAC->getBinsCoded();
1325}
1326
1327Void TEncSlice::calculateBoundingCtuTsAddrForSlice(UInt &startCtuTSAddrSlice, UInt &boundingCtuTSAddrSlice, Bool &haveReachedTileBoundary,
1328                                                   TComPic* pcPic, const Int sliceMode, const Int sliceArgument)
1329{
1330  TComSlice* pcSlice = pcPic->getSlice(getSliceIdx());
1331  const UInt numberOfCtusInFrame = pcPic->getNumberOfCtusInFrame();
1332  const TComPPS &pps=*(pcSlice->getPPS());
1333  boundingCtuTSAddrSlice=0;
1334  haveReachedTileBoundary=false;
1335
1336  switch (sliceMode)
1337  {
1338    case FIXED_NUMBER_OF_CTU:
1339      {
1340        UInt ctuAddrIncrement    = sliceArgument;
1341        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1342      }
1343      break;
1344    case FIXED_NUMBER_OF_BYTES:
1345      boundingCtuTSAddrSlice  = numberOfCtusInFrame; // This will be adjusted later if required.
1346      break;
1347    case FIXED_NUMBER_OF_TILES:
1348      {
1349        const UInt tileIdx        = pcPic->getPicSym()->getTileIdxMap( pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice) );
1350        const UInt tileTotalCount = (pcPic->getPicSym()->getNumTileColumnsMinus1()+1) * (pcPic->getPicSym()->getNumTileRowsMinus1()+1);
1351        UInt ctuAddrIncrement   = 0;
1352
1353        for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++)
1354        {
1355          if((tileIdx + tileIdxIncrement) < tileTotalCount)
1356          {
1357            UInt tileWidthInCtus   = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidthInCtus();
1358            UInt tileHeightInCtus  = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeightInCtus();
1359            ctuAddrIncrement    += (tileWidthInCtus * tileHeightInCtus);
1360          }
1361        }
1362
1363        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1364      }
1365      break;
1366    default:
1367      boundingCtuTSAddrSlice    = numberOfCtusInFrame;
1368      break;
1369  }
1370
1371  // Adjust for tiles and wavefronts.
1372  const Bool wavefrontsAreEnabled = pps.getEntropyCodingSyncEnabledFlag();
1373
1374  if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) &&
1375      (pps.getNumTileRowsMinus1() > 0 || pps.getNumTileColumnsMinus1() > 0))
1376  {
1377    const UInt ctuRSAddr                  = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice);
1378    const UInt startTileIdx               = pcPic->getPicSym()->getTileIdxMap(ctuRSAddr);
1379
1380    const TComTile *pStartingTile         = pcPic->getPicSym()->getTComTile(startTileIdx);
1381    const UInt tileStartTsAddr            = pcPic->getPicSym()->getCtuRsToTsAddrMap(pStartingTile->getFirstCtuRsAddr());
1382    const UInt tileStartWidth             = pStartingTile->getTileWidthInCtus();
1383    const UInt tileStartHeight            = pStartingTile->getTileHeightInCtus();
1384    const UInt tileLastTsAddr_excl        = tileStartTsAddr + tileStartWidth*tileStartHeight;
1385    const UInt tileBoundingCtuTsAddrSlice = tileLastTsAddr_excl;
1386
1387    const UInt ctuColumnOfStartingTile    = ((startCtuTSAddrSlice-tileStartTsAddr)%tileStartWidth);
1388    if (wavefrontsAreEnabled && ctuColumnOfStartingTile!=0)
1389    {
1390      // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1391      const UInt numberOfCTUsToEndOfRow            = tileStartWidth - ctuColumnOfStartingTile;
1392      const UInt wavefrontTileBoundingCtuAddrSlice = startCtuTSAddrSlice + numberOfCTUsToEndOfRow;
1393      if (wavefrontTileBoundingCtuAddrSlice < boundingCtuTSAddrSlice)
1394      {
1395        boundingCtuTSAddrSlice = wavefrontTileBoundingCtuAddrSlice;
1396      }
1397    }
1398
1399    if (tileBoundingCtuTsAddrSlice < boundingCtuTSAddrSlice)
1400    {
1401      boundingCtuTSAddrSlice = tileBoundingCtuTsAddrSlice;
1402      haveReachedTileBoundary = true;
1403    }
1404  }
1405  else if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) && wavefrontsAreEnabled && ((startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) != 0))
1406  {
1407    // Adjust for wavefronts (no tiles).
1408    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1409    boundingCtuTSAddrSlice = min(boundingCtuTSAddrSlice, startCtuTSAddrSlice - (startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) + (pcPic->getFrameWidthInCtus()));
1410  }
1411}
1412
1413/** Determines the starting and bounding CTU address of current slice / dependent slice
1414 * \param [out] startCtuTsAddr
1415 * \param [out] boundingCtuTsAddr
1416 * \param [in]  pcPic
1417
1418 * Updates startCtuTsAddr, boundingCtuTsAddr with appropriate CTU address
1419 */
1420Void TEncSlice::xDetermineStartAndBoundingCtuTsAddr  ( UInt& startCtuTsAddr, UInt& boundingCtuTsAddr, TComPic* pcPic )
1421{
1422  TComSlice* pcSlice                 = pcPic->getSlice(getSliceIdx());
1423
1424  // Non-dependent slice
1425  UInt startCtuTsAddrSlice           = pcSlice->getSliceCurStartCtuTsAddr();
1426  Bool haveReachedTileBoundarySlice  = false;
1427  UInt boundingCtuTsAddrSlice;
1428  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSlice, boundingCtuTsAddrSlice, haveReachedTileBoundarySlice, pcPic,
1429                                     m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument());
1430  pcSlice->setSliceCurEndCtuTsAddr(   boundingCtuTsAddrSlice );
1431  pcSlice->setSliceCurStartCtuTsAddr( startCtuTsAddrSlice    );
1432
1433  // Dependent slice
1434  UInt startCtuTsAddrSliceSegment          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1435  Bool haveReachedTileBoundarySliceSegment = false;
1436  UInt boundingCtuTsAddrSliceSegment;
1437  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSliceSegment, boundingCtuTsAddrSliceSegment, haveReachedTileBoundarySliceSegment, pcPic,
1438                                     m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument());
1439  if (boundingCtuTsAddrSliceSegment>boundingCtuTsAddrSlice)
1440  {
1441    boundingCtuTsAddrSliceSegment = boundingCtuTsAddrSlice;
1442  }
1443  pcSlice->setSliceSegmentCurEndCtuTsAddr( boundingCtuTsAddrSliceSegment );
1444  pcSlice->setSliceSegmentCurStartCtuTsAddr(startCtuTsAddrSliceSegment);
1445
1446  // Make a joint decision based on reconstruction and dependent slice bounds
1447  startCtuTsAddr    = max(startCtuTsAddrSlice   , startCtuTsAddrSliceSegment   );
1448  boundingCtuTsAddr = boundingCtuTsAddrSliceSegment;
1449}
1450
1451Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1452{
1453  return 4.2005*log(lambda) + 13.7122;
1454}
1455
1456//! \}
Note: See TracBrowser for help on using the repository browser.