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

Last change on this file since 1529 was 1511, checked in by seregin, 9 years ago

add chroma format IDC output

  • Property svn:eol-style set to native
File size: 14.8 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#if SVC_EXTENSION
230          if( layerId == 0 )
231          {
232#endif
233          printf( "\tTotal Frames |   "   "Bitrate     "  "Y-PSNR" );
234
235          if (printSequenceMSE)
236          {
237            printf( "    Y-MSE\n" );
238          }
239          else
240          {
241            printf("\n");
242          }
243
244          //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
245#if SVC_EXTENSION
246          }
247
248          printf( "  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf",
249                 layerId,
250#else
251          printf( "\t %8d    %c "          "%12.4lf  "    "%8.4lf",
252#endif
253                 getNumPic(), cDelim,
254                 getBits() * dScale,
255                 getPsnr(COMPONENT_Y) / (Double)getNumPic() );
256
257          if (printSequenceMSE)
258          {
259            printf( "  %8.4lf\n", m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic() );
260          }
261          else
262          {
263            printf("\n");
264          }
265        }
266        break;
267      case CHROMA_420:
268      case CHROMA_422:
269      case CHROMA_444:
270        {
271          Double PSNRyuv = MAX_DOUBLE;
272          Double MSEyuv  = MAX_DOUBLE;
273         
274          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv, bitDepths);
275
276          if (printMSEBasedSNR)
277          {
278#if SVC_EXTENSION
279            if( layerId == 0 )
280            {
281#endif
282            printf( "         \tTotal Frames |   "   "Bitrate     "  "Y-PSNR    "  "U-PSNR    "  "V-PSNR    "  "YUV-PSNR " );
283
284            if (printSequenceMSE)
285            {
286              printf( " Y-MSE     "  "U-MSE     "  "V-MSE    "  "YUV-MSE \n" );
287            }
288            else
289            {
290              printf("\n");
291            }
292
293            //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
294#if SVC_EXTENSION
295            }
296            printf( "Average:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
297                   layerId,
298#else
299            printf( "Average: \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
300#endif
301                   getNumPic(), cDelim,
302                   getBits() * dScale,
303                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
304                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
305                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
306                   PSNRyuv );
307
308            if (printSequenceMSE)
309            {
310              printf( "  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
311                     m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
312                     m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
313                     m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
314                     MSEyuv );
315            }
316            else
317            {
318              printf("\n");
319            }
320
321#if SVC_EXTENSION
322            printf( "From MSE:  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
323                   layerId,
324#else
325            printf( "From MSE:\t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
326#endif
327                   getNumPic(), cDelim,
328                   getBits() * dScale,
329                   MSEBasedSNR[COMPONENT_Y],
330                   MSEBasedSNR[COMPONENT_Cb],
331                   MSEBasedSNR[COMPONENT_Cr],
332                   PSNRyuv );
333          }
334          else
335          {
336#if SVC_EXTENSION
337            if( layerId == 0 )
338            {
339#endif
340            printf( "\tTotal Frames |   "   "Bitrate     "  "Y-PSNR    "  "U-PSNR    "  "V-PSNR    "  "YUV-PSNR " );
341           
342            if (printSequenceMSE)
343            {
344              printf( " Y-MSE     "  "U-MSE     "  "V-MSE    "  "YUV-MSE \n" );
345            }
346            else
347            {
348              printf("\n");
349            }
350
351            //printf( "\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" );
352#if SVC_EXTENSION
353            }
354            printf( "  L%d \t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
355                   layerId,
356#else
357            printf( "\t %8d    %c "          "%12.4lf  "    "%8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
358#endif
359                   getNumPic(), cDelim,
360                   getBits() * dScale,
361                   getPsnr(COMPONENT_Y) / (Double)getNumPic(),
362                   getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
363                   getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
364                   PSNRyuv );
365
366            if (printSequenceMSE)
367            {
368              printf( "  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf\n",
369                     m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
370                     m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
371                     m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
372                     MSEyuv );
373            }
374            else
375            {
376              printf("\n");
377            }
378          }
379        }
380        break;
381      default:
382        fprintf(stderr, "Unknown format during print out\n");
383        exit(1);
384        break;
385    }
386  }
387
388
389  Void    printSummary(const ChromaFormat chFmt, const Bool printSequenceMSE, const BitDepths &bitDepths, const std::string &sFilename)
390  {
391    FILE* pFile = fopen (sFilename.c_str(), "at");
392
393    Double dFps     =   m_dFrmRate; //--CFG_KDY
394    Double dScale   = dFps / 1000 / (Double)m_uiNumPic;
395    switch (chFmt)
396    {
397      case CHROMA_400:
398        fprintf(pFile, "%f\t %f\n",
399            getBits() * dScale,
400            getPsnr(COMPONENT_Y) / (Double)getNumPic() );
401        break;
402      case CHROMA_420:
403      case CHROMA_422:
404      case CHROMA_444:
405        {
406          Double PSNRyuv = MAX_DOUBLE;
407          Double MSEyuv  = MAX_DOUBLE;
408         
409          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv, bitDepths);
410
411          fprintf(pFile, "%f\t %f\t %f\t %f\t %f",
412              getBits() * dScale,
413              getPsnr(COMPONENT_Y) / (Double)getNumPic(),
414              getPsnr(COMPONENT_Cb) / (Double)getNumPic(),
415              getPsnr(COMPONENT_Cr) / (Double)getNumPic(),
416              PSNRyuv );
417
418          if (printSequenceMSE)
419          {
420            fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
421                m_MSEyuvframe[COMPONENT_Y ] / (Double)getNumPic(),
422                m_MSEyuvframe[COMPONENT_Cb] / (Double)getNumPic(),
423                m_MSEyuvframe[COMPONENT_Cr] / (Double)getNumPic(),
424                MSEyuv );
425          }
426          else
427          {
428            fprintf(pFile, "\n");
429          }
430
431          break;
432        }
433
434      default:
435          fprintf(stderr, "Unknown format during print out\n");
436          exit(1);
437          break;
438    }
439
440    fclose(pFile);
441  }
442};
443
444extern TEncAnalyze             m_gcAnalyzeAll;
445extern TEncAnalyze             m_gcAnalyzeI;
446extern TEncAnalyze             m_gcAnalyzeP;
447extern TEncAnalyze             m_gcAnalyzeB;
448
449extern TEncAnalyze             m_gcAnalyzeAll_in;
450
451//! \}
452
453#endif // !defined(AFX_TENCANALYZE_H__C79BCAA2_6AC8_4175_A0FE_CF02F5829233__INCLUDED_)
Note: See TracBrowser for help on using the repository browser.