[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(&param, 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