Commit 0d95d925 authored by Thibault Saunier's avatar Thibault Saunier 🌵 Committed by GStreamer Merge Bot

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 #126

Part-of: <!222>
parent 8e9e95b9
Pipeline #260637 waiting for manual action with stages
in 21 seconds
......@@ -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
......
......@@ -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);
......
......@@ -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
......@@ -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;
}
......@@ -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
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment