[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.3, Fri Oct 13 08:39:20 2006 UTC revision 1.6, Wed Nov 8 06:55:27 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  struct framestat_t{  struct framestat_t{
47          int type;          int type;
48          int quant;          int quant;
# Line 62  Line 68 
68          uint8_t* errmap;          uint8_t* errmap;
69          */          */
70    
71            int grid;
72    
73          /*for average SSIM*/          /*for average SSIM*/
74          float ssim_sum;          float ssim_sum;
75          int frame_cnt;          int frame_cnt;
# Line 112  Line 120 
120          if(out==NULL) printf("Cannot open %s in plugin_ssim\n",path);          if(out==NULL) printf("Cannot open %s in plugin_ssim\n",path);
121    
122          fprintf(out,"SSIM Error Metric\n");          fprintf(out,"SSIM Error Metric\n");
123          fprintf(out,"quant   avg     min     max");          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);
# Line 219  Line 227 
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;
# Line 232  Line 254 
254  }  }
255    
256  /*calculate contrast and correlation of the two blocks*/  /*calculate contrast and correlation of the two blocks*/
257  void iconsim_c(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr){  void consim_gaussian(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr){
258          int valo, valc, devo =0, devc=0, corr=0;          unsigned int valo, valc,i,j,str;
259          int i,j;          float devo=0, devc=0, corr=0,sumo,sumc,sumcorr;
260            str = stride - 8;
261          for(i=0;i< 8;i++){          for(i=0;i< 8;i++){
262                    sumo = 0;
263                    sumc = 0;
264                    sumcorr = 0;
265                  for(j=0;j< 8;j++){                  for(j=0;j< 8;j++){
266                          valo = *ptro - lumo;                          valo = *ptro;
267                          valc = *ptrc - lumc;                          valc = *ptrc;
268                          devo += valo*valo;                          sumo += valo*valo*mask8[j];
269                            sumc += valc*valc*mask8[j];
270                            sumcorr += valo*valc*mask8[j];
271                          ptro++;                          ptro++;
                         devc += valc*valc;  
272                          ptrc++;                          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){
289            unsigned int valo, valc, devo=0, devc=0, corr=0,i,j,str;
290            str = stride - 8;
291            for(i=0;i< 8;i++){
292                    for(j=0;j< 8;j++){
293                            valo = *ptro;
294                            valc = *ptrc;
295                            devo += valo*valo;
296                            devc += valc*valc;
297                          corr += valo*valc;                          corr += valo*valc;
298                            ptro++;
299                            ptrc++;
300                  }                  }
301          ptro += stride -8;          ptro += str;
302          ptrc += stride -8;          ptrc += str;
303          }          }
304          *pdevo = devo;  
305          *pdevc = devc;          *pdevo = devo - ((lumo*lumo + 32) >> 6);
306          *pcorr = corr;          *pdevc = devc - ((lumc*lumc + 32) >> 6);
307            *pcorr = corr - ((lumo*lumc + 32) >> 6);
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;
323          int meanc, meano;          int meanc, meano;
324          int devc, devo, corr;          int devc, devo, corr;
325    
         #define GRID 1  
   
326          width = data->width - 8;          width = data->width - 8;
327          height = data->height - 8;          height = data->height - 8;
328          str = data->original.stride[0];          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]);          if(str != data->current.stride[0]) printf("WARNING: Different strides in plugin_ssim original: %d current: %d\n",str,data->current.stride[0]);
330          ovr = str - width + (width % GRID);          ovr = str - width + (width % ssim->grid);
331    
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+=GRID){          for(i=0;i<height;i+=ssim->grid){
339                  /*begin of each row*/                  /*begin of each row*/
340                  meano = meanc = devc = devo = corr = 0;                  meano = meanc = devc = devo = corr = 0;
341                  meano = ssim->func8x8(ptr1,str);                  meano = ssim->func8x8(ptr1,str);
342                  meanc = ssim->func8x8(ptr2,str);                  meanc = ssim->func8x8(ptr2,str);
343                  ssim->consim(ptr1,ptr2,str,meano>>6,meanc>>6,&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
# Line 305  Line 351 
351                          ssim->errmap[i*width] = (uint8_t) 127*val;                          ssim->errmap[i*width] = (uint8_t) 127*val;
352                  */                  */
353    
354    
355                  if(val < min) min = val;                  if(val < min) min = val;
356                  if(val > max) max = val;                  if(val > max) max = val;
357                  ptr1+=GRID;                  ptr1+=ssim->grid;
358                  ptr2+=GRID;                  ptr2+=ssim->grid;
359                  /*rest of each row*/                  /*rest of each row*/
360                  for(j=1;j<width;j+=GRID){                  for(j=ssim->grid;j<width;j+=ssim->grid){
361                          /* for grid = 1 use                          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 {
365                          meano = ssim->func8x8(ptr1,str);                          meano = ssim->func8x8(ptr1,str);
366                          meanc = ssim->func8x8(ptr2,str);                          meanc = ssim->func8x8(ptr2,str);
367                          ssim->consim(ptr1,ptr2,str,meano>>6,meanc>>6,&devo,&devc,&corr);                          }
368                            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
# Line 329  Line 377 
377                          */                          */
378                          if(val < min) min = val;                          if(val < min) min = val;
379                          if(val > max) max = val;                          if(val > max) max = val;
380                          ptr1+=GRID;                          ptr1+=ssim->grid;
381                          ptr2+=GRID;                          ptr2+=ssim->grid;
382                  }                  }
383                  ptr1 +=ovr;                  ptr1 +=ovr;
384                  ptr2 +=ovr;                  ptr2 +=ovr;
# Line 351  Line 399 
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  }  }
# Line 368  Line 416 
416    
417          ssim->func8x8 = lum_8x8_c;          ssim->func8x8 = lum_8x8_c;
418          ssim->func2x8 = lum_2x8_c;          ssim->func2x8 = lum_2x8_c;
419          ssim->consim = iconsim_c;          ssim->consim = consim_c;
420    
421          ssim->param = param;          ssim->param = param;
422    
423            ssim->grid = param->acc;
424    
425  #if defined(ARCH_IS_IA32)  #if defined(ARCH_IS_IA32)
426          if(cpu_flags & XVID_CPU_MMX){          if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){
427                  ssim->func8x8 = lum_8x8_mmx;                  ssim->func8x8 = lum_8x8_mmx;
428                  ssim->consim = consim_mmx;                  ssim->consim = consim_mmx;
429          }          }
430          if(cpu_flags & XVID_CPU_SSE2){          if((cpu_flags & XVID_CPU_SSE2) && (param->acc > 0)){
431                  ssim->consim = consim_sse2;                  ssim->consim = consim_sse2;
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    
# Line 424  Line 483 
483                          if(ssim->param->stat_path != NULL)                          if(ssim->param->stat_path != NULL)
484                                  framestat_write(ssim,ssim->param->stat_path);                                  framestat_write(ssim,ssim->param->stat_path);
485                          framestat_free(ssim->head);                          framestat_free(ssim->head);
486                          //free(ssim->errmap);                          /*free(ssim->errmap);*/
487                          free(ssim->param);                          free(ssim->param);
488                          free(ssim);                          free(ssim);
489                          break;                          break;

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.6

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