HEVC Test Model (HM)  HM-16.3
TEncAnalyze.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 
38 #ifndef __TENCANALYZE__
39 #define __TENCANALYZE__
40 
41 #if _MSC_VER > 1000
42 #pragma once
43 #endif // _MSC_VER > 1000
44 
45 #include <stdio.h>
46 #include <memory.h>
47 #include <assert.h>
48 #include "TLibCommon/CommonDef.h"
50 #include "math.h"
51 
54 
55 // ====================================================================================================================
56 // Class definition
57 // ====================================================================================================================
58 
61 {
62 private:
66  Double m_dFrmRate; //--CFG_KDY
68 
69 public:
70  virtual ~TEncAnalyze() {}
71  TEncAnalyze() { clear(); }
72 
73  Void addResult( Double psnr[MAX_NUM_COMPONENT], Double bits, const Double MSEyuvframe[MAX_NUM_COMPONENT])
74  {
75  m_dAddBits += bits;
76  for(UInt i=0; i<MAX_NUM_COMPONENT; i++)
77  {
78  m_dPSNRSum[i] += psnr[i];
79  m_MSEyuvframe[i] += MSEyuvframe[i];
80  }
81 
82  m_uiNumPic++;
83  }
84 
85  Double getPsnr(ComponentID compID) const { return m_dPSNRSum[compID]; }
86  Double getBits() const { return m_dAddBits; }
87  Void setBits(Double numBits) { m_dAddBits=numBits; }
88  UInt getNumPic() const { return m_uiNumPic; }
89 
90  Void setFrmRate (Double dFrameRate) { m_dFrmRate = dFrameRate; } //--CFG_KDY
92  {
93  m_dAddBits = 0;
94  for(UInt i=0; i<MAX_NUM_COMPONENT; i++)
95  {
96  m_dPSNRSum[i] = 0;
97  m_MSEyuvframe[i] = 0;
98  }
99  m_uiNumPic = 0;
100  }
101 
102 
103  Void calculateCombinedValues(const ChromaFormat chFmt, Double &PSNRyuv, Double &MSEyuv)
104  {
105  MSEyuv = 0;
106  Int scale = 0;
107 
108  Int maximumBitDepth = g_bitDepth[0];
109  for (UInt channelTypeIndex = 1; channelTypeIndex < MAX_NUM_CHANNEL_TYPE; channelTypeIndex++)
110  {
111  if (g_bitDepth[channelTypeIndex] > maximumBitDepth)
112  {
113  maximumBitDepth = g_bitDepth[channelTypeIndex];
114  }
115  }
116 
117  const UInt maxval = 255 << (maximumBitDepth - 8);
118  const UInt numberValidComponents = getNumberValidComponents(chFmt);
119 
120  for (UInt comp=0; comp<numberValidComponents; comp++)
121  {
122  const ComponentID compID = ComponentID(comp);
123  const UInt csx = getComponentScaleX(compID, chFmt);
124  const UInt csy = getComponentScaleY(compID, chFmt);
125  const Int scaleChan = (4>>(csx+csy));
126  const UInt bitDepthShift = 2 * (maximumBitDepth - g_bitDepth[toChannelType(compID)]); //*2 because this is a squared number
127 
128  const Double channelMSE = (m_MSEyuvframe[compID] * Double(1 << bitDepthShift)) / Double(getNumPic());
129 
130  scale += scaleChan;
131  MSEyuv += scaleChan * channelMSE;
132  }
133 
134  MSEyuv /= Double(scale); // i.e. divide by 6 for 4:2:0, 8 for 4:2:2 etc.
135  PSNRyuv = (MSEyuv==0 ? 999.99 : 10*log10((maxval*maxval)/MSEyuv));
136  }
137 
138 
139  Void printOut ( Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE )
140  {
141  Double dFps = m_dFrmRate; //--CFG_KDY
142  Double dScale = dFps / 1000 / (Double)m_uiNumPic;
143 
144  Double MSEBasedSNR[MAX_NUM_COMPONENT];
145  if (printMSEBasedSNR)
146  {
147  for (UInt componentIndex = 0; componentIndex < MAX_NUM_COMPONENT; componentIndex++)
148  {
149  const ComponentID compID = ComponentID(componentIndex);
150 
151  if (getNumPic() == 0)
152  {
153  MSEBasedSNR[compID] = 0 * dScale; // this is the same calculation that will be evaluated for any other statistic when there are no frames (it should result in NaN). We use it here so all the output is consistent.
154  }
155  else
156  {
157  //NOTE: this is not the true maximum value for any bitDepth other than 8. It comes from the original HM PSNR calculation
158  const UInt maxval = 255 << (g_bitDepth[toChannelType(compID)] - 8);
159  const Double MSE = m_MSEyuvframe[compID];
160 
161  MSEBasedSNR[compID] = (MSE == 0) ? 999.99 : (10 * log10((maxval * maxval) / (MSE / (Double)getNumPic())));
162  }
163  }
164  }
165 
166  switch (chFmt)
167  {
168  case CHROMA_400:
169  if (printMSEBasedSNR)
170  {
171  printf( " \tTotal Frames | " "Bitrate " "Y-PSNR" );
172 
173  if (printSequenceMSE)
174  {
175  printf( " Y-MSE\n" );
176  }
177  else
178  {
179  printf("\n");
180  }
181 
182  //printf( "\t------------ " " ----------" " -------- " " -------- " " --------\n" );
183  printf( "Average: \t %8d %c " "%12.4lf " "%8.4lf",
184  getNumPic(), cDelim,
185  getBits() * dScale,
187 
188  if (printSequenceMSE)
189  {
190  printf( " %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
191  }
192  else
193  {
194  printf("\n");
195  }
196 
197  printf( "From MSE:\t %8d %c " "%12.4lf " "%8.4lf\n",
198  getNumPic(), cDelim,
199  getBits() * dScale,
200  MSEBasedSNR[COMPONENT_Y] );
201  }
202  else
203  {
204  printf( "\tTotal Frames | " "Bitrate " "Y-PSNR" );
205 
206  if (printSequenceMSE)
207  {
208  printf( " Y-MSE\n" );
209  }
210  else
211  {
212  printf("\n");
213  }
214 
215  //printf( "\t------------ " " ----------" " -------- " " -------- " " --------\n" );
216  printf( "\t %8d %c " "%12.4lf " "%8.4lf",
217  getNumPic(), cDelim,
218  getBits() * dScale,
220 
221  if (printSequenceMSE)
222  {
223  printf( " %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
224  }
225  else
226  {
227  printf("\n");
228  }
229  }
230  break;
231  case CHROMA_420:
232  case CHROMA_422:
233  case CHROMA_444:
234  {
235  Double PSNRyuv = MAX_DOUBLE;
236  Double MSEyuv = MAX_DOUBLE;
237 
238  calculateCombinedValues(chFmt, PSNRyuv, MSEyuv);
239 
240  if (printMSEBasedSNR)
241  {
242  printf( " \tTotal Frames | " "Bitrate " "Y-PSNR " "U-PSNR " "V-PSNR " "YUV-PSNR " );
243 
244  if (printSequenceMSE)
245  {
246  printf( " Y-MSE " "U-MSE " "V-MSE " "YUV-MSE \n" );
247  }
248  else
249  {
250  printf("\n");
251  }
252 
253  //printf( "\t------------ " " ----------" " -------- " " -------- " " --------\n" );
254  printf( "Average: \t %8d %c " "%12.4lf " "%8.4lf " "%8.4lf " "%8.4lf " "%8.4lf",
255  getNumPic(), cDelim,
256  getBits() * dScale,
260  PSNRyuv );
261 
262  if (printSequenceMSE)
263  {
264  printf( " %8.4lf " "%8.4lf " "%8.4lf " "%8.4lf\n",
265  m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
266  m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
267  m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
268  MSEyuv );
269  }
270  else
271  {
272  printf("\n");
273  }
274 
275  printf( "From MSE:\t %8d %c " "%12.4lf " "%8.4lf " "%8.4lf " "%8.4lf " "%8.4lf\n",
276  getNumPic(), cDelim,
277  getBits() * dScale,
278  MSEBasedSNR[COMPONENT_Y],
279  MSEBasedSNR[COMPONENT_Cb],
280  MSEBasedSNR[COMPONENT_Cr],
281  PSNRyuv );
282  }
283  else
284  {
285  printf( "\tTotal Frames | " "Bitrate " "Y-PSNR " "U-PSNR " "V-PSNR " "YUV-PSNR " );
286 
287  if (printSequenceMSE)
288  {
289  printf( " Y-MSE " "U-MSE " "V-MSE " "YUV-MSE \n" );
290  }
291  else
292  {
293  printf("\n");
294  }
295 
296  //printf( "\t------------ " " ----------" " -------- " " -------- " " --------\n" );
297  printf( "\t %8d %c " "%12.4lf " "%8.4lf " "%8.4lf " "%8.4lf " "%8.4lf",
298  getNumPic(), cDelim,
299  getBits() * dScale,
303  PSNRyuv );
304 
305  if (printSequenceMSE)
306  {
307  printf( " %8.4lf " "%8.4lf " "%8.4lf " "%8.4lf\n",
308  m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
309  m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
310  m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
311  MSEyuv );
312  }
313  else
314  {
315  printf("\n");
316  }
317  }
318  }
319  break;
320  default:
321  fprintf(stderr, "Unknown format during print out\n");
322  exit(1);
323  break;
324  }
325  }
326 
327 
328  Void printSummary(const ChromaFormat chFmt, const Bool printSequenceMSE, Char ch='T')
329  {
330  FILE* pFile = NULL;
331 
332  switch( ch )
333  {
334  case 'T':
335  pFile = fopen ("summaryTotal.txt", "at");
336  break;
337  case 'I':
338  pFile = fopen ("summary_I.txt", "at");
339  break;
340  case 'P':
341  pFile = fopen ("summary_P.txt", "at");
342  break;
343  case 'B':
344  pFile = fopen ("summary_B.txt", "at");
345  break;
346  default:
347  assert(0);
348  return;
349  break;
350  }
351 
352  Double dFps = m_dFrmRate; //--CFG_KDY
353  Double dScale = dFps / 1000 / (Double)m_uiNumPic;
354  switch (chFmt)
355  {
356  case CHROMA_400:
357  fprintf(pFile, "%f\t %f\n",
358  getBits() * dScale,
360  break;
361  case CHROMA_420:
362  case CHROMA_422:
363  case CHROMA_444:
364  {
365  Double PSNRyuv = MAX_DOUBLE;
366  Double MSEyuv = MAX_DOUBLE;
367 
368  calculateCombinedValues(chFmt, PSNRyuv, MSEyuv);
369 
370  fprintf(pFile, "%f\t %f\t %f\t %f\t %f",
371  getBits() * dScale,
375  PSNRyuv );
376 
377  if (printSequenceMSE)
378  {
379  fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
380  m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
381  m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
382  m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
383  MSEyuv );
384  }
385  else
386  {
387  fprintf(pFile, "\n");
388  }
389 
390  break;
391  }
392 
393  default:
394  fprintf(stderr, "Unknown format during print out\n");
395  exit(1);
396  break;
397  }
398 
399  fclose(pFile);
400  }
401 };
402 
407 
409 
411 
412 #endif // !defined(AFX_TENCANALYZE_H__C79BCAA2_6AC8_4175_A0FE_CF02F5829233__INCLUDED_)
Double getPsnr(ComponentID compID) const
Definition: TEncAnalyze.h:85
Void setFrmRate(Double dFrameRate)
Definition: TEncAnalyze.h:90
Defines constants, macros and tool parameters.
TEncAnalyze m_gcAnalyzeP
Definition: TEncAnalyze.cpp:49
void Void
Definition: TypeDef.h:285
#define NULL
Definition: CommonDef.h:100
UInt m_uiNumPic
Definition: TEncAnalyze.h:65
static UInt getComponentScaleY(const ComponentID id, const ChromaFormat fmt)
char Char
Definition: TypeDef.h:291
Double m_dFrmRate
Definition: TEncAnalyze.h:66
unsigned int UInt
Definition: TypeDef.h:297
static UInt getComponentScaleX(const ComponentID id, const ChromaFormat fmt)
Double m_dPSNRSum[MAX_NUM_COMPONENT]
Definition: TEncAnalyze.h:63
UInt getNumPic() const
Definition: TEncAnalyze.h:88
virtual ~TEncAnalyze()
Definition: TEncAnalyze.h:70
TEncAnalyze m_gcAnalyzeI
Definition: TEncAnalyze.cpp:48
TEncAnalyze m_gcAnalyzeAll_in
Definition: TEncAnalyze.cpp:52
Void calculateCombinedValues(const ChromaFormat chFmt, Double &PSNRyuv, Double &MSEyuv)
Definition: TEncAnalyze.h:103
Void addResult(Double psnr[MAX_NUM_COMPONENT], Double bits, const Double MSEyuvframe[MAX_NUM_COMPONENT])
Definition: TEncAnalyze.h:73
TEncAnalyze m_gcAnalyzeAll
Definition: TEncAnalyze.cpp:47
Void printOut(Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE)
Definition: TEncAnalyze.h:139
encoder analyzer class
Definition: TEncAnalyze.h:60
bool Bool
Definition: TypeDef.h:286
TEncAnalyze m_gcAnalyzeB
Definition: TEncAnalyze.cpp:50
Double m_dAddBits
Definition: TEncAnalyze.h:64
static ChannelType toChannelType(const ComponentID id)
ChromaFormat
chroma formats (according to semantics of chroma_format_idc)
Definition: TypeDef.h:352
Double getBits() const
Definition: TEncAnalyze.h:86
Int g_bitDepth[MAX_NUM_CHANNEL_TYPE]
Definition: TComRom.cpp:548
Void printSummary(const ChromaFormat chFmt, const Bool printSequenceMSE, Char ch='T')
Definition: TEncAnalyze.h:328
int Int
Definition: TypeDef.h:296
ComponentID
Definition: TypeDef.h:368
#define MAX_DOUBLE
max. value of Double-type value
Definition: CommonDef.h:124
double Double
Definition: TypeDef.h:298
static UInt getNumberValidComponents(const ChromaFormat fmt)
Void clear()
Definition: TEncAnalyze.h:91
Void setBits(Double numBits)
Definition: TEncAnalyze.h:87
Double m_MSEyuvframe[MAX_NUM_COMPONENT]
Definition: TEncAnalyze.h:67