<p><br>
On Oct 1, 2013 1:44 AM, "Steve Borho" <<a href="mailto:steve@borho.org">steve@borho.org</a>> wrote:<br>
><br>
><br>
><br>
><br>
> On Fri, Sep 27, 2013 at 11:52 PM, Aarthi Thirumalai <<a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a>> wrote:<br>
>><br>
>> # HG changeset patch<br>
>> # User Aarthi Thirumalai<br>
>> # Date 1380343885 -19800<br>
>> # Sat Sep 28 10:21:25 2013 +0530<br>
>> # Node ID b1539ccab7bab1708433a9b8b18f5f8c090b1810<br>
>> # Parent a8b00de495520f00a4648dac5d111e40b5570ca3<br>
>> integrated ssim computation for each CTURow<br>
>><br>
>> diff -r a8b00de49552 -r b1539ccab7ba source/encoder/frameencoder.cpp<br>
>> --- a/source/encoder/frameencoder.cpp Sat Sep 28 10:18:23 2013 +0530<br>
>> +++ b/source/encoder/frameencoder.cpp Sat Sep 28 10:21:25 2013 +0530<br>
>> @@ -91,6 +91,9 @@<br>
>> delete[] m_rows;<br>
>> }<br>
>><br>
>> + if (tempBuf)<br>
><br>
><br>
> X265_FREE does the NULL check for you<br>
> <br>
>><br>
>> + X265_FREE(tempBuf);<br>
>> +<br>
>> m_frameFilter.destroy();<br>
>><br>
>> // wait for worker thread to exit<br>
>> @@ -106,6 +109,8 @@<br>
>> 2 : (m_cfg->param.bEnableSAO || m_cfg->param.bEnableLoopFilter ? 1 : 0);<br>
>><br>
>> m_rows = new CTURow[m_numRows];<br>
>> + if(m_cfg->param.bEnableSsim)<br>
><br>
><br>
> white-space<br>
> <br>
>><br>
>> + CHECKED_MALLOC(tempBuf, int, m_cfg->param.bEnableSsim * 8 * (m_cfg->param.sourceWidth/4 + 3));<br>
>> for (int i = 0; i < m_numRows; ++i)<br>
>> {<br>
>> m_rows[i].create(top);<br>
>> @@ -168,6 +173,8 @@<br>
>> assert(0);<br>
>> }<br>
>> start();<br>
>> +fail:<br>
>> + return;<br>
>> }<br>
>><br>
>> int FrameEncoder::getStreamHeaders(NALUnitEBSP **nalunits)<br>
>> @@ -540,6 +547,31 @@<br>
>> slice->setSaoEnabledFlag((saoParam->bSaoFlag[0] == 1) ? true : false);<br>
>> }<br>
>><br>
>> + /*Compute SSIM if enabled*/<br>
>> + if(m_cfg->param.bEnableSsim)<br>
><br>
> white-space <br>
>><br>
>> + {<br>
>> + pixel *rec = (pixel*)m_pic->getPicYuvRec()->getLumaAddr();<br>
>> + pixel *org = (pixel*)m_pic->getPicYuvOrg()->getLumaAddr();<br>
>> + int stride = m_pic->getPicYuvOrg()->getStride();<br>
>> + for(int row = 0; row < m_numRows; row++)<br>
>> + {<br>
>> + int bEnd = ((row + 1) == (this->m_numRows - 1));<br>
>> + int bStart = (row == 0);<br>
>> + int minPixY = row * 64 - 4 * !bStart;<br>
>> + int maxPixY = (row + 1)* 64 - 4 * !bEnd;<br>
>> + int ssim_cnt;<br>
>> + x265_emms();<br>
>> + /* offset by 2 pixels to avoid alignment of ssim blocks with dct blocks,<br>
>> + * and overlap by 4 */<br>
><br>
><br>
> do you understand what this comment implies? I don't and we probably should<br>
> <br>
The function to calculate ssim for each row in this manner. Starting point : offset block by 2 in x axis. Do ssim for 2 4x4 blocks till row end. Offset by 4 in y axis from starting point n repeat above step for entire height(maxpicy - minpic) this offset is done so block positions don't match with dct sizes.<br>
>><br>
>> + minPixY += bStart ? 2 : -6;<br>
>> + slice->m_ssim +=<br>
>> + calculateSSIM(<br>
>> + rec + 2 + minPixY * stride, stride,<br>
>> + org + 2 + minPixY * stride, stride,<br>
>> + m_cfg->param.sourceWidth-2, maxPixY - minPixY, tempBuf, &ssim_cnt );<br>
><br>
><br>
> formatting<br>
> <br>
>><br>
>> + slice->m_ssimCnt += ssim_cnt;<br>
>> + }<br>
>> + }<br>
>> entropyCoder->setBitstream(NULL);<br>
>><br>
>> // Reconstruction slice<br>
>> @@ -687,6 +719,38 @@<br>
>> delete bitstreamRedirect;<br>
>> }<br>
>><br>
>> +/* Function to calculate SSIM for each row */<br>
>> +float FrameEncoder::calculateSSIM( pixel *pix1, intptr_t stride1,<br>
>> + pixel *pix2, intptr_t stride2,<br>
>> + int width, int height, void *buf, int *cnt )<br>
><br>
> coding-style <br>
>><br>
>> +{<br>
>> + int z = 0;<br>
>> + float ssim = 0.0;<br>
>> + int (*sum0)[4] = (int (*)[4]) buf;<br>
>> + int (*sum1)[4] = sum0 + (width >> 2) + 3;<br>
>> + width >>= 2;<br>
>> + height >>= 2;<br>
>> + for( int y = 1; y < height; y++ )<br>
>> + {<br>
>> + for( ; z <= y; z++ )<br>
>> + {<br>
>> + void* swap = sum0;<br>
>> + sum0 = sum1;<br>
>> + sum1 = (int (*)[4])swap;<br>
>> + for( int x = 0; x < width; x+=2 )<br>
>> + {<br>
>> + if(m_pic->getPicYuvRec() == 0 || x== 98){<br>
>> + int nullaalret = 1; nullaalret++;<br>
>> + }<br>
>> + primitives.ssim4x4x2Core( &pix1[4*(x+z*stride1)], stride1, &pix2[4*(x+z*stride2)], stride2, &sum0[x] );<br>
>> + }<br>
>> + }<br>
>> + for( int x = 0; x < width-1; x += 4 )<br>
>> + ssim += primitives.ssimEnd4( sum0+x, sum1+x, X265_MIN(4,width-x-1) );<br>
>> + }<br>
>> + *cnt = (height-1) * (width-1);<br>
>> + return ssim;<br>
>> +}<br>
>> void FrameEncoder::encodeSlice(TComOutputBitstream* substreams)<br>
>> {<br>
>> // choose entropy coder<br>
>> diff -r a8b00de49552 -r b1539ccab7ba source/encoder/frameencoder.h<br>
>> --- a/source/encoder/frameencoder.h Sat Sep 28 10:18:23 2013 +0530<br>
>> +++ b/source/encoder/frameencoder.h Sat Sep 28 10:21:25 2013 +0530<br>
>> @@ -153,6 +153,10 @@<br>
>> // worker thread<br>
>> void threadMain();<br>
>><br>
>> + /* called by compressFrame to calculate SSIM for each row after applying deblock filter and SAO. */<br>
>> + float calculateSSIM(pixel *pix1, intptr_t stride1,pixel *pix2, intptr_t stride2,<br>
>> + int width, int height, void *buf, int *cnt );<br>
>> +<br>
>> Event m_enable;<br>
>> Event m_done;<br>
>> bool m_threadActive;<br>
>> @@ -185,6 +189,9 @@<br>
>> int m_filterRowDelay;<br>
>> CTURow* m_rows;<br>
>> Event m_completionEvent;<br>
>> +<br>
>> + /* Temp Storage that doesnt need repeated malloc */<br>
>> + void * tempBuf;<br>
>> };<br>
>> }<br>
>><br>
>> _______________________________________________<br>
>> x265-devel mailing list<br>
>> <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
>> <a href="https://mailman.videolan.org/listinfo/x265-devel">https://mailman.videolan.org/listinfo/x265-devel</a><br>
><br>
><br>
><br>
><br>
> -- <br>
> Steve Borho<br>
><br>
> _______________________________________________<br>
> x265-devel mailing list<br>
> <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
> <a href="https://mailman.videolan.org/listinfo/x265-devel">https://mailman.videolan.org/listinfo/x265-devel</a><br>
><br>
</p>