[x265] [PATCH] row wise generation of hash in framefilter

santhoshini at multicorewareinc.com santhoshini at multicorewareinc.com
Mon Oct 28 07:23:35 CET 2013


# HG changeset patch
# User Santhoshini Sekar <santhoshini at multicorewareinc.com>
# Date 1382937954 -19800
#      Mon Oct 28 10:55:54 2013 +0530
# Node ID f6c9b2e9c7b4bbc0939b17acc41dade41e145fcf
# Parent  ccac3a7d3622b7326443745c1ecae0e2edd3e539
row wise generation of hash in framefilter

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


More information about the x265-devel mailing list