[Spice-devel,v16,10/23] streaming: Use the optimal number of threads for VP8 encoding

Submitted by Francois Gouget on June 7, 2016, 1:59 p.m.

Details

Message ID 96fdab2338fbd9fd2d31a0ba79f19ff81f1cea58.1465306176.git.fgouget@free.fr
State New
Headers show
Series "Add GStreamer support for video streaming" ( rev: 22 21 20 19 18 ) in Spice

Not browsing as part of any series.

Commit Message

Francois Gouget June 7, 2016, 1:59 p.m.
Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
---
 configure.ac               |  4 ++++
 server/gstreamer-encoder.c | 27 ++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/configure.ac b/configure.ac
index ac08410..650ea4a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,6 +128,10 @@  AC_SUBST([SPICE_PROTOCOL_MIN_VER])
 PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.22])
 AS_VAR_APPEND([SPICE_REQUIRES], [" glib-2.0 >= 2.22"])
 
+AC_CHECK_LIB(glib-2.0, g_get_num_processors,
+             AC_DEFINE([HAVE_G_GET_NUMPROCESSORS], 1, [Defined if we have g_get_num_processors()]),,
+             $GLIB2_LIBS)
+
 PKG_CHECK_MODULES([GOBJECT2], [gobject-2.0 >= 2.22])
 AS_VAR_APPEND([SPICE_REQUIRES], [" gobject-2.0 >= 2.22"])
 
diff --git a/server/gstreamer-encoder.c b/server/gstreamer-encoder.c
index e0d4d3a..e0b10b3 100644
--- a/server/gstreamer-encoder.c
+++ b/server/gstreamer-encoder.c
@@ -189,6 +189,25 @@  static void set_appsrc_caps(SpiceGstEncoder *encoder)
     gst_app_src_set_caps(encoder->appsrc, encoder->src_caps);
 }
 
+static int physical_core_count = 0;
+static int get_physical_core_count(void)
+{
+    if (!physical_core_count) {
+#ifdef HAVE_G_GET_NUMPROCESSORS
+        physical_core_count = g_get_num_processors();
+#endif
+        if (system("egrep -l '^flags\\b.*: .*\\bht\\b' /proc/cpuinfo >/dev/null 2>&1") == 0) {
+            /* Hyperthreading is enabled so divide by two to get the number
+             * of physical cores.
+             */
+            physical_core_count = physical_core_count / 2;
+        }
+        if (physical_core_count == 0)
+            physical_core_count = 1;
+    }
+    return physical_core_count;
+}
+
 /* A helper for spice_gst_encoder_encode_frame() */
 static gboolean create_pipeline(SpiceGstEncoder *encoder)
 {
@@ -214,8 +233,14 @@  static gboolean create_pipeline(SpiceGstEncoder *encoder)
          *   CPU usage.
          * - deadline is supposed to be set in microseconds but in practice
          *   it behaves like a boolean.
+         * - At least up to GStreamer 1.6.2, vp8enc cannot be trusted to pick
+         *   the optimal number of threads. Also exceeding the number of
+         *   physical core really degrades image quality.
+         * - token-partitions parallelizes more operations.
          */
-        gstenc = g_strdup_printf("vp8enc end-usage=cbr min-quantizer=10 error-resilient=default lag-in-frames=0 deadline=1 cpu-used=4");
+        int threads = get_physical_core_count();
+        int parts = threads < 2 ? 0 : threads < 4 ? 1 : threads < 8 ? 2 : 3;
+        gstenc = g_strdup_printf("vp8enc end-usage=cbr min-quantizer=10 error-resilient=default lag-in-frames=0 deadline=1 cpu-used=4 threads=%d token-partitions=%d", threads, parts);
         break;
         }
     default: