1/******************************************************************************
2 *
3 * Copyright (C) 2015 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/*****************************************************************************/
22/* File Includes                                                             */
23/*****************************************************************************/
24/* System include files */
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <math.h>
29
30/* User include files */
31#include "ih264_typedefs.h"
32#include "iv2.h"
33#include "ive2.h"
34#include "ih264e.h"
35#include "app.h"
36#include "psnr.h"
37
38/*****************************************************************************/
39/*                                                                           */
40/*  Function Name : init_psnr                                                */
41/*                                                                           */
42/*  Description   : Initialize  PSNR for the Y, U, V component               */
43/*                                                                           */
44/*  Inputs        :                                                          */
45/*                                                                           */
46/*  Globals       :                                                          */
47/*                                                                           */
48/*  Processing    :                                                          */
49/*                                                                           */
50/*  Outputs       :                                                          */
51/*                                                                           */
52/*  Returns       :                                                          */
53/*                                                                           */
54/*  Issues        :                                                          */
55/*                                                                           */
56/*  Revision History:                                                        */
57/*                                                                           */
58/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
59/*         28 12 2005   Ittiam          Draft                                */
60/*                                                                           */
61/*****************************************************************************/
62void init_psnr(app_ctxt_t *ps_app_ctxt)
63{
64    ps_app_ctxt->adbl_psnr[0]   = 0;
65    ps_app_ctxt->adbl_psnr[1]   = 0;
66    ps_app_ctxt->adbl_psnr[2]   = 0;
67    ps_app_ctxt->u4_psnr_cnt    = 0;
68}
69
70
71/*****************************************************************************/
72/*                                                                           */
73/*  Function Name : compute_psnr                                             */
74/*                                                                           */
75/*  Description   : Computes the PSNR for the Y, U, V component              */
76/*                                                                           */
77/*  Inputs        :                                                          */
78/*                                                                           */
79/*  Globals       :                                                          */
80/*                                                                           */
81/*  Processing    :                                                          */
82/*                                                                           */
83/*  Outputs       :                                                          */
84/*                                                                           */
85/*  Returns       :                                                          */
86/*                                                                           */
87/*  Issues        :                                                          */
88/*                                                                           */
89/*  Revision History:                                                        */
90/*                                                                           */
91/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
92/*         28 12 2005   Ittiam          Draft                                */
93/*                                                                           */
94/*****************************************************************************/
95void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t *ps_buf2)
96{
97    WORD32 i, j;
98    WORD32 comp;
99    DOUBLE df_psnr[3];
100    WORD32 wd, ht, strd1, strd2;
101    UWORD8 *pu1_buf1, *pu1_buf2;
102    WORD32 incr1, incr2;
103
104    printf("\nPicNum %4d\t ", ps_app_ctxt->u4_psnr_cnt);
105
106    for(comp = 0; comp < 3; comp++)
107    {
108        df_psnr[comp] = 0;
109        pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[comp];
110        pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[comp];
111        wd = ps_buf1->au4_wd[comp];
112        ht = ps_buf1->au4_ht[comp];
113        strd1 = ps_buf1->au4_strd[comp];
114        strd2 = ps_buf2->au4_strd[comp];
115        incr1 = 1;
116        incr2 = 1;
117
118        if((IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
119                        || (IV_YUV_420SP_UV == ps_buf1->e_color_fmt))
120        {
121            switch(comp)
122            {
123                case 0:
124                    pu1_buf1 = ps_buf1->apv_bufs[0];
125                    break;
126                case 1:
127                    if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
128                        pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1];
129                    else
130                        pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1] + 1;
131                    incr1 = 2;
132                    break;
133                case 2:
134                    if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
135                        pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1] + 1;
136                    else
137                        pu1_buf1 = ps_buf1->apv_bufs[1];
138                    incr1 = 2;
139                    break;
140            }
141        }
142        if ((IV_YUV_420SP_UV == ps_buf2->e_color_fmt)
143                        || (IV_YUV_420SP_UV == ps_buf2->e_color_fmt))
144        {
145            switch(comp)
146            {
147                case 0:
148                    pu1_buf2 = ps_buf2->apv_bufs[0];
149                    break;
150                case 1:
151                    if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt)
152                        pu1_buf2 = ps_buf2->apv_bufs[1];
153                    else
154                        pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1;
155                    incr1 = 2;
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                    incr1 = 2;
163                    break;
164            }
165        }
166
167        for(i = 0; i < ht; i++)
168        {
169            for(j = 0; j < wd; j++)
170            {
171                WORD32 diff;
172                diff = (*pu1_buf1 - *pu1_buf2);
173                pu1_buf1 += incr1;
174                pu1_buf2 += incr2;
175                df_psnr[comp] += diff * diff;
176            }
177            pu1_buf1 += strd1 - ps_buf1->au4_wd[comp];
178            pu1_buf2 += strd2 - ps_buf2->au4_wd[comp];
179        }
180        df_psnr[comp] /= (wd * ht);
181        if(df_psnr[comp])
182            df_psnr[comp] = 20 * log10(255 / sqrt(df_psnr[comp]));
183        else
184            df_psnr[comp] = 100;
185
186        ps_app_ctxt->adbl_psnr[comp] += df_psnr[comp];
187        switch(comp)
188        {
189            case 0:
190                printf("Y :");
191                break;
192            case 1:
193                printf("U :");
194                break;
195            case 2:
196                printf("V :");
197                break;
198            default:
199                break;
200        }
201        printf("%2.2f\t", df_psnr[comp]);
202
203    }
204
205    ps_app_ctxt->u4_psnr_cnt++;
206}
207
208
209/*****************************************************************************/
210/*                                                                           */
211/*  Function Name : print_average_psnr                                       */
212/*                                                                           */
213/*  Description   : Computes the average PSNR for the Y, U, V component      */
214/*                                                                           */
215/*  Inputs        :                                                          */
216/*                                                                           */
217/*  Globals       :                                                          */
218/*                                                                           */
219/*  Processing    :                                                          */
220/*                                                                           */
221/*  Outputs       :                                                          */
222/*                                                                           */
223/*  Returns       :                                                          */
224/*                                                                           */
225/*  Issues        :                                                          */
226/*                                                                           */
227/*  Revision History:                                                        */
228/*                                                                           */
229/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
230/*         28 12 2005   Ittiam          Draft                                */
231/*                                                                           */
232/*****************************************************************************/
233void print_average_psnr(app_ctxt_t *ps_app_ctxt)
234{
235    printf("\n");
236
237    printf("Avg PSNR Y                      : %-2.2f\n", (ps_app_ctxt->adbl_psnr[0] / ps_app_ctxt->u4_psnr_cnt));
238    printf("Avg PSNR U                      : %-2.2f\n", (ps_app_ctxt->adbl_psnr[1] / ps_app_ctxt->u4_psnr_cnt));
239    printf("Avg PSNR V                      : %-2.2f\n", (ps_app_ctxt->adbl_psnr[2] / ps_app_ctxt->u4_psnr_cnt));
240}
241
242