[x265] [PATCH 2 of 2] calculate SSIM for each Row after deblock, sao
Steve Borho
steve at borho.org
Fri Oct 4 21:27:58 CEST 2013
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?
> + 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?
> }
>
> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20131004/194b503f/attachment-0001.html>
More information about the x265-devel
mailing list