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

Last change on this file since 1510 was 1489, checked in by seregin, 9 years ago

store VPS with a picture, VPS is a static pointer for now

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