source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncTop.cpp @ 296

Last change on this file since 296 was 296, checked in by tech, 11 years ago

Reintegrated branch 5.1-dev0 rev. 295.

  • Property svn:eol-style set to native
File size: 32.8 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-2012, ITU/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 ITU/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/** \file     TEncTop.cpp
35    \brief    encoder class
36*/
37
38#include "TLibCommon/CommonDef.h"
39#include "TEncTop.h"
40#include "TEncPic.h"
41#include "../../App/TAppEncoder/TAppEncTop.h"
42#if FAST_BIT_EST
43#include "TLibCommon/ContextModel.h"
44#endif
45
46//! \ingroup TLibEncoder
47//! \{
48
49// ====================================================================================================================
50// Constructor / destructor / create / destroy
51// ====================================================================================================================
52
53TEncTop::TEncTop()
54{
55  m_iPOCLast          = -1;
56  m_iNumPicRcvd       =  0;
57  m_uiNumAllPicCoded  =  0;
58  m_pppcRDSbacCoder   =  NULL;
59  m_pppcBinCoderCABAC =  NULL;
60  m_cRDGoOnSbacCoder.init( &m_cRDGoOnBinCoderCABAC );
61#if ENC_DEC_TRACE
62  g_hTrace = fopen( "TraceEnc.txt", "wb" );
63  g_bJustDoIt = g_bEncDecTraceDisable;
64  g_nSymbolCounter = 0;
65#endif
66
67  m_iMaxRefPicNum     = 0;
68
69#if FAST_BIT_EST
70  ContextModel::buildNextStateTable();
71#endif
72
73  m_pcSbacCoders           = NULL;
74  m_pcBinCoderCABACs       = NULL;
75  m_ppppcRDSbacCoders      = NULL;
76  m_ppppcBinCodersCABAC    = NULL;
77  m_pcRDGoOnSbacCoders     = NULL;
78  m_pcRDGoOnBinCodersCABAC = NULL;
79  m_pcBitCounters          = NULL;
80  m_pcRdCosts              = NULL;
81}
82
83TEncTop::~TEncTop()
84{
85#if ENC_DEC_TRACE
86  fclose( g_hTrace );
87#endif
88}
89
90Void TEncTop::create ()
91{
92  // initialize global variables
93  if( m_viewId == 0 && m_isDepth == false )
94  {
95    initROM();
96  }
97
98
99  // create processing unit classes
100  m_cGOPEncoder.        create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight );
101  m_cSliceEncoder.      create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
102  m_cCuEncoder.         create( g_uiMaxCUDepth, g_uiMaxCUWidth, g_uiMaxCUHeight );
103  if (m_bUseSAO)
104  {
105    m_cEncSAO.setSaoInterleavingFlag(getSaoInterleavingFlag());
106    m_cEncSAO.setMaxNumOffsetsPerPic(getMaxNumOffsetsPerPic());
107    m_cEncSAO.create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
108    m_cEncSAO.createEncBuffer();
109  }
110#if ADAPTIVE_QP_SELECTION
111  if (m_bUseAdaptQpSelect)
112  {
113    m_cTrQuant.initSliceQpDelta();
114  }
115#endif
116  m_cAdaptiveLoopFilter.create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
117  m_cLoopFilter.        create( g_uiMaxCUDepth );
118 
119#if DEPTH_MAP_GENERATION
120  m_cDepthMapGenerator. create( false, getSourceWidth(), getSourceHeight(), g_uiMaxCUDepth, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiBitDepth + g_uiBitIncrement, PDM_SUB_SAMP_EXP_X(m_uiPredDepthMapGeneration), PDM_SUB_SAMP_EXP_Y(m_uiPredDepthMapGeneration) );
121#endif
122#if H3D_IVRP
123  m_cResidualGenerator. create( false, getSourceWidth(), getSourceHeight(), g_uiMaxCUDepth, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiBitDepth + g_uiBitIncrement );
124#endif
125
126  if(m_bUseALF)
127  {
128    m_cAdaptiveLoopFilter.setAlfCoefInSlice(m_bALFParamInSlice);
129    m_cAdaptiveLoopFilter.createAlfGlobalBuffers();
130  }
131
132  if(m_bUseSAO || m_bUseALF)
133  {
134    m_vAPS.reserve(MAX_NUM_SUPPORTED_APS);
135  }
136
137  // if SBAC-based RD optimization is used
138  if( m_bUseSBACRD )
139  {
140    m_pppcRDSbacCoder = new TEncSbac** [g_uiMaxCUDepth+1];
141#if FAST_BIT_EST
142    m_pppcBinCoderCABAC = new TEncBinCABACCounter** [g_uiMaxCUDepth+1];
143#else
144    m_pppcBinCoderCABAC = new TEncBinCABAC** [g_uiMaxCUDepth+1];
145#endif
146   
147    for ( Int iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
148    {
149      m_pppcRDSbacCoder[iDepth] = new TEncSbac* [CI_NUM];
150#if FAST_BIT_EST
151      m_pppcBinCoderCABAC[iDepth] = new TEncBinCABACCounter* [CI_NUM];
152#else
153      m_pppcBinCoderCABAC[iDepth] = new TEncBinCABAC* [CI_NUM];
154#endif
155     
156      for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
157      {
158        m_pppcRDSbacCoder[iDepth][iCIIdx] = new TEncSbac;
159#if FAST_BIT_EST
160        m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABACCounter;
161#else
162        m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABAC;
163#endif
164        m_pppcRDSbacCoder   [iDepth][iCIIdx]->init( m_pppcBinCoderCABAC [iDepth][iCIIdx] );
165      }
166    }
167  }
168  m_pcTAppEncTop = NULL;
169#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
170  if( g_aacWedgeLists.empty() && m_bUseDMM )
171  {
172    initWedgeLists();
173  }
174#endif
175}
176
177/**
178 - Allocate coders required for wavefront for the nominated number of substreams.
179 .
180 \param iNumSubstreams Determines how much information to allocate.
181 */
182Void TEncTop::createWPPCoders(Int iNumSubstreams)
183{
184  if (m_pcSbacCoders != NULL)
185    return; // already generated.
186
187  m_iNumSubstreams         = iNumSubstreams;
188  m_pcSbacCoders           = new TEncSbac       [iNumSubstreams];
189  m_pcBinCoderCABACs       = new TEncBinCABAC   [iNumSubstreams];
190  m_pcRDGoOnSbacCoders     = new TEncSbac       [iNumSubstreams];
191  m_pcRDGoOnBinCodersCABAC = new TEncBinCABAC   [iNumSubstreams];
192  m_pcBitCounters          = new TComBitCounter [iNumSubstreams];
193  m_pcRdCosts              = new TComRdCost     [iNumSubstreams];
194
195  for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
196  {
197    m_pcRDGoOnSbacCoders[ui].init( &m_pcRDGoOnBinCodersCABAC[ui] );
198    m_pcSbacCoders[ui].init( &m_pcBinCoderCABACs[ui] );
199  }
200  if( m_bUseSBACRD )
201  {
202    m_ppppcRDSbacCoders      = new TEncSbac***    [iNumSubstreams];
203    m_ppppcBinCodersCABAC    = new TEncBinCABAC***[iNumSubstreams];
204    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ )
205    {
206      m_ppppcRDSbacCoders[ui]  = new TEncSbac** [g_uiMaxCUDepth+1];
207      m_ppppcBinCodersCABAC[ui]= new TEncBinCABAC** [g_uiMaxCUDepth+1];
208     
209      for ( Int iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
210      {
211        m_ppppcRDSbacCoders[ui][iDepth]  = new TEncSbac*     [CI_NUM];
212        m_ppppcBinCodersCABAC[ui][iDepth]= new TEncBinCABAC* [CI_NUM];
213
214        for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
215        {
216          m_ppppcRDSbacCoders  [ui][iDepth][iCIIdx] = new TEncSbac;
217          m_ppppcBinCodersCABAC[ui][iDepth][iCIIdx] = new TEncBinCABAC;
218          m_ppppcRDSbacCoders  [ui][iDepth][iCIIdx]->init( m_ppppcBinCodersCABAC[ui][iDepth][iCIIdx] );
219        }
220      }
221    }
222  }
223}
224
225Void TEncTop::destroy ()
226{
227  if(m_bUseALF)
228  {
229    m_cAdaptiveLoopFilter.destroyAlfGlobalBuffers();
230  }
231
232  for(Int i=0; i< m_vAPS.size(); i++)
233  {
234    TComAPS& cAPS = m_vAPS[i];
235    m_cGOPEncoder.freeAPS(&cAPS, &m_cSPS);
236  }
237
238  // destroy processing unit classes
239  m_cGOPEncoder.        destroy();
240  m_cSliceEncoder.      destroy();
241  m_cCuEncoder.         destroy();
242  if (m_cSPS.getUseSAO())
243  {
244    m_cEncSAO.destroy();
245    m_cEncSAO.destroyEncBuffer();
246  }
247  m_cAdaptiveLoopFilter.destroy();
248  m_cLoopFilter.        destroy();
249
250#if DEPTH_MAP_GENERATION
251  m_cDepthMapGenerator. destroy();
252#endif
253#if H3D_IVRP
254  m_cResidualGenerator. destroy();
255#endif
256
257  m_RPSList.            destroy();
258 
259  // SBAC RD
260  if( m_bUseSBACRD )
261  {
262    Int iDepth;
263    for ( iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
264    {
265      for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
266      {
267        delete m_pppcRDSbacCoder[iDepth][iCIIdx];
268        delete m_pppcBinCoderCABAC[iDepth][iCIIdx];
269      }
270    }
271   
272    for ( iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
273    {
274      delete [] m_pppcRDSbacCoder[iDepth];
275      delete [] m_pppcBinCoderCABAC[iDepth];
276    }
277   
278    delete [] m_pppcRDSbacCoder;
279    delete [] m_pppcBinCoderCABAC;
280
281    for ( UInt ui = 0; ui < m_iNumSubstreams; ui++ )
282    {
283      for ( iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
284      {
285        for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
286        {
287          delete m_ppppcRDSbacCoders  [ui][iDepth][iCIIdx];
288          delete m_ppppcBinCodersCABAC[ui][iDepth][iCIIdx];
289        }
290      }
291
292      for ( iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
293      {
294        delete [] m_ppppcRDSbacCoders  [ui][iDepth];
295        delete [] m_ppppcBinCodersCABAC[ui][iDepth];
296      }
297      delete[] m_ppppcRDSbacCoders  [ui];
298      delete[] m_ppppcBinCodersCABAC[ui];
299    }
300    delete[] m_ppppcRDSbacCoders;
301    delete[] m_ppppcBinCodersCABAC;
302  }
303  delete[] m_pcSbacCoders;
304  delete[] m_pcBinCoderCABACs;
305  delete[] m_pcRDGoOnSbacCoders; 
306  delete[] m_pcRDGoOnBinCodersCABAC;
307  delete[] m_pcBitCounters;
308  delete[] m_pcRdCosts;
309 
310  // destroy ROM
311  if(m_viewId == 0 && m_isDepth == false)
312  {
313  destroyROM();
314  }
315 
316  return;
317}
318
319Void TEncTop::init( TAppEncTop* pcTAppEncTop )
320{
321  UInt *aTable4=NULL, *aTable8=NULL;
322  UInt* aTableLastPosVlcIndex=NULL; 
323  // initialize SPS
324  xInitSPS();
325 
326  // initialize PPS
327  m_cPPS.setSPS(&m_cSPS);
328  m_cSPS.setRPSList(&m_RPSList);
329  xInitPPS();
330  xInitRPS();
331
332  xInitSPSforInterViewRefs();
333  xInitPPSforTiles();
334
335  // initialize processing unit classes
336  m_cGOPEncoder.  init( this );
337  m_cSliceEncoder.init( this );
338  m_cCuEncoder.   init( this );
339 
340  m_pcTAppEncTop = pcTAppEncTop;
341
342#if DEPTH_MAP_GENERATION
343#if VIDYO_VPS_INTEGRATION
344  m_cDepthMapGenerator.init( (TComPrediction*)this->getPredSearch(), m_pcTAppEncTop->getVPSAccess(), m_pcTAppEncTop->getSPSAccess(), m_pcTAppEncTop->getAUPicAccess() );
345#else
346  m_cDepthMapGenerator.init( (TComPrediction*)this->getPredSearch(), m_pcTAppEncTop->getSPSAccess(), m_pcTAppEncTop->getAUPicAccess() );
347#endif
348#endif
349#if H3D_IVRP
350  m_cResidualGenerator.init( &m_cTrQuant, &m_cDepthMapGenerator );
351#endif
352
353  // initialize transform & quantization class
354  m_pcCavlcCoder = getCavlcCoder();
355 
356  m_cTrQuant.init( g_uiMaxCUWidth, g_uiMaxCUHeight, 1 << m_uiQuadtreeTULog2MaxSize,
357                  0,
358                  aTable4, aTable8, 
359                  aTableLastPosVlcIndex, m_bUseRDOQ, true 
360#if ADAPTIVE_QP_SELECTION                 
361                  , m_bUseAdaptQpSelect
362#endif
363                  );
364 
365  // initialize encoder search class
366#if DV_V_RESTRICTION_B0037
367  m_cSearch.init( this, &m_cTrQuant, m_iSearchRange, m_bipredSearchRange, m_bUseDisparitySearchRangeRestriction, m_iVerticalDisparitySearchRange, m_iFastSearch, 0, &m_cEntropyCoder, &m_cRdCost, getRDSbacCoder(), getRDGoOnSbacCoder() );
368#else
369  m_cSearch.init( this, &m_cTrQuant, m_iSearchRange, m_bipredSearchRange, m_iFastSearch, 0, &m_cEntropyCoder, &m_cRdCost, getRDSbacCoder(), getRDGoOnSbacCoder() );
370#endif
371  if(m_bUseALF)
372  {
373    m_cAdaptiveLoopFilter.setALFEncodePassReduction( m_iALFEncodePassReduction );
374    m_cAdaptiveLoopFilter.setALFMaxNumberFilters( m_iALFMaxNumberFilters );
375    m_cAdaptiveLoopFilter.initPicQuadTreePartition(m_bALFPicBasedEncode );   
376  }
377
378  m_iMaxRefPicNum = 0;
379}
380
381// ====================================================================================================================
382// Public member functions
383// ====================================================================================================================
384
385Void TEncTop::initNewPic( TComPicYuv* pcPicYuvOrg, TComPicYuv* pcOrgPdmDepth )
386{
387  TComPic* pcPicCurr = NULL;
388
389  // get original YUV
390  xGetNewPicBuffer( pcPicCurr );
391  pcPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() );
392
393#if INTER_VIEW_VECTOR_SCALING_C0115
394  pcPicCurr->setViewOrderIdx(m_iViewOrderIdx);    // will be changed to view_id
395#endif
396  pcPicCurr->setScaleOffset( m_aaiCodedScale, m_aaiCodedOffset );
397
398#if H3D_IVMP
399  if( m_uiMultiviewMvRegMode )
400  {
401    AOF( pcOrgPdmDepth );
402    AOF( pcPicCurr->getOrgDepthMap() );
403    pcOrgPdmDepth->copyToPic( pcPicCurr->getOrgDepthMap() );
404  }
405  else
406  {
407    AOT( pcOrgPdmDepth );
408    AOT( pcPicCurr->getOrgDepthMap() );
409  }
410#endif
411
412#if DEPTH_MAP_GENERATION
413  // add extra pic buffers
414  Bool  bNeedPrdDepthMapBuf = ( m_uiPredDepthMapGeneration > 0 );
415  if( bNeedPrdDepthMapBuf && !pcPicCurr->getPredDepthMap() )
416  {
417    pcPicCurr->addPrdDepthMapBuffer( PDM_SUB_SAMP_EXP_X(m_uiPredDepthMapGeneration), PDM_SUB_SAMP_EXP_Y(m_uiPredDepthMapGeneration) );
418  }
419#endif
420
421  // compute image characteristics
422  if ( getUseAdaptiveQP() )
423  {
424    m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) );
425  }
426}
427
428Void TEncTop::deletePicBuffer()
429{
430  TComList<TComPic*>::iterator iterPic = m_cListPic.begin();
431  Int iSize = Int( m_cListPic.size() );
432 
433  for ( Int i = 0; i < iSize; i++ )
434  {
435    TComPic* pcPic = *(iterPic++);
436   
437    pcPic->destroy();
438    delete pcPic;
439    pcPic = NULL;
440  }
441}
442
443/**
444 - Application has picture buffer list with size of GOP + 1
445 - Picture buffer list acts like as ring buffer
446 - End of the list has the latest picture
447 .
448 \param   bEos                true if end-of-sequence is reached
449 \param   pcPicYuvOrg         original YUV picture
450 \retval  rcListPicYuvRecOut  list of reconstruction YUV pictures
451 \retval  rcListBitstreamOut  list of output bitstreams
452 \retval  iNumEncoded         number of encoded pictures
453 */
454Void TEncTop::encode( bool bEos, TComPicYuv* pcPicYuvOrg, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded, Int gopId )
455{ 
456
457  if( gopId == 0)
458  {
459    m_cGOPEncoder.initGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut); 
460  }
461
462  {
463    m_cGOPEncoder.compressPicInGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, gopId );
464  }
465 
466  if( gopId + 1 == m_cGOPEncoder.getGOPSize() )
467  {
468    iNumEncoded         = m_iNumPicRcvd;
469    m_iNumPicRcvd       = 0;
470    m_uiNumAllPicCoded += iNumEncoded;
471  }
472}
473
474
475#if HHI_INTERVIEW_SKIP || H3D_IVMP || H3D_IVRP
476Void
477TEncTop::deleteExtraPicBuffers( Int iPoc )
478{
479  TComPic*                      pcPic = 0;
480  TComList<TComPic*>::iterator  cIter = m_cListPic.begin();
481  TComList<TComPic*>::iterator  cEnd  = m_cListPic.end  ();
482  for( ; cIter != cEnd; cIter++ )
483  {
484    if( (*cIter)->getPOC() == iPoc )
485    {
486      pcPic = *cIter;
487      break;
488    }
489  }
490  AOF( pcPic );
491  if ( pcPic )
492  {
493#if H3D_IVMP
494    pcPic->removeOrgDepthMapBuffer();
495#endif
496#if H3D_IVRP
497    pcPic->removeResidualBuffer   ();
498#endif
499#if HHI_INTERVIEW_SKIP
500    pcPic->removeUsedPelsMapBuffer();
501#endif
502  }
503}
504#endif
505
506Void
507TEncTop::compressMotion( Int iPoc )
508{
509  TComPic*                      pcPic = 0;
510  TComList<TComPic*>::iterator  cIter = m_cListPic.begin();
511  TComList<TComPic*>::iterator  cEnd  = m_cListPic.end  ();
512  for( ; cIter != cEnd; cIter++ )
513  {
514    if( (*cIter)->getPOC() == iPoc )
515    {
516      pcPic = *cIter;
517      break;
518    }
519  }
520  AOF( pcPic );
521  if ( pcPic )
522  {
523    pcPic->compressMotion();
524  }
525}
526
527// ====================================================================================================================
528// Protected member functions
529// ====================================================================================================================
530
531/**
532 - Application has picture buffer list with size of GOP + 1
533 - Picture buffer list acts like as ring buffer
534 - End of the list has the latest picture
535 .
536 \retval rpcPic obtained picture buffer
537 */
538Void TEncTop::xGetNewPicBuffer ( TComPic*& rpcPic )
539{
540  TComSlice::sortPicList(m_cListPic);
541 
542  if (m_cListPic.size() >= (UInt)(m_iGOPSize + getMaxDecPicBuffering(MAX_TLAYER-1) + 2) )
543  {
544    TComList<TComPic*>::iterator iterPic  = m_cListPic.begin();
545    Int iSize = Int( m_cListPic.size() );
546    for ( Int i = 0; i < iSize; i++ )
547    {
548      rpcPic = *(++iterPic);
549      if(rpcPic->getSlice(0)->isReferenced() == false)
550         break;
551    }
552  }
553  else
554  {
555        if ( getUseAdaptiveQP() )
556        {
557          TEncPic* pcEPic = new TEncPic;
558          pcEPic->create( m_iSourceWidth, m_iSourceHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, m_cPPS.getMaxCuDQPDepth()+1 );
559          rpcPic = pcEPic;
560        }
561        else
562        {
563          rpcPic = new TComPic;
564          rpcPic->create( m_iSourceWidth, m_iSourceHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
565        }
566    m_cListPic.pushBack( rpcPic );
567  }
568#if HHI_INTERVIEW_SKIP
569  if( m_bInterViewSkip )
570  {
571    rpcPic->addUsedPelsMapBuffer();
572  }
573#endif
574  rpcPic->setReconMark (false);
575 
576  m_iPOCLast++;
577  m_iNumPicRcvd++;
578 
579#if H3D_IVMP
580  if( m_uiMultiviewMvRegMode )
581  {
582    rpcPic->addOrgDepthMapBuffer();
583  }
584#endif
585 
586  rpcPic->getSlice(0)->setPOC( m_iPOCLast );
587  // mark it should be extended
588  rpcPic->getPicYuvRec()->setBorderExtension(false);
589  rpcPic->getPicYuvOrg()->setBorderExtension(false); 
590}
591
592Void TEncTop::xInitSPS()
593{
594  m_cSPS.setPicWidthInLumaSamples         ( m_iSourceWidth      );
595  m_cSPS.setPicHeightInLumaSamples        ( m_iSourceHeight     );
596  m_cSPS.setPicCroppingFlag( m_croppingMode!= 0 );
597  if (m_croppingMode != 0)
598  {
599    m_cSPS.setPicCropLeftOffset( m_cropLeft );
600    m_cSPS.setPicCropRightOffset( m_cropRight );
601    m_cSPS.setPicCropTopOffset( m_cropTop );
602    m_cSPS.setPicCropBottomOffset( m_cropBottom );
603  }
604  m_cSPS.setMaxCUWidth    ( g_uiMaxCUWidth      );
605  m_cSPS.setMaxCUHeight   ( g_uiMaxCUHeight     );
606  m_cSPS.setMaxCUDepth    ( g_uiMaxCUDepth      );
607  m_cSPS.setMinTrDepth    ( 0                   );
608  m_cSPS.setMaxTrDepth    ( 1                   );
609 
610  m_cSPS.setPCMLog2MinSize (m_uiPCMLog2MinSize);
611  m_cSPS.setUsePCM        ( m_usePCM           );
612  m_cSPS.setPCMLog2MaxSize( m_pcmLog2MaxSize  );
613
614  m_cSPS.setUseALF        ( m_bUseALF           );
615  if(m_bUseALF)
616  {
617    m_cSPS.setUseALFCoefInSlice(m_bALFParamInSlice);
618  }
619 
620#if RWTH_SDC_DLT_B0036
621  m_cSPS.setUseDLT        ( m_bUseDLT );
622#endif
623 
624  m_cSPS.setQuadtreeTULog2MaxSize( m_uiQuadtreeTULog2MaxSize );
625  m_cSPS.setQuadtreeTULog2MinSize( m_uiQuadtreeTULog2MinSize );
626  m_cSPS.setQuadtreeTUMaxDepthInter( m_uiQuadtreeTUMaxDepthInter    );
627  m_cSPS.setQuadtreeTUMaxDepthIntra( m_uiQuadtreeTUMaxDepthIntra    );
628 
629#if LOSSLESS_CODING
630  m_cSPS.setUseLossless   ( m_useLossless  );
631#endif
632  m_cSPS.setUseLMChroma   ( m_bUseLMChroma           ); 
633 
634  m_cSPS.setMaxTrSize   ( 1 << m_uiQuadtreeTULog2MaxSize );
635 
636  m_cSPS.setUseLComb    ( m_bUseLComb           );
637  m_cSPS.setLCMod       ( m_bLCMod   );
638  m_cSPS.setUseNSQT( m_useNSQT );
639 
640  Int i;
641#if HHI_AMVP_OFF
642  for ( i = 0; i < g_uiMaxCUDepth; i++ )
643  {
644    m_cSPS.setAMVPMode( i, AM_NONE );
645  }
646#else
647  for ( i = 0; i < g_uiMaxCUDepth; i++ )
648  {
649    m_cSPS.setAMVPMode( i, AM_EXPL );
650  }
651#endif
652 
653  for (i = 0; i < g_uiMaxCUDepth-1; i++ )
654  {
655    m_cSPS.setAMPAcc( i, m_useAMP );
656    //m_cSPS.setAMPAcc( i, 1 );
657  }
658
659  m_cSPS.setUseAMP ( m_useAMP );
660
661  for (i = g_uiMaxCUDepth-1; i < g_uiMaxCUDepth; i++ )
662  {
663    m_cSPS.setAMPAcc(i, 0);
664  }
665
666  m_cSPS.setBitDepth    ( g_uiBitDepth        );
667  m_cSPS.setBitIncrement( g_uiBitIncrement    );
668  m_cSPS.setQpBDOffsetY ( (Int)(6*(g_uiBitDepth + g_uiBitIncrement - 8)) );
669  m_cSPS.setQpBDOffsetC ( (Int)(6*(g_uiBitDepth + g_uiBitIncrement - 8)) );
670
671  m_cSPS.setLFCrossSliceBoundaryFlag( m_bLFCrossSliceBoundaryFlag );
672  m_cSPS.setUseSAO( m_bUseSAO );
673
674  m_cSPS.setMaxTLayers( m_maxTempLayer );
675  m_cSPS.setTemporalIdNestingFlag( false );
676  for ( i = 0; i < m_cSPS.getMaxTLayers(); i++ )
677  {
678    m_cSPS.setMaxDecPicBuffering(m_maxDecPicBuffering[i], i);
679    m_cSPS.setNumReorderPics(m_numReorderPics[i], i);
680  }
681  m_cSPS.setPCMBitDepthLuma (g_uiPCMBitDepthLuma);
682  m_cSPS.setPCMBitDepthChroma (g_uiPCMBitDepthChroma);
683  m_cSPS.setPCMFilterDisableFlag  ( m_bPCMFilterDisableFlag );
684
685  m_cSPS.setLFCrossTileBoundaryFlag( m_bLFCrossTileBoundaryFlag );
686  m_cSPS.setUniformSpacingIdr( m_iUniformSpacingIdr );
687  m_cSPS.setNumColumnsMinus1( m_iNumColumnsMinus1 );
688  m_cSPS.setNumRowsMinus1( m_iNumRowsMinus1 );
689  if( m_iUniformSpacingIdr == 0 )
690  {
691    m_cSPS.setColumnWidth( m_puiColumnWidth );
692    m_cSPS.setRowHeight( m_puiRowHeight );
693  }
694  m_cSPS.setScalingListFlag ( (m_useScalingListId == 0) ? 0 : 1 );
695  m_cSPS.setUseDF( m_loopFilterOffsetInAPS );
696
697#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
698  m_cSPS.setUseDMM( m_bUseDMM );
699#endif
700
701#if HHI_DMM_PRED_TEX && FLEX_CODING_ORDER_M23723
702  m_cSPS.setUseDMM34( m_bUseDMM34 );
703#endif
704
705#if OL_QTLIMIT_PREDCODING_B0068
706  m_cSPS.setUseQTLPC( m_bUseQTLPC );
707#endif
708#if HHI_MPI
709  m_cSPS.setUseMVI( m_bUseMVI );
710#endif
711
712  if( m_isDepth )
713  {
714    m_cSPS.initMultiviewSPSDepth    ( m_viewId, m_iViewOrderIdx );
715#if DEPTH_MAP_GENERATION
716    m_cSPS.setPredDepthMapGeneration( m_viewId, true );
717#endif
718#if H3D_IVRP
719    m_cSPS.setMultiviewResPredMode  ( 0 );
720#endif
721  }
722  else
723  {
724#if QC_MVHEVC_B0046
725    m_cSPS.initMultiviewSPS   ( m_viewId);
726#else
727    m_cSPS.initMultiviewSPS           ( m_viewId, m_iViewOrderIdx, m_uiCamParPrecision, m_bCamParInSliceHeader, m_aaiCodedScale, m_aaiCodedOffset );
728#endif
729    if( m_viewId )
730    {
731#if DEPTH_MAP_GENERATION
732#if H3D_IVMP
733      m_cSPS.setPredDepthMapGeneration( m_viewId, false, m_uiPredDepthMapGeneration, m_uiMultiviewMvPredMode, m_uiPdmPrecision, m_aaiPdmScaleNomDelta, m_aaiPdmOffset );
734#else
735      m_cSPS.setPredDepthMapGeneration( m_viewId, false, m_uiPredDepthMapGeneration, 0, m_uiPdmPrecision, m_aaiPdmScaleNomDelta, m_aaiPdmOffset );
736#endif
737#endif
738#if H3D_IVRP
739      m_cSPS.setMultiviewResPredMode  ( m_uiMultiviewResPredMode );
740#endif
741    }
742    else
743    {
744#if DEPTH_MAP_GENERATION
745      m_cSPS.setPredDepthMapGeneration( m_viewId, false );
746#endif
747#if H3D_IVRP
748      m_cSPS.setMultiviewResPredMode  ( 0 );
749#endif
750    }
751  }
752}
753
754Void TEncTop::xInitPPS()
755{
756  m_cPPS.setConstrainedIntraPred( m_bUseConstrainedIntraPred );
757  m_cPPS.setSliceGranularity(m_iSliceGranularity);
758  Bool bUseDQP = (getMaxCuDQPDepth() > 0)? true : false;
759
760#if LOSSLESS_CODING
761  Int lowestQP = - m_cSPS.getQpBDOffsetY();
762
763  if(getUseLossless())
764  {
765    if ((getMaxCuDQPDepth() == 0) && (getMaxDeltaQP() == 0 ) && (getQP() == lowestQP) )
766    {
767      bUseDQP = false;
768    }
769    else
770    {
771      bUseDQP = true;
772    }
773  }
774  else
775  {
776    if(bUseDQP == false)
777    {
778      if((getMaxDeltaQP() != 0 )|| getUseAdaptiveQP())
779      {
780        bUseDQP = true;
781      }
782    }
783  }
784
785#else
786  if(bUseDQP == false)
787  {
788    if((getMaxDeltaQP() != 0 )|| getUseAdaptiveQP())
789    {
790      bUseDQP = true;
791    }
792  }
793#endif
794
795  if(bUseDQP)
796  {
797    m_cPPS.setUseDQP(true);
798    m_cPPS.setMaxCuDQPDepth( m_iMaxCuDQPDepth );
799    m_cPPS.setMinCuDQPSize( m_cPPS.getSPS()->getMaxCUWidth() >> ( m_cPPS.getMaxCuDQPDepth()) );
800  }
801  else
802  {
803    m_cPPS.setUseDQP(false);
804    m_cPPS.setMaxCuDQPDepth( 0 );
805    m_cPPS.setMinCuDQPSize( m_cPPS.getSPS()->getMaxCUWidth() >> ( m_cPPS.getMaxCuDQPDepth()) );
806  }
807
808  m_cPPS.setChromaQpOffset   ( m_iChromaQpOffset    );
809  m_cPPS.setChromaQpOffset2nd( m_iChromaQpOffset2nd );
810
811  m_cPPS.setEntropyCodingMode( 1 ); // In the PPS now, but also remains in slice header!
812  m_cPPS.setNumSubstreams(m_iWaveFrontSubstreams);
813  m_cPPS.setUseWP( m_bUseWeightPred );
814  m_cPPS.setWPBiPredIdc( m_uiBiPredIdc );
815  m_cPPS.setEnableTMVPFlag( m_bEnableTMVP );
816  m_cPPS.setOutputFlagPresentFlag( false );
817  m_cPPS.setSignHideFlag(getSignHideFlag());
818  m_cPPS.setTSIG(getTSIG());
819  m_cPPS.setDeblockingFilterControlPresent (m_DeblockingFilterControlPresent );
820  m_cPPS.setLog2ParallelMergeLevelMinus2      (LOG2_PARALLEL_MERGE_LEVEL_MINUS2);
821#if CABAC_INIT_FLAG
822  m_cPPS.setCabacInitPresentFlag(CABAC_INIT_PRESENT_FLAG);
823#endif
824}
825
826//Function for initializing m_RPSList, a list of TComReferencePictureSet, based on the GOPEntry objects read from the config file.
827Void TEncTop::xInitRPS()
828{
829  TComReferencePictureSet*      rps;
830 
831  m_RPSList.create(getGOPSize()+m_extraRPSs);
832  for( Int i = 0; i < getGOPSize()+m_extraRPSs; i++) 
833  {
834    GOPEntryMvc ge = getGOPEntry(i);
835    rps = m_RPSList.getReferencePictureSet(i);
836    rps->setNumberOfPictures(ge.m_numRefPics);
837    rps->setNumRefIdc(ge.m_numRefIdc);
838    Int numNeg = 0;
839    Int numPos = 0;
840    for( Int j = 0; j < ge.m_numRefPics; j++)
841    {
842      rps->setDeltaPOC(j,ge.m_referencePics[j]);
843      rps->setUsed(j,ge.m_usedByCurrPic[j]);
844      if(ge.m_referencePics[j]>0)
845      {
846        numPos++;
847      }
848      else
849      {
850        numNeg++;
851      }
852    }
853    rps->setNumberOfNegativePictures(numNeg);
854    rps->setNumberOfPositivePictures(numPos);
855    rps->setInterRPSPrediction(ge.m_interRPSPrediction);
856    if (ge.m_interRPSPrediction)
857    {
858      rps->setDeltaRIdxMinus1(ge.m_deltaRIdxMinus1);
859      rps->setDeltaRPS(ge.m_deltaRPS);
860      rps->setNumRefIdc(ge.m_numRefIdc);
861      for (Int j = 0; j < ge.m_numRefIdc; j++ )
862      {
863        rps->setRefIdc(j, ge.m_refIdc[j]);
864      }
865#if WRITE_BACK
866      // the folowing code overwrite the deltaPOC and Used by current values read from the config file with the ones
867      // computed from the RefIdc.  This is not necessary if both are identical. Currently there is no check to see if they are identical.
868      numNeg = 0;
869      numPos = 0;
870      TComReferencePictureSet*     RPSRef = m_RPSList.getReferencePictureSet(i-(ge.m_deltaRIdxMinus1+1));
871      for (Int j = 0; j < ge.m_numRefIdc; j++ )
872      {
873        if (ge.m_refIdc[j])
874        {
875          Int deltaPOC = ge.m_deltaRPS + ((j < RPSRef->getNumberOfPictures())? RPSRef->getDeltaPOC(j) : 0);
876          rps->setDeltaPOC((numNeg+numPos),deltaPOC);
877          rps->setUsed((numNeg+numPos),ge.m_refIdc[j]==1?1:0);
878          if (deltaPOC<0)
879          {
880            numNeg++;
881          }
882          else
883          {
884            numPos++;
885          }
886        }
887      }
888      rps->setNumberOfNegativePictures(numNeg);
889      rps->setNumberOfPositivePictures(numPos);
890      rps->sortDeltaPOC();
891#endif
892    }
893  }
894 
895}
896
897   // This is a function that
898   // determines what Reference Picture Set to use
899   // for a specific slice (with POC = POCCurr)
900Void TEncTop::selectReferencePictureSet(TComSlice* slice, Int POCCurr, Int GOPid,TComList<TComPic*>& listPic )
901{
902#if QC_REM_IDV_B0046
903  if( (slice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR ||slice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) && slice->getSPS()->getViewId() && POCCurr == 0 )
904#else
905  if( slice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDV && POCCurr == 0 )
906#endif
907  {
908    TComReferencePictureSet* rps = slice->getLocalRPS();
909    rps->setNumberOfNegativePictures(0);
910    rps->setNumberOfPositivePictures(0);
911    rps->setNumberOfLongtermPictures(0);
912    rps->setNumberOfPictures(0);
913    slice->setRPS(rps);
914  }
915  else
916  {
917    slice->setRPSidx(GOPid);
918
919    for(Int extraNum=m_iGOPSize; extraNum<m_extraRPSs+m_iGOPSize; extraNum++)
920    {   
921      if(m_uiIntraPeriod > 0)
922      {
923        if(POCCurr%m_uiIntraPeriod==m_GOPList[extraNum].m_POC)
924        {
925          slice->setRPSidx(extraNum);
926        }
927      }
928      else
929      {
930        if(POCCurr==m_GOPList[extraNum].m_POC)
931        {
932          slice->setRPSidx(extraNum);
933        }
934      }
935    }
936
937    slice->setRPS(getRPSList()->getReferencePictureSet(slice->getRPSidx()));
938    slice->getRPS()->setNumberOfPictures(slice->getRPS()->getNumberOfNegativePictures()+slice->getRPS()->getNumberOfPositivePictures());
939  }
940}
941
942Void TEncTop::xInitSPSforInterViewRefs()
943{
944  // base view
945  if( getGOPEntry( MAX_GOP ).m_POC == -1 )
946  { 
947    m_cSPS.setNumberOfUsableInterViewRefs( 0 );
948    m_cSPS.setListsModificationPresentFlag( false );
949    return;
950  }
951
952  Int numberUsableInterViewRefs = 0;
953  for( Int i = 0; i < getGOPSize()+1 && numberUsableInterViewRefs < MAX_VIEW_NUM; i++ ) 
954  {
955    GOPEntryMvc ge = ( i < getGOPSize() ) ? getGOPEntry( i ) : getGOPEntry( MAX_GOP );
956    for( Int j = 0; j < ge.m_numInterViewRefPics; j++ )
957    {
958      // add ref view to list
959      Bool onList = false;
960      for( Int k = 0; k < numberUsableInterViewRefs; k++ )
961      {
962        if( ge.m_interViewRefs[j] == m_cSPS.getUsableInterViewRef( k ) )
963        {
964          onList = true;
965          break;
966        }
967      }
968      if( !onList )
969      {
970        m_cSPS.setUsableInterViewRef( (UInt)numberUsableInterViewRefs, ge.m_interViewRefs[j] );
971        numberUsableInterViewRefs++;
972      }
973    }
974  }
975  m_cSPS.setNumberOfUsableInterViewRefs( numberUsableInterViewRefs );
976
977  // sort inter view refs
978  for( Int j = 1; j < m_cSPS.getNumberOfUsableInterViewRefs(); j++ )
979  { 
980    Int deltaViewId = m_cSPS.getUsableInterViewRef( j );
981    for( Int k = j-1; k >= 0; k-- )
982    {
983      Int temp = m_cSPS.getUsableInterViewRef( k );
984      if( deltaViewId > temp )
985      {
986        m_cSPS.setUsableInterViewRef( k+1, temp );
987        m_cSPS.setUsableInterViewRef( k, deltaViewId );
988      }
989    }
990  }
991
992  m_cSPS.setListsModificationPresentFlag( true );
993}
994
995Void  TEncTop::xInitPPSforTiles()
996{
997    m_cPPS.setColumnRowInfoPresent( m_iColumnRowInfoPresent );
998    m_cPPS.setUniformSpacingIdr( m_iUniformSpacingIdr );
999    m_cPPS.setNumColumnsMinus1( m_iNumColumnsMinus1 );
1000    m_cPPS.setNumRowsMinus1( m_iNumRowsMinus1 );
1001    if( m_iUniformSpacingIdr == 0 )
1002    {
1003      m_cPPS.setColumnWidth( m_puiColumnWidth );
1004      m_cPPS.setRowHeight( m_puiRowHeight );
1005    }
1006    m_cPPS.setTileBehaviorControlPresentFlag( m_iTileBehaviorControlPresentFlag );
1007    m_cPPS.setLFCrossTileBoundaryFlag( m_bLFCrossTileBoundaryFlag );
1008
1009    // # substreams is "per tile" when tiles are independent.
1010    if ( m_iWaveFrontSynchro )
1011    {
1012      m_cPPS.setNumSubstreams(m_iWaveFrontSubstreams * (m_iNumColumnsMinus1+1)*(m_iNumRowsMinus1+1));
1013    }
1014}
1015
1016Void  TEncCfg::xCheckGSParameters()
1017{
1018  Int   iWidthInCU = ( m_iSourceWidth%g_uiMaxCUWidth ) ? m_iSourceWidth/g_uiMaxCUWidth + 1 : m_iSourceWidth/g_uiMaxCUWidth;
1019  Int   iHeightInCU = ( m_iSourceHeight%g_uiMaxCUHeight ) ? m_iSourceHeight/g_uiMaxCUHeight + 1 : m_iSourceHeight/g_uiMaxCUHeight;
1020  UInt  uiCummulativeColumnWidth = 0;
1021  UInt  uiCummulativeRowHeight = 0;
1022
1023  //check the column relative parameters
1024  if( m_iNumColumnsMinus1 >= (1<<(LOG2_MAX_NUM_COLUMNS_MINUS1+1)) )
1025  {
1026    printf( "The number of columns is larger than the maximum allowed number of columns.\n" );
1027    exit( EXIT_FAILURE );
1028  }
1029
1030  if( m_iNumColumnsMinus1 >= iWidthInCU )
1031  {
1032    printf( "The current picture can not have so many columns.\n" );
1033    exit( EXIT_FAILURE );
1034  }
1035
1036  if( m_iNumColumnsMinus1 && m_iUniformSpacingIdr==0 )
1037  {
1038    for(Int i=0; i<m_iNumColumnsMinus1; i++)
1039      uiCummulativeColumnWidth += m_puiColumnWidth[i];
1040
1041    if( uiCummulativeColumnWidth >= iWidthInCU )
1042    {
1043      printf( "The width of the column is too large.\n" );
1044      exit( EXIT_FAILURE );
1045    }
1046  }
1047
1048  //check the row relative parameters
1049  if( m_iNumRowsMinus1 >= (1<<(LOG2_MAX_NUM_ROWS_MINUS1+1)) )
1050  {
1051    printf( "The number of rows is larger than the maximum allowed number of rows.\n" );
1052    exit( EXIT_FAILURE );
1053  }
1054
1055  if( m_iNumRowsMinus1 >= iHeightInCU )
1056  {
1057    printf( "The current picture can not have so many rows.\n" );
1058    exit( EXIT_FAILURE );
1059  }
1060
1061  if( m_iNumRowsMinus1 && m_iUniformSpacingIdr==0 )
1062  {
1063    for(Int i=0; i<m_iNumRowsMinus1; i++)
1064      uiCummulativeRowHeight += m_puiRowHeight[i];
1065
1066    if( uiCummulativeRowHeight >= iHeightInCU )
1067    {
1068      printf( "The height of the row is too large.\n" );
1069      exit( EXIT_FAILURE );
1070    }
1071  }
1072}
1073
1074Void TEncTop::setTEncTopList(std::vector<TEncTop*>* pacTEncTopList )
1075{
1076  assert(m_viewId!=-1); // not to be set for single view coding
1077
1078  m_pacTEncTopList=pacTEncTopList;
1079
1080}
1081
1082Void TEncTop::printOutSummary(UInt uiNumAllPicCoded)
1083{
1084  assert (uiNumAllPicCoded == m_cAnalyzeAll.getNumPic());
1085
1086  //--CFG_KDY
1087  m_cAnalyzeAll.setFrmRate( getFrameRate() );
1088  m_cAnalyzeI.setFrmRate( getFrameRate() );
1089  m_cAnalyzeP.setFrmRate( getFrameRate() );
1090  m_cAnalyzeB.setFrmRate( getFrameRate() );
1091
1092  //-- all
1093  if(m_viewId==-1)
1094    printf( "\n\nSUMMARY --------------------------------------------------------\n" );
1095  else {
1096    if ( m_isDepth )
1097    {
1098      printf( "\n\nSUMMARY ---------------------------------------------- DEPTH %2d\n", m_viewId );
1099    }
1100    else
1101    {
1102      printf( "\n\nSUMMARY ---------------------------------------------- VIDEO %2d\n", m_viewId );
1103    }
1104  };
1105  m_cAnalyzeAll.printOut('a');
1106
1107  printf( "\n\nI Slices--------------------------------------------------------\n" );
1108  m_cAnalyzeI.printOut('i');
1109
1110  printf( "\n\nP Slices--------------------------------------------------------\n" );
1111  m_cAnalyzeP.printOut('p');
1112
1113  printf( "\n\nB Slices--------------------------------------------------------\n" );
1114  m_cAnalyzeB.printOut('b');
1115
1116//  m_cAnalyzeAll.printSummaryOut();
1117//  m_cAnalyzeI.printSummary('I');
1118//  m_cAnalyzeP.printSummary('P');
1119//  m_cAnalyzeB.printSummary('B');
1120}
1121
1122//! \}
Note: See TracBrowser for help on using the repository browser.