<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Sep 27, 2013 at 11:52 PM, 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 1380343885 -19800<br>
#      Sat Sep 28 10:21:25 2013 +0530<br>
# Node ID b1539ccab7bab1708433a9b8b18f5f8c090b1810<br>
# Parent  a8b00de495520f00a4648dac5d111e40b5570ca3<br>
integrated ssim computation for each CTURow<br>
<br>
diff -r a8b00de49552 -r b1539ccab7ba source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp   Sat Sep 28 10:18:23 2013 +0530<br>
+++ b/source/encoder/frameencoder.cpp   Sat Sep 28 10:21:25 2013 +0530<br>
@@ -91,6 +91,9 @@<br>
         delete[] m_rows;<br>
     }<br>
<br>
+    if (tempBuf)<br></blockquote><div><br></div><div>X265_FREE does the NULL check for you</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        X265_FREE(tempBuf);<br>
+<br>
     m_frameFilter.destroy();<br>
<br>
     // wait for worker thread to exit<br>
@@ -106,6 +109,8 @@<br>
                         2 : (m_cfg->param.bEnableSAO || m_cfg->param.bEnableLoopFilter ? 1 : 0);<br>
<br>
     m_rows = new CTURow[m_numRows];<br>
+    if(m_cfg->param.bEnableSsim)<br></blockquote><div><br></div><div>white-space</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        CHECKED_MALLOC(tempBuf, int, m_cfg->param.bEnableSsim * 8 * (m_cfg->param.sourceWidth/4 + 3));<br>
     for (int i = 0; i < m_numRows; ++i)<br>
     {<br>
         m_rows[i].create(top);<br>
@@ -168,6 +173,8 @@<br>
         assert(0);<br>
     }<br>
     start();<br>
+fail:<br>
+    return;<br>
 }<br>
<br>
 int FrameEncoder::getStreamHeaders(NALUnitEBSP **nalunits)<br>
@@ -540,6 +547,31 @@<br>
         slice->setSaoEnabledFlag((saoParam->bSaoFlag[0] == 1) ? true : false);<br>
     }<br>
<br>
+    /*Compute SSIM if enabled*/<br>
+       if(m_cfg->param.bEnableSsim)<br></blockquote><div>white-space </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+       {<br>
+            pixel *rec = (pixel*)m_pic->getPicYuvRec()->getLumaAddr();<br>
+            pixel *org = (pixel*)m_pic->getPicYuvOrg()->getLumaAddr();<br>
+            int stride = m_pic->getPicYuvOrg()->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>
+               /* offset by 2 pixels to avoid alignment of ssim blocks with dct blocks,<br>
+               * and overlap by 4 */<br></blockquote><div><br></div><div>do you understand what this comment implies?  I don't and we probably should</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+                minPixY += bStart ? 2 : -6;<br>
+                slice->m_ssim +=<br>
+                calculateSSIM(<br>
+                rec + 2 + minPixY * stride, stride,<br>
+                org + 2 + minPixY * stride, stride,<br>
+                m_cfg->param.sourceWidth-2, maxPixY - minPixY, tempBuf, &ssim_cnt );<br></blockquote><div><br></div><div>formatting</div><div> </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>
     entropyCoder->setBitstream(NULL);<br>
<br>
     // Reconstruction slice<br>
@@ -687,6 +719,38 @@<br>
     delete bitstreamRedirect;<br>
 }<br>
<br>
+/* Function to calculate SSIM for each row */<br>
+float FrameEncoder::calculateSSIM( pixel *pix1, intptr_t stride1,<br>
+                                   pixel *pix2, intptr_t stride2,<br>
+                                   int width, int height, void *buf, int *cnt )<br></blockquote><div>coding-style </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+{<br>
+    int z = 0;<br>
+    float ssim = 0.0;<br>
+    int (*sum0)[4] = (int (*)[4]) buf;<br>
+    int (*sum1)[4] = sum0 + (width >> 2) + 3;<br>
+    width >>= 2;<br>
+    height >>= 2;<br>
+    for( int y = 1; y < height; y++ )<br>
+    {<br>
+        for( ; z <= y; z++ )<br>
+        {<br>
+            void* swap = sum0;<br>
+            sum0 = sum1;<br>
+            sum1 = (int (*)[4])swap;<br>
+            for( int x = 0; x < width; x+=2 )<br>
+            {<br>
+                if(m_pic->getPicYuvRec() == 0 || x== 98){<br>
+                    int nullaalret = 1; nullaalret++;<br>
+                }<br>
+                primitives.ssim4x4x2Core( &pix1[4*(x+z*stride1)], stride1, &pix2[4*(x+z*stride2)], stride2, &sum0[x] );<br>
+            }<br>
+        }<br>
+        for( int x = 0; x < width-1; x += 4 )<br>
+            ssim += primitives.ssimEnd4( sum0+x, sum1+x, X265_MIN(4,width-x-1) );<br>
+    }<br>
+    *cnt = (height-1) * (width-1);<br>
+    return ssim;<br>
+}<br>
 void FrameEncoder::encodeSlice(TComOutputBitstream* substreams)<br>
 {<br>
     // choose entropy coder<br>
diff -r a8b00de49552 -r b1539ccab7ba source/encoder/frameencoder.h<br>
--- a/source/encoder/frameencoder.h     Sat Sep 28 10:18:23 2013 +0530<br>
+++ b/source/encoder/frameencoder.h     Sat Sep 28 10:21:25 2013 +0530<br>
@@ -153,6 +153,10 @@<br>
     // worker thread<br>
     void threadMain();<br>
<br>
+    /* called by compressFrame to calculate SSIM for each row after applying deblock filter and SAO. */<br>
+    float calculateSSIM(pixel *pix1, intptr_t stride1,pixel *pix2, intptr_t stride2,<br>
+                        int width, int height, void *buf, int *cnt );<br>
+<br>
     Event                    m_enable;<br>
     Event                    m_done;<br>
     bool                     m_threadActive;<br>
@@ -185,6 +189,9 @@<br>
     int                      m_filterRowDelay;<br>
     CTURow*                  m_rows;<br>
     Event                    m_completionEvent;<br>
+<br>
+    /* Temp Storage that doesnt need repeated malloc */<br>
+    void *                   tempBuf;<br>
 };<br>
 }<br>
<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>Steve Borho
</div></div>