summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@igalia.com>2020-12-13 22:54:37 -0300
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-01-23 04:27:07 +0000
commit0d95d9258b9700d1d7da5cf562c30aef2b865a93 (patch)
treee6ebd785cfa3a97c35ae23fb6c296402036f8bf9
parent8e9e95b90a4c68364155b9e5e7cff5a4b5ca36a4 (diff)
uri-source: Respect stream-id even on streams muxed in raw
The issue is that we rely on `decodebin::autoplug-select` to `SKIP` unwanted pads, that signal was first provided to select factories during autoplugin, not totally thought to avoid exposing pads. For streams muxed directly in raw, decodebin has nothing to plug after the demuxer and the pad is exposed right away, meaning that we do not have any chance to avoid that pad to be exposed. This patch takes that limitation into account and checks the stream ID of the pads exposed by decodebin before exposing them itself, so we end up using the right pad even if more are uselessly exposed by decodebin. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/126 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/222>
-rw-r--r--ges/ges-audio-uri-source.c6
-rw-r--r--ges/ges-source.c7
-rw-r--r--ges/ges-source.h16
-rw-r--r--ges/ges-uri-source.c46
-rw-r--r--ges/ges-uri-source.h3
-rw-r--r--ges/ges-video-uri-source.c13
6 files changed, 77 insertions, 14 deletions
diff --git a/ges/ges-audio-uri-source.c b/ges/ges-audio-uri-source.c
index bc96a3b5..ce3af096 100644
--- a/ges/ges-audio-uri-source.c
+++ b/ges/ges-audio-uri-source.c
@@ -136,7 +136,8 @@ ges_audio_uri_source_class_init (GESAudioUriSourceClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GESTimelineElementClass *element_class = GES_TIMELINE_ELEMENT_CLASS (klass);
- GESAudioSourceClass *source_class = GES_AUDIO_SOURCE_CLASS (klass);
+ GESSourceClass *src_class = GES_SOURCE_CLASS (klass);
+ GESAudioSourceClass *audio_src_class = GES_AUDIO_SOURCE_CLASS (klass);
object_class->get_property = ges_audio_uri_source_get_property;
object_class->set_property = ges_audio_uri_source_set_property;
@@ -153,7 +154,8 @@ ges_audio_uri_source_class_init (GESAudioUriSourceClass * klass)
element_class->get_natural_framerate = _get_natural_framerate;
- source_class->create_source = ges_audio_uri_source_create_source;
+ src_class->select_pad = ges_uri_source_select_pad;
+ audio_src_class->create_source = ges_audio_uri_source_create_source;
}
static void
diff --git a/ges/ges-source.c b/ges/ges-source.c
index 5a3b85fb..73868601 100644
--- a/ges/ges-source.c
+++ b/ges/ges-source.c
@@ -82,8 +82,15 @@ _set_ghost_pad_target (GESSource * self, GstPad * srcpad, GstElement * element)
{
GstPadLinkReturn link_return;
GESSourcePrivate *priv = self->priv;
+ GESSourceClass *source_klass = GES_SOURCE_GET_CLASS (self);
gboolean use_converter = ! !priv->first_converter;
+ if (source_klass->select_pad && !source_klass->select_pad (self, srcpad)) {
+ GST_INFO_OBJECT (self, "Ignoring pad %" GST_PTR_FORMAT, srcpad);
+ return;
+ }
+
+
if (use_converter && priv->is_rendering_smartly) {
GstPad *pad = gst_element_get_static_pad (priv->first_converter, "sink");
use_converter = gst_pad_can_link (srcpad, pad);
diff --git a/ges/ges-source.h b/ges/ges-source.h
index a243d99c..022297ee 100644
--- a/ges/ges-source.h
+++ b/ges/ges-source.h
@@ -55,9 +55,21 @@ struct _GESSourceClass {
/*< private >*/
GESTrackElementClass parent_class;
- /*< private >*/
+ /**
+ * GESSourceClass::select_pad:
+ * @source: The @source for which to check if @pad should be used or not
+ * @pad: The pad to check
+ *
+ * Check whether @pad should be exposed/used.
+ *
+ * Returns: %TRUE if @pad should be used %FALSE otherwise.
+ *
+ * Since: 1.20
+ */
+ gboolean (*select_pad)(GESSource *source, GstPad *pad);
+
/* Padding for API extension */
- gpointer _ges_reserved[GES_PADDING];
+ gpointer _ges_reserved[GES_PADDING - 1];
};
G_END_DECLS
diff --git a/ges/ges-uri-source.c b/ges/ges-uri-source.c
index d828eb77..1775db4c 100644
--- a/ges/ges-uri-source.c
+++ b/ges/ges-uri-source.c
@@ -71,13 +71,17 @@ autoplug_select_cb (GstElement * bin, GstPad * pad, GstCaps * caps,
(ges_extractable_get_asset (GES_EXTRACTABLE (self->element)))));
gboolean wanted = !g_strcmp0 (stream_id, wanted_id);
-
if (!ges_source_get_rendering_smartly (GES_SOURCE (self->element))) {
- if (!wanted && are_raw_caps (caps)) {
- GST_DEBUG_OBJECT (self->element, "Totally skipping %s", stream_id);
+ if (!are_raw_caps (caps))
+ goto done;
+
+ if (!wanted) {
+ GST_INFO_OBJECT (self->element, "Not matching stream id: %s -> SKIPPING",
+ stream_id);
res = GST_AUTOPLUG_SELECT_SKIP;
+ } else {
+ GST_INFO_OBJECT (self->element, "Using stream %s", stream_id);
}
- GST_LOG_OBJECT (self->element, "Not being smart here");
goto done;
}
@@ -183,3 +187,37 @@ ges_uri_source_init (GESTrackElement * element, GESUriSource * self)
g_signal_connect (element, "notify::track",
G_CALLBACK (ges_uri_source_track_set_cb), self);
}
+
+gboolean
+ges_uri_source_select_pad (GESSource * self, GstPad * pad)
+{
+ gboolean res = TRUE;
+ gboolean is_nested_timeline;
+ GESUriSourceAsset *asset =
+ GES_URI_SOURCE_ASSET (ges_extractable_get_asset (GES_EXTRACTABLE (self)));
+ const GESUriClipAsset *clip_asset =
+ ges_uri_source_asset_get_filesource_asset (asset);
+ const gchar *wanted_stream_id = ges_asset_get_id (GES_ASSET (asset));
+ gchar *stream_id;
+
+ if (clip_asset) {
+ g_object_get (G_OBJECT (clip_asset), "is-nested-timeline",
+ &is_nested_timeline, NULL);
+
+ if (is_nested_timeline) {
+ GST_DEBUG_OBJECT (self, "Nested timeline track selection is handled"
+ " by the timeline SELECT_STREAM events handling.");
+
+ return TRUE;
+ }
+ }
+
+ stream_id = gst_pad_get_stream_id (pad);
+ res = !g_strcmp0 (stream_id, wanted_stream_id);
+
+ GST_INFO_OBJECT (self, "%s pad with stream id: %s as %s wanted",
+ res ? "Using" : "Ignoring", stream_id, wanted_stream_id);
+ g_free (stream_id);
+
+ return res;
+}
diff --git a/ges/ges-uri-source.h b/ges/ges-uri-source.h
index 7a8fba21..86b35adb 100644
--- a/ges/ges-uri-source.h
+++ b/ges/ges-uri-source.h
@@ -35,7 +35,8 @@ struct _GESUriSource
GESTrackElement *element;
};
-G_GNUC_INTERNAL GstElement * ges_uri_source_create_source (GESUriSource *self);
+G_GNUC_INTERNAL gboolean ges_uri_source_select_pad (GESSource *self, GstPad *pad);
+G_GNUC_INTERNAL GstElement *ges_uri_source_create_source (GESUriSource *self);
G_GNUC_INTERNAL void ges_uri_source_init (GESTrackElement *element, GESUriSource *self);
G_END_DECLS
diff --git a/ges/ges-video-uri-source.c b/ges/ges-video-uri-source.c
index f7426b14..4e8de057 100644
--- a/ges/ges-video-uri-source.c
+++ b/ges/ges-video-uri-source.c
@@ -297,7 +297,8 @@ static void
ges_video_uri_source_class_init (GESVideoUriSourceClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GESVideoSourceClass *source_class = GES_VIDEO_SOURCE_CLASS (klass);
+ GESSourceClass *src_class = GES_SOURCE_CLASS (klass);
+ GESVideoSourceClass *video_src_class = GES_VIDEO_SOURCE_CLASS (klass);
object_class->get_property = ges_video_uri_source_get_property;
object_class->set_property = ges_video_uri_source_set_property;
@@ -312,12 +313,14 @@ ges_video_uri_source_class_init (GESVideoUriSourceClass * klass)
g_param_spec_string ("uri", "URI", "uri of the resource",
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- source_class->create_source = ges_video_uri_source_create_source;
- source_class->ABI.abi.needs_converters =
+ src_class->select_pad = ges_uri_source_select_pad;
+
+ video_src_class->create_source = ges_video_uri_source_create_source;
+ video_src_class->ABI.abi.needs_converters =
ges_video_uri_source_needs_converters;
- source_class->ABI.abi.get_natural_size =
+ video_src_class->ABI.abi.get_natural_size =
ges_video_uri_source_get_natural_size;
- source_class->ABI.abi.create_filters = ges_video_uri_source_create_filters;
+ video_src_class->ABI.abi.create_filters = ges_video_uri_source_create_filters;
}
static void