HEVC Test Model (HM)  HM-16.18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-2017, 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 #if EXTENSION_360_VIDEO
52 #include "TAppEncHelper360/TExt360EncAnalyze.h"
53 #endif
54 
57 
58 // ====================================================================================================================
59 // Class definition
60 // ====================================================================================================================
61 
64 {
65 private:
69  Double m_dFrmRate; //--CFG_KDY
71 #if JVET_F0064_MSSSIM
73 #endif
74 
75 #if EXTENSION_360_VIDEO
76  TExt360EncAnalyze m_ext360;
77 #endif
78 
79 public:
80  virtual ~TEncAnalyze() {}
81  TEncAnalyze() { clear(); }
82 
83 #if JVET_F0064_MSSSIM
84  Void addResult( Double psnr[MAX_NUM_COMPONENT], Double bits, const Double MSEyuvframe[MAX_NUM_COMPONENT], const Double MSSSIM[MAX_NUM_COMPONENT] ) {
85 #else
86  Void addResult( Double psnr[MAX_NUM_COMPONENT], Double bits, const Double MSEyuvframe[MAX_NUM_COMPONENT] ) {
87 #endif
88  m_dAddBits += bits;
89  for(UInt i=0; i<MAX_NUM_COMPONENT; i++)
90  {
91  m_dPSNRSum[i] += psnr[i];
92  m_MSEyuvframe[i] += MSEyuvframe[i];
93 #if JVET_F0064_MSSSIM
94  m_MSSSIM[i] += MSSSIM[i];
95 #endif
96  }
97 
98  m_uiNumPic++;
99  }
100 
101  Double getPsnr(ComponentID compID) const { return m_dPSNRSum[compID]; }
102 #if JVET_F0064_MSSSIM
103  Double getMsssim(ComponentID compID) const { return m_MSSSIM[compID]; }
104 #endif
105  Double getBits() const { return m_dAddBits; }
106  Void setBits(Double numBits) { m_dAddBits=numBits; }
107  UInt getNumPic() const { return m_uiNumPic; }
108 #if EXTENSION_360_VIDEO
109  TExt360EncAnalyze& getExt360Info() { return m_ext360; }
110 #endif
111 
112  Void setFrmRate (Double dFrameRate) { m_dFrmRate = dFrameRate; } //--CFG_KDY
114  {
115  m_dAddBits = 0;
116  for(UInt i=0; i<MAX_NUM_COMPONENT; i++)
117  {
118  m_dPSNRSum[i] = 0;
119  m_MSEyuvframe[i] = 0;
120 #if JVET_F0064_MSSSIM
121  m_MSSSIM[i] = 0;
122 #endif
123  }
124  m_uiNumPic = 0;
125 #if EXTENSION_360_VIDEO
126  m_ext360.clear();
127 #endif
128  }
129 
130 
131  Void calculateCombinedValues(const ChromaFormat chFmt, Double &PSNRyuv, Double &MSEyuv, const BitDepths &bitDepths)
132  {
133  MSEyuv = 0;
134  Int scale = 0;
135 
136  Int maximumBitDepth = bitDepths.recon[CHANNEL_TYPE_LUMA];
137  for (UInt channelTypeIndex = 1; channelTypeIndex < MAX_NUM_CHANNEL_TYPE; channelTypeIndex++)
138  {
139  if (bitDepths.recon[channelTypeIndex] > maximumBitDepth)
140  {
141  maximumBitDepth = bitDepths.recon[channelTypeIndex];
142  }
143  }
144 
145  const UInt maxval = 255 << (maximumBitDepth - 8);
146  const UInt numberValidComponents = getNumberValidComponents(chFmt);
147 
148  for (UInt comp=0; comp<numberValidComponents; comp++)
149  {
150  const ComponentID compID = ComponentID(comp);
151  const UInt csx = getComponentScaleX(compID, chFmt);
152  const UInt csy = getComponentScaleY(compID, chFmt);
153  const Int scaleChan = (4>>(csx+csy));
154  const UInt bitDepthShift = 2 * (maximumBitDepth - bitDepths.recon[toChannelType(compID)]); //*2 because this is a squared number
155 
156  const Double channelMSE = (m_MSEyuvframe[compID] * Double(1 << bitDepthShift)) / Double(getNumPic());
157 
158  scale += scaleChan;
159  MSEyuv += scaleChan * channelMSE;
160  }
161 
162  MSEyuv /= Double(scale); // i.e. divide by 6 for 4:2:0, 8 for 4:2:2 etc.
163  PSNRyuv = (MSEyuv==0 ? 999.99 : 10*log10((maxval*maxval)/MSEyuv));
164  }
165 
166 
167 #if JVET_F0064_MSSSIM
168  Void printOut ( TChar cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const Bool printMSSSIM, const BitDepths &bitDepths )
169 #else
170  Void printOut ( TChar cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths )
171 #endif
172  {
173  Double dFps = m_dFrmRate; //--CFG_KDY
174  Double dScale = dFps / 1000 / (Double)m_uiNumPic;
175 
176  Double MSEBasedSNR[MAX_NUM_COMPONENT];
177  if (printMSEBasedSNR)
178  {
179  for (UInt componentIndex = 0; componentIndex < MAX_NUM_COMPONENT; componentIndex++)
180  {
181  const ComponentID compID = ComponentID(componentIndex);
182 
183  if (getNumPic() == 0)
184  {
185  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.
186  }
187  else
188  {
189  //NOTE: this is not the true maximum value for any bitDepth other than 8. It comes from the original HM PSNR calculation
190  const UInt maxval = 255 << (bitDepths.recon[toChannelType(compID)] - 8);
191  const Double MSE = m_MSEyuvframe[compID];
192 
193  MSEBasedSNR[compID] = (MSE == 0) ? 999.99 : (10 * log10((maxval * maxval) / (MSE / (Double)getNumPic())));
194  }
195  }
196  }
197 
198  switch (chFmt)
199  {
200  case CHROMA_400:
201  if (printMSEBasedSNR)
202  {
203  printf( " \tTotal Frames | " "Bitrate " "Y-PSNR" );
204 
205 #if JVET_F0064_MSSSIM
206  if (printMSSSIM)
207  {
208  printf( " Y-MS-SSIM");
209  }
210 #endif
211  if (printSequenceMSE)
212  {
213  printf( " Y-MSE\n" );
214  }
215  else
216  {
217  printf("\n");
218  }
219 
220  //printf( "\t------------ " " ----------" " -------- " " -------- " " --------\n" );
221  printf( "Average: \t %8d %c " "%12.4lf " "%8.4lf",
222  getNumPic(), cDelim,
223  getBits() * dScale,
225 
226 #if JVET_F0064_MSSSIM
227  if (printMSSSIM)
228  {
229  printf(" %8.6lf", getMsssim(COMPONENT_Y) / (Double)getNumPic());
230  }
231 #endif
232 
233  if (printSequenceMSE)
234  {
235  printf( " %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
236  }
237  else
238  {
239  printf("\n");
240  }
241 
242  printf( "From MSE:\t %8d %c " "%12.4lf " "%8.4lf\n",
243  getNumPic(), cDelim,
244  getBits() * dScale,
245  MSEBasedSNR[COMPONENT_Y] );
246  }
247  else
248  {
249  printf( "\tTotal Frames | " "Bitrate " "Y-PSNR" );
250 
251 #if JVET_F0064_MSSSIM
252  if (printMSSSIM)
253  {
254  printf( "Y-MS-SSIM");
255  }
256 #endif
257 
258  if (printSequenceMSE)
259  {
260  printf( " Y-MSE\n" );
261  }
262  else
263  {
264  printf("\n");
265  }
266 
267  //printf( "\t------------ " " ----------" " -------- " " -------- " " --------\n" );
268  printf( "\t %8d %c " "%12.4lf " "%8.4lf",
269  getNumPic(), cDelim,
270  getBits() * dScale,
272 
273 #if JVET_F0064_MSSSIM
274  if (printMSSSIM)
275  {
276  printf("%8.6lf", getMsssim(COMPONENT_Y) / (Double)getNumPic());
277  }
278 #endif
279  if (printSequenceMSE)
280  {
281  printf( " %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
282  }
283  else
284  {
285  printf("\n");
286  }
287  }
288  break;
289  case CHROMA_420:
290  case CHROMA_422:
291  case CHROMA_444:
292  {
293  Double PSNRyuv = MAX_DOUBLE;
294  Double MSEyuv = MAX_DOUBLE;
295 
296  calculateCombinedValues(chFmt, PSNRyuv, MSEyuv, bitDepths);
297 
298  if (printMSEBasedSNR)
299  {
300  printf( " \tTotal Frames | " "Bitrate " "Y-PSNR " "U-PSNR " "V-PSNR " "YUV-PSNR " );
301 
302 #if JVET_F0064_MSSSIM
303  if (printMSSSIM)
304  {
305  printf(" Y-MS-SSIM " "U-MS-SSIM " "V-MS-SSIM ");
306  }
307 #endif
308  if (printSequenceMSE)
309  {
310  printf( " Y-MSE " "U-MSE " "V-MSE " "YUV-MSE \n" );
311  }
312  else
313  {
314  printf("\n");
315  }
316 
317  //printf( "\t------------ " " ----------" " -------- " " -------- " " --------\n" );
318  printf( "Average: \t %8d %c " "%12.4lf " "%8.4lf " "%8.4lf " "%8.4lf " "%8.4lf",
319  getNumPic(), cDelim,
320  getBits() * dScale,
324  PSNRyuv );
325 
326 #if JVET_F0064_MSSSIM
327  if (printMSSSIM)
328  {
329  printf(" %8.6lf " "%8.6lf " "%8.6lf ",
333  }
334 #endif
335  if (printSequenceMSE)
336  {
337  printf( " %8.4lf " "%8.4lf " "%8.4lf " "%8.4lf\n",
341  MSEyuv );
342  }
343  else
344  {
345  printf("\n");
346  }
347 
348  printf( "From MSE:\t %8d %c " "%12.4lf " "%8.4lf " "%8.4lf " "%8.4lf " "%8.4lf\n",
349  getNumPic(), cDelim,
350  getBits() * dScale,
351  MSEBasedSNR[COMPONENT_Y],
352  MSEBasedSNR[COMPONENT_Cb],
353  MSEBasedSNR[COMPONENT_Cr],
354  PSNRyuv );
355  }
356  else
357  {
358  printf( "\tTotal Frames | " "Bitrate " "Y-PSNR " "U-PSNR " "V-PSNR " "YUV-PSNR " );
359 
360 #if JVET_F0064_MSSSIM
361  if (printMSSSIM)
362  {
363  printf(" Y-MS-SSIM " "U-MS-SSIM " "V-MS-SSIM ");
364  }
365 #endif
366 
367 #if EXTENSION_360_VIDEO
368  m_ext360.printHeader();
369 #endif
370 
371  if (printSequenceMSE)
372  {
373  printf( " Y-MSE " "U-MSE " "V-MSE " "YUV-MSE \n" );
374  }
375  else
376  {
377  printf("\n");
378  }
379 
380  //printf( "\t------------ " " ----------" " -------- " " -------- " " --------\n" );
381  printf( "\t %8d %c " "%12.4lf " "%8.4lf " "%8.4lf " "%8.4lf " "%8.4lf",
382  getNumPic(), cDelim,
383  getBits() * dScale,
387  PSNRyuv );
388 
389 #if JVET_F0064_MSSSIM
390  if (printMSSSIM)
391  {
392  printf(" %8.6lf " "%8.6lf " "%8.6lf ",
396  }
397 #endif
398 
399 #if EXTENSION_360_VIDEO
400  m_ext360.printPSNRs(getNumPic());
401 #endif
402 
403  if (printSequenceMSE)
404  {
405  printf( " %8.4lf " "%8.4lf " "%8.4lf " "%8.4lf\n",
409  MSEyuv );
410  }
411  else
412  {
413  printf("\n");
414  }
415  }
416  }
417  break;
418  default:
419  fprintf(stderr, "Unknown format during print out\n");
420  exit(1);
421  break;
422  }
423  }
424 
425 
426  Void printSummary(const ChromaFormat chFmt, const Bool printSequenceMSE, const BitDepths &bitDepths, const std::string &sFilename)
427  {
428  FILE* pFile = fopen (sFilename.c_str(), "at");
429 
430  Double dFps = m_dFrmRate; //--CFG_KDY
431  Double dScale = dFps / 1000 / (Double)m_uiNumPic;
432  switch (chFmt)
433  {
434  case CHROMA_400:
435  fprintf(pFile, "%f\t %f\n",
436  getBits() * dScale,
438  break;
439  case CHROMA_420:
440  case CHROMA_422:
441  case CHROMA_444:
442  {
443  Double PSNRyuv = MAX_DOUBLE;
444  Double MSEyuv = MAX_DOUBLE;
445 
446  calculateCombinedValues(chFmt, PSNRyuv, MSEyuv, bitDepths);
447 
448  fprintf(pFile, "%f\t %f\t %f\t %f\t %f",
449  getBits() * dScale,
453  PSNRyuv );
454 
455  if (printSequenceMSE)
456  {
457  fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
461  MSEyuv );
462  }
463  else
464  {
465  fprintf(pFile, "\n");
466  }
467 
468  break;
469  }
470 
471  default:
472  fprintf(stderr, "Unknown format during print out\n");
473  exit(1);
474  break;
475  }
476 
477  fclose(pFile);
478  }
479 };
480 
485 
487 
489 
490 #endif // !defined(AFX_TENCANALYZE_H__C79BCAA2_6AC8_4175_A0FE_CF02F5829233__INCLUDED_)
Double getPsnr(ComponentID compID) const
Definition: TEncAnalyze.h:101
Void setFrmRate(Double dFrameRate)
Definition: TEncAnalyze.h:112
Defines version information, constants and small in-line functions.
TEncAnalyze m_gcAnalyzeB
void Void
Definition: TypeDef.h:203
UInt m_uiNumPic
Definition: TEncAnalyze.h:68
static UInt getComponentScaleY(const ComponentID id, const ChromaFormat fmt)
Double m_dFrmRate
Definition: TEncAnalyze.h:69
unsigned int UInt
Definition: TypeDef.h:212
static UInt getComponentScaleX(const ComponentID id, const ChromaFormat fmt)
TEncAnalyze m_gcAnalyzeI
Double m_dPSNRSum[MAX_NUM_COMPONENT]
Definition: TEncAnalyze.h:66
UInt getNumPic() const
Definition: TEncAnalyze.h:107
Void printOut(TChar cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const Bool printMSSSIM, const BitDepths &bitDepths)
Definition: TEncAnalyze.h:168
virtual ~TEncAnalyze()
Definition: TEncAnalyze.h:80
Void addResult(Double psnr[MAX_NUM_COMPONENT], Double bits, const Double MSEyuvframe[MAX_NUM_COMPONENT], const Double MSSSIM[MAX_NUM_COMPONENT])
Definition: TEncAnalyze.h:84
Int recon[MAX_NUM_CHANNEL_TYPE]
the bit depth as indicated in the SPS
Definition: TypeDef.h:793
Double m_MSSSIM[MAX_NUM_COMPONENT]
Definition: TEncAnalyze.h:72
char TChar
Definition: TypeDef.h:206
TEncAnalyze m_gcAnalyzeAll_in
encoder analyzer class
Definition: TEncAnalyze.h:63
bool Bool
Definition: TypeDef.h:204
Double m_dAddBits
Definition: TEncAnalyze.h:67
static ChannelType toChannelType(const ComponentID id)
TEncAnalyze m_gcAnalyzeAll
ChromaFormat
chroma formats (according to semantics of chroma_format_idc)
Definition: TypeDef.h:292
Double getBits() const
Definition: TEncAnalyze.h:105
Void printSummary(const ChromaFormat chFmt, const Bool printSequenceMSE, const BitDepths &bitDepths, const std::string &sFilename)
Definition: TEncAnalyze.h:426
Void calculateCombinedValues(const ChromaFormat chFmt, Double &PSNRyuv, Double &MSEyuv, const BitDepths &bitDepths)
Definition: TEncAnalyze.h:131
static const Double MAX_DOUBLE
max. value of Double-type value
Definition: CommonDef.h:116
int Int
Definition: TypeDef.h:211
Double getMsssim(ComponentID compID) const
Definition: TEncAnalyze.h:103
ComponentID
Definition: TypeDef.h:308
TEncAnalyze m_gcAnalyzeP
double Double
Definition: TypeDef.h:213
static UInt getNumberValidComponents(const ChromaFormat fmt)
Void clear()
Definition: TEncAnalyze.h:113
Void setBits(Double numBits)
Definition: TEncAnalyze.h:106
Double m_MSEyuvframe[MAX_NUM_COMPONENT]
Definition: TEncAnalyze.h:70