[cvs] / xvidcore / src / plugins / plugin_ssim.c Repository:
ViewVC logotype

Annotation of /xvidcore/src/plugins/plugin_ssim.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (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 : suxen_drol 1.9 #include <stdlib.h>
27 : Skal 1.1 #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.7 /* 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 1.1 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 1.5 int grid;
82 :    
83 : Skal 1.1 /*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 1.3 framestat_t* tmp = ssim->head;
129 : Skal 1.1 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 1.4 fprintf(out,"quant avg min max\n");
134 : Skal 1.1 while(tmp->next->next != NULL){
135 : Skal 1.6 fprintf(out,"%3d %1.3f %1.3f %1.3f\n",tmp->quant,tmp->ssim_avg,tmp->ssim_min,tmp->ssim_max);
136 : Skal 1.1 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 1.3 framestat_t* tmp;
144 : Skal 1.1 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 1.6 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 1.7 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 1.1 /*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 1.6 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 1.7 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 1.6 /*calculate contrast and correlation of the two blocks*/
347 : Skal 1.5 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 1.1 for(i=0;i< 8;i++){
351 :     for(j=0;j< 8;j++){
352 : Skal 1.5 valo = *ptro;
353 :     valc = *ptrc;
354 : Skal 1.1 devo += valo*valo;
355 : Skal 1.5 devc += valc*valc;
356 :     corr += valo*valc;
357 : Skal 1.1 ptro++;
358 :     ptrc++;
359 :     }
360 : Skal 1.5 ptro += str;
361 :     ptrc += str;
362 : Skal 1.1 }
363 : Skal 1.5
364 :     *pdevo = devo - ((lumo*lumo + 32) >> 6);
365 :     *pdevc = devc - ((lumc*lumc + 32) >> 6);
366 :     *pcorr = corr - ((lumo*lumc + 32) >> 6);
367 : Skal 1.1 };
368 :    
369 :     /*calculate the final ssim value*/
370 : Skal 1.6 static float calc_ssim(float meano, float meanc, float devo, float devc, float corr){
371 : Skal 1.1 static const float c1 = (0.01*255)*(0.01*255);
372 :     static const float c2 = (0.03*255)*(0.03*255);
373 : Skal 1.6 /*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 1.1 }
376 :    
377 :     static void ssim_after(xvid_plg_data_t* data, ssim_data_t* ssim){
378 : Skal 1.6 int i,j,c=0,opt;
379 : Skal 1.1 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 1.5 ovr = str - width + (width % ssim->grid);
390 : Skal 1.1
391 :     ptr1 = (unsigned char*) data->original.plane[0];
392 :     ptr2 = (unsigned char*) data->current.plane[0];
393 :    
394 : Skal 1.6 opt = ssim->grid == 1 && ssim->param->acc != 0;
395 : Skal 1.1
396 :     /*TODO: Thread*/
397 : Skal 1.5 for(i=0;i<height;i+=ssim->grid){
398 : Skal 1.1 /*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 1.5 ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr);
403 : Skal 1.2 emms();
404 :    
405 : Skal 1.6 val = calc_ssim((float) meano,(float) meanc,(float) devo,(float) devc,(float) corr);
406 : Skal 1.1 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 1.5
414 : Skal 1.1 if(val < min) min = val;
415 :     if(val > max) max = val;
416 : Skal 1.5 ptr1+=ssim->grid;
417 :     ptr2+=ssim->grid;
418 : Skal 1.1 /*rest of each row*/
419 : Skal 1.5 for(j=ssim->grid;j<width;j+=ssim->grid){
420 : Skal 1.6 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 1.5 }
427 :     ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr);
428 : Skal 1.2 emms();
429 :    
430 : Skal 1.6 val = calc_ssim((float) meano,(float) meanc,(float) devo,(float) devc,(float) corr);
431 : Skal 1.1 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 1.5 ptr1+=ssim->grid;
440 :     ptr2+=ssim->grid;
441 : Skal 1.1 }
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 1.6 printf(" SSIM: avg: %1.3f min: %1.3f max: %1.3f\n",isum,min,max);
462 : Skal 1.1 }
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 1.5 ssim->consim = consim_c;
476 : Skal 1.1
477 :     ssim->param = param;
478 :    
479 : Skal 1.5 ssim->grid = param->acc;
480 :    
481 : Isibaar 1.10 #if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
482 : Isibaar 1.8 {
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 1.1 }
492 : Skal 1.2 #endif
493 : Skal 1.1
494 : Skal 1.6 /*gaussian weigthing not implemented*/
495 : Skal 1.7 #if !defined(USE_INT_GAUSSIAN)
496 : Skal 1.6 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 1.7 #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 1.6 if(ssim->grid > 4) ssim->grid = 4;
511 :    
512 : Skal 1.1 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 1.4 /*free(ssim->errmap);*/
555 : Skal 1.1 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