<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Oct 8, 2013 at 6:43 AM, Aarthi Thirumalai <span dir="ltr"><<a href="mailto:aarthi@multicorewareinc.com" target="_blank">aarthi@multicorewareinc.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Aarthi Thirumalai<br>
# Date 1381232217 -19800<br>
#      Tue Oct 08 17:06:57 2013 +0530<br>
# Node ID 47286888d5a293234340153112810ce2a4f81546<br>
# Parent  9b3a427a1009d1853bbdc30abe1fd891864e6b38<br>
primitives: added C primitives to compute SSIM<br>
<br>
diff -r 9b3a427a1009 -r 47286888d5a2 source/common/pixel.cpp<br>
--- a/source/common/pixel.cpp   Tue Oct 08 11:12:12 2013 +0530<br>
+++ b/source/common/pixel.cpp   Tue Oct 08 17:06:57 2013 +0530<br>
@@ -653,6 +653,58 @@<br>
     }<br>
 }<br>
<br>
+/* structural similarity metric */<br>
+void ssim_4x4x2_core(const pixel *pix1, intptr_t stride1, const pixel *pix2, intptr_t stride2, ssim_t sums[2][4])<br>
+{<br>
+    for (int z = 0; z < 2; z++)<br>
+    {<br>
+        ssim_t s1 = 0, s2 = 0, ss = 0, s12 = 0;<br>
+        for (int y = 0; y < 4; y++)<br>
+        {<br>
+            for (int x = 0; x < 4; x++)<br>
+            {<br>
+                ssim_t a = pix1[x + y * stride1];<br>
+                ssim_t b = pix2[x + y * stride2];<br>
+                s1 += a;<br>
+                s2 += b;<br>
+                ss += a * a;<br>
+                ss += b * b;<br>
+                s12 += a * b;<br>
+            }<br>
+        }<br>
+        sums[z][0] = s1;<br>
+        sums[z][1] = s2;<br>
+        sums[z][2] = ss;<br>
+        sums[z][3] = s12;<br>
+        pix1 += 4;<br>
+        pix2 += 4;<br>
+    }<br>
+}<br>
+<br>
+float ssim_end_1(ssim_t s1, ssim_t s2, ssim_t ss, ssim_t s12)<br>
+{<br>
+    static const uint32_t pixelMax = (1 << X265_DEPTH) - 1;<br>
+    static const ssim_t ssim_c1 = (ssim_t)(.01 * .01 * pixelMax * pixelMax * 64 + .5);<br>
+    static const ssim_t ssim_c2 = (ssim_t)(.03 * .03 * pixelMax * pixelMax * 64 * 63 + .5);<br>
+    ssim_t vars = ss * 64 - s1 * s1 - s2 * s2;<br>
+    ssim_t covar = s12 * 64 - s1 * s2;<br>
+    return (float)(2 * s1 * s2 + ssim_c1) * (float)(2 * covar + ssim_c2)<br>
+           / ((float)(s1 * s1 + s2 * s2 + ssim_c1) * (float)(vars + ssim_c2));<br>
+}<br>
+<br>
+float ssim_end_4(ssim_t sum0[5][4], ssim_t sum1[5][4], int width)<br>
+{<br>
+    float ssim = 0.0;<br>
+<br>
+    for (int i = 0; i < width; i++)<br>
+    {<br>
+        ssim += ssim_end_1(sum0[i][0] + sum0[i + 1][0] + sum1[i][0] + sum1[i + 1][0],<br>
+                           sum0[i][1] + sum0[i + 1][1] + sum1[i][1] + sum1[i + 1][1],<br>
+                           sum0[i][2] + sum0[i + 1][2] + sum1[i][2] + sum1[i + 1][2],<br>
+                           sum0[i][3] + sum0[i + 1][3] + sum1[i][3] + sum1[i + 1][3]);<br>
+    }<br>
+    return ssim;<br>
+}<br>
 }  // end anonymous namespace<br>
<br>
 namespace x265 {<br>
@@ -870,5 +922,7 @@<br>
     p.scale1D_128to64 = scale1D_128to64;<br>
     p.scale2D_64to32 = scale2D_64to32;<br>
     p.frame_init_lowres_core = frame_init_lowres_core;<br>
+    p.ssim_4x4x2_core = ssim_4x4x2_core;<br>
+    p.ssim_end_4 = ssim_end_4;<br>
 }<br>
 }<br>
diff -r 9b3a427a1009 -r 47286888d5a2 source/common/primitives.h<br>
--- a/source/common/primitives.h        Tue Oct 08 11:12:12 2013 +0530<br>
+++ b/source/common/primitives.h        Tue Oct 08 17:06:57 2013 +0530<br>
@@ -64,11 +64,13 @@<br>
 typedef uint32_t sum_t;<br>
 typedef uint64_t sum2_t;<br>
 typedef uint64_t pixel4;<br>
+typedef int64_t ssim_t;<br>
 #else<br>
 typedef uint8_t pixel;<br>
 typedef uint16_t sum_t;<br>
 typedef uint32_t sum2_t;<br>
 typedef uint32_t pixel4;<br>
+typedef int32_t ssim_t;<br>
 #endif // if HIGH_BIT_DEPTH<br>
<br>
 namespace x265 {<br>
@@ -200,6 +202,8 @@<br>
 typedef void (*downscale_t)(pixel *src0, pixel *dstf, pixel *dsth, pixel *dstv, pixel *dstc,<br>
                             intptr_t src_stride, intptr_t dst_stride, int width, int height);<br>
 typedef void (*extendCURowBorder_t)(pixel* txt, intptr_t stride, int width, int height, int marginX);<br>
+typedef void (*ssim_4x4x2_core_t)(const pixel *pix1, intptr_t stride1, const pixel *pix2, intptr_t stride2, ssim_t sums[2][4]);<br>
+typedef float (*ssim_end4_t)(ssim_t sum0[5][4], ssim_t sum1[5][4], int width);<br>
<br>
 /* Define a structure containing function pointers to optimized encoder<br>
  * primitives.  Each pointer can reference either an assembly routine,<br>
@@ -259,6 +263,8 @@<br>
     scale_t         scale1D_128to64;<br>
     scale_t         scale2D_64to32;<br>
     downscale_t     frame_init_lowres_core;<br>
+    ssim_4x4x2_core_t ssim_4x4x2_core;<br>
+    ssim_end4_t       ssim_end_4;<br>
 };<br></blockquote><div><br></div><div>The next logical step is to hookup x264's assembly functions for this primitive pointer in asm-primitives.cpp </div></div><div><br></div>-- <br>Steve Borho
</div></div>