<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Oct 8, 2013 at 12:13 PM, Aarthi Priya 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"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote"><div><div class="h5">On Tue, Oct 8, 2013 at 10:29 PM, Steve Borho <span dir="ltr"><<a href="mailto:steve@borho.org" target="_blank">steve@borho.org</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote"><div>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 1381232542 -19800<br>
#      Tue Oct 08 17:12:22 2013 +0530<br>
# Node ID 3ba555e98be2c0641d92d14155c6fb303c0003d9<br>
# Parent  47286888d5a293234340153112810ce2a4f81546<br>
calculate SSIM for each Row after deblock, sao<br></blockquote><div><br></div></div><div>I've queued this and the other patch after fixing more nits</div><div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<br>
diff -r 47286888d5a2 -r 3ba555e98be2 source/Lib/TLibEncoder/TEncTop.cpp<br>
--- a/source/Lib/TLibEncoder/TEncTop.cpp        Tue Oct 08 17:06:57 2013 +0530<br>
+++ b/source/Lib/TLibEncoder/TEncTop.cpp        Tue Oct 08 17:12:22 2013 +0530<br>
@@ -513,7 +513,7 @@<br>
     int width  = recon->getWidth() - getPad(0);<br>
     int height = recon->getHeight() - getPad(1);<br>
     int size = width * height;<br>
-<br>
+    double ssim = 0;<br>
     UInt64 ssdY = computeSSD(orig->getLumaAddr(), recon->getLumaAddr(), stride, width, height);<br>
<br>
     height >>= 1;<br>
@@ -604,7 +604,14 @@<br>
     {<br>
         m_analyzeB.addResult(psnrY, psnrU, psnrV, (double)bits);<br>
     }<br>
-<br>
+    if (param.bEnableSsim)<br>
+    {<br>
+        if(pic->getSlice()->m_ssimCnt > 0)<br></blockquote></div><div>white-space </div><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        {<br>
+            ssim += pic->getSlice()->m_ssim / pic->getSlice()->m_ssimCnt;<br></blockquote></div><div>I declared double ssim = pic->.. here since `ssim' is used nowhere else  </div></div></div></div></blockquote>

<div><br></div></div></div><div>I had added ssim var to print out along its value along  with psnr values at the end of this fuction. guess I haven't committed that change.  ll do it over this, once its pushed. </div>
<div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+            m_globalSsim += ssim;<br>
+        }<br>
+    }<br>
     if (param.logLevel >= X265_LOG_DEBUG)<br>
     {<br>
         char c = (slice->isIntra() ? 'I' : slice->isInterP() ? 'P' : 'B');<br>
diff -r 47286888d5a2 -r 3ba555e98be2 source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp   Tue Oct 08 17:06:57 2013 +0530<br>
+++ b/source/encoder/frameencoder.cpp   Tue Oct 08 17:12:22 2013 +0530<br>
@@ -92,7 +92,7 @@<br>
     }<br>
<br>
     m_frameFilter.destroy();<br>
-<br>
+    X265_FREE(ssimBuf);<br></blockquote><div><br></div></div><div>renamed ssimBuf to m_ssimBuf to follow class member naming convention</div><div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



     // wait for worker thread to exit<br>
     stop();<br>
 }<br>
@@ -111,6 +111,9 @@<br>
         m_rows[i].create(top);<br>
     }<br>
<br>
+    if (m_cfg->param.bEnableSsim)<br>
+        CHECKED_MALLOC(ssimBuf, ssim_t, 8 * (m_cfg->param.sourceWidth / 4 + 3));<br></blockquote><div><br></div></div><div>It's actually *safer* to not use CHECKED_MALLOC here.  You're already checking for NULL pointer below before using the buffer, so all the checked malloc does here is skip the rest of the class initialization, including the part that starts the worker thread.. so instead of a bad malloc causing no SSIM results to be displayed, it would cause the encoder to deadlock.</div>

</div></div></div></blockquote><div><br></div></div><div>aah yes. got it.  </div><div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra">
<div class="gmail_quote">
<div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
     // NOTE: 2 times of numRows because both Encoder and Filter in same queue<br>
     if (!WaveFront::init(m_numRows * 2))<br>
     {<br>
@@ -168,6 +171,8 @@<br>
         assert(0);<br>
     }<br>
     start();<br>
+fail:<br>
+    return;<br>
 }<br>
<br>
 int FrameEncoder::getStreamHeaders(NALUnitEBSP **nalunits)<br>
@@ -535,6 +540,31 @@<br>
         slice->setSaoEnabledFlag((saoParam->bSaoFlag[0] == 1) ? true : false);<br>
     }<br>
<br>
+    /*Compute SSIM if enabled*/<br></blockquote><div><br></div></div><div>added spaces within /* and */ </div><div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



+    if (m_cfg->param.bEnableSsim && ssimBuf)<br>
+    {<br>
+        pixel *rec = (pixel*)m_pic->getPicYuvRec()->getLumaAddr();<br>
+        pixel *org = (pixel*)m_pic->getPicYuvOrg()->getLumaAddr();<br>
+        int stride1 = m_pic->getPicYuvOrg()->getStride();<br>
+        int stride2 = m_pic->getPicYuvRec()->getStride();<br>
+        for (int row = 0; row < m_numRows; row++)<br>
+        {<br>
+            int bEnd = ((row + 1) == (this->m_numRows - 1));<br>
+            int bStart = (row == 0);<br>
+            int minPixY = row * 64 - 4 * !bStart;<br>
+            int maxPixY = (row + 1) * 64 - 4 * !bEnd;<br>
+            int ssim_cnt;<br>
+            x265_emms();<br>
+<br>
+            /* SSIM is done for each row in blocks of 4x4 . The First blocks are offset by 2 pixels to the right<br>
+            * to avoid alignment of ssim blocks with DCT blocks. */<br>
+            minPixY += bStart ? 2 : -6;<br>
+            slice->m_ssim += calculateSSIM(rec + 2 + minPixY * stride1, stride1, org + 2 + minPixY * stride2, stride2,<br>
+                m_cfg->param.sourceWidth - 2, maxPixY - minPixY, ssimBuf, &ssim_cnt);<br></blockquote><div><br></div></div><div>lined up the second line of arguments with the first</div><div><div><div>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+            slice->m_ssimCnt += ssim_cnt;<br>
+        }<br>
+    }<br>
+<br>
     entropyCoder->setBitstream(NULL);<br>
<br>
     // Reconstruction slice<br>
@@ -681,6 +711,39 @@<br>
     delete bitstreamRedirect;<br>
 }<br>
<br>
+/* Function to calculate SSIM for each row */<br>
+float FrameEncoder::calculateSSIM(pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2, int width, int height, void *buf, int *cnt)<br>
+{<br>
+    int z = 0;<br>
+    float ssim = 0.0;<br>
+    ssim_t(*sum0)[4] = (ssim_t(*)[4])buf;<br>
+    ssim_t(*sum1)[4] = sum0 + (width >> 2) + 3;<br>
+    width >>= 2;<br>
+    height >>= 2;<br>
+<br>
+    for (int y = 1; y < height; y++)<br>
+    {<br>
+        for (; z <= y; z++)<br>
+        {<br>
+            void* swap = sum0;<br>
+            sum0 = sum1;<br>
+            sum1 = (ssim_t(*)[4])swap;<br>
+            for (int x = 0; x < width; x += 2)<br>
+            {<br>
+                primitives.ssim_4x4x2_core(&pix1[(4 * x + (z * stride1))], stride1, &pix2[(4 * x + (z * stride2))], stride2, &sum0[x]);<br>
+            }<br>
+        }<br>
+<br>
+        for (int x = 0; x < width - 1; x += 4)<br>
+        {<br>
+            ssim += primitives.ssim_end_4(sum0 + x, sum1 + x, X265_MIN(4, width - x - 1));<br>
+        }<br>
+    }<br>
+<br>
+    *cnt = (height - 1) * (width - 1);<br>
+    return ssim;<br>
+}<br>
+<br>
 void FrameEncoder::encodeSlice(TComOutputBitstream* substreams)<br>
 {<br>
     // choose entropy coder<br>
diff -r 47286888d5a2 -r 3ba555e98be2 source/encoder/frameencoder.h<br>
--- a/source/encoder/frameencoder.h     Tue Oct 08 17:06:57 2013 +0530<br>
+++ b/source/encoder/frameencoder.h     Tue Oct 08 17:12:22 2013 +0530<br>
@@ -145,6 +145,9 @@<br>
     /* called by compressFrame to perform wave-front compression analysis */<br>
     void compressCTURows();<br>
<br>
+    /* called by compressFrame to calculate SSIM for each row . */<br></blockquote><div><br></div></div></div><div>fixed white-space in the comment</div></div></div></div></blockquote><div><br></div></div></div><div>any better way to catch such white space issues before commit? uncrustify doesnt seem to fix all of this.</div>
</div></div></div></blockquote></div><div class="gmail_extra"><br></div>No, it just takes an eye practiced in the art of bikeshedding.<br clear="all"><div><br></div>-- <br>Steve Borho
</div></div>