diff options
Diffstat (limited to 'gst/switch/gstswitch.c')
-rw-r--r-- | gst/switch/gstswitch.c | 364 |
1 files changed, 171 insertions, 193 deletions
diff --git a/gst/switch/gstswitch.c b/gst/switch/gstswitch.c index e57508bc..995bbdbe 100644 --- a/gst/switch/gstswitch.c +++ b/gst/switch/gstswitch.c @@ -16,7 +16,7 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ - + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -24,7 +24,8 @@ /* Object header */ #include "gstswitch.h" -enum { +enum +{ ARG_0, ARG_NB_SOURCES, ARG_ACTIVE_SOURCE @@ -34,20 +35,16 @@ GST_DEBUG_CATEGORY_EXTERN (GST_CAT_ELEMENT_PADS); GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DATAFLOW); /* ElementFactory information */ -static GstElementDetails gst_switch_details = GST_ELEMENT_DETAILS ( - "Switch", - "Generic", - "N-to-1 input switching", - "Julien Moutte <julien@moutte.net>" -); +static GstElementDetails gst_switch_details = GST_ELEMENT_DETAILS ("Switch", + "Generic", + "N-to-1 input switching", + "Julien Moutte <julien@moutte.net>"); static GstStaticPadTemplate gst_switch_sink_factory = -GST_STATIC_PAD_TEMPLATE ( - "sink%d", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS_ANY -); +GST_STATIC_PAD_TEMPLATE ("sink%d", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); static GstElementClass *parent_class = NULL; @@ -58,33 +55,33 @@ static GstElementClass *parent_class = NULL; /* ============================================================= */ static void -gst_switch_release_pad (GstElement *element, GstPad *pad) +gst_switch_release_pad (GstElement * element, GstPad * pad) { GList *sinkpads = NULL; GstSwitch *gstswitch = NULL; GstSwitchPad *switchpad = NULL; - + g_return_if_fail (GST_IS_SWITCH (element)); - + gstswitch = GST_SWITCH (element); - + GST_CAT_LOG_OBJECT (GST_CAT_ELEMENT_PADS, gstswitch, - "releasing requested pad %p", pad); - + "releasing requested pad %p", pad); + sinkpads = gstswitch->sinkpads; - + /* Walking through our pad list searching for the pad we want to release */ while (sinkpads) { switchpad = sinkpads->data; - + if (switchpad && switchpad->sinkpad == pad) break; - else + else switchpad = NULL; - + sinkpads = g_list_next (sinkpads); } - + /* Releasing the found pad */ if (switchpad) { /* We unref the data of that pad to loose our reference */ @@ -102,178 +99,169 @@ gst_switch_release_pad (GstElement *element, GstPad *pad) } } -static GstPad* -gst_switch_request_new_pad (GstElement *element, - GstPadTemplate *templ, - const gchar *unused) +static GstPad * +gst_switch_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * unused) { char *name = NULL; GstPad *sinkpad = NULL; GstSwitch *gstswitch = NULL; GstSwitchPad *switchpad = NULL; - + g_return_val_if_fail (GST_IS_SWITCH (element), NULL); - + gstswitch = GST_SWITCH (element); - + /* We only provide requested sink pads */ if (templ->direction != GST_PAD_SINK) { GST_CAT_LOG_OBJECT (GST_CAT_ELEMENT_PADS, gstswitch, - "requested a non sink pad"); + "requested a non sink pad"); return NULL; } - + name = g_strdup_printf ("sink%d", gstswitch->nb_sinkpads); - + sinkpad = gst_pad_new_from_template (templ, name); - + if (name) g_free (name); - + /* That pad will proxy caps and link */ gst_pad_set_link_function (sinkpad, - GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); + GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_getcaps_function (sinkpad, - GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); - + GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); + gst_element_add_pad (GST_ELEMENT (gstswitch), sinkpad); - + switchpad = g_new0 (GstSwitchPad, 1); if (!switchpad) return NULL; - + switchpad->sinkpad = sinkpad; switchpad->data = NULL; switchpad->forwarded = FALSE; switchpad->eos = FALSE; - + gstswitch->sinkpads = g_list_insert (gstswitch->sinkpads, switchpad, - gstswitch->nb_sinkpads); + gstswitch->nb_sinkpads); gstswitch->nb_sinkpads++; - + if (GST_PAD_CAPS (gstswitch->srcpad)) { gst_pad_try_set_caps (sinkpad, GST_PAD_CAPS (gstswitch->srcpad)); } - + return sinkpad; } static gboolean -gst_switch_poll_sinkpads (GstSwitch *gstswitch) +gst_switch_poll_sinkpads (GstSwitch * gstswitch) { GList *pads; - + g_return_val_if_fail (gstswitch != NULL, FALSE); g_return_val_if_fail (GST_IS_SWITCH (gstswitch), FALSE); - + pads = gstswitch->sinkpads; - + while (pads) { GstSwitchPad *switchpad = pads->data; - + /* We only pull from usable pads and non EOS pads */ if (GST_PAD_IS_USABLE (switchpad->sinkpad) && !switchpad->eos) { - + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, - "polling pad %p", - switchpad->sinkpad); - + "polling pad %p", switchpad->sinkpad); + /* We loose the reference to the data we stored */ if (switchpad->data) { - gst_data_unref (switchpad->data); + gst_data_unref (switchpad->data); } - + /* If that data was not forwarded we unref it another time to destroy it */ if (!switchpad->forwarded && switchpad->data) { - gst_data_unref (switchpad->data); + gst_data_unref (switchpad->data); } - + switchpad->data = NULL; switchpad->data = gst_pad_pull (switchpad->sinkpad); - + if (!switchpad->data) { - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, - "received NULL data from pad %p", - switchpad->sinkpad); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, + "received NULL data from pad %p", switchpad->sinkpad); + } else { + gst_data_ref (switchpad->data); + switchpad->forwarded = FALSE; + + /* If the buffer is an EOS event we tag the pad as being in EOS. That + means we won't try to pull more data from that pad */ + if (GST_IS_EVENT (switchpad->data) && + (GST_EVENT_TYPE (GST_EVENT (switchpad->data)) == GST_EVENT_EOS)) { + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, + "received EOS event on pad %p", switchpad->sinkpad); + switchpad->eos = TRUE; + } } - else { - gst_data_ref (switchpad->data); - switchpad->forwarded = FALSE; - - /* If the buffer is an EOS event we tag the pad as being in EOS. That - means we won't try to pull more data from that pad */ - if (GST_IS_EVENT (switchpad->data) && - (GST_EVENT_TYPE (GST_EVENT (switchpad->data)) == GST_EVENT_EOS)) { - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, - "received EOS event on pad %p", - switchpad->sinkpad); - switchpad->eos = TRUE; - } - } - } - else { + } else { GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, - "not pulling from pad %s (eos is %d)", - gst_pad_get_name (switchpad->sinkpad), - switchpad->eos); + "not pulling from pad %s (eos is %d)", + gst_pad_get_name (switchpad->sinkpad), switchpad->eos); } pads = g_list_next (pads); } - + return TRUE; } -static void -gst_switch_loop (GstElement *element) +static void +gst_switch_loop (GstElement * element) { GstSwitch *gstswitch = NULL; GstSwitchPad *switchpad = NULL; - + g_return_if_fail (element != NULL); g_return_if_fail (GST_IS_SWITCH (element)); - + gstswitch = GST_SWITCH (element); - + /* We poll all our sinkpads */ gst_switch_poll_sinkpads (gstswitch); - + /* We get the active sinkpad */ switchpad = g_list_nth_data (gstswitch->sinkpads, gstswitch->active_sinkpad); - + if (switchpad && switchpad->data) { GstData *data = switchpad->data; - + /* Loose our reference to that data */ gst_data_unref (switchpad->data); switchpad->data = NULL; - + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, - "using data from active pad %p", - switchpad->sinkpad); - + "using data from active pad %p", switchpad->sinkpad); + if (GST_IS_EVENT (data)) { GstEvent *event = GST_EVENT (data); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, - "handling event from active pad %p", - switchpad->sinkpad); + "handling event from active pad %p", switchpad->sinkpad); /* Handling event */ gst_pad_event_default (switchpad->sinkpad, event); - } - else { + } else { /* Pushing active sinkpad data to srcpad */ GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, gstswitch, - "pushing data from active pad %p to %p", - switchpad->sinkpad, gstswitch->srcpad); + "pushing data from active pad %p to %p", + switchpad->sinkpad, gstswitch->srcpad); gst_pad_push (gstswitch->srcpad, data); } - + /* Mark this data as forwarded so that it won't get unrefed on next poll */ switchpad->forwarded = TRUE; } } static GstElementStateReturn -gst_switch_change_state (GstElement *element) +gst_switch_change_state (GstElement * element) { GstSwitch *gstswitch; @@ -287,26 +275,26 @@ gst_switch_change_state (GstElement *element) case GST_STATE_PAUSED_TO_PLAYING: break; case GST_STATE_PLAYING_TO_PAUSED: - { - GList *sinkpads = NULL; - - sinkpads = gstswitch->sinkpads; - - while (sinkpads) { - GstSwitchPad *switchpad = sinkpads->data; - - /* If a data is still stored in our structure we unref it */ - if (switchpad->data) { - gst_data_unref (switchpad->data); - switchpad->data = NULL; - } - - switchpad->forwarded = FALSE; - switchpad->eos = FALSE; - - sinkpads = g_list_next (sinkpads); - } + { + GList *sinkpads = NULL; + + sinkpads = gstswitch->sinkpads; + + while (sinkpads) { + GstSwitchPad *switchpad = sinkpads->data; + + /* If a data is still stored in our structure we unref it */ + if (switchpad->data) { + gst_data_unref (switchpad->data); + switchpad->data = NULL; + } + + switchpad->forwarded = FALSE; + switchpad->eos = FALSE; + + sinkpads = g_list_next (sinkpads); } + } break; case GST_STATE_PAUSED_TO_READY: break; @@ -316,7 +304,7 @@ gst_switch_change_state (GstElement *element) if (GST_ELEMENT_CLASS (parent_class)->change_state) return GST_ELEMENT_CLASS (parent_class)->change_state (element); - else + else return GST_STATE_SUCCESS; } @@ -327,15 +315,15 @@ gst_switch_change_state (GstElement *element) /* =========================================== */ static void -gst_switch_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +gst_switch_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { GstSwitch *gstswitch = NULL; - + g_return_if_fail (GST_IS_SWITCH (object)); - + gstswitch = GST_SWITCH (object); - + switch (prop_id) { case ARG_ACTIVE_SOURCE: gstswitch->active_sinkpad = g_value_get_int (value); @@ -347,15 +335,15 @@ gst_switch_set_property (GObject *object, guint prop_id, } static void -gst_switch_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +gst_switch_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) { GstSwitch *gstswitch = NULL; - + g_return_if_fail (GST_IS_SWITCH (object)); - + gstswitch = GST_SWITCH (object); - + switch (prop_id) { case ARG_ACTIVE_SOURCE: g_value_set_int (value, gstswitch->active_sinkpad); @@ -376,50 +364,50 @@ gst_switch_get_property (GObject *object, guint prop_id, /* =========================================== */ static void -gst_switch_dispose (GObject *object) +gst_switch_dispose (GObject * object) { GstSwitch *gstswitch = NULL; GList *sinkpads = NULL; - + gstswitch = GST_SWITCH (object); sinkpads = gstswitch->sinkpads; - + while (sinkpads) { GstSwitchPad *switchpad = sinkpads->data; - + /* If a data is still stored in our structure we unref it */ if (switchpad->data) { gst_data_unref (switchpad->data); switchpad->data = NULL; } - + /* Freeing our structure */ g_free (switchpad); - + sinkpads = g_list_next (sinkpads); } - + /* Freeing the list correctly */ - if (gstswitch->sinkpads) { + if (gstswitch->sinkpads) { g_list_free (gstswitch->sinkpads); gstswitch->sinkpads = NULL; } - + G_OBJECT_CLASS (parent_class)->dispose (object); } static void -gst_switch_init (GstSwitch *gstswitch) +gst_switch_init (GstSwitch * gstswitch) { gstswitch->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_element_add_pad (GST_ELEMENT (gstswitch), gstswitch->srcpad); gst_pad_set_link_function (gstswitch->srcpad, - GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); + GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_getcaps_function (gstswitch->srcpad, - GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); + GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); gst_element_set_loop_function (GST_ELEMENT (gstswitch), gst_switch_loop); - + gstswitch->sinkpads = NULL; gstswitch->active_sinkpad = 0; gstswitch->nb_sinkpads = 0; @@ -429,15 +417,15 @@ static void gst_switch_base_init (gpointer g_class) { GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - + gst_element_class_set_details (element_class, &gst_switch_details); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_switch_sink_factory)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_switch_sink_factory)); } static void -gst_switch_class_init (GstSwitchClass *klass) +gst_switch_class_init (GstSwitchClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; @@ -446,26 +434,22 @@ gst_switch_class_init (GstSwitchClass *klass) gstelement_class = (GstElementClass *) klass; parent_class = g_type_class_ref (GST_TYPE_ELEMENT); - + g_object_class_install_property (gobject_class, - ARG_NB_SOURCES, - g_param_spec_int ("nb_sources", - "number of sources", - "number of sources", - G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + ARG_NB_SOURCES, + g_param_spec_int ("nb_sources", + "number of sources", + "number of sources", G_MININT, G_MAXINT, 0, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, - ARG_ACTIVE_SOURCE, - g_param_spec_int ("active_source", - "active source", - "active source", - G_MININT, G_MAXINT, 0, - G_PARAM_READWRITE)); - + ARG_ACTIVE_SOURCE, + g_param_spec_int ("active_source", + "active source", + "active source", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); + gobject_class->dispose = gst_switch_dispose; gobject_class->set_property = gst_switch_set_property; gobject_class->get_property = gst_switch_get_property; - + gstelement_class->change_state = gst_switch_change_state; gstelement_class->request_new_pad = gst_switch_request_new_pad; gstelement_class->release_pad = gst_switch_release_pad; @@ -483,40 +467,34 @@ gst_switch_get_type (void) static GType switch_type = 0; if (!switch_type) { - static const GTypeInfo switch_info = { - sizeof(GstSwitchClass), - gst_switch_base_init, - NULL, - (GClassInitFunc) gst_switch_class_init, - NULL, - NULL, - sizeof(GstSwitch), - 0, - (GInstanceInitFunc) gst_switch_init, - }; - - switch_type = g_type_register_static (GST_TYPE_ELEMENT, - "GstSwitch", &switch_info, 0); + static const GTypeInfo switch_info = { + sizeof (GstSwitchClass), + gst_switch_base_init, + NULL, + (GClassInitFunc) gst_switch_class_init, + NULL, + NULL, + sizeof (GstSwitch), + 0, + (GInstanceInitFunc) gst_switch_init, + }; + + switch_type = g_type_register_static (GST_TYPE_ELEMENT, + "GstSwitch", &switch_info, 0); } - + return switch_type; } static gboolean -plugin_init (GstPlugin *plugin) +plugin_init (GstPlugin * plugin) { return gst_element_register (plugin, "switch", GST_RANK_NONE, - GST_TYPE_SWITCH); + GST_TYPE_SWITCH); } -GST_PLUGIN_DEFINE ( - GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "switch", - "N-to-1 input switching", - plugin_init, - VERSION, - GST_LICENSE, - GST_PACKAGE, - GST_ORIGIN -) +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "switch", + "N-to-1 input switching", + plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN) |