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

Steve Borho steve at borho.org
Mon Oct 28 17:48:03 CET 2013


On Mon, Oct 28, 2013 at 1:23 AM, <santhoshini at multicorewareinc.com> wrote:

> # 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
>

queued with a minor re-org, the hash generation should not depend on --psnr
being enabled


>
> 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 */
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>



-- 
Steve Borho
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20131028/bb436233/attachment-0001.html>


More information about the x265-devel mailing list