[x265] [PATCH 4 of 9] api: make x265_encoder_get_stats() somewhat future proof

Steve Borho steve at borho.org
Tue Nov 19 08:41:15 CET 2013


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1384825870 21600
#      Mon Nov 18 19:51:10 2013 -0600
# Node ID c56f65c702978bf47b256528b503dd62602696dd
# Parent  ba9cb99c569329d13c66fd519f3f5ce8931c535c
api: make x265_encoder_get_stats() somewhat future proof

By passing in the size of x265_stats as the user application knows about the
encoder can know not to try to set new fields that were added to the end of
x265_stats.  This requires some discipline on our part to only append to the
structure and to always check the size for any new fields we might add.

diff -r ba9cb99c5693 -r c56f65c70297 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Mon Nov 18 19:37:45 2013 -0600
+++ b/source/encoder/encoder.cpp	Mon Nov 18 19:51:10 2013 -0600
@@ -478,29 +478,35 @@
     }
 }
 
-void Encoder::fetchStats(x265_stats *stats)
+void Encoder::fetchStats(x265_stats *stats, size_t statsSizeBytes)
 {
-    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.m_accBits;
-    stats->elapsedEncodeTime = (double)(x265_mdate() - m_encodeStartTime) / 1000000;
-    if (stats->encodedPictureCount > 0)
+    if (statsSizeBytes >= sizeof(stats))
     {
-        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;
+        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.m_accBits;
+        stats->elapsedEncodeTime = (double)(x265_mdate() - m_encodeStartTime) / 1000000;
+        if (stats->encodedPictureCount > 0)
+        {
+            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;
+        }
+        else
+        {
+            stats->globalSsim = 0;
+            stats->globalPsnr = 0;
+            stats->bitrate = 0;
+            stats->elapsedVideoTime = 0;
+        }
     }
-    else
-    {
-        stats->globalSsim = 0;
-        stats->globalPsnr = 0;
-        stats->bitrate = 0;
-        stats->elapsedVideoTime = 0;
-    }
+    /* If new statistics are added to x265_stats, we must check here whether the
+     * structure provided by the user is the new structure or an older one (for
+     * future safety) */
 }
 
 void Encoder::writeLog(int argc, char **argv)
@@ -524,7 +530,7 @@
         fprintf(m_csvfpt, ", %s, ", buffer);
 
         x265_stats stats;
-        fetchStats(&stats);
+        fetchStats(&stats, sizeof(stats));
 
         // elapsed time, fps, bitrate
         fprintf(m_csvfpt, "%.2f, %.2f, %.2f,",
@@ -1484,11 +1490,11 @@
 EXTERN_CYCLE_COUNTER(ME);
 
 extern "C"
-void x265_encoder_get_stats(x265_encoder *enc, x265_stats *outputStats)
+void x265_encoder_get_stats(x265_encoder *enc, x265_stats *outputStats, uint32_t statsSizeBytes)
 {
     Encoder *encoder = static_cast<Encoder*>(enc);
 
-    encoder->fetchStats(outputStats);
+    encoder->fetchStats(outputStats, statsSizeBytes);
 }
 
 extern "C"
diff -r ba9cb99c5693 -r c56f65c70297 source/encoder/encoder.h
--- a/source/encoder/encoder.h	Mon Nov 18 19:37:45 2013 -0600
+++ b/source/encoder/encoder.h	Mon Nov 18 19:51:10 2013 -0600
@@ -116,7 +116,7 @@
 
     int getStreamHeaders(NALUnitEBSP **nalunits);
 
-    void fetchStats(x265_stats* stats);
+    void fetchStats(x265_stats* stats, size_t statsSizeBytes);
 
     void writeLog(int argc, char **argv);
 
diff -r ba9cb99c5693 -r c56f65c70297 source/x265.cpp
--- a/source/x265.cpp	Mon Nov 18 19:37:45 2013 -0600
+++ b/source/x265.cpp	Mon Nov 18 19:51:10 2013 -0600
@@ -653,7 +653,7 @@
     if (cliopt.bProgress)
         fprintf(stderr, "                                                                               \r");
 
-    x265_encoder_get_stats(encoder, &stats);
+    x265_encoder_get_stats(encoder, &stats, sizeof(stats));
     if (param.csvfn && !b_ctrl_c)
         x265_encoder_log(encoder, argc, argv);
     x265_encoder_close(encoder);
diff -r ba9cb99c5693 -r c56f65c70297 source/x265.h
--- a/source/x265.h	Mon Nov 18 19:37:45 2013 -0600
+++ b/source/x265.h	Mon Nov 18 19:51:10 2013 -0600
@@ -234,6 +234,8 @@
     uint32_t  encodedPictureCount;  /* number of output pictures thus far */
     uint32_t  totalWPFrames;        /* number of uni-directional weighted frames used */
     uint64_t  accBits;              /* total bits output thus far */
+
+    /* new statistic member variables must be added below this line */
 } x265_stats;
 
 /* Input parameters to the encoder */
@@ -429,7 +431,7 @@
 
 /* x265_encoder_get_stats:
  *       returns encoder statistics */
-void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *);
+void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *, uint32_t statsSizeBytes);
 
 /* x265_encoder_log:
  *       write a line to the configured CSV file.  If a CSV filename was not


More information about the x265-devel mailing list