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

Last change on this file since 1403 was 1403, checked in by tech, 9 years ago

Fixes.

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