mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-27 11:32:51 +00:00
gst/gstbin.c: Add default event/set_manager handlers. The set_manager handler takes care that the manager is distribu...
Original commit message from CVS: * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_manager), (gst_bin_send_event): Add default event/set_manager handlers. The set_manager handler takes care that the manager is distributed over kids that were already in the bin before the manager was set. The event handler is a utility virtual function that sends the event over all sinks, so that gst_element_send_event (bin, event); has the expected behaviour. * gst/gstpad.c: (gst_pad_event_default): Re-install default event handling for discontinuities, so that seeking works without requiring hacks in applications or extra code in sinks. * gst/gstpipeline.c: (gst_pipeline_class_init), (gst_pipeline_send_event): Half hack, half utility: set a pipeline to PAUSED for seek events, since that is the only way we can guarantee a/v sync. Means that you can do gst_element_seek (pipeline, method, pos); on a pipeline and it "just works".
This commit is contained in:
parent
f96e2fabad
commit
8eb4bb6a51
4 changed files with 121 additions and 4 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
|||
2005-03-25 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_manager),
|
||||
(gst_bin_send_event):
|
||||
Add default event/set_manager handlers. The set_manager handler
|
||||
takes care that the manager is distributed over kids that were
|
||||
already in the bin before the manager was set. The event handler
|
||||
is a utility virtual function that sends the event over all sinks,
|
||||
so that gst_element_send_event (bin, event); has the expected
|
||||
behaviour.
|
||||
* gst/gstpad.c: (gst_pad_event_default):
|
||||
Re-install default event handling for discontinuities, so that
|
||||
seeking works without requiring hacks in applications or extra
|
||||
code in sinks.
|
||||
* gst/gstpipeline.c: (gst_pipeline_class_init),
|
||||
(gst_pipeline_send_event):
|
||||
Half hack, half utility: set a pipeline to PAUSED for seek events,
|
||||
since that is the only way we can guarantee a/v sync. Means that
|
||||
you can do gst_element_seek (pipeline, method, pos); on a pipeline
|
||||
and it "just works".
|
||||
|
||||
2005-03-25 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* gst/gstpipeline.c: (gst_pipeline_use_clock):
|
||||
|
|
59
gst/gstbin.c
59
gst/gstbin.c
|
@ -61,6 +61,9 @@ static GstElementStateReturn gst_bin_get_state (GstElement * element,
|
|||
static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
|
||||
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
|
||||
|
||||
static void gst_bin_set_manager (GstElement * element, GstPipeline * manager);
|
||||
static gboolean gst_bin_send_event (GstElement * element, GstEvent * event);
|
||||
|
||||
#ifndef GST_DISABLE_INDEX
|
||||
static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
|
||||
#endif
|
||||
|
@ -166,6 +169,8 @@ gst_bin_class_init (GstBinClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_bin_restore_thyself);
|
||||
#endif
|
||||
|
||||
gstelement_class->set_manager = GST_DEBUG_FUNCPTR (gst_bin_set_manager);
|
||||
gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_bin_send_event);
|
||||
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state);
|
||||
gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state);
|
||||
#ifndef GST_DISABLE_INDEX
|
||||
|
@ -787,6 +792,60 @@ gst_bin_dispose (GObject * object)
|
|||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_bin_set_manager (GstElement * element, GstPipeline * manager)
|
||||
{
|
||||
GstBin *bin = GST_BIN (element);
|
||||
GList *kids;
|
||||
GstElement *kid;
|
||||
|
||||
GST_ELEMENT_CLASS (parent_class)->set_manager (element, manager);
|
||||
|
||||
GST_LOCK (element);
|
||||
for (kids = bin->children; kids != NULL; kids = kids->next) {
|
||||
kid = GST_ELEMENT (kids->data);
|
||||
gst_element_set_manager (kid, manager);
|
||||
}
|
||||
GST_UNLOCK (element);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is a utility event handler for seek events.
|
||||
* It will change pipeline state to PAUSED, iterate event
|
||||
* over all available sinks, distribute new basetime to the
|
||||
* pipeline after preroll is done and then re-set to PLAYING.
|
||||
* Applications are free to override this behaviour and
|
||||
* implement their own seek handler, but this will work for
|
||||
* pretty much all cases in practice.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
gst_bin_send_event (GstElement * element, GstEvent * event)
|
||||
{
|
||||
GstBin *bin = GST_BIN (element);
|
||||
GstIterator *iter;
|
||||
GstElement *sink;
|
||||
gpointer data;
|
||||
gboolean res = TRUE;
|
||||
|
||||
iter = gst_bin_iterate_sinks (bin);
|
||||
GST_DEBUG_OBJECT (bin, "Sending event to sink children");
|
||||
|
||||
/* iterate over all sinks; preroll will take care of sync,
|
||||
* discont event handling will take care of proper clock
|
||||
* adjustment. Sweet. */
|
||||
while (gst_iterator_next (iter, &data) == GST_ITERATOR_OK) {
|
||||
gst_event_ref (event);
|
||||
sink = GST_ELEMENT (data);
|
||||
res &= gst_element_send_event (sink, event);
|
||||
gst_object_unref (GST_OBJECT (sink));
|
||||
}
|
||||
gst_iterator_free (iter);
|
||||
gst_event_unref (event);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_name (GstElement * element, const gchar * name)
|
||||
{
|
||||
|
|
20
gst/gstpad.c
20
gst/gstpad.c
|
@ -26,6 +26,7 @@
|
|||
#include "gstmarshal.h"
|
||||
#include "gstutils.h"
|
||||
#include "gstelement.h"
|
||||
#include "gstpipeline.h"
|
||||
#include "gstbin.h"
|
||||
#include "gstscheduler.h"
|
||||
#include "gstevent.h"
|
||||
|
@ -3381,6 +3382,7 @@ done:
|
|||
*
|
||||
* Returns: TRUE if the event was sent succesfully.
|
||||
*/
|
||||
|
||||
gboolean
|
||||
gst_pad_event_default (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
|
@ -3388,8 +3390,17 @@ gst_pad_event_default (GstPad * pad, GstEvent * event)
|
|||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_EOS:
|
||||
{
|
||||
case GST_EVENT_DISCONTINUOUS:{
|
||||
GstElement *element = gst_pad_get_parent (pad);
|
||||
guint64 time;
|
||||
|
||||
if (element && element->clock && GST_ELEMENT_MANAGER (element) &&
|
||||
gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)) {
|
||||
GST_PIPELINE (GST_ELEMENT_MANAGER (element))->stream_time = time;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_EOS:{
|
||||
GstRealPad *rpad = GST_PAD_REALIZE (pad);
|
||||
|
||||
if (GST_RPAD_TASK (rpad)) {
|
||||
|
@ -3397,10 +3408,11 @@ gst_pad_event_default (GstPad * pad, GstEvent * event)
|
|||
gst_task_pause (GST_RPAD_TASK (rpad));
|
||||
}
|
||||
}
|
||||
return gst_pad_event_default_dispatch (pad, event);
|
||||
default:
|
||||
return gst_pad_event_default_dispatch (pad, event);
|
||||
break;
|
||||
}
|
||||
|
||||
return gst_pad_event_default_dispatch (pad, event);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -61,6 +61,8 @@ static void gst_pipeline_set_property (GObject * object, guint prop_id,
|
|||
static void gst_pipeline_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_pipeline_send_event (GstElement * element,
|
||||
GstEvent * event);
|
||||
static GstBusSyncReply pipeline_bus_handler (GstBus * bus, GstMessage * message,
|
||||
GstPipeline * pipeline);
|
||||
|
||||
|
@ -128,6 +130,7 @@ gst_pipeline_class_init (gpointer g_class, gpointer class_data)
|
|||
|
||||
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pipeline_dispose);
|
||||
|
||||
gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_pipeline_send_event);
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_pipeline_change_state);
|
||||
gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_pipeline_get_clock_func);
|
||||
|
@ -274,6 +277,28 @@ is_eos (GstPipeline * pipeline)
|
|||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_pipeline_send_event (GstElement * element, GstEvent * event)
|
||||
{
|
||||
gboolean was_playing;
|
||||
gboolean res;
|
||||
|
||||
GST_STATE_LOCK (element);
|
||||
/* hmm... questionable */
|
||||
was_playing = (GST_STATE (element) == GST_STATE_PLAYING);
|
||||
GST_STATE_UNLOCK (element);
|
||||
|
||||
if (was_playing && GST_EVENT_TYPE (event) == GST_EVENT_SEEK)
|
||||
gst_element_set_state (element, GST_STATE_PAUSED);
|
||||
|
||||
res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
|
||||
|
||||
if (was_playing && GST_EVENT_TYPE (event) == GST_EVENT_SEEK)
|
||||
gst_element_set_state (element, GST_STATE_PLAYING);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* FIXME, make me threadsafe */
|
||||
static GstBusSyncReply
|
||||
pipeline_bus_handler (GstBus * bus, GstMessage * message,
|
||||
|
|
Loading…
Reference in a new issue