mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 21:21:12 +00:00
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>
This commit is contained in:
parent
8e9e95b90a
commit
0d95d9258b
6 changed files with 77 additions and 14 deletions
|
@ -136,7 +136,8 @@ ges_audio_uri_source_class_init (GESAudioUriSourceClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GESTimelineElementClass *element_class = GES_TIMELINE_ELEMENT_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->get_property = ges_audio_uri_source_get_property;
|
||||||
object_class->set_property = ges_audio_uri_source_set_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;
|
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
|
static void
|
||||||
|
|
|
@ -82,8 +82,15 @@ _set_ghost_pad_target (GESSource * self, GstPad * srcpad, GstElement * element)
|
||||||
{
|
{
|
||||||
GstPadLinkReturn link_return;
|
GstPadLinkReturn link_return;
|
||||||
GESSourcePrivate *priv = self->priv;
|
GESSourcePrivate *priv = self->priv;
|
||||||
|
GESSourceClass *source_klass = GES_SOURCE_GET_CLASS (self);
|
||||||
gboolean use_converter = ! !priv->first_converter;
|
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) {
|
if (use_converter && priv->is_rendering_smartly) {
|
||||||
GstPad *pad = gst_element_get_static_pad (priv->first_converter, "sink");
|
GstPad *pad = gst_element_get_static_pad (priv->first_converter, "sink");
|
||||||
use_converter = gst_pad_can_link (srcpad, pad);
|
use_converter = gst_pad_can_link (srcpad, pad);
|
||||||
|
|
|
@ -55,9 +55,21 @@ struct _GESSourceClass {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GESTrackElementClass parent_class;
|
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 */
|
/* Padding for API extension */
|
||||||
gpointer _ges_reserved[GES_PADDING];
|
gpointer _ges_reserved[GES_PADDING - 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -71,13 +71,17 @@ autoplug_select_cb (GstElement * bin, GstPad * pad, GstCaps * caps,
|
||||||
(ges_extractable_get_asset (GES_EXTRACTABLE (self->element)))));
|
(ges_extractable_get_asset (GES_EXTRACTABLE (self->element)))));
|
||||||
gboolean wanted = !g_strcmp0 (stream_id, wanted_id);
|
gboolean wanted = !g_strcmp0 (stream_id, wanted_id);
|
||||||
|
|
||||||
|
|
||||||
if (!ges_source_get_rendering_smartly (GES_SOURCE (self->element))) {
|
if (!ges_source_get_rendering_smartly (GES_SOURCE (self->element))) {
|
||||||
if (!wanted && are_raw_caps (caps)) {
|
if (!are_raw_caps (caps))
|
||||||
GST_DEBUG_OBJECT (self->element, "Totally skipping %s", stream_id);
|
goto done;
|
||||||
|
|
||||||
|
if (!wanted) {
|
||||||
|
GST_INFO_OBJECT (self->element, "Not matching stream id: %s -> SKIPPING",
|
||||||
|
stream_id);
|
||||||
res = GST_AUTOPLUG_SELECT_SKIP;
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,3 +187,37 @@ ges_uri_source_init (GESTrackElement * element, GESUriSource * self)
|
||||||
g_signal_connect (element, "notify::track",
|
g_signal_connect (element, "notify::track",
|
||||||
G_CALLBACK (ges_uri_source_track_set_cb), self);
|
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;
|
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_GNUC_INTERNAL void ges_uri_source_init (GESTrackElement *element, GESUriSource *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -297,7 +297,8 @@ static void
|
||||||
ges_video_uri_source_class_init (GESVideoUriSourceClass * klass)
|
ges_video_uri_source_class_init (GESVideoUriSourceClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (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->get_property = ges_video_uri_source_get_property;
|
||||||
object_class->set_property = ges_video_uri_source_set_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",
|
g_param_spec_string ("uri", "URI", "uri of the resource",
|
||||||
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
|
||||||
source_class->create_source = ges_video_uri_source_create_source;
|
src_class->select_pad = ges_uri_source_select_pad;
|
||||||
source_class->ABI.abi.needs_converters =
|
|
||||||
|
video_src_class->create_source = ges_video_uri_source_create_source;
|
||||||
|
video_src_class->ABI.abi.needs_converters =
|
||||||
ges_video_uri_source_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;
|
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
|
static void
|
||||||
|
|
Loading…
Reference in a new issue