37 |
|
|
38 |
typedef struct framestat_t framestat_t; |
typedef struct framestat_t framestat_t; |
39 |
|
|
40 |
|
/*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 |
struct framestat_t{ |
struct framestat_t{ |
47 |
int type; |
int type; |
48 |
int quant; |
int quant; |
122 |
fprintf(out,"SSIM Error Metric\n"); |
fprintf(out,"SSIM Error Metric\n"); |
123 |
fprintf(out,"quant avg min max\n"); |
fprintf(out,"quant avg min max\n"); |
124 |
while(tmp->next->next != NULL){ |
while(tmp->next->next != NULL){ |
125 |
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.3f %1.3f %1.3f\n",tmp->quant,tmp->ssim_avg,tmp->ssim_min,tmp->ssim_max); |
126 |
tmp = tmp->next; |
tmp = tmp->next; |
127 |
} |
} |
128 |
fclose(out); |
fclose(out); |
227 |
return mean; |
return mean; |
228 |
} |
} |
229 |
|
|
230 |
|
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 |
/*calculate the difference between two blocks next to each other on a row*/ |
/*calculate the difference between two blocks next to each other on a row*/ |
245 |
int lum_2x8_c(uint8_t* ptr, int stride){ |
int lum_2x8_c(uint8_t* ptr, int stride){ |
246 |
int mean=0,i; |
int mean=0,i; |
254 |
} |
} |
255 |
|
|
256 |
/*calculate contrast and correlation of the two blocks*/ |
/*calculate contrast and correlation of the two blocks*/ |
257 |
|
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 |
void consim_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){ |
289 |
unsigned int valo, valc, devo=0, devc=0, corr=0,i,j,str; |
unsigned int valo, valc, devo=0, devc=0, corr=0,i,j,str; |
290 |
str = stride - 8; |
str = stride - 8; |
308 |
}; |
}; |
309 |
|
|
310 |
/*calculate the final ssim value*/ |
/*calculate the final ssim value*/ |
311 |
static float calc_ssim(int meano, int meanc, int devo, int devc, int corr){ |
static float calc_ssim(float meano, float meanc, float devo, float devc, float corr){ |
312 |
static const float c1 = (0.01*255)*(0.01*255); |
static const float c1 = (0.01*255)*(0.01*255); |
313 |
static const float c2 = (0.03*255)*(0.03*255); |
static const float c2 = (0.03*255)*(0.03*255); |
314 |
float fmeano,fmeanc,fdevo,fdevc,fcorr; |
/*printf("meano: %f meanc: %f devo: %f devc: %f corr: %f\n",meano,meanc,devo,devc,corr);*/ |
315 |
fmeanc = (float) meanc; |
return ((2.0*meano*meanc + c1)*(corr/32.0 + c2))/((meano*meano + meanc*meanc + c1)*(devc/64.0 + devo/64.0 + c2)); |
|
fmeano = (float) meano; |
|
|
fdevo = (float) devo; |
|
|
fdevc = (float) devc; |
|
|
fcorr = (float) corr; |
|
|
/* printf("meano: %f meanc: %f devo: %f devc: %f corr: %f\n",fmeano,fmeanc,fdevo,fdevc,fcorr); */ |
|
|
return ((2.0*fmeano*fmeanc + c1)*(fcorr/32.0 + c2))/((fmeano*fmeano + fmeanc*fmeanc + c1)*(fdevc/64.0 + fdevo/64.0 + c2)); |
|
316 |
} |
} |
317 |
|
|
318 |
static void ssim_after(xvid_plg_data_t* data, ssim_data_t* ssim){ |
static void ssim_after(xvid_plg_data_t* data, ssim_data_t* ssim){ |
319 |
int i,j,c=0; |
int i,j,c=0,opt; |
320 |
int width,height,str,ovr; |
int width,height,str,ovr; |
321 |
unsigned char * ptr1,*ptr2; |
unsigned char * ptr1,*ptr2; |
322 |
float isum=0, min=1.00,max=0.00, val; |
float isum=0, min=1.00,max=0.00, val; |
332 |
ptr1 = (unsigned char*) data->original.plane[0]; |
ptr1 = (unsigned char*) data->original.plane[0]; |
333 |
ptr2 = (unsigned char*) data->current.plane[0]; |
ptr2 = (unsigned char*) data->current.plane[0]; |
334 |
|
|
335 |
|
opt = ssim->grid == 1 && ssim->param->acc != 0; |
336 |
|
|
337 |
/*TODO: Thread*/ |
/*TODO: Thread*/ |
338 |
for(i=0;i<height;i+=ssim->grid){ |
for(i=0;i<height;i+=ssim->grid){ |
343 |
ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr); |
ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr); |
344 |
emms(); |
emms(); |
345 |
|
|
346 |
val = calc_ssim(meano,meanc,devo,devc,corr); |
val = calc_ssim((float) meano,(float) meanc,(float) devo,(float) devc,(float) corr); |
347 |
isum += val; |
isum += val; |
348 |
c++; |
c++; |
349 |
/* for visualisation |
/* for visualisation |
358 |
ptr2+=ssim->grid; |
ptr2+=ssim->grid; |
359 |
/*rest of each row*/ |
/*rest of each row*/ |
360 |
for(j=ssim->grid;j<width;j+=ssim->grid){ |
for(j=ssim->grid;j<width;j+=ssim->grid){ |
361 |
if(ssim->grid == 1){ |
if(opt){ |
362 |
meano += ssim->func2x8(ptr1,str); |
meano += ssim->func2x8(ptr1,str); |
363 |
meanc += ssim->func2x8(ptr2,str); |
meanc += ssim->func2x8(ptr2,str); |
364 |
} else { |
} else { |
368 |
ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr); |
ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr); |
369 |
emms(); |
emms(); |
370 |
|
|
371 |
val = calc_ssim(meano,meanc,devo,devc,corr); |
val = calc_ssim((float) meano,(float) meanc,(float) devo,(float) devc,(float) corr); |
372 |
isum += val; |
isum += val; |
373 |
c++; |
c++; |
374 |
/* for visualisation |
/* for visualisation |
399 |
} |
} |
400 |
*/ |
*/ |
401 |
if(ssim->param->b_printstat){ |
if(ssim->param->b_printstat){ |
402 |
printf(" SSIM: avg: %f min: %f max: %f\n",isum,min,max); |
printf(" SSIM: avg: %1.3f min: %1.3f max: %1.3f\n",isum,min,max); |
403 |
} |
} |
404 |
|
|
405 |
} |
} |
422 |
|
|
423 |
ssim->grid = param->acc; |
ssim->grid = param->acc; |
424 |
|
|
|
/*gaussian weigthing not implemented*/ |
|
|
if(ssim->grid == 0) ssim->grid = 1; |
|
|
if(ssim->grid > 4) ssim->grid = 4; |
|
|
|
|
|
printf("Grid: %d\n",ssim->grid); |
|
|
|
|
425 |
#if defined(ARCH_IS_IA32) |
#if defined(ARCH_IS_IA32) |
426 |
if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){ |
if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){ |
427 |
ssim->func8x8 = lum_8x8_mmx; |
ssim->func8x8 = lum_8x8_mmx; |
432 |
} |
} |
433 |
#endif |
#endif |
434 |
|
|
435 |
|
/*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 |
ssim->ssim_sum = 0.0; |
ssim->ssim_sum = 0.0; |
445 |
ssim->frame_cnt = 0; |
ssim->frame_cnt = 0; |
446 |
|
|