source: SHVCSoftware/branches/SHM-3.1-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 389

Last change on this file since 389 was 389, checked in by qualcomm, 11 years ago

Signaling representation format in VPS (MACRO: REPN_FORMAT_IN_VPS)

Includes signaling of representation format - including picture resolution, bit depth, chroma format - in the VPS, with the option of updating them in the SPS. The configuration file has "RepFormatIdx%d" added to indicate for each layer which representation format is used. The rep_format() structures are automatically created by the encoder. If the bit depth and the chroma format are also changed across layers, some more configuration support would be needed.

From: Adarsh K. Ramasubramonian <aramasub@…>

  • Property svn:eol-style set to native
File size: 81.4 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-2013, 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#if SVC_EXTENSION
140  m_ppcTEncTop        = pcEncTop->getLayerEnc();
141#endif 
142  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
143  m_pcCuEncoder       = pcEncTop->getCuEncoder();
144  m_pcPredSearch      = pcEncTop->getPredSearch();
145 
146  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
147  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
148  m_pcSbacCoder       = pcEncTop->getSbacCoder();
149  m_pcBinCABAC        = pcEncTop->getBinCABAC();
150  m_pcTrQuant         = pcEncTop->getTrQuant();
151 
152  m_pcBitCounter      = pcEncTop->getBitCounter();
153  m_pcRdCost          = pcEncTop->getRdCost();
154  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
155  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
156 
157  // create lambda and QP arrays
158  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
159  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
160  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
161  m_pcRateCtrl        = pcEncTop->getRateCtrl();
162}
163
164/**
165 - non-referenced frame marking
166 - QP computation based on temporal structure
167 - lambda computation based on QP
168 - set temporal layer ID and the parameter sets
169 .
170 \param pcPic         picture class
171 \param pocLast       POC of last picture
172 \param pocCurr       current POC
173 \param iNumPicRcvd   number of received pictures
174 \param iTimeOffset   POC offset for hierarchical structure
175 \param iDepth        temporal layer depth
176 \param rpcSlice      slice header class
177 \param pSPS          SPS associated with the slice
178 \param pPPS          PPS associated with the slice
179 */
180#if SVC_EXTENSION
181//\param vps          VPS associated with the slice
182Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, TComVPS *vps )
183#else
184Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
185#endif
186{
187  Double dQP;
188  Double dLambda;
189 
190  rpcSlice = pcPic->getSlice(0);
191  rpcSlice->setSPS( pSPS );
192  rpcSlice->setPPS( pPPS );
193  rpcSlice->setSliceBits(0);
194  rpcSlice->setPic( pcPic );
195#if SVC_EXTENSION
196  UInt layerId = pcPic->getLayerId();
197  rpcSlice->setVPS( vps );
198  rpcSlice->initSlice( layerId );
199#else
200  rpcSlice->initSlice();
201#endif
202  rpcSlice->setPicOutputFlag( true );
203  rpcSlice->setPOC( pocCurr );
204 
205  // depth computation based on GOP size
206  Int depth;
207  {
208    Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
209    if ( poc == 0 )
210    {
211      depth = 0;
212    }
213    else
214    {
215      Int step = m_pcCfg->getGOPSize();
216      depth    = 0;
217      for( Int i=step>>1; i>=1; i>>=1 )
218      {
219        for ( Int j=i; j<m_pcCfg->getGOPSize(); j+=step )
220        {
221          if ( j == poc )
222          {
223            i=0;
224            break;
225          }
226        }
227        step >>= 1;
228        depth++;
229      }
230    }
231  }
232 
233  // slice type
234  SliceType eSliceType;
235 
236  eSliceType=B_SLICE;
237  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
238 
239  rpcSlice->setSliceType    ( eSliceType );
240 
241  // ------------------------------------------------------------------------------------------------------------------
242  // Non-referenced frame marking
243  // ------------------------------------------------------------------------------------------------------------------
244 
245  if(pocLast == 0)
246  {
247    rpcSlice->setTemporalLayerNonReferenceFlag(false);
248  }
249  else
250  {
251    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
252  }
253  rpcSlice->setReferenced(true);
254 
255  // ------------------------------------------------------------------------------------------------------------------
256  // QP setting
257  // ------------------------------------------------------------------------------------------------------------------
258 
259  dQP = m_pcCfg->getQP();
260  if(eSliceType!=I_SLICE)
261  {
262#if REPN_FORMAT_IN_VPS
263    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
264#else
265    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
266#endif
267    {
268      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
269    }
270  }
271 
272  // modify QP
273  Int* pdQPs = m_pcCfg->getdQPs();
274  if ( pdQPs )
275  {
276    dQP += pdQPs[ rpcSlice->getPOC() ];
277  }
278#if !RATE_CONTROL_LAMBDA_DOMAIN
279  if ( m_pcCfg->getUseRateCtrl())
280  {
281    dQP = m_pcRateCtrl->getFrameQP(rpcSlice->isReferenced(), rpcSlice->getPOC());
282  }
283#endif
284  // ------------------------------------------------------------------------------------------------------------------
285  // Lambda computation
286  // ------------------------------------------------------------------------------------------------------------------
287 
288  Int iQP;
289  Double dOrigQP = dQP;
290
291  // pre-compute lambda and QP values for all possible QP candidates
292  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
293  {
294    // compute QP value
295    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
296   
297    // compute lambda value
298    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
299    Int    SHIFT_QP = 12;
300    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
301#if FULL_NBIT
302    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
303#else
304    Int    bitdepth_luma_qp_scale = 0;
305#endif
306    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
307#if FULL_NBIT
308    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
309#endif
310    // Case #1: I or P-slices (key-frame)
311    Double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
312    if ( eSliceType==I_SLICE )
313    {
314      dQPFactor=0.57*dLambda_scale;
315    }
316    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
317
318    if ( depth>0 )
319    {
320#if FULL_NBIT
321        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
322#else
323        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
324#endif
325    }
326   
327    // if hadamard is used in ME process
328    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
329    {
330      dLambda *= 0.95;
331    }
332   
333#if REPN_FORMAT_IN_VPS
334    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
335#else
336    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
337#endif
338
339    m_pdRdPicLambda[iDQpIdx] = dLambda;
340    m_pdRdPicQp    [iDQpIdx] = dQP;
341    m_piRdPicQp    [iDQpIdx] = iQP;
342  }
343 
344  // obtain dQP = 0 case
345  dLambda = m_pdRdPicLambda[0];
346  dQP     = m_pdRdPicQp    [0];
347  iQP     = m_piRdPicQp    [0];
348 
349  if( rpcSlice->getSliceType( ) != I_SLICE )
350  {
351    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
352  }
353
354#if JCTVC_M0259_LAMBDAREFINEMENT
355  if( rpcSlice->getLayerId() > 0 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && depth >= 3 && m_pcCfg->getGOPSize() == ( 1 << depth ) )
356  {
357    Int nCurLayer = rpcSlice->getLayerId();
358    Double gamma = xCalEnhLambdaFactor( m_ppcTEncTop[nCurLayer-1]->getQP() - m_ppcTEncTop[nCurLayer]->getQP() ,
359      1.0 * m_ppcTEncTop[nCurLayer]->getSourceWidth() * m_ppcTEncTop[nCurLayer]->getSourceHeight() 
360      / m_ppcTEncTop[nCurLayer-1]->getSourceWidth() / m_ppcTEncTop[nCurLayer-1]->getSourceHeight() );
361    dLambda *= gamma;
362  }
363#endif
364
365  // store lambda
366  m_pcRdCost ->setLambda( dLambda );
367#if WEIGHTED_CHROMA_DISTORTION
368// for RDO
369  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
370  Double weight = 1.0;
371  Int qpc;
372  Int chromaQPOffset;
373
374  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
375  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
376  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
377  m_pcRdCost->setCbDistortionWeight(weight);
378
379  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
380  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
381  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
382#if JCTVC_M0259_LAMBDAREFINEMENT
383  if( rpcSlice->getLayerId() > 0 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && m_pcCfg->getGOPSize() >= 8 && rpcSlice->isIntra() == false && depth == 0 )
384  {
385    dLambda *= 1.1;
386    weight *= 1.15;
387  }
388#endif
389  m_pcRdCost->setCrDistortionWeight(weight);
390#endif
391
392#if RDOQ_CHROMA_LAMBDA
393// for RDOQ
394  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
395#else
396  m_pcTrQuant->setLambda( dLambda );
397#endif
398
399#if SAO_CHROMA_LAMBDA
400// For SAO
401  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
402#else
403  rpcSlice   ->setLambda( dLambda );
404#endif
405 
406#if HB_LAMBDA_FOR_LDC
407  // restore original slice type
408  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
409 
410#if SVC_EXTENSION
411  if(m_pcCfg->getLayerId() > 0)
412  {
413    eSliceType=B_SLICE;
414  }
415#endif
416  rpcSlice->setSliceType        ( eSliceType );
417#endif
418 
419  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
420  {
421    dQP = xGetQPValueAccordingToLambda( dLambda );
422#if REPN_FORMAT_IN_VPS
423    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );   
424#else
425    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );   
426#endif
427  }
428
429  rpcSlice->setSliceQp          ( iQP );
430#if ADAPTIVE_QP_SELECTION
431  rpcSlice->setSliceQpBase      ( iQP );
432#endif
433  rpcSlice->setSliceQpDelta     ( 0 );
434  rpcSlice->setSliceQpDeltaCb   ( 0 );
435  rpcSlice->setSliceQpDeltaCr   ( 0 );
436  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
437  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
438 
439  if ( m_pcCfg->getDeblockingFilterMetric() )
440  {
441    rpcSlice->setDeblockingFilterOverrideFlag(true);
442    rpcSlice->setDeblockingFilterDisable(false);
443    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
444    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
445  } else
446  if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
447  {
448    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
449    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
450    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
451    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
452    if ( !rpcSlice->getDeblockingFilterDisable())
453    {
454      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
455      {
456        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
457        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
458        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
459        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
460      }
461      else
462      {
463      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
464      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
465      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
466      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
467      }
468    }
469  }
470  else
471  {
472    rpcSlice->setDeblockingFilterOverrideFlag( false );
473    rpcSlice->setDeblockingFilterDisable( false );
474    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
475    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
476  }
477
478  rpcSlice->setDepth            ( depth );
479 
480  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
481  if(eSliceType==I_SLICE)
482  {
483    pcPic->setTLayer(0);
484  }
485  rpcSlice->setTLayer( pcPic->getTLayer() );
486
487  assert( m_apcPicYuvPred );
488  assert( m_apcPicYuvResi );
489 
490  pcPic->setPicYuvPred( m_apcPicYuvPred );
491  pcPic->setPicYuvResi( m_apcPicYuvResi );
492  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
493  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
494  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
495  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
496  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
497  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
498
499#if SVC_EXTENSION
500  if( layerId > 0 )
501  {
502#if JCTVC_M0458_INTERLAYER_RPS_SIG
503    if( rpcSlice->getNumILRRefIdx() > 0 )
504    {
505      rpcSlice->setActiveNumILRRefIdx( m_ppcTEncTop[layerId]->getNumActiveRefLayers() );
506      for( Int i = 0; i < rpcSlice->getActiveNumILRRefIdx(); i++ )
507      {
508        rpcSlice->setInterLayerPredLayerIdc( m_ppcTEncTop[layerId]->getPredLayerId(i), i );
509      }
510      rpcSlice->setInterLayerPredEnabledFlag(1);
511    }
512#else
513    rpcSlice->setNumILRRefIdx( rpcSlice->getVPS()->getNumDirectRefLayers( layerId ) );
514#endif
515#if M0457_COL_PICTURE_SIGNALING
516    rpcSlice->setMFMEnabledFlag(m_ppcTEncTop[layerId]->getMFMEnabledFlag());
517#if !REMOVE_COL_PICTURE_SIGNALING
518    rpcSlice->setAltColIndicationFlag(rpcSlice->getMFMEnabledFlag());
519#endif
520#endif
521  }
522
523#endif
524}
525
526#if RATE_CONTROL_LAMBDA_DOMAIN
527Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
528{
529  TComSlice* slice = pic->getSlice(0);
530
531  // store lambda
532  slice->setSliceQp( sliceQP );
533  slice->setSliceQpBase ( sliceQP );
534  m_pcRdCost ->setLambda( lambda );
535#if WEIGHTED_CHROMA_DISTORTION
536  // for RDO
537  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
538  Double weight;
539  Int qpc;
540  Int chromaQPOffset;
541
542  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
543  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
544  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
545  m_pcRdCost->setCbDistortionWeight(weight);
546
547  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
548  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
549  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
550  m_pcRdCost->setCrDistortionWeight(weight);
551#endif
552
553#if RDOQ_CHROMA_LAMBDA
554  // for RDOQ
555  m_pcTrQuant->setLambda( lambda, lambda / weight );
556#else
557  m_pcTrQuant->setLambda( lambda );
558#endif
559
560#if SAO_CHROMA_LAMBDA
561  // For SAO
562  slice   ->setLambda( lambda, lambda / weight );
563#else
564  slice   ->setLambda( lambda );
565#endif
566}
567#else
568/**
569 - lambda re-computation based on rate control QP
570 */
571Void TEncSlice::xLamdaRecalculation(Int changeQP, Int idGOP, Int depth, SliceType eSliceType, TComSPS* pcSPS, TComSlice* pcSlice)
572{
573  Int qp;
574  Double recalQP= (Double)changeQP;
575  Double origQP = (Double)recalQP;
576  Double lambda;
577
578  // pre-compute lambda and QP values for all possible QP candidates
579  for ( Int deltqQpIdx = 0; deltqQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; deltqQpIdx++ )
580  {
581    // compute QP value
582    recalQP = origQP + ((deltqQpIdx+1)>>1)*(deltqQpIdx%2 ? -1 : 1);
583
584    // compute lambda value
585    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
586    Int    SHIFT_QP = 12;
587    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
588#if FULL_NBIT
589    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
590#else
591    Int    bitdepth_luma_qp_scale = 0;
592#endif
593    Double qp_temp = (Double) recalQP + bitdepth_luma_qp_scale - SHIFT_QP;
594#if FULL_NBIT
595    Double qp_temp_orig = (Double) recalQP - SHIFT_QP;
596#endif
597    // Case #1: I or P-slices (key-frame)
598    Double dQPFactor = m_pcCfg->getGOPEntry(idGOP).m_QPFactor;
599    if ( eSliceType==I_SLICE )
600    {
601      dQPFactor=0.57*dLambda_scale;
602    }
603    lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
604
605    if ( depth>0 )
606    {
607#if FULL_NBIT
608      lambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
609#else
610      lambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
611#endif
612    }
613
614    // if hadamard is used in ME process
615    if ( !m_pcCfg->getUseHADME() )
616    {
617      lambda *= 0.95;
618    }
619
620#if REPN_FORMAT_IN_VPS
621    qp = max( -pcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
622#else
623    qp = max( -pcSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
624#endif
625
626    m_pdRdPicLambda[deltqQpIdx] = lambda;
627    m_pdRdPicQp    [deltqQpIdx] = recalQP;
628    m_piRdPicQp    [deltqQpIdx] = qp;
629  }
630
631  // obtain dQP = 0 case
632  lambda  = m_pdRdPicLambda[0];
633  recalQP = m_pdRdPicQp    [0];
634  qp      = m_piRdPicQp    [0];
635
636  if( pcSlice->getSliceType( ) != I_SLICE )
637  {
638    lambda *= m_pcCfg->getLambdaModifier( depth );
639  }
640
641  // store lambda
642  m_pcRdCost ->setLambda( lambda );
643#if WEIGHTED_CHROMA_DISTORTION
644  // for RDO
645  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
646  Double weight = 1.0;
647  Int qpc;
648  Int chromaQPOffset;
649
650  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
651  qpc = Clip3( 0, 57, qp + chromaQPOffset);
652  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
653  m_pcRdCost->setCbDistortionWeight(weight);
654
655  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
656  qpc = Clip3( 0, 57, qp + chromaQPOffset);
657  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
658  m_pcRdCost->setCrDistortionWeight(weight);
659#endif
660
661#if RDOQ_CHROMA_LAMBDA
662  // for RDOQ
663  m_pcTrQuant->setLambda( lambda, lambda / weight );   
664#else
665  m_pcTrQuant->setLambda( lambda );
666#endif
667
668#if SAO_CHROMA_LAMBDA
669  // For SAO
670  pcSlice   ->setLambda( lambda, lambda / weight ); 
671#else
672  pcSlice   ->setLambda( lambda );
673#endif
674}
675#endif
676// ====================================================================================================================
677// Public member functions
678// ====================================================================================================================
679
680Void TEncSlice::setSearchRange( TComSlice* pcSlice )
681{
682  Int iCurrPOC = pcSlice->getPOC();
683  Int iRefPOC;
684  Int iGOPSize = m_pcCfg->getGOPSize();
685  Int iOffset = (iGOPSize >> 1);
686  Int iMaxSR = m_pcCfg->getSearchRange();
687  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
688 
689  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
690  {
691    //RefPicList e = (RefPicList)iDir;
692    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
693    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
694    {
695      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
696      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
697      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
698    }
699  }
700}
701
702/**
703 - multi-loop slice encoding for different slice QP
704 .
705 \param rpcPic    picture class
706 */
707Void TEncSlice::precompressSlice( TComPic*& rpcPic )
708{
709  // if deltaQP RD is not used, simply return
710  if ( m_pcCfg->getDeltaQpRD() == 0 )
711  {
712    return;
713  }
714
715#if RATE_CONTROL_LAMBDA_DOMAIN
716  if ( m_pcCfg->getUseRateCtrl() )
717  {
718    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
719    assert(0);
720  }
721#endif
722 
723  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
724  Double     dPicRdCostBest = MAX_DOUBLE;
725  UInt       uiQpIdxBest = 0;
726 
727  Double dFrameLambda;
728#if FULL_NBIT
729  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
730#else
731  Int    SHIFT_QP = 12;
732#endif
733 
734  // set frame lambda
735  if (m_pcCfg->getGOPSize() > 1)
736  {
737    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
738  }
739  else
740  {
741    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
742  }
743  m_pcRdCost      ->setFrameLambda(dFrameLambda);
744 
745  // for each QP candidate
746  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
747  {
748    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
749#if ADAPTIVE_QP_SELECTION
750    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
751#endif
752    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
753#if WEIGHTED_CHROMA_DISTORTION
754    // for RDO
755    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
756    Int iQP = m_piRdPicQp    [uiQpIdx];
757    Double weight = 1.0;
758    Int qpc;
759    Int chromaQPOffset;
760
761    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
762    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
763    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
764    m_pcRdCost->setCbDistortionWeight(weight);
765
766    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
767    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
768    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
769    m_pcRdCost->setCrDistortionWeight(weight);
770#endif
771
772#if RDOQ_CHROMA_LAMBDA
773    // for RDOQ
774    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
775#else
776    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
777#endif
778#if SAO_CHROMA_LAMBDA
779    // For SAO
780    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
781#else
782    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
783#endif
784   
785    // try compress
786    compressSlice   ( rpcPic );
787   
788    Double dPicRdCost;
789    UInt64 uiPicDist        = m_uiPicDist;
790    UInt64 uiALFBits        = 0;
791   
792    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
793   
794    // compute RD cost and choose the best
795    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
796   
797    if ( dPicRdCost < dPicRdCostBest )
798    {
799      uiQpIdxBest    = uiQpIdx;
800      dPicRdCostBest = dPicRdCost;
801    }
802  }
803 
804  // set best values
805  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
806#if ADAPTIVE_QP_SELECTION
807  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
808#endif
809  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
810#if WEIGHTED_CHROMA_DISTORTION
811  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
812  Int iQP = m_piRdPicQp    [uiQpIdxBest];
813  Double weight = 1.0;
814  Int qpc;
815  Int chromaQPOffset;
816
817  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
818  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
819  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
820  m_pcRdCost->setCbDistortionWeight(weight);
821
822  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
823  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
824  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
825  m_pcRdCost->setCrDistortionWeight(weight);
826#endif
827
828#if RDOQ_CHROMA_LAMBDA
829  // for RDOQ
830  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
831#else
832  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
833#endif
834#if SAO_CHROMA_LAMBDA
835  // For SAO
836  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
837#else
838  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
839#endif
840}
841
842/** \param rpcPic   picture class
843 */
844#if RATE_CONTROL_INTRA
845Void TEncSlice::calCostSliceI(TComPic*& rpcPic)
846{
847  UInt    uiCUAddr;
848  UInt    uiStartCUAddr;
849  UInt    uiBoundingCUAddr;
850  Int     iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;;
851  Double  iSumHadSlice = 0;
852
853  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
854  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
855  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
856
857  UInt uiEncCUOrder;
858  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
859  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
860       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
861       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
862  {
863    // initialize CU encoder
864    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
865    pcCU->initCU( rpcPic, uiCUAddr );
866
867#if REPN_FORMAT_IN_VPS
868    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
869    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(), pcSlice->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
870#else
871    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
872    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
873#endif
874
875    iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height);
876
877    (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift;
878    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra;
879
880  }
881  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
882}
883#endif
884
885Void TEncSlice::compressSlice( TComPic*& rpcPic )
886{
887  UInt  uiCUAddr;
888  UInt   uiStartCUAddr;
889  UInt   uiBoundingCUAddr;
890  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
891  TEncBinCABAC* pppcRDSbacCoder = NULL;
892  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
893  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
894 
895  // initialize cost values
896  m_uiPicTotalBits  = 0;
897  m_dPicRdCost      = 0;
898  m_uiPicDist       = 0;
899 
900  // set entropy coder
901  if( m_pcCfg->getUseSBACRD() )
902  {
903    m_pcSbacCoder->init( m_pcBinCABAC );
904    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
905    m_pcEntropyCoder->resetEntropy      ();
906    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
907    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
908    pppcRDSbacCoder->setBinCountingEnableFlag( false );
909    pppcRDSbacCoder->setBinsCoded( 0 );
910  }
911  else
912  {
913    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
914    m_pcEntropyCoder->resetEntropy      ();
915    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
916  }
917 
918  //------------------------------------------------------------------------------
919  //  Weighted Prediction parameters estimation.
920  //------------------------------------------------------------------------------
921  // calculate AC/DC values for current picture
922  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
923  {
924    xCalcACDCParamSlice(pcSlice);
925  }
926
927  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
928
929  if ( bWp_explicit )
930  {
931    //------------------------------------------------------------------------------
932    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
933    //------------------------------------------------------------------------------
934    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
935    {
936      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
937    }
938
939    xEstimateWPParamSlice( pcSlice );
940    pcSlice->initWpScaling();
941
942    // check WP on/off
943    xCheckWPEnable( pcSlice );
944  }
945
946#if ADAPTIVE_QP_SELECTION
947  if( m_pcCfg->getUseAdaptQpSelect() )
948  {
949    m_pcTrQuant->clearSliceARLCnt();
950    if(pcSlice->getSliceType()!=I_SLICE)
951    {
952      Int qpBase = pcSlice->getSliceQpBase();
953      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
954    }
955  }
956#endif
957  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
958  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
959  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
960  Int  iNumSubstreams = 1;
961  UInt uiTilesAcross  = 0;
962
963  if( m_pcCfg->getUseSBACRD() )
964  {
965    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
966    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
967    delete[] m_pcBufferSbacCoders;
968    delete[] m_pcBufferBinCoderCABACs;
969    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
970    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
971    for (Int ui = 0; ui < uiTilesAcross; ui++)
972    {
973      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
974    }
975    for (UInt ui = 0; ui < uiTilesAcross; ui++)
976    {
977      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
978    }
979
980    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
981    {
982      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
983    }
984  }
985  //if( m_pcCfg->getUseSBACRD() )
986  {
987    delete[] m_pcBufferLowLatSbacCoders;
988    delete[] m_pcBufferLowLatBinCoderCABACs;
989    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
990    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
991    for (Int ui = 0; ui < uiTilesAcross; ui++)
992    {
993      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
994    }
995    for (UInt ui = 0; ui < uiTilesAcross; ui++)
996      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
997  }
998  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
999  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
1000  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1001  UInt uiTileCol      = 0;
1002  UInt uiTileStartLCU = 0;
1003  UInt uiTileLCUX     = 0;
1004
1005  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1006  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
1007  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1008  if( depSliceSegmentsEnabled )
1009  {
1010    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
1011    {
1012      if( m_pcCfg->getWaveFrontsynchro() )
1013      {
1014        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1015        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1016        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1017        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
1018        uiLin     = uiCUAddr / uiWidthInLCUs;
1019        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
1020          + uiLin%iNumSubstreamsPerTile;
1021        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1022        {
1023          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1024          uiCol     = uiCUAddr % uiWidthInLCUs;
1025          if(uiCol==uiTileStartLCU)
1026          {
1027            CTXMem[0]->loadContexts(m_pcSbacCoder);
1028          }
1029        }
1030      }
1031      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1032      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1033    }
1034    else
1035    {
1036      if(m_pcCfg->getWaveFrontsynchro())
1037      {
1038        CTXMem[1]->loadContexts(m_pcSbacCoder);
1039      }
1040      CTXMem[0]->loadContexts(m_pcSbacCoder);
1041    }
1042  }
1043  // for every CU in slice
1044  UInt uiEncCUOrder;
1045  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1046       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1047       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1048  {
1049    // initialize CU encoder
1050    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1051    pcCU->initCU( rpcPic, uiCUAddr );
1052
1053#if !RATE_CONTROL_LAMBDA_DOMAIN
1054    if(m_pcCfg->getUseRateCtrl())
1055    {
1056      if(m_pcRateCtrl->calculateUnitQP())
1057      {
1058        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
1059      }
1060    }
1061#endif
1062    // inherit from TR if necessary, select substream to use.
1063    if( m_pcCfg->getUseSBACRD() )
1064    {
1065      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1066      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1067      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1068      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1069      uiCol     = uiCUAddr % uiWidthInLCUs;
1070      uiLin     = uiCUAddr / uiWidthInLCUs;
1071      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1072      {
1073        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1074        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1075        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1076                      + uiLin%iNumSubstreamsPerTile;
1077      }
1078      else
1079      {
1080        // dependent tiles => substreams are "per frame".
1081        uiSubStrm = uiLin % iNumSubstreams;
1082      }
1083      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1084      {
1085        // We'll sync if the TR is available.
1086        TComDataCU *pcCUUp = pcCU->getCUAbove();
1087        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1088        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1089        TComDataCU *pcCUTR = NULL;
1090        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1091        {
1092          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1093        }
1094        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1095             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1096             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1097             )
1098           )
1099        {
1100          // TR not available.
1101        }
1102        else
1103        {
1104          // TR is available, we use it.
1105          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1106        }
1107      }
1108      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1109    }
1110
1111    // reset the entropy coder
1112    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1113        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1114        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1115        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1116    {
1117      SliceType sliceType = pcSlice->getSliceType();
1118      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1119      {
1120        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1121      }
1122      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1123      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1124      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1125      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1126    }
1127    // if RD based on SBAC is used
1128    if( m_pcCfg->getUseSBACRD() )
1129    {
1130      // set go-on entropy coder
1131      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1132      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1133     
1134      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1135
1136#if RATE_CONTROL_LAMBDA_DOMAIN
1137      Double oldLambda = m_pcRdCost->getLambda();
1138      if ( m_pcCfg->getUseRateCtrl() )
1139      {
1140        Int estQP        = pcSlice->getSliceQp();
1141        Double estLambda = -1.0;
1142        Double bpp       = -1.0;
1143
1144#if M0036_RC_IMPROVEMENT
1145        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1146#else
1147        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1148#endif
1149        {
1150          estQP = pcSlice->getSliceQp();
1151        }
1152        else
1153        {
1154#if RATE_CONTROL_INTRA
1155          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1156          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1157          {
1158            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1159          }
1160          else
1161          {
1162            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1163            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1164          }
1165#else
1166          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1167          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1168          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1169#endif
1170
1171#if REPN_FORMAT_IN_VPS
1172          estQP     = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, estQP );
1173#else
1174          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1175#endif
1176
1177          m_pcRdCost->setLambda(estLambda);
1178#if M0036_RC_IMPROVEMENT
1179#if RDOQ_CHROMA_LAMBDA
1180          // set lambda for RDOQ
1181          Double weight=m_pcRdCost->getChromaWeight();
1182          m_pcTrQuant->setLambda( estLambda, estLambda / weight );
1183#else
1184          m_pcTrQuant->setLambda( estLambda );
1185#endif
1186#endif
1187        }
1188
1189        m_pcRateCtrl->setRCQP( estQP );
1190        pcCU->getSlice()->setSliceQpBase( estQP );
1191      }
1192#endif
1193
1194      // run CU encoder
1195      m_pcCuEncoder->compressCU( pcCU );
1196
1197#if !TICKET_1090_FIX
1198#if RATE_CONTROL_LAMBDA_DOMAIN
1199      if ( m_pcCfg->getUseRateCtrl() )
1200      {
1201#if !M0036_RC_IMPROVEMENT
1202        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1203#if REPN_FORMAT_IN_VPS
1204        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1205        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->>getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1206#else
1207        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1208        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1209#endif
1210        Double MAD = (Double)SAD / (Double)(height * width);
1211        MAD = MAD * MAD;
1212        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1213#endif
1214
1215        Int actualQP        = g_RCInvalidQPValue;
1216        Double actualLambda = m_pcRdCost->getLambda();
1217        Int actualBits      = pcCU->getTotalBits();
1218        Int numberOfEffectivePixels    = 0;
1219        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1220        {
1221          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1222          {
1223            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1224            break;
1225          }
1226        }
1227
1228        if ( numberOfEffectivePixels == 0 )
1229        {
1230          actualQP = g_RCInvalidQPValue;
1231        }
1232        else
1233        {
1234          actualQP = pcCU->getQP( 0 );
1235        }
1236        m_pcRdCost->setLambda(oldLambda);
1237#if RATE_CONTROL_INTRA
1238        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1239          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1240#else
1241        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1242#endif
1243      }
1244#endif
1245#endif
1246     
1247      // restore entropy coder to an initial stage
1248      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1249      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1250      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1251      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1252      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1253      m_pcBitCounter->resetBits();
1254      pppcRDSbacCoder->setBinsCoded( 0 );
1255      m_pcCuEncoder->encodeCU( pcCU );
1256
1257      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1258      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1259      {
1260        pcSlice->setNextSlice( true );
1261        break;
1262      }
1263      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1264      {
1265        pcSlice->setNextSliceSegment( true );
1266        break;
1267      }
1268      if( m_pcCfg->getUseSBACRD() )
1269      {
1270         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1271       
1272         //Store probabilties of second LCU in line into buffer
1273         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1274        {
1275          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1276        }
1277      }
1278
1279#if TICKET_1090_FIX
1280#if RATE_CONTROL_LAMBDA_DOMAIN
1281      if ( m_pcCfg->getUseRateCtrl() )
1282      {
1283#if !M0036_RC_IMPROVEMENT
1284        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1285#if REPN_FORMAT_IN_VPS
1286        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1287        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1288#else
1289        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1290        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1291#endif
1292        Double MAD = (Double)SAD / (Double)(height * width);
1293        MAD = MAD * MAD;
1294        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1295#endif
1296
1297        Int actualQP        = g_RCInvalidQPValue;
1298        Double actualLambda = m_pcRdCost->getLambda();
1299        Int actualBits      = pcCU->getTotalBits();
1300        Int numberOfEffectivePixels    = 0;
1301        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1302        {
1303          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1304          {
1305            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1306            break;
1307          }
1308        }
1309
1310        if ( numberOfEffectivePixels == 0 )
1311        {
1312          actualQP = g_RCInvalidQPValue;
1313        }
1314        else
1315        {
1316          actualQP = pcCU->getQP( 0 );
1317        }
1318        m_pcRdCost->setLambda(oldLambda);
1319
1320#if RATE_CONTROL_INTRA
1321        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 
1322          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1323#else
1324        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1325#endif
1326      }
1327#endif
1328#endif
1329    }
1330    // other case: encodeCU is not called
1331    else
1332    {
1333      m_pcCuEncoder->compressCU( pcCU );
1334      m_pcCuEncoder->encodeCU( pcCU );
1335      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1336      {
1337        pcSlice->setNextSlice( true );
1338        break;
1339      }
1340      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1341      {
1342        pcSlice->setNextSliceSegment( true );
1343        break;
1344      }
1345    }
1346   
1347    m_uiPicTotalBits += pcCU->getTotalBits();
1348    m_dPicRdCost     += pcCU->getTotalCost();
1349    m_uiPicDist      += pcCU->getTotalDistortion();
1350#if !RATE_CONTROL_LAMBDA_DOMAIN
1351    if(m_pcCfg->getUseRateCtrl())
1352    {
1353      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1354      m_pcRateCtrl->updataRCUnitStatus();
1355    }
1356#endif
1357  }
1358  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1359  {
1360    pcSlice->setNextSlice( true );
1361  }
1362  if( depSliceSegmentsEnabled )
1363  {
1364    if (m_pcCfg->getWaveFrontsynchro())
1365    {
1366      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1367    }
1368     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1369  }
1370  xRestoreWPparam( pcSlice );
1371#if !RATE_CONTROL_LAMBDA_DOMAIN
1372  if(m_pcCfg->getUseRateCtrl())
1373  {
1374    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1375  }
1376#endif
1377}
1378
1379/**
1380 \param  rpcPic        picture class
1381 \retval rpcBitstream  bitstream class
1382 */
1383Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1384{
1385  UInt       uiCUAddr;
1386  UInt       uiStartCUAddr;
1387  UInt       uiBoundingCUAddr;
1388  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1389
1390  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1391  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1392  // choose entropy coder
1393  {
1394    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1395    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1396  }
1397 
1398  m_pcCuEncoder->setBitCounter( NULL );
1399  m_pcBitCounter = NULL;
1400  // Appropriate substream bitstream is switched later.
1401  // for every CU
1402#if ENC_DEC_TRACE
1403  g_bJustDoIt = g_bEncDecTraceEnable;
1404#endif
1405  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1406  DTRACE_CABAC_T( "\tPOC: " );
1407  DTRACE_CABAC_V( rpcPic->getPOC() );
1408  DTRACE_CABAC_T( "\n" );
1409#if ENC_DEC_TRACE
1410  g_bJustDoIt = g_bEncDecTraceDisable;
1411#endif
1412
1413  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1414  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1415  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1416  UInt uiBitsOriginallyInSubstreams = 0;
1417  {
1418    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1419    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1420    {
1421      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1422    }
1423   
1424    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1425    {
1426      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1427    }
1428
1429    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1430    {
1431      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1432    }
1433  }
1434
1435  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1436  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1437  UInt uiTileCol      = 0;
1438  UInt uiTileStartLCU = 0;
1439  UInt uiTileLCUX     = 0;
1440  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1441  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1442                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1443                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1444  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1445  if( depSliceSegmentsEnabled )
1446  {
1447    if( pcSlice->isNextSlice()||
1448        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1449    {
1450      if(m_pcCfg->getWaveFrontsynchro())
1451      {
1452        CTXMem[1]->loadContexts(m_pcSbacCoder);
1453      }
1454      CTXMem[0]->loadContexts(m_pcSbacCoder);
1455    }
1456    else
1457    {
1458      if(m_pcCfg->getWaveFrontsynchro())
1459      {
1460        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1461        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1462        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1463        uiLin     = uiCUAddr / uiWidthInLCUs;
1464        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1465          + uiLin%iNumSubstreamsPerTile;
1466        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1467        {
1468          uiCol     = uiCUAddr % uiWidthInLCUs;
1469          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1470          if(uiCol==uiTileLCUX)
1471          {
1472            CTXMem[0]->loadContexts(m_pcSbacCoder);
1473          }
1474        }
1475      }
1476      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1477    }
1478  }
1479
1480  UInt uiEncCUOrder;
1481  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1482       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1483       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1484  {
1485    if( m_pcCfg->getUseSBACRD() )
1486    {
1487      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1488      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1489      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1490      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1491      uiCol     = uiCUAddr % uiWidthInLCUs;
1492      uiLin     = uiCUAddr / uiWidthInLCUs;
1493      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1494      {
1495        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1496        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1497        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1498                      + uiLin%iNumSubstreamsPerTile;
1499      }
1500      else
1501      {
1502        // dependent tiles => substreams are "per frame".
1503        uiSubStrm = uiLin % iNumSubstreams;
1504      }
1505
1506      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1507      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1508      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1509      {
1510        // We'll sync if the TR is available.
1511        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1512        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1513        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1514        TComDataCU *pcCUTR = NULL;
1515        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1516        {
1517          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1518        }
1519        if ( (true/*bEnforceSliceRestriction*/ &&
1520             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1521             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1522             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1523             ))
1524           )
1525        {
1526          // TR not available.
1527        }
1528        else
1529        {
1530          // TR is available, we use it.
1531          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1532        }
1533      }
1534      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1535    }
1536    // reset the entropy coder
1537    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1538        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1539        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1540        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1541    {
1542      {
1543        // We're crossing into another tile, tiles are independent.
1544        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1545        // have to perform it here.
1546        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1547        {
1548          ; // do nothing.
1549        }
1550        else
1551        {
1552          SliceType sliceType  = pcSlice->getSliceType();
1553          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1554          {
1555            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1556          }
1557          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1558          // Byte-alignment in slice_data() when new tile
1559          pcSubstreams[uiSubStrm].writeByteAlignment();
1560        }
1561      }
1562      {
1563        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1564        UInt uiAccumulatedSubstreamLength = 0;
1565        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1566        {
1567          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1568        }
1569        // add bits coded in previous dependent slices + bits coded so far
1570        // add number of emulation prevention byte count in the tile
1571        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1572      }
1573    }
1574
1575    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1576    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1577    {
1578      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1579      Int iNumCuInWidth     = saoParam->numCuInWidth;
1580      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1581      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1582      Int rx = uiCUAddr % iNumCuInWidth;
1583      Int ry = uiCUAddr / iNumCuInWidth;
1584      Int allowMergeLeft = 1;
1585      Int allowMergeUp   = 1;
1586      if (rx!=0)
1587      {
1588        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1589        {
1590          allowMergeLeft = 0;
1591        }
1592      }
1593      if (ry!=0)
1594      {
1595        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1596        {
1597          allowMergeUp = 0;
1598        }
1599      }
1600      Int addr = pcCU->getAddr();
1601      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1602      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1603      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1604      {
1605        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1606        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1607        if (allowMergeLeft)
1608        {
1609          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1610        }
1611        else
1612        {
1613          mergeLeft = 0;
1614        }
1615        if(mergeLeft == 0)
1616        {
1617          if (allowMergeUp)
1618          {
1619            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1620          }
1621          else
1622          {
1623            mergeUp = 0;
1624          }
1625          if(mergeUp == 0)
1626          {
1627            for (Int compIdx=0;compIdx<3;compIdx++)
1628            {
1629            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1630              {
1631                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1632              }
1633            }
1634          }
1635        }
1636      }
1637    }
1638    else if (pcSlice->getSPS()->getUseSAO())
1639    {
1640      Int addr = pcCU->getAddr();
1641      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1642      for (Int cIdx=0; cIdx<3; cIdx++)
1643      {
1644        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1645        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1646        {
1647          saoLcuParam->mergeUpFlag   = 0;
1648          saoLcuParam->mergeLeftFlag = 0;
1649          saoLcuParam->subTypeIdx    = 0;
1650          saoLcuParam->typeIdx       = -1;
1651          saoLcuParam->offset[0]     = 0;
1652          saoLcuParam->offset[1]     = 0;
1653          saoLcuParam->offset[2]     = 0;
1654          saoLcuParam->offset[3]     = 0;
1655        }
1656      }
1657    }
1658#if ENC_DEC_TRACE
1659    g_bJustDoIt = g_bEncDecTraceEnable;
1660#endif
1661    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1662      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1663    {
1664      m_pcCuEncoder->encodeCU( pcCU );
1665    }
1666    else
1667    {
1668      m_pcCuEncoder->encodeCU( pcCU );
1669    }
1670#if ENC_DEC_TRACE
1671    g_bJustDoIt = g_bEncDecTraceDisable;
1672#endif   
1673    if( m_pcCfg->getUseSBACRD() )
1674    {
1675       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1676       
1677
1678       //Store probabilties of second LCU in line into buffer
1679       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1680      {
1681        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1682      }
1683    }
1684  }
1685  if( depSliceSegmentsEnabled )
1686  {
1687    if (m_pcCfg->getWaveFrontsynchro())
1688    {
1689      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1690    }
1691    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1692  }
1693#if ADAPTIVE_QP_SELECTION
1694  if( m_pcCfg->getUseAdaptQpSelect() )
1695  {
1696    m_pcTrQuant->storeSliceQpNext(pcSlice);
1697  }
1698#endif
1699  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1700  {
1701    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1702    {
1703      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1704    }
1705    else
1706    {
1707      m_pcEntropyCoder->determineCabacInitIdx();
1708    }
1709  }
1710}
1711
1712/** Determines the starting and bounding LCU address of current slice / dependent slice
1713 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1714 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1715 */
1716Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1717{
1718  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1719  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1720  UInt tileIdxIncrement;
1721  UInt tileIdx;
1722  UInt tileWidthInLcu;
1723  UInt tileHeightInLcu;
1724  UInt tileTotalCount;
1725
1726  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1727  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1728  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1729  if (bEncodeSlice) 
1730  {
1731    UInt uiCUAddrIncrement;
1732    switch (m_pcCfg->getSliceMode())
1733    {
1734    case FIXED_NUMBER_OF_LCU:
1735      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1736      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1737      break;
1738    case FIXED_NUMBER_OF_BYTES:
1739      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1740      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1741      break;
1742    case FIXED_NUMBER_OF_TILES:
1743      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1744        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1745        );
1746      uiCUAddrIncrement        = 0;
1747      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1748
1749      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1750      {
1751        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1752        {
1753          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1754          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1755          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1756        }
1757      }
1758
1759      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1760      break;
1761    default:
1762      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1763      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1764      break;
1765    } 
1766    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1767    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1768    {
1769      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1770    }
1771    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1772  }
1773  else
1774  {
1775    UInt uiCUAddrIncrement     ;
1776    switch (m_pcCfg->getSliceMode())
1777    {
1778    case FIXED_NUMBER_OF_LCU:
1779      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1780      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1781      break;
1782    case FIXED_NUMBER_OF_TILES:
1783      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1784        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1785        );
1786      uiCUAddrIncrement        = 0;
1787      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1788
1789      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1790      {
1791        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1792        {
1793          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1794          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1795          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1796        }
1797      }
1798
1799      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1800      break;
1801    default:
1802      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1803      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1804      break;
1805    } 
1806    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1807    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1808    {
1809      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1810    }
1811    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1812  }
1813
1814  Bool tileBoundary = false;
1815  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1816      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1817  {
1818    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1819    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1820    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1821    UInt tileBoundingCUAddrSlice = 0;
1822    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1823    {
1824      lcuEncAddr++;
1825      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1826    }
1827    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1828   
1829    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1830    {
1831      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1832      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1833      tileBoundary = true;
1834    }
1835  }
1836
1837  // Dependent slice
1838  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1839  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1840  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1841  if (bEncodeSlice) 
1842  {
1843    UInt uiCUAddrIncrement;
1844    switch (m_pcCfg->getSliceSegmentMode())
1845    {
1846    case FIXED_NUMBER_OF_LCU:
1847      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1848      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1849      break;
1850    case FIXED_NUMBER_OF_BYTES:
1851      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1852      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1853      break;
1854    case FIXED_NUMBER_OF_TILES:
1855      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1856        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1857        );
1858      uiCUAddrIncrement        = 0;
1859      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1860
1861      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1862      {
1863        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1864        {
1865          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1866          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1867          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1868        }
1869      }
1870      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1871      break;
1872    default:
1873      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1874      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1875      break;
1876    } 
1877    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1878    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1879    {
1880      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1881    }
1882    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1883  }
1884  else
1885  {
1886    UInt uiCUAddrIncrement;
1887    switch (m_pcCfg->getSliceSegmentMode())
1888    {
1889    case FIXED_NUMBER_OF_LCU:
1890      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1891      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1892      break;
1893    case FIXED_NUMBER_OF_TILES:
1894      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1895        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1896        );
1897      uiCUAddrIncrement        = 0;
1898      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1899
1900      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1901      {
1902        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1903        {
1904          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1905          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1906          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1907        }
1908      }
1909      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1910      break;
1911    default:
1912      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1913      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1914      break;
1915    } 
1916    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1917    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1918    {
1919      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1920    }
1921    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1922  }
1923  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1924    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1925  {
1926    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1927    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1928    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1929    UInt tileBoundingCUAddrSlice = 0;
1930    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1931    {
1932      lcuEncAddr++;
1933      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1934    }
1935    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1936
1937    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1938    {
1939      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1940      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1941      tileBoundary = true;
1942    }
1943  }
1944
1945  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1946  {
1947    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1948    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1949  }
1950
1951  //calculate real dependent slice start address
1952  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1953  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1954  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1955  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1956#if REPN_FORMAT_IN_VPS
1957  UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
1958  UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
1959#else
1960  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1961  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1962#endif
1963  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1964  {
1965    uiInternalAddress++;
1966    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1967    {
1968      uiInternalAddress=0;
1969      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1970    }
1971    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1972    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1973  }
1974  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1975 
1976  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1977  startCUAddrSliceSegment=uiRealStartAddress;
1978 
1979  //calculate real slice start address
1980  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1981  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1982  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1983  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1984#if REPN_FORMAT_IN_VPS
1985  uiWidth = pcSlice->getPicWidthInLumaSamples();
1986  uiHeight = pcSlice->getPicHeightInLumaSamples();
1987#else
1988  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1989  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1990#endif
1991  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1992  {
1993    uiInternalAddress++;
1994    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1995    {
1996      uiInternalAddress=0;
1997      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1998    }
1999    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2000    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2001  }
2002  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
2003 
2004  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
2005  uiStartCUAddrSlice=uiRealStartAddress;
2006 
2007  // Make a joint decision based on reconstruction and dependent slice bounds
2008  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
2009  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
2010
2011
2012  if (!bEncodeSlice)
2013  {
2014    // 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
2015    // first. Set the flags accordingly.
2016    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2017      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2018      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
2019      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2020      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
2021      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
2022      || tileBoundary
2023)
2024    {
2025      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
2026      {
2027        pcSlice->setNextSlice       ( true );
2028        pcSlice->setNextSliceSegment( false );
2029      }
2030      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
2031      {
2032        pcSlice->setNextSlice       ( false );
2033        pcSlice->setNextSliceSegment( true );
2034      }
2035      else
2036      {
2037        pcSlice->setNextSlice       ( true );
2038        pcSlice->setNextSliceSegment( true );
2039      }
2040    }
2041    else
2042    {
2043      pcSlice->setNextSlice       ( false );
2044      pcSlice->setNextSliceSegment( false );
2045    }
2046  }
2047}
2048
2049Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
2050{
2051  return 4.2005*log(lambda) + 13.7122;
2052}
2053
2054#if JCTVC_M0259_LAMBDAREFINEMENT
2055Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
2056{
2057  double tmp = beta * pow( 2.0 , deltaQP / 6 );
2058  double gamma = tmp / ( tmp + 1 );
2059  return( gamma );
2060}
2061#endif
2062//! \}
Note: See TracBrowser for help on using the repository browser.