mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
ges: support and handle no-more-pads in GESTimeline(Pipeline)
... to arrange for a clean READY to PAUSED state change transition. Not doing so might have playsink reaching PAUSED prematurely as one track prerolls, only to lose this state again (temporarily) when the other track needs to preroll. This is generally not nice or convenient, and particularly nasty when trying to perform seek in PAUSED.
This commit is contained in:
parent
ee237ec523
commit
2162c635e2
2 changed files with 55 additions and 2 deletions
|
@ -44,6 +44,7 @@ typedef struct
|
||||||
GstPad *srcpad; /* Timeline source pad */
|
GstPad *srcpad; /* Timeline source pad */
|
||||||
GstPad *playsinkpad;
|
GstPad *playsinkpad;
|
||||||
GstPad *encodebinpad;
|
GstPad *encodebinpad;
|
||||||
|
GstPad *blocked_pad;
|
||||||
} OutputChain;
|
} OutputChain;
|
||||||
|
|
||||||
G_DEFINE_TYPE (GESTimelinePipeline, ges_timeline_pipeline, GST_TYPE_PIPELINE);
|
G_DEFINE_TYPE (GESTimelinePipeline, ges_timeline_pipeline, GST_TYPE_PIPELINE);
|
||||||
|
@ -382,6 +383,13 @@ no_pad:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pad_blocked (GstPad * pad, gboolean blocked, gpointer user_data)
|
||||||
|
{
|
||||||
|
/* no nothing */
|
||||||
|
GST_DEBUG_OBJECT (pad, "blocked callback, blocked: %d", blocked);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pad_added_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
|
pad_added_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
|
||||||
{
|
{
|
||||||
|
@ -466,7 +474,9 @@ pad_added_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
|
||||||
gst_object_unref (tmppad);
|
gst_object_unref (tmppad);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
gst_object_unref (tmppad);
|
chain->blocked_pad = tmppad;
|
||||||
|
GST_DEBUG ("blocking pad %" GST_PTR_FORMAT, tmppad);
|
||||||
|
gst_pad_set_blocked_async (tmppad, TRUE, pad_blocked, NULL);
|
||||||
|
|
||||||
GST_DEBUG ("Reconfiguring playsink");
|
GST_DEBUG ("Reconfiguring playsink");
|
||||||
|
|
||||||
|
@ -568,6 +578,13 @@ pad_removed_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
|
||||||
gst_object_unref (chain->playsinkpad);
|
gst_object_unref (chain->playsinkpad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chain->blocked_pad) {
|
||||||
|
GST_DEBUG ("unblocking pad %" GST_PTR_FORMAT, chain->blocked_pad);
|
||||||
|
gst_pad_set_blocked_async (chain->blocked_pad, FALSE, pad_blocked, NULL);
|
||||||
|
gst_object_unref (chain->blocked_pad);
|
||||||
|
chain->blocked_pad = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Unlike/remove tee */
|
/* Unlike/remove tee */
|
||||||
peer = gst_element_get_static_pad (chain->tee, "sink");
|
peer = gst_element_get_static_pad (chain->tee, "sink");
|
||||||
gst_pad_unlink (pad, peer);
|
gst_pad_unlink (pad, peer);
|
||||||
|
@ -581,6 +598,22 @@ pad_removed_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
|
||||||
GST_DEBUG ("done");
|
GST_DEBUG ("done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
no_more_pads_cb (GstElement * timeline, GESTimelinePipeline * self)
|
||||||
|
{
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
|
GST_DEBUG ("received no-more-pads");
|
||||||
|
for (tmp = self->priv->chains; tmp; tmp = g_list_next (tmp)) {
|
||||||
|
OutputChain *chain = (OutputChain *) tmp->data;
|
||||||
|
|
||||||
|
if (chain->blocked_pad) {
|
||||||
|
GST_DEBUG ("unblocking pad %" GST_PTR_FORMAT, chain->blocked_pad);
|
||||||
|
gst_pad_set_blocked_async (chain->blocked_pad, FALSE, pad_blocked, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ges_timeline_pipeline_add_timeline:
|
* ges_timeline_pipeline_add_timeline:
|
||||||
* @pipeline: a #GESTimelinePipeline
|
* @pipeline: a #GESTimelinePipeline
|
||||||
|
@ -612,6 +645,8 @@ ges_timeline_pipeline_add_timeline (GESTimelinePipeline * pipeline,
|
||||||
g_signal_connect (timeline, "pad-added", (GCallback) pad_added_cb, pipeline);
|
g_signal_connect (timeline, "pad-added", (GCallback) pad_added_cb, pipeline);
|
||||||
g_signal_connect (timeline, "pad-removed", (GCallback) pad_removed_cb,
|
g_signal_connect (timeline, "pad-removed", (GCallback) pad_removed_cb,
|
||||||
pipeline);
|
pipeline);
|
||||||
|
g_signal_connect (timeline, "no-more-pads", (GCallback) no_more_pads_cb,
|
||||||
|
pipeline);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -908,7 +908,8 @@ static void
|
||||||
pad_added_cb (GESTrack * track, GstPad * pad, TrackPrivate * tr_priv)
|
pad_added_cb (GESTrack * track, GstPad * pad, TrackPrivate * tr_priv)
|
||||||
{
|
{
|
||||||
gchar *padname;
|
gchar *padname;
|
||||||
|
gboolean no_more;
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
GST_DEBUG ("track:%p, pad:%s:%s", track, GST_DEBUG_PAD_NAME (pad));
|
GST_DEBUG ("track:%p, pad:%s:%s", track, GST_DEBUG_PAD_NAME (pad));
|
||||||
|
|
||||||
|
@ -918,8 +919,20 @@ pad_added_cb (GESTrack * track, GstPad * pad, TrackPrivate * tr_priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the pad */
|
/* Remember the pad */
|
||||||
|
GST_OBJECT_LOCK (track);
|
||||||
tr_priv->pad = pad;
|
tr_priv->pad = pad;
|
||||||
|
|
||||||
|
no_more = TRUE;
|
||||||
|
for (tmp = tr_priv->timeline->priv->tracks; tmp; tmp = g_list_next (tmp)) {
|
||||||
|
TrackPrivate *tr_priv = (TrackPrivate *) tmp->data;
|
||||||
|
|
||||||
|
if (!tr_priv->pad) {
|
||||||
|
GST_LOG ("Found track without pad %p", tr_priv->track);
|
||||||
|
no_more = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GST_OBJECT_UNLOCK (track);
|
||||||
|
|
||||||
/* ghost it ! */
|
/* ghost it ! */
|
||||||
GST_DEBUG ("Ghosting pad and adding it to ourself");
|
GST_DEBUG ("Ghosting pad and adding it to ourself");
|
||||||
padname = g_strdup_printf ("track_%p_src", track);
|
padname = g_strdup_printf ("track_%p_src", track);
|
||||||
|
@ -927,6 +940,11 @@ pad_added_cb (GESTrack * track, GstPad * pad, TrackPrivate * tr_priv)
|
||||||
g_free (padname);
|
g_free (padname);
|
||||||
gst_pad_set_active (tr_priv->ghostpad, TRUE);
|
gst_pad_set_active (tr_priv->ghostpad, TRUE);
|
||||||
gst_element_add_pad (GST_ELEMENT (tr_priv->timeline), tr_priv->ghostpad);
|
gst_element_add_pad (GST_ELEMENT (tr_priv->timeline), tr_priv->ghostpad);
|
||||||
|
|
||||||
|
if (no_more) {
|
||||||
|
GST_DEBUG ("Signaling no-more-pads");
|
||||||
|
gst_element_no_more_pads (GST_ELEMENT (tr_priv->timeline));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue