diff options
author | Jan Schmidt <thaytan@noraisin.net> | 2011-06-21 14:33:29 +1000 |
---|---|---|
committer | Jan Schmidt <thaytan@noraisin.net> | 2011-06-21 14:33:29 +1000 |
commit | 3a12092ae6eb09393413887cfab6dc1cfa196c20 (patch) | |
tree | 60508f7f13a1722e87d2e8736eed319fd82d05a2 | |
parent | 8e2404b8dfe1ed6c4a23573ec01de85604487d3c (diff) |
Enable threading in ffmpeg decoders that support it.
Add a max-threads property, which defaults to '0 = auto'
Add a utility function taken from libschroedinger which sets
the ffmpeg worker thread count to match the computer processor
count by default.
-rw-r--r-- | ext/ffmpeg/gstffmpegdec.c | 26 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegutils.c | 38 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegutils.h | 2 |
3 files changed, 66 insertions, 0 deletions
diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c index 8fab659..ef76928 100644 --- a/ext/ffmpeg/gstffmpegdec.c +++ b/ext/ffmpeg/gstffmpegdec.c @@ -121,6 +121,7 @@ struct _GstFFMpegDec gboolean do_padding; gboolean debug_mv; gboolean crop; + int max_threads; /* QoS stuff *//* with LOCK */ gdouble proportion; @@ -194,6 +195,7 @@ gst_ts_info_get (GstFFMpegDec * dec, gint idx) #define DEFAULT_DO_PADDING TRUE #define DEFAULT_DEBUG_MV FALSE #define DEFAULT_CROP TRUE +#define DEFAULT_MAX_THREADS 0 enum { @@ -204,6 +206,7 @@ enum PROP_DO_PADDING, PROP_DEBUG_MV, PROP_CROP, + PROP_MAX_THREADS, PROP_LAST }; @@ -358,6 +361,8 @@ gst_ffmpegdec_class_init (GstFFMpegDecClass * klass) gobject_class->get_property = gst_ffmpegdec_get_property; if (klass->in_plugin->type == AVMEDIA_TYPE_VIDEO) { + int caps; + g_object_class_install_property (gobject_class, PROP_SKIPFRAME, g_param_spec_enum ("skip-frame", "Skip frames", "Which types of frames to skip during decoding", @@ -385,6 +390,15 @@ gst_ffmpegdec_class_init (GstFFMpegDecClass * klass) "Crop images to the display region", DEFAULT_CROP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); #endif + + caps = klass->in_plugin->capabilities; + if (caps & (CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS)) { + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MAX_THREADS, + g_param_spec_int ("max-threads", "Maximum decode threads", + "Maximum number of worker threads to spawn. (0 = auto)", + 0, G_MAXINT, DEFAULT_MAX_THREADS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + } } gstelement_class->change_state = gst_ffmpegdec_change_state; @@ -428,6 +442,7 @@ gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec) ffmpegdec->do_padding = DEFAULT_DO_PADDING; ffmpegdec->debug_mv = DEFAULT_DEBUG_MV; ffmpegdec->crop = DEFAULT_CROP; + ffmpegdec->max_threads = DEFAULT_MAX_THREADS; ffmpegdec->format.video.par_n = -1; ffmpegdec->format.video.fps_n = -1; @@ -849,6 +864,11 @@ gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps) * supports it) */ ffmpegdec->context->debug_mv = ffmpegdec->debug_mv; + if (ffmpegdec->max_threads == 0) + ffmpegdec->context->thread_count = gst_ffmpeg_auto_max_threads (); + else + ffmpegdec->context->thread_count = ffmpegdec->max_threads; + /* open codec - we don't select an output pix_fmt yet, * simply because we don't know! We only get it * during playback... */ @@ -2794,6 +2814,9 @@ gst_ffmpegdec_set_property (GObject * object, case PROP_CROP: ffmpegdec->crop = g_value_get_boolean (value); break; + case PROP_MAX_THREADS: + ffmpegdec->max_threads = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2825,6 +2848,9 @@ gst_ffmpegdec_get_property (GObject * object, case PROP_CROP: g_value_set_boolean (value, ffmpegdec->crop); break; + case PROP_MAX_THREADS: + g_value_set_int (value, ffmpegdec->max_threads); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/ext/ffmpeg/gstffmpegutils.c b/ext/ffmpeg/gstffmpegutils.c index 89a564e..d039914 100644 --- a/ext/ffmpeg/gstffmpegutils.c +++ b/ext/ffmpeg/gstffmpegutils.c @@ -21,6 +21,10 @@ #include "config.h" #endif #include "gstffmpegutils.h" +#include <unistd.h> +#ifdef __APPLE__ +#include <sys/sysctl.h> +#endif G_CONST_RETURN gchar * gst_ffmpeg_get_codecid_longname (enum CodecID codec_id) @@ -443,3 +447,37 @@ new_aligned_buffer (gint size, GstCaps * caps) return buf; } + +int +gst_ffmpeg_auto_max_threads (void) +{ + static gsize n_threads = 0; + if (g_once_init_enter (&n_threads)) { + int n = 1; +#if defined(_WIN32) + { + const char *s = getenv ("NUMBER_OF_PROCESSORS"); + if (s) { + n = atoi (s); + } + } +#elif defined(__APPLE__) + { + int mib[] = { CTL_HW, HW_NCPU }; + size_t dataSize = sizeof (int); + + if (sysctl (mib, 2, &n_threads, &dataSize, NULL, 0)) { + n = 1; + } + } +#else + n = sysconf (_SC_NPROCESSORS_CONF); +#endif + if (n < 1) + n = 1; + + g_once_init_leave (&n_threads, n); + } + + return (int) (n_threads); +} diff --git a/ext/ffmpeg/gstffmpegutils.h b/ext/ffmpeg/gstffmpegutils.h index a75ed01..4b713de 100644 --- a/ext/ffmpeg/gstffmpegutils.h +++ b/ext/ffmpeg/gstffmpegutils.h @@ -80,6 +80,8 @@ gst_ffmpeg_time_gst_to_ff (guint64 time, AVRational base) void gst_ffmpeg_init_pix_fmt_info(void); +int +gst_ffmpeg_auto_max_threads(void); G_CONST_RETURN gchar * gst_ffmpeg_get_codecid_longname (enum CodecID codec_id); |