[x264-devel] Fix SSIM calculation with sliced threads

Jason Garrett-Glaser git at videolan.org
Sun Jul 10 06:11:02 CEST 2011


x264 | branch: master | Jason Garrett-Glaser <jason at x264.com> | Sat Jul  9 19:21:00 2011 -0700| [dc94dfcb767c4d44706f9e5f722a384efd0e6c01] | committer: Jason Garrett-Glaser

Fix SSIM calculation with sliced threads

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=dc94dfcb767c4d44706f9e5f722a384efd0e6c01
---

 common/common.h   |    1 +
 common/pixel.c    |    3 ++-
 common/pixel.h    |    2 +-
 encoder/encoder.c |    7 +++++--
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/common/common.h b/common/common.h
index d9e8799..0b146fc 100644
--- a/common/common.h
+++ b/common/common.h
@@ -830,6 +830,7 @@ struct x264_t
             /* Metrics */
             int64_t i_ssd[3];
             double f_ssim;
+            int i_ssim_cnt;
         } frame;
 
         /* Cumulated stats */
diff --git a/common/pixel.c b/common/pixel.c
index cf8be63..12ecb6f 100644
--- a/common/pixel.c
+++ b/common/pixel.c
@@ -619,7 +619,7 @@ static float ssim_end4( int sum0[5][4], int sum1[5][4], int width )
 float x264_pixel_ssim_wxh( x264_pixel_function_t *pf,
                            pixel *pix1, int stride1,
                            pixel *pix2, int stride2,
-                           int width, int height, void *buf )
+                           int width, int height, void *buf, int *cnt )
 {
     int z = 0;
     float ssim = 0.0;
@@ -638,6 +638,7 @@ float x264_pixel_ssim_wxh( x264_pixel_function_t *pf,
         for( int x = 0; x < width-1; x += 4 )
             ssim += pf->ssim_end4( sum0+x, sum1+x, X264_MIN(4,width-x-1) );
     }
+    *cnt = (height-1) * (width-1);
     return ssim;
 }
 
diff --git a/common/pixel.h b/common/pixel.h
index 0127256..d47d9a8 100644
--- a/common/pixel.h
+++ b/common/pixel.h
@@ -125,7 +125,7 @@ typedef struct
 void x264_pixel_init( int cpu, x264_pixel_function_t *pixf );
 void x264_pixel_ssd_nv12( x264_pixel_function_t *pf, pixel *pix1, int i_pix1, pixel *pix2, int i_pix2, int i_width, int i_height, uint64_t *ssd_u, uint64_t *ssd_v );
 uint64_t x264_pixel_ssd_wxh( x264_pixel_function_t *pf, pixel *pix1, int i_pix1, pixel *pix2, int i_pix2, int i_width, int i_height );
-float x264_pixel_ssim_wxh( x264_pixel_function_t *pf, pixel *pix1, int i_pix1, pixel *pix2, int i_pix2, int i_width, int i_height, void *buf );
+float x264_pixel_ssim_wxh( x264_pixel_function_t *pf, pixel *pix1, int i_pix1, pixel *pix2, int i_pix2, int i_width, int i_height, void *buf, int *cnt );
 int x264_field_vsad( x264_t *h, int mb_x, int mb_y );
 
 #endif
diff --git a/encoder/encoder.c b/encoder/encoder.c
index 2b6dd83..20b8fcf 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -1819,6 +1819,7 @@ static void x264_fdec_filter_row( x264_t *h, int mb_y, int b_inloop )
 
         if( h->param.analyse.b_ssim )
         {
+            int ssim_cnt;
             x264_emms();
             /* offset by 2 pixels to avoid alignment of ssim blocks with dct blocks,
              * and overlap by 4 */
@@ -1827,7 +1828,8 @@ static void x264_fdec_filter_row( x264_t *h, int mb_y, int b_inloop )
                 x264_pixel_ssim_wxh( &h->pixf,
                     h->fdec->plane[0] + 2+minpix_y*h->fdec->i_stride[0], h->fdec->i_stride[0],
                     h->fenc->plane[0] + 2+minpix_y*h->fenc->i_stride[0], h->fenc->i_stride[0],
-                    h->param.i_width-2, maxpix_y-minpix_y, h->scratch_buffer );
+                    h->param.i_width-2, maxpix_y-minpix_y, h->scratch_buffer, &ssim_cnt );
+            h->stat.frame.i_ssim_cnt += ssim_cnt;
         }
     }
 }
@@ -2446,6 +2448,7 @@ static int x264_threaded_slices_write( x264_t *h )
         for( int j = 0; j < 3; j++ )
             h->stat.frame.i_ssd[j] += t->stat.frame.i_ssd[j];
         h->stat.frame.f_ssim += t->stat.frame.f_ssim;
+        h->stat.frame.i_ssim_cnt += t->stat.frame.i_ssim_cnt;
     }
 
     return 0;
@@ -3126,7 +3129,7 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
     if( h->param.analyse.b_ssim )
     {
         double ssim_y = h->stat.frame.f_ssim
-                      / (((h->param.i_width-6)>>2) * ((h->param.i_height-6)>>2));
+                      / h->stat.frame.i_ssim_cnt;
         h->stat.f_ssim_mean_y[h->sh.i_type] += ssim_y * dur;
         snprintf( psz_message + strlen(psz_message), 80 - strlen(psz_message),
                   " SSIM Y:%.5f", ssim_y );



More information about the x264-devel mailing list