source: 3DVCSoftware/branches/0.1-poznan-univ/source/Lib/TLibEncoder/TEncSlice.cpp @ 4

Last change on this file since 4 was 2, checked in by hhi, 13 years ago

inital import

  • Property svn:eol-style set to native
File size: 25.6 KB
Line 
1
2
3/** \file     TEncSlice.cpp
4    \brief    slice encoder class
5*/
6
7#include "TEncTop.h"
8#include "TEncSlice.h"
9
10// ====================================================================================================================
11// Constructor / destructor / create / destroy
12// ====================================================================================================================
13
14TEncSlice::TEncSlice()
15{
16  m_apcPicYuvPred = NULL;
17  m_apcPicYuvResi = NULL;
18 
19  m_pdRdPicLambda = NULL;
20  m_pdRdPicQp     = NULL;
21  m_piRdPicQp     = NULL;
22}
23
24TEncSlice::~TEncSlice()
25{
26}
27
28Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
29{
30  // create prediction picture
31  if ( m_apcPicYuvPred == NULL )
32  {
33    m_apcPicYuvPred  = new TComPicYuv;
34    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
35  }
36 
37  // create residual picture
38  if( m_apcPicYuvResi == NULL )
39  {
40    m_apcPicYuvResi  = new TComPicYuv;
41    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
42  }
43}
44
45Void TEncSlice::destroy()
46{
47  // destroy prediction picture
48  if ( m_apcPicYuvPred )
49  {
50    m_apcPicYuvPred->destroy();
51    delete m_apcPicYuvPred;
52    m_apcPicYuvPred  = NULL;
53  }
54 
55  // destroy residual picture
56  if ( m_apcPicYuvResi )
57  {
58    m_apcPicYuvResi->destroy();
59    delete m_apcPicYuvResi;
60    m_apcPicYuvResi  = NULL;
61  }
62 
63  // free lambda and QP arrays
64  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
65  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
66  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
67}
68
69Void TEncSlice::init( TEncTop* pcEncTop )
70{
71  m_pcCfg             = pcEncTop;
72  m_pcListPic         = pcEncTop->getListPic();
73 
74  //SB
75  m_pcPicEncoder      = pcEncTop->getPicEncoder();
76  m_pcCuEncoder       = pcEncTop->getCuEncoder();
77  m_pcPredSearch      = pcEncTop->getPredSearch();
78 
79  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
80  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
81  m_pcSbacCoder       = pcEncTop->getSbacCoder();
82  m_pcBinCABAC        = pcEncTop->getBinCABAC();
83  m_pcTrQuant         = pcEncTop->getTrQuant();
84 
85  m_pcBitCounter      = pcEncTop->getBitCounter();
86  m_pcRdCost          = pcEncTop->getRdCost();
87  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
88  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
89 
90  // create lambda and QP arrays
91  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
92  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
93  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
94}
95
96/**
97 - non-referenced frame marking
98 - QP computation based on temporal structure
99 - lambda computation based on QP
100 .
101 \param pcPic         picture class
102 \param iPOCLast      POC of last picture
103 \param uiPOCCurr     current POC
104 \param iNumPicRcvd   number of received pictures
105 \param iTimeOffset   POC offset for hierarchical structure
106 \param iDepth        temporal layer depth
107 \param rpcSlice      slice header class
108 */
109Void TEncSlice::initEncSlice( TComPic* pcPic, TComSlice*& rpcSlice )
110{
111  Double dQP;
112  Double dLambda;
113 
114  rpcSlice = pcPic->getSlice(0);
115  rpcSlice->setSliceBits(0);
116  rpcSlice->setPic( pcPic );
117  rpcSlice->initSlice();
118  rpcSlice->setPOC( pcPic->getPOC() );
119 
120  // slice type
121  SliceType eSliceType  = pcPic->getSliceType()  ;
122  rpcSlice->setSliceType    ( eSliceType );
123 
124  // ------------------------------------------------------------------------------------------------------------------
125  // Non-referenced frame marking
126  // ------------------------------------------------------------------------------------------------------------------
127 
128  rpcSlice->setReferenced(pcPic->getReferenced()) ;
129 
130  // ------------------------------------------------------------------------------------------------------------------
131  // QP setting
132  // ------------------------------------------------------------------------------------------------------------------
133
134  Double dOrigQP = double(pcPic->getQP());
135 
136  // ------------------------------------------------------------------------------------------------------------------
137  // Lambda computation
138  // ------------------------------------------------------------------------------------------------------------------
139 
140  Int iQP;
141
142  // pre-compute lambda and QP values for all possible QP candidates
143#if QC_MOD_LCEC_RDOQ
144  m_pcTrQuant->setRDOQOffset(1);
145#endif
146
147  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
148  {
149    // compute QP value
150    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
151   
152    // compute lambda value
153    Int    NumberBFrames = ( m_pcCfg->getRateGOPSize() - 1 );
154    Int    SHIFT_QP = 12;
155    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
156#if FULL_NBIT
157    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
158#else
159    Int    bitdepth_luma_qp_scale = 0;
160#endif
161    Double qp_temp = (double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
162#if FULL_NBIT
163    Double qp_temp_orig = (double) dQP - SHIFT_QP;
164#endif
165    // Case #1: I or P-slices (key-frame)
166    if(eSliceType == I_SLICE || eSliceType == P_SLICE )
167    {
168      if ( m_pcCfg->getUseRDOQ() && rpcSlice->isIntra() && dQP == dOrigQP )
169      {
170        dLambda = 0.57 * pow( 2.0, qp_temp/3.0 );
171      }
172      else
173      {
174        if ( NumberBFrames > 0 ) // HB structure or HP structure
175        {
176          dLambda = 0.68 * pow( 2.0, qp_temp/3.0 );
177        }
178        else                     // IPP structure
179        {
180          dLambda = 0.85 * pow( 2.0, qp_temp/3.0 );
181        }
182      }
183      dLambda *= dLambda_scale;
184    }
185    else // P or B slices for HB or HP structure
186    {
187      dLambda = 0.68 * pow( 2.0, qp_temp/3.0 );
188      if ( pcPic->getSlice(0)->isInterB () )
189      {
190#if FULL_NBIT
191        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
192#else
193        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
194#endif
195        if ( rpcSlice->isReferenced() ) // HB structure and referenced
196        {
197          dLambda *= 0.80;
198          dLambda *= dLambda_scale;
199        }
200      }
201      else
202      {
203        dLambda *= dLambda_scale;
204      }
205    }
206    // if hadamard is used in ME process
207    if ( !m_pcCfg->getUseHADME() ) dLambda *= 0.95;
208   
209    iQP = Max( MIN_QP, Min( MAX_QP, (Int)floor( dQP + 0.5 ) ) );
210   
211    m_pdRdPicLambda[iDQpIdx] = dLambda;
212    m_pdRdPicQp    [iDQpIdx] = dQP;
213    m_piRdPicQp    [iDQpIdx] = iQP;
214  }
215 
216  // obtain dQP = 0 case
217  dLambda = m_pdRdPicLambda[0];
218  dQP     = m_pdRdPicQp    [0];
219  iQP     = m_piRdPicQp    [0];
220 
221  // store lambda
222//GT VSO
223  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->isDepthCoder()  );   
224  m_pcRdCost->setLambdaVSO( dLambda * m_pcCfg->getLambdaScaleVSO() ); 
225//GT VSO end
226
227  m_pcRdCost ->setLambda      ( dLambda );
228  m_pcTrQuant->setLambda      ( dLambda );
229  rpcSlice   ->setLambda      ( dLambda );
230  m_pcRdCost ->setLambdaMVReg ( dLambda * m_pcCfg->getMultiviewMvRegLambdaScale() );
231 
232//#if HB_LAMBDA_FOR_LDC
233//  // restore original slice type
234//  if ( m_pcCfg->getUseLDC() )
235//  {
236//    eSliceType = P_SLICE;
237//  }
238//  eSliceType = (iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
239// 
240//  rpcSlice->setSliceType        ( eSliceType );
241//#endif
242 
243  rpcSlice->setSliceQp          ( iQP );
244  rpcSlice->setSliceQpDelta     ( 0 );
245  rpcSlice->setNumRefIdx        ( REF_PIC_LIST_0, eSliceType == I_SLICE ? 0 : pcPic->getNumRefs(REF_PIC_LIST_0) ) ;
246  rpcSlice->setNumRefIdx        ( REF_PIC_LIST_1, eSliceType == I_SLICE ? 0 : pcPic->getNumRefs(REF_PIC_LIST_1) ) ;
247 
248  rpcSlice->setSymbolMode       ( m_pcCfg->getSymbolMode());
249  rpcSlice->setLoopFilterDisable( m_pcCfg->getLoopFilterDisable() );
250 
251  rpcSlice->setDepth            ( 0 );
252  rpcSlice->setViewIdx          ( pcPic->getViewIdx() );
253
254  rpcSlice->setColDir( pcPic->getColDir());
255
256  assert( m_apcPicYuvPred );
257  assert( m_apcPicYuvResi );
258 
259  pcPic->setPicYuvPred( m_apcPicYuvPred );
260  pcPic->setPicYuvResi( m_apcPicYuvResi );
261  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
262  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
263  rpcSlice->setEntropySliceMode     ( m_pcCfg->getEntropySliceMode()     );
264  rpcSlice->setEntropySliceArgument ( m_pcCfg->getEntropySliceArgument() );
265}
266
267// ====================================================================================================================
268// Public member functions
269// ====================================================================================================================
270
271Void TEncSlice::setSearchRange( TComSlice* pcSlice )
272{
273  Int iCurrPOC = pcSlice->getPOC();
274  Int iRefPOC;
275  Int iRateGOPSize = m_pcCfg->getRateGOPSize();
276  Int iOffset = (iRateGOPSize >> 1);
277  Int iMaxSR = m_pcCfg->getSearchRange();
278  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
279 
280  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
281  {
282    RefPicList e = (RefPicList)iDir;
283    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
284    {
285      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
286      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iRateGOPSize);
287      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
288    }
289  }
290}
291
292/**
293 - multi-loop slice encoding for different slice QP
294 .
295 \param rpcPic    picture class
296 */
297Void TEncSlice::precompressSlice( TComPic*& rpcPic )
298{
299  // if deltaQP RD is not used, simply return
300  if ( m_pcCfg->getDeltaQpRD() == 0 ) return;
301 
302  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
303  Double     dPicRdCostBest = MAX_DOUBLE;
304  Double dSumCURdCostBest;
305  UInt64     uiPicDistBest;
306  UInt64     uiPicBitsBest;
307  UInt       uiQpIdxBest = 0;
308 
309  Double dFrameLambda;
310#if FULL_NBIT
311  Int    SHIFT_QP = 12 + 6 * (g_uiBitDepth - 8);
312#else
313  Int    SHIFT_QP = 12;
314#endif
315 
316  // set frame lambda
317  if (m_pcCfg->getGOPSize() > 1)
318  {
319    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
320  }
321  else
322  {
323    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
324  }
325  m_pcRdCost      ->setFrameLambda(dFrameLambda);
326  m_pcRdCost      ->setFrameLambdaVSO( dFrameLambda * m_pcCfg->getLambdaScaleVSO() ); 
327 
328  // for each QP candidate
329  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
330  {
331    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
332    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
333    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
334    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
335    m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdx] * m_pcCfg->getMultiviewMvRegLambdaScale() );
336   
337    // try compress
338    compressSlice   ( rpcPic );
339   
340    Double dPicRdCost;
341    UInt64 uiPicDist        = m_uiPicDist;
342    UInt64 uiALFBits        = 0;
343   
344    m_pcPicEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
345   
346    // compute RD cost and choose the best
347    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
348   
349    if ( dPicRdCost < dPicRdCostBest )
350    {
351      uiQpIdxBest    = uiQpIdx;
352      dPicRdCostBest = dPicRdCost;
353      dSumCURdCostBest = m_dPicRdCost;
354     
355      uiPicBitsBest = m_uiPicTotalBits + uiALFBits;
356      uiPicDistBest = uiPicDist;
357    }
358  }
359 
360  // set best values
361  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
362  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
363  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
364  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
365  m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdxBest] * m_pcCfg->getMultiviewMvRegLambdaScale() );
366}
367
368/** \param rpcPic   picture class
369 */
370Void TEncSlice::compressSlice( TComPic*& rpcPic )
371{
372  UInt  uiCUAddr;
373  UInt   uiStartCUAddr;
374  UInt   uiBoundingCUAddr;
375  UInt64 uiBitsCoded            = 0;
376  TEncBinCABAC* pppcRDSbacCoder = NULL;
377  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
378  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
379 
380#ifdef WEIGHT_PRED
381  //------------------------------------------------------------------------------
382  //  Weighted Prediction parameters estimation.
383  //------------------------------------------------------------------------------
384  // calculate AC/DC values for current picture
385  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPredIdc() )
386    xCalcACDCParamSlice(pcSlice);
387
388  Bool  wp_Explicit =  (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==1);
389  Bool  wp_Implicit = (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==2);
390
391  if ( wp_Explicit || wp_Implicit )
392  {
393        //------------------------------------------------------------------------------
394        //  Weighted Prediction implemented at Slice level, sliceMode=2 only.
395        //------------------------------------------------------------------------------
396    if ( pcSlice->getSliceMode()==2 || pcSlice->getEntropySliceMode()==2 )
397    {
398      printf("Weighted Prediction not implemented with slice mode determined by max number of bins.\n"); exit(0);
399    }
400
401    if( wp_Explicit )
402      xEstimateWPParamSlice(pcSlice);
403
404    pcSlice->initWpScaling();
405    pcSlice->displayWpScaling();
406  }
407#endif
408
409  // initialize cost values
410  m_uiPicTotalBits  = 0;
411  m_dPicRdCost      = 0;
412  m_uiPicDist       = 0;
413 
414  // set entropy coder
415  if( m_pcCfg->getUseSBACRD() )
416  {
417    m_pcSbacCoder->init( m_pcBinCABAC );
418    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
419    m_pcEntropyCoder->resetEntropy      ();
420    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
421    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
422    pppcRDSbacCoder->setBinCountingEnableFlag( false );
423    pppcRDSbacCoder->setBinsCoded( 0 );
424  }
425  else
426  {
427    m_pcCavlcCoder  ->setAdaptFlag    ( false );
428    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
429    m_pcEntropyCoder->resetEntropy      ();
430    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
431  }
432 
433  // initialize ALF parameters
434  m_pcEntropyCoder->setAlfCtrl(false);
435  m_pcEntropyCoder->setMaxAlfCtrlDepth(0); //unnecessary
436 
437  // for every CU in slice
438  for(  uiCUAddr = uiStartCUAddr; uiCUAddr < uiBoundingCUAddr; uiCUAddr++  )
439  {
440    // set QP
441    m_pcCuEncoder->setQpLast( pcSlice->getSliceQp() );
442    // initialize CU encoder
443    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
444    pcCU->initCU( rpcPic, uiCUAddr );
445   
446    // if RD based on SBAC is used
447    if( m_pcCfg->getUseSBACRD() )
448    {
449      // set go-on entropy coder
450      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
451      m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
452     
453      // run CU encoder
454      m_pcCuEncoder->compressCU( pcCU );
455     
456      // restore entropy coder to an initial stage
457      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
458      m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
459      pppcRDSbacCoder->setBinCountingEnableFlag( true );
460     
461      m_pcCuEncoder->encodeCU( pcCU );
462
463      pppcRDSbacCoder->setBinCountingEnableFlag( false );
464      uiBitsCoded += m_pcBitCounter->getNumberOfWrittenBits();
465      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + uiBitsCoded ) >> 3 ) > m_pcCfg->getSliceArgument())
466      {
467        if (uiCUAddr==uiStartCUAddr && pcSlice->getSliceBits()==0)
468        {
469          // Could not fit even a single LCU within the slice under the defined byte-constraint. Display a warning message and code 1 LCU in the slice.
470          fprintf(stdout,"\nSlice overflow warning! codedBits=%6d, limitBytes=%6d", m_pcBitCounter->getNumberOfWrittenBits(), m_pcCfg->getSliceArgument() );
471          uiCUAddr = uiCUAddr + 1;
472        }
473        pcSlice->setNextSlice( true );
474        break;
475      }
476     
477      UInt uiBinsCoded = pppcRDSbacCoder->getBinsCoded();
478      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && uiBinsCoded > m_pcCfg->getEntropySliceArgument())
479      {
480        if (uiCUAddr == uiStartCUAddr)
481        {
482          // Could not fit even a single LCU within the entropy slice under the defined byte-constraint. Display a warning message and code 1 LCU in the entropy slice.
483          fprintf(stdout,"\nEntropy Slice overflow warning! codedBins=%6d, limitBins=%6d", uiBinsCoded, m_pcCfg->getEntropySliceArgument() );
484          uiCUAddr = uiCUAddr + 1;
485        }
486        pcSlice->setNextEntropySlice( true );
487        break;
488      }
489    }
490    // other case: encodeCU is not called
491    else
492    {
493      m_pcCuEncoder->compressCU( pcCU );
494      m_pcCavlcCoder ->setAdaptFlag(true);
495      m_pcCuEncoder->encodeCU( pcCU );
496     
497      uiBitsCoded += m_pcBitCounter->getNumberOfWrittenBits();
498      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + uiBitsCoded ) >> 3 ) > m_pcCfg->getSliceArgument())
499      {
500        if (uiCUAddr==uiStartCUAddr && pcSlice->getSliceBits()==0)
501        {
502          // Could not fit even a single LCU within the slice under the defined byte-constraint. Display a warning message and code 1 LCU in the slice.
503          fprintf(stdout,"\nSlice overflow warning! codedBits=%6d, limitBytes=%6d", m_pcBitCounter->getNumberOfWrittenBits(), m_pcCfg->getSliceArgument() );
504          uiCUAddr = uiCUAddr + 1;
505        }
506        pcSlice->setNextSlice( true );
507        break;
508      }
509
510      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && uiBitsCoded > m_pcCfg->getEntropySliceArgument())
511      {
512        if (uiCUAddr == uiStartCUAddr)
513        {
514          // Could not fit even a single LCU within the entropy slice under the defined bit/bin-constraint. Display a warning message and code 1 LCU in the entropy slice.
515          fprintf(stdout,"\nEntropy Slice overflow warning! codedBits=%6d, limitBits=%6d", m_pcBitCounter->getNumberOfWrittenBits(), m_pcCfg->getEntropySliceArgument() );
516          uiCUAddr = uiCUAddr + 1;
517        }
518        pcSlice->setNextEntropySlice( true );
519        break;
520      }
521      m_pcCavlcCoder ->setAdaptFlag(false);
522    }
523   
524    m_uiPicTotalBits += pcCU->getTotalBits();
525    m_dPicRdCost     += pcCU->getTotalCost();
526    m_uiPicDist      += pcCU->getTotalDistortion();
527  }
528  pcSlice->setSliceCurEndCUAddr( uiCUAddr );
529  pcSlice->setEntropySliceCurEndCUAddr( uiCUAddr );
530  pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + uiBitsCoded) );
531}
532
533/**
534 \param  rpcPic        picture class
535 \retval rpcBitstream  bitstream class
536 */
537Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComBitstream*& rpcBitstream )
538{
539  UInt       uiCUAddr;
540  UInt       uiStartCUAddr;
541  UInt       uiBoundingCUAddr;
542  xDetermineStartAndBoundingCUAddr  ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, true );
543  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
544
545  // choose entropy coder
546  Int iSymbolMode = pcSlice->getSymbolMode();
547  if (iSymbolMode)
548  {
549    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
550    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
551  }
552  else
553  {
554    m_pcCavlcCoder  ->setAdaptFlag( true );
555    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
556    m_pcEntropyCoder->resetEntropy();
557  }
558 
559  // set bitstream
560  m_pcEntropyCoder->setBitstream( rpcBitstream );
561  // for every CU
562#if ENC_DEC_TRACE
563  g_bJustDoIt = g_bEncDecTraceEnable;
564#endif
565  DTRACE_CABAC_V( g_nSymbolCounter++ );
566  DTRACE_CABAC_T( "\tPOC: " );
567  DTRACE_CABAC_V( rpcPic->getPOC() );
568  DTRACE_CABAC_T( "\n" );
569#if ENC_DEC_TRACE
570  g_bJustDoIt = g_bEncDecTraceDisable;
571#endif
572
573  for(  uiCUAddr = uiStartCUAddr; uiCUAddr<uiBoundingCUAddr; uiCUAddr++  )
574  {
575    m_pcCuEncoder->setQpLast( pcSlice->getSliceQp() );
576    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
577#if ENC_DEC_TRACE
578    g_bJustDoIt = g_bEncDecTraceEnable;
579#endif
580    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && uiCUAddr==uiBoundingCUAddr-1 )
581    {
582      m_pcCuEncoder->encodeCU( pcCU, true );
583    }
584    else
585    {
586      m_pcCuEncoder->encodeCU( pcCU );
587    }
588#if ENC_DEC_TRACE
589    g_bJustDoIt = g_bEncDecTraceDisable;
590#endif   
591  }
592}
593
594/** Determines the starting and bounding LCU address of current slice / entropy slice
595 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
596 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
597 */
598Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
599{
600  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
601  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
602  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
603  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
604  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
605  if (bEncodeSlice) 
606  {
607    UInt uiCUAddrIncrement;
608    switch (m_pcCfg->getSliceMode())
609    {
610    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
611      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
612      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement     ) < uiNumberOfCUsInFrame ) ? (uiStartCUAddrSlice + uiCUAddrIncrement     ) : uiNumberOfCUsInFrame;
613      break;
614    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
615      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
616      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
617      break;
618    default:
619      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
620      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame;
621      break;
622    } 
623    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
624  }
625  else
626  {
627    UInt uiCUAddrIncrement     ;
628    switch (m_pcCfg->getSliceMode())
629    {
630    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
631      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
632      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement     ) < uiNumberOfCUsInFrame ) ? (uiStartCUAddrSlice + uiCUAddrIncrement     ) : uiNumberOfCUsInFrame;
633      break;
634    default:
635      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
636      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame;
637      break;
638    } 
639    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
640  }
641
642  // Entropy slice
643  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
644  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
645  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
646  if (bEncodeSlice) 
647  {
648    UInt uiCUAddrIncrement;
649    switch (m_pcCfg->getEntropySliceMode())
650    {
651    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
652      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
653      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame;
654      break;
655    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
656      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
657      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
658      break;
659    default:
660      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
661      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame;
662      break;
663    } 
664    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
665  }
666  else
667  {
668    UInt uiCUAddrIncrement;
669    switch (m_pcCfg->getEntropySliceMode())
670    {
671    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
672      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
673      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame;
674      break;
675    default:
676      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
677      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame;
678      break;
679    } 
680    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
681  }
682
683  // Make a joint decision based on reconstruction and entropy slice bounds
684  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
685  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
686
687
688  if (!bEncodeSlice)
689  {
690    // 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
691    // first. Set the flags accordingly.
692    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
693      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
694      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) )
695    {
696      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
697      {
698        pcSlice->setNextSlice       ( true );
699        pcSlice->setNextEntropySlice( false );
700      }
701      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
702      {
703        pcSlice->setNextSlice       ( false );
704        pcSlice->setNextEntropySlice( true );
705      }
706      else
707      {
708        pcSlice->setNextSlice       ( true );
709        pcSlice->setNextEntropySlice( true );
710      }
711    }
712    else
713    {
714      pcSlice->setNextSlice       ( false );
715      pcSlice->setNextEntropySlice( false );
716    }
717  }
718}
Note: See TracBrowser for help on using the repository browser.