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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5, Mon Oct 30 11:21:42 2006 UTC revision 1.8, Thu Dec 21 23:27:25 2006 UTC
# Line 37  Line 37 
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    /* 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  struct framestat_t{  struct framestat_t{
57          int type;          int type;
58          int quant;          int quant;
# Line 116  Line 132 
132          fprintf(out,"SSIM Error Metric\n");          fprintf(out,"SSIM Error Metric\n");
133          fprintf(out,"quant   avg     min     max\n");          fprintf(out,"quant   avg     min     max\n");
134          while(tmp->next->next != NULL){          while(tmp->next->next != NULL){
135                  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);
136                  tmp = tmp->next;                  tmp = tmp->next;
137          }          }
138          fclose(out);          fclose(out);
# Line 221  Line 237 
237          return mean;          return mean;
238  }  }
239    
240    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    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  /*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*/
270  int lum_2x8_c(uint8_t* ptr, int stride){  int lum_2x8_c(uint8_t* ptr, int stride){
271          int mean=0,i;          int mean=0,i;
# Line 234  Line 279 
279  }  }
280    
281  /*calculate contrast and correlation of the two blocks*/  /*calculate contrast and correlation of the two blocks*/
282    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    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    /*calculate contrast and correlation of the two blocks*/
347  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){
348          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;
349          str = stride - 8;          str = stride - 8;
# Line 257  Line 367 
367  };  };
368    
369  /*calculate the final ssim value*/  /*calculate the final ssim value*/
370  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){
371          static const float c1 = (0.01*255)*(0.01*255);          static const float c1 = (0.01*255)*(0.01*255);
372          static const float c2 = (0.03*255)*(0.03*255);          static const float c2 = (0.03*255)*(0.03*255);
373          float fmeano,fmeanc,fdevo,fdevc,fcorr;          /*printf("meano: %f meanc: %f devo: %f devc: %f corr: %f\n",meano,meanc,devo,devc,corr);*/
374          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));  
375  }  }
376    
377  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){
378          int i,j,c=0;          int i,j,c=0,opt;
379          int width,height,str,ovr;          int width,height,str,ovr;
380          unsigned char * ptr1,*ptr2;          unsigned char * ptr1,*ptr2;
381          float isum=0, min=1.00,max=0.00, val;          float isum=0, min=1.00,max=0.00, val;
# Line 287  Line 391 
391          ptr1 = (unsigned char*) data->original.plane[0];          ptr1 = (unsigned char*) data->original.plane[0];
392          ptr2 = (unsigned char*) data->current.plane[0];          ptr2 = (unsigned char*) data->current.plane[0];
393    
394            opt = ssim->grid == 1 && ssim->param->acc != 0;
395    
396          /*TODO: Thread*/          /*TODO: Thread*/
397          for(i=0;i<height;i+=ssim->grid){          for(i=0;i<height;i+=ssim->grid){
# Line 298  Line 402 
402                  ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr);                  ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr);
403                  emms();                  emms();
404    
405                  val = calc_ssim(meano,meanc,devo,devc,corr);                  val = calc_ssim((float) meano,(float) meanc,(float) devo,(float) devc,(float) corr);
406                  isum += val;                  isum += val;
407                  c++;                  c++;
408                  /* for visualisation                  /* for visualisation
# Line 313  Line 417 
417                  ptr2+=ssim->grid;                  ptr2+=ssim->grid;
418                  /*rest of each row*/                  /*rest of each row*/
419                  for(j=ssim->grid;j<width;j+=ssim->grid){                  for(j=ssim->grid;j<width;j+=ssim->grid){
420                          if(ssim->grid == 1){                          if(opt){
421                          meano += ssim->func2x8(ptr1,str);                          meano += ssim->func2x8(ptr1,str);
422                          meanc += ssim->func2x8(ptr2,str);                          meanc += ssim->func2x8(ptr2,str);
423                          } else {                          } else {
# Line 323  Line 427 
427                          ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr);                          ssim->consim(ptr1,ptr2,str,meano,meanc,&devo,&devc,&corr);
428                          emms();                          emms();
429    
430                          val = calc_ssim(meano,meanc,devo,devc,corr);                          val = calc_ssim((float) meano,(float) meanc,(float) devo,(float) devc,(float) corr);
431                          isum += val;                          isum += val;
432                          c++;                          c++;
433                          /* for visualisation                          /* for visualisation
# Line 354  Line 458 
458          }          }
459  */  */
460          if(ssim->param->b_printstat){          if(ssim->param->b_printstat){
461                  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);
462          }          }
463    
464  }  }
# Line 362  Line 466 
466  static int ssim_create(xvid_plg_create_t* create, void** handle){  static int ssim_create(xvid_plg_create_t* create, void** handle){
467          ssim_data_t* ssim;          ssim_data_t* ssim;
468          plg_ssim_param_t* param;          plg_ssim_param_t* param;
         int cpu_flags;  
469          param = (plg_ssim_param_t*) malloc(sizeof(plg_ssim_param_t));          param = (plg_ssim_param_t*) malloc(sizeof(plg_ssim_param_t));
470          *param = *((plg_ssim_param_t*) create->param);          *param = *((plg_ssim_param_t*) create->param);
471          ssim = (ssim_data_t*) malloc(sizeof(ssim_data_t));          ssim = (ssim_data_t*) malloc(sizeof(ssim_data_t));
472    
         cpu_flags = check_cpu_features();  
   
473          ssim->func8x8 = lum_8x8_c;          ssim->func8x8 = lum_8x8_c;
474          ssim->func2x8 = lum_2x8_c;          ssim->func2x8 = lum_2x8_c;
475          ssim->consim = consim_c;          ssim->consim = consim_c;
# Line 377  Line 478 
478    
479          ssim->grid = param->acc;          ssim->grid = param->acc;
480    
         /*gaussian weigthing not implemented*/  
         if(ssim->grid == 0) ssim->grid = 1;  
         if(ssim->grid > 4) ssim->grid = 4;  
   
         printf("Grid: %d\n",ssim->grid);  
   
481  #if defined(ARCH_IS_IA32)  #if defined(ARCH_IS_IA32)
482            {
483                    int cpu_flags = check_cpu_features();
484          if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){          if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){
485                  ssim->func8x8 = lum_8x8_mmx;                  ssim->func8x8 = lum_8x8_mmx;
486                  ssim->consim = consim_mmx;                  ssim->consim = consim_mmx;
# Line 391  Line 488 
488          if((cpu_flags & XVID_CPU_SSE2) && (param->acc > 0)){          if((cpu_flags & XVID_CPU_SSE2) && (param->acc > 0)){
489                  ssim->consim = consim_sse2;                  ssim->consim = consim_sse2;
490          }          }
491            }
492  #endif  #endif
493    
494            /*gaussian weigthing not implemented*/
495    #if !defined(USE_INT_GAUSSIAN)
496            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    #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            if(ssim->grid > 4) ssim->grid = 4;
511    
512          ssim->ssim_sum = 0.0;          ssim->ssim_sum = 0.0;
513          ssim->frame_cnt = 0;          ssim->frame_cnt = 0;
514    

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.8

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4