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

Last change on this file since 5 was 5, checked in by hhi, 12 years ago

Clean version with cfg-files

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