summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungha Yang <seungha.yang@navercorp.com>2018-10-06 18:51:58 +0900
committerMathieu Duponchelle <mathieu@centricular.com>2019-07-18 00:05:21 +0200
commite8f21b510a7cad1215bc698d519bd30e9c9e340c (patch)
tree8ac70ccc216ed6748cf8a7877f9778527deac78f
parent4d3cd3983aba981431bbd18d4daf50f350847d5c (diff)
avviddec: Add thread-type property
The thread-type property allows specifying preferred multithreading methods by user. Note that FF_THREAD_FRAME may introduce additional latency especially on non-filesrc usecase, since it introduces a decoding delay of (number of threads) frames. https://bugzilla.gnome.org/show_bug.cgi?id=797254
-rw-r--r--ext/libav/gstavviddec.c57
-rw-r--r--ext/libav/gstavviddec.h1
2 files changed, 49 insertions, 9 deletions
diff --git a/ext/libav/gstavviddec.c b/ext/libav/gstavviddec.c
index 8611649..3469279 100644
--- a/ext/libav/gstavviddec.c
+++ b/ext/libav/gstavviddec.c
@@ -46,6 +46,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
#define REQUIRED_POOL_MAX_BUFFERS 32
#define DEFAULT_STRIDE_ALIGN 31
#define DEFAULT_ALLOC_PARAM { 0, DEFAULT_STRIDE_ALIGN, 0, 0, }
+#define DEFAULT_THREAD_TYPE 0
enum
{
@@ -56,6 +57,7 @@ enum
PROP_DEBUG_MV,
PROP_MAX_THREADS,
PROP_OUTPUT_CORRUPT,
+ PROP_THREAD_TYPE,
PROP_LAST
};
@@ -144,6 +146,27 @@ gst_ffmpegviddec_skipframe_get_type (void)
return ffmpegdec_skipframe_type;
}
+static const GFlagsValue ffmpegdec_thread_types[] = {
+ {0x0, "Auto", "auto"},
+ {0x1, "Frame", "frame"},
+ {0x2, "Slice", "slice"},
+ {0, NULL, NULL},
+};
+
+#define GST_FFMPEGVIDDEC_TYPE_THREAD_TYPE (gst_ffmpegviddec_thread_type_get_type())
+static GType
+gst_ffmpegviddec_thread_type_get_type (void)
+{
+ static GType ffmpegdec_thread_type_type = 0;
+
+ if (!ffmpegdec_thread_type_type) {
+ ffmpegdec_thread_type_type =
+ g_flags_register_static ("GstLibAVVidDecThreadType",
+ ffmpegdec_thread_types);
+ }
+ return ffmpegdec_thread_type_type;
+}
+
static void
gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass)
{
@@ -240,6 +263,11 @@ gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
"Maximum number of worker threads to spawn. (0 = auto)",
0, G_MAXINT, DEFAULT_MAX_THREADS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_THREAD_TYPE,
+ g_param_spec_flags ("thread-type", "Thread type",
+ "Multithreading methods to use",
+ GST_FFMPEGVIDDEC_TYPE_THREAD_TYPE,
+ DEFAULT_THREAD_TYPE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
viddec_class->set_format = gst_ffmpegviddec_set_format;
@@ -271,6 +299,7 @@ gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec)
ffmpegdec->debug_mv = DEFAULT_DEBUG_MV;
ffmpegdec->max_threads = DEFAULT_MAX_THREADS;
ffmpegdec->output_corrupt = DEFAULT_OUTPUT_CORRUPT;
+ ffmpegdec->thread_type = DEFAULT_THREAD_TYPE;
GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (ffmpegdec));
gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST
@@ -489,18 +518,22 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
* supports it) */
ffmpegdec->context->debug_mv = ffmpegdec->debug_mv;
- {
+ if (ffmpegdec->max_threads == 0) {
+ if (!(oclass->in_plugin->capabilities & AV_CODEC_CAP_AUTO_THREADS))
+ ffmpegdec->context->thread_count = gst_ffmpeg_auto_max_threads ();
+ else
+ ffmpegdec->context->thread_count = 0;
+ } else
+ ffmpegdec->context->thread_count = ffmpegdec->max_threads;
+
+ if (ffmpegdec->thread_type) {
+ GST_DEBUG_OBJECT (ffmpegdec, "Use requested thread type 0x%x",
+ ffmpegdec->thread_type);
+ ffmpegdec->context->thread_type = ffmpegdec->thread_type;
+ } else {
GstQuery *query;
gboolean is_live;
- if (ffmpegdec->max_threads == 0) {
- if (!(oclass->in_plugin->capabilities & AV_CODEC_CAP_AUTO_THREADS))
- ffmpegdec->context->thread_count = gst_ffmpeg_auto_max_threads ();
- else
- ffmpegdec->context->thread_count = 0;
- } else
- ffmpegdec->context->thread_count = ffmpegdec->max_threads;
-
query = gst_query_new_latency ();
is_live = FALSE;
/* Check if upstream is live. If it isn't we can enable frame based
@@ -2255,6 +2288,9 @@ gst_ffmpegviddec_set_property (GObject * object,
case PROP_OUTPUT_CORRUPT:
ffmpegdec->output_corrupt = g_value_get_boolean (value);
break;
+ case PROP_THREAD_TYPE:
+ ffmpegdec->thread_type = g_value_get_flags (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -2286,6 +2322,9 @@ gst_ffmpegviddec_get_property (GObject * object,
case PROP_OUTPUT_CORRUPT:
g_value_set_boolean (value, ffmpegdec->output_corrupt);
break;
+ case PROP_THREAD_TYPE:
+ g_value_set_flags (value, ffmpegdec->thread_type);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/ext/libav/gstavviddec.h b/ext/libav/gstavviddec.h
index a25d50a..a4ee1a0 100644
--- a/ext/libav/gstavviddec.h
+++ b/ext/libav/gstavviddec.h
@@ -69,6 +69,7 @@ struct _GstFFMpegVidDec
gboolean debug_mv;
int max_threads;
gboolean output_corrupt;
+ guint thread_type;
GstCaps *last_caps;