source: 3DVCSoftware/branches/HTM-16.2-dev/source/Lib/TLibEncoder/TEncAnalyze.h @ 1412

Last change on this file since 1412 was 1412, checked in by tech, 7 years ago
  • Update HM-16.18
  • Cleanups
  • Encoder Extension

-- Representation formats
-- Parameter set sharing
-- GOP configuration

  • Property svn:eol-style set to native
File size: 15.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-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
34/** \file     TEncAnalyze.h
35    \brief    encoder analyzer class (header)
36*/
37
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"
49#include "TLibCommon/TComChromaFormat.h"
50#include "math.h"
51#if EXTENSION_360_VIDEO
52#include "TAppEncHelper360/TExt360EncAnalyze.h"
53#endif
54
55//! \ingroup TLibEncoder
56//! \{
57
58// ====================================================================================================================
59// Class definition
60// ====================================================================================================================
61
62/// encoder analyzer class
63class TEncAnalyze
64{
65private:
66  Double    m_dPSNRSum[MAX_NUM_COMPONENT];
67  Double    m_dAddBits;
68  UInt      m_uiNumPic;
69  Double    m_dFrmRate; //--CFG_KDY
70  Double    m_MSEyuvframe[MAX_NUM_COMPONENT]; // sum of MSEs
71#if JVET_F0064_MSSSIM
72  Double    m_MSSSIM[MAX_NUM_COMPONENT];
73#endif
74
75#if EXTENSION_360_VIDEO
76  TExt360EncAnalyze m_ext360;
77#endif
78
79public:
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
113  Void    clear()
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,
224                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
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,
271                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
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,
321                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
322                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
323                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
324                   PSNRyuv );
325
326#if JVET_F0064_MSSSIM
327            if (printMSSSIM)
328            {
329              printf("    %8.6lf     " "%8.6lf     " "%8.6lf ",
330                     getMsssim(COMPONENT_Y) / (Double)getNumPic(),
331                     getMsssim(COMPONENT_Cb) / (Double)getNumPic(),
332                     getMsssim(COMPONENT_Cr) / (Double)getNumPic());
333            }
334#endif
335            if (printSequenceMSE)
336            {
337              printf( "  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
338                     m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
339                     m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
340                     m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
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,
384                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
385                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
386                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
387                   PSNRyuv );
388
389#if JVET_F0064_MSSSIM
390            if (printMSSSIM)
391            {
392              printf("    %8.6lf     " "%8.6lf     " "%8.6lf ",
393                     getMsssim(COMPONENT_Y) / (Double)getNumPic(),
394                     getMsssim(COMPONENT_Cb) / (Double)getNumPic(),
395                     getMsssim(COMPONENT_Cr) / (Double)getNumPic());
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",
406                     m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
407                     m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
408                     m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
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,
437            getPsnr(COMPONENT_Y) / (Double)getNumPic() );
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,
450              getPsnr(COMPONENT_Y) / (Double)getNumPic(),
451              getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
452              getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
453              PSNRyuv );
454
455          if (printSequenceMSE)
456          {
457            fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
458                m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
459                m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
460                m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
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
481extern TEncAnalyze             m_gcAnalyzeAll;
482extern TEncAnalyze             m_gcAnalyzeI;
483extern TEncAnalyze             m_gcAnalyzeP;
484extern TEncAnalyze             m_gcAnalyzeB;
485
486extern TEncAnalyze             m_gcAnalyzeAll_in;
487
488//! \}
489
490#endif // !defined(AFX_TENCANALYZE_H__C79BCAA2_6AC8_4175_A0FE_CF02F5829233__INCLUDED_)
Note: See TracBrowser for help on using the repository browser.