1 /******************************************************************************
2 *
3 * Copyright (C) 2022 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25
26 #include "ih264_typedefs.h"
27 #include "iv2.h"
28 #include "ive2.h"
29 #include "isvce.h"
30 #include "app.h"
31 #include "psnr.h"
32
33 /*****************************************************************************/
34 /* */
35 /* Function Name : init_psnr */
36 /* */
37 /* Description : Initialize PSNR for the Y, U, V component */
38 /* */
39 /* Inputs : */
40 /* */
41 /* Globals : */
42 /* */
43 /* Processing : */
44 /* */
45 /* Outputs : */
46 /* */
47 /* Returns : */
48 /* */
49 /* Issues : */
50 /* */
51 /* Revision History: */
52 /* */
53 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
54 /* 28 12 2005 Ittiam Draft */
55 /* */
56 /*****************************************************************************/
init_psnr(app_ctxt_t * ps_app_ctxt)57 void init_psnr(app_ctxt_t *ps_app_ctxt)
58 {
59 ps_app_ctxt->adbl_psnr[0] = 0;
60 ps_app_ctxt->adbl_psnr[1] = 0;
61 ps_app_ctxt->adbl_psnr[2] = 0;
62 ps_app_ctxt->u4_psnr_cnt = 0;
63 }
64
65 /*****************************************************************************/
66 /* */
67 /* Function Name : compute_psnr */
68 /* */
69 /* Description : Computes the PSNR for the Y, U, V component */
70 /* */
71 /* Inputs : */
72 /* */
73 /* Globals : */
74 /* */
75 /* Processing : */
76 /* */
77 /* Outputs : */
78 /* */
79 /* Returns : */
80 /* */
81 /* Issues : */
82 /* */
83 /* Revision History: */
84 /* */
85 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
86 /* 28 12 2005 Ittiam Draft */
87 /* */
88 /*****************************************************************************/
compute_psnr(app_ctxt_t * ps_app_ctxt,iv_raw_buf_t * ps_buf1,iv_raw_buf_t * ps_buf2)89 void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t *ps_buf2)
90 {
91 WORD32 i, j;
92 WORD32 comp;
93 DOUBLE df_psnr[3];
94 WORD32 wd, ht, strd1, strd2;
95 UWORD8 *pu1_buf1, *pu1_buf2;
96 WORD32 incr1, incr2;
97
98 printf("\nPicNum %4d\t ", ps_app_ctxt->u4_psnr_cnt);
99
100 for(comp = 0; comp < 3; comp++)
101 {
102 df_psnr[comp] = 0;
103 pu1_buf1 = (UWORD8 *) ps_buf1->apv_bufs[comp];
104 pu1_buf2 = (UWORD8 *) ps_buf2->apv_bufs[comp];
105 wd = ps_buf1->au4_wd[comp];
106 ht = ps_buf1->au4_ht[comp];
107 strd1 = ps_buf1->au4_strd[comp] - ps_buf1->au4_wd[comp];
108 strd2 = ps_buf2->au4_strd[comp] - ps_buf2->au4_wd[comp];
109 incr1 = 1;
110 incr2 = 1;
111
112 if((IV_YUV_420SP_UV == ps_buf1->e_color_fmt) || (IV_YUV_420SP_VU == ps_buf1->e_color_fmt))
113 {
114 switch(comp)
115 {
116 case 0:
117 pu1_buf1 = ps_buf1->apv_bufs[0];
118 break;
119 case 1:
120 if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
121 pu1_buf1 = (UWORD8 *) ps_buf1->apv_bufs[1];
122 else
123 pu1_buf1 = (UWORD8 *) ps_buf1->apv_bufs[1] + 1;
124 incr1 = 2;
125 wd = ps_buf1->au4_wd[0] >> 1;
126 ht = ps_buf1->au4_ht[0] >> 1;
127 break;
128 case 2:
129 if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
130 pu1_buf1 = (UWORD8 *) ps_buf1->apv_bufs[1] + 1;
131 else
132 pu1_buf1 = ps_buf1->apv_bufs[1];
133 incr1 = 2;
134 wd = ps_buf1->au4_wd[0] >> 1;
135 ht = ps_buf1->au4_ht[0] >> 1;
136 strd1 = ps_buf1->au4_strd[1] - ps_buf1->au4_wd[1];
137 break;
138 }
139 }
140 if((IV_YUV_420SP_UV == ps_buf2->e_color_fmt) || (IV_YUV_420SP_VU == ps_buf2->e_color_fmt))
141 {
142 switch(comp)
143 {
144 case 0:
145 pu1_buf2 = ps_buf2->apv_bufs[0];
146 break;
147 case 1:
148 if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt)
149 pu1_buf2 = ps_buf2->apv_bufs[1];
150 else
151 pu1_buf2 = (UWORD8 *) ps_buf2->apv_bufs[1] + 1;
152 incr2 = 2;
153 wd = ps_buf2->au4_wd[0] >> 1;
154 ht = ps_buf2->au4_ht[0] >> 1;
155
156 break;
157 case 2:
158 if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt)
159 pu1_buf2 = (UWORD8 *) ps_buf2->apv_bufs[1] + 1;
160 else
161 pu1_buf2 = ps_buf2->apv_bufs[1];
162 incr2 = 2;
163 wd = ps_buf2->au4_wd[0] >> 1;
164 ht = ps_buf2->au4_ht[0] >> 1;
165 strd2 = ps_buf2->au4_strd[1] - ps_buf2->au4_wd[1];
166
167 break;
168 }
169 }
170
171 for(i = 0; i < ht; i++)
172 {
173 for(j = 0; j < wd; j++)
174 {
175 WORD32 diff;
176 diff = (*pu1_buf1 - *pu1_buf2);
177 pu1_buf1 += incr1;
178 pu1_buf2 += incr2;
179 df_psnr[comp] += diff * diff;
180 }
181 pu1_buf1 += strd1;
182 pu1_buf2 += strd2;
183 }
184 df_psnr[comp] /= (wd * ht);
185 if(df_psnr[comp])
186 df_psnr[comp] = 20 * log10(255 / sqrt(df_psnr[comp]));
187 else
188 df_psnr[comp] = 100;
189
190 ps_app_ctxt->adbl_psnr[comp] += df_psnr[comp];
191 switch(comp)
192 {
193 case 0:
194 printf("Y :");
195 break;
196 case 1:
197 printf("U :");
198 break;
199 case 2:
200 printf("V :");
201 break;
202 default:
203 break;
204 }
205 printf("%2.2f\t", df_psnr[comp]);
206 }
207
208 ps_app_ctxt->u4_psnr_cnt++;
209 }
210
211 /*****************************************************************************/
212 /* */
213 /* Function Name : print_average_psnr */
214 /* */
215 /* Description : Computes the average PSNR for the Y, U, V component */
216 /* */
217 /* Inputs : */
218 /* */
219 /* Globals : */
220 /* */
221 /* Processing : */
222 /* */
223 /* Outputs : */
224 /* */
225 /* Returns : */
226 /* */
227 /* Issues : */
228 /* */
229 /* Revision History: */
230 /* */
231 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
232 /* 28 12 2005 Ittiam Draft */
233 /* */
234 /*****************************************************************************/
print_average_psnr(app_ctxt_t * ps_app_ctxt)235 void print_average_psnr(app_ctxt_t *ps_app_ctxt)
236 {
237 printf("\n");
238
239 printf("Avg PSNR Y : %-2.2f\n",
240 (ps_app_ctxt->adbl_psnr[0] / ps_app_ctxt->u4_psnr_cnt));
241 printf("Avg PSNR U : %-2.2f\n",
242 (ps_app_ctxt->adbl_psnr[1] / ps_app_ctxt->u4_psnr_cnt));
243 printf("Avg PSNR V : %-2.2f\n",
244 (ps_app_ctxt->adbl_psnr[2] / ps_app_ctxt->u4_psnr_cnt));
245 }
246