<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Oct 28, 2013 at 1:23 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 1382937954 -19800<br>
#      Mon Oct 28 10:55:54 2013 +0530<br>
# Node ID f6c9b2e9c7b4bbc0939b17acc41dade41e145fcf<br>
# Parent  ccac3a7d3622b7326443745c1ecae0e2edd3e539<br>
row wise generation of hash in framefilter<br></blockquote><div><br></div><div>queued with a minor re-org, the hash generation should not depend on --psnr being enabled</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
diff -r ccac3a7d3622 -r f6c9b2e9c7b4 source/Lib/TLibCommon/TComPic.h<br>
--- a/source/Lib/TLibCommon/TComPic.h   Fri Oct 25 22:40:09 2013 -0500<br>
+++ b/source/Lib/TLibCommon/TComPic.h   Mon Oct 28 10:55:54 2013 +0530<br>
@@ -44,6 +44,7 @@<br>
 #include "TComPicYuv.h"<br>
 #include "lowres.h"<br>
 #include "threading.h"<br>
+#include "md5.h"<br>
<br>
 namespace x265 {<br>
 // private namespace<br>
@@ -91,6 +92,9 @@<br>
     UInt64                m_SSDV;<br>
     double                m_elapsedCompressTime;<br>
     double                m_frameTime;<br>
+    MD5Context            m_state[3];<br>
+    UInt                  m_crc[3];<br>
+    UInt                  m_checksum[3];<br>
<br>
     TComPic();<br>
     virtual ~TComPic();<br>
diff -r ccac3a7d3622 -r f6c9b2e9c7b4 source/Lib/TLibCommon/TComPicYuv.cpp<br>
--- a/source/Lib/TLibCommon/TComPicYuv.cpp      Fri Oct 25 22:40:09 2013 -0500<br>
+++ b/source/Lib/TLibCommon/TComPicYuv.cpp      Mon Oct 28 10:55:54 2013 +0530<br>
@@ -179,6 +179,17 @@<br>
     delete[] m_buOffsetY;<br>
 }<br>
<br>
+UInt TComPicYuv::getCUHeight(int rowNum)<br>
+{<br>
+    UInt height;<br>
+<br>
+    if (rowNum == m_numCuInHeight - 1)<br>
+        height = ((getHeight() % g_maxCUHeight) ? (getHeight() % g_maxCUHeight) : g_maxCUHeight);<br>
+    else<br>
+        height = g_maxCUHeight;<br>
+    return height;<br>
+}<br>
+<br>
 void  TComPicYuv::copyToPic(TComPicYuv* destPicYuv)<br>
 {<br>
     assert(m_picWidth  == destPicYuv->getWidth());<br>
diff -r ccac3a7d3622 -r f6c9b2e9c7b4 source/Lib/TLibCommon/TComPicYuv.h<br>
--- a/source/Lib/TLibCommon/TComPicYuv.h        Fri Oct 25 22:40:09 2013 -0500<br>
+++ b/source/Lib/TLibCommon/TComPicYuv.h        Mon Oct 28 10:55:54 2013 +0530<br>
@@ -41,6 +41,7 @@<br>
 #include "CommonDef.h"<br>
 #include "TComRom.h"<br>
 #include "x265.h"<br>
+#include "md5.h"<br>
<br>
 namespace x265 {<br>
 // private namespace<br>
@@ -160,6 +161,8 @@<br>
<br>
     Pel*  getCrAddr(int cuAddr, int absZOrderIdx) { return m_picOrgV + m_cuOffsetC[cuAddr] + m_buOffsetC[g_zscanToRaster[absZOrderIdx]]; }<br>
<br>
+    UInt getCUHeight(int rowNum);<br>
+<br>
     // ------------------------------------------------------------------------------------------------<br>
     //  Miscellaneous<br>
     // ------------------------------------------------------------------------------------------------<br>
@@ -175,9 +178,11 @@<br>
     void  dump(char* pFileName, bool bAdd = false);<br>
 }; // END CLASS DEFINITION TComPicYuv<br>
<br>
-void calcChecksum(TComPicYuv & pic, UChar digest[3][16]);<br>
-void calcCRC(TComPicYuv & pic, UChar digest[3][16]);<br>
-void calcMD5(TComPicYuv & pic, UChar digest[3][16]);<br>
+void updateChecksum(const Pel* plane, UInt& checksumVal, UInt height, UInt width, UInt stride, int row, UInt cu_Height);<br>
+void updateCRC(const Pel* plane, UInt& crcVal, UInt height, UInt width, UInt stride);<br>
+void crcFinish(UInt& crc, UChar digest[16]);<br>
+void checksumFinish(UInt& checksum, UChar digest[16]);<br>
+void updateMD5Plane(MD5Context& md5, const Pel* plane, UInt width, UInt height, UInt stride);<br>
 }<br>
 //! \}<br>
<br>
diff -r ccac3a7d3622 -r f6c9b2e9c7b4 source/Lib/TLibCommon/TComPicYuvMD5.cpp<br>
--- a/source/Lib/TLibCommon/TComPicYuvMD5.cpp   Fri Oct 25 22:40:09 2013 -0500<br>
+++ b/source/Lib/TLibCommon/TComPicYuvMD5.cpp   Mon Oct 28 10:55:54 2013 +0530<br>
@@ -43,7 +43,7 @@<br>
  * OUTBIT_BITDEPTH_DIV8.<br>
  */<br>
 template<UInt OUTPUT_BITDEPTH_DIV8><br>
-static void md5_block(MD5& md5, const Pel* plane, UInt n)<br>
+static void md5_block(MD5Context& md5, const Pel* plane, UInt n)<br>
 {<br>
     /* create a 64 byte buffer for packing Pel's into */<br>
     UChar buf[64 / OUTPUT_BITDEPTH_DIV8][OUTPUT_BITDEPTH_DIV8];<br>
@@ -58,7 +58,7 @@<br>
         }<br>
     }<br>
<br>
-    md5.update((UChar*)buf, n * OUTPUT_BITDEPTH_DIV8);<br>
+    MD5Update(&md5, (UChar*)buf, n * OUTPUT_BITDEPTH_DIV8);<br>
 }<br>
<br>
 /**<br>
@@ -66,7 +66,7 @@<br>
  * is adjusted to OUTBIT_BITDEPTH_DIV8.<br>
  */<br>
 template<UInt OUTPUT_BITDEPTH_DIV8><br>
-static void md5_plane(MD5& md5, const Pel* plane, UInt width, UInt height, UInt stride)<br>
+static void md5_plane(MD5Context& md5, const Pel* plane, UInt width, UInt height, UInt stride)<br>
 {<br>
     /* N is the number of samples to process per md5 update.<br>
      * All N samples must fit in buf */<br>
@@ -88,11 +88,10 @@<br>
     }<br>
 }<br>
<br>
-static void compCRC(const Pel* plane, UInt width, UInt height, UInt stride, UChar digest[16])<br>
+void updateCRC(const Pel* plane, UInt& crcVal, UInt height, UInt width, UInt stride)<br>
 {<br>
     UInt crcMsb;<br>
     UInt bitVal;<br>
-    UInt crcVal = 0xffff;<br>
     UInt bitIdx;<br>
<br>
     for (UInt y = 0; y < height; y++)<br>
@@ -119,106 +118,55 @@<br>
             }<br>
         }<br>
     }<br>
-<br>
-    for (bitIdx = 0; bitIdx < 16; bitIdx++)<br>
-    {<br>
-        crcMsb = (crcVal >> 15) & 1;<br>
-        crcVal = ((crcVal << 1) & 0xffff) ^ (crcMsb * 0x1021);<br>
-    }<br>
-<br>
-    digest[0] = (crcVal >> 8)  & 0xff;<br>
-    digest[1] =  crcVal      & 0xff;<br>
 }<br>
<br>
-void calcCRC(TComPicYuv& pic, UChar digest[3][16])<br>
+void crcFinish(UInt& crcVal, UChar digest[16])<br>
+{<br>
+    UInt crcMsb;<br>
+    for (int bitIdx = 0; bitIdx < 16; bitIdx++)<br>
+    {<br>
+        crcMsb = (crcVal >> 15) & 1;<br>
+        crcVal = ((crcVal << 1) & 0xffff) ^ (crcMsb * 0x1021);<br>
+    }<br>
+    digest[0] = (crcVal >> 8)  & 0xff;<br>
+    digest[1] =  crcVal        & 0xff;<br>
+}<br>
+<br>
+void updateChecksum(const Pel* plane, UInt& checksumVal, UInt height, UInt width, UInt stride, int row, UInt cu_Height)<br>
 {<br>
-    UInt width = pic.getWidth();<br>
-    UInt height = pic.getHeight();<br>
-    UInt stride = pic.getStride();<br>
-<br>
-    compCRC(pic.getLumaAddr(), width, height, stride, digest[0]);<br>
-<br>
-    width >>= 1;<br>
-    height >>= 1;<br>
-    stride = pic.getCStride();<br>
-<br>
-    compCRC(pic.getCbAddr(), width, height, stride, digest[1]);<br>
-    compCRC(pic.getCrAddr(), width, height, stride, digest[2]);<br>
-}<br>
-<br>
-static void compChecksum(const Pel* plane, UInt width, UInt height, UInt stride, UChar digest[16])<br>
-{<br>
-    UInt checksum = 0;<br>
     UChar xor_mask;<br>
<br>
-    for (UInt y = 0; y < height; y++)<br>
+    for (UInt y = row * cu_Height; y < ((row * cu_Height) + height); y++)<br>
     {<br>
         for (UInt x = 0; x < width; x++)<br>
         {<br>
             xor_mask = (x & 0xff) ^ (y & 0xff) ^ (x >> 8) ^ (y >> 8);<br>
-            checksum = (checksum + ((plane[y * stride + x] & 0xff) ^ xor_mask)) & 0xffffffff;<br>
+            checksumVal = (checksumVal + ((plane[y * stride + x] & 0xff) ^ xor_mask)) & 0xffffffff;<br>
<br>
             if (X265_DEPTH > 8)<br>
             {<br>
-                checksum = (checksum + ((plane[y * stride + x] >> 7 >> 1) ^ xor_mask)) & 0xffffffff;<br>
+                checksumVal = (checksumVal + ((plane[y * stride + x] >> 7 >> 1) ^ xor_mask)) & 0xffffffff;<br>
             }<br>
         }<br>
     }<br>
-<br>
-    digest[0] = (checksum >> 24) & 0xff;<br>
-    digest[1] = (checksum >> 16) & 0xff;<br>
-    digest[2] = (checksum >> 8)  & 0xff;<br>
-    digest[3] =  checksum      & 0xff;<br>
 }<br>
<br>
-void calcChecksum(TComPicYuv& pic, UChar digest[3][16])<br>
-{<br>
-    UInt width = pic.getWidth();<br>
-    UInt height = pic.getHeight();<br>
-    UInt stride = pic.getStride();<br>
-<br>
-    compChecksum(pic.getLumaAddr(), width, height, stride, digest[0]);<br>
-<br>
-    width >>= 1;<br>
-    height >>= 1;<br>
-    stride = pic.getCStride();<br>
-<br>
-    compChecksum(pic.getCbAddr(), width, height, stride, digest[1]);<br>
-    compChecksum(pic.getCrAddr(), width, height, stride, digest[2]);<br>
+void checksumFinish(UInt& checksum, UChar digest[16])<br>
+{<br>
+    digest[0] = (checksum >> 24) & 0xff;<br>
+    digest[1] = (checksum >> 16) & 0xff;<br>
+    digest[2] = (checksum >> 8)  & 0xff;<br>
+    digest[3] =  checksum        & 0xff;<br>
 }<br>
<br>
-/**<br>
- * Calculate the MD5sum of pic, storing the result in digest.<br>
- * MD5 calculation is performed on Y' then Cb, then Cr; each in raster order.<br>
- * Pel data is inserted into the MD5 function in little-endian byte order,<br>
- * using sufficient bytes to represent the picture bitdepth.  Eg, 10bit data<br>
- * uses little-endian two byte words; 8bit data uses single byte words.<br>
- */<br>
-void calcMD5(TComPicYuv& pic, UChar digest[3][16])<br>
+void updateMD5Plane(MD5Context& md5, const Pel* plane, UInt width, UInt height, UInt stride)<br>
 {<br>
     /* choose an md5_plane packing function based on the system bitdepth */<br>
-    typedef void (*MD5PlaneFunc)(MD5&, const Pel*, UInt, UInt, UInt);<br>
+    typedef void (*MD5PlaneFunc)(MD5Context&, const Pel*, UInt, UInt, UInt);<br>
     MD5PlaneFunc md5_plane_func;<br>
     md5_plane_func = X265_DEPTH <= 8 ? (MD5PlaneFunc)md5_plane<1> : (MD5PlaneFunc)md5_plane<2>;<br>
<br>
-    MD5 md5Y, md5U, md5V;<br>
-    UInt width = pic.getWidth();<br>
-    UInt height = pic.getHeight();<br>
-    UInt stride = pic.getStride();<br>
-<br>
-    md5_plane_func(md5Y, pic.getLumaAddr(), width, height, stride);<br>
-    md5Y.finalize(digest[0]);<br>
-<br>
-    md5_plane_func = X265_DEPTH <= 8 ? (MD5PlaneFunc)md5_plane<1> : (MD5PlaneFunc)md5_plane<2>;<br>
-    width >>= 1;<br>
-    height >>= 1;<br>
-    stride = pic.getCStride();<br>
-<br>
-    md5_plane_func(md5U, pic.getCbAddr(), width, height, stride);<br>
-    md5U.finalize(digest[1]);<br>
-<br>
-    md5_plane_func(md5V, pic.getCrAddr(), width, height, stride);<br>
-    md5V.finalize(digest[2]);<br>
+    md5_plane_func(md5, plane, width, height, stride);<br>
 }<br>
 }<br>
 //! \}<br>
diff -r ccac3a7d3622 -r f6c9b2e9c7b4 source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp        Fri Oct 25 22:40:09 2013 -0500<br>
+++ b/source/encoder/encoder.cpp        Mon Oct 28 10:55:54 2013 +0530<br>
@@ -499,19 +499,28 @@<br>
         {<br>
             /* calculate MD5sum for entire reconstructed picture */<br>
             sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;<br>
-            calcMD5(*recon, sei_recon_picture_digest.digest);<br>
+            for (int i = 0; i < 3; i++)<br>
+            {<br>
+                MD5Final(&(pic->m_state[i]), sei_recon_picture_digest.digest[i]);<br>
+            }<br>
             digestStr = digestToString(sei_recon_picture_digest.digest, 16);<br>
         }<br>
         else if (param.decodedPictureHashSEI == 2)<br>
         {<br>
             sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;<br>
-            calcCRC(*recon, sei_recon_picture_digest.digest);<br>
+            for (int i = 0; i < 3; i++)<br>
+            {<br>
+                crcFinish((pic->m_crc[i]), sei_recon_picture_digest.digest[i]);<br>
+            }<br>
             digestStr = digestToString(sei_recon_picture_digest.digest, 2);<br>
         }<br>
         else if (param.decodedPictureHashSEI == 3)<br>
         {<br>
             sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;<br>
-            calcChecksum(*recon, sei_recon_picture_digest.digest);<br>
+            for (int i = 0; i < 3; i++)<br>
+            {<br>
+                checksumFinish(pic->m_checksum[i], sei_recon_picture_digest.digest[i]);<br>
+            }<br>
             digestStr = digestToString(sei_recon_picture_digest.digest, 4);<br>
         }<br>
<br>
diff -r ccac3a7d3622 -r f6c9b2e9c7b4 source/encoder/framefilter.cpp<br>
--- a/source/encoder/framefilter.cpp    Fri Oct 25 22:40:09 2013 -0500<br>
+++ b/source/encoder/framefilter.cpp    Mon Oct 28 10:55:54 2013 +0530<br>
@@ -426,6 +426,65 @@<br>
     m_pic->m_SSDY += ssdY;<br>
     m_pic->m_SSDU += ssdU;<br>
     m_pic->m_SSDV += ssdV;<br>
+<br>
+    if (m_cfg->param.decodedPictureHashSEI == 1)<br>
+    {<br>
+        UInt width = recon->getWidth();<br>
+        UInt height = recon->getCUHeight(row);<br>
+        UInt stride = recon->getStride();<br>
+<br>
+        if (row == 0)<br>
+        {<br>
+            for (int i = 0; i < 3; i++)<br>
+                MD5Init(&(m_pic->m_state[i]));<br>
+        }<br>
+<br>
+        updateMD5Plane(m_pic->m_state[0], recon->getLumaAddr(cuAddr), width, height, stride);<br>
+<br>
+        width >>= 1;<br>
+        height >>= 1;<br>
+        stride = recon->getCStride();<br>
+<br>
+        updateMD5Plane(m_pic->m_state[1], recon->getCbAddr(cuAddr), width, height, stride);<br>
+<br>
+        updateMD5Plane(m_pic->m_state[2], recon->getCrAddr(cuAddr), width, height, stride);<br>
+    }<br>
+    else if (m_cfg->param.decodedPictureHashSEI == 2)<br>
+    {<br>
+        UInt width = recon->getWidth();<br>
+        UInt height = recon->getCUHeight(row);<br>
+        UInt stride = recon->getStride();<br>
+        if (row == 0)<br>
+        {<br>
+            m_pic->m_crc[0] = m_pic->m_crc[1] = m_pic->m_crc[2] = 0xffff;<br>
+        }<br>
+        updateCRC(recon->getLumaAddr(cuAddr), m_pic->m_crc[0], height, width, stride);<br>
+<br>
+        width >>= 1;<br>
+        height >>= 1;<br>
+        stride = recon->getCStride();<br>
+<br>
+        updateCRC(recon->getCbAddr(cuAddr), m_pic->m_crc[1], height, width, stride);<br>
+        updateCRC(recon->getCrAddr(cuAddr), m_pic->m_crc[2], height, width, stride);<br>
+    }<br>
+    else if (m_cfg->param.decodedPictureHashSEI == 3)<br>
+    {<br>
+        UInt width = recon->getWidth();<br>
+        UInt height = recon->getCUHeight(row);<br>
+        UInt stride = recon->getStride();<br>
+        UInt cuHeight = g_maxCUHeight;<br>
+        if (row == 0)<br>
+        {<br>
+            m_pic->m_checksum[0] = m_pic->m_checksum[1] = m_pic->m_checksum[2] = 0;<br>
+        }<br>
+        updateChecksum(recon->getLumaAddr(), m_pic->m_checksum[0], height, width, stride, row, cuHeight);<br>
+        width >>= 1;<br>
+        height >>= 1;<br>
+        stride = recon->getCStride();<br>
+        cuHeight >>= 1;<br>
+        updateChecksum(recon->getCbAddr(), m_pic->m_checksum[1], height, width, stride, row, cuHeight);<br>
+        updateChecksum(recon->getCrAddr(), m_pic->m_checksum[2], height, width, stride, row, cuHeight);<br>
+    }<br>
 }<br>
<br>
 /* Function to calculate SSIM for each row */<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>