26 |
#include <malloc.h> |
#include <malloc.h> |
27 |
#include <stdio.h> |
#include <stdio.h> |
28 |
#include <math.h> |
#include <math.h> |
29 |
#include <stdint.h> |
#include "../portab.h" |
30 |
#include "../xvid.h" |
#include "../xvid.h" |
31 |
#include "plugin_ssim.h" |
#include "plugin_ssim.h" |
32 |
#include "../utils/emms.h" |
#include "../utils/emms.h" |
62 |
uint8_t* errmap; |
uint8_t* errmap; |
63 |
*/ |
*/ |
64 |
|
|
65 |
|
int grid; |
66 |
|
|
67 |
/*for average SSIM*/ |
/*for average SSIM*/ |
68 |
float ssim_sum; |
float ssim_sum; |
69 |
int frame_cnt; |
int frame_cnt; |
109 |
|
|
110 |
/*writeout the collected stats*/ |
/*writeout the collected stats*/ |
111 |
void framestat_write(ssim_data_t* ssim, char* path){ |
void framestat_write(ssim_data_t* ssim, char* path){ |
112 |
|
framestat_t* tmp = ssim->head; |
113 |
FILE* out = fopen(path,"w"); |
FILE* out = fopen(path,"w"); |
114 |
if(out==NULL) printf("Cannot open %s in plugin_ssim\n",path); |
if(out==NULL) printf("Cannot open %s in plugin_ssim\n",path); |
|
framestat_t* tmp = ssim->head; |
|
115 |
|
|
116 |
fprintf(out,"SSIM Error Metric\n"); |
fprintf(out,"SSIM Error Metric\n"); |
117 |
fprintf(out,"quant avg min max"); |
fprintf(out,"quant avg min max\n"); |
118 |
while(tmp->next->next != NULL){ |
while(tmp->next->next != NULL){ |
119 |
fprintf(out,"%3d %1.4f %1.4f %1.4f\n",tmp->quant,tmp->ssim_avg,tmp->ssim_min,tmp->ssim_max); |
fprintf(out,"%3d %1.4f %1.4f %1.4f\n",tmp->quant,tmp->ssim_avg,tmp->ssim_min,tmp->ssim_max); |
120 |
tmp = tmp->next; |
tmp = tmp->next; |
124 |
|
|
125 |
/*writeout the collected stats in octave readable format*/ |
/*writeout the collected stats in octave readable format*/ |
126 |
void framestat_write_oct(ssim_data_t* ssim, char* path){ |
void framestat_write_oct(ssim_data_t* ssim, char* path){ |
127 |
|
framestat_t* tmp; |
128 |
FILE* out = fopen(path,"w"); |
FILE* out = fopen(path,"w"); |
129 |
if(out==NULL) printf("Cannot open %s in plugin_ssim\n",path); |
if(out==NULL) printf("Cannot open %s in plugin_ssim\n",path); |
|
framestat_t* tmp; |
|
130 |
|
|
131 |
fprintf(out,"quant = ["); |
fprintf(out,"quant = ["); |
132 |
tmp = ssim->head; |
tmp = ssim->head; |
234 |
} |
} |
235 |
|
|
236 |
/*calculate contrast and correlation of the two blocks*/ |
/*calculate contrast and correlation of the two blocks*/ |
237 |
void iconsim_c(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr){ |
void consim_c(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr){ |
238 |
int valo, valc, devo =0, devc=0, corr=0; |
unsigned int valo, valc, devo=0, devc=0, corr=0,i,j,str; |
239 |
int i,j; |
str = stride - 8; |
240 |
for(i=0;i< 8;i++){ |
for(i=0;i< 8;i++){ |
241 |
for(j=0;j< 8;j++){ |
for(j=0;j< 8;j++){ |
242 |
valo = *ptro - lumo; |
valo = *ptro; |
243 |
valc = *ptrc - lumc; |
valc = *ptrc; |
244 |
devo += valo*valo; |
devo += valo*valo; |
|
ptro++; |
|
245 |
devc += valc*valc; |
devc += valc*valc; |
|
ptrc++; |
|
246 |
corr += valo*valc; |
corr += valo*valc; |
247 |
|
ptro++; |
248 |
|
ptrc++; |
249 |
} |
} |
250 |
ptro += stride -8; |
ptro += str; |
251 |
ptrc += stride -8; |
ptrc += str; |
252 |
} |
} |
253 |
*pdevo = devo; |
|
254 |
*pdevc = devc; |
*pdevo = devo - ((lumo*lumo + 32) >> 6); |
255 |
*pcorr = corr; |
*pdevc = devc - ((lumc*lumc + 32) >> 6); |
256 |
|
*pcorr = corr - ((lumo*lumc + 32) >> 6); |
257 |
}; |
}; |
258 |
|
|
259 |
/*calculate the final ssim value*/ |
/*calculate the final ssim value*/ |
266 |
fdevo = (float) devo; |
fdevo = (float) devo; |
267 |
fdevc = (float) devc; |
fdevc = (float) devc; |
268 |
fcorr = (float) corr; |
fcorr = (float) corr; |
269 |
// printf("meano: %f meanc: %f devo: %f devc: %f corr: %f\n",fmeano,fmeanc,fdevo,fdevc,fcorr); |
/* printf("meano: %f meanc: %f devo: %f devc: %f corr: %f\n",fmeano,fmeanc,fdevo,fdevc,fcorr); */ |
270 |
return ((2.0*fmeano*fmeanc + c1)*(fcorr/32.0 + c2))/((fmeano*fmeano + fmeanc*fmeanc + c1)*(fdevc/64.0 + fdevo/64.0 + c2)); |
return ((2.0*fmeano*fmeanc + c1)*(fcorr/32.0 + c2))/((fmeano*fmeano + fmeanc*fmeanc + c1)*(fdevc/64.0 + fdevo/64.0 + c2)); |
271 |
} |
} |
272 |
|
|
278 |
int meanc, meano; |
int meanc, meano; |
279 |
int devc, devo, corr; |
int devc, devo, corr; |
280 |
|
|
|
#define GRID 1 |
|
|
|
|
281 |
width = data->width - 8; |
width = data->width - 8; |
282 |
height = data->height - 8; |
height = data->height - 8; |
283 |
str = data->original.stride[0]; |
str = data->original.stride[0]; |
284 |
if(str != data->current.stride[0]) printf("WARNING: Different strides in plugin_ssim original: %d current: %d\n",str,data->current.stride[0]); |
if(str != data->current.stride[0]) printf("WARNING: Different strides in plugin_ssim original: %d current: %d\n",str,data->current.stride[0]); |
285 |
ovr = str - width + (width % GRID); |
ovr = str - width + (width % ssim->grid); |
286 |
|
|
287 |
ptr1 = (unsigned char*) data->original.plane[0]; |
ptr1 = (unsigned char*) data->original.plane[0]; |
288 |
ptr2 = (unsigned char*) data->current.plane[0]; |
ptr2 = (unsigned char*) data->current.plane[0]; |
290 |
|
|
291 |
|
|
292 |
/*TODO: Thread*/ |
/*TODO: Thread*/ |
293 |
for(i=0;i<height;i+=GRID){ |
for(i=0;i<height;i+=ssim->grid){ |
294 |
/*begin of each row*/ |
/*begin of each row*/ |
295 |
meano = meanc = devc = devo = corr = 0; |
meano = meanc = devc = devo = corr = 0; |
296 |
meano = ssim->func8x8(ptr1,str); |
meano = ssim->func8x8(ptr1,str); |
297 |
meanc = ssim->func8x8(ptr2,str); |
meanc = ssim->func8x8(ptr2,str); |
298 |
ssim->consim(ptr1,ptr2,str,meano>>6,meanc>>6,&devo,&devc,&corr); |
ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr); |
299 |
|
emms(); |
300 |
|
|
301 |
val = calc_ssim(meano,meanc,devo,devc,corr); |
val = calc_ssim(meano,meanc,devo,devc,corr); |
302 |
isum += val; |
isum += val; |
306 |
ssim->errmap[i*width] = (uint8_t) 127*val; |
ssim->errmap[i*width] = (uint8_t) 127*val; |
307 |
*/ |
*/ |
308 |
|
|
309 |
|
|
310 |
if(val < min) min = val; |
if(val < min) min = val; |
311 |
if(val > max) max = val; |
if(val > max) max = val; |
312 |
ptr1+=GRID; |
ptr1+=ssim->grid; |
313 |
ptr2+=GRID; |
ptr2+=ssim->grid; |
314 |
/*rest of each row*/ |
/*rest of each row*/ |
315 |
for(j=1;j<width;j+=GRID){ |
for(j=ssim->grid;j<width;j+=ssim->grid){ |
316 |
/* for grid = 1 use |
if(ssim->grid == 1){ |
317 |
meano += ssim->func2x8(ptr1,str); |
meano += ssim->func2x8(ptr1,str); |
318 |
meanc += ssim->func2x8(ptr2,str); |
meanc += ssim->func2x8(ptr2,str); |
319 |
*/ |
} else { |
320 |
meano = ssim->func8x8(ptr1,str); |
meano = ssim->func8x8(ptr1,str); |
321 |
meanc = ssim->func8x8(ptr2,str); |
meanc = ssim->func8x8(ptr2,str); |
322 |
ssim->consim(ptr1,ptr2,str,meano>>6,meanc>>6,&devo,&devc,&corr); |
} |
323 |
|
ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr); |
324 |
|
emms(); |
325 |
|
|
326 |
val = calc_ssim(meano,meanc,devo,devc,corr); |
val = calc_ssim(meano,meanc,devo,devc,corr); |
327 |
isum += val; |
isum += val; |
328 |
c++; |
c++; |
332 |
*/ |
*/ |
333 |
if(val < min) min = val; |
if(val < min) min = val; |
334 |
if(val > max) max = val; |
if(val > max) max = val; |
335 |
ptr1+=GRID; |
ptr1+=ssim->grid; |
336 |
ptr2+=GRID; |
ptr2+=ssim->grid; |
337 |
} |
} |
338 |
ptr1 +=ovr; |
ptr1 +=ovr; |
339 |
ptr2 +=ovr; |
ptr2 +=ovr; |
371 |
|
|
372 |
ssim->func8x8 = lum_8x8_c; |
ssim->func8x8 = lum_8x8_c; |
373 |
ssim->func2x8 = lum_2x8_c; |
ssim->func2x8 = lum_2x8_c; |
374 |
ssim->consim = iconsim_c; |
ssim->consim = consim_c; |
375 |
|
|
376 |
ssim->param = param; |
ssim->param = param; |
377 |
|
|
378 |
if(cpu_flags & XVID_CPU_MMX){ |
ssim->grid = param->acc; |
379 |
|
|
380 |
|
/*gaussian weigthing not implemented*/ |
381 |
|
if(ssim->grid == 0) ssim->grid = 1; |
382 |
|
if(ssim->grid > 4) ssim->grid = 4; |
383 |
|
|
384 |
|
printf("Grid: %d\n",ssim->grid); |
385 |
|
|
386 |
|
#if defined(ARCH_IS_IA32) |
387 |
|
if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){ |
388 |
ssim->func8x8 = lum_8x8_mmx; |
ssim->func8x8 = lum_8x8_mmx; |
389 |
ssim->consim = consim_mmx; |
ssim->consim = consim_mmx; |
390 |
} |
} |
391 |
if(cpu_flags & XVID_CPU_SSE2){ |
if((cpu_flags & XVID_CPU_SSE2) && (param->acc > 0)){ |
392 |
ssim->consim = consim_sse2; |
ssim->consim = consim_sse2; |
393 |
} |
} |
394 |
|
#endif |
395 |
|
|
396 |
ssim->ssim_sum = 0.0; |
ssim->ssim_sum = 0.0; |
397 |
ssim->frame_cnt = 0; |
ssim->frame_cnt = 0; |
435 |
if(ssim->param->stat_path != NULL) |
if(ssim->param->stat_path != NULL) |
436 |
framestat_write(ssim,ssim->param->stat_path); |
framestat_write(ssim,ssim->param->stat_path); |
437 |
framestat_free(ssim->head); |
framestat_free(ssim->head); |
438 |
//free(ssim->errmap); |
/*free(ssim->errmap);*/ |
439 |
free(ssim->param); |
free(ssim->param); |
440 |
free(ssim); |
free(ssim); |
441 |
break; |
break; |