Signed-off-by: Francois Gouget <fgouget@xxxxxxxxxxxxxxx> --- This patch is mostly optional: skipping it will only cause conflicts in the following server patches: server: Give up after a while if GStreamer cannot handle the video server: Add support for GStreamer 0.10 The code would still be functional without them and resubmitting them would be easy. configure.ac | 4 ++++ server/gstreamer-encoder.c | 27 ++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e60a005..c82c3f9 100644 --- a/configure.ac +++ b/configure.ac @@ -129,6 +129,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 5e6e52c..09e3678 100644 --- a/server/gstreamer-encoder.c +++ b/server/gstreamer-encoder.c @@ -188,6 +188,25 @@ static void set_appsrc_caps(SpiceGstEncoder *encoder) g_object_set(G_OBJECT(encoder->appsrc), "caps", encoder->src_caps, NULL); } +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) { @@ -211,8 +230,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 resize-allowed=true error-resilient=true 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 resize-allowed=true error-resilient=true lag-in-frames=0 deadline=1 cpu-used=4 threads=%d token-partitions=%d", threads, parts); break; } default: -- 2.7.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel