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

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