HEVC Test Model (HM)  HM-16.3
TComCodingStatistics.h
Go to the documentation of this file.
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-2015, 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 #ifndef __TCOMCODINGSTATISTICS__
35 #define __TCOMCODINGSTATISTICS__
36 
37 #include "TypeDef.h"
38 #include <stdio.h>
39 #include <string>
40 #include <map>
41 #include <math.h>
42 #include "TComChromaFormat.h"
43 
45 
46 
48 {
49  STATS__NAL_UNIT_TOTAL_BODY,// This is a special case and is not included in the total sums.
74 
82 
95 };
96 
97 static inline const Char* getName(TComCodingStatisticsType name)
98 {
99  static const Char *statNames[]=
100  {
101  "NAL_UNIT_TOTAL_BODY", // This is a special case and is not included in the total sums.
102  "NAL_UNIT_PACKING",
103  "EMULATION_PREVENTION_3_BYTES",
104  "NAL_UNIT_HEADER_BITS",
105  "CABAC_INITIALISATION-and-rounding",
106  "CABAC_BITS__TQ_BYPASS_FLAG",
107  "CABAC_BITS__SKIP_FLAG",
108  "CABAC_BITS__MERGE_FLAG",
109  "CABAC_BITS__MERGE_INDEX",
110  "CABAC_BITS__MVP_IDX",
111  "CABAC_BITS__SPLIT_FLAG",
112  "CABAC_BITS__PART_SIZE",
113  "CABAC_BITS__PRED_MODE",
114  "CABAC_BITS__INTRA_DIR_ANG",
115  "CABAC_BITS__INTER_DIR",
116  "CABAC_BITS__REF_FRM_IDX",
117  "CABAC_BITS__MVD",
118  "CABAC_BITS__MVD_EP",
119  "CABAC_BITS__TRANSFORM_SUBDIV_FLAG",
120  "CABAC_BITS__QT_ROOT_CBF",
121  "CABAC_BITS__DELTA_QP_EP",
122  "CABAC_BITS__CHROMA_QP_ADJUSTMENT",
123  "CABAC_BITS__QT_CBF",
124  "CABAC_BITS__CROSS_COMPONENT_PREDICTION",
125  "CABAC_BITS__TRANSFORM_SKIP_FLAGS",
126  "CABAC_BITS__LAST_SIG_X_Y",
127  "CABAC_BITS__SIG_COEFF_GROUP_FLAG",
128  "CABAC_BITS__SIG_COEFF_MAP_FLAG",
129  "CABAC_BITS__GT1_FLAG",
130  "CABAC_BITS__GT2_FLAG",
131  "CABAC_BITS__SIGN_BIT",
132  "CABAC_BITS__ESCAPE_BITS",
133  "CABAC_BITS__SAO",
134  "CABAC_TRM_BITS",
135  "CABAC_FIXED_BITS",
136  "CABAC_PCM_ALIGN_BITS",
137  "CABAC_PCM_CODE_BITS",
138  "BYTE_ALIGNMENT_BITS",
139  "TRAILING_BITS",
140  "EXPLICIT_RDPCM_BITS",
141  "CABAC_EP_BIT_ALIGNMENT",
142  "CABAC_BITS__ALIGNED_SIGN_BIT",
143  "CABAC_BITS__ALIGNED_ESCAPE_BITS"
144  };
145  assert(STATS__NUM_STATS == sizeof(statNames)/sizeof(Char *) && name < STATS__NUM_STATS);
146  return statNames[name];
147 }
148 
150 
153 
155 {
156 public:
157 
159  : type(t), subClass(0)
160  { }
162  : type(t), subClass(log2w)
163  { }
165  : type(t), subClass(log2w)
166  { }
168  : type(t), subClass((cid+1)*CODING_STATS_NUM_WIDTHS)
169  { }
172  { }
174  : type(t), subClass((cid+1)*CODING_STATS_NUM_WIDTHS + log2w)
175  { }
178  { }
179 
181  {
182  return subClass%CODING_STATS_NUM_WIDTHS;
183  }
184 
185  static const Char *GetSubClassString(const UInt subClass)
186  {
187  assert (subClass<CODING_STATS_NUM_SUBCLASSES);
188  static const Char *strings[1+MAX_NUM_COMPONENT+MAX_NUM_CHANNEL_TYPE]={"-", "Y", "Cb", "Cr", "Luma", "Chroma"};
189  return strings[subClass/CODING_STATS_NUM_WIDTHS];
190  }
191 
194 };
195 
196 
197 
199 {
200  public:
201 
202 
204  {
205  UInt values[512+1];
207  {
209  values[0]=0;
210  for(UInt i=1; i<sizeof(values)/sizeof(UInt); i++)
211  {
212  values[i]=UInt( log(Double(i))*es/log(2.0) );
213  }
214  }
215  };
216 
217  struct SStat
218  {
219  SStat() : bits(0), count(0), sum(0) { }
223  Void clear() { bits=0; count=0; sum=0; }
224 
225  SStat &operator+=(const SStat &src)
226  { bits+=src.bits; count+=src.count; sum+=src.sum; return *this; }
227  };
228 
230  {
231  private:
234  std::map<std::string, SStat> mappings_ep;
235  friend class TComCodingStatistics;
236  };
237 
238  private:
239 
241 
243  { }
244 
245  static Void OutputLine(const Char *pName, const Char sep, UInt width, const Char *pSubClassStr, const SStat &sCABAC, const SStat &sEP)
246  {
247  if (width==0)
248  {
249  OutputLine(pName, sep, "-", pSubClassStr, sCABAC, sEP);
250  }
251  else
252  {
253  printf("%c%-45s%c %6d %6s %12lld %12lld %12lld %12lld %12lld %12lld %12lld (%12lld)%c\n",
254  sep=='~'?'[':' ', pName, sep, 1<<width, pSubClassStr,
255  sCABAC.count, sCABAC.sum, sCABAC.bits, sEP.count, sEP.sum, sEP.bits, sCABAC.bits+sEP.bits, (sCABAC.bits+sEP.bits)/8, sep=='~'?']':' ');
256  }
257  }
258  static Void OutputLine(const Char *pName, const Char sep, const Char *pWidthString, const Char *pSubClassStr, const SStat &sCABAC, const SStat &sEP)
259  {
260  printf("%c%-45s%c %6s %6s %12lld %12lld %12lld %12lld %12lld %12lld %12lld (%12lld)%c\n",
261  sep=='~'?'[':' ', pName, sep, pWidthString, pSubClassStr,
262  sCABAC.count, sCABAC.sum, sCABAC.bits, sEP.count, sEP.sum, sEP.bits, sCABAC.bits+sEP.bits, (sCABAC.bits+sEP.bits)/8, sep=='~'?']':' ');
263  }
264  static Void OutputLine(const Char *pName, const Char sep, const Char *pWidthString, const Char *pSubClassStr, const SStat &sEP)
265  {
266  printf("%c%-45s%c %6s %6s %12s %12s %12s %12lld %12lld %12lld %12lld (%12lld)%c\n",
267  sep=='~'?'[':' ', pName, sep, pWidthString, pSubClassStr,
268  "", "", "", sEP.count, sEP.sum, sEP.bits, sEP.bits, (sEP.bits)/8, sep=='~'?']':' ');
269  }
270 
271  static Void OutputDashedLine(const Char *pText)
272  {
273  printf("--%s",pText);
274  UInt tot=0;
275  for(;pText[tot]!=0; tot++);
276 
277  tot+=2;
278  for (; tot<168; tot++)
279  {
280  printf("-");
281  }
282  printf("\n");
283  }
284 
286  {
288 
289  Int64 cr=0; // CABAC remainder, which is added to "STATS__CABAC_INITIALISATION"
290  {
291  Int64 totalCABACbits=0, roundedCABACbits=0;
293  {
294  for(UInt c=0; c<CODING_STATS_NUM_SUBCLASSES; c++)
295  {
296  totalCABACbits+=data.statistics[i][c].bits;
297  roundedCABACbits+=data.statistics[i][c].bits/es;
298  }
299  }
300  Int64 remainder=totalCABACbits - roundedCABACbits*es;
301  cr=(remainder+es/2)/es;
302  }
303 
304  printf("Note %s will be excluded from the total as it should be the sum of all the other entries (except for %s)\n", getName(STATS__NAL_UNIT_TOTAL_BODY), getName(STATS__NAL_UNIT_PACKING));
305  printf(" %-45s- Width Type CABAC Count CABAC Sum CABAC bits EP Count EP Sum EP bits Total bits ( Total bytes)\n", "Decoder statistics");
306 
307  OutputDashedLine("");
308  SStat cabacTotalBits, epTotalBits;
309  SStat statTotals_cabac[CODING_STATS_NUM_SUBCLASSES];
310  SStat statTotals_ep[CODING_STATS_NUM_SUBCLASSES];
311 
312  for(Int i=0; i<STATS__NUM_STATS; i++)
313  {
314  SStat cabacSubTotal, epSubTotal;
315  Bool bHadClassifiedEntry=false;
316  const Char *pName=getName(TComCodingStatisticsType(i));
317 
318  for(UInt c=0; c<CODING_STATS_NUM_SUBCLASSES; c++)
319  {
320  SStat &sCABACorig=data.statistics[i][c];
321  SStat &sEP=data.statistics_ep[i][c];
322 
323  if (sCABACorig.bits==0 && sEP.bits==0)
324  {
325  continue;
326  }
327 
328  SStat sCABAC;
329  {
330  Int64 thisCABACbits=sCABACorig.bits/es;
331  if (i==STATS__CABAC_INITIALISATION && sCABACorig.bits!=0)
332  {
333  thisCABACbits+=cr;
334  cr=0;
335  }
336  sCABAC.bits=thisCABACbits;
337  sCABAC.count=sCABACorig.count;
338  sCABAC.sum=sCABACorig.sum;
339  }
341  OutputLine(pName, ':', width, TComCodingStatisticsClassType::GetSubClassString(c), sCABAC, sEP);
342  cabacSubTotal+=sCABAC;
343  epSubTotal+=sEP;
345  {
346  cabacTotalBits+=sCABAC;
347  epTotalBits+=sEP;
348  statTotals_cabac[c]+=sCABAC;
349  statTotals_ep[c]+=sEP;
350  }
351  bHadClassifiedEntry=bHadClassifiedEntry||(c!=0);
352  }
353  if (bHadClassifiedEntry)
354  {
355  OutputLine(pName, '~', "~~ST~~", "~~ST~~", cabacSubTotal, epSubTotal);
356  }
358  {
359  OutputDashedLine("");
360  }
361  }
362  OutputDashedLine("");
363  OutputLine("CABAC Sub-total", '~', "~~ST~~", "~~ST~~", cabacTotalBits, epTotalBits);
364 
365  OutputDashedLine("CAVLC HEADER BITS");
366  SStat cavlcTotalBits;
367  for(std::map<std::string, SStat>::iterator it=data.mappings_ep.begin(); it!=data.mappings_ep.end(); it++)
368  {
369  SStat s=it->second;
370  cavlcTotalBits+=s;
371  OutputLine(it->first.c_str(), ':', "-", "-", s);
372  }
373 
374  OutputDashedLine("");
375  OutputLine("CAVLC Header Sub-total", '~', "~~ST~~", "~~ST~~", cavlcTotalBits);
376 
377  // Now output the breakdowns
378  OutputDashedLine("CABAC Break down by size");
379  for(UInt s=0; s<CODING_STATS_NUM_WIDTHS; s++)
380  {
381  SStat subTotalCabac, subTotalEP;
383  {
384  subTotalCabac+=statTotals_cabac[c+s];
385  subTotalEP+=statTotals_ep[c+s];
386  }
387  if (subTotalCabac.bits!=0 || subTotalEP.bits!=0)
388  {
389  OutputLine("CABAC by size Sub-total", '=', s, "All", subTotalCabac, subTotalEP);
390  }
391  }
392  OutputDashedLine("Break down by component/Channel type");
394  {
395  SStat subTotalCabac, subTotalEP;
396  for(UInt s=0; s<CODING_STATS_NUM_WIDTHS; s++)
397  {
398  subTotalCabac+=statTotals_cabac[c+s];
399  subTotalEP+=statTotals_ep[c+s];
400  }
401  if (subTotalCabac.bits!=0 || subTotalEP.bits!=0)
402  {
403  OutputLine("CABAC by type Sub-total", '=', "-", TComCodingStatisticsClassType::GetSubClassString(c), subTotalCabac, subTotalEP);
404  }
405  }
406  OutputDashedLine("Break down by size and component/Channel type");
408  {
409  for(UInt s=0; s<CODING_STATS_NUM_WIDTHS; s++)
410  {
411  SStat subTotalCabac, subTotalEP;
412  subTotalCabac+=statTotals_cabac[c+s];
413  subTotalEP+=statTotals_ep[c+s];
414  if (subTotalCabac.bits!=0 || subTotalEP.bits!=0)
415  {
416  OutputLine("CABAC by size and type Sub-total", '=', s, TComCodingStatisticsClassType::GetSubClassString(c), subTotalCabac, subTotalEP);
417  }
418  }
419  }
420 
421  OutputDashedLine("");
422  OutputLine("CABAC Sub-total", '~', "~~ST~~", "~~ST~~", cabacTotalBits, epTotalBits);
423  OutputLine("CAVLC Header Sub-total", '~', "~~ST~~", "~~ST~~", cavlcTotalBits);
424  OutputDashedLine("GRAND TOTAL");
425  epTotalBits+=cavlcTotalBits;
426  OutputLine("TOTAL", '~', "~~GT~~", "~~GT~~", cabacTotalBits, epTotalBits);
427  }
428 
429 
430  public:
432  {
433  static TComCodingStatistics inst;
434  return inst;
435  }
436 
439 
441 
442  static SStat &GetStatisticEP(const std::string &str) { return GetSingletonInstance().data.mappings_ep[str]; }
443 
444  static SStat &GetStatisticEP(const Char *pKey) {return GetStatisticEP(std::string(pKey)); }
445 
446  static Void IncrementStatisticEP(const TComCodingStatisticsClassType &stat, const Int numBits, const Int value)
447  {
448  SStat &s=GetStatisticEP(stat);
449  s.bits+=numBits;
450  s.count++;
451  s.sum+=value;
452  }
453 
454  static Void IncrementStatisticEP(const std::string &str, const Int numBits, const Int value)
455  {
456  SStat &s=GetStatisticEP(str);
457  s.bits+=numBits;
458  s.count++;
459  s.sum+=value;
460  }
461 
462  static Void IncrementStatisticEP(const Char *pKey, const Int numBits, const Int value)
463  {
464  SStat &s=GetStatisticEP(pKey);
465  s.bits+=numBits;
466  s.count++;
467  s.sum+=value;
468  }
469 
471 
472  static Void UpdateCABACStat(const TComCodingStatisticsClassType &stat, UInt uiRangeBefore, UInt uiRangeAfter, Int val)
473  {
475  // doing rangeBefore*p(x)=rangeAfter
476  // p(x)=rangeAfter/rangeBefore
477  // entropy = -log2(p(x))=-log(p(x))/log(2) = -(log rangeAfter - log rangeBefore) / log(2) = (log rangeBefore / log 2 - log rangeAfter / log 2)
478  SStat &s=inst.data.statistics[stat.type][stat.subClass];
479  s.bits+=inst.values.values[uiRangeBefore]-inst.values.values[uiRangeAfter];
480  s.count++;
481  s.sum+=val;
482  }
483 };
484 
485 #endif
SStat statistics[STATS__NUM_STATS+1][CODING_STATS_NUM_SUBCLASSES]
static Bool isAlignedBins(TComCodingStatisticsType statT)
TComCodingStatisticsData data
static Void OutputLine(const Char *pName, const Char sep, const Char *pWidthString, const Char *pSubClassStr, const SStat &sEP)
ChannelType
Definition: TypeDef.h:361
void Void
Definition: TypeDef.h:285
TComCodingStatisticsClassType(const TComCodingStatisticsType t, const Int log2w)
char Char
Definition: TypeDef.h:291
static const Char * GetSubClassString(const UInt subClass)
unsigned int UInt
Definition: TypeDef.h:297
static Void IncrementStatisticEP(const Char *pKey, const Int numBits, const Int value)
static const UInt CODING_STATS_NUM_WIDTHS
SStat statistics_ep[STATS__NUM_STATS+1][CODING_STATS_NUM_SUBCLASSES]
static SStat & GetStatisticEP(const TComCodingStatisticsClassType &stat)
TComCodingStatisticsClassType(const TComCodingStatisticsType t, const ChannelType chid)
TComCodingStatisticsType type
static const UInt CODING_STATS_NUM_SUBCLASSES
static Void IncrementStatisticEP(const std::string &str, const Int numBits, const Int value)
TComCodingStatisticsClassType(const TComCodingStatisticsType t, const UInt log2w, const ComponentID cid)
static const Char * getName(TComCodingStatisticsType name)
bool Bool
Definition: TypeDef.h:286
static SStat & GetStatisticEP(const Char *pKey)
long long Int64
Definition: TypeDef.h:317
static Void OutputDashedLine(const Char *pText)
TComCodingStatisticsClassType(const TComCodingStatisticsType t, const UInt log2w, const ChannelType chid)
static Void UpdateCABACStat(const TComCodingStatisticsClassType &stat, UInt uiRangeBefore, UInt uiRangeAfter, Int val)
SStat & operator+=(const SStat &src)
static Void OutputLine(const Char *pName, const Char sep, const Char *pWidthString, const Char *pSubClassStr, const SStat &sCABAC, const SStat &sEP)
TComCodingStatisticsClassType(const TComCodingStatisticsType t)
static UInt GetSubClassWidth(const UInt subClass)
int Int
Definition: TypeDef.h:296
ComponentID
Definition: TypeDef.h:368
TComCodingStatisticsClassType(const TComCodingStatisticsType t, const ComponentID cid)
static const TComCodingStatisticsData & GetStatistics()
TComCodingStatisticsType
static Void OutputLine(const Char *pName, const Char sep, UInt width, const Char *pSubClassStr, const SStat &sCABAC, const SStat &sEP)
double Double
Definition: TypeDef.h:298
static SStat & GetStatisticEP(const std::string &str)
Define basic types, new types and enumerations.
static Void SetStatistics(const TComCodingStatisticsData &src)
static const Int64 TCOMCODINGSTATISTICS_ENTROPYSCALE
static Void IncrementStatisticEP(const TComCodingStatisticsClassType &stat, const Int numBits, const Int value)
TComCodingStatisticsClassType(const TComCodingStatisticsType t, const UInt log2w)
static TComCodingStatistics & GetSingletonInstance()