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