Parent Directory | Revision Log
Revision 1767 - (view) (download)
1 : | Skal | 1730 | /***************************************************************************** |
2 : | * | ||
3 : | * XVID MPEG-4 VIDEO CODEC | ||
4 : | * - SSIM plugin: computes the SSIM metric - | ||
5 : | * | ||
6 : | * Copyright(C) 2005 Johannes Reinhardt <Johannes.Reinhardt@gmx.de> | ||
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 : | * | ||
23 : | * | ||
24 : | ****************************************************************************/ | ||
25 : | |||
26 : | #include <malloc.h> | ||
27 : | #include <stdio.h> | ||
28 : | #include <math.h> | ||
29 : | Isibaar | 1734 | #include "../portab.h" |
30 : | Skal | 1730 | #include "../xvid.h" |
31 : | #include "plugin_ssim.h" | ||
32 : | #include "../utils/emms.h" | ||
33 : | |||
34 : | /* needed for visualisation of the error map with X | ||
35 : | display.h borrowed from x264 | ||
36 : | #include "display.h"*/ | ||
37 : | |||
38 : | typedef struct framestat_t framestat_t; | ||
39 : | |||
40 : | Skal | 1757 | /*dev 1.0 gaussian weighting. the weight for the pixel x,y is w(x)*w(y)*/ |
41 : | static float mask8[8] = { | ||
42 : | 0.0069815, 0.1402264, 1.0361408, 2.8165226, | ||
43 : | 2.8165226, 1.0361408, 0.1402264, 0.0069815 | ||
44 : | }; | ||
45 : | |||
46 : | Skal | 1758 | /* integer version. Norm: coeffs sums up to 4096. |
47 : | Define USE_INT_GAUSSIAN to use it as replacement to float version */ | ||
48 : | |||
49 : | /* #define USE_INT_GAUSSIAN */ | ||
50 : | static const uint16_t imask8[8] = { | ||
51 : | 4, 72, 530, 1442, 1442, 530, 72, 4 | ||
52 : | }; | ||
53 : | #define GACCUM(X) ( ((X)+(1<<11)) >> 12 ) | ||
54 : | |||
55 : | |||
56 : | Skal | 1730 | struct framestat_t{ |
57 : | int type; | ||
58 : | int quant; | ||
59 : | float ssim_min; | ||
60 : | float ssim_max; | ||
61 : | float ssim_avg; | ||
62 : | framestat_t* next; | ||
63 : | }; | ||
64 : | |||
65 : | |||
66 : | typedef int (*lumfunc)(uint8_t* ptr, int stride); | ||
67 : | typedef void (*csfunc)(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr); | ||
68 : | |||
69 : | int lum_8x8_mmx(uint8_t* ptr, int stride); | ||
70 : | void consim_mmx(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr); | ||
71 : | void consim_sse2(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr); | ||
72 : | |||
73 : | typedef struct{ | ||
74 : | |||
75 : | plg_ssim_param_t* param; | ||
76 : | |||
77 : | /* for error map visualisation | ||
78 : | uint8_t* errmap; | ||
79 : | */ | ||
80 : | |||
81 : | Skal | 1743 | int grid; |
82 : | |||
83 : | Skal | 1730 | /*for average SSIM*/ |
84 : | float ssim_sum; | ||
85 : | int frame_cnt; | ||
86 : | |||
87 : | /*function pointers*/ | ||
88 : | lumfunc func8x8; | ||
89 : | lumfunc func2x8; | ||
90 : | csfunc consim; | ||
91 : | |||
92 : | /*stats - for debugging*/ | ||
93 : | framestat_t* head; | ||
94 : | framestat_t* tail; | ||
95 : | } ssim_data_t; | ||
96 : | |||
97 : | /* append the stats for another frame to the linked list*/ | ||
98 : | void framestat_append(ssim_data_t* ssim,int type, int quant, float min, float max, float avg){ | ||
99 : | framestat_t* act; | ||
100 : | act = (framestat_t*) malloc(sizeof(framestat_t)); | ||
101 : | act->type = type; | ||
102 : | act->quant = quant; | ||
103 : | act->ssim_min = min; | ||
104 : | act->ssim_max = max; | ||
105 : | act->ssim_avg = avg; | ||
106 : | act->next = NULL; | ||
107 : | |||
108 : | if(ssim->head == NULL){ | ||
109 : | ssim->head = act; | ||
110 : | ssim->tail = act; | ||
111 : | } else { | ||
112 : | ssim->tail->next = act; | ||
113 : | ssim->tail = act; | ||
114 : | } | ||
115 : | } | ||
116 : | |||
117 : | /* destroy the whole list*/ | ||
118 : | void framestat_free(framestat_t* stat){ | ||
119 : | if(stat != NULL){ | ||
120 : | if(stat->next != NULL) framestat_free(stat->next); | ||
121 : | free(stat); | ||
122 : | } | ||
123 : | return; | ||
124 : | } | ||
125 : | |||
126 : | /*writeout the collected stats*/ | ||
127 : | void framestat_write(ssim_data_t* ssim, char* path){ | ||
128 : | Isibaar | 1734 | framestat_t* tmp = ssim->head; |
129 : | Skal | 1730 | FILE* out = fopen(path,"w"); |
130 : | if(out==NULL) printf("Cannot open %s in plugin_ssim\n",path); | ||
131 : | |||
132 : | fprintf(out,"SSIM Error Metric\n"); | ||
133 : | Skal | 1737 | fprintf(out,"quant avg min max\n"); |
134 : | Skal | 1730 | while(tmp->next->next != NULL){ |
135 : | Skal | 1757 | fprintf(out,"%3d %1.3f %1.3f %1.3f\n",tmp->quant,tmp->ssim_avg,tmp->ssim_min,tmp->ssim_max); |
136 : | Skal | 1730 | tmp = tmp->next; |
137 : | } | ||
138 : | fclose(out); | ||
139 : | } | ||
140 : | |||
141 : | /*writeout the collected stats in octave readable format*/ | ||
142 : | void framestat_write_oct(ssim_data_t* ssim, char* path){ | ||
143 : | Isibaar | 1734 | framestat_t* tmp; |
144 : | Skal | 1730 | FILE* out = fopen(path,"w"); |
145 : | if(out==NULL) printf("Cannot open %s in plugin_ssim\n",path); | ||
146 : | |||
147 : | fprintf(out,"quant = ["); | ||
148 : | tmp = ssim->head; | ||
149 : | while(tmp->next->next != NULL){ | ||
150 : | fprintf(out,"%d, ",tmp->quant); | ||
151 : | tmp = tmp->next; | ||
152 : | } | ||
153 : | fprintf(out,"%d];\n\n",tmp->quant); | ||
154 : | |||
155 : | fprintf(out,"ssim_min = ["); | ||
156 : | tmp = ssim->head; | ||
157 : | while(tmp->next->next != NULL){ | ||
158 : | fprintf(out,"%f, ",tmp->ssim_min); | ||
159 : | tmp = tmp->next; | ||
160 : | } | ||
161 : | fprintf(out,"%f];\n\n",tmp->ssim_min); | ||
162 : | |||
163 : | fprintf(out,"ssim_max = ["); | ||
164 : | tmp = ssim->head; | ||
165 : | while(tmp->next->next != NULL){ | ||
166 : | fprintf(out,"%f, ",tmp->ssim_max); | ||
167 : | tmp = tmp->next; | ||
168 : | } | ||
169 : | fprintf(out,"%f];\n\n",tmp->ssim_max); | ||
170 : | |||
171 : | fprintf(out,"ssim_avg = ["); | ||
172 : | tmp = ssim->head; | ||
173 : | while(tmp->next->next != NULL){ | ||
174 : | fprintf(out,"%f, ",tmp->ssim_avg); | ||
175 : | tmp = tmp->next; | ||
176 : | } | ||
177 : | fprintf(out,"%f];\n\n",tmp->ssim_avg); | ||
178 : | |||
179 : | fprintf(out,"ivop = ["); | ||
180 : | tmp = ssim->head; | ||
181 : | while(tmp->next->next != NULL){ | ||
182 : | if(tmp->type == XVID_TYPE_IVOP){ | ||
183 : | fprintf(out,"%d, ",tmp->quant); | ||
184 : | fprintf(out,"%f, ",tmp->ssim_avg); | ||
185 : | fprintf(out,"%f, ",tmp->ssim_min); | ||
186 : | fprintf(out,"%f; ",tmp->ssim_max); | ||
187 : | } | ||
188 : | tmp = tmp->next; | ||
189 : | } | ||
190 : | fprintf(out,"%d, ",tmp->quant); | ||
191 : | fprintf(out,"%f, ",tmp->ssim_avg); | ||
192 : | fprintf(out,"%f, ",tmp->ssim_min); | ||
193 : | fprintf(out,"%f];\n\n",tmp->ssim_max); | ||
194 : | |||
195 : | fprintf(out,"pvop = ["); | ||
196 : | tmp = ssim->head; | ||
197 : | while(tmp->next->next != NULL){ | ||
198 : | if(tmp->type == XVID_TYPE_PVOP){ | ||
199 : | fprintf(out,"%d, ",tmp->quant); | ||
200 : | fprintf(out,"%f, ",tmp->ssim_avg); | ||
201 : | fprintf(out,"%f, ",tmp->ssim_min); | ||
202 : | fprintf(out,"%f; ",tmp->ssim_max); | ||
203 : | } | ||
204 : | tmp = tmp->next; | ||
205 : | } | ||
206 : | fprintf(out,"%d, ",tmp->quant); | ||
207 : | fprintf(out,"%f, ",tmp->ssim_avg); | ||
208 : | fprintf(out,"%f, ",tmp->ssim_min); | ||
209 : | fprintf(out,"%f];\n\n",tmp->ssim_max); | ||
210 : | |||
211 : | fprintf(out,"bvop = ["); | ||
212 : | tmp = ssim->head; | ||
213 : | while(tmp->next->next != NULL){ | ||
214 : | if(tmp->type == XVID_TYPE_BVOP){ | ||
215 : | fprintf(out,"%d, ",tmp->quant); | ||
216 : | fprintf(out,"%f, ",tmp->ssim_avg); | ||
217 : | fprintf(out,"%f, ",tmp->ssim_min); | ||
218 : | fprintf(out,"%f; ",tmp->ssim_max); | ||
219 : | } | ||
220 : | tmp = tmp->next; | ||
221 : | } | ||
222 : | fprintf(out,"%d, ",tmp->quant); | ||
223 : | fprintf(out,"%f, ",tmp->ssim_avg); | ||
224 : | fprintf(out,"%f, ",tmp->ssim_min); | ||
225 : | fprintf(out,"%f];\n\n",tmp->ssim_max); | ||
226 : | |||
227 : | fclose(out); | ||
228 : | } | ||
229 : | |||
230 : | /*calculate the luminance of a 8x8 block*/ | ||
231 : | int lum_8x8_c(uint8_t* ptr, int stride){ | ||
232 : | int mean=0,i,j; | ||
233 : | for(i=0;i< 8;i++) | ||
234 : | for(j=0;j< 8;j++){ | ||
235 : | mean += ptr[i*stride + j]; | ||
236 : | } | ||
237 : | return mean; | ||
238 : | } | ||
239 : | |||
240 : | Skal | 1757 | int lum_8x8_gaussian(uint8_t* ptr, int stride){ |
241 : | float mean=0,sum; | ||
242 : | int i,j; | ||
243 : | for(i=0;i<8;i++){ | ||
244 : | sum = 0; | ||
245 : | for(j=0;j<8;j++) | ||
246 : | sum += ptr[i*stride + j]*mask8[j]; | ||
247 : | |||
248 : | sum *=mask8[i]; | ||
249 : | mean += sum; | ||
250 : | } | ||
251 : | return (int) mean + 0.5; | ||
252 : | } | ||
253 : | |||
254 : | Skal | 1758 | int lum_8x8_gaussian_int(uint8_t* ptr, int stride){ |
255 : | uint32_t mean; | ||
256 : | int i,j; | ||
257 : | mean = 0; | ||
258 : | for(i=0;i<8;i++){ | ||
259 : | uint32_t sum = 0; | ||
260 : | for(j=0;j<8;j++) | ||
261 : | sum += ptr[i*stride + j]*imask8[j]; | ||
262 : | |||
263 : | sum = GACCUM(sum) * imask8[i]; | ||
264 : | mean += sum; | ||
265 : | } | ||
266 : | return (int)GACCUM(mean); | ||
267 : | } | ||
268 : | |||
269 : | Skal | 1730 | /*calculate the difference between two blocks next to each other on a row*/ |
270 : | int lum_2x8_c(uint8_t* ptr, int stride){ | ||
271 : | int mean=0,i; | ||
272 : | /*Luminance*/ | ||
273 : | for(i=0;i< 8;i++){ | ||
274 : | mean -= *(ptr-1); | ||
275 : | mean += *(ptr+ 8 - 1); | ||
276 : | ptr+=stride; | ||
277 : | } | ||
278 : | return mean; | ||
279 : | } | ||
280 : | |||
281 : | /*calculate contrast and correlation of the two blocks*/ | ||
282 : | Skal | 1757 | void consim_gaussian(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr){ |
283 : | unsigned int valo, valc,i,j,str; | ||
284 : | float devo=0, devc=0, corr=0,sumo,sumc,sumcorr; | ||
285 : | str = stride - 8; | ||
286 : | for(i=0;i< 8;i++){ | ||
287 : | sumo = 0; | ||
288 : | sumc = 0; | ||
289 : | sumcorr = 0; | ||
290 : | for(j=0;j< 8;j++){ | ||
291 : | valo = *ptro; | ||
292 : | valc = *ptrc; | ||
293 : | sumo += valo*valo*mask8[j]; | ||
294 : | sumc += valc*valc*mask8[j]; | ||
295 : | sumcorr += valo*valc*mask8[j]; | ||
296 : | ptro++; | ||
297 : | ptrc++; | ||
298 : | } | ||
299 : | |||
300 : | devo += sumo*mask8[i]; | ||
301 : | devc += sumc*mask8[i]; | ||
302 : | corr += sumcorr*mask8[i]; | ||
303 : | ptro += str; | ||
304 : | ptrc += str; | ||
305 : | } | ||
306 : | |||
307 : | *pdevo = (int) (devo - ((lumo*lumo + 32) >> 6)) + 0.5; | ||
308 : | *pdevc = (int) (devc - ((lumc*lumc + 32) >> 6)) + 0.5; | ||
309 : | *pcorr = (int) (corr - ((lumo*lumc + 32) >> 6)) + 0.5; | ||
310 : | }; | ||
311 : | |||
312 : | Skal | 1758 | void consim_gaussian_int(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr) |
313 : | { | ||
314 : | unsigned int valo, valc,i,j,str; | ||
315 : | uint32_t devo=0, devc=0, corr=0; | ||
316 : | str = stride - 8; | ||
317 : | for(i=0;i< 8;i++){ | ||
318 : | uint32_t sumo = 0; | ||
319 : | uint32_t sumc = 0; | ||
320 : | uint32_t sumcorr = 0; | ||
321 : | for(j=0;j< 8;j++){ | ||
322 : | valo = *ptro; | ||
323 : | valc = *ptrc; | ||
324 : | sumo += valo*valo*imask8[j]; | ||
325 : | sumc += valc*valc*imask8[j]; | ||
326 : | sumcorr += valo*valc*imask8[j]; | ||
327 : | ptro++; | ||
328 : | ptrc++; | ||
329 : | } | ||
330 : | |||
331 : | devo += GACCUM(sumo)*imask8[i]; | ||
332 : | devc += GACCUM(sumc)*imask8[i]; | ||
333 : | corr += GACCUM(sumcorr)*imask8[i]; | ||
334 : | ptro += str; | ||
335 : | ptrc += str; | ||
336 : | } | ||
337 : | |||
338 : | devo = GACCUM(devo); | ||
339 : | devc = GACCUM(devc); | ||
340 : | corr = GACCUM(corr); | ||
341 : | *pdevo = (int) (devo - ((lumo*lumo + 32) >> 6)) + 0.5; | ||
342 : | *pdevc = (int) (devc - ((lumc*lumc + 32) >> 6)) + 0.5; | ||
343 : | *pcorr = (int) (corr - ((lumo*lumc + 32) >> 6)) + 0.5; | ||
344 : | }; | ||
345 : | |||
346 : | Skal | 1757 | /*calculate contrast and correlation of the two blocks*/ |
347 : | Skal | 1743 | void consim_c(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr){ |
348 : | unsigned int valo, valc, devo=0, devc=0, corr=0,i,j,str; | ||
349 : | str = stride - 8; | ||
350 : | Skal | 1730 | for(i=0;i< 8;i++){ |
351 : | for(j=0;j< 8;j++){ | ||
352 : | Skal | 1743 | valo = *ptro; |
353 : | valc = *ptrc; | ||
354 : | Skal | 1730 | devo += valo*valo; |
355 : | Skal | 1743 | devc += valc*valc; |
356 : | corr += valo*valc; | ||
357 : | Skal | 1730 | ptro++; |
358 : | ptrc++; | ||
359 : | } | ||
360 : | Skal | 1743 | ptro += str; |
361 : | ptrc += str; | ||
362 : | Skal | 1730 | } |
363 : | Skal | 1743 | |
364 : | *pdevo = devo - ((lumo*lumo + 32) >> 6); | ||
365 : | *pdevc = devc - ((lumc*lumc + 32) >> 6); | ||
366 : | *pcorr = corr - ((lumo*lumc + 32) >> 6); | ||
367 : | Skal | 1730 | }; |
368 : | |||
369 : | /*calculate the final ssim value*/ | ||
370 : | Skal | 1757 | static float calc_ssim(float meano, float meanc, float devo, float devc, float corr){ |
371 : | Skal | 1730 | static const float c1 = (0.01*255)*(0.01*255); |
372 : | static const float c2 = (0.03*255)*(0.03*255); | ||
373 : | Skal | 1757 | /*printf("meano: %f meanc: %f devo: %f devc: %f corr: %f\n",meano,meanc,devo,devc,corr);*/ |
374 : | return ((2.0*meano*meanc + c1)*(corr/32.0 + c2))/((meano*meano + meanc*meanc + c1)*(devc/64.0 + devo/64.0 + c2)); | ||
375 : | Skal | 1730 | } |
376 : | |||
377 : | static void ssim_after(xvid_plg_data_t* data, ssim_data_t* ssim){ | ||
378 : | Skal | 1757 | int i,j,c=0,opt; |
379 : | Skal | 1730 | int width,height,str,ovr; |
380 : | unsigned char * ptr1,*ptr2; | ||
381 : | float isum=0, min=1.00,max=0.00, val; | ||
382 : | int meanc, meano; | ||
383 : | int devc, devo, corr; | ||
384 : | |||
385 : | width = data->width - 8; | ||
386 : | height = data->height - 8; | ||
387 : | str = data->original.stride[0]; | ||
388 : | if(str != data->current.stride[0]) printf("WARNING: Different strides in plugin_ssim original: %d current: %d\n",str,data->current.stride[0]); | ||
389 : | Skal | 1743 | ovr = str - width + (width % ssim->grid); |
390 : | Skal | 1730 | |
391 : | ptr1 = (unsigned char*) data->original.plane[0]; | ||
392 : | ptr2 = (unsigned char*) data->current.plane[0]; | ||
393 : | |||
394 : | Skal | 1757 | opt = ssim->grid == 1 && ssim->param->acc != 0; |
395 : | Skal | 1730 | |
396 : | /*TODO: Thread*/ | ||
397 : | Skal | 1743 | for(i=0;i<height;i+=ssim->grid){ |
398 : | Skal | 1730 | /*begin of each row*/ |
399 : | meano = meanc = devc = devo = corr = 0; | ||
400 : | meano = ssim->func8x8(ptr1,str); | ||
401 : | meanc = ssim->func8x8(ptr2,str); | ||
402 : | Skal | 1743 | ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr); |
403 : | Skal | 1732 | emms(); |
404 : | |||
405 : | Skal | 1757 | val = calc_ssim((float) meano,(float) meanc,(float) devo,(float) devc,(float) corr); |
406 : | Skal | 1730 | isum += val; |
407 : | c++; | ||
408 : | /* for visualisation | ||
409 : | if(ssim->param->b_visualize) | ||
410 : | ssim->errmap[i*width] = (uint8_t) 127*val; | ||
411 : | */ | ||
412 : | |||
413 : | Skal | 1743 | |
414 : | Skal | 1730 | if(val < min) min = val; |
415 : | if(val > max) max = val; | ||
416 : | Skal | 1743 | ptr1+=ssim->grid; |
417 : | ptr2+=ssim->grid; | ||
418 : | Skal | 1730 | /*rest of each row*/ |
419 : | Skal | 1743 | for(j=ssim->grid;j<width;j+=ssim->grid){ |
420 : | Skal | 1757 | if(opt){ |
421 : | meano += ssim->func2x8(ptr1,str); | ||
422 : | meanc += ssim->func2x8(ptr2,str); | ||
423 : | } else { | ||
424 : | meano = ssim->func8x8(ptr1,str); | ||
425 : | meanc = ssim->func8x8(ptr2,str); | ||
426 : | Skal | 1743 | } |
427 : | ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr); | ||
428 : | Skal | 1732 | emms(); |
429 : | |||
430 : | Skal | 1757 | val = calc_ssim((float) meano,(float) meanc,(float) devo,(float) devc,(float) corr); |
431 : | Skal | 1730 | isum += val; |
432 : | c++; | ||
433 : | /* for visualisation | ||
434 : | if(ssim->param->b_visualize) | ||
435 : | ssim->errmap[i*width +j] = (uint8_t) 255*val; | ||
436 : | */ | ||
437 : | if(val < min) min = val; | ||
438 : | if(val > max) max = val; | ||
439 : | Skal | 1743 | ptr1+=ssim->grid; |
440 : | ptr2+=ssim->grid; | ||
441 : | Skal | 1730 | } |
442 : | ptr1 +=ovr; | ||
443 : | ptr2 +=ovr; | ||
444 : | } | ||
445 : | isum/=c; | ||
446 : | ssim->ssim_sum += isum; | ||
447 : | ssim->frame_cnt++; | ||
448 : | |||
449 : | if(ssim->param->stat_path != NULL) | ||
450 : | framestat_append(ssim,data->type,data->quant,min,max,isum); | ||
451 : | |||
452 : | /* for visualization | ||
453 : | if(ssim->param->b_visualize){ | ||
454 : | disp_gray(0,ssim->errmap,width,height,width, "Error-Map"); | ||
455 : | disp_gray(1,data->original.plane[0],data->width,data->height,data->original.stride[0],"Original"); | ||
456 : | disp_gray(2,data->current.plane[0],data->width,data->height,data->original.stride[0],"Compressed"); | ||
457 : | disp_sync(); | ||
458 : | } | ||
459 : | */ | ||
460 : | if(ssim->param->b_printstat){ | ||
461 : | Skal | 1757 | printf(" SSIM: avg: %1.3f min: %1.3f max: %1.3f\n",isum,min,max); |
462 : | Skal | 1730 | } |
463 : | |||
464 : | } | ||
465 : | |||
466 : | static int ssim_create(xvid_plg_create_t* create, void** handle){ | ||
467 : | ssim_data_t* ssim; | ||
468 : | plg_ssim_param_t* param; | ||
469 : | param = (plg_ssim_param_t*) malloc(sizeof(plg_ssim_param_t)); | ||
470 : | *param = *((plg_ssim_param_t*) create->param); | ||
471 : | ssim = (ssim_data_t*) malloc(sizeof(ssim_data_t)); | ||
472 : | |||
473 : | ssim->func8x8 = lum_8x8_c; | ||
474 : | ssim->func2x8 = lum_2x8_c; | ||
475 : | Skal | 1743 | ssim->consim = consim_c; |
476 : | Skal | 1730 | |
477 : | ssim->param = param; | ||
478 : | |||
479 : | Skal | 1743 | ssim->grid = param->acc; |
480 : | |||
481 : | Skal | 1732 | #if defined(ARCH_IS_IA32) |
482 : | Isibaar | 1767 | { |
483 : | int cpu_flags = check_cpu_features(); | ||
484 : | if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){ | ||
485 : | ssim->func8x8 = lum_8x8_mmx; | ||
486 : | ssim->consim = consim_mmx; | ||
487 : | } | ||
488 : | if((cpu_flags & XVID_CPU_SSE2) && (param->acc > 0)){ | ||
489 : | ssim->consim = consim_sse2; | ||
490 : | } | ||
491 : | Skal | 1730 | } |
492 : | Skal | 1732 | #endif |
493 : | Skal | 1730 | |
494 : | Skal | 1757 | /*gaussian weigthing not implemented*/ |
495 : | Skal | 1758 | #if !defined(USE_INT_GAUSSIAN) |
496 : | Skal | 1757 | if(ssim->grid == 0){ |
497 : | ssim->grid = 1; | ||
498 : | ssim->func8x8 = lum_8x8_gaussian; | ||
499 : | ssim->func2x8 = NULL; | ||
500 : | ssim->consim = consim_gaussian; | ||
501 : | } | ||
502 : | Skal | 1758 | #else |
503 : | if(ssim->grid == 0){ | ||
504 : | ssim->grid = 1; | ||
505 : | ssim->func8x8 = lum_8x8_gaussian_int; | ||
506 : | ssim->func2x8 = NULL; | ||
507 : | ssim->consim = consim_gaussian_int; | ||
508 : | } | ||
509 : | #endif | ||
510 : | Skal | 1757 | if(ssim->grid > 4) ssim->grid = 4; |
511 : | |||
512 : | Skal | 1730 | ssim->ssim_sum = 0.0; |
513 : | ssim->frame_cnt = 0; | ||
514 : | |||
515 : | /* for visualization | ||
516 : | if(param->b_visualize){ | ||
517 : | //error map | ||
518 : | ssim->errmap = (uint8_t*) malloc(sizeof(uint8_t)*(create->width-8)*(create->height-8)); | ||
519 : | } else { | ||
520 : | ssim->errmap = NULL; | ||
521 : | }; | ||
522 : | */ | ||
523 : | |||
524 : | /*stats*/ | ||
525 : | ssim->head=NULL; | ||
526 : | ssim->tail=NULL; | ||
527 : | |||
528 : | *(handle) = (void*) ssim; | ||
529 : | |||
530 : | return 0; | ||
531 : | } | ||
532 : | |||
533 : | int xvid_plugin_ssim(void * handle, int opt, void * param1, void * param2){ | ||
534 : | ssim_data_t* ssim; | ||
535 : | switch(opt){ | ||
536 : | case(XVID_PLG_INFO): | ||
537 : | ((xvid_plg_info_t*) param1)->flags = XVID_REQORIGINAL; | ||
538 : | break; | ||
539 : | case(XVID_PLG_CREATE): | ||
540 : | ssim_create((xvid_plg_create_t*) param1,(void**) param2); | ||
541 : | break; | ||
542 : | case(XVID_PLG_BEFORE): | ||
543 : | case(XVID_PLG_FRAME): | ||
544 : | break; | ||
545 : | case(XVID_PLG_AFTER): | ||
546 : | ssim_after((xvid_plg_data_t*) param1, (ssim_data_t*) handle); | ||
547 : | break; | ||
548 : | case(XVID_PLG_DESTROY): | ||
549 : | ssim = (ssim_data_t*) handle; | ||
550 : | printf("Average SSIM: %f\n",ssim->ssim_sum/ssim->frame_cnt); | ||
551 : | if(ssim->param->stat_path != NULL) | ||
552 : | framestat_write(ssim,ssim->param->stat_path); | ||
553 : | framestat_free(ssim->head); | ||
554 : | Skal | 1737 | /*free(ssim->errmap);*/ |
555 : | Skal | 1730 | free(ssim->param); |
556 : | free(ssim); | ||
557 : | break; | ||
558 : | default: | ||
559 : | break; | ||
560 : | } | ||
561 : | return 0; | ||
562 : | }; |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |