xref: /aosp_15_r20/external/libavc/examples/svcenc/psnr.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
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