mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +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 *playsinkpad;
|
||||
GstPad *encodebinpad;
|
||||
GstPad *blocked_pad;
|
||||
} OutputChain;
|
||||
|
||||
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
|
||||
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);
|
||||
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");
|
||||
|
||||
|
@ -568,6 +578,13 @@ pad_removed_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
|
|||
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 */
|
||||
peer = gst_element_get_static_pad (chain->tee, "sink");
|
||||
gst_pad_unlink (pad, peer);
|
||||
|
@ -581,6 +598,22 @@ pad_removed_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
|
|||
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:
|
||||
* @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-removed", (GCallback) pad_removed_cb,
|
||||
pipeline);
|
||||
g_signal_connect (timeline, "no-more-pads", (GCallback) no_more_pads_cb,
|
||||
pipeline);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -908,7 +908,8 @@ static void
|
|||
pad_added_cb (GESTrack * track, GstPad * pad, TrackPrivate * tr_priv)
|
||||
{
|
||||
gchar *padname;
|
||||
|
||||
gboolean no_more;
|
||||
GList *tmp;
|
||||
|
||||
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 */
|
||||
GST_OBJECT_LOCK (track);
|
||||
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 ! */
|
||||
GST_DEBUG ("Ghosting pad and adding it to ourself");
|
||||
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);
|
||||
gst_pad_set_active (tr_priv->ghostpad, TRUE);
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue