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

Last change on this file since 375 was 332, checked in by tech, 12 years ago

Merged branch 6.1-Cleanup@329.

  • Property svn:eol-style set to native
File size: 58.9 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
[56]4 * granted under this license. 
[5]5 *
[56]6 * Copyright (c) 2010-2012, 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"
[100]40#include "../../App/TAppEncoder/TAppEncTop.h"
[56]41#include <math.h>
[2]42
[56]43//! \ingroup TLibEncoder
44//! \{
45
[2]46// ====================================================================================================================
47// Constructor / destructor / create / destroy
48// ====================================================================================================================
49
50TEncSlice::TEncSlice()
51{
52  m_apcPicYuvPred = NULL;
53  m_apcPicYuvResi = NULL;
[56]54 
[2]55  m_pdRdPicLambda = NULL;
56  m_pdRdPicQp     = NULL;
57  m_piRdPicQp     = NULL;
[56]58  m_pcBufferSbacCoders    = NULL;
59  m_pcBufferBinCoderCABACs  = NULL;
60  m_pcBufferLowLatSbacCoders    = NULL;
61  m_pcBufferLowLatBinCoderCABACs  = NULL;
[313]62#if FCO_DVP_REFINE_C0132_C0170
63  m_pPicBaseTxt = NULL;
64  m_pPicBaseDepth = NULL;
65#endif
[2]66}
67
68TEncSlice::~TEncSlice()
69{
70}
71
72Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
73{
74  // create prediction picture
75  if ( m_apcPicYuvPred == NULL )
76  {
77    m_apcPicYuvPred  = new TComPicYuv;
78    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
79  }
[56]80 
[2]81  // create residual picture
82  if( m_apcPicYuvResi == NULL )
83  {
84    m_apcPicYuvResi  = new TComPicYuv;
85    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
86  }
87}
88
89Void TEncSlice::destroy()
90{
91  // destroy prediction picture
92  if ( m_apcPicYuvPred )
93  {
94    m_apcPicYuvPred->destroy();
95    delete m_apcPicYuvPred;
96    m_apcPicYuvPred  = NULL;
97  }
[56]98 
[2]99  // destroy residual picture
100  if ( m_apcPicYuvResi )
101  {
102    m_apcPicYuvResi->destroy();
103    delete m_apcPicYuvResi;
104    m_apcPicYuvResi  = NULL;
105  }
[56]106 
[2]107  // free lambda and QP arrays
108  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
109  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
110  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
[56]111
112  if ( m_pcBufferSbacCoders )
113  {
114    delete[] m_pcBufferSbacCoders;
115  }
116  if ( m_pcBufferBinCoderCABACs )
117  {
118    delete[] m_pcBufferBinCoderCABACs;
119  }
120  if ( m_pcBufferLowLatSbacCoders )
121    delete[] m_pcBufferLowLatSbacCoders;
122  if ( m_pcBufferLowLatBinCoderCABACs )
123    delete[] m_pcBufferLowLatBinCoderCABACs;
[2]124}
125
126Void TEncSlice::init( TEncTop* pcEncTop )
127{
128  m_pcCfg             = pcEncTop;
129  m_pcListPic         = pcEncTop->getListPic();
[56]130 
131  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
[2]132  m_pcCuEncoder       = pcEncTop->getCuEncoder();
133  m_pcPredSearch      = pcEncTop->getPredSearch();
[56]134 
[2]135  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
136  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
137  m_pcSbacCoder       = pcEncTop->getSbacCoder();
138  m_pcBinCABAC        = pcEncTop->getBinCABAC();
139  m_pcTrQuant         = pcEncTop->getTrQuant();
[56]140 
[2]141  m_pcBitCounter      = pcEncTop->getBitCounter();
142  m_pcRdCost          = pcEncTop->getRdCost();
143  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
144  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
[56]145 
[2]146  // create lambda and QP arrays
147  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
148  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
149  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
150}
151
152/**
153 - non-referenced frame marking
154 - QP computation based on temporal structure
155 - lambda computation based on QP
[56]156 - set temporal layer ID and the parameter sets
[2]157 .
158 \param pcPic         picture class
159 \param iPOCLast      POC of last picture
160 \param uiPOCCurr     current POC
161 \param iNumPicRcvd   number of received pictures
162 \param iTimeOffset   POC offset for hierarchical structure
163 \param iDepth        temporal layer depth
164 \param rpcSlice      slice header class
[56]165 \param pSPS          SPS associated with the slice
166 \param pPPS          PPS associated with the slice
[2]167 */
[210]168#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
[296]169#if MTK_DEPTH_MERGE_TEXTURE_CANDIDATE_C0137
170Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS * pVPS, TComSPS* pSPS, TComPPS *pPPS, bool isDepth )
171#else
[77]172Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS * pVPS, TComSPS* pSPS, TComPPS *pPPS )
[296]173#endif
[77]174#else
[56]175Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
[77]176#endif
[2]177{
178  Double dQP;
179  Double dLambda;
[56]180 
[2]181  rpcSlice = pcPic->getSlice(0);
[210]182#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
[77]183  rpcSlice->setVPS( pVPS );
184#endif
[56]185  rpcSlice->setSPS( pSPS );
186  rpcSlice->setPPS( pPPS );
[2]187  rpcSlice->setSliceBits(0);
188  rpcSlice->setPic( pcPic );
189  rpcSlice->initSlice();
[56]190  rpcSlice->initTiles();
191  rpcSlice->setPicOutputFlag( true );
192  rpcSlice->setPOC( uiPOCCurr );
193 
[296]194#if INTER_VIEW_VECTOR_SCALING_C0115
195  rpcSlice->setViewOrderIdx(m_pcCfg->getViewOrderIdx());    // will be changed to view_id
[21]196#endif
[189]197#if LGE_ILLUCOMP_B0045
198  rpcSlice->setApplyIC(false);
199#endif
[56]200  // set mutliview parameters
201  rpcSlice->initMultiviewSlice( pcPic->getCodedScale(), pcPic->getCodedOffset() );
202
203  // depth computation based on GOP size
204  int iDepth;
205  {
206    Int i, j;
207    Int iPOC = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
208    if ( iPOC == 0 )
209    {
210      iDepth = 0;
211    }
212    else
213    {
214      Int iStep = m_pcCfg->getGOPSize();
215      iDepth    = 0;
216      for( i=iStep>>1; i>=1; i>>=1 )
217      {
218        for ( j=i; j<m_pcCfg->getGOPSize(); j+=iStep )
219        {
220          if ( j == iPOC )
221          {
222            i=0;
223            break;
224          }
225        }
226        iStep>>=1;
227        iDepth++;
228      }
229    }
230  }
231 
[2]232  // slice type
[56]233  SliceType eSliceTypeBaseView;
234  if( iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0 )
235  {
236    eSliceTypeBaseView = I_SLICE;
237  }
238  else
239  {
240    eSliceTypeBaseView = B_SLICE;
241  }
242  SliceType eSliceType = eSliceTypeBaseView;
243  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
244  {
245    eSliceType = B_SLICE; 
246  }
247  rpcSlice->setSliceType( eSliceType );
248 
[2]249  // ------------------------------------------------------------------------------------------------------------------
250  // Non-referenced frame marking
251  // ------------------------------------------------------------------------------------------------------------------
[56]252  rpcSlice->setReferenced( m_pcCfg->getGOPEntry(iGOPid).m_refPic );
253  if( eSliceTypeBaseView == I_SLICE )
254  {
255    rpcSlice->setReferenced(true);
256  }
257 
[2]258  // ------------------------------------------------------------------------------------------------------------------
259  // QP setting
260  // ------------------------------------------------------------------------------------------------------------------
[56]261 
262  dQP = m_pcCfg->getQP();
263  if( eSliceType != I_SLICE )
264  {
265#if LOSSLESS_CODING
266    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
267#endif
268    {
269    dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset;
270    }
271  }
272 
273  // modify QP
274  Int* pdQPs = m_pcCfg->getdQPs();
275  if ( pdQPs )
276  {
277    dQP += pdQPs[ rpcSlice->getPOC() ];
278  }
279 
[2]280  // ------------------------------------------------------------------------------------------------------------------
281  // Lambda computation
282  // ------------------------------------------------------------------------------------------------------------------
[56]283 
[2]284  Int iQP;
[56]285  Double dOrigQP = dQP;
[2]286
287  // pre-compute lambda and QP values for all possible QP candidates
288  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
289  {
290    // compute QP value
291    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
[56]292   
[2]293    // compute lambda value
[56]294    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
[2]295    Int    SHIFT_QP = 12;
296    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
297#if FULL_NBIT
298    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
299#else
300    Int    bitdepth_luma_qp_scale = 0;
301#endif
[56]302    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
[2]303#if FULL_NBIT
[56]304    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
[2]305#endif
306    // Case #1: I or P-slices (key-frame)
[56]307    Double dQPFactor;
308    if( eSliceType != I_SLICE ) 
[2]309    {
[56]310      dQPFactor = m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPFactor;
[2]311    }
[56]312    else
[2]313    {
[56]314      dQPFactor = 0.57 * dLambda_scale;
315    }
316
317    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
318
319    if ( iDepth>0 )
320    {
[2]321#if FULL_NBIT
322        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
323#else
324        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
325#endif
326    }
[56]327   
[2]328    // if hadamard is used in ME process
[56]329    if ( !m_pcCfg->getUseHADME() )
330    {
331      dLambda *= 0.95;
332    }
333   
334    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
[5]335
[2]336    m_pdRdPicLambda[iDQpIdx] = dLambda;
337    m_pdRdPicQp    [iDQpIdx] = dQP;
338    m_piRdPicQp    [iDQpIdx] = iQP;
339  }
[56]340 
[2]341  // obtain dQP = 0 case
342  dLambda = m_pdRdPicLambda[0];
343  dQP     = m_pdRdPicQp    [0];
344  iQP     = m_piRdPicQp    [0];
[56]345 
346  if( rpcSlice->getSliceType( ) != I_SLICE )
347  {
348    dLambda *= m_pcCfg->getLambdaModifier( iDepth );
349  }
[5]350
[2]351  // store lambda
[56]352  m_pcRdCost ->setLambda( dLambda );
353#if WEIGHTED_CHROMA_DISTORTION
354// for RDO
355  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
356  Double weight = 1.0;
357  if(iQP >= 0)
358  {
359    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
360  }
361  m_pcRdCost ->setChromaDistortionWeight( weight );     
362#endif
363
[5]364#if HHI_VSO
365  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->isDepthCoder()  );
366  m_pcRdCost->setLambdaVSO( dLambda * m_pcCfg->getLambdaScaleVSO() );
367#endif
[2]368
[102]369#if SAIT_VSO_EST_A0033
370  m_pcRdCost->setDisparityCoeff( m_pcCfg->getDispCoeff() );
371#endif
[115]372#if LGE_WVSO_A0119
[120]373  if( m_pcCfg->getUseWVSO() && m_pcCfg->isDepthCoder() )
[115]374  {
[102]375
[115]376    Int iDWeight, iVSOWeight, iVSDWeight;
377    iDWeight = m_pcCfg->getDWeight();
378    iVSOWeight = m_pcCfg->getVSOWeight();
379    iVSDWeight = m_pcCfg->getVSDWeight();
380
381    m_pcRdCost->setDWeight( iDWeight );
382    m_pcRdCost->setVSOWeight( iVSOWeight );
383    m_pcRdCost->setVSDWeight( iVSDWeight );
384
385  }
386#endif
[56]387#if RDOQ_CHROMA_LAMBDA
388// for RDOQ
389  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
390#else
391  m_pcTrQuant->setLambda( dLambda );
392#endif
393
394#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
395// For ALF or SAO
396  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
397#else
398  rpcSlice   ->setLambda( dLambda );
399#endif
400 
[296]401#if H3D_IVMP
[2]402  m_pcRdCost ->setLambdaMVReg ( dLambda * m_pcCfg->getMultiviewMvRegLambdaScale() );
[5]403#endif
[56]404 
405#if HB_LAMBDA_FOR_LDC
406  // restore original slice type
407  eSliceType = eSliceTypeBaseView;
408  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
409  {
410    eSliceType = B_SLICE;
411  }
412  rpcSlice->setSliceType( eSliceType );
413#endif
414 
[2]415  rpcSlice->setSliceQp          ( iQP );
[56]416#if ADAPTIVE_QP_SELECTION
417  rpcSlice->setSliceQpBase      ( iQP );
418#endif
[2]419  rpcSlice->setSliceQpDelta     ( 0 );
[56]420  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
421  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
422 
423  rpcSlice->setLoopFilterOffsetInAPS( m_pcCfg->getLoopFilterOffsetInAPS() );
424  if (rpcSlice->getPPS()->getDeblockingFilterControlPresent())
425  {
426    rpcSlice->setInheritDblParamFromAPS( m_pcCfg->getLoopFilterOffsetInAPS() ? 1 : 0 );
427    rpcSlice->setLoopFilterDisable( m_pcCfg->getLoopFilterDisable() );
428    if ( !rpcSlice->getLoopFilterDisable())
429    {
430      rpcSlice->setLoopFilterBetaOffset( m_pcCfg->getLoopFilterBetaOffset() );
431      rpcSlice->setLoopFilterTcOffset( m_pcCfg->getLoopFilterTcOffset() );
432    }
433  }
[5]434
[56]435  rpcSlice->setDepth            ( iDepth );
436 
437  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
438  if( eSliceType == I_SLICE )
439  {
440    pcPic->setTLayer(0);
441  }
442  rpcSlice->setTLayer( pcPic->getTLayer() );
[5]443
[2]444  assert( m_apcPicYuvPred );
445  assert( m_apcPicYuvResi );
[56]446 
[2]447  pcPic->setPicYuvPred( m_apcPicYuvPred );
448  pcPic->setPicYuvResi( m_apcPicYuvResi );
449  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
450  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
451  rpcSlice->setEntropySliceMode     ( m_pcCfg->getEntropySliceMode()     );
452  rpcSlice->setEntropySliceArgument ( m_pcCfg->getEntropySliceArgument() );
[56]453
[296]454#if ( HHI_MPI || H3D_IVMP )
455  #if ( HHI_MPI && H3D_IVMP )
[56]456  const int iExtraMergeCandidates = ( pSPS->getUseMVI() || pSPS->getMultiviewMvPredMode() ) ? 1 : 0;
457  #elif HHI_MPI
458  const int iExtraMergeCandidates = pSPS->getUseMVI() ? 1 : 0;
[296]459  #elif MTK_DEPTH_MERGE_TEXTURE_CANDIDATE_C0137
460  const int iExtraMergeCandidates = ( isDepth || pSPS->getMultiviewMvPredMode() ) ? 1 : 0;
[56]461  #else
462  const int iExtraMergeCandidates = pSPS->getMultiviewMvPredMode() ? 1 : 0;
463  #endif
464  rpcSlice->setMaxNumMergeCand      (MRG_MAX_NUM_CANDS_SIGNALED+iExtraMergeCandidates);
465#else
466  rpcSlice->setMaxNumMergeCand      (MRG_MAX_NUM_CANDS_SIGNALED);
467#endif
468  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPredIdc() );
[2]469}
470
471// ====================================================================================================================
472// Public member functions
473// ====================================================================================================================
474
475Void TEncSlice::setSearchRange( TComSlice* pcSlice )
476{
477  Int iCurrPOC = pcSlice->getPOC();
478  Int iRefPOC;
[56]479  Int iGOPSize = m_pcCfg->getGOPSize();
480  Int iOffset = (iGOPSize >> 1);
[2]481  Int iMaxSR = m_pcCfg->getSearchRange();
482  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
[56]483 
[2]484  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
485  {
486    RefPicList e = (RefPicList)iDir;
487    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
488    {
489      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
[56]490      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
[2]491      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
492    }
493  }
494}
495
496/**
497 - multi-loop slice encoding for different slice QP
498 .
499 \param rpcPic    picture class
500 */
501Void TEncSlice::precompressSlice( TComPic*& rpcPic )
502{
503  // if deltaQP RD is not used, simply return
[56]504  if ( m_pcCfg->getDeltaQpRD() == 0 )
505  {
506    return;
507  }
508 
[2]509  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
510  Double     dPicRdCostBest = MAX_DOUBLE;
511  UInt       uiQpIdxBest = 0;
[56]512 
[2]513  Double dFrameLambda;
514#if FULL_NBIT
515  Int    SHIFT_QP = 12 + 6 * (g_uiBitDepth - 8);
516#else
517  Int    SHIFT_QP = 12;
518#endif
[56]519 
[2]520  // set frame lambda
521  if (m_pcCfg->getGOPSize() > 1)
522  {
523    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
524  }
525  else
526  {
527    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
528  }
529  m_pcRdCost      ->setFrameLambda(dFrameLambda);
[56]530 
[2]531  // for each QP candidate
532  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
533  {
534    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
[56]535#if ADAPTIVE_QP_SELECTION
536    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
537#endif
[2]538    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
[56]539#if WEIGHTED_CHROMA_DISTORTION
540    // for RDO
541    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
542    int iQP = m_piRdPicQp    [uiQpIdx];
543    Double weight = 1.0;
544    if(iQP >= 0)
545    {
546      weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
547    }
548    m_pcRdCost    ->setChromaDistortionWeight( weight );     
549#endif
550
551#if RDOQ_CHROMA_LAMBDA
552    // for RDOQ
553    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
554#else
[2]555    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
[56]556#endif
557#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
558    // For ALF or SAO
559    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
560#else
[2]561    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
[56]562#endif
[296]563#if H3D_IVMP
[2]564    m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdx] * m_pcCfg->getMultiviewMvRegLambdaScale() );
[5]565#endif
[56]566   
[2]567    // try compress
568    compressSlice   ( rpcPic );
[56]569   
[2]570    Double dPicRdCost;
571    UInt64 uiPicDist        = m_uiPicDist;
572    UInt64 uiALFBits        = 0;
[56]573   
574    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
575   
[2]576    // compute RD cost and choose the best
577    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
[56]578   
[2]579    if ( dPicRdCost < dPicRdCostBest )
580    {
581      uiQpIdxBest    = uiQpIdx;
582      dPicRdCostBest = dPicRdCost;
583    }
584  }
[56]585 
[2]586  // set best values
587  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
[56]588#if ADAPTIVE_QP_SELECTION
589  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
590#endif
[2]591  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
[56]592#if WEIGHTED_CHROMA_DISTORTION
593  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
594  int iQP = m_piRdPicQp    [uiQpIdxBest];
595  Double weight = 1.0;
596  if(iQP >= 0)
597  {
598    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
599  }
600  m_pcRdCost ->setChromaDistortionWeight( weight );     
601#endif
602
603#if RDOQ_CHROMA_LAMBDA
604  // for RDOQ
605  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
606#else
[2]607  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
[56]608#endif
609#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
610  // For ALF or SAO
611  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
612#else
[2]613  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
[56]614#endif
[296]615#if H3D_IVMP
[2]616  m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdxBest] * m_pcCfg->getMultiviewMvRegLambdaScale() );
[5]617#endif
[2]618}
619
620/** \param rpcPic   picture class
621 */
622Void TEncSlice::compressSlice( TComPic*& rpcPic )
623{
624  UInt  uiCUAddr;
625  UInt   uiStartCUAddr;
626  UInt   uiBoundingCUAddr;
[56]627  rpcPic->getSlice(getSliceIdx())->setEntropySliceCounter(0);
[2]628  TEncBinCABAC* pppcRDSbacCoder = NULL;
629  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
630  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
[189]631#if LG_ZEROINTRADEPTHRESI_A0087
[100]632  rpcPic->setIntraPeriod(this->m_pcCfg->getIntraPeriod());
633#endif
[56]634 
[2]635  // initialize cost values
636  m_uiPicTotalBits  = 0;
637  m_dPicRdCost      = 0;
638  m_uiPicDist       = 0;
[56]639 
[189]640#if CABAC_INIT_FLAG && FIX_POZNAN_CABAC_INIT_FLAG
[101]641  Bool bReset =(pcSlice->getPOC() == 0) || 
642    (pcSlice->getPOC() % m_pcCfg->getIntraPeriod() == 0) ||
643    (pcSlice->getPPS()->getEncPrevPOC() % m_pcCfg->getIntraPeriod() == 0) ||
644    (pcSlice->getPOC()/m_pcCfg->getIntraPeriod() > pcSlice->getPPS()->getEncPrevPOC()/m_pcCfg->getIntraPeriod()) ||
645    (m_pcGOPEncoder->getGOPSize() == 0);
646
647  if ( bReset && pcSlice->getPPS()->getCabacInitPresentFlag())
648  {
649    pcSlice->getPPS()->setEncCABACTableIdx(pcSlice->getSliceType()); // reset cabac initialization table index
650  };
651#endif
652
[2]653  // set entropy coder
654  if( m_pcCfg->getUseSBACRD() )
655  {
656    m_pcSbacCoder->init( m_pcBinCABAC );
657    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
658    m_pcEntropyCoder->resetEntropy      ();
659    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
660    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
661    pppcRDSbacCoder->setBinCountingEnableFlag( false );
662    pppcRDSbacCoder->setBinsCoded( 0 );
663  }
664  else
665  {
666    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
667    m_pcEntropyCoder->resetEntropy      ();
668    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
669  }
[56]670 
671  //------------------------------------------------------------------------------
672  //  Weighted Prediction parameters estimation.
673  //------------------------------------------------------------------------------
674  // calculate AC/DC values for current picture
675  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPredIdc() )
676  {
677    xCalcACDCParamSlice(pcSlice);
678  }
[313]679#if FIX_LGE_WP_FOR_3D_C0223
680  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc());
[5]681
[313]682  if ( bWp_explicit )
683  {
684    //------------------------------------------------------------------------------
685    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
686    //------------------------------------------------------------------------------
687    if ( pcSlice->getSliceMode()==2 || pcSlice->getEntropySliceMode()==2 )
688    {
689      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
690    }
691    xEstimateWPParamSlice( pcSlice );
692    pcSlice->initWpScaling();
693#if !FIX_LGE_WP_FOR_3D_C0223 // Interim fix for encoder/decoder mismatch of non-fade sequence
694    // check WP on/off
695    xCheckWPEnable( pcSlice );
696#endif
697  }
698#else
699
[56]700  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==1);
701  Bool bWp_implicit = (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==2);
702
703  if ( bWp_explicit || bWp_implicit )
704  {
705    //------------------------------------------------------------------------------
706    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
707    //------------------------------------------------------------------------------
708    if ( pcSlice->getSliceMode()==2 || pcSlice->getEntropySliceMode()==2 )
709    {
710      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
711    }
712
713    if( bWp_explicit )
714    {
715      xEstimateWPParamSlice( pcSlice );
716    }
717   
718    pcSlice->initWpScaling();
719
720    // check WP on/off
721    if( bWp_explicit )
722    {
723      xCheckWPEnable( pcSlice );
724    }
725  }
[313]726#endif
[56]727#if ADAPTIVE_QP_SELECTION
728  if( m_pcCfg->getUseAdaptQpSelect() )
729  {
730    m_pcTrQuant->clearSliceARLCnt();
731    if(pcSlice->getSliceType()!=I_SLICE)
732    {
733      Int qpBase = pcSlice->getSliceQpBase();
734      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
735    }
736  }
737#endif
[2]738  // initialize ALF parameters
739  m_pcEntropyCoder->setAlfCtrl(false);
740  m_pcEntropyCoder->setMaxAlfCtrlDepth(0); //unnecessary
[56]741 
[100]742#if SAIT_VSO_EST_A0033
743 if( m_pcCfg->getUseVSO() )
744 {
745
746   Int frameWidth = m_pcCfg->getSourceWidth();
747   Pel* pVideoRec = m_pcRdCost->getVideoRecPicYuv()->getLumaAddr();
748   Int iVideoRecStride = m_pcRdCost->getVideoRecPicYuv()->getStride();
749
750   Pel* pDepthOrg = m_pcRdCost->getDepthPicYuv()->getLumaAddr();
751   Int iDepthOrgStride = m_pcRdCost->getDepthPicYuv()->getStride();
752
753   for( Int y = 0 ; y < m_pcCfg->getSourceHeight() ; y++ )
754   {
[102]755     pVideoRec[-1] = pVideoRec[0];
756     pVideoRec[frameWidth] = pVideoRec[frameWidth-1];
757     pDepthOrg[-1] = pDepthOrg[0];
758     pDepthOrg[frameWidth] = pDepthOrg[frameWidth-1];
[100]759
760     pVideoRec += iVideoRecStride;
761     pDepthOrg += iDepthOrgStride;
762   }
763 }
764#endif
[102]765
[56]766  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
767  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
768  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
769  Int  iNumSubstreams = 1;
770  UInt uiTilesAcross  = 0;
[5]771
[189]772#if LGE_ILLUCOMP_B0045
[296]773  if (pcEncTop->getViewId() != 0 
774#if !LGE_ILLUCOMP_DEPTH_C0046
775      && !pcEncTop->isDepthCoder() 
776#endif
777      && pcEncTop->getUseIC())   // DCP of ViewID 0 is not available
[189]778  {
779    pcSlice ->xSetApplyIC();
780  }
781#endif
782
[56]783  if( m_pcCfg->getUseSBACRD() )
784  {
785    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
786    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
787    delete[] m_pcBufferSbacCoders;
788    delete[] m_pcBufferBinCoderCABACs;
789    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
790    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
791    for (int ui = 0; ui < uiTilesAcross; ui++)
792    {
793      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
794    }
795    for (UInt ui = 0; ui < uiTilesAcross; ui++)
796    {
797      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
798    }
799
800    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
801    {
802      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
803    }
804  }
805  //if( m_pcCfg->getUseSBACRD() )
806  {
807    delete[] m_pcBufferLowLatSbacCoders;
808    delete[] m_pcBufferLowLatBinCoderCABACs;
809    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
810    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
811    for (int ui = 0; ui < uiTilesAcross; ui++)
812    {
813      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
814    }
815    for (UInt ui = 0; ui < uiTilesAcross; ui++)
816      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
817  }
[296]818
819#if MERL_VSP_C0152
820  // Send Depth/Texture pointers to slice level
821  pcSlice->setBWVSPLUTParam(m_aiShiftLUT, m_iShiftPrec);
822  pcSlice->setRefPicBaseTxt(m_pPicBaseTxt);
823  pcSlice->setRefPicBaseDepth(m_pPicBaseDepth);
824#endif
825
[56]826  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
827  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
828  UInt uiCol=0, uiLin=0, uiSubStrm=0;
829  UInt uiTileCol      = 0;
830  UInt uiTileStartLCU = 0;
831  UInt uiTileLCUX     = 0;
[210]832#if !QC_MVHEVC_B0046
[100]833  Int iLastPosY = -1;
[210]834#endif
[2]835  // for every CU in slice
[56]836  UInt uiEncCUOrder;
837  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
838  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
839       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
840       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
[2]841  {
842    // initialize CU encoder
843    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
844    pcCU->initCU( rpcPic, uiCUAddr );
[210]845#if !QC_MVHEVC_B0046
[100]846    if ( m_pcRdCost->getUseRenModel() )
847    {
848      // updated renderer model if necessary
849      Int iCurPosX;
850      Int iCurPosY; 
851      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
852      if ( iCurPosY != iLastPosY )
853      {
854        iLastPosY = iCurPosY; 
855       
856        m_pcGOPEncoder->getEncTop()->getEncTop()->setupRenModel( rpcPic->getCurrSlice()->getPOC() , rpcPic->getCurrSlice()->getSPS()->getViewId(), rpcPic->getCurrSlice()->getSPS()->isDepth() ? 1 : 0, iCurPosY );
857      }
858    }   
[210]859#endif
[56]860    // inherit from TR if necessary, select substream to use.
861    if( m_pcCfg->getUseSBACRD() )
862    {
863      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
864      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
865      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
866      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
867      uiCol     = uiCUAddr % uiWidthInLCUs;
868      uiLin     = uiCUAddr / uiWidthInLCUs;
869      if (pcSlice->getPPS()->getNumSubstreams() > 1)
870      {
871        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
872        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
873        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
874                      + uiLin%iNumSubstreamsPerTile;
875      }
876      else
877      {
878        // dependent tiles => substreams are "per frame".
879        uiSubStrm = uiLin % iNumSubstreams;
880      }
881      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
882      {
883        // We'll sync if the TR is available.
884        TComDataCU *pcCUUp = pcCU->getCUAbove();
885        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
886        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
887        TComDataCU *pcCUTR = NULL;
888        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
889        {
890          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
891        }
892        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
893             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
894             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
895             )||
896             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
897             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
898             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
899             )
900           )
901        {
902          // TR not available.
903        }
904        else
905        {
906          // TR is available, we use it.
907          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
908        }
909      }
910      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
911    }
912
913    // reset the entropy coder
914    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
915        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
916        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
917    {
918#if CABAC_INIT_FLAG
919      SliceType sliceType = pcSlice->getSliceType();
920      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
921      {
922        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
923      }
924      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
925      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
926      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
927      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
928#else
929      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp(), false );
930      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
931      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp() );
932      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
933#endif
934    }
[2]935    // if RD based on SBAC is used
936    if( m_pcCfg->getUseSBACRD() )
937    {
938      // set go-on entropy coder
939      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
[56]940      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
941     
942      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
[2]943      // run CU encoder
944      m_pcCuEncoder->compressCU( pcCU );
[56]945     
[2]946      // restore entropy coder to an initial stage
947      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
[56]948      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
949      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
950      m_pcBitCounter = &pcBitCounters[uiSubStrm];
[2]951      pppcRDSbacCoder->setBinCountingEnableFlag( true );
[56]952      m_pcBitCounter->resetBits();
953      pppcRDSbacCoder->setBinsCoded( 0 );
[2]954      m_pcCuEncoder->encodeCU( pcCU );
955
956      pppcRDSbacCoder->setBinCountingEnableFlag( false );
[56]957      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
[2]958      {
959        pcSlice->setNextSlice( true );
960        break;
961      }
[56]962      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
[2]963      {
964        pcSlice->setNextEntropySlice( true );
965        break;
966      }
[56]967      if( m_pcCfg->getUseSBACRD() )
968      {
969         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
970       
971         //Store probabilties of second LCU in line into buffer
972        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
973        {
974          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
975        }
976      }
[2]977    }
978    // other case: encodeCU is not called
979    else
980    {
981      m_pcCuEncoder->compressCU( pcCU );
982      m_pcCuEncoder->encodeCU( pcCU );
[56]983      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
[2]984      {
985        pcSlice->setNextSlice( true );
986        break;
987      }
[56]988      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
[2]989      {
990        pcSlice->setNextEntropySlice( true );
991        break;
992      }
993    }
[56]994   
[2]995    m_uiPicTotalBits += pcCU->getTotalBits();
996    m_dPicRdCost     += pcCU->getTotalCost();
997    m_uiPicDist      += pcCU->getTotalDistortion();
998  }
[56]999  xRestoreWPparam( pcSlice );
[2]1000}
1001
1002/**
1003 \param  rpcPic        picture class
1004 \retval rpcBitstream  bitstream class
1005 */
[56]1006Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
[2]1007{
1008  UInt       uiCUAddr;
1009  UInt       uiStartCUAddr;
1010  UInt       uiBoundingCUAddr;
1011  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1012
[56]1013  uiStartCUAddr=pcSlice->getEntropySliceCurStartCUAddr();
1014  uiBoundingCUAddr=pcSlice->getEntropySliceCurEndCUAddr();
[2]1015  // choose entropy coder
1016  {
1017    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1018    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1019  }
[56]1020 
1021  m_pcCuEncoder->setBitCounter( NULL );
1022  m_pcBitCounter = NULL;
1023  // Appropriate substream bitstream is switched later.
[2]1024  // for every CU
1025#if ENC_DEC_TRACE
1026  g_bJustDoIt = g_bEncDecTraceEnable;
1027#endif
[56]1028  DTRACE_CABAC_VL( g_nSymbolCounter++ );
[2]1029  DTRACE_CABAC_T( "\tPOC: " );
1030  DTRACE_CABAC_V( rpcPic->getPOC() );
1031  DTRACE_CABAC_T( "\n" );
1032#if ENC_DEC_TRACE
1033  g_bJustDoIt = g_bEncDecTraceDisable;
1034#endif
1035
[56]1036  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1037  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1038  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1039  UInt uiBitsOriginallyInSubstreams = 0;
[2]1040  {
[56]1041    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1042    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1043    {
1044      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1045    }
1046   
1047    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1048    {
1049      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1050    }
1051
1052    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1053    {
1054      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1055    }
1056  }
1057
1058  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1059  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1060  UInt uiTileCol      = 0;
1061  UInt uiTileStartLCU = 0;
1062  UInt uiTileLCUX     = 0;
1063
1064  UInt uiEncCUOrder;
[296]1065
[56]1066  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1067                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1068                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1069  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1070       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1071       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1072  {
1073    if( m_pcCfg->getUseSBACRD() )
1074    {
1075      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1076      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1077      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1078      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1079      uiCol     = uiCUAddr % uiWidthInLCUs;
1080      uiLin     = uiCUAddr / uiWidthInLCUs;
1081      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1082      {
1083        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1084        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1085        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1086                      + uiLin%iNumSubstreamsPerTile;
1087      }
1088      else
1089      {
1090        // dependent tiles => substreams are "per frame".
1091        uiSubStrm = uiLin % iNumSubstreams;
1092      }
1093
1094      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1095
1096      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1097      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1098      {
1099        // We'll sync if the TR is available.
1100        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1101        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1102        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1103        TComDataCU *pcCUTR = NULL;
1104        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1105        {
1106          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1107        }
1108        if ( (true/*bEnforceSliceRestriction*/ &&
1109             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1110             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1111             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1112             ))||
1113             (true/*bEnforceEntropySliceRestriction*/ &&
1114             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1115             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
1116             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1117             ))
1118           )
1119        {
1120          // TR not available.
1121        }
1122        else
1123        {
1124          // TR is available, we use it.
1125          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1126        }
1127      }
1128      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1129    }
1130    // reset the entropy coder
1131    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1132        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1133        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1134    {
1135      Int iTileIdx            = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr);
1136      Bool bWriteTileMarker   = false;
1137      // check if current iTileIdx should have a marker
1138      for (Int iEntryIdx=0; iEntryIdx<m_pcCfg->getMaxTileMarkerEntryPoints()-1; iEntryIdx++)
1139      {
1140        bWriteTileMarker = ( (((Int)((iEntryIdx+1)*m_pcCfg->getMaxTileMarkerOffset()+0.5)) == iTileIdx ) && iEntryIdx < (m_pcCfg->getMaxTileMarkerEntryPoints()-1)) ? true : false;
1141        if (bWriteTileMarker)
1142        {
1143          break;
1144        }
1145      }
1146      {
1147        // We're crossing into another tile, tiles are independent.
1148        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1149        // have to perform it here.
1150        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1151        {
1152          ; // do nothing.
1153        }
1154        else
1155        {
1156#if CABAC_INIT_FLAG
1157          SliceType sliceType  = pcSlice->getSliceType();
1158          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
1159          {
1160            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1161          }
1162          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1163#else
1164          m_pcEntropyCoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
1165#endif
1166          pcSubstreams[uiSubStrm].write( 1, 1 );
1167          pcSubstreams[uiSubStrm].writeAlignZero();
1168        }
1169      }
1170      {
1171        // Write TileMarker into the appropriate substream (nothing has been written to it yet).
1172        if (m_pcCfg->getTileMarkerFlag() && bWriteTileMarker)
1173        {
1174          // Log locations where tile markers are to be inserted during emulation prevention
1175          UInt uiMarkerCount = pcSubstreams[uiSubStrm].getTileMarkerLocationCount();
1176          pcSubstreams[uiSubStrm].setTileMarkerLocation     ( uiMarkerCount, pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3 );
1177          pcSubstreams[uiSubStrm].setTileMarkerLocationCount( uiMarkerCount + 1 );
1178          // Write tile index
1179          m_pcEntropyCoder->writeTileMarker(iTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx()); // Tile index
1180        }
1181
1182       
1183        UInt uiAccumulatedSubstreamLength = 0;
1184        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1185        {
1186          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1187        }
1188        UInt uiLocationCount = pcSlice->getTileLocationCount();
1189        // add bits coded in previous entropy slices + bits coded so far
1190        pcSlice->setTileLocation( uiLocationCount, (pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3 ); 
1191        pcSlice->setTileLocationCount( uiLocationCount + 1 );
1192      }
1193    }
1194
[332]1195#if H3D_QTL
[189]1196    rpcPic->setReduceBitsFlag(true);
1197#endif
1198
[56]1199    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1200
1201    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
1202    {
1203      Int iNumCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
1204      Int iCUAddrInSlice    = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU());
1205      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1206      Int rx = uiCUAddr % iNumCuInWidth;
1207      Int ry = uiCUAddr / iNumCuInWidth;
1208      m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
1209    }
[2]1210#if ENC_DEC_TRACE
1211    g_bJustDoIt = g_bEncDecTraceEnable;
1212#endif
[56]1213    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && 
1214      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
[2]1215    {
1216      m_pcCuEncoder->encodeCU( pcCU, true );
1217    }
1218    else
1219    {
1220      m_pcCuEncoder->encodeCU( pcCU );
1221    }
1222#if ENC_DEC_TRACE
1223    g_bJustDoIt = g_bEncDecTraceDisable;
[56]1224#endif   
1225    if( m_pcCfg->getUseSBACRD() )
1226    {
1227       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1228       
1229
1230       //Store probabilties of second LCU in line into buffer
1231      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1232      {
1233        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1234      }
1235    }
[189]1236
[332]1237#if H3D_QTL
[189]1238    rpcPic->setReduceBitsFlag(false);
1239#endif
1240
[2]1241  }
[56]1242
1243#if ADAPTIVE_QP_SELECTION
1244  if( m_pcCfg->getUseAdaptQpSelect() )
1245  {
1246    m_pcTrQuant->storeSliceQpNext(pcSlice);
1247  }
1248#endif
1249#if CABAC_INIT_FLAG
1250  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1251  {
1252    m_pcEntropyCoder->determineCabacInitIdx();
1253  }
1254#endif
[2]1255}
1256
1257/** Determines the starting and bounding LCU address of current slice / entropy slice
1258 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1259 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1260 */
1261Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1262{
1263  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1264  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
[56]1265  UInt tileIdxIncrement;
1266  UInt tileIdx;
1267  UInt tileWidthInLcu;
1268  UInt tileHeightInLcu;
1269  UInt tileTotalCount;
1270
[2]1271  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1272  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1273  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
[56]1274  if (bEncodeSlice) 
[2]1275  {
1276    UInt uiCUAddrIncrement;
1277    switch (m_pcCfg->getSliceMode())
1278    {
1279    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1280      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
[56]1281      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1282      break;
1283    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1284      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1285      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1286      break;
[56]1287    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1288      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1289        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1290        );
1291      uiCUAddrIncrement        = 0;
1292      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1293
1294      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1295      {
1296        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1297        {
1298          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1299          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1300          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1301        }
1302      }
1303
1304      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1305      break;
[2]1306    default:
1307      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
[56]1308      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1309      break;
[56]1310    } 
[2]1311    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1312  }
1313  else
1314  {
1315    UInt uiCUAddrIncrement     ;
1316    switch (m_pcCfg->getSliceMode())
1317    {
1318    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1319      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
[56]1320      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1321      break;
[56]1322    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1323      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1324        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1325        );
1326      uiCUAddrIncrement        = 0;
1327      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1328
1329      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1330      {
1331        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1332        {
1333          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1334          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1335          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1336        }
1337      }
1338
1339      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1340      break;
[2]1341    default:
1342      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
[56]1343      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1344      break;
[56]1345    } 
[2]1346    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1347  }
1348
[56]1349  Bool tileBoundary = false;
1350  if ((m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE || m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE) && 
1351      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1352  {
1353    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1354    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1355    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1356    UInt tileBoundingCUAddrSlice = 0;
1357    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1358    {
1359      lcuEncAddr++;
1360      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1361    }
1362    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1363   
1364    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1365    {
1366      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1367      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1368      tileBoundary = true;
1369    }
1370  }
1371
[2]1372  // Entropy slice
1373  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
1374  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
1375  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
[56]1376  if (bEncodeSlice) 
[2]1377  {
1378    UInt uiCUAddrIncrement;
1379    switch (m_pcCfg->getEntropySliceMode())
1380    {
1381    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1382      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
[56]1383      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1384      break;
1385    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
1386      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1387      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
1388      break;
1389    default:
1390      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
[56]1391      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1392      break;
[56]1393    } 
[2]1394    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1395  }
1396  else
1397  {
1398    UInt uiCUAddrIncrement;
1399    switch (m_pcCfg->getEntropySliceMode())
1400    {
1401    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1402      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
[56]1403      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1404      break;
1405    default:
1406      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
[56]1407      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1408      break;
[56]1409    } 
[2]1410    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1411  }
[56]1412  if(uiBoundingCUAddrEntropySlice>uiBoundingCUAddrSlice)
1413  {
1414    uiBoundingCUAddrEntropySlice = uiBoundingCUAddrSlice;
1415    pcSlice->setEntropySliceCurEndCUAddr(uiBoundingCUAddrSlice);
1416  }
1417  //calculate real entropy slice start address
1418  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1419  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1420  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1421  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1422  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1423  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1424  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1425  {
1426    uiInternalAddress++;
1427    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1428    {
1429      uiInternalAddress=0;
1430      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1431    }
1432    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1433    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1434  }
1435  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1436 
1437  pcSlice->setEntropySliceCurStartCUAddr(uiRealStartAddress);
1438  uiStartCUAddrEntropySlice=uiRealStartAddress;
1439 
1440  //calculate real slice start address
1441  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1442  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1443  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1444  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1445  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1446  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1447  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1448  {
1449    uiInternalAddress++;
1450    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1451    {
1452      uiInternalAddress=0;
1453      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1454    }
1455    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1456    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1457  }
1458  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1459 
1460  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1461  uiStartCUAddrSlice=uiRealStartAddress;
1462 
[2]1463  // Make a joint decision based on reconstruction and entropy slice bounds
1464  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
1465  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
1466
1467
1468  if (!bEncodeSlice)
1469  {
1470    // For fixed number of LCU within an entropy and reconstruction slice we already know whether we will encounter end of entropy and/or reconstruction slice
1471    // first. Set the flags accordingly.
1472    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1473      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
[56]1474      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1475      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1476      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1477      || tileBoundary
1478)
[2]1479    {
1480      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
1481      {
1482        pcSlice->setNextSlice       ( true );
1483        pcSlice->setNextEntropySlice( false );
1484      }
1485      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
1486      {
1487        pcSlice->setNextSlice       ( false );
1488        pcSlice->setNextEntropySlice( true );
1489      }
1490      else
1491      {
1492        pcSlice->setNextSlice       ( true );
1493        pcSlice->setNextEntropySlice( true );
1494      }
1495    }
1496    else
1497    {
1498      pcSlice->setNextSlice       ( false );
1499      pcSlice->setNextEntropySlice( false );
1500    }
1501  }
1502}
[56]1503//! \}
Note: See TracBrowser for help on using the repository browser.