source: 3DVCSoftware/branches/0.2-poznan-univ/source/Lib/TLibEncoder/TEncSlice.cpp @ 28

Last change on this file since 28 was 12, checked in by poznan-univ, 13 years ago

Poznan Tools

  • Depth base motion vector prediction
  • Property svn:eol-style set to native
File size: 27.6 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-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#if POZNAN_STAT_JK
478  m_pcCuEncoder->setStatFileEnabled(false);
479#endif
480
481  // for every CU in slice
482  for(  uiCUAddr = uiStartCUAddr; uiCUAddr < uiBoundingCUAddr; uiCUAddr++  )
483  {
484    // set QP
485    m_pcCuEncoder->setQpLast( pcSlice->getSliceQp() );
486    // initialize CU encoder
487    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
488    pcCU->initCU( rpcPic, uiCUAddr );
489
490    // if RD based on SBAC is used
491    if( m_pcCfg->getUseSBACRD() )
492    {
493      // set go-on entropy coder
494      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
495      m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
496
497      // run CU encoder
498      m_pcCuEncoder->compressCU( pcCU );
499
500      // restore entropy coder to an initial stage
501      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
502      m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
503      pppcRDSbacCoder->setBinCountingEnableFlag( true );
504
505      m_pcCuEncoder->encodeCU( pcCU );
506
507      pppcRDSbacCoder->setBinCountingEnableFlag( false );
508      uiBitsCoded += m_pcBitCounter->getNumberOfWrittenBits();
509      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + uiBitsCoded ) >> 3 ) > m_pcCfg->getSliceArgument())
510      {
511        if (uiCUAddr==uiStartCUAddr && pcSlice->getSliceBits()==0)
512        {
513          // 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.
514          fprintf(stdout,"\nSlice overflow warning! codedBits=%6d, limitBytes=%6d", m_pcBitCounter->getNumberOfWrittenBits(), m_pcCfg->getSliceArgument() );
515          uiCUAddr = uiCUAddr + 1;
516        }
517        pcSlice->setNextSlice( true );
518        break;
519      }
520
521      UInt uiBinsCoded = pppcRDSbacCoder->getBinsCoded();
522      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && uiBinsCoded > m_pcCfg->getEntropySliceArgument())
523      {
524        if (uiCUAddr == uiStartCUAddr)
525        {
526          // 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.
527          fprintf(stdout,"\nEntropy Slice overflow warning! codedBins=%6d, limitBins=%6d", uiBinsCoded, m_pcCfg->getEntropySliceArgument() );
528          uiCUAddr = uiCUAddr + 1;
529        }
530        pcSlice->setNextEntropySlice( true );
531        break;
532      }
533    }
534    // other case: encodeCU is not called
535    else
536    {
537      m_pcCuEncoder->compressCU( pcCU );
538      m_pcCavlcCoder ->setAdaptFlag(true);
539      m_pcCuEncoder->encodeCU( pcCU );
540
541      uiBitsCoded += m_pcBitCounter->getNumberOfWrittenBits();
542      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + uiBitsCoded ) >> 3 ) > m_pcCfg->getSliceArgument())
543      {
544        if (uiCUAddr==uiStartCUAddr && pcSlice->getSliceBits()==0)
545        {
546          // 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.
547          fprintf(stdout,"\nSlice overflow warning! codedBits=%6d, limitBytes=%6d", m_pcBitCounter->getNumberOfWrittenBits(), m_pcCfg->getSliceArgument() );
548          uiCUAddr = uiCUAddr + 1;
549        }
550        pcSlice->setNextSlice( true );
551        break;
552      }
553
554      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && uiBitsCoded > m_pcCfg->getEntropySliceArgument())
555      {
556        if (uiCUAddr == uiStartCUAddr)
557        {
558          // 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.
559          fprintf(stdout,"\nEntropy Slice overflow warning! codedBits=%6d, limitBits=%6d", m_pcBitCounter->getNumberOfWrittenBits(), m_pcCfg->getEntropySliceArgument() );
560          uiCUAddr = uiCUAddr + 1;
561        }
562        pcSlice->setNextEntropySlice( true );
563        break;
564      }
565      m_pcCavlcCoder ->setAdaptFlag(false);
566    }
567
568    m_uiPicTotalBits += pcCU->getTotalBits();
569    m_dPicRdCost     += pcCU->getTotalCost();
570    m_uiPicDist      += pcCU->getTotalDistortion();
571  }
572  pcSlice->setSliceCurEndCUAddr( uiCUAddr );
573  pcSlice->setEntropySliceCurEndCUAddr( uiCUAddr );
574  pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + uiBitsCoded) );
575}
576
577/**
578 \param  rpcPic        picture class
579 \retval rpcBitstream  bitstream class
580 */
581Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComBitstream*& rpcBitstream )
582{
583  UInt       uiCUAddr;
584  UInt       uiStartCUAddr;
585  UInt       uiBoundingCUAddr;
586  xDetermineStartAndBoundingCUAddr  ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, true );
587  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
588
589  // choose entropy coder
590  Int iSymbolMode = pcSlice->getSymbolMode();
591  if (iSymbolMode)
592  {
593    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
594    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
595  }
596  else
597  {
598    m_pcCavlcCoder  ->setAdaptFlag( true );
599    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
600    m_pcEntropyCoder->resetEntropy();
601  }
602
603  // set bitstream
604  m_pcEntropyCoder->setBitstream( rpcBitstream );
605  // for every CU
606#if ENC_DEC_TRACE
607  g_bJustDoIt = g_bEncDecTraceEnable;
608#endif
609  DTRACE_CABAC_V( g_nSymbolCounter++ );
610  DTRACE_CABAC_T( "\tPOC: " );
611  DTRACE_CABAC_V( rpcPic->getPOC() );
612  DTRACE_CABAC_T( "\n" );
613#if ENC_DEC_TRACE
614  g_bJustDoIt = g_bEncDecTraceDisable;
615#endif
616
617#if POZNAN_STAT_JK
618  m_pcCuEncoder->setStatFileEnabled(true);
619#endif
620
621  for(  uiCUAddr = uiStartCUAddr; uiCUAddr<uiBoundingCUAddr; uiCUAddr++  )
622  {
623    m_pcCuEncoder->setQpLast( pcSlice->getSliceQp() );
624    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
625#if ENC_DEC_TRACE
626    g_bJustDoIt = g_bEncDecTraceEnable;
627#endif
628
629        // JK {
630        DTRACE_CABAC_V( g_nSymbolCounter++ );
631        DTRACE_CABAC_T( "\tCU: " );
632        DTRACE_CABAC_V( uiCUAddr );
633        DTRACE_CABAC_T( "\n" );
634        // JK }
635
636    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && uiCUAddr==uiBoundingCUAddr-1 )
637    {
638      m_pcCuEncoder->encodeCU( pcCU, true );
639    }
640    else
641    {
642      m_pcCuEncoder->encodeCU( pcCU );
643    }
644#if ENC_DEC_TRACE
645    g_bJustDoIt = g_bEncDecTraceDisable;
646#endif
647  }
648}
649
650/** Determines the starting and bounding LCU address of current slice / entropy slice
651 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
652 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
653 */
654Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
655{
656  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
657  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
658  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
659  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
660  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
661  if (bEncodeSlice)
662  {
663    UInt uiCUAddrIncrement;
664    switch (m_pcCfg->getSliceMode())
665    {
666    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
667      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
668      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement     ) < uiNumberOfCUsInFrame ) ? (uiStartCUAddrSlice + uiCUAddrIncrement     ) : uiNumberOfCUsInFrame;
669      break;
670    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
671      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
672      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
673      break;
674    default:
675      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
676      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame;
677      break;
678    }
679    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
680  }
681  else
682  {
683    UInt uiCUAddrIncrement     ;
684    switch (m_pcCfg->getSliceMode())
685    {
686    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
687      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
688      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement     ) < uiNumberOfCUsInFrame ) ? (uiStartCUAddrSlice + uiCUAddrIncrement     ) : uiNumberOfCUsInFrame;
689      break;
690    default:
691      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
692      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame;
693      break;
694    }
695    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
696  }
697
698  // Entropy slice
699  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
700  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
701  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
702  if (bEncodeSlice)
703  {
704    UInt uiCUAddrIncrement;
705    switch (m_pcCfg->getEntropySliceMode())
706    {
707    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
708      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
709      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame;
710      break;
711    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
712      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
713      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
714      break;
715    default:
716      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
717      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame;
718      break;
719    }
720    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
721  }
722  else
723  {
724    UInt uiCUAddrIncrement;
725    switch (m_pcCfg->getEntropySliceMode())
726    {
727    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
728      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
729      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame;
730      break;
731    default:
732      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
733      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame;
734      break;
735    }
736    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
737  }
738
739  // Make a joint decision based on reconstruction and entropy slice bounds
740  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
741  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
742
743
744  if (!bEncodeSlice)
745  {
746    // 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
747    // first. Set the flags accordingly.
748    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
749      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
750      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) )
751    {
752      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
753      {
754        pcSlice->setNextSlice       ( true );
755        pcSlice->setNextEntropySlice( false );
756      }
757      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
758      {
759        pcSlice->setNextSlice       ( false );
760        pcSlice->setNextEntropySlice( true );
761      }
762      else
763      {
764        pcSlice->setNextSlice       ( true );
765        pcSlice->setNextEntropySlice( true );
766      }
767    }
768    else
769    {
770      pcSlice->setNextSlice       ( false );
771      pcSlice->setNextEntropySlice( false );
772    }
773  }
774}
Note: See TracBrowser for help on using the repository browser.