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

Last change on this file since 1367 was 1333, checked in by seregin, 9 years ago

port rev 4411

  • Property svn:eol-style set to native
File size: 14.5 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#if SVC_EXTENSION
139  Void    printOut ( Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths, UInt layer = 0 )
140#else
141  Void    printOut ( Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths )
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 << (bitDepths.recon[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, bitDepths);
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, const BitDepths &bitDepths, const std::string &sFilename)
379  {
380    FILE* pFile = fopen (sFilename.c_str(), "at");
381
382    Double dFps     =   m_dFrmRate; //--CFG_KDY
383    Double dScale   = dFps / 1000 / (Double)m_uiNumPic;
384    switch (chFmt)
385    {
386      case CHROMA_400:
387        fprintf(pFile, "%f\t %f\n",
388            getBits() * dScale,
389            getPsnr(COMPONENT_Y) / (Double)getNumPic() );
390        break;
391      case CHROMA_420:
392      case CHROMA_422:
393      case CHROMA_444:
394        {
395          Double PSNRyuv = MAX_DOUBLE;
396          Double MSEyuv  = MAX_DOUBLE;
397         
398          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv, bitDepths);
399
400          fprintf(pFile, "%f\t %f\t %f\t %f\t %f",
401              getBits() * dScale,
402              getPsnr(COMPONENT_Y) / (Double)getNumPic(),
403              getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
404              getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
405              PSNRyuv );
406
407          if (printSequenceMSE)
408          {
409            fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
410                m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
411                m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
412                m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
413                MSEyuv );
414          }
415          else
416          {
417            fprintf(pFile, "\n");
418          }
419
420          break;
421        }
422
423      default:
424          fprintf(stderr, "Unknown format during print out\n");
425          exit(1);
426          break;
427    }
428
429    fclose(pFile);
430  }
431};
432
433extern TEncAnalyze             m_gcAnalyzeAll;
434extern TEncAnalyze             m_gcAnalyzeI;
435extern TEncAnalyze             m_gcAnalyzeP;
436extern TEncAnalyze             m_gcAnalyzeB;
437
438extern TEncAnalyze             m_gcAnalyzeAll_in;
439
440//! \}
441
442#endif // !defined(AFX_TENCANALYZE_H__C79BCAA2_6AC8_4175_A0FE_CF02F5829233__INCLUDED_)
Note: See TracBrowser for help on using the repository browser.