<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Oct 15, 2013 at 1:56 AM,  <span dir="ltr"><<a href="mailto:santhoshini@multicorewareinc.com" target="_blank">santhoshini@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 Santhoshini Sekar <<a href="mailto:santhoshini@multicorewareinc.com">santhoshini@multicorewareinc.com</a>><br>
# Date 1381817138 -19800<br>
#      Tue Oct 15 11:35:38 2013 +0530<br>
# Node ID 957578be76da25eeab8fb0cf5eaf2a5d0471dd24<br>
# Parent  8ae52f2b159c8378e981e369aa15c4c36db48f7c<br>
PSNR Row wise calculation<br>
<br>
diff -r 8ae52f2b159c -r 957578be76da source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp        Thu Oct 10 01:15:11 2013 -0500<br>
+++ b/source/encoder/encoder.cpp        Tue Oct 15 11:35:38 2013 +0530<br>
@@ -362,109 +362,6 @@<br>
 //       (we do not yet have a switch to disable PSNR reporting)<br>
 //   2 - it would be better to accumulate SSD of each CTU at the end of processCTU() while it is cache-hot<br>
 //       in fact, we almost certainly are already measuring the CTU distortion and not accumulating it<br>
-static UInt64 computeSSD(Pel *fenc, Pel *rec, int stride, int width, int height)<br>
-{<br>
-    UInt64 ssd = 0;<br>
-<br>
-    if ((width | height) & 3)<br>
-    {<br>
-        /* Slow Path */<br>
-        for (int y = 0; y < height; y++)<br>
-        {<br>
-            for (int x = 0; x < width; x++)<br>
-            {<br>
-                int diff = (int)(fenc[x] - rec[x]);<br>
-                ssd += diff * diff;<br>
-            }<br>
-<br>
-            fenc += stride;<br>
-            rec += stride;<br>
-        }<br>
-<br>
-        return ssd;<br>
-    }<br>
-<br>
-    int y = 0;<br>
-    /* Consume Y in chunks of 64 */<br>
-    for (; y + 64 <= height; y += 64)<br>
-    {<br>
-        int x = 0;<br>
-<br>
-        if (!(stride & 31))<br>
-            for (; x + 64 <= width; x += 64)<br>
-            {<br>
-                ssd += primitives.sse_pp[PARTITION_64x64](fenc + x, stride, rec + x, stride);<br>
-            }<br>
-<br>
-        if (!(stride & 15))<br>
-            for (; x + 16 <= width; x += 16)<br>
-            {<br>
-                ssd += primitives.sse_pp[PARTITION_16x64](fenc + x, stride, rec + x, stride);<br>
-            }<br>
-<br>
-        for (; x + 4 <= width; x += 4)<br>
-        {<br>
-            ssd += primitives.sse_pp[PARTITION_4x64](fenc + x, stride, rec + x, stride);<br>
-        }<br>
-<br>
-        fenc += stride * 64;<br>
-        rec += stride * 64;<br>
-    }<br>
-<br>
-    /* Consume Y in chunks of 16 */<br>
-    for (; y + 16 <= height; y += 16)<br>
-    {<br>
-        int x = 0;<br>
-<br>
-        if (!(stride & 31))<br>
-            for (; x + 64 <= width; x += 64)<br>
-            {<br>
-                ssd += primitives.sse_pp[PARTITION_64x16](fenc + x, stride, rec + x, stride);<br>
-            }<br>
-<br>
-        if (!(stride & 15))<br>
-            for (; x + 16 <= width; x += 16)<br>
-            {<br>
-                ssd += primitives.sse_pp[PARTITION_16x16](fenc + x, stride, rec + x, stride);<br>
-            }<br>
-<br>
-        for (; x + 4 <= width; x += 4)<br>
-        {<br>
-            ssd += primitives.sse_pp[PARTITION_4x16](fenc + x, stride, rec + x, stride);<br>
-        }<br>
-<br>
-        fenc += stride * 16;<br>
-        rec += stride * 16;<br>
-    }<br>
-<br>
-    /* Consume Y in chunks of 4 */<br>
-    for (; y + 4 <= height; y += 4)<br>
-    {<br>
-        int x = 0;<br>
-<br>
-        if (!(stride & 31))<br>
-            for (; x + 64 <= width; x += 64)<br>
-            {<br>
-                ssd += primitives.sse_pp[PARTITION_64x4](fenc + x, stride, rec + x, stride);<br>
-            }<br>
-<br>
-        if (!(stride & 15))<br>
-            for (; x + 16 <= width; x += 16)<br>
-            {<br>
-                ssd += primitives.sse_pp[PARTITION_16x4](fenc + x, stride, rec + x, stride);<br>
-            }<br>
-<br>
-        for (; x + 4 <= width; x += 4)<br>
-        {<br>
-            ssd += primitives.sse_pp[PARTITION_4x4](fenc + x, stride, rec + x, stride);<br>
-        }<br>
-<br>
-        fenc += stride * 4;<br>
-        rec += stride * 4;<br>
-    }<br>
-<br>
-    return ssd;<br>
-}<br>
<br>
 /**<br>
  * Produce an ascii(hex) representation of picture digest.<br>
@@ -496,27 +393,17 @@<br>
 uint64_t Encoder::calculateHashAndPSNR(TComPic* pic, NALUnitEBSP **nalunits)<br>
 {<br>
     TComPicYuv* recon = pic->getPicYuvRec();<br>
-    TComPicYuv* orig  = pic->getPicYuvOrg();<br>
<br>
-    //===== calculate PSNR =====<br>
-    int stride = recon->getStride();<br>
     int width  = recon->getWidth() - getPad(0);<br>
     int height = recon->getHeight() - getPad(1);<br>
     int size = width * height;<br>
<br>
-    UInt64 ssdY = computeSSD(orig->getLumaAddr(), recon->getLumaAddr(), stride, width, height);<br>
-<br>
-    height >>= 1;<br>
-    width  >>= 1;<br>
-    stride = recon->getCStride();<br>
-<br>
-    UInt64 ssdU = computeSSD(orig->getCbAddr(), recon->getCbAddr(), stride, width, height);<br>
-    UInt64 ssdV = computeSSD(orig->getCrAddr(), recon->getCrAddr(), stride, width, height);<br>
-<br>
     int maxvalY = 255 << (X265_DEPTH - 8);<br>
     int maxvalC = 255 << (X265_DEPTH - 8);<br>
     double refValueY = (double)maxvalY * maxvalY * size;<br>
     double refValueC = (double)maxvalC * maxvalC * size / 4.0;<br>
+    UInt64 ssdY,ssdU,ssdV;<br></blockquote><div> </div><div>white-space</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    m_frameEncoder->reportStatistics(ssdY, ssdU, ssdV);<br></blockquote><div><br></div><div>the problem is here, m_frameEncoder is pointing to the *next" frame encoder by this point, not the one which encoded this picture.</div>
<div><br></div><div>I recommend moving the YUV SSD accumulators from frameFilter to TComPic and then right here you can dereference TComPic->m_SSDY, etc.  I think this will simplify a few other things.</div><div> <br></div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
     double psnrY = (ssdY ? 10.0 * log10(refValueY / (double)ssdY) : 99.99);<br>
     double psnrU = (ssdU ? 10.0 * log10(refValueC / (double)ssdU) : 99.99);<br>
     double psnrV = (ssdV ? 10.0 * log10(refValueC / (double)ssdV) : 99.99);<br>
diff -r 8ae52f2b159c -r 957578be76da source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp   Thu Oct 10 01:15:11 2013 -0500<br>
+++ b/source/encoder/frameencoder.cpp   Tue Oct 15 11:35:38 2013 +0530<br>
@@ -1115,3 +1115,10 @@<br>
<br>
     return NULL;<br>
 }<br>
+<br>
+void FrameEncoder::reportStatistics(UInt64 &ssdY, UInt64 &ssdU, UInt64 &ssdV)<br>
+{<br>
+    ssdY = m_frameFilter.m_SSDY;<br>
+    ssdU = m_frameFilter.m_SSDU;<br>
+    ssdV = m_frameFilter.m_SSDV;<br>
+}<br>
diff -r 8ae52f2b159c -r 957578be76da source/encoder/frameencoder.h<br>
--- a/source/encoder/frameencoder.h     Thu Oct 10 01:15:11 2013 -0500<br>
+++ b/source/encoder/frameencoder.h     Tue Oct 15 11:35:38 2013 +0530<br>
@@ -113,6 +113,8 @@<br>
         }<br>
     }<br>
<br>
+    void reportStatistics(UInt64 &ssdY, UInt64 &ssdU, UInt64 &ssdV);<br>
+<br>
     TEncEntropy* getEntropyCoder(int row)      { return &this->m_rows[row].m_entropyCoder; }<br>
<br>
     TEncSbac*    getSbacCoder(int row)         { return &this->m_rows[row].m_sbacCoder; }<br>
diff -r 8ae52f2b159c -r 957578be76da source/encoder/framefilter.cpp<br>
--- a/source/encoder/framefilter.cpp    Thu Oct 10 01:15:11 2013 -0500<br>
+++ b/source/encoder/framefilter.cpp    Tue Oct 15 11:35:38 2013 +0530<br>
@@ -36,6 +36,9 @@<br>
     : m_cfg(NULL)<br>
     , m_pic(NULL)<br>
 {<br>
+    m_SSDY = 0;<br>
+    m_SSDU = 0;<br>
+    m_SSDV = 0;<br>
 }<br>
<br>
 void FrameFilter::destroy()<br>
@@ -86,6 +89,9 @@<br>
     m_entropyCoder.setEntropyCoder(&m_rdGoOnSbacCoder, pic->getSlice());<br>
     m_entropyCoder.setBitstream(&m_bitCounter);<br>
     m_rdGoOnBinCodersCABAC.m_fracBits = 0;<br>
+    m_SSDY=0;<br>
+    m_SSDU=0;<br>
+    m_SSDV=0;<br></blockquote><div> </div><div>white-space </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
     if (m_cfg->param.bEnableSAO)<br>
     {<br>
@@ -264,6 +270,144 @@<br>
     {<br>
         m_pic->m_reconRowWait.trigger();<br>
     }<br>
+<br>
+    if (m_cfg->param.bEnablePsnr)<br>
+    {<br>
+        calculatePSNR(lineStartCUAddr, row);<br>
+    }<br>
+}<br>
+<br>
+static UInt64 computeSSD(pixel *fenc, pixel *rec, int stride, int width, int height)<br>
+{<br>
+    UInt64 ssd = 0;<br>
+<br>
+    if ((width | height) & 3)<br>
+    {<br>
+        /* Slow Path */<br>
+        for (int y = 0; y < height; y++)<br>
+        {<br>
+            for (int x = 0; x < width; x++)<br>
+            {<br>
+                int diff = (int)(fenc[x] - rec[x]);<br>
+                ssd += diff * diff;<br>
+            }<br>
+<br>
+            fenc += stride;<br>
+            rec += stride;<br>
+        }<br>
+<br>
+        return ssd;<br>
+    }<br>
+<br>
+    int y = 0;<br>
+    /* Consume Y in chunks of 64 */<br>
+    for (; y + 64 <= height; y += 64)<br>
+    {<br>
+        int x = 0;<br>
+<br>
+        if (!(stride & 31))<br>
+            for (; x + 64 <= width; x += 64)<br>
+            {<br>
+                ssd += primitives.sse_pp[PARTITION_64x64](fenc + x, stride, rec + x, stride);<br>
+            }<br>
+<br>
+        if (!(stride & 15))<br>
+            for (; x + 16 <= width; x += 16)<br>
+            {<br>
+                ssd += primitives.sse_pp[PARTITION_16x64](fenc + x, stride, rec + x, stride);<br>
+            }<br>
+<br>
+        for (; x + 4 <= width; x += 4)<br>
+        {<br>
+            ssd += primitives.sse_pp[PARTITION_4x64](fenc + x, stride, rec + x, stride);<br>
+        }<br>
+<br>
+        fenc += stride * 64;<br>
+        rec += stride * 64;<br>
+    }<br>
+<br>
+    /* Consume Y in chunks of 16 */<br>
+    for (; y + 16 <= height; y += 16)<br>
+    {<br>
+        int x = 0;<br>
+<br>
+        if (!(stride & 31))<br>
+            for (; x + 64 <= width; x += 64)<br>
+            {<br>
+                ssd += primitives.sse_pp[PARTITION_64x16](fenc + x, stride, rec + x, stride);<br>
+            }<br>
+<br>
+        if (!(stride & 15))<br>
+            for (; x + 16 <= width; x += 16)<br>
+            {<br>
+                ssd += primitives.sse_pp[PARTITION_16x16](fenc + x, stride, rec + x, stride);<br>
+            }<br>
+<br>
+        for (; x + 4 <= width; x += 4)<br>
+        {<br>
+            ssd += primitives.sse_pp[PARTITION_4x16](fenc + x, stride, rec + x, stride);<br>
+        }<br>
+<br>
+        fenc += stride * 16;<br>
+        rec += stride * 16;<br>
+    }<br>
+<br>
+    /* Consume Y in chunks of 4 */<br>
+    for (; y + 4 <= height; y += 4)<br>
+    {<br>
+        int x = 0;<br>
+<br>
+        if (!(stride & 31))<br>
+            for (; x + 64 <= width; x += 64)<br>
+            {<br>
+                ssd += primitives.sse_pp[PARTITION_64x4](fenc + x, stride, rec + x, stride);<br>
+            }<br>
+<br>
+        if (!(stride & 15))<br>
+            for (; x + 16 <= width; x += 16)<br>
+            {<br>
+                ssd += primitives.sse_pp[PARTITION_16x4](fenc + x, stride, rec + x, stride);<br>
+            }<br>
+<br>
+        for (; x + 4 <= width; x += 4)<br>
+        {<br>
+            ssd += primitives.sse_pp[PARTITION_4x4](fenc + x, stride, rec + x, stride);<br>
+        }<br>
+<br>
+        fenc += stride * 4;<br>
+        rec += stride * 4;<br>
+    }<br>
+<br>
+    return ssd;<br>
+}<br>
+<br>
+void FrameFilter::calculatePSNR(uint32_t cuAddr, int row)<br>
+{<br>
+    TComPicYuv* recon = m_pic->getPicYuvRec();<br>
+    TComPicYuv* orig  = m_pic->getPicYuvOrg();<br>
+<br>
+    //===== calculate PSNR =====<br>
+    int stride = recon->getStride();<br>
+<br>
+    int width  = recon->getWidth() - m_cfg->getPad(0);<br>
+    int height;<br>
+    if (row == m_numRows - 1)<br>
+        height = ((recon->getHeight() % g_maxCUHeight) ? (recon->getHeight() % g_maxCUHeight) : g_maxCUHeight);<br>
+    else<br>
+        height = g_maxCUHeight;<br>
+<br>
+    UInt64 ssdY = computeSSD(orig->getLumaAddr(cuAddr), recon->getLumaAddr(cuAddr), stride, width, height);<br>
+<br>
+    height >>= 1;<br>
+    width  >>= 1;<br>
+    stride = recon->getCStride();<br>
+<br>
+    UInt64 ssdU = computeSSD(orig->getCbAddr(cuAddr), recon->getCbAddr(cuAddr), stride, width, height);<br>
+    UInt64 ssdV = computeSSD(orig->getCrAddr(cuAddr), recon->getCrAddr(cuAddr), stride, width, height);<br>
+<br>
+    m_SSDY += ssdY;<br>
+    m_SSDU += ssdU;<br>
+    m_SSDV += ssdV;<br>
 }<br>
<br>
 void FrameFilter::processSao(int row)<br>
diff -r 8ae52f2b159c -r 957578be76da source/encoder/framefilter.h<br>
--- a/source/encoder/framefilter.h      Thu Oct 10 01:15:11 2013 -0500<br>
+++ b/source/encoder/framefilter.h      Tue Oct 15 11:35:38 2013 +0530<br>
@@ -53,7 +53,7 @@<br>
     void processRow(int row);<br>
     void processRowPost(int row);<br>
     void processSao(int row);<br>
-<br>
+    void calculatePSNR(uint32_t cu, int row);<br>
 protected:<br>
<br>
     TEncCfg*                    m_cfg;<br>
@@ -72,6 +72,9 @@<br>
     TEncBinCABACCounter         m_rdGoOnBinCodersCABAC;<br>
     TComBitCounter              m_bitCounter;<br>
     TEncSbac*                   m_rdGoOnSbacCoderRow0;  // for bitstream exact only, depends on HM's bug<br>
+    UInt64                      m_SSDY;<br>
+    UInt64                      m_SSDU;<br>
+    UInt64                      m_SSDV;<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>