source: 3DVCSoftware/branches/0.3-nokia/source/Lib/TLibEncoder/TEncSlice.cpp

Last change on this file was 50, checked in by nokia, 13 years ago

FCO bug-fix to 3DV-HTM version 0.4: decoder crushed with texture-only coding.

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