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

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

Merged 14.1-update-dev1@1312.

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