source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncAnalyze.h @ 1313

Last change on this file since 1313 was 1313, checked in by tech, 9 years ago

Merged 14.1-update-dev1@1312.

  • Property svn:eol-style set to native
File size: 13.2 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/** \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
52//! \ingroup TLibEncoder
53//! \{
54
55// ====================================================================================================================
56// Class definition
57// ====================================================================================================================
58
59/// encoder analyzer class
60class TEncAnalyze
61{
62private:
63  Double    m_dPSNRSum[MAX_NUM_COMPONENT];
64  Double    m_dAddBits;
65  UInt      m_uiNumPic;
66  Double    m_dFrmRate; //--CFG_KDY
67  Double    m_MSEyuvframe[MAX_NUM_COMPONENT]; // sum of MSEs
68
69public:
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
91  Void    clear()
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, const BitDepths &bitDepths)
104  {
105    MSEyuv    = 0;
106    Int scale = 0;
107
108    Int maximumBitDepth = bitDepths.recon[CHANNEL_TYPE_LUMA];
109    for (UInt channelTypeIndex = 1; channelTypeIndex < MAX_NUM_CHANNEL_TYPE; channelTypeIndex++)
110    {
111      if (bitDepths.recon[channelTypeIndex] > maximumBitDepth)
112      {
113        maximumBitDepth = bitDepths.recon[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 - bitDepths.recon[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, const BitDepths &bitDepths )
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 << (bitDepths.recon[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,
186                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
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,
219                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
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, bitDepths);
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,
257                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
258                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
259                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
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,
300                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
301                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
302                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
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, const BitDepths &bitDepths, const std::string &sFilename)
329  {
330    FILE* pFile = fopen (sFilename.c_str(), "at");
331
332    Double dFps     =   m_dFrmRate; //--CFG_KDY
333    Double dScale   = dFps / 1000 / (Double)m_uiNumPic;
334    switch (chFmt)
335    {
336      case CHROMA_400:
337        fprintf(pFile, "%f\t %f\n",
338            getBits() * dScale,
339            getPsnr(COMPONENT_Y) / (Double)getNumPic() );
340        break;
341      case CHROMA_420:
342      case CHROMA_422:
343      case CHROMA_444:
344        {
345          Double PSNRyuv = MAX_DOUBLE;
346          Double MSEyuv  = MAX_DOUBLE;
347         
348          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv, bitDepths);
349
350          fprintf(pFile, "%f\t %f\t %f\t %f\t %f",
351              getBits() * dScale,
352              getPsnr(COMPONENT_Y) / (Double)getNumPic(),
353              getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
354              getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
355              PSNRyuv );
356
357          if (printSequenceMSE)
358          {
359            fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
360                m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
361                m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
362                m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
363                MSEyuv );
364          }
365          else
366          {
367            fprintf(pFile, "\n");
368          }
369
370          break;
371        }
372
373      default:
374          fprintf(stderr, "Unknown format during print out\n");
375          exit(1);
376          break;
377    }
378
379    fclose(pFile);
380  }
381};
382
383extern TEncAnalyze             m_gcAnalyzeAll;
384extern TEncAnalyze             m_gcAnalyzeI;
385extern TEncAnalyze             m_gcAnalyzeP;
386extern TEncAnalyze             m_gcAnalyzeB;
387
388extern TEncAnalyze             m_gcAnalyzeAll_in;
389
390//! \}
391
392#endif // !defined(AFX_TENCANALYZE_H__C79BCAA2_6AC8_4175_A0FE_CF02F5829233__INCLUDED_)
Note: See TracBrowser for help on using the repository browser.