source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibEncoder/TEncAnalyze.h @ 1154

Last change on this file since 1154 was 1029, checked in by seregin, 10 years ago

merge with SHM-upgrade branch

  • Property svn:eol-style set to native
File size: 14.4 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-2014, 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)
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      if (g_bitDepth[channelTypeIndex] > maximumBitDepth)
111        maximumBitDepth = g_bitDepth[channelTypeIndex];
112
113    const UInt maxval                = 255 << (maximumBitDepth - 8);
114    const UInt numberValidComponents = getNumberValidComponents(chFmt);
115
116    for (UInt comp=0; comp<numberValidComponents; comp++)
117    {
118      const ComponentID compID        = ComponentID(comp);
119      const UInt        csx           = getComponentScaleX(compID, chFmt);
120      const UInt        csy           = getComponentScaleY(compID, chFmt);
121      const Int         scaleChan     = (4>>(csx+csy));
122      const UInt        bitDepthShift = 2 * (maximumBitDepth - g_bitDepth[toChannelType(compID)]); //*2 because this is a squared number
123
124      const Double      channelMSE    = (m_MSEyuvframe[compID] * Double(1 << bitDepthShift)) / Double(getNumPic());
125
126      scale  += scaleChan;
127      MSEyuv += scaleChan * channelMSE;
128    }
129
130    MSEyuv /= Double(scale);  // i.e. divide by 6 for 4:2:0, 8 for 4:2:2 etc.
131    PSNRyuv = (MSEyuv==0 ? 999.99 : 10*log10((maxval*maxval)/MSEyuv));
132  }
133
134#if SVC_EXTENSION
135  Void    printOut ( Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, UInt layer )
136#else
137  Void    printOut ( Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE )
138#endif
139  {
140    Double dFps     =   m_dFrmRate; //--CFG_KDY
141    Double dScale   = dFps / 1000 / (Double)m_uiNumPic;
142
143    Double MSEBasedSNR[MAX_NUM_COMPONENT];
144    if (printMSEBasedSNR)
145    {
146      for (UInt componentIndex = 0; componentIndex < MAX_NUM_COMPONENT; componentIndex++)
147      {
148        const ComponentID compID = ComponentID(componentIndex);
149
150        if (getNumPic() == 0) 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.
151        else
152        {
153          //NOTE: this is not the true maximum value for any bitDepth other than 8. It comes from the original HM PSNR calculation
154          const UInt maxval = 255 << (g_bitDepth[toChannelType(compID)] - 8);
155          const Double MSE = m_MSEyuvframe[compID];
156
157          MSEBasedSNR[compID] = (MSE == 0) ? 999.99 : (10 * log10((maxval * maxval) / (MSE / (Double)getNumPic())));
158        }
159      }
160    }
161
162    switch (chFmt)
163    {
164      case CHROMA_400:
165        if (printMSEBasedSNR)
166        {
167#if SVC_EXTENSION
168          if( layer == 0 )
169          {
170#endif
171          printf( "         \tTotal Frames |   "   "Bitrate     "  "Y-PSNR" );
172
173          if (printSequenceMSE) printf( "    Y-MSE\n" );
174          else printf("\n");
175
176          //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
177#if SVC_EXTENSION
178          }
179
180          printf( "Average:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf",
181                 layer,
182
183#else
184          printf( "Average: \t %8d    %c "          "%12.4lf  "    "%8.4lf",
185#endif
186                 getNumPic(), cDelim,
187                 getBits() * dScale,
188                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
189
190          if (printSequenceMSE)
191          {
192            printf( "  %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
193          }
194          else printf("\n");
195
196#if SVC_EXTENSION
197          printf( "From MSE:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf\n",
198                 layer,
199#else
200          printf( "From MSE:\t %8d    %c "          "%12.4lf  "    "%8.4lf\n",
201#endif
202                 getNumPic(), cDelim,
203                 getBits() * dScale,
204                 MSEBasedSNR[COMPONENT_Y] );
205        }
206        else
207        {
208          printf( "\tTotal Frames |   "   "Bitrate     "  "Y-PSNR" );
209
210          if (printSequenceMSE) printf( "    Y-MSE\n" );
211          else printf("\n");
212
213          //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
214#if SVC_EXTENSION
215          printf( "  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf",
216                 layer,
217#else
218          printf( "\t %8d    %c "          "%12.4lf  "    "%8.4lf",
219#endif
220                 getNumPic(), cDelim,
221                 getBits() * dScale,
222                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
223
224          if (printSequenceMSE)
225          {
226            printf( "  %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
227          }
228          else printf("\n");
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#if SVC_EXTENSION
243            if( layer == 0 )
244            {
245#endif
246            printf( "         \tTotal Frames |   "   "Bitrate     "  "Y-PSNR    "  "U-PSNR    "  "V-PSNR    "  "YUV-PSNR " );
247
248            if (printSequenceMSE) printf( " Y-MSE     "  "U-MSE     "  "V-MSE    "  "YUV-MSE \n" );
249            else printf("\n");
250
251            //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
252#if SVC_EXTENSION
253            }
254            printf( "Average:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
255                   layer,
256#else
257            printf( "Average: \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
258#endif
259                   getNumPic(), cDelim,
260                   getBits() * dScale,
261                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
262                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
263                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
264                   PSNRyuv );
265
266            if (printSequenceMSE)
267            {
268              printf( "  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
269                     m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
270                     m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
271                     m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
272                     MSEyuv );
273            }
274            else printf("\n");
275
276#if SVC_EXTENSION
277            printf( "From MSE:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
278                   layer,
279#else
280            printf( "From MSE:\t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
281#endif
282                   getNumPic(), cDelim,
283                   getBits() * dScale,
284                   MSEBasedSNR[COMPONENT_Y],
285                   MSEBasedSNR[COMPONENT_Cb],
286                   MSEBasedSNR[COMPONENT_Cr],
287                   PSNRyuv );
288          }
289          else
290          {
291#if SVC_EXTENSION
292            if( layer == 0 )
293            {
294#endif
295            printf( "\tTotal Frames |   "   "Bitrate     "  "Y-PSNR    "  "U-PSNR    "  "V-PSNR    "  "YUV-PSNR " );
296           
297            if (printSequenceMSE) printf( " Y-MSE     "  "U-MSE     "  "V-MSE    "  "YUV-MSE \n" );
298            else printf("\n");
299
300            //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
301#if SVC_EXTENSION
302            }
303            printf( "  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
304                   layer,
305#else
306            printf( "\t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
307#endif
308                   getNumPic(), cDelim,
309                   getBits() * dScale,
310                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
311                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
312                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
313                   PSNRyuv );
314
315            if (printSequenceMSE)
316            {
317              printf( "  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
318                     m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
319                     m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
320                     m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
321                     MSEyuv );
322            }
323            else printf("\n");
324          }
325        }
326        break;
327      default:
328        fprintf(stderr, "Unknown format during print out\n");
329        exit(1);
330        break;
331    }
332  }
333
334
335  Void    printSummary(const ChromaFormat chFmt, const Bool printSequenceMSE, Char ch='T')
336  {
337    FILE* pFile = NULL;
338
339    switch( ch )
340    {
341      case 'T':
342        pFile = fopen ("summaryTotal.txt", "at");
343        break;
344      case 'I':
345        pFile = fopen ("summary_I.txt", "at");
346        break;
347      case 'P':
348        pFile = fopen ("summary_P.txt", "at");
349        break;
350      case 'B':
351        pFile = fopen ("summary_B.txt", "at");
352        break;
353      default:
354        assert(0);
355        return;
356        break;
357    }
358
359    Double dFps     =   m_dFrmRate; //--CFG_KDY
360    Double dScale   = dFps / 1000 / (Double)m_uiNumPic;
361    switch (chFmt)
362    {
363      case CHROMA_400:
364        fprintf(pFile, "%f\t %f\n",
365            getBits() * dScale,
366            getPsnr(COMPONENT_Y) / (Double)getNumPic() );
367        break;
368      case CHROMA_420:
369      case CHROMA_422:
370      case CHROMA_444:
371        {
372          Double PSNRyuv = MAX_DOUBLE;
373          Double MSEyuv  = MAX_DOUBLE;
374         
375          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv);
376
377          fprintf(pFile, "%f\t %f\t %f\t %f\t %f",
378              getBits() * dScale,
379              getPsnr(COMPONENT_Y) / (Double)getNumPic(),
380              getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
381              getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
382              PSNRyuv );
383
384          if (printSequenceMSE)
385          {
386            fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
387                m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
388                m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
389                m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
390                MSEyuv );
391          }
392          else fprintf(pFile, "\n");
393
394          break;
395        }
396
397      default:
398          fprintf(stderr, "Unknown format during print out\n");
399          exit(1);
400          break;
401    }
402
403    fclose(pFile);
404  }
405};
406
407#if SVC_EXTENSION
408extern TEncAnalyze             m_gcAnalyzeAll [MAX_LAYERS];
409extern TEncAnalyze             m_gcAnalyzeI [MAX_LAYERS];
410extern TEncAnalyze             m_gcAnalyzeP [MAX_LAYERS];
411extern TEncAnalyze             m_gcAnalyzeB [MAX_LAYERS];
412#else
413extern TEncAnalyze             m_gcAnalyzeAll;
414extern TEncAnalyze             m_gcAnalyzeI;
415extern TEncAnalyze             m_gcAnalyzeP;
416extern TEncAnalyze             m_gcAnalyzeB;
417#endif
418
419extern TEncAnalyze             m_gcAnalyzeAll_in;
420
421//! \}
422
423#endif // !defined(AFX_TENCANALYZE_H__C79BCAA2_6AC8_4175_A0FE_CF02F5829233__INCLUDED_)
Note: See TracBrowser for help on using the repository browser.