[x265] [PATCH 2 of 2] calculate SSIM for each Row after deblock, sao

Aarthi Priya Thirumalai aarthi at multicorewareinc.com
Sat Oct 5 05:49:03 CEST 2013


On Sat, Oct 5, 2013 at 12:57 AM, Steve Borho <steve at borho.org> wrote:

>
>
>
> On Fri, Oct 4, 2013 at 6:21 AM, Aarthi Thirumalai <
> aarthi at multicorewareinc.com> wrote:
>
>> # HG changeset patch
>> # User Aarthi Thirumalai
>> # Date 1380885604 -19800
>> #      Fri Oct 04 16:50:04 2013 +0530
>> # Node ID ed4f57163274364e419dabfa4f864aa5a48cab6b
>> # Parent  92641f3d3195b8da2275cfc44b1921d8f81a54bc
>> calculate SSIM for each Row after deblock, sao.
>>
>> diff -r 92641f3d3195 -r ed4f57163274 source/Lib/TLibEncoder/TEncTop.cpp
>> --- a/source/Lib/TLibEncoder/TEncTop.cpp        Fri Oct 04 16:46:15 2013
>> +0530
>> +++ b/source/Lib/TLibEncoder/TEncTop.cpp        Fri Oct 04 16:50:04 2013
>> +0530
>> @@ -513,7 +513,7 @@
>>      int width  = recon->getWidth() - getPad(0);
>>      int height = recon->getHeight() - getPad(1);
>>      int size = width * height;
>> -
>> +    double ssim = 0;
>>      UInt64 ssdY = computeSSD(orig->getLumaAddr(), recon->getLumaAddr(),
>> stride, width, height);
>>
>>      height >>= 1;
>> @@ -604,7 +604,11 @@
>>      {
>>          m_analyzeB.addResult(psnrY, psnrU, psnrV, (double)bits);
>>      }
>> -
>> +    if (param.bEnableSsim)
>> +    {
>> +        ssim += pic->getSlice()->m_ssim / pic->getSlice()->m_ssimCnt;
>>
>
> is m_ssimCnt always non-zero?
>  needs a check here.
>


> +        m_globalSsim += ssim;
>> +    }
>>      if (param.logLevel >= X265_LOG_DEBUG)
>>      {
>>          char c = (slice->isIntra() ? 'I' : slice->isInterP() ? 'P' :
>> 'B');
>> diff -r 92641f3d3195 -r ed4f57163274 source/encoder/frameencoder.cpp
>> --- a/source/encoder/frameencoder.cpp   Fri Oct 04 16:46:15 2013 +0530
>> +++ b/source/encoder/frameencoder.cpp   Fri Oct 04 16:50:04 2013 +0530
>> @@ -111,6 +111,9 @@
>>          m_rows[i].create(top);
>>      }
>>
>> +    if (m_cfg->param.bEnableSsim)
>> +        CHECKED_MALLOC(tempBuf, int, m_cfg->param.bEnableSsim * 8 *
>> (m_cfg->param.sourceWidth / 4 + 3));
>> +
>>      // NOTE: 2 times of numRows because both Encoder and Filter in same
>> queue
>>      if (!WaveFront::init(m_numRows * 2))
>>      {
>> @@ -168,6 +171,10 @@
>>          assert(0);
>>      }
>>      start();
>> +    return;
>> +fail:
>> +    X265_FREE(tempBuf);
>> +    tempBuf = 0;
>>
>
> this looks quite backwards, you only free tempBuf on malloc failure?  the
> buffer doesn't appear to be used?
>


>  Its passed as an argument in calculateSSIM().
>
>>  }
>>
>>  int FrameEncoder::getStreamHeaders(NALUnitEBSP **nalunits)
>> @@ -540,6 +547,32 @@
>>          slice->setSaoEnabledFlag((saoParam->bSaoFlag[0] == 1) ? true :
>> false);
>>      }
>>
>> +    /*Compute SSIM if enabled*/
>> +    if (m_cfg->param.bEnableSsim)
>> +    {
>> +        pixel *rec = (pixel*)m_pic->getPicYuvRec()->getLumaAddr();
>> +        pixel *org = (pixel*)m_pic->getPicYuvOrg()->getLumaAddr();
>> +        int stride1 = m_pic->getPicYuvOrg()->getStride();
>> +        int stride2 = m_pic->getPicYuvRec()->getStride();
>> +        for (int row = 0; row < m_numRows; row++)
>> +        {
>> +            int bEnd = ((row + 1) == (this->m_numRows - 1));
>> +            int bStart = (row == 0);
>> +            int minPixY = row * 64 - 4 * !bStart;
>> +            int maxPixY = (row + 1) * 64 - 4 * !bEnd;
>> +            int ssim_cnt;
>> +            x265_emms();
>> +
>> +            /* SSIM is done for each row in blocks of 4x4 . The First
>> blocks are offset by 2 pixels to the right
>> +            * to avoid alignment of ssim blocks with DCT blocks. */
>> +            minPixY += bStart ? 2 : -6;
>> +            slice->m_ssim +=
>> +                calculateSSIM(rec + 2 + minPixY * stride1, stride1, org
>> + 2 + minPixY * stride2, stride2,
>> +                              m_cfg->param.sourceWidth - 2, maxPixY -
>> minPixY, tempBuf, &ssim_cnt);
>> +            slice->m_ssimCnt += ssim_cnt;
>> +        }
>> +    }
>> +
>>      entropyCoder->setBitstream(NULL);
>>
>>      // Reconstruction slice
>> @@ -687,6 +720,39 @@
>>      delete bitstreamRedirect;
>>  }
>>
>> +/* Function to calculate SSIM for each row */
>> +float FrameEncoder::calculateSSIM(pixel *pix1, intptr_t stride1, pixel
>> *pix2, intptr_t stride2, int width, int height, void *buf, int *cnt)
>> +{
>> +    int z = 0;
>> +    float ssim = 0.0;
>> +
>> +    int(*sum0)[4] = (int(*)[4])buf;
>> +    int(*sum1)[4] = sum0 + (width >> 2) + 3;
>> +    width >>= 2;
>> +    height >>= 2;
>> +    for (int y = 1; y < height; y++)
>> +    {
>> +        for (; z <= y; z++)
>> +        {
>> +            void* swap = sum0;
>> +            sum0 = sum1;
>> +            sum1 = (int(*)[4])swap;
>> +            for (int x = 0; x < width; x += 2)
>> +            {
>> +                primitives.ssim_4x4x2_core_int(&pix1[4 * (x + (z *
>> stride1))], stride1, &pix2[4 * (x + (z * stride2))], stride2, &sum0[x]);
>> +            }
>> +        }
>> +
>> +        for (int x = 0; x < width - 1; x += 4)
>> +        {
>> +            ssim += primitives.ssim_end4_int(sum0 + x, sum1 + x,
>> X265_MIN(4, width - x - 1));
>> +        }
>> +    }
>> +
>> +    *cnt = (height - 1) * (width - 1);
>> +    return ssim;
>> +}
>> +
>>  void FrameEncoder::encodeSlice(TComOutputBitstream* substreams)
>>  {
>>      // choose entropy coder
>> diff -r 92641f3d3195 -r ed4f57163274 source/encoder/frameencoder.h
>> --- a/source/encoder/frameencoder.h     Fri Oct 04 16:46:15 2013 +0530
>> +++ b/source/encoder/frameencoder.h     Fri Oct 04 16:50:04 2013 +0530
>> @@ -145,6 +145,9 @@
>>      /* called by compressFrame to perform wave-front compression
>> analysis */
>>      void compressCTURows();
>>
>> +    /* called by compressFrame to calculate SSIM for each row . */
>> +    float calculateSSIM(pixel *pix1, intptr_t stride1, pixel *pix2,
>> intptr_t stride2, int width, int height, void *buf, int *cnt);
>> +
>>      void encodeSlice(TComOutputBitstream* substreams);
>>
>>      /* blocks until worker thread is done, returns encoded picture and
>> bitstream */
>> @@ -185,6 +188,9 @@
>>      int                      m_filterRowDelay;
>>      CTURow*                  m_rows;
>>      Event                    m_completionEvent;
>> +
>> +    /* Temp Storage that doesnt need repeated malloc */
>> +    void *                   tempBuf;
>>  };
>>  }
>>
>> _______________________________________________
>> x265-devel mailing list
>> x265-devel at videolan.org
>> https://mailman.videolan.org/listinfo/x265-devel
>>
>
>
>
> --
> Steve Borho
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20131005/b8906807/attachment.html>


More information about the x265-devel mailing list