Parent Directory | Revision Log
Revision 1.3 - (view) (download)
1 : | Isibaar | 1.1 | /***************************************************************************** |
2 : | * | ||
3 : | * XVID MPEG-4 VIDEO CODEC | ||
4 : | * - PSNR-HVS-M plugin: computes the PSNR-HVS-M metric - | ||
5 : | * | ||
6 : | * Copyright(C) 2010 Michael Militzer <michael@xvid.org> | ||
7 : | * | ||
8 : | * This program is free software ; you can redistribute it and/or modify | ||
9 : | * it under the terms of the GNU General Public License as published by | ||
10 : | * the Free Software Foundation ; either version 2 of the License, or | ||
11 : | * (at your option) any later version. | ||
12 : | * | ||
13 : | * This program is distributed in the hope that it will be useful, | ||
14 : | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
15 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 : | * GNU General Public License for more details. | ||
17 : | * | ||
18 : | * You should have received a copy of the GNU General Public License | ||
19 : | * along with this program ; if not, write to the Free Software | ||
20 : | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 : | * | ||
22 : | Isibaar | 1.3 | * $Id: plugin_psnrhvsm.c,v 1.2 2010/11/08 20:20:39 Isibaar Exp $ |
23 : | Isibaar | 1.1 | * |
24 : | ****************************************************************************/ | ||
25 : | |||
26 : | /***************************************************************************** | ||
27 : | * | ||
28 : | * The PSNR-HVS-M metric is described in the following paper: | ||
29 : | * | ||
30 : | * "On between-coefficient contrast masking of DCT basis functions", by | ||
31 : | * N. Ponomarenko, F. Silvestri, K. Egiazarian, M. Carli, J. Astola, V. Lukin, | ||
32 : | * in Proceedings of the Third International Workshop on Video Processing and | ||
33 : | * Quality Metrics for Consumer Electronics VPQM-07, January, 2007, 4 p. | ||
34 : | * | ||
35 : | * http://www.ponomarenko.info/psnrhvsm.htm | ||
36 : | * | ||
37 : | ****************************************************************************/ | ||
38 : | |||
39 : | #include <stdlib.h> | ||
40 : | #include <stdio.h> | ||
41 : | #include <math.h> | ||
42 : | #include "../portab.h" | ||
43 : | #include "../xvid.h" | ||
44 : | #include "../dct/fdct.h" | ||
45 : | #include "../image/image.h" | ||
46 : | #include "../utils/mem_transfer.h" | ||
47 : | #include "../utils/emms.h" | ||
48 : | |||
49 : | typedef struct { | ||
50 : | |||
51 : | Isibaar | 1.3 | uint64_t mse_sum_y; /* for avrg psnr-hvs-m */ |
52 : | uint64_t mse_sum_u; | ||
53 : | uint64_t mse_sum_v; | ||
54 : | |||
55 : | Isibaar | 1.1 | long frame_cnt; |
56 : | |||
57 : | } psnrhvsm_data_t; /* internal plugin data */ | ||
58 : | |||
59 : | static const float CSF_Coeff[64] = | ||
60 : | { 1.608443f, 2.339554f, 2.573509f, 1.608443f, 1.072295f, 0.643377f, 0.504610f, 0.421887f, | ||
61 : | 2.144591f, 2.144591f, 1.838221f, 1.354478f, 0.989811f, 0.443708f, 0.428918f, 0.467911f, | ||
62 : | 1.838221f, 1.979622f, 1.608443f, 1.072295f, 0.643377f, 0.451493f, 0.372972f, 0.459555f, | ||
63 : | 1.838221f, 1.513829f, 1.169777f, 0.887417f, 0.504610f, 0.295806f, 0.321689f, 0.415082f, | ||
64 : | 1.429727f, 1.169777f, 0.695543f, 0.459555f, 0.378457f, 0.236102f, 0.249855f, 0.334222f, | ||
65 : | 1.072295f, 0.735288f, 0.467911f, 0.402111f, 0.317717f, 0.247453f, 0.227744f, 0.279729f, | ||
66 : | 0.525206f, 0.402111f, 0.329937f, 0.295806f, 0.249855f, 0.212687f, 0.214459f, 0.254803f, | ||
67 : | 0.357432f, 0.279729f, 0.270896f, 0.262603f, 0.229778f, 0.257351f, 0.249855f, 0.259950f | ||
68 : | }; | ||
69 : | |||
70 : | static const float Mask_Coeff[64] = | ||
71 : | { 0.000000f, 0.826446f, 1.000000f, 0.390625f, 0.173611f, 0.062500f, 0.038447f, 0.026874f, | ||
72 : | 0.694444f, 0.694444f, 0.510204f, 0.277008f, 0.147929f, 0.029727f, 0.027778f, 0.033058f, | ||
73 : | 0.510204f, 0.591716f, 0.390625f, 0.173611f, 0.062500f, 0.030779f, 0.021004f, 0.031888f, | ||
74 : | 0.510204f, 0.346021f, 0.206612f, 0.118906f, 0.038447f, 0.013212f, 0.015625f, 0.026015f, | ||
75 : | 0.308642f, 0.206612f, 0.073046f, 0.031888f, 0.021626f, 0.008417f, 0.009426f, 0.016866f, | ||
76 : | 0.173611f, 0.081633f, 0.033058f, 0.024414f, 0.015242f, 0.009246f, 0.007831f, 0.011815f, | ||
77 : | 0.041649f, 0.024414f, 0.016437f, 0.013212f, 0.009426f, 0.006830f, 0.006944f, 0.009803f, | ||
78 : | 0.019290f, 0.011815f, 0.011080f, 0.010412f, 0.007972f, 0.010000f, 0.009426f, 0.010203f | ||
79 : | }; | ||
80 : | |||
81 : | Isibaar | 1.2 | #if 0 /* Floating-point implementation */ |
82 : | Isibaar | 1.1 | |
83 : | static uint32_t Calc_MSE_H(int16_t *DCT_A, int16_t *DCT_B, uint8_t *IMG_A, uint8_t *IMG_B, int stride) | ||
84 : | { | ||
85 : | int x, y, i, j; | ||
86 : | uint32_t Global_A, Global_B, Sum_A = 0, Sum_B = 0; | ||
87 : | uint32_t Local[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
88 : | uint32_t Local_Square[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
89 : | float MASK_A = 0.f, MASK_B = 0.f; | ||
90 : | Isibaar | 1.2 | float Mult1 = 1.f, Mult2 = 1.f; |
91 : | Isibaar | 1.1 | uint32_t MSE_H = 0; |
92 : | |||
93 : | /* Step 1: Calculate CSF weighted energy of DCT coefficients */ | ||
94 : | for (y = 0; y < 8; y++) { | ||
95 : | for (x = 0; x < 8; x++) { | ||
96 : | MASK_A += (float)(DCT_A[y*8 + x]*DCT_A[y*8 + x])*Mask_Coeff[y*8 + x]; | ||
97 : | MASK_B += (float)(DCT_B[y*8 + x]*DCT_B[y*8 + x])*Mask_Coeff[y*8 + x]; | ||
98 : | } | ||
99 : | } | ||
100 : | |||
101 : | /* Step 2: Determine local variances compared to entire block variance */ | ||
102 : | for (y = 0; y < 2; y++) { | ||
103 : | for (x = 0; x < 2; x++) { | ||
104 : | Isibaar | 1.2 | for (j = 0; j < 4; j++) { |
105 : | for (i = 0; i < 4; i++) { | ||
106 : | uint8_t A = IMG_A[(y*4+j)*stride + 4*x + i]; | ||
107 : | uint8_t B = IMG_B[(y*4+j)*stride + 4*x + i]; | ||
108 : | |||
109 : | Local[y*2 + x] += A; | ||
110 : | Local[y*2 + x + 4] += B; | ||
111 : | Local_Square[y*2 + x] += A*A; | ||
112 : | Local_Square[y*2 + x + 4] += B*B; | ||
113 : | } | ||
114 : | Isibaar | 1.1 | } |
115 : | } | ||
116 : | } | ||
117 : | |||
118 : | Global_A = Local[0] + Local[1] + Local[2] + Local[3]; | ||
119 : | Global_B = Local[4] + Local[5] + Local[6] + Local[7]; | ||
120 : | |||
121 : | for (i = 0; i < 8; i++) | ||
122 : | Local[i] = (Local_Square[i]<<4) - (Local[i]*Local[i]); /* 16*Var(Di) */ | ||
123 : | |||
124 : | Local_Square[0] += (Local_Square[1] + Local_Square[2] + Local_Square[3]); | ||
125 : | Local_Square[4] += (Local_Square[5] + Local_Square[6] + Local_Square[7]); | ||
126 : | |||
127 : | Global_A = (Local_Square[0]<<6) - Global_A*Global_A; /* 64*Var(D) */ | ||
128 : | Global_B = (Local_Square[4]<<6) - Global_B*Global_B; /* 64*Var(D) */ | ||
129 : | |||
130 : | /* Step 3: Calculate contrast masking threshold */ | ||
131 : | Isibaar | 1.2 | if (Global_A) |
132 : | Mult1 = (float)(Local[0]+Local[1]+Local[2]+Local[3])/((float)(Global_A)/4.f); | ||
133 : | |||
134 : | if (Global_B) | ||
135 : | Mult2 = (float)(Local[4]+Local[5]+Local[6]+Local[7])/((float)(Global_B)/4.f); | ||
136 : | |||
137 : | MASK_A = (float)sqrt(MASK_A * Mult1) / 32.f; | ||
138 : | MASK_B = (float)sqrt(MASK_B * Mult2) / 32.f; | ||
139 : | Isibaar | 1.1 | |
140 : | if (MASK_B > MASK_A) MASK_A = MASK_B; /* MAX(MASK_A, MASK_B) */ | ||
141 : | |||
142 : | /* Step 4: Calculate MSE of DCT coeffs reduced by masking effect */ | ||
143 : | for (j = 0; j < 8; j++) { | ||
144 : | for (i = 0; i < 8; i++) { | ||
145 : | float u = (float)abs(DCT_A[j*8 + i] - DCT_B[j*8 + i]); | ||
146 : | |||
147 : | if ((i|j)>0) { | ||
148 : | if (u < (MASK_A / Mask_Coeff[j*8 + i])) | ||
149 : | u = 0; /* The error is not perceivable */ | ||
150 : | else | ||
151 : | u -= (MASK_A / Mask_Coeff[j*8 + i]); | ||
152 : | } | ||
153 : | |||
154 : | MSE_H += (uint32_t) ((256.f*(u * CSF_Coeff[j*8 + i])*(u * CSF_Coeff[j*8 + i])) + 0.5f); | ||
155 : | } | ||
156 : | } | ||
157 : | return MSE_H; /* Fixed-point value right-shifted by eight */ | ||
158 : | } | ||
159 : | |||
160 : | Isibaar | 1.3 | #else |
161 : | |||
162 : | /* First draft of a fixed-point implementation. | ||
163 : | Might serve as a template for MMX/SSE code */ | ||
164 : | Isibaar | 1.1 | |
165 : | static const uint16_t iMask_Coeff[64] = | ||
166 : | { 0, 59577, 65535, 40959, 27306, 16384, 12850, 10743, | ||
167 : | 54612, 54612, 46811, 34492, 25206, 11299, 10923, 11915, | ||
168 : | 46811, 50412, 40959, 27306, 16384, 11497, 9498, 11703, | ||
169 : | 46811, 38550, 29789, 22598, 12850, 7533, 8192, 10570, | ||
170 : | 36408, 29789, 17712, 11703, 9637, 6012, 6363, 8511, | ||
171 : | 27306, 18724, 11915, 10240, 8091, 6302, 5799, 7123, | ||
172 : | 13374, 10240, 8402, 7533, 6363, 5416, 5461, 6489, | ||
173 : | 9102, 7123, 6898, 6687, 5851, 6553, 6363, 6620 | ||
174 : | }; | ||
175 : | |||
176 : | static const uint16_t Inv_iMask_Coeff[64] = | ||
177 : | { 0, 310, 256, 655, 1475, 4096, 6659, 9526, | ||
178 : | 369, 369, 502, 924, 1731, 8612, 9216, 7744, | ||
179 : | 502, 433, 655, 1475, 4096, 8317, 12188, 8028, | ||
180 : | 502, 740, 1239, 2153, 6659, 19376, 16384, 9840, | ||
181 : | 829, 1239, 3505, 8028, 11838, 30415, 27159, 15178, | ||
182 : | 1475, 3136, 7744, 10486, 16796, 27688, 32691, 21667, | ||
183 : | 6147, 10486, 15575, 19376, 27159, 37482, 36866, 26114, | ||
184 : | 13271, 21667, 23105, 24587, 32112, 25600, 27159, 25091 | ||
185 : | }; | ||
186 : | |||
187 : | static const uint16_t iCSF_Coeff[64] = | ||
188 : | { 1647, 2396, 2635, 1647, 1098, 659, 517, 432, | ||
189 : | 2196, 2196, 1882, 1387, 1014, 454, 439, 479, | ||
190 : | 1882, 2027, 1647, 1098, 659, 462, 382, 471, | ||
191 : | 1882, 1550, 1198, 909, 517, 303, 329, 425, | ||
192 : | 1464, 1198, 712, 471, 388, 242, 256, 342, | ||
193 : | 1098, 753, 479, 412, 325, 253, 233, 286, | ||
194 : | 538, 412, 338, 303, 256, 218, 220, 261, | ||
195 : | 366, 286, 277, 269, 235, 264, 256, 266 | ||
196 : | }; | ||
197 : | |||
198 : | Isibaar | 1.2 | static __inline uint32_t isqrt(unsigned long n) |
199 : | { | ||
200 : | uint32_t c = 0x8000; | ||
201 : | uint32_t g = 0x8000; | ||
202 : | |||
203 : | for(;;) { | ||
204 : | if(g*g > n) | ||
205 : | g ^= c; | ||
206 : | c >>= 1; | ||
207 : | if(c == 0) | ||
208 : | return g; | ||
209 : | g |= c; | ||
210 : | } | ||
211 : | } | ||
212 : | |||
213 : | Isibaar | 1.1 | static uint32_t Calc_MSE_H(int16_t *DCT_A, int16_t *DCT_B, uint8_t *IMG_A, uint8_t *IMG_B, int stride) |
214 : | { | ||
215 : | int x, y, i, j; | ||
216 : | uint32_t Global_A, Global_B, Sum_A = 0, Sum_B = 0; | ||
217 : | uint32_t Local[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
218 : | uint32_t Local_Square[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
219 : | uint32_t MASK; | ||
220 : | uint32_t MSE_H = 0; | ||
221 : | |||
222 : | /* Step 1: Calculate CSF weighted energy of DCT coefficients */ | ||
223 : | for (y = 0; y < 8; y++) { | ||
224 : | for (x = 0; x < 8; x++) { | ||
225 : | uint16_t A = (abs(DCT_A[y*8 + x]) * iMask_Coeff[y*8 + x] + 4096) >> 13; | ||
226 : | uint16_t B = (abs(DCT_B[y*8 + x]) * iMask_Coeff[y*8 + x] + 4096) >> 13; | ||
227 : | |||
228 : | Sum_A += ((A*A) >> 3); /* PMADDWD */ | ||
229 : | Sum_B += ((B*B) >> 3); | ||
230 : | } | ||
231 : | } | ||
232 : | |||
233 : | /* Step 2: Determine local variances compared to entire block variance */ | ||
234 : | for (y = 0; y < 2; y++) { | ||
235 : | for (x = 0; x < 2; x++) { | ||
236 : | Isibaar | 1.2 | for (j = 0; j < 4; j++) { |
237 : | for (i = 0; i < 4; i++) { | ||
238 : | uint8_t A = IMG_A[(y*4+j)*stride + 4*x + i]; | ||
239 : | uint8_t B = IMG_B[(y*4+j)*stride + 4*x + i]; | ||
240 : | |||
241 : | Local[y*2 + x] += A; | ||
242 : | Local[y*2 + x + 4] += B; | ||
243 : | Local_Square[y*2 + x] += A*A; | ||
244 : | Local_Square[y*2 + x + 4] += B*B; | ||
245 : | } | ||
246 : | Isibaar | 1.1 | } |
247 : | } | ||
248 : | } | ||
249 : | |||
250 : | Global_A = Local[0] + Local[1] + Local[2] + Local[3]; | ||
251 : | Global_B = Local[4] + Local[5] + Local[6] + Local[7]; | ||
252 : | |||
253 : | for (i = 0; i < 8; i++) | ||
254 : | Local[i] = (Local_Square[i]<<4) - (Local[i]*Local[i]); /* 16*Var(Di) */ | ||
255 : | |||
256 : | Local_Square[0] += (Local_Square[1] + Local_Square[2] + Local_Square[3]); | ||
257 : | Local_Square[4] += (Local_Square[5] + Local_Square[6] + Local_Square[7]); | ||
258 : | |||
259 : | Global_A = (Local_Square[0]<<6) - Global_A*Global_A; /* 64*Var(D) */ | ||
260 : | Global_B = (Local_Square[4]<<6) - Global_B*Global_B; /* 64*Var(D) */ | ||
261 : | |||
262 : | /* Step 3: Calculate contrast masking threshold */ | ||
263 : | { | ||
264 : | Isibaar | 1.2 | uint32_t MASK_A, MASK_B; |
265 : | uint32_t Mult1 = 64, Mult2 = 64; | ||
266 : | |||
267 : | if (Global_A) | ||
268 : | Mult1 = ((Local[0]+Local[1]+Local[2]+Local[3])<<8) / Global_A; | ||
269 : | Isibaar | 1.1 | |
270 : | Isibaar | 1.2 | if (Global_B) |
271 : | Mult2 = ((Local[4]+Local[5]+Local[6]+Local[7])<<8) / Global_B; | ||
272 : | Isibaar | 1.1 | |
273 : | Isibaar | 1.2 | MASK_A = isqrt(2*Sum_A*Mult1) + 16; |
274 : | MASK_B = isqrt(2*Sum_B*Mult2) + 16; | ||
275 : | Isibaar | 1.1 | |
276 : | if (MASK_B > MASK_A) /* MAX(MASK_A, MASK_B) */ | ||
277 : | Isibaar | 1.2 | MASK = (uint32_t) MASK_B; |
278 : | Isibaar | 1.1 | else |
279 : | Isibaar | 1.2 | MASK = (uint32_t) MASK_A; |
280 : | Isibaar | 1.1 | } |
281 : | |||
282 : | /* Step 4: Calculate MSE of DCT coeffs reduced by masking effect */ | ||
283 : | for (j = 0; j < 8; j++) { | ||
284 : | for (i = 0; i < 8; i++) { | ||
285 : | uint32_t Thresh = (MASK * Inv_iMask_Coeff[j*8 + i] + 128) >> 8; | ||
286 : | uint32_t u = abs(DCT_A[j*8 + i] - DCT_B[j*8 + i]) << 10; | ||
287 : | |||
288 : | if ((i|j)>0) { | ||
289 : | if (u < Thresh) | ||
290 : | u = 0; /* The error is not perceivable */ | ||
291 : | else | ||
292 : | u -= Thresh; | ||
293 : | } | ||
294 : | |||
295 : | { | ||
296 : | uint64_t tmp = (u * iCSF_Coeff[j*8 + i] + 512) >> 10; | ||
297 : | MSE_H += (uint32_t) ((tmp * tmp) >> 12); | ||
298 : | } | ||
299 : | } | ||
300 : | } | ||
301 : | return MSE_H; | ||
302 : | } | ||
303 : | |||
304 : | #endif | ||
305 : | |||
306 : | static void psnrhvsm_after(xvid_plg_data_t *data, psnrhvsm_data_t *psnrhvsm) | ||
307 : | { | ||
308 : | DECLARE_ALIGNED_MATRIX(DCT, 2, 64, int16_t, CACHE_LINE); | ||
309 : | Isibaar | 1.3 | int32_t x, y, u, v; |
310 : | Isibaar | 1.1 | int16_t *DCT_A = &DCT[0], *DCT_B = &DCT[64]; |
311 : | Isibaar | 1.3 | uint64_t sse_y = 0, sse_u = 0, sse_v = 0; |
312 : | |||
313 : | for (y = 0; y < data->height>>3; y++) { | ||
314 : | uint8_t *IMG_A = (uint8_t *) data->original.plane[0]; | ||
315 : | uint8_t *IMG_B = (uint8_t *) data->current.plane[0]; | ||
316 : | uint32_t stride = data->original.stride[0]; | ||
317 : | |||
318 : | for (x = 0; x < data->width>>3; x++) { /* non multiple of 8 handling ?? */ | ||
319 : | int offset = (y<<3)*stride + (x<<3); | ||
320 : | Isibaar | 1.1 | |
321 : | emms(); | ||
322 : | |||
323 : | /* Transfer data */ | ||
324 : | transfer_8to16copy(DCT_A, IMG_A + offset, stride); | ||
325 : | transfer_8to16copy(DCT_B, IMG_B + offset, stride); | ||
326 : | |||
327 : | /* Perform DCT */ | ||
328 : | fdct(DCT_A); | ||
329 : | fdct(DCT_B); | ||
330 : | |||
331 : | emms(); | ||
332 : | |||
333 : | /* Calculate MSE_H reduced by contrast masking effect */ | ||
334 : | Isibaar | 1.3 | sse_y += Calc_MSE_H(DCT_A, DCT_B, IMG_A + offset, IMG_B + offset, stride); |
335 : | Isibaar | 1.1 | } |
336 : | } | ||
337 : | |||
338 : | Isibaar | 1.3 | for (y = 0; y < data->height>>4; y++) { |
339 : | uint8_t *U_A = (uint8_t *) data->original.plane[1]; | ||
340 : | uint8_t *V_A = (uint8_t *) data->original.plane[2]; | ||
341 : | uint8_t *U_B = (uint8_t *) data->current.plane[1]; | ||
342 : | uint8_t *V_B = (uint8_t *) data->current.plane[2]; | ||
343 : | uint32_t stride_uv = data->current.stride[1]; | ||
344 : | |||
345 : | for (x = 0; x < data->width>>4; x++) { /* non multiple of 8 handling ?? */ | ||
346 : | int offset = (y<<3)*stride_uv + (x<<3); | ||
347 : | |||
348 : | emms(); | ||
349 : | |||
350 : | /* Transfer data */ | ||
351 : | transfer_8to16copy(DCT_A, U_A + offset, stride_uv); | ||
352 : | transfer_8to16copy(DCT_B, U_B + offset, stride_uv); | ||
353 : | |||
354 : | /* Perform DCT */ | ||
355 : | fdct(DCT_A); | ||
356 : | fdct(DCT_B); | ||
357 : | |||
358 : | emms(); | ||
359 : | |||
360 : | /* Calculate MSE_H reduced by contrast masking effect */ | ||
361 : | sse_u += Calc_MSE_H(DCT_A, DCT_B, U_A + offset, U_B + offset, stride_uv); | ||
362 : | |||
363 : | emms(); | ||
364 : | |||
365 : | /* Transfer data */ | ||
366 : | transfer_8to16copy(DCT_A, V_A + offset, stride_uv); | ||
367 : | transfer_8to16copy(DCT_B, V_B + offset, stride_uv); | ||
368 : | |||
369 : | /* Perform DCT */ | ||
370 : | fdct(DCT_A); | ||
371 : | fdct(DCT_B); | ||
372 : | |||
373 : | emms(); | ||
374 : | |||
375 : | /* Calculate MSE_H reduced by contrast masking effect */ | ||
376 : | sse_v += Calc_MSE_H(DCT_A, DCT_B, V_A + offset, V_B + offset, stride_uv); | ||
377 : | } | ||
378 : | } | ||
379 : | |||
380 : | y = (int32_t) ( 4*sse_y / (data->width * data->height)); | ||
381 : | u = (int32_t) (16*sse_u / (data->width * data->height)); | ||
382 : | v = (int32_t) (16*sse_v / (data->width * data->height)); | ||
383 : | |||
384 : | psnrhvsm->mse_sum_y += y; | ||
385 : | psnrhvsm->mse_sum_u += u; | ||
386 : | psnrhvsm->mse_sum_v += v; | ||
387 : | Isibaar | 1.1 | psnrhvsm->frame_cnt++; |
388 : | |||
389 : | Isibaar | 1.3 | printf(" psnrhvsm y: %2.2f, psnrhvsm u: %2.2f, psnrhvsm v: %2.2f\n", sse_to_PSNR(y, 1024), sse_to_PSNR(u, 1024), sse_to_PSNR(v, 1024)); |
390 : | Isibaar | 1.1 | } |
391 : | |||
392 : | static int psnrhvsm_create(xvid_plg_create_t *create, void **handle) | ||
393 : | { | ||
394 : | psnrhvsm_data_t *psnrhvsm; | ||
395 : | psnrhvsm = (psnrhvsm_data_t *) malloc(sizeof(psnrhvsm_data_t)); | ||
396 : | |||
397 : | Isibaar | 1.3 | psnrhvsm->mse_sum_y = 0; |
398 : | psnrhvsm->mse_sum_u = 0; | ||
399 : | psnrhvsm->mse_sum_v = 0; | ||
400 : | |||
401 : | Isibaar | 1.1 | psnrhvsm->frame_cnt = 0; |
402 : | |||
403 : | *(handle) = (void*) psnrhvsm; | ||
404 : | return 0; | ||
405 : | } | ||
406 : | |||
407 : | int xvid_plugin_psnrhvsm(void *handle, int opt, void *param1, void *param2) | ||
408 : | { | ||
409 : | switch(opt) { | ||
410 : | case(XVID_PLG_INFO): | ||
411 : | ((xvid_plg_info_t *)param1)->flags = XVID_REQORIGINAL; | ||
412 : | break; | ||
413 : | case(XVID_PLG_CREATE): | ||
414 : | psnrhvsm_create((xvid_plg_create_t *)param1,(void **)param2); | ||
415 : | break; | ||
416 : | case(XVID_PLG_BEFORE): | ||
417 : | case(XVID_PLG_FRAME): | ||
418 : | break; | ||
419 : | case(XVID_PLG_AFTER): | ||
420 : | psnrhvsm_after((xvid_plg_data_t *)param1, (psnrhvsm_data_t *)handle); | ||
421 : | break; | ||
422 : | case(XVID_PLG_DESTROY): | ||
423 : | { | ||
424 : | Isibaar | 1.3 | uint32_t y, u, v; |
425 : | Isibaar | 1.1 | psnrhvsm_data_t *psnrhvsm = (psnrhvsm_data_t *)handle; |
426 : | |||
427 : | if (psnrhvsm) { | ||
428 : | Isibaar | 1.3 | y = (uint32_t) (psnrhvsm->mse_sum_y / psnrhvsm->frame_cnt); |
429 : | u = (uint32_t) (psnrhvsm->mse_sum_u / psnrhvsm->frame_cnt); | ||
430 : | v = (uint32_t) (psnrhvsm->mse_sum_v / psnrhvsm->frame_cnt); | ||
431 : | Isibaar | 1.1 | |
432 : | emms(); | ||
433 : | Isibaar | 1.3 | printf("Average psnrhvsm y: %2.2f, psnrhvsm u: %2.2f, psnrhvsm v: %2.2f\n", |
434 : | sse_to_PSNR(y, 1024), sse_to_PSNR(u, 1024), sse_to_PSNR(v, 1024)); | ||
435 : | Isibaar | 1.1 | free(psnrhvsm); |
436 : | } | ||
437 : | } | ||
438 : | break; | ||
439 : | default: | ||
440 : | break; | ||
441 : | } | ||
442 : | return 0; | ||
443 : | }; |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |