From c6baee26229972984abcf709f6e8516f504c51c5 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Fri, 21 Jan 2011 19:33:11 +0100 Subject: [PATCH] recorder: Switch to webm The vp8 codec provides better performance in pretty much all cases compared to theora while still being free (as in not patent encumbered). Also add a %T placeholder to the pipeline string which will be replaced with the a thread count based on the target system. https://bugzilla.gnome.org/show_bug.cgi?id=632595 --- data/org.gnome.shell.gschema.xml.in | 6 ++-- src/shell-recorder.c | 47 ++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in index c19463099..d45cba319 100644 --- a/data/org.gnome.shell.gschema.xml.in +++ b/data/org.gnome.shell.gschema.xml.in @@ -101,11 +101,13 @@ take care of its own output - this might be used to send the output to an icecast server via shout2send or similar. When unset or set to an empty value, the default pipeline will be used. This is currently - 'videorate ! theoraenc ! oggmux' and records to Ogg Theora. + 'videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux' + and records to WEBM using the VP8 codec. %T is used as a placeholder + for a guess at the optimal thread count on the system. - 'ogv' + 'webm' <_summary>File extension used for storing the screencast <_description> The filename for recorded screencasts will be a unique filename diff --git a/src/shell-recorder.c b/src/shell-recorder.c index 57377bd82..a1c626b41 100644 --- a/src/shell-recorder.c +++ b/src/shell-recorder.c @@ -147,11 +147,11 @@ G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT); * (Theora does have some support for frames at non-uniform times, but * things seem to break down if there are large gaps.) */ -#define DEFAULT_PIPELINE "videorate ! theoraenc ! oggmux" +#define DEFAULT_PIPELINE "videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux" -/* The default filename pattern. Example shell-20090311b-2.ogg +/* The default filename pattern. Example shell-20090311b-2.webm */ -#define DEFAULT_FILENAME "shell-%d%u-%c.ogg" +#define DEFAULT_FILENAME "shell-%d%u-%c.webm" /* If we can find the amount of memory on the machine, we use half * of that for memory_target, otherwise, we use this value, in kB. @@ -1493,11 +1493,47 @@ recorder_pipeline_closed (RecorderPipeline *pipeline) recorder_pipeline_free (pipeline); } +/* + * Replaces '%T' in the passed pipeline with the thread count, + * the maximum possible value is 64 (limit of what vp8enc supports) + * + * It is assumes that %T occurs only once. + */ +static char* +substitute_thread_count (const char *pipeline) +{ + char *tmp; + int n_threads; + GString *result; + + tmp = strstr (pipeline, "%T"); + + if (!tmp) + return g_strdup (pipeline); + +#ifdef _SC_NPROCESSORS_ONLN + { + int n_processors = sysconf (_SC_NPROCESSORS_ONLN); /* includes hyper-threading */ + n_threads = MIN (MAX (1, n_processors - 1), 64); + } +#else + n_threads = 3; +#endif + + result = g_string_new (NULL); + g_string_append_len (result, pipeline, tmp - pipeline); + g_string_append_printf (result, "%d", n_threads); + g_string_append (result, tmp + 2); + + return g_string_free (result, FALSE);; +} + static gboolean recorder_open_pipeline (ShellRecorder *recorder) { RecorderPipeline *pipeline; const char *pipeline_description; + char *parsed_pipeline; GError *error = NULL; GstBus *bus; @@ -1509,9 +1545,12 @@ recorder_open_pipeline (ShellRecorder *recorder) if (!pipeline_description) pipeline_description = DEFAULT_PIPELINE; - pipeline->pipeline = gst_parse_launch_full (pipeline_description, NULL, + parsed_pipeline = substitute_thread_count (pipeline_description); + + pipeline->pipeline = gst_parse_launch_full (parsed_pipeline, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &error); + g_free (parsed_pipeline); if (pipeline->pipeline == NULL) {