source: 3DVCSoftware/branches/HTM-11.0-dev0/source/Lib/TLibEncoder/TEncSlice.cpp @ 962

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

Update to HM-14.0

Integration of:

#define H_MV_HLS_8_SYN_Q0041_03 1 #3 Syntax only (HS /Q0041/hybrid scalability) The proposed text was endorsed, with non-editorial open issues considered as follows …: #define H_MV_HLS_7_OTHER_P0187_1 0 (OTHER/P0187/NoOutputOfPriorPicsFlag) #1 Inference of NoOutputOfPriorPicsFlag and proposes to take into account colour format and bit depth for the inference in addition to spatial resolution
#define H_MV_HLS_8_SYN_39_19 1
#39 Syntax only + (PS/Q0165,Q0078/presence of num_add_output_layer_sets) proposal 2. change condition for presence of num_add_output_layer_sets to avoid sending it when there is only one layer set.
#define H_MV_HLS_8_HRD_Q0101_04 1 #4 (HRD /Q0101/Bitstream part buffer) On Bitstream Partition Buffer. Decision (BF/Cleanup): Adopt (sub-proposals 1–11, refined as described).
#define H_MV_HLS_8_PPS_NODOC_NN 1
#NN (PPS /NODOC/reserved flag): Add a flag in PPS for SHVC color gamut scalability
#define H_MV_HLS_8_MIS_Q0177_47 1 #47 (MISC /Q0177/EOS NAL) proposal 2: clarification of description of end of sequence NAL unit
#define H_MV_HLS_8_HRD_Q0182_05 1
#5 (HRD /Q0182/Bitstream part buffer) Decision (BF/Cleanup/Ed): Adopted (such that we use the main proposal for sub-proposal 1, and alternative 1 for sub-proposal 2). + #define H_MV_HLS_8_HRD_Q0182_06 0 #6 (HRD /Q0182/hrd_parameters) Sub-proposal 2 Alternative 1: Clarify that the VPS hrd_parameters( ) syntax structure that applies to the layer set which is associated with the bitstream partition initial arrival time SEI message is used to determine the lengths of the nal_initial_arrival_delay[ i ] and vcl_initial_arrival_delay[ i ] syntax elements. Decision (BF/Cleanup/Ed): Adopted alternative 1 for sub-proposal 2
#define H_MV_HLS_8_SPS_NODOC_48 1
#48 (SPS /NODOC/PPS extension cleanups) Alignment with RExt
#define H_MV_HLS_8_DBP_NODOC_42 1 #42 (DBP /NODOC/sharing) Remove sub-DPB sharing and processes that mark inter-layer reference pictures as "unused for reference"
#define H_MV_HLS_8_RPS_Q0100_36 1
#36 (RPS /Q0100/constraint to semantics) v3, add constraint to RPS semantics
#define H_MV_HLS_8_POC_Q0142_32 1 #32 (POC /Q0142/poc_lsb_not_present_flag) v2: Add semantic constraints to poc_lsb_not_present_flag.
#define H_MV_HLS_8_HRD_Q0102_08 1
#8 (HRD /Q0102/sps_max_dec_pic_buffering_minus1) Sub-proposal 2: A semantics bug fix is proposed for sps_max_dec_pic_buffering_minus1 as a bug-fix. In discussion, the first option was preferred. Decision (BF/Cleanup/Ed.): Adopt.
#define H_MV_HLS_8_MIS_Q0102_30 1 #30 (MISC /Q0102/loop index) proposal 3, change the max loop index for signaling bit rate and pic rate info to MaxSubLayersInLayerSetMinus1
#define H_MV_HLS_8_GEN_Q0108_13 1
#13 (GEN /Q0108/STSA TemporalId) Agreed to remove restriction from proposal 2, to allow STSA pics of non-base layers to have TemporalId equal to 0.
#define H_MV_HLS_8_PMS_Q0195_21 1 #21 (PS /Q0195/constraint update_ref_format_flag) proposal 2: add a semantic constraint on the value of update_ref_format_flag
#define H_MV_HLS_8_PMS_Q0195_20 1
#20 (PS /Q0195/syntax table rep format) proposal 1: restructure syntax table for sending of rep_format_idx_present_flag and vps_num_ref_formats_minus1
#define H_MV_HLS_8_MIS_Q0177_22 1 #22 (MISC /Q0177/inference sps_temporal_id_nesting_flag) proposal 1: modify inference rule for sps_temporal_id_nesting_flag when it is not present
#define H_MV_HLS_8_PMS_Q0165_18 1
#18 (PS /Q0165/disallow an empty layer set) proposal 1.a), add a constraint to disallow an empty layer set
#define H_MV_HLS_8_RPS_Q0060_17 1 #17 (RPS /Q0060/condition refLayerPicIdc) Proposal 2: Add a condition to the derivation of refLayerPicIdc of (TemporalId == 0)
#define H_MV_HLS_8_POC_Q0146_15 1
#15 (POC /Q0146/inference of poc_msb_val_present_flag) Proposal 1.1: Change inference rule in semantics of poc_msb_val_present_flag

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