[x265] [PATCH] PSNR Row wise calculation

Steve Borho steve at borho.org
Tue Oct 15 09:57:06 CEST 2013


On Tue, Oct 15, 2013 at 1:56 AM, <santhoshini at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Santhoshini Sekar <santhoshini at multicorewareinc.com>
> # Date 1381817138 -19800
> #      Tue Oct 15 11:35:38 2013 +0530
> # Node ID 957578be76da25eeab8fb0cf5eaf2a5d0471dd24
> # Parent  8ae52f2b159c8378e981e369aa15c4c36db48f7c
> PSNR Row wise calculation
>
> diff -r 8ae52f2b159c -r 957578be76da source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp        Thu Oct 10 01:15:11 2013 -0500
> +++ b/source/encoder/encoder.cpp        Tue Oct 15 11:35:38 2013 +0530
> @@ -362,109 +362,6 @@
>  //       (we do not yet have a switch to disable PSNR reporting)
>  //   2 - it would be better to accumulate SSD of each CTU at the end of
> processCTU() while it is cache-hot
>  //       in fact, we almost certainly are already measuring the CTU
> distortion and not accumulating it
> -static UInt64 computeSSD(Pel *fenc, Pel *rec, int stride, int width, int
> height)
> -{
> -    UInt64 ssd = 0;
> -
> -    if ((width | height) & 3)
> -    {
> -        /* Slow Path */
> -        for (int y = 0; y < height; y++)
> -        {
> -            for (int x = 0; x < width; x++)
> -            {
> -                int diff = (int)(fenc[x] - rec[x]);
> -                ssd += diff * diff;
> -            }
> -
> -            fenc += stride;
> -            rec += stride;
> -        }
> -
> -        return ssd;
> -    }
> -
> -    int y = 0;
> -    /* Consume Y in chunks of 64 */
> -    for (; y + 64 <= height; y += 64)
> -    {
> -        int x = 0;
> -
> -        if (!(stride & 31))
> -            for (; x + 64 <= width; x += 64)
> -            {
> -                ssd += primitives.sse_pp[PARTITION_64x64](fenc + x,
> stride, rec + x, stride);
> -            }
> -
> -        if (!(stride & 15))
> -            for (; x + 16 <= width; x += 16)
> -            {
> -                ssd += primitives.sse_pp[PARTITION_16x64](fenc + x,
> stride, rec + x, stride);
> -            }
> -
> -        for (; x + 4 <= width; x += 4)
> -        {
> -            ssd += primitives.sse_pp[PARTITION_4x64](fenc + x, stride,
> rec + x, stride);
> -        }
> -
> -        fenc += stride * 64;
> -        rec += stride * 64;
> -    }
> -
> -    /* Consume Y in chunks of 16 */
> -    for (; y + 16 <= height; y += 16)
> -    {
> -        int x = 0;
> -
> -        if (!(stride & 31))
> -            for (; x + 64 <= width; x += 64)
> -            {
> -                ssd += primitives.sse_pp[PARTITION_64x16](fenc + x,
> stride, rec + x, stride);
> -            }
> -
> -        if (!(stride & 15))
> -            for (; x + 16 <= width; x += 16)
> -            {
> -                ssd += primitives.sse_pp[PARTITION_16x16](fenc + x,
> stride, rec + x, stride);
> -            }
> -
> -        for (; x + 4 <= width; x += 4)
> -        {
> -            ssd += primitives.sse_pp[PARTITION_4x16](fenc + x, stride,
> rec + x, stride);
> -        }
> -
> -        fenc += stride * 16;
> -        rec += stride * 16;
> -    }
> -
> -    /* Consume Y in chunks of 4 */
> -    for (; y + 4 <= height; y += 4)
> -    {
> -        int x = 0;
> -
> -        if (!(stride & 31))
> -            for (; x + 64 <= width; x += 64)
> -            {
> -                ssd += primitives.sse_pp[PARTITION_64x4](fenc + x,
> stride, rec + x, stride);
> -            }
> -
> -        if (!(stride & 15))
> -            for (; x + 16 <= width; x += 16)
> -            {
> -                ssd += primitives.sse_pp[PARTITION_16x4](fenc + x,
> stride, rec + x, stride);
> -            }
> -
> -        for (; x + 4 <= width; x += 4)
> -        {
> -            ssd += primitives.sse_pp[PARTITION_4x4](fenc + x, stride, rec
> + x, stride);
> -        }
> -
> -        fenc += stride * 4;
> -        rec += stride * 4;
> -    }
> -
> -    return ssd;
> -}
>
>  /**
>   * Produce an ascii(hex) representation of picture digest.
> @@ -496,27 +393,17 @@
>  uint64_t Encoder::calculateHashAndPSNR(TComPic* pic, NALUnitEBSP
> **nalunits)
>  {
>      TComPicYuv* recon = pic->getPicYuvRec();
> -    TComPicYuv* orig  = pic->getPicYuvOrg();
>
> -    //===== calculate PSNR =====
> -    int stride = recon->getStride();
>      int width  = recon->getWidth() - getPad(0);
>      int height = recon->getHeight() - getPad(1);
>      int size = width * height;
>
> -    UInt64 ssdY = computeSSD(orig->getLumaAddr(), recon->getLumaAddr(),
> stride, width, height);
> -
> -    height >>= 1;
> -    width  >>= 1;
> -    stride = recon->getCStride();
> -
> -    UInt64 ssdU = computeSSD(orig->getCbAddr(), recon->getCbAddr(),
> stride, width, height);
> -    UInt64 ssdV = computeSSD(orig->getCrAddr(), recon->getCrAddr(),
> stride, width, height);
> -
>      int maxvalY = 255 << (X265_DEPTH - 8);
>      int maxvalC = 255 << (X265_DEPTH - 8);
>      double refValueY = (double)maxvalY * maxvalY * size;
>      double refValueC = (double)maxvalC * maxvalC * size / 4.0;
> +    UInt64 ssdY,ssdU,ssdV;
>

white-space

+    m_frameEncoder->reportStatistics(ssdY, ssdU, ssdV);
>

the problem is here, m_frameEncoder is pointing to the *next" frame encoder
by this point, not the one which encoded this picture.

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.


>      double psnrY = (ssdY ? 10.0 * log10(refValueY / (double)ssdY) :
> 99.99);
>      double psnrU = (ssdU ? 10.0 * log10(refValueC / (double)ssdU) :
> 99.99);
>      double psnrV = (ssdV ? 10.0 * log10(refValueC / (double)ssdV) :
> 99.99);
> diff -r 8ae52f2b159c -r 957578be76da source/encoder/frameencoder.cpp
> --- a/source/encoder/frameencoder.cpp   Thu Oct 10 01:15:11 2013 -0500
> +++ b/source/encoder/frameencoder.cpp   Tue Oct 15 11:35:38 2013 +0530
> @@ -1115,3 +1115,10 @@
>
>      return NULL;
>  }
> +
> +void FrameEncoder::reportStatistics(UInt64 &ssdY, UInt64 &ssdU, UInt64
> &ssdV)
> +{
> +    ssdY = m_frameFilter.m_SSDY;
> +    ssdU = m_frameFilter.m_SSDU;
> +    ssdV = m_frameFilter.m_SSDV;
> +}
> diff -r 8ae52f2b159c -r 957578be76da source/encoder/frameencoder.h
> --- a/source/encoder/frameencoder.h     Thu Oct 10 01:15:11 2013 -0500
> +++ b/source/encoder/frameencoder.h     Tue Oct 15 11:35:38 2013 +0530
> @@ -113,6 +113,8 @@
>          }
>      }
>
> +    void reportStatistics(UInt64 &ssdY, UInt64 &ssdU, UInt64 &ssdV);
> +
>      TEncEntropy* getEntropyCoder(int row)      { return
> &this->m_rows[row].m_entropyCoder; }
>
>      TEncSbac*    getSbacCoder(int row)         { return
> &this->m_rows[row].m_sbacCoder; }
> diff -r 8ae52f2b159c -r 957578be76da source/encoder/framefilter.cpp
> --- a/source/encoder/framefilter.cpp    Thu Oct 10 01:15:11 2013 -0500
> +++ b/source/encoder/framefilter.cpp    Tue Oct 15 11:35:38 2013 +0530
> @@ -36,6 +36,9 @@
>      : m_cfg(NULL)
>      , m_pic(NULL)
>  {
> +    m_SSDY = 0;
> +    m_SSDU = 0;
> +    m_SSDV = 0;
>  }
>
>  void FrameFilter::destroy()
> @@ -86,6 +89,9 @@
>      m_entropyCoder.setEntropyCoder(&m_rdGoOnSbacCoder, pic->getSlice());
>      m_entropyCoder.setBitstream(&m_bitCounter);
>      m_rdGoOnBinCodersCABAC.m_fracBits = 0;
> +    m_SSDY=0;
> +    m_SSDU=0;
> +    m_SSDV=0;
>

white-space


>      if (m_cfg->param.bEnableSAO)
>      {
> @@ -264,6 +270,144 @@
>      {
>          m_pic->m_reconRowWait.trigger();
>      }
> +
> +    if (m_cfg->param.bEnablePsnr)
> +    {
> +        calculatePSNR(lineStartCUAddr, row);
> +    }
> +}
> +
> +static UInt64 computeSSD(pixel *fenc, pixel *rec, int stride, int width,
> int height)
> +{
> +    UInt64 ssd = 0;
> +
> +    if ((width | height) & 3)
> +    {
> +        /* Slow Path */
> +        for (int y = 0; y < height; y++)
> +        {
> +            for (int x = 0; x < width; x++)
> +            {
> +                int diff = (int)(fenc[x] - rec[x]);
> +                ssd += diff * diff;
> +            }
> +
> +            fenc += stride;
> +            rec += stride;
> +        }
> +
> +        return ssd;
> +    }
> +
> +    int y = 0;
> +    /* Consume Y in chunks of 64 */
> +    for (; y + 64 <= height; y += 64)
> +    {
> +        int x = 0;
> +
> +        if (!(stride & 31))
> +            for (; x + 64 <= width; x += 64)
> +            {
> +                ssd += primitives.sse_pp[PARTITION_64x64](fenc + x,
> stride, rec + x, stride);
> +            }
> +
> +        if (!(stride & 15))
> +            for (; x + 16 <= width; x += 16)
> +            {
> +                ssd += primitives.sse_pp[PARTITION_16x64](fenc + x,
> stride, rec + x, stride);
> +            }
> +
> +        for (; x + 4 <= width; x += 4)
> +        {
> +            ssd += primitives.sse_pp[PARTITION_4x64](fenc + x, stride,
> rec + x, stride);
> +        }
> +
> +        fenc += stride * 64;
> +        rec += stride * 64;
> +    }
> +
> +    /* Consume Y in chunks of 16 */
> +    for (; y + 16 <= height; y += 16)
> +    {
> +        int x = 0;
> +
> +        if (!(stride & 31))
> +            for (; x + 64 <= width; x += 64)
> +            {
> +                ssd += primitives.sse_pp[PARTITION_64x16](fenc + x,
> stride, rec + x, stride);
> +            }
> +
> +        if (!(stride & 15))
> +            for (; x + 16 <= width; x += 16)
> +            {
> +                ssd += primitives.sse_pp[PARTITION_16x16](fenc + x,
> stride, rec + x, stride);
> +            }
> +
> +        for (; x + 4 <= width; x += 4)
> +        {
> +            ssd += primitives.sse_pp[PARTITION_4x16](fenc + x, stride,
> rec + x, stride);
> +        }
> +
> +        fenc += stride * 16;
> +        rec += stride * 16;
> +    }
> +
> +    /* Consume Y in chunks of 4 */
> +    for (; y + 4 <= height; y += 4)
> +    {
> +        int x = 0;
> +
> +        if (!(stride & 31))
> +            for (; x + 64 <= width; x += 64)
> +            {
> +                ssd += primitives.sse_pp[PARTITION_64x4](fenc + x,
> stride, rec + x, stride);
> +            }
> +
> +        if (!(stride & 15))
> +            for (; x + 16 <= width; x += 16)
> +            {
> +                ssd += primitives.sse_pp[PARTITION_16x4](fenc + x,
> stride, rec + x, stride);
> +            }
> +
> +        for (; x + 4 <= width; x += 4)
> +        {
> +            ssd += primitives.sse_pp[PARTITION_4x4](fenc + x, stride, rec
> + x, stride);
> +        }
> +
> +        fenc += stride * 4;
> +        rec += stride * 4;
> +    }
> +
> +    return ssd;
> +}
> +
> +void FrameFilter::calculatePSNR(uint32_t cuAddr, int row)
> +{
> +    TComPicYuv* recon = m_pic->getPicYuvRec();
> +    TComPicYuv* orig  = m_pic->getPicYuvOrg();
> +
> +    //===== calculate PSNR =====
> +    int stride = recon->getStride();
> +
> +    int width  = recon->getWidth() - m_cfg->getPad(0);
> +    int height;
> +    if (row == m_numRows - 1)
> +        height = ((recon->getHeight() % g_maxCUHeight) ?
> (recon->getHeight() % g_maxCUHeight) : g_maxCUHeight);
> +    else
> +        height = g_maxCUHeight;
> +
> +    UInt64 ssdY = computeSSD(orig->getLumaAddr(cuAddr),
> recon->getLumaAddr(cuAddr), stride, width, height);
> +
> +    height >>= 1;
> +    width  >>= 1;
> +    stride = recon->getCStride();
> +
> +    UInt64 ssdU = computeSSD(orig->getCbAddr(cuAddr),
> recon->getCbAddr(cuAddr), stride, width, height);
> +    UInt64 ssdV = computeSSD(orig->getCrAddr(cuAddr),
> recon->getCrAddr(cuAddr), stride, width, height);
> +
> +    m_SSDY += ssdY;
> +    m_SSDU += ssdU;
> +    m_SSDV += ssdV;
>  }
>
>  void FrameFilter::processSao(int row)
> diff -r 8ae52f2b159c -r 957578be76da source/encoder/framefilter.h
> --- a/source/encoder/framefilter.h      Thu Oct 10 01:15:11 2013 -0500
> +++ b/source/encoder/framefilter.h      Tue Oct 15 11:35:38 2013 +0530
> @@ -53,7 +53,7 @@
>      void processRow(int row);
>      void processRowPost(int row);
>      void processSao(int row);
> -
> +    void calculatePSNR(uint32_t cu, int row);
>  protected:
>
>      TEncCfg*                    m_cfg;
> @@ -72,6 +72,9 @@
>      TEncBinCABACCounter         m_rdGoOnBinCodersCABAC;
>      TComBitCounter              m_bitCounter;
>      TEncSbac*                   m_rdGoOnSbacCoderRow0;  // for bitstream
> exact only, depends on HM's bug
> +    UInt64                      m_SSDY;
> +    UInt64                      m_SSDU;
> +    UInt64                      m_SSDV;
>  };
>  }
>
> _______________________________________________
> 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/20131015/4782ed85/attachment-0001.html>


More information about the x265-devel mailing list