mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +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;
|
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);
|
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",
|
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src_%u",
|
||||||
|
@ -185,6 +189,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_uri_source_bin_debug);
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SIGNAL_DRAINED,
|
SIGNAL_DRAINED,
|
||||||
|
SIGNAL_ABOUT_TO_FINISH,
|
||||||
SIGNAL_SOURCE_SETUP,
|
SIGNAL_SOURCE_SETUP,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
@ -336,6 +341,17 @@ gst_uri_source_bin_class_init (GstURISourceBinClass * klass)
|
||||||
G_STRUCT_OFFSET (GstURISourceBinClass, drained), NULL, NULL,
|
G_STRUCT_OFFSET (GstURISourceBinClass, drained), NULL, NULL,
|
||||||
g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
|
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:
|
* GstURISourceBin::source-setup:
|
||||||
* @bin: the urisourcebin.
|
* @bin: the urisourcebin.
|
||||||
|
@ -695,6 +711,20 @@ link_pending_pad_to_output (GstURISourceBin * urisrc, OutputSlotInfo * slot)
|
||||||
return res;
|
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
|
static GstPadProbeReturn
|
||||||
demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
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:
|
case GST_EVENT_EOS:
|
||||||
{
|
{
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
|
gboolean all_streams_eos;
|
||||||
|
|
||||||
GST_LOG_OBJECT (urisrc, "EOS on pad %" GST_PTR_FORMAT, pad);
|
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);
|
BUFFERING_LOCK (urisrc);
|
||||||
/* Mark that we fed an EOS to this slot */
|
/* Mark that we fed an EOS to this slot */
|
||||||
child_info->output_slot->is_eos = TRUE;
|
child_info->output_slot->is_eos = TRUE;
|
||||||
|
all_streams_eos = all_slots_are_eos (urisrc);
|
||||||
BUFFERING_UNLOCK (urisrc);
|
BUFFERING_UNLOCK (urisrc);
|
||||||
|
|
||||||
/* EOS means this element is no longer buffering */
|
/* 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);
|
s = gst_event_writable_structure (ev);
|
||||||
gst_structure_set (s, "urisourcebin-custom-eos", G_TYPE_BOOLEAN, TRUE,
|
gst_structure_set (s, "urisourcebin-custom-eos", G_TYPE_BOOLEAN, TRUE,
|
||||||
NULL);
|
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;
|
break;
|
||||||
case GST_EVENT_CAPS:
|
case GST_EVENT_CAPS:
|
||||||
|
@ -769,6 +806,28 @@ done:
|
||||||
return ret;
|
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 */
|
/* Called with lock held */
|
||||||
static OutputSlotInfo *
|
static OutputSlotInfo *
|
||||||
get_output_slot (GstURISourceBin * urisrc, gboolean do_download,
|
get_output_slot (GstURISourceBin * urisrc, gboolean do_download,
|
||||||
|
@ -976,6 +1035,9 @@ create_output_pad (GstURISourceBin * urisrc, GstPad * pad)
|
||||||
gst_object_unref (pad_tmpl);
|
gst_object_unref (pad_tmpl);
|
||||||
g_free (padname);
|
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;
|
return newpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1595,7 +1657,7 @@ handle_new_pad (GstURISourceBin * urisrc, GstPad * srcpad, GstCaps * caps)
|
||||||
gst_query_unref (query);
|
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);
|
do_download);
|
||||||
|
|
||||||
GST_URI_SOURCE_BIN_LOCK (urisrc);
|
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)
|
if (slot == NULL || gst_pad_link (srcpad, slot->sinkpad) != GST_PAD_LINK_OK)
|
||||||
goto could_not_link;
|
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);
|
expose_output_pad (urisrc, slot->srcpad);
|
||||||
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
|
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue