source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/TComCodingStatistics.h @ 1302

Last change on this file since 1302 was 1259, checked in by seregin, 9 years ago

port rev 4256

File size: 16.9 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-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
44static const Int64 TCOMCODINGSTATISTICS_ENTROPYSCALE=32768;
45
46
47enum TComCodingStatisticsType
48{
49  STATS__NAL_UNIT_TOTAL_BODY,// This is a special case and is not included in the total sums.
50  STATS__NAL_UNIT_PACKING,
51  STATS__EMULATION_PREVENTION_3_BYTES,
52  STATS__NAL_UNIT_HEADER_BITS,
53  STATS__CABAC_INITIALISATION,
54  STATS__CABAC_BITS__TQ_BYPASS_FLAG,
55  STATS__CABAC_BITS__SKIP_FLAG,
56  STATS__CABAC_BITS__MERGE_FLAG,
57  STATS__CABAC_BITS__MERGE_INDEX,
58  STATS__CABAC_BITS__MVP_IDX,
59  STATS__CABAC_BITS__SPLIT_FLAG,
60  STATS__CABAC_BITS__PART_SIZE,
61  STATS__CABAC_BITS__PRED_MODE,
62  STATS__CABAC_BITS__INTRA_DIR_ANG,
63  STATS__CABAC_BITS__INTER_DIR,
64  STATS__CABAC_BITS__REF_FRM_IDX,
65  STATS__CABAC_BITS__MVD,
66  STATS__CABAC_BITS__MVD_EP,
67  STATS__CABAC_BITS__TRANSFORM_SUBDIV_FLAG,
68  STATS__CABAC_BITS__QT_ROOT_CBF,
69  STATS__CABAC_BITS__DELTA_QP_EP,
70  STATS__CABAC_BITS__CHROMA_QP_ADJUSTMENT,
71  STATS__CABAC_BITS__QT_CBF,
72  STATS__CABAC_BITS__CROSS_COMPONENT_PREDICTION,
73  STATS__CABAC_BITS__TRANSFORM_SKIP_FLAGS,
74
75  STATS__CABAC_BITS__LAST_SIG_X_Y,
76  STATS__CABAC_BITS__SIG_COEFF_GROUP_FLAG,
77  STATS__CABAC_BITS__SIG_COEFF_MAP_FLAG,
78  STATS__CABAC_BITS__GT1_FLAG,
79  STATS__CABAC_BITS__GT2_FLAG,
80  STATS__CABAC_BITS__SIGN_BIT,
81  STATS__CABAC_BITS__ESCAPE_BITS,
82
83  STATS__CABAC_BITS__SAO,
84  STATS__CABAC_TRM_BITS,
85  STATS__CABAC_FIXED_BITS,
86  STATS__CABAC_PCM_ALIGN_BITS,
87  STATS__CABAC_PCM_CODE_BITS,
88  STATS__BYTE_ALIGNMENT_BITS,
89  STATS__TRAILING_BITS,
90  STATS__EXPLICIT_RDPCM_BITS,
91  STATS__CABAC_EP_BIT_ALIGNMENT,
92  STATS__CABAC_BITS__ALIGNED_SIGN_BIT,
93  STATS__CABAC_BITS__ALIGNED_ESCAPE_BITS,
94  STATS__NUM_STATS
95};
96
97static 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
149static inline Bool isAlignedBins(TComCodingStatisticsType statT) { return statT==STATS__CABAC_BITS__ALIGNED_SIGN_BIT || statT==STATS__CABAC_BITS__ALIGNED_ESCAPE_BITS; }
150
151static const UInt CODING_STATS_NUM_WIDTHS=7;
152static const UInt CODING_STATS_NUM_SUBCLASSES=CODING_STATS_NUM_WIDTHS*(1+MAX_NUM_COMPONENT+MAX_NUM_CHANNEL_TYPE);
153
154class TComCodingStatisticsClassType
155{
156public:
157
158  TComCodingStatisticsClassType(const TComCodingStatisticsType t)
159    : type(t), subClass(0)
160  { }
161  TComCodingStatisticsClassType(const TComCodingStatisticsType t, const UInt log2w )
162    : type(t), subClass(log2w)
163  { }
164  TComCodingStatisticsClassType(const TComCodingStatisticsType t, const Int log2w )
165    : type(t), subClass(log2w)
166  { }
167  TComCodingStatisticsClassType(const TComCodingStatisticsType t, const ComponentID cid )
168    : type(t), subClass((cid+1)*CODING_STATS_NUM_WIDTHS)
169  { }
170  TComCodingStatisticsClassType(const TComCodingStatisticsType t, const ChannelType chid )
171    : type(t), subClass((chid+MAX_NUM_COMPONENT+1)*CODING_STATS_NUM_WIDTHS)
172  { }
173  TComCodingStatisticsClassType(const TComCodingStatisticsType t, const UInt log2w, const ComponentID cid )
174    : type(t), subClass((cid+1)*CODING_STATS_NUM_WIDTHS + log2w)
175  { }
176  TComCodingStatisticsClassType(const TComCodingStatisticsType t, const UInt log2w, const ChannelType chid )
177    : type(t), subClass((chid+MAX_NUM_COMPONENT+1)*CODING_STATS_NUM_WIDTHS + log2w)
178  { }
179
180  static UInt GetSubClassWidth(const UInt subClass)
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
192  TComCodingStatisticsType type;
193  UInt subClass;
194};
195
196
197
198class TComCodingStatistics
199{
200  public:
201
202
203    struct StatLogValue
204    {
205      UInt values[512+1];
206      StatLogValue()
207      {
208        const Double es=Double(TCOMCODINGSTATISTICS_ENTROPYSCALE);
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) { }
220      Int64 bits;
221      Int64 count;
222      Int64 sum;
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
229    class TComCodingStatisticsData
230    {
231      private:
232        SStat statistics[STATS__NUM_STATS+1][CODING_STATS_NUM_SUBCLASSES];
233        SStat statistics_ep[STATS__NUM_STATS+1][CODING_STATS_NUM_SUBCLASSES ];
234        std::map<std::string, SStat> mappings_ep;
235        friend class TComCodingStatistics;
236    };
237
238  private:
239
240    TComCodingStatisticsData data;
241
242    TComCodingStatistics() : data()
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
285    ~TComCodingStatistics()
286    {
287      const Int64 es=TCOMCODINGSTATISTICS_ENTROPYSCALE;
288
289      Int64 cr=0; // CABAC remainder, which is added to "STATS__CABAC_INITIALISATION"
290      {
291        Int64 totalCABACbits=0, roundedCABACbits=0;
292        for(Int i=STATS__NAL_UNIT_PACKING; i<STATS__NUM_STATS; i++)
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          }
340          UInt width=TComCodingStatisticsClassType::GetSubClassWidth(c);
341          OutputLine(pName, ':', width, TComCodingStatisticsClassType::GetSubClassString(c), sCABAC, sEP);
342          cabacSubTotal+=sCABAC;
343          epSubTotal+=sEP;
344          if (i!=STATS__NAL_UNIT_TOTAL_BODY)
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        }
357        if (i==STATS__NAL_UNIT_TOTAL_BODY)
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;
382        for(UInt c=0; c<CODING_STATS_NUM_SUBCLASSES; c+=CODING_STATS_NUM_WIDTHS)
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");
393      for(UInt c=0; c<CODING_STATS_NUM_SUBCLASSES; c+=CODING_STATS_NUM_WIDTHS)
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");
407      for(UInt c=0; c<CODING_STATS_NUM_SUBCLASSES; c+=CODING_STATS_NUM_WIDTHS)
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:
431    static TComCodingStatistics& GetSingletonInstance()
432    {
433      static TComCodingStatistics inst;
434      return inst;
435    }
436
437    static const TComCodingStatisticsData &GetStatistics()         { return GetSingletonInstance().data; }
438    static Void SetStatistics(const TComCodingStatisticsData &src) { GetSingletonInstance().data=src; }
439
440    static SStat &GetStatisticEP(const TComCodingStatisticsClassType &stat) { return GetSingletonInstance().data.statistics_ep[stat.type][stat.subClass]; }
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
470    StatLogValue values;
471
472    static Void UpdateCABACStat(const TComCodingStatisticsClassType &stat, UInt uiRangeBefore, UInt uiRangeAfter, Int val)
473    {
474      TComCodingStatistics &inst=GetSingletonInstance();
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
Note: See TracBrowser for help on using the repository browser.