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

Last change on this file since 1263 was 1259, checked in by seregin, 9 years ago

port rev 4256

  • Property svn:eol-style set to native
File size: 15.0 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)
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#if SVC_EXTENSION
139  Void    printOut ( Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, UInt layer )
140#else
141  Void    printOut ( Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE )
142#endif
143  {
144    Double dFps     =   m_dFrmRate; //--CFG_KDY
145    Double dScale   = dFps / 1000 / (Double)m_uiNumPic;
146
147    Double MSEBasedSNR[MAX_NUM_COMPONENT];
148    if (printMSEBasedSNR)
149    {
150      for (UInt componentIndex = 0; componentIndex < MAX_NUM_COMPONENT; componentIndex++)
151      {
152        const ComponentID compID = ComponentID(componentIndex);
153
154        if (getNumPic() == 0)
155        {
156          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.
157        }
158        else
159        {
160          //NOTE: this is not the true maximum value for any bitDepth other than 8. It comes from the original HM PSNR calculation
161          const UInt maxval = 255 << (g_bitDepth[toChannelType(compID)] - 8);
162          const Double MSE = m_MSEyuvframe[compID];
163
164          MSEBasedSNR[compID] = (MSE == 0) ? 999.99 : (10 * log10((maxval * maxval) / (MSE / (Double)getNumPic())));
165        }
166      }
167    }
168
169    switch (chFmt)
170    {
171      case CHROMA_400:
172        if (printMSEBasedSNR)
173        {
174#if SVC_EXTENSION
175          if( layer == 0 )
176          {
177#endif
178          printf( "         \tTotal Frames |   "   "Bitrate     "  "Y-PSNR" );
179
180          if (printSequenceMSE)
181          {
182            printf( "    Y-MSE\n" );
183          }
184          else
185          {
186            printf("\n");
187          }
188
189          //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
190#if SVC_EXTENSION
191          }
192
193          printf( "Average:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf",
194                 layer,
195
196#else
197          printf( "Average: \t %8d    %c "          "%12.4lf  "    "%8.4lf",
198#endif
199                 getNumPic(), cDelim,
200                 getBits() * dScale,
201                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
202
203          if (printSequenceMSE)
204          {
205            printf( "  %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
206          }
207          else
208          {
209            printf("\n");
210          }
211
212#if SVC_EXTENSION
213          printf( "From MSE:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf\n",
214                 layer,
215#else
216          printf( "From MSE:\t %8d    %c "          "%12.4lf  "    "%8.4lf\n",
217#endif
218                 getNumPic(), cDelim,
219                 getBits() * dScale,
220                 MSEBasedSNR[COMPONENT_Y] );
221        }
222        else
223        {
224          printf( "\tTotal Frames |   "   "Bitrate     "  "Y-PSNR" );
225
226          if (printSequenceMSE)
227          {
228            printf( "    Y-MSE\n" );
229          }
230          else
231          {
232            printf("\n");
233          }
234
235          //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
236#if SVC_EXTENSION
237          printf( "  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf",
238                 layer,
239#else
240          printf( "\t %8d    %c "          "%12.4lf  "    "%8.4lf",
241#endif
242                 getNumPic(), cDelim,
243                 getBits() * dScale,
244                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
245
246          if (printSequenceMSE)
247          {
248            printf( "  %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
249          }
250          else
251          {
252            printf("\n");
253          }
254        }
255        break;
256      case CHROMA_420:
257      case CHROMA_422:
258      case CHROMA_444:
259        {
260          Double PSNRyuv = MAX_DOUBLE;
261          Double MSEyuv  = MAX_DOUBLE;
262         
263          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv);
264
265          if (printMSEBasedSNR)
266          {
267#if SVC_EXTENSION
268            if( layer == 0 )
269            {
270#endif
271            printf( "         \tTotal Frames |   "   "Bitrate     "  "Y-PSNR    "  "U-PSNR    "  "V-PSNR    "  "YUV-PSNR " );
272
273            if (printSequenceMSE)
274            {
275              printf( " Y-MSE     "  "U-MSE     "  "V-MSE    "  "YUV-MSE \n" );
276            }
277            else
278            {
279              printf("\n");
280            }
281
282            //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
283#if SVC_EXTENSION
284            }
285            printf( "Average:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
286                   layer,
287#else
288            printf( "Average: \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
289#endif
290                   getNumPic(), cDelim,
291                   getBits() * dScale,
292                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
293                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
294                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
295                   PSNRyuv );
296
297            if (printSequenceMSE)
298            {
299              printf( "  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
300                     m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
301                     m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
302                     m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
303                     MSEyuv );
304            }
305            else
306            {
307              printf("\n");
308            }
309
310#if SVC_EXTENSION
311            printf( "From MSE:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
312                   layer,
313#else
314            printf( "From MSE:\t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
315#endif
316                   getNumPic(), cDelim,
317                   getBits() * dScale,
318                   MSEBasedSNR[COMPONENT_Y],
319                   MSEBasedSNR[COMPONENT_Cb],
320                   MSEBasedSNR[COMPONENT_Cr],
321                   PSNRyuv );
322          }
323          else
324          {
325#if SVC_EXTENSION
326            if( layer == 0 )
327            {
328#endif
329            printf( "\tTotal Frames |   "   "Bitrate     "  "Y-PSNR    "  "U-PSNR    "  "V-PSNR    "  "YUV-PSNR " );
330           
331            if (printSequenceMSE)
332            {
333              printf( " Y-MSE     "  "U-MSE     "  "V-MSE    "  "YUV-MSE \n" );
334            }
335            else
336            {
337              printf("\n");
338            }
339
340            //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
341#if SVC_EXTENSION
342            }
343            printf( "  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
344                   layer,
345#else
346            printf( "\t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
347#endif
348                   getNumPic(), cDelim,
349                   getBits() * dScale,
350                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
351                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
352                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
353                   PSNRyuv );
354
355            if (printSequenceMSE)
356            {
357              printf( "  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
358                     m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
359                     m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
360                     m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
361                     MSEyuv );
362            }
363            else
364            {
365              printf("\n");
366            }
367          }
368        }
369        break;
370      default:
371        fprintf(stderr, "Unknown format during print out\n");
372        exit(1);
373        break;
374    }
375  }
376
377
378  Void    printSummary(const ChromaFormat chFmt, const Bool printSequenceMSE, Char ch='T')
379  {
380    FILE* pFile = NULL;
381
382    switch( ch )
383    {
384      case 'T':
385        pFile = fopen ("summaryTotal.txt", "at");
386        break;
387      case 'I':
388        pFile = fopen ("summary_I.txt", "at");
389        break;
390      case 'P':
391        pFile = fopen ("summary_P.txt", "at");
392        break;
393      case 'B':
394        pFile = fopen ("summary_B.txt", "at");
395        break;
396      default:
397        assert(0);
398        return;
399        break;
400    }
401
402    Double dFps     =   m_dFrmRate; //--CFG_KDY
403    Double dScale   = dFps / 1000 / (Double)m_uiNumPic;
404    switch (chFmt)
405    {
406      case CHROMA_400:
407        fprintf(pFile, "%f\t %f\n",
408            getBits() * dScale,
409            getPsnr(COMPONENT_Y) / (Double)getNumPic() );
410        break;
411      case CHROMA_420:
412      case CHROMA_422:
413      case CHROMA_444:
414        {
415          Double PSNRyuv = MAX_DOUBLE;
416          Double MSEyuv  = MAX_DOUBLE;
417         
418          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv);
419
420          fprintf(pFile, "%f\t %f\t %f\t %f\t %f",
421              getBits() * dScale,
422              getPsnr(COMPONENT_Y) / (Double)getNumPic(),
423              getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
424              getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
425              PSNRyuv );
426
427          if (printSequenceMSE)
428          {
429            fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
430                m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
431                m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
432                m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
433                MSEyuv );
434          }
435          else
436          {
437            fprintf(pFile, "\n");
438          }
439
440          break;
441        }
442
443      default:
444          fprintf(stderr, "Unknown format during print out\n");
445          exit(1);
446          break;
447    }
448
449    fclose(pFile);
450  }
451};
452
453#if SVC_EXTENSION
454extern TEncAnalyze             m_gcAnalyzeAll [MAX_LAYERS];
455extern TEncAnalyze             m_gcAnalyzeI [MAX_LAYERS];
456extern TEncAnalyze             m_gcAnalyzeP [MAX_LAYERS];
457extern TEncAnalyze             m_gcAnalyzeB [MAX_LAYERS];
458#else
459extern TEncAnalyze             m_gcAnalyzeAll;
460extern TEncAnalyze             m_gcAnalyzeI;
461extern TEncAnalyze             m_gcAnalyzeP;
462extern TEncAnalyze             m_gcAnalyzeB;
463#endif
464
465extern TEncAnalyze             m_gcAnalyzeAll_in;
466
467//! \}
468
469#endif // !defined(AFX_TENCANALYZE_H__C79BCAA2_6AC8_4175_A0FE_CF02F5829233__INCLUDED_)
Note: See TracBrowser for help on using the repository browser.