[x265] [PATCH] stats: fix use of uninitialized pixels in maximum and average luma level calculation
Steve Borho
steve at borho.org
Thu Aug 13 10:55:05 CEST 2015
On 08/13, kavitha at multicorewareinc.com wrote:
> # HG changeset patch
> # User Kavitha Sampath <kavitha at multicorewareinc.com>
> # Date 1439450035 -19800
> # Thu Aug 13 12:43:55 2015 +0530
> # Node ID ac3966a43ba77b609d0e209df80f3a3aac234c08
> # Parent bc5a7c2ac38b06d2a232b983f10bc0394d252ad7
> stats: fix use of uninitialized pixels in maximum and average luma level calculation
>
> To avoid complexity in determining pixels of border CUs that lie outside the frame,
> luma level calculations are performed at the frame level, immediately after
> copying the picture into PicYuv
>
> diff -r bc5a7c2ac38b -r ac3966a43ba7 source/common/picyuv.cpp
> --- a/source/common/picyuv.cpp Wed Aug 12 15:13:51 2015 +0530
> +++ b/source/common/picyuv.cpp Thu Aug 13 12:43:55 2015 +0530
> @@ -42,6 +42,9 @@
> m_cuOffsetC = NULL;
> m_buOffsetY = NULL;
> m_buOffsetC = NULL;
> +
> + maxLumaLevel = 0;
> + avgLumaLevel = 0;
PicYuv is a class, so member variables need the m_ prefix.
otherwise the patch look ok
> }
>
> bool PicYuv::create(uint32_t picWidth, uint32_t picHeight, uint32_t picCsp)
> @@ -235,17 +238,25 @@
> pixel *U = m_picOrg[1];
> pixel *V = m_picOrg[2];
>
> + uint64_t sumLuma = 0;
> for (int r = 0; r < height; r++)
> {
> - /* Clip luma of source picture to max and min values before extending edges of picYuv */
> - for (int c = 0; c < m_stride; c++)
> + for (int c = 0; c < width; c++)
> + {
> + /* Clip luma of source picture to max and min values before extending edges of picYuv */
> Y[c] = x265_clip3((pixel)param.minLuma, (pixel)param.maxLuma, Y[c]);
>
> + /* Determine maximum and average luma level in a picture */
> + maxLumaLevel = X265_MAX(Y[c], maxLumaLevel);
> + sumLuma += Y[c];
> + }
> +
> for (int x = 0; x < padx; x++)
> Y[width + x] = Y[width - 1];
>
> Y += m_stride;
> }
> + avgLumaLevel = (double)sumLuma / (m_picHeight * m_picWidth);
>
> for (int r = 0; r < height >> m_vChromaShift; r++)
> {
> diff -r bc5a7c2ac38b -r ac3966a43ba7 source/common/picyuv.h
> --- a/source/common/picyuv.h Wed Aug 12 15:13:51 2015 +0530
> +++ b/source/common/picyuv.h Thu Aug 13 12:43:55 2015 +0530
> @@ -60,6 +60,9 @@
> uint32_t m_chromaMarginX;
> uint32_t m_chromaMarginY;
>
> + uint16_t maxLumaLevel;
> + double avgLumaLevel;
> +
> PicYuv();
>
> bool create(uint32_t picWidth, uint32_t picHeight, uint32_t csp);
> diff -r bc5a7c2ac38b -r ac3966a43ba7 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp Wed Aug 12 15:13:51 2015 +0530
> +++ b/source/encoder/encoder.cpp Thu Aug 13 12:43:55 2015 +0530
> @@ -1163,8 +1163,8 @@
> frameStats->avgChromaDistortion = curFrame->m_encData->m_frameStats.avgChromaDistortion;
> frameStats->avgLumaDistortion = curFrame->m_encData->m_frameStats.avgLumaDistortion;
> frameStats->avgPsyEnergy = curFrame->m_encData->m_frameStats.avgPsyEnergy;
> - frameStats->avgLumaLevel = curFrame->m_encData->m_frameStats.avgLumaLevel;
> - frameStats->maxLumaLevel = curFrame->m_encData->m_frameStats.maxLumaLevel;
> + frameStats->avgLumaLevel = curFrame->m_fencPic->avgLumaLevel;
> + frameStats->maxLumaLevel = curFrame->m_fencPic->maxLumaLevel;
> for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++)
> {
> frameStats->cuStats.percentSkipCu[depth] = curFrame->m_encData->m_frameStats.percentSkipCu[depth];
> diff -r bc5a7c2ac38b -r ac3966a43ba7 source/encoder/frameencoder.cpp
> --- a/source/encoder/frameencoder.cpp Wed Aug 12 15:13:51 2015 +0530
> +++ b/source/encoder/frameencoder.cpp Thu Aug 13 12:43:55 2015 +0530
> @@ -592,10 +592,7 @@
> m_frame->m_encData->m_frameStats.lumaDistortion += m_rows[i].rowStats.lumaDistortion;
> m_frame->m_encData->m_frameStats.chromaDistortion += m_rows[i].rowStats.chromaDistortion;
> m_frame->m_encData->m_frameStats.psyEnergy += m_rows[i].rowStats.psyEnergy;
> - m_frame->m_encData->m_frameStats.lumaLevel += m_rows[i].rowStats.lumaLevel;
>
> - if (m_rows[i].rowStats.maxLumaLevel > m_frame->m_encData->m_frameStats.maxLumaLevel)
> - m_frame->m_encData->m_frameStats.maxLumaLevel = m_rows[i].rowStats.maxLumaLevel;
> for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++)
> {
> m_frame->m_encData->m_frameStats.cntSkipCu[depth] += m_rows[i].rowStats.cntSkipCu[depth];
> @@ -609,7 +606,6 @@
> m_frame->m_encData->m_frameStats.avgLumaDistortion = (double)(m_frame->m_encData->m_frameStats.lumaDistortion / m_frame->m_encData->m_frameStats.totalCtu);
> m_frame->m_encData->m_frameStats.avgChromaDistortion = (double)(m_frame->m_encData->m_frameStats.chromaDistortion / m_frame->m_encData->m_frameStats.totalCtu);
> m_frame->m_encData->m_frameStats.avgPsyEnergy = (double)(m_frame->m_encData->m_frameStats.psyEnergy / m_frame->m_encData->m_frameStats.totalCtu);
> - m_frame->m_encData->m_frameStats.avgLumaLevel = (double)(m_frame->m_encData->m_frameStats.lumaLevel / m_frame->m_encData->m_frameStats.totalCtu);
> m_frame->m_encData->m_frameStats.percentIntraNxN = (double)(m_frame->m_encData->m_frameStats.cntIntraNxN * 100) / m_frame->m_encData->m_frameStats.totalCu;
> for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++)
> {
> @@ -990,17 +986,6 @@
> curRow.rowStats.cuIntraDistribution[depth][n] += frameLog.cuIntraDistribution[depth][n];
> }
>
> - /* calculate maximum and average luma levels */
> - uint32_t ctuLumaLevel = 0;
> - uint32_t ctuNoOfPixels = best.fencYuv->m_size * best.fencYuv->m_size;
> - for (uint32_t i = 0; i < ctuNoOfPixels; i++)
> - {
> - pixel p = best.fencYuv->m_buf[0][i];
> - ctuLumaLevel += p;
> - curRow.rowStats.maxLumaLevel = X265_MAX(p, curRow.rowStats.maxLumaLevel);
> - }
> - curRow.rowStats.lumaLevel += (double)(ctuLumaLevel) / ctuNoOfPixels;
> -
> curEncData.m_cuStat[cuAddr].totalBits = best.totalBits;
> x265_emms();
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
--
Steve Borho
More information about the x265-devel
mailing list