[x265] [PATCH] collect global stats of psnr and ssim
santhoshini at multicorewareinc.com
santhoshini at multicorewareinc.com
Mon Nov 4 04:11:10 CET 2013
# HG changeset patch
# User Santhoshini Sekar <santhoshini at multicorewareinc.com>
# Date 1383209712 -19800
# Thu Oct 31 14:25:12 2013 +0530
# Node ID 8bed3004d0b92ce257f68569a7d3c7532e141d9e
# Parent ec6b4d35f11053b06d0e1ea46df798ff89a4c127
collect global stats of psnr and ssim
diff -r ec6b4d35f110 -r 8bed3004d0b9 source/Lib/TLibCommon/TComPic.cpp
--- a/source/Lib/TLibCommon/TComPic.cpp Thu Oct 31 00:09:49 2013 -0500
+++ b/source/Lib/TLibCommon/TComPic.cpp Thu Oct 31 14:25:12 2013 +0530
@@ -65,6 +65,8 @@
m_SSDY = 0;
m_SSDU = 0;
m_SSDV = 0;
+ m_ssim = 0;
+ m_ssimCnt = 0;
m_frameTime = 0.0;
m_elapsedCompressTime = 0.0;
}
diff -r ec6b4d35f110 -r 8bed3004d0b9 source/Lib/TLibCommon/TComPic.h
--- a/source/Lib/TLibCommon/TComPic.h Thu Oct 31 00:09:49 2013 -0500
+++ b/source/Lib/TLibCommon/TComPic.h Thu Oct 31 14:25:12 2013 +0530
@@ -93,9 +93,13 @@
double m_elapsedCompressTime;
double m_frameTime;
MD5Context m_state[3];
- uint32_t m_crc[3];
- uint32_t m_checksum[3];
-
+ uint32_t m_crc[3];
+ uint32_t m_checksum[3];
+
+ /* SSIM values per frame */
+ double m_ssim;
+ int m_ssimCnt;
+
TComPic();
virtual ~TComPic();
diff -r ec6b4d35f110 -r 8bed3004d0b9 source/Lib/TLibCommon/TComSlice.cpp
--- a/source/Lib/TLibCommon/TComSlice.cpp Thu Oct 31 00:09:49 2013 -0500
+++ b/source/Lib/TLibCommon/TComSlice.cpp Thu Oct 31 14:25:12 2013 +0530
@@ -120,8 +120,6 @@
m_cabacInitFlag = false;
m_numEntryPointOffsets = 0;
m_enableTMVPFlag = true;
- m_ssim = 0;
- m_ssimCnt = 0;
m_numWPRefs = 0;
}
diff -r ec6b4d35f110 -r 8bed3004d0b9 source/Lib/TLibCommon/TComSlice.h
--- a/source/Lib/TLibCommon/TComSlice.h Thu Oct 31 00:09:49 2013 -0500
+++ b/source/Lib/TLibCommon/TComSlice.h Thu Oct 31 14:25:12 2013 +0530
@@ -1341,10 +1341,6 @@
wpScalingParam m_weightPredTable[2][MAX_NUM_REF][3]; // [REF_PIC_LIST_0 or REF_PIC_LIST_1][refIdx][0:Y, 1:U, 2:V]
int m_numWPRefs; // number of references for which unidirectional weighted prediction is used
- /* SSIM values per frame */
- double m_ssim;
- int m_ssimCnt;
-
TComSlice();
virtual ~TComSlice();
void initSlice();
diff -r ec6b4d35f110 -r 8bed3004d0b9 source/Lib/TLibEncoder/TEncAnalyze.h
--- a/source/Lib/TLibEncoder/TEncAnalyze.h Thu Oct 31 00:09:49 2013 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/* The copyright in this software is being made available under the BSD
- * License, included below. This software may be subject to other third party
- * and contributor rights, including patent rights, and no such rights are
- * granted under this license.
- *
- * Copyright (c) 2010-2013, ITU/ISO/IEC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** \file TEncAnalyze.h
- \brief encoder analyzer class (header)
-*/
-
-#ifndef X265_TENCANALYZE_H
-#define X265_TENCANALYZE_H
-
-#include "TLibCommon/CommonDef.h"
-
-#include <stdio.h>
-#include <memory.h>
-#include <assert.h>
-
-namespace x265 {
-// private namespace
-
-/// encoder analyzer class
-class TEncAnalyze
-{
-private:
-
- double m_psnrSumY;
- double m_psnrSumU;
- double m_psnrSumV;
- double m_accBits;
- uint32_t m_numPics;
-
-public:
-
- TEncAnalyze() { m_psnrSumY = m_psnrSumU = m_psnrSumV = m_accBits = m_numPics = 0; }
-
- void addResult(double psnrY, double psnrU, double psnrV, double bits)
- {
- m_psnrSumY += psnrY;
- m_psnrSumU += psnrU;
- m_psnrSumV += psnrV;
- m_accBits += bits;
- m_numPics++;
- }
-
- double getPsnrY() { return m_psnrSumY; }
-
- double getPsnrU() { return m_psnrSumU; }
-
- double getPsnrV() { return m_psnrSumV; }
-
- double getBits() { return m_accBits; }
-
- uint32_t getNumPic() { return m_numPics; }
-
- void clear() { m_psnrSumY = m_psnrSumU = m_psnrSumV = m_accBits = m_numPics = 0; }
-
- void printOut(char delim, double fps)
- {
- double scale = fps / 1000 / (double)m_numPics;
-
- if (m_numPics == 0)
- return;
-
- if (delim == 'a')
- fprintf(stderr, "x265 [info]: global: ");
- else
- fprintf(stderr, "x265 [info]: frame %c:%-6d ", delim - 32, m_numPics);
- fprintf(stderr, "kb/s: %-8.2lf PSNR Mean: Y:%.3lf U:%.3lf V:%.3lf\n",
- getBits() * scale,
- getPsnrY() / (double)getNumPic(),
- getPsnrU() / (double)getNumPic(),
- getPsnrV() / (double)getNumPic());
- }
-
- void printSummaryOut(double fps)
- {
- FILE* fp = fopen("summaryTotal.txt", "at");
-
- if (fp)
- {
- double scale = fps / 1000 / (double)m_numPics;
-
- fprintf(fp, "%f\t %f\t %f\t %f\n", getBits() * scale,
- getPsnrY() / (double)getNumPic(),
- getPsnrU() / (double)getNumPic(),
- getPsnrV() / (double)getNumPic());
-
- fclose(fp);
- }
- }
-
- void printSummary(char ch, double fps)
- {
- FILE* fp = NULL;
-
- switch (ch)
- {
- case 'I':
- fp = fopen("summary_I.txt", "at");
- break;
- case 'P':
- fp = fopen("summary_P.txt", "at");
- break;
- case 'B':
- fp = fopen("summary_B.txt", "at");
- break;
- default:
- assert(0);
- return;
- }
-
- if (fp)
- {
- double scale = fps / 1000 / (double)m_numPics;
-
- fprintf(fp, "%f\t %f\t %f\t %f\n",
- getBits() * scale,
- getPsnrY() / (double)getNumPic(),
- getPsnrU() / (double)getNumPic(),
- getPsnrV() / (double)getNumPic());
-
- fclose(fp);
- }
- }
-};
-}
-
-#endif // ifndef X265_TENCANALYZE_H
diff -r ec6b4d35f110 -r 8bed3004d0b9 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Thu Oct 31 00:09:49 2013 -0500
+++ b/source/encoder/encoder.cpp Thu Oct 31 14:25:12 2013 +0530
@@ -57,7 +57,6 @@
m_frameEncoder = NULL;
m_rateControl = NULL;
m_dpb = NULL;
- m_globalSsim = 0;
m_nals = NULL;
m_packetData = NULL;
m_outputCount = 0;
@@ -315,20 +314,98 @@
return ret;
}
+void EncStats::addPsnr(double psnrY, double psnrU, double psnrV)
+{
+ m_psnrSumY += psnrY;
+ m_psnrSumU += psnrU;
+ m_psnrSumV += psnrV;
+}
+
+void EncStats::addBits(double bits)
+{
+ m_accBits += bits;
+ m_numPics++;
+}
+
+void EncStats::addSsim(double ssim)
+{
+ m_globalSsim += ssim;
+}
+
void Encoder::printSummary()
{
double fps = (double)param.frameRate;
if (param.logLevel >= X265_LOG_INFO)
{
- m_analyzeI.printOut('i', fps);
- m_analyzeP.printOut('p', fps);
- m_analyzeB.printOut('b', fps);
- m_analyzeAll.printOut('a', fps);
+ double scale = fps / 1000 / (double)m_analyzeI.m_numPics;
+
+ fprintf(stderr, "\n x265 [info]: frame %c:%-6d ", 'i' - 32, m_analyzeI.m_numPics);
+ fprintf(stderr, "kb/s: %-8.2lf", m_analyzeI.m_accBits * scale);
+ if (param.bEnablePsnr)
+ {
+ fprintf(stderr, " PSNR Mean: Y:%.3lf U:%.3lf V:%.3lf",
+ m_analyzeI.m_psnrSumY / (double)m_analyzeI.m_numPics,
+ m_analyzeI.m_psnrSumU / (double)m_analyzeI.m_numPics,
+ m_analyzeI.m_psnrSumV / (double)m_analyzeI.m_numPics);
+ }
+ if (param.bEnableSsim)
+ {
+ fprintf(stderr, " SSIM Mean: %.3lf \n",
+ m_analyzeI.m_globalSsim / (double)m_analyzeI.m_numPics);
+ }
+ scale = fps / 1000 / (double)m_analyzeP.m_numPics;
+
+ fprintf(stderr, "\n x265 [info]: frame %c:%-6d ", 'p' - 32, m_analyzeP.m_numPics);
+ fprintf(stderr, "kb/s: %-8.2lf", m_analyzeP.m_accBits * scale);
+ if (param.bEnablePsnr)
+ {
+ fprintf(stderr, " PSNR Mean: Y:%.3lf U:%.3lf V:%.3lf",
+ m_analyzeP.m_psnrSumY / (double)m_analyzeP.m_numPics,
+ m_analyzeP.m_psnrSumU / (double)m_analyzeP.m_numPics,
+ m_analyzeP.m_psnrSumV / (double)m_analyzeP.m_numPics);
+ }
+ if (param.bEnableSsim)
+ {
+ fprintf(stderr, " SSIM Mean: %.3lf \n",
+ m_analyzeP.m_globalSsim / (double)m_analyzeP.m_numPics);
+ }
+ scale = fps / 1000 / (double)m_analyzeB.m_numPics;
+
+ fprintf(stderr, "\n x265 [info]: frame %c:%-6d ", 'b' - 32, m_analyzeB.m_numPics);
+ fprintf(stderr, "kb/s: %-8.2lf", m_analyzeB.m_accBits * scale);
+ if (param.bEnablePsnr)
+ {
+ fprintf(stderr, " PSNR Mean: Y:%.3lf U:%.3lf V:%.3lf",
+ m_analyzeB.m_psnrSumY / (double)m_analyzeB.m_numPics,
+ m_analyzeB.m_psnrSumU / (double)m_analyzeB.m_numPics,
+ m_analyzeB.m_psnrSumV / (double)m_analyzeB.m_numPics);
+ }
+ if (param.bEnableSsim)
+ {
+ fprintf(stderr, " SSIM Mean: %.3lf \n",
+ m_analyzeB.m_globalSsim / (double)m_analyzeB.m_numPics);
+ }
+ scale = fps / 1000 / (double)m_analyzeAll.m_numPics;
+
+ fprintf(stderr, "\n x265 [info]: global: ");
+ fprintf(stderr, "kb/s: %-8.2lf", m_analyzeAll.m_accBits * scale);
+ if (param.bEnablePsnr)
+ {
+ fprintf(stderr, " PSNR Mean: Y:%.3lf U:%.3lf V:%.3lf",
+ m_analyzeAll.m_psnrSumY / (double)m_analyzeAll.m_numPics,
+ m_analyzeAll.m_psnrSumU / (double)m_analyzeAll.m_numPics,
+ m_analyzeAll.m_psnrSumV / (double)m_analyzeAll.m_numPics);
+ }
+ if (param.bEnableSsim)
+ {
+ fprintf(stderr, " SSIM Mean: %.3lf \n",
+ m_analyzeAll.m_globalSsim / (double)m_analyzeAll.m_numPics);
+ }
}
if (param.bEnableWeightedPred)
{
- int numPFrames = m_analyzeP.getNumPic();
+ int numPFrames = m_analyzeP.m_numPics;
x265_log(¶m, X265_LOG_INFO, "%d of %d (%.2f%%) P frames weighted\n",
m_numWPFrames, numPFrames, (float) 100.0 * m_numWPFrames / numPFrames);
}
@@ -336,16 +413,16 @@
void Encoder::fetchStats(x265_stats *stats)
{
- stats->globalPsnrY = m_analyzeAll.getPsnrY();
- stats->globalPsnrU = m_analyzeAll.getPsnrU();
- stats->globalPsnrV = m_analyzeAll.getPsnrV();
- stats->encodedPictureCount = m_analyzeAll.getNumPic();
+ stats->globalPsnrY = m_analyzeAll.m_psnrSumY;
+ stats->globalPsnrU = m_analyzeAll.m_psnrSumU;
+ stats->globalPsnrV = m_analyzeAll.m_psnrSumV;
+ stats->encodedPictureCount = m_analyzeAll.m_numPics;
stats->totalWPFrames = m_numWPFrames;
- stats->accBits = m_analyzeAll.getBits();
+ stats->accBits = m_analyzeAll.m_accBits;
stats->elapsedEncodeTime = (double)(x265_mdate() - m_encodeStartTime) / 1000000;
if (stats->encodedPictureCount > 0)
{
- stats->globalSsim = m_globalSsim / stats->encodedPictureCount;
+ stats->globalSsim = m_analyzeAll.m_globalSsim / stats->encodedPictureCount;
stats->globalPsnr = (stats->globalPsnrY * 6 + stats->globalPsnrU + stats->globalPsnrV) / (8 * stats->encodedPictureCount);
stats->elapsedVideoTime = (double)stats->encodedPictureCount / param.frameRate;
stats->bitrate = (0.001f * stats->accBits) / stats->elapsedVideoTime;
@@ -527,27 +604,60 @@
uint32_t bits = numRBSPBytes * 8;
- //===== add PSNR =====
- m_analyzeAll.addResult(psnrY, psnrU, psnrV, (double)bits);
- TComSlice* slice = pic->getSlice();
- if (slice->isIntra())
- {
- m_analyzeI.addResult(psnrY, psnrU, psnrV, (double)bits);
- }
- if (slice->isInterP())
- {
- m_analyzeP.addResult(psnrY, psnrU, psnrV, (double)bits);
- }
- if (slice->isInterB())
- {
- m_analyzeB.addResult(psnrY, psnrU, psnrV, (double)bits);
- }
- double ssim = 0.0;
- if (param.bEnableSsim && pic->getSlice()->m_ssimCnt > 0)
- {
- ssim = pic->getSlice()->m_ssim / pic->getSlice()->m_ssimCnt;
- m_globalSsim += ssim;
- }
+ TComSlice* slice = pic->getSlice();
+
+ //===== add Bits and number of pics =====
+ m_analyzeAll.addBits((double)bits);
+ if (slice->isIntra())
+ {
+ m_analyzeI.addBits((double)bits);
+ }
+ if (slice->isInterP())
+ {
+ m_analyzeP.addBits((double)bits);
+ }
+ if (slice->isInterB())
+ {
+ m_analyzeB.addBits((double)bits);
+ }
+ //===== add PSNR =====
+ if (param.bEnablePsnr)
+ {
+ m_analyzeAll.addPsnr(psnrY, psnrU, psnrV);
+
+ if (slice->isIntra())
+ {
+ m_analyzeI.addPsnr(psnrY, psnrU, psnrV);
+ }
+ if (slice->isInterP())
+ {
+ m_analyzeP.addPsnr(psnrY, psnrU, psnrV);
+ }
+ if (slice->isInterB())
+ {
+ m_analyzeB.addPsnr(psnrY, psnrU, psnrV);
+ }
+ }
+ //===== add SSIM =====
+ double ssim = 0.0;
+ if (param.bEnableSsim && pic->m_ssimCnt > 0)
+ {
+ ssim = pic->m_ssim / pic->m_ssimCnt;
+ m_analyzeAll.addSsim(ssim);
+
+ if (slice->isIntra())
+ {
+ m_analyzeI.addSsim(ssim);
+ }
+ if (slice->isInterP())
+ {
+ m_analyzeP.addSsim(ssim);
+ }
+ if (slice->isInterB())
+ {
+ m_analyzeB.addSsim(ssim);
+ }
+ }
// if debug log level is enabled, per frame logging is performed
if (param.logLevel >= X265_LOG_DEBUG)
diff -r ec6b4d35f110 -r 8bed3004d0b9 source/encoder/encoder.h
--- a/source/encoder/encoder.h Thu Oct 31 00:09:49 2013 -0500
+++ b/source/encoder/encoder.h Thu Oct 31 14:25:12 2013 +0530
@@ -27,12 +27,33 @@
#include "x265.h"
#include "TLibEncoder/TEncCfg.h"
-#include "TLibEncoder/TEncAnalyze.h"
#include "piclist.h"
struct x265_encoder {};
+struct EncStats
+{
+ double m_psnrSumY;
+ double m_psnrSumU;
+ double m_psnrSumV;
+ double m_accBits;
+ double m_globalSsim;
+ uint32_t m_numPics;
+
+ EncStats()
+ {
+ m_psnrSumY = m_psnrSumU = m_psnrSumV = m_accBits = m_numPics = 0;
+ m_globalSsim = 0;
+ }
+
+ void addPsnr(double psnrY, double psnrU, double psnrV);
+
+ void addBits(double bits);
+
+ void addSsim(double ssim);
+};
+
namespace x265 {
// private namespace
@@ -61,11 +82,10 @@
int m_curEncoder;
/* Collect statistics globally */
- TEncAnalyze m_analyzeAll;
- TEncAnalyze m_analyzeI;
- TEncAnalyze m_analyzeP;
- TEncAnalyze m_analyzeB;
- double m_globalSsim;
+ EncStats m_analyzeAll;
+ EncStats m_analyzeI;
+ EncStats m_analyzeP;
+ EncStats m_analyzeB;
FILE* m_csvfpt;
int64_t m_encodeStartTime;
diff -r ec6b4d35f110 -r 8bed3004d0b9 source/encoder/framefilter.cpp
--- a/source/encoder/framefilter.cpp Thu Oct 31 00:09:49 2013 -0500
+++ b/source/encoder/framefilter.cpp Thu Oct 31 14:25:12 2013 +0530
@@ -317,9 +317,9 @@
/* 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;
- m_pic->getSlice()->m_ssim += calculateSSIM(rec + 2 + minPixY * stride1, stride1, org + 2 + minPixY * stride2, stride2,
+ m_pic->m_ssim += calculateSSIM(rec + 2 + minPixY * stride1, stride1, org + 2 + minPixY * stride2, stride2,
m_cfg->param.sourceWidth - 2, maxPixY - minPixY, m_ssimBuf, &ssim_cnt);
- m_pic->getSlice()->m_ssimCnt += ssim_cnt;
+ m_pic->m_ssimCnt += ssim_cnt;
}
if (m_cfg->param.decodedPictureHashSEI == 1)
{
More information about the x265-devel
mailing list