Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvenc/source/Lib/EncoderLib/Analyze.h
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or 
4
other Intellectual Property Rights other than the copyrights concerning 
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
/** \file     Analyze.h
43
    \brief    encoder analyzer class (header)
44
*/
45
46
#pragma once
47
48
#include "CommonLib/CommonDef.h"
49
50
#include <stdio.h>
51
#include <memory.h>
52
#include <assert.h>
53
#include <cinttypes>
54
#include "math.h"
55
56
//! \ingroup EncoderLib
57
//! \{
58
59
namespace vvenc {
60
61
// ====================================================================================================================
62
// Class definition
63
// ====================================================================================================================
64
65
/// encoder analyzer class
66
class Analyze
67
{
68
private:
69
  double    m_dPSNRSum[MAX_NUM_COMP];
70
  double    m_dAddBits;
71
  uint32_t  m_uiNumPic;
72
  double    m_dFrmRate; //--CFG_KDY
73
  double    m_MSEyuvframe[MAX_NUM_COMP]; // sum of MSEs
74
  uint32_t  m_uiLosslessFrames[MAX_NUM_COMP];
75
76
public:
77
0
  virtual ~Analyze()  {}
78
0
  Analyze() { clear(); }
79
80
  void  addResult( double psnr[MAX_NUM_COMP], double bits, const double MSEyuvframe[MAX_NUM_COMP]
81
    , bool isEncodeLtRef
82
  )
83
0
  {
84
0
    m_dAddBits  += bits;
85
0
    if (isEncodeLtRef)
86
0
      return;
87
0
    for(uint32_t i=0; i<MAX_NUM_COMP; i++)
88
0
    {
89
0
      if( psnr[i] == MAX_DOUBLE )
90
0
      {
91
0
        m_uiLosslessFrames[i] += 1;
92
0
      }
93
0
      else
94
0
      {
95
0
        m_dPSNRSum[i] += psnr[i];
96
0
      }
97
0
      m_MSEyuvframe[i] += MSEyuvframe[i];
98
0
    }
99
100
0
    m_uiNumPic++;
101
0
  }
102
0
  double  getPsnr(ComponentID compID) const { return  m_dPSNRSum[compID];  }
103
0
  double  getBits()                   const { return  m_dAddBits;   }
104
0
  void    setBits(double numBits)     { m_dAddBits = numBits; }
105
0
  uint32_t    getNumPic()                 const { return  m_uiNumPic;   }
106
0
  uint32_t    getLosslessFrames(ComponentID compID) const { return m_uiLosslessFrames[compID]; }
107
0
  double      getNumPicLossy(ComponentID compID) const { return double( m_uiNumPic - m_uiLosslessFrames[compID] ); }
108
109
0
  void    setFrmRate  (double dFrameRate) { m_dFrmRate = dFrameRate; } //--CFG_KDY
110
  void    clear()
111
0
  {
112
0
    m_dAddBits = 0;
113
0
    for(uint32_t i=0; i<MAX_NUM_COMP; i++)
114
0
    {
115
0
      m_dPSNRSum[i] = 0;
116
0
      m_MSEyuvframe[i] = 0;
117
0
      m_uiLosslessFrames[i] = 0;
118
0
    }
119
0
    m_uiNumPic = 0;
120
0
  }
121
122
123
  void calculateCombinedValues(const ChromaFormat chFmt, double &PSNRyuv, double &MSEyuv, const BitDepths &bitDepths)
124
0
  {
125
0
    MSEyuv    = 0;
126
0
    int scale = 0;
127
128
0
    int maximumBitDepth = bitDepths[CH_L];
129
0
    for (uint32_t ch = 1; ch < MAX_NUM_CH; ch++)
130
0
    {
131
0
      if (bitDepths[ChannelType(ch)] > maximumBitDepth)
132
0
      {
133
0
        maximumBitDepth = bitDepths[ChannelType(ch)];
134
0
      }
135
0
    }
136
137
0
    const uint32_t maxval                = 255 << (maximumBitDepth - 8);
138
0
    const uint32_t numberValidComponents = getNumberValidComponents(chFmt);
139
140
0
    for (uint32_t comp=0; comp<numberValidComponents; comp++)
141
0
    {
142
0
      const ComponentID compID        = ComponentID(comp);
143
0
      const uint32_t        csx           = getComponentScaleX(compID, chFmt);
144
0
      const uint32_t        csy           = getComponentScaleY(compID, chFmt);
145
0
      const int         scaleChan     = (4>>(csx+csy));
146
0
      const uint32_t        bitDepthShift = 2 * (maximumBitDepth - bitDepths[toChannelType(compID)]); //*2 because this is a squared number
147
148
0
      const double      channelMSE    = (m_MSEyuvframe[compID] * double(1 << bitDepthShift)) / double(getNumPic());
149
150
0
      scale  += scaleChan;
151
0
      MSEyuv += scaleChan * channelMSE;
152
0
    }
153
154
0
    MSEyuv /= double(scale);  // i.e. divide by 6 for 4:2:0, 8 for 4:2:2 etc.
155
0
    PSNRyuv = (MSEyuv == 0) ? MAX_DOUBLE : 10.0 * log10((maxval * maxval) / MSEyuv);
156
0
  }
157
158
  std::string printOut ( char cDelim, const ChromaFormat chFmt, const bool printMSEBasedSNR, const bool printSequenceMSE, const bool printHexPsnr, const BitDepths &bitDepths )
159
0
  {
160
0
    double dFps     =   m_dFrmRate; //--CFG_KDY
161
0
    double dScale   = dFps / 1000 / (double)m_uiNumPic;
162
0
    std::string info("vvenc [info]:");
163
164
0
    double MSEBasedSNR[MAX_NUM_COMP];
165
0
    if (printMSEBasedSNR)
166
0
    {
167
0
      for (uint32_t componentIndex = 0; componentIndex < MAX_NUM_COMP; componentIndex++)
168
0
      {
169
0
        const ComponentID compID = ComponentID(componentIndex);
170
171
0
        if (getNumPic() == 0)
172
0
        {
173
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.
174
0
        }
175
0
        else
176
0
        {
177
0
          const uint32_t maxval = 255 << (bitDepths[toChannelType(compID)] - 8); // fix with WPSNR: 1023 (4095) instead of 1020 (4080) for bit depth 10 (12)
178
0
          const double MSE  = m_MSEyuvframe[compID];
179
180
0
          MSEBasedSNR[compID] = (MSE == 0) ? MAX_DOUBLE : 10.0 * log10((maxval * maxval) / (MSE / (double)getNumPic()));
181
0
        }
182
0
      }
183
0
    }
184
185
0
    bool printLosslessPlanes = getLosslessFrames(COMP_Y) != 0 || getLosslessFrames(COMP_Cb) != 0 || getLosslessFrames(COMP_Cr) != 0;
186
0
    switch (chFmt)
187
0
    {
188
0
      case CHROMA_400:
189
0
        if (printMSEBasedSNR)
190
0
        {
191
0
          info.append(prnt("         \tTotal Frames |   "   "Bitrate     "  "Y-PSNR" ) );
192
          
193
0
          if (printHexPsnr)
194
0
          {
195
0
            info.append(prnt("xY-PSNR           " ));
196
0
          }
197
198
0
          if (printSequenceMSE)
199
0
          {
200
0
            info.append(prnt("    Y-MSE\n" ));
201
0
          }
202
0
          else
203
0
          {
204
0
            info.append(prnt("\n" ));
205
0
          }
206
207
          //info.append(prnt("\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" ));
208
0
          info.append(prnt("vvenc [info]: Average: \t %8d    %c "          "%12.4lf  ", getNumPic(), cDelim, getBits() * dScale ));
209
0
          info.append( getNumPicLossy(COMP_Y) ? prnt("%8.4lf  ", getPsnr(COMP_Y )  / getNumPicLossy(COMP_Y))  :  prnt(" inf%6s", " " ) );
210
211
0
          if (printHexPsnr)
212
0
          {
213
0
            if( getNumPicLossy(COMP_Y) )
214
0
            {
215
0
              double dPsnr;
216
0
              uint64_t xPsnr;
217
0
              dPsnr = getPsnr(COMP_Y) / getNumPicLossy(COMP_Y);
218
219
0
              std::copy(reinterpret_cast<uint8_t *>(&dPsnr),
220
0
                        reinterpret_cast<uint8_t *>(&dPsnr) + sizeof(dPsnr),
221
0
                        reinterpret_cast<uint8_t *>(&xPsnr));
222
0
              info.append(prnt( "   %16" PRIx64 " ", xPsnr ));
223
0
            }
224
0
            else
225
0
            {
226
0
              info.append(prnt( " inf%14s", " " ));
227
0
            }
228
0
          }
229
230
0
          if (printSequenceMSE)
231
0
          {
232
0
            info.append(prnt("  %8.4lf\n", m_MSEyuvframe[COMP_Y] / (double)getNumPic() ));
233
0
          }
234
0
          else
235
0
          {
236
0
            info.append(prnt("\n"));
237
0
          }
238
239
0
          info.append(prnt("vvenc [info]: From MSE:\t %8d    %c "          "%12.4lf  ", getNumPic(), cDelim, getBits() * dScale));
240
0
          info.append( MSEBasedSNR[COMP_Y] != MAX_DOUBLE  ? prnt("%8.4lf\n"  , MSEBasedSNR[COMP_Y]) :  prnt(" inf%6s\n", " " ) );
241
0
        }
242
0
        else
243
0
        {
244
0
          info.append(prnt("\tTotal Frames |   "   "Bitrate     "  "Y-PSNR" ));
245
246
0
          if (printHexPsnr)
247
0
          {
248
0
            info.append(prnt("xY-PSNR           "));
249
0
          }
250
251
0
          if (printSequenceMSE)
252
0
          {
253
0
            info.append(prnt("    Y-MSE\n" ));
254
0
          }
255
0
          else
256
0
          {
257
0
            info.append(prnt("\n"));
258
0
          }
259
260
          //info.append(prnt("\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" ));
261
0
          info.append(prnt("vvenc[info]:\t %8d    %c "          "%12.4lf  ", getNumPic(), cDelim, getBits() * dScale));
262
0
          info.append( getNumPicLossy(COMP_Y) ? prnt("%8.4lf  ", getPsnr(COMP_Y )  / getNumPicLossy(COMP_Y))  :  prnt(" inf%6s", " " ) );
263
264
0
          if (printHexPsnr)
265
0
          {
266
0
            if( getNumPicLossy(COMP_Y) )
267
0
            {
268
0
              double dPsnr;
269
0
              uint64_t xPsnr;
270
0
              dPsnr = getPsnr(COMP_Y) / getNumPicLossy(COMP_Y);
271
272
0
              std::copy(reinterpret_cast<uint8_t *>(&dPsnr),
273
0
                        reinterpret_cast<uint8_t *>(&dPsnr) + sizeof(dPsnr),
274
0
                        reinterpret_cast<uint8_t *>(&xPsnr));
275
276
0
              info.append(prnt( "   %16" PRIx64 " ", xPsnr ));
277
0
            }
278
0
            else
279
0
            {
280
0
              info.append(prnt( " inf%14s", " " ));
281
0
            }
282
0
          }
283
284
0
          if (printSequenceMSE)
285
0
          {
286
0
            info.append(prnt("  %8.4lf\n", m_MSEyuvframe[COMP_Y] / (double)getNumPic() ));
287
0
          }
288
0
          else
289
0
          {
290
0
            info.append(prnt("\n"));
291
0
          }
292
0
        }
293
0
        break;
294
0
      case CHROMA_420:
295
0
      case CHROMA_422:
296
0
      case CHROMA_444:
297
0
        {
298
0
          double PSNRyuv = MAX_DOUBLE;
299
0
          double MSEyuv  = MAX_DOUBLE;
300
301
0
          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv, bitDepths);
302
303
0
          if (printMSEBasedSNR)
304
0
          {
305
0
            info.append(prnt("         \tTotal Frames |   "   "Bitrate     "  "Y-PSNR    "  "U-PSNR    "  "V-PSNR    "  "YUV-PSNR   " ));
306
307
0
            if (printHexPsnr)
308
0
            {
309
0
              info.append(prnt("xY-PSNR           "  "xU-PSNR           "  "xV-PSNR           "));
310
0
            }
311
312
0
            if (printSequenceMSE)
313
0
            {
314
0
              info.append(prnt(" Y-MSE     "  "U-MSE     "  "V-MSE    "  "YUV-MSE   " ));
315
0
            }
316
            
317
0
            if (printLosslessPlanes)
318
0
            {
319
0
              info.append(prnt("Y-Lossless  U-Lossless  V-Lossless\n"));
320
0
            }
321
0
            else
322
0
            {
323
0
              info.append(prnt("\n"));
324
0
            }
325
326
            //info.append(prnt("\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" ));
327
0
            info.append(prnt("vvenc [info]: Average: \t %8d    %c "          "%12.4lf  ",getNumPic(), cDelim, getBits() * dScale ));
328
0
            info.append( getNumPicLossy(COMP_Y) ? prnt("%8.4lf  ", getPsnr(COMP_Y )  / getNumPicLossy(COMP_Y))  :  prnt(" inf%6s", " " ) );
329
0
            info.append( getNumPicLossy(COMP_Cb)? prnt("%8.4lf  ", getPsnr(COMP_Cb ) / getNumPicLossy(COMP_Cb)) :  prnt(" inf%6s", " " ) );
330
0
            info.append( getNumPicLossy(COMP_Cr)? prnt("%8.4lf  ", getPsnr(COMP_Cr ) / getNumPicLossy(COMP_Cr)) :  prnt(" inf%6s", " " ) );
331
0
            info.append( PSNRyuv != MAX_DOUBLE  ? prnt("%8.4lf"  , PSNRyuv)                                     :  prnt(" inf%6s", " " ) );
332
333
0
            if (printHexPsnr)
334
0
            {
335
0
              for (int i = 0; i < MAX_NUM_COMP; i++)
336
0
              {
337
0
                if( getNumPicLossy((ComponentID)i) )
338
0
                {
339
0
                  double dPsnr = getPsnr((ComponentID)i) / getNumPicLossy((ComponentID)i);
340
0
                  uint64_t xPsnr;
341
0
                  std::copy(reinterpret_cast<uint8_t *>(&dPsnr),
342
0
                            reinterpret_cast<uint8_t *>(&dPsnr) + sizeof(dPsnr),
343
0
                            reinterpret_cast<uint8_t *>(&xPsnr));
344
0
                  info.append(prnt( "   %16" PRIx64 " ", xPsnr ));
345
0
                }
346
0
                else
347
0
                {
348
0
                  info.append(prnt( " inf%14s", " " ));
349
0
                }
350
0
              }
351
0
            }
352
353
0
            if (printSequenceMSE)
354
0
            {
355
0
              info.append(prnt("  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
356
0
                     m_MSEyuvframe[COMP_Y ] / (double)getNumPic(),
357
0
                     m_MSEyuvframe[COMP_Cb] / (double)getNumPic(),
358
0
                     m_MSEyuvframe[COMP_Cr] / (double)getNumPic(),
359
0
                     MSEyuv ));
360
0
            }
361
0
            if (printLosslessPlanes)
362
0
            {
363
0
              info.append(prnt("  %10d  "  "%10d  "  "%10d\n", getLosslessFrames(COMP_Y), getLosslessFrames(COMP_Cb), getLosslessFrames(COMP_Cr) ));
364
0
            }
365
0
            else
366
0
            {
367
0
              info.append(prnt("\n"));
368
0
            }
369
370
0
            info.append(prnt("vvenc [info]: From MSE:\t %8d    %c "          "%12.4lf  ", getNumPic(), cDelim, getBits() * dScale ));
371
0
            info.append( MSEBasedSNR[COMP_Y]  != MAX_DOUBLE  ? prnt("%8.4lf" , MSEBasedSNR[COMP_Y])  :  prnt(" inf%6s", " " ) );
372
0
            info.append( MSEBasedSNR[COMP_Cb] != MAX_DOUBLE  ? prnt("%8.4lf" , MSEBasedSNR[COMP_Cb]) :  prnt(" inf%6s", " " ) );
373
0
            info.append( MSEBasedSNR[COMP_Cr] != MAX_DOUBLE  ? prnt("%8.4lf" , MSEBasedSNR[COMP_Cr]) :  prnt(" inf%6s", " " ) );
374
0
            info.append( PSNRyuv != MAX_DOUBLE  ? prnt("%8.4lf\n", PSNRyuv)                          :  prnt(" inf%6s\n", " " ) );
375
0
          }
376
0
          else
377
0
          {
378
0
            info.append(prnt("\tTotal Frames |   "   "Bitrate     "  "Y-PSNR    "  "U-PSNR    "  "V-PSNR    "  "YUV-PSNR   " ));
379
380
0
            if (printHexPsnr)
381
0
            {
382
0
              info.append(prnt("xY-PSNR           "  "xU-PSNR           "  "xV-PSNR           "));
383
0
            }
384
0
            if (printSequenceMSE)
385
0
            {
386
0
              info.append(prnt(" Y-MSE     "  "U-MSE     "  "V-MSE    "  "YUV-MSE   " ));
387
0
            }
388
0
            if (printLosslessPlanes)
389
0
            {
390
0
              info.append(prnt("Y-Lossless  U-Lossless  V-Lossless\n"));
391
0
            }
392
0
            else
393
0
            {
394
0
              info.append(prnt("\n"));
395
0
            }
396
397
            //info.append(prnt("\t------------ "  " ----------"   " -------- "  " -------- "  " --------\n" ));
398
0
            info.append(prnt("vvenc [info]:\t %8d    %c "          "%12.4lf  ", getNumPic(), cDelim, getBits() * dScale ));
399
0
            info.append( getNumPicLossy(COMP_Y) ? prnt("%8.4lf  ", getPsnr(COMP_Y )  / getNumPicLossy(COMP_Y))  :  prnt(" inf%6s", " " ) );
400
0
            info.append( getNumPicLossy(COMP_Cb)? prnt("%8.4lf  ", getPsnr(COMP_Cb ) / getNumPicLossy(COMP_Cb)) :  prnt(" inf%6s", " " ) );
401
0
            info.append( getNumPicLossy(COMP_Cr)? prnt("%8.4lf  ", getPsnr(COMP_Cr ) / getNumPicLossy(COMP_Cr)) :  prnt(" inf%6s", " " ) );
402
0
            info.append( PSNRyuv != MAX_DOUBLE  ? prnt("%8.4lf"  , PSNRyuv)                                     :  prnt(" inf%6s", " " ) );
403
404
0
            if (printHexPsnr)
405
0
            {
406
0
              for (int i = 0; i < MAX_NUM_COMP; i++)
407
0
              {
408
0
                if( getNumPicLossy((ComponentID)i) )
409
0
                {
410
0
                  double dPsnr = getPsnr((ComponentID)i) / getNumPicLossy((ComponentID)i);
411
0
                  uint64_t xPsnr;
412
0
                  std::copy(reinterpret_cast<uint8_t *>(&dPsnr),
413
0
                            reinterpret_cast<uint8_t *>(&dPsnr) + sizeof(dPsnr),
414
0
                            reinterpret_cast<uint8_t *>(&xPsnr));
415
0
                  info.append(prnt( "   %16" PRIx64 " ", xPsnr ));
416
0
                }
417
0
                else
418
0
                {
419
0
                  info.append(prnt( " inf%14s", " " ));
420
0
                }
421
0
              }
422
0
            }
423
0
            if (printSequenceMSE)
424
0
            {
425
0
              info.append(prnt("  %8.4lf  "   "%8.4lf  "    "%8.4lf  "   "%8.4lf",
426
0
                     m_MSEyuvframe[COMP_Y ] / (double)getNumPic(),
427
0
                     m_MSEyuvframe[COMP_Cb] / (double)getNumPic(),
428
0
                     m_MSEyuvframe[COMP_Cr] / (double)getNumPic(),
429
0
                     MSEyuv ));
430
0
            }
431
0
            if (printLosslessPlanes)
432
0
            {
433
0
              info.append(prnt(" %8d   "  " %8d   "  " %8d  \n", getLosslessFrames(COMP_Y), getLosslessFrames(COMP_Cb), getLosslessFrames(COMP_Cr) ));
434
0
            }
435
0
            else
436
0
            {
437
0
              info.append(prnt("\n"));
438
0
            }
439
0
          }
440
0
        }
441
0
        break;
442
0
      default:
443
0
        info.append(prnt("vvenc [info]: Unknown format during print out\n"));
444
0
        break;
445
0
    }
446
0
    return info;
447
0
  }
448
449
450
  void    printSummary(const ChromaFormat chFmt, const bool printSequenceMSE, const bool printHexPsnr, const BitDepths &bitDepths, const std::string &sFilename)
451
0
  {
452
0
    FILE* pFile = fopen (sFilename.c_str(), "at");
453
0
    if ( nullptr == pFile )
454
0
    {
455
0
      return;
456
0
    }
457
458
0
    double dFps     =   m_dFrmRate; //--CFG_KDY
459
0
    double dScale   = dFps / 1000 / (double)m_uiNumPic;
460
0
    switch (chFmt)
461
0
    {
462
0
      case CHROMA_400:
463
0
        fprintf(pFile, "%f\t %f\n",
464
0
            getBits() * dScale,
465
0
            getPsnr(COMP_Y) / (double)getNumPic() );
466
0
        break;
467
0
      case CHROMA_420:
468
0
      case CHROMA_422:
469
0
      case CHROMA_444:
470
0
        {
471
0
          double PSNRyuv = MAX_DOUBLE;
472
0
          double MSEyuv  = MAX_DOUBLE;
473
474
0
          calculateCombinedValues(chFmt, PSNRyuv, MSEyuv, bitDepths);
475
476
0
          fprintf(pFile, "%f\t %f\t %f\t %f\t %f",
477
0
              getBits() * dScale,
478
0
              getPsnr(COMP_Y ) / (double)getNumPic(),
479
0
              getPsnr(COMP_Cb) / (double)getNumPic(),
480
0
              getPsnr(COMP_Cr) / (double)getNumPic(),
481
0
              PSNRyuv );
482
483
0
          if (printSequenceMSE)
484
0
          {
485
0
            fprintf(pFile, "\t %f\t %f\t %f\t %f\n",
486
0
                m_MSEyuvframe[COMP_Y ] / (double)getNumPic(),
487
0
                m_MSEyuvframe[COMP_Cb] / (double)getNumPic(),
488
0
                m_MSEyuvframe[COMP_Cr] / (double)getNumPic(),
489
0
                MSEyuv );
490
0
          }
491
0
          else
492
0
          {
493
0
            fprintf(pFile, "\n");
494
0
          }
495
496
0
          break;
497
0
        }
498
499
0
      default:
500
0
          fprintf(pFile, "Unknown format during print out\n");
501
0
          break;
502
0
    }
503
504
0
    fclose(pFile);
505
0
  }
506
};
507
508
} // namespace vvenc
509
510
//! \}
511