• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 
12 #include "vpx_scale/yv12config.h"
13 #include "math.h"
14 #include "systemdependent.h" /* for vp8_clear_system_state() */
15 
16 #define MAX_PSNR 60
17 
vp8_mse2psnr(double Samples,double Peak,double Mse)18 double vp8_mse2psnr(double Samples, double Peak, double Mse)
19 {
20     double psnr;
21 
22     if ((double)Mse > 0.0)
23         psnr = 10.0 * log10(Peak * Peak * Samples / Mse);
24     else
25         psnr = MAX_PSNR;      // Limit to prevent / 0
26 
27     if (psnr > MAX_PSNR)
28         psnr = MAX_PSNR;
29 
30     return psnr;
31 }
32 
vp8_calc_psnr(YV12_BUFFER_CONFIG * source,YV12_BUFFER_CONFIG * dest,double * YPsnr,double * UPsnr,double * VPsnr,double * sq_error)33 double vp8_calc_psnr(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, double *YPsnr, double *UPsnr, double *VPsnr, double *sq_error)
34 {
35     int i, j;
36     int Diff;
37     double frame_psnr;
38     double Total;
39     double grand_total;
40     unsigned char *src = source->y_buffer;
41     unsigned char *dst = dest->y_buffer;
42 
43     Total = 0.0;
44     grand_total = 0.0;
45 
46     // Loop throught the Y plane raw and reconstruction data summing (square differences)
47     for (i = 0; i < source->y_height; i++)
48     {
49 
50         for (j = 0; j < source->y_width; j++)
51         {
52             Diff        = (int)(src[j]) - (int)(dst[j]);
53             Total      += Diff * Diff;
54         }
55 
56         src += source->y_stride;
57         dst += dest->y_stride;
58     }
59 
60     // Work out Y PSNR
61     *YPsnr = vp8_mse2psnr(source->y_height * source->y_width, 255.0, Total);
62     grand_total += Total;
63     Total = 0;
64 
65 
66     // Loop through the U plane
67     src = source->u_buffer;
68     dst = dest->u_buffer;
69 
70     for (i = 0; i < source->uv_height; i++)
71     {
72 
73         for (j = 0; j < source->uv_width; j++)
74         {
75             Diff        = (int)(src[j]) - (int)(dst[j]);
76             Total      += Diff * Diff;
77         }
78 
79         src += source->uv_stride;
80         dst += dest->uv_stride;
81     }
82 
83     // Work out U PSNR
84     *UPsnr = vp8_mse2psnr(source->uv_height * source->uv_width, 255.0, Total);
85     grand_total += Total;
86     Total = 0;
87 
88 
89     // V PSNR
90     src = source->v_buffer;
91     dst = dest->v_buffer;
92 
93     for (i = 0; i < source->uv_height; i++)
94     {
95 
96         for (j = 0; j < source->uv_width; j++)
97         {
98             Diff        = (int)(src[j]) - (int)(dst[j]);
99             Total      += Diff * Diff;
100         }
101 
102         src += source->uv_stride;
103         dst += dest->uv_stride;
104     }
105 
106     // Work out UV PSNR
107     *VPsnr = vp8_mse2psnr(source->uv_height * source->uv_width, 255.0, Total);
108     grand_total += Total;
109     Total = 0;
110 
111     // Work out total PSNR
112     frame_psnr = vp8_mse2psnr(source->y_height * source->y_width * 3 / 2 , 255.0, grand_total);
113 
114     *sq_error = 1.0 * grand_total;
115 
116     return frame_psnr;
117 }
118