source: 3DVCSoftware/branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSlice.cpp @ 1003

Last change on this file since 1003 was 418, checked in by mitsubishi-htm, 12 years ago

-Update variable names.
-Some format improvements.

  • Property svn:eol-style set to native
File size: 59.6 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  }
790#endif
791
792  if( m_pcCfg->getUseSBACRD() )
793  {
794    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
795    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
796    delete[] m_pcBufferSbacCoders;
797    delete[] m_pcBufferBinCoderCABACs;
798    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
799    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
800    for (int ui = 0; ui < uiTilesAcross; ui++)
801    {
802      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
803    }
804    for (UInt ui = 0; ui < uiTilesAcross; ui++)
805    {
806      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
807    }
808
809    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
810    {
811      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
812    }
813  }
814  //if( m_pcCfg->getUseSBACRD() )
815  {
816    delete[] m_pcBufferLowLatSbacCoders;
817    delete[] m_pcBufferLowLatBinCoderCABACs;
818    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
819    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
820    for (int ui = 0; ui < uiTilesAcross; ui++)
821    {
822      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
823    }
824    for (UInt ui = 0; ui < uiTilesAcross; ui++)
825      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
826  }
827
828#if MERL_VSP_C0152
829  // Send Depth/Texture pointers to slice level
830#if !MERL_VSP_NBDV_RefVId_Fix_D0166
831  pcSlice->setBWVSPLUTParam(m_aiShiftLUT, m_iShiftPrec);
832#endif
833  pcSlice->setRefPicBaseTxt(m_pPicBaseTxt);
834  pcSlice->setRefPicBaseDepth(m_pPicBaseDepth);
835#if MERL_VSP_NBDV_RefVId_Fix_D0166
836  for (Int refViewId=0; refViewId < pcSlice->getViewId(); refViewId++)
837  {
838    assert( m_pcListDepthPic[refViewId] );
839    pcSlice->setListDepthPic(m_pcListDepthPic[refViewId], refViewId);
840    pcSlice->setBWVSPLUTParam(m_aiShiftLUT[refViewId], m_iShiftPrec, refViewId);
841  }
842#endif
843#endif
844
845  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
846  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
847  UInt uiCol=0, uiLin=0, uiSubStrm=0;
848  UInt uiTileCol      = 0;
849  UInt uiTileStartLCU = 0;
850  UInt uiTileLCUX     = 0;
851#if !QC_MVHEVC_B0046
852  Int iLastPosY = -1;
853#endif
854  // for every CU in slice
855  UInt uiEncCUOrder;
856  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
857  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
858       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
859       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
860  {
861    // initialize CU encoder
862    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
863    pcCU->initCU( rpcPic, uiCUAddr );
864#if !QC_MVHEVC_B0046
865    if ( m_pcRdCost->getUseRenModel() )
866    {
867      // updated renderer model if necessary
868      Int iCurPosX;
869      Int iCurPosY; 
870      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
871      if ( iCurPosY != iLastPosY )
872      {
873        iLastPosY = iCurPosY; 
874       
875        m_pcGOPEncoder->getEncTop()->getEncTop()->setupRenModel( rpcPic->getCurrSlice()->getPOC() , rpcPic->getCurrSlice()->getSPS()->getViewId(), rpcPic->getCurrSlice()->getSPS()->isDepth() ? 1 : 0, iCurPosY );
876      }
877    }   
878#endif
879    // inherit from TR if necessary, select substream to use.
880    if( m_pcCfg->getUseSBACRD() )
881    {
882      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
883      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
884      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
885      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
886      uiCol     = uiCUAddr % uiWidthInLCUs;
887      uiLin     = uiCUAddr / uiWidthInLCUs;
888      if (pcSlice->getPPS()->getNumSubstreams() > 1)
889      {
890        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
891        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
892        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
893                      + uiLin%iNumSubstreamsPerTile;
894      }
895      else
896      {
897        // dependent tiles => substreams are "per frame".
898        uiSubStrm = uiLin % iNumSubstreams;
899      }
900      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
901      {
902        // We'll sync if the TR is available.
903        TComDataCU *pcCUUp = pcCU->getCUAbove();
904        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
905        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
906        TComDataCU *pcCUTR = NULL;
907        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
908        {
909          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
910        }
911        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
912             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
913             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
914             )||
915             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
916             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
917             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
918             )
919           )
920        {
921          // TR not available.
922        }
923        else
924        {
925          // TR is available, we use it.
926          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
927        }
928      }
929      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
930    }
931
932    // reset the entropy coder
933    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
934        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
935        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
936    {
937#if CABAC_INIT_FLAG
938      SliceType sliceType = pcSlice->getSliceType();
939      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
940      {
941        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
942      }
943      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
944      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
945      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
946      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
947#else
948      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp(), false );
949      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
950      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp() );
951      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
952#endif
953    }
954    // if RD based on SBAC is used
955    if( m_pcCfg->getUseSBACRD() )
956    {
957      // set go-on entropy coder
958      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
959      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
960     
961      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
962      // run CU encoder
963      m_pcCuEncoder->compressCU( pcCU );
964     
965      // restore entropy coder to an initial stage
966      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
967      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
968      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
969      m_pcBitCounter = &pcBitCounters[uiSubStrm];
970      pppcRDSbacCoder->setBinCountingEnableFlag( true );
971      m_pcBitCounter->resetBits();
972      pppcRDSbacCoder->setBinsCoded( 0 );
973      m_pcCuEncoder->encodeCU( pcCU );
974
975      pppcRDSbacCoder->setBinCountingEnableFlag( false );
976      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
977      {
978        pcSlice->setNextSlice( true );
979        break;
980      }
981      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
982      {
983        pcSlice->setNextEntropySlice( true );
984        break;
985      }
986      if( m_pcCfg->getUseSBACRD() )
987      {
988         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
989       
990         //Store probabilties of second LCU in line into buffer
991        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
992        {
993          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
994        }
995      }
996    }
997    // other case: encodeCU is not called
998    else
999    {
1000      m_pcCuEncoder->compressCU( pcCU );
1001      m_pcCuEncoder->encodeCU( pcCU );
1002      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1003      {
1004        pcSlice->setNextSlice( true );
1005        break;
1006      }
1007      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1008      {
1009        pcSlice->setNextEntropySlice( true );
1010        break;
1011      }
1012    }
1013   
1014    m_uiPicTotalBits += pcCU->getTotalBits();
1015    m_dPicRdCost     += pcCU->getTotalCost();
1016    m_uiPicDist      += pcCU->getTotalDistortion();
1017  }
1018  xRestoreWPparam( pcSlice );
1019}
1020
1021/**
1022 \param  rpcPic        picture class
1023 \retval rpcBitstream  bitstream class
1024 */
1025Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
1026{
1027  UInt       uiCUAddr;
1028  UInt       uiStartCUAddr;
1029  UInt       uiBoundingCUAddr;
1030  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1031
1032  uiStartCUAddr=pcSlice->getEntropySliceCurStartCUAddr();
1033  uiBoundingCUAddr=pcSlice->getEntropySliceCurEndCUAddr();
1034  // choose entropy coder
1035  {
1036    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1037    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1038  }
1039 
1040  m_pcCuEncoder->setBitCounter( NULL );
1041  m_pcBitCounter = NULL;
1042  // Appropriate substream bitstream is switched later.
1043  // for every CU
1044#if ENC_DEC_TRACE
1045  g_bJustDoIt = g_bEncDecTraceEnable;
1046#endif
1047  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1048  DTRACE_CABAC_T( "\tPOC: " );
1049  DTRACE_CABAC_V( rpcPic->getPOC() );
1050  DTRACE_CABAC_T( "\n" );
1051#if ENC_DEC_TRACE
1052  g_bJustDoIt = g_bEncDecTraceDisable;
1053#endif
1054
1055  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1056  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1057  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1058  UInt uiBitsOriginallyInSubstreams = 0;
1059  {
1060    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1061    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1062    {
1063      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1064    }
1065   
1066    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1067    {
1068      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1069    }
1070
1071    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1072    {
1073      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1074    }
1075  }
1076
1077  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1078  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1079  UInt uiTileCol      = 0;
1080  UInt uiTileStartLCU = 0;
1081  UInt uiTileLCUX     = 0;
1082
1083  UInt uiEncCUOrder;
1084
1085  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1086                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1087                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1088  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1089       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1090       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1091  {
1092    if( m_pcCfg->getUseSBACRD() )
1093    {
1094      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1095      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1096      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1097      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1098      uiCol     = uiCUAddr % uiWidthInLCUs;
1099      uiLin     = uiCUAddr / uiWidthInLCUs;
1100      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1101      {
1102        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1103        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1104        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1105                      + uiLin%iNumSubstreamsPerTile;
1106      }
1107      else
1108      {
1109        // dependent tiles => substreams are "per frame".
1110        uiSubStrm = uiLin % iNumSubstreams;
1111      }
1112
1113      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1114
1115      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1116      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1117      {
1118        // We'll sync if the TR is available.
1119        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1120        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1121        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1122        TComDataCU *pcCUTR = NULL;
1123        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1124        {
1125          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1126        }
1127        if ( (true/*bEnforceSliceRestriction*/ &&
1128             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1129             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1130             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1131             ))||
1132             (true/*bEnforceEntropySliceRestriction*/ &&
1133             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1134             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
1135             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1136             ))
1137           )
1138        {
1139          // TR not available.
1140        }
1141        else
1142        {
1143          // TR is available, we use it.
1144          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1145        }
1146      }
1147      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1148    }
1149    // reset the entropy coder
1150    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1151        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1152        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1153    {
1154      Int iTileIdx            = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr);
1155      Bool bWriteTileMarker   = false;
1156      // check if current iTileIdx should have a marker
1157      for (Int iEntryIdx=0; iEntryIdx<m_pcCfg->getMaxTileMarkerEntryPoints()-1; iEntryIdx++)
1158      {
1159        bWriteTileMarker = ( (((Int)((iEntryIdx+1)*m_pcCfg->getMaxTileMarkerOffset()+0.5)) == iTileIdx ) && iEntryIdx < (m_pcCfg->getMaxTileMarkerEntryPoints()-1)) ? true : false;
1160        if (bWriteTileMarker)
1161        {
1162          break;
1163        }
1164      }
1165      {
1166        // We're crossing into another tile, tiles are independent.
1167        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1168        // have to perform it here.
1169        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1170        {
1171          ; // do nothing.
1172        }
1173        else
1174        {
1175#if CABAC_INIT_FLAG
1176          SliceType sliceType  = pcSlice->getSliceType();
1177          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
1178          {
1179            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1180          }
1181          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1182#else
1183          m_pcEntropyCoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
1184#endif
1185          pcSubstreams[uiSubStrm].write( 1, 1 );
1186          pcSubstreams[uiSubStrm].writeAlignZero();
1187        }
1188      }
1189      {
1190        // Write TileMarker into the appropriate substream (nothing has been written to it yet).
1191        if (m_pcCfg->getTileMarkerFlag() && bWriteTileMarker)
1192        {
1193          // Log locations where tile markers are to be inserted during emulation prevention
1194          UInt uiMarkerCount = pcSubstreams[uiSubStrm].getTileMarkerLocationCount();
1195          pcSubstreams[uiSubStrm].setTileMarkerLocation     ( uiMarkerCount, pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3 );
1196          pcSubstreams[uiSubStrm].setTileMarkerLocationCount( uiMarkerCount + 1 );
1197          // Write tile index
1198          m_pcEntropyCoder->writeTileMarker(iTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx()); // Tile index
1199        }
1200
1201       
1202        UInt uiAccumulatedSubstreamLength = 0;
1203        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1204        {
1205          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1206        }
1207        UInt uiLocationCount = pcSlice->getTileLocationCount();
1208        // add bits coded in previous entropy slices + bits coded so far
1209        pcSlice->setTileLocation( uiLocationCount, (pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3 ); 
1210        pcSlice->setTileLocationCount( uiLocationCount + 1 );
1211      }
1212    }
1213
1214#if H3D_QTL
1215    rpcPic->setReduceBitsFlag(true);
1216#endif
1217
1218    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1219
1220    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
1221    {
1222      Int iNumCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
1223      Int iCUAddrInSlice    = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU());
1224      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1225      Int rx = uiCUAddr % iNumCuInWidth;
1226      Int ry = uiCUAddr / iNumCuInWidth;
1227      m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
1228    }
1229#if ENC_DEC_TRACE
1230    g_bJustDoIt = g_bEncDecTraceEnable;
1231#endif
1232    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && 
1233      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1234    {
1235      m_pcCuEncoder->encodeCU( pcCU, true );
1236    }
1237    else
1238    {
1239      m_pcCuEncoder->encodeCU( pcCU );
1240    }
1241#if ENC_DEC_TRACE
1242    g_bJustDoIt = g_bEncDecTraceDisable;
1243#endif   
1244    if( m_pcCfg->getUseSBACRD() )
1245    {
1246       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1247       
1248
1249       //Store probabilties of second LCU in line into buffer
1250      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1251      {
1252        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1253      }
1254    }
1255
1256#if H3D_QTL
1257    rpcPic->setReduceBitsFlag(false);
1258#endif
1259
1260  }
1261
1262#if ADAPTIVE_QP_SELECTION
1263  if( m_pcCfg->getUseAdaptQpSelect() )
1264  {
1265    m_pcTrQuant->storeSliceQpNext(pcSlice);
1266  }
1267#endif
1268#if CABAC_INIT_FLAG
1269  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1270  {
1271    m_pcEntropyCoder->determineCabacInitIdx();
1272  }
1273#endif
1274}
1275
1276/** Determines the starting and bounding LCU address of current slice / entropy slice
1277 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1278 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1279 */
1280Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1281{
1282  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1283  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1284  UInt tileIdxIncrement;
1285  UInt tileIdx;
1286  UInt tileWidthInLcu;
1287  UInt tileHeightInLcu;
1288  UInt tileTotalCount;
1289
1290  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1291  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1292  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1293  if (bEncodeSlice) 
1294  {
1295    UInt uiCUAddrIncrement;
1296    switch (m_pcCfg->getSliceMode())
1297    {
1298    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1299      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1300      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1301      break;
1302    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1303      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1304      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1305      break;
1306    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1307      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1308        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1309        );
1310      uiCUAddrIncrement        = 0;
1311      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1312
1313      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1314      {
1315        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1316        {
1317          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1318          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1319          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1320        }
1321      }
1322
1323      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1324      break;
1325    default:
1326      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1327      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1328      break;
1329    } 
1330    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1331  }
1332  else
1333  {
1334    UInt uiCUAddrIncrement     ;
1335    switch (m_pcCfg->getSliceMode())
1336    {
1337    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1338      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1339      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1340      break;
1341    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1342      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1343        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1344        );
1345      uiCUAddrIncrement        = 0;
1346      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1347
1348      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1349      {
1350        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1351        {
1352          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1353          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1354          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1355        }
1356      }
1357
1358      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1359      break;
1360    default:
1361      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1362      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1363      break;
1364    } 
1365    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1366  }
1367
1368  Bool tileBoundary = false;
1369  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) && 
1370      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1371  {
1372    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1373    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1374    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1375    UInt tileBoundingCUAddrSlice = 0;
1376    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1377    {
1378      lcuEncAddr++;
1379      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1380    }
1381    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1382   
1383    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1384    {
1385      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1386      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1387      tileBoundary = true;
1388    }
1389  }
1390
1391  // Entropy slice
1392  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
1393  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
1394  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
1395  if (bEncodeSlice) 
1396  {
1397    UInt uiCUAddrIncrement;
1398    switch (m_pcCfg->getEntropySliceMode())
1399    {
1400    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1401      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1402      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1403      break;
1404    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
1405      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1406      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
1407      break;
1408    default:
1409      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1410      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1411      break;
1412    } 
1413    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1414  }
1415  else
1416  {
1417    UInt uiCUAddrIncrement;
1418    switch (m_pcCfg->getEntropySliceMode())
1419    {
1420    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1421      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1422      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1423      break;
1424    default:
1425      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1426      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1427      break;
1428    } 
1429    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1430  }
1431  if(uiBoundingCUAddrEntropySlice>uiBoundingCUAddrSlice)
1432  {
1433    uiBoundingCUAddrEntropySlice = uiBoundingCUAddrSlice;
1434    pcSlice->setEntropySliceCurEndCUAddr(uiBoundingCUAddrSlice);
1435  }
1436  //calculate real entropy slice start address
1437  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1438  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1439  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1440  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1441  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1442  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1443  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1444  {
1445    uiInternalAddress++;
1446    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1447    {
1448      uiInternalAddress=0;
1449      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1450    }
1451    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1452    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1453  }
1454  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1455 
1456  pcSlice->setEntropySliceCurStartCUAddr(uiRealStartAddress);
1457  uiStartCUAddrEntropySlice=uiRealStartAddress;
1458 
1459  //calculate real slice start address
1460  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1461  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1462  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1463  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1464  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1465  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1466  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1467  {
1468    uiInternalAddress++;
1469    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1470    {
1471      uiInternalAddress=0;
1472      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1473    }
1474    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1475    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1476  }
1477  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1478 
1479  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1480  uiStartCUAddrSlice=uiRealStartAddress;
1481 
1482  // Make a joint decision based on reconstruction and entropy slice bounds
1483  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
1484  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
1485
1486
1487  if (!bEncodeSlice)
1488  {
1489    // 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
1490    // first. Set the flags accordingly.
1491    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1492      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1493      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1494      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1495      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1496      || tileBoundary
1497)
1498    {
1499      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
1500      {
1501        pcSlice->setNextSlice       ( true );
1502        pcSlice->setNextEntropySlice( false );
1503      }
1504      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
1505      {
1506        pcSlice->setNextSlice       ( false );
1507        pcSlice->setNextEntropySlice( true );
1508      }
1509      else
1510      {
1511        pcSlice->setNextSlice       ( true );
1512        pcSlice->setNextEntropySlice( true );
1513      }
1514    }
1515    else
1516    {
1517      pcSlice->setNextSlice       ( false );
1518      pcSlice->setNextEntropySlice( false );
1519    }
1520  }
1521}
1522//! \}
Note: See TracBrowser for help on using the repository browser.