mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 20:05:38 +00:00
urisourcebin: Add 'about-to-finish' signal
With push-based sources, urisourcebin will emit this signal when the stream has been fully consumed. This signal can be used to know when the source is done providing data.
This commit is contained in:
parent
08044ab7e6
commit
ebf138e29e
1 changed files with 67 additions and 2 deletions
|
@ -167,8 +167,12 @@ struct _GstURISourceBinClass
|
|||
{
|
||||
GstBinClass parent_class;
|
||||
|
||||
/* emitted when all data is decoded */
|
||||
/* emitted when all data has been drained out
|
||||
* FIXME : What do we need this for ?? */
|
||||
void (*drained) (GstElement * element);
|
||||
/* emitted when all data has been fed into buffering slots (i.e the
|
||||
* actual sources are done) */
|
||||
void (*about_to_finish) (GstElement * element);
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src_%u",
|
||||
|
@ -185,6 +189,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_uri_source_bin_debug);
|
|||
enum
|
||||
{
|
||||
SIGNAL_DRAINED,
|
||||
SIGNAL_ABOUT_TO_FINISH,
|
||||
SIGNAL_SOURCE_SETUP,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
@ -336,6 +341,17 @@ gst_uri_source_bin_class_init (GstURISourceBinClass * klass)
|
|||
G_STRUCT_OFFSET (GstURISourceBinClass, drained), NULL, NULL,
|
||||
g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
|
||||
|
||||
/**
|
||||
* GstURISourceBin::about-to-finish:
|
||||
*
|
||||
* This signal is emitted when the data for the current uri is played.
|
||||
*/
|
||||
gst_uri_source_bin_signals[SIGNAL_ABOUT_TO_FINISH] =
|
||||
g_signal_new ("about-to-finish", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstURISourceBinClass, about_to_finish), NULL, NULL,
|
||||
g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
|
||||
|
||||
/**
|
||||
* GstURISourceBin::source-setup:
|
||||
* @bin: the urisourcebin.
|
||||
|
@ -695,6 +711,20 @@ link_pending_pad_to_output (GstURISourceBin * urisrc, OutputSlotInfo * slot)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* Called with lock held */
|
||||
static gboolean
|
||||
all_slots_are_eos (GstURISourceBin * urisrc)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
||||
for (tmp = urisrc->out_slots; tmp; tmp = tmp->next) {
|
||||
OutputSlotInfo *slot = (OutputSlotInfo *) tmp->data;
|
||||
if (slot->is_eos == FALSE)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstPadProbeReturn
|
||||
demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||
{
|
||||
|
@ -718,6 +748,7 @@ demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||
case GST_EVENT_EOS:
|
||||
{
|
||||
GstStructure *s;
|
||||
gboolean all_streams_eos;
|
||||
|
||||
GST_LOG_OBJECT (urisrc, "EOS on pad %" GST_PTR_FORMAT, pad);
|
||||
|
||||
|
@ -732,6 +763,7 @@ demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||
BUFFERING_LOCK (urisrc);
|
||||
/* Mark that we fed an EOS to this slot */
|
||||
child_info->output_slot->is_eos = TRUE;
|
||||
all_streams_eos = all_slots_are_eos (urisrc);
|
||||
BUFFERING_UNLOCK (urisrc);
|
||||
|
||||
/* EOS means this element is no longer buffering */
|
||||
|
@ -744,6 +776,11 @@ demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||
s = gst_event_writable_structure (ev);
|
||||
gst_structure_set (s, "urisourcebin-custom-eos", G_TYPE_BOOLEAN, TRUE,
|
||||
NULL);
|
||||
if (all_streams_eos) {
|
||||
GST_DEBUG_OBJECT (urisrc, "POSTING ABOUT TO FINISH");
|
||||
g_signal_emit (urisrc,
|
||||
gst_uri_source_bin_signals[SIGNAL_ABOUT_TO_FINISH], 0, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GST_EVENT_CAPS:
|
||||
|
@ -769,6 +806,28 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static GstPadProbeReturn
|
||||
pre_queue_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||
{
|
||||
GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (user_data);
|
||||
GstPadProbeReturn ret = GST_PAD_PROBE_OK;
|
||||
GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);
|
||||
|
||||
switch (GST_EVENT_TYPE (ev)) {
|
||||
case GST_EVENT_EOS:
|
||||
{
|
||||
GST_LOG_OBJECT (urisrc, "EOS on pad %" GST_PTR_FORMAT, pad);
|
||||
GST_DEBUG_OBJECT (urisrc, "POSTING ABOUT TO FINISH");
|
||||
g_signal_emit (urisrc,
|
||||
gst_uri_source_bin_signals[SIGNAL_ABOUT_TO_FINISH], 0, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Called with lock held */
|
||||
static OutputSlotInfo *
|
||||
get_output_slot (GstURISourceBin * urisrc, gboolean do_download,
|
||||
|
@ -976,6 +1035,9 @@ create_output_pad (GstURISourceBin * urisrc, GstPad * pad)
|
|||
gst_object_unref (pad_tmpl);
|
||||
g_free (padname);
|
||||
|
||||
GST_DEBUG_OBJECT (urisrc, "Created output pad %s:%s for pad %s:%s",
|
||||
GST_DEBUG_PAD_NAME (newpad), GST_DEBUG_PAD_NAME (pad));
|
||||
|
||||
return newpad;
|
||||
}
|
||||
|
||||
|
@ -1595,7 +1657,7 @@ handle_new_pad (GstURISourceBin * urisrc, GstPad * srcpad, GstCaps * caps)
|
|||
gst_query_unref (query);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (urisrc, "check media-type %s, %d", media_type,
|
||||
GST_DEBUG_OBJECT (urisrc, "check media-type %s, do_download:%d", media_type,
|
||||
do_download);
|
||||
|
||||
GST_URI_SOURCE_BIN_LOCK (urisrc);
|
||||
|
@ -1604,6 +1666,9 @@ handle_new_pad (GstURISourceBin * urisrc, GstPad * srcpad, GstCaps * caps)
|
|||
if (slot == NULL || gst_pad_link (srcpad, slot->sinkpad) != GST_PAD_LINK_OK)
|
||||
goto could_not_link;
|
||||
|
||||
gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
|
||||
pre_queue_event_probe, urisrc, NULL);
|
||||
|
||||
expose_output_pad (urisrc, slot->srcpad);
|
||||
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue