source: 3DVCSoftware/branches/0.3-poznan-univ/source/Lib/TLibEncoder/TEncSlice.cpp @ 34

Last change on this file since 34 was 21, checked in by hschwarz, 13 years ago

updated with HHI branch (0.2-HHI)

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