From bd128c199cfcc7c88a0cbdc02386aa0547adcf1d Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 25 Dec 2001 02:15:46 +0000 Subject: [PATCH] Tee Fixes. added cothread_stop (not used) improved the pad event dispatcher. Original commit message from CVS: Tee Fixes. added cothread_stop (not used) improved the pad event dispatcher. added an event_received signal on the pad. do less state changes in the autoplugger. small scheduler fix. --- gst/autoplug/gststaticautoplugrender.c | 15 +++--- gst/cothreads.c | 12 +++-- gst/cothreads.h | 2 + gst/elements/gsttee.c | 88 +++++++++++++++++++++++++--------- gst/elements/gsttee.h | 2 - gst/gstelement.c | 14 +++--- gst/gstpad.c | 72 ++++++++++++++++++---------- gst/gstpad.h | 1 + gst/schedulers/gstbasicscheduler.c | 2 +- plugins/elements/gsttee.c | 88 +++++++++++++++++++++++++--------- plugins/elements/gsttee.h | 2 - 11 files changed, 206 insertions(+), 92 deletions(-) diff --git a/gst/autoplug/gststaticautoplugrender.c b/gst/autoplug/gststaticautoplugrender.c index c94eb33..348f27e 100644 --- a/gst/autoplug/gststaticautoplugrender.c +++ b/gst/autoplug/gststaticautoplugrender.c @@ -173,10 +173,14 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink) { GList *sinkpads; gboolean connected = FALSE; + GstElementState state = GST_STATE (gst_element_get_parent (src)); GST_DEBUG (0,"gstpipeline: autoplug pad connect function for %s %s:%s to \"%s\"\n", GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME(pad), GST_ELEMENT_NAME(sink)); + if (state == GST_STATE_PLAYING) + gst_element_set_state (GST_ELEMENT (gst_element_get_parent (src)), GST_STATE_PAUSED); + sinkpads = gst_element_get_pad_list(sink); while (sinkpads) { GstPad *sinkpad = (GstPad *)sinkpads->data; @@ -185,25 +189,20 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink) if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK && !GST_PAD_CONNECTED (pad) && !GST_PAD_CONNECTED(sinkpad)) { - GstElementState state = GST_STATE (gst_element_get_parent (src)); - if (state == GST_STATE_PLAYING) - gst_element_set_state (GST_ELEMENT (gst_element_get_parent (src)), GST_STATE_PAUSED); - if ((connected = gst_pad_try_connect (pad, sinkpad))) { - if (state == GST_STATE_PLAYING) - gst_element_set_state (GST_ELEMENT (gst_element_get_parent (src)), GST_STATE_PLAYING); break; } else { GST_DEBUG (0,"pads incompatible %s, %s\n", GST_PAD_NAME (pad), GST_PAD_NAME (sinkpad)); } - if (state == GST_STATE_PLAYING) - gst_element_set_state (GST_ELEMENT (gst_element_get_parent (src)), GST_STATE_PLAYING); } sinkpads = g_list_next(sinkpads); } + if (state == GST_STATE_PLAYING) + gst_element_set_state (GST_ELEMENT (gst_element_get_parent (src)), GST_STATE_PLAYING); + if (!connected) { GST_DEBUG (0,"gstpipeline: no path to sinks for type\n"); } diff --git a/gst/cothreads.c b/gst/cothreads.c index cc208dd..bbc91ee 100644 --- a/gst/cothreads.c +++ b/gst/cothreads.c @@ -270,6 +270,14 @@ cothread_setfunc (cothread_state * thread, cothread_func func, int argc, char ** thread->pc = (void *) func; } +void +cothread_stop (cothread_state * thread) +{ + thread->flags &= ~COTHREAD_STARTED; + thread->pc = 0; + thread->sp = thread->top_sp; +} + /** * cothread_main: * @ctx: cothread context to find main thread of @@ -320,10 +328,6 @@ cothread_stub (void) /* we do this to avoid ever returning, we just switch to 0th thread */ cothread_switch (cothread_main (ctx)); } - thread->flags &= ~COTHREAD_STARTED; - thread->pc = 0; - thread->sp = thread->top_sp; - fprintf (stderr, "uh, yeah, we shouldn't be here, but we should deal anyway\n"); GST_DEBUG_LEAVE (""); } diff --git a/gst/cothreads.h b/gst/cothreads.h index 5c5fdde..4fe370a 100644 --- a/gst/cothreads.h +++ b/gst/cothreads.h @@ -74,6 +74,8 @@ cothread_state* cothread_create (cothread_context *ctx); void cothread_free (cothread_state *thread); void cothread_setfunc (cothread_state *thread, cothread_func func, int argc, char **argv); +void cothread_stop (cothread_state *thread); + int cothread_getcurrent (void); void cothread_switch (cothread_state *thread); void cothread_set_data (cothread_state *thread, gchar *key, gpointer data); diff --git a/gst/elements/gsttee.c b/gst/elements/gsttee.c index 6c6f83e..0335ae2 100644 --- a/gst/elements/gsttee.c +++ b/gst/elements/gsttee.c @@ -57,6 +57,7 @@ static void gst_tee_class_init (GstTeeClass *klass); static void gst_tee_init (GstTee *tee); static GstPad* gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp, const gchar *unused); +static gboolean gst_tee_event_handler (GstPad *pad, GstEvent *event); static void gst_tee_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); @@ -124,8 +125,6 @@ gst_tee_init (GstTee *tee) gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain)); gst_pad_set_negotiate_function (tee->sinkpad, GST_DEBUG_FUNCPTR(gst_tee_handle_negotiate_sink)); - tee->numsrcpads = 0; - tee->srcpads = NULL; tee->silent = FALSE; } @@ -145,17 +144,38 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar tee = GST_TEE (element); - name = g_strdup_printf ("src%d",tee->numsrcpads); + name = g_strdup_printf ("src%d", GST_ELEMENT (tee)->numsrcpads); srcpad = gst_pad_new_from_template (templ, name); gst_element_add_pad (GST_ELEMENT (tee), srcpad); + gst_pad_set_event_function (srcpad, gst_tee_event_handler); + GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL; + + if (GST_PAD_CAPS (tee->sinkpad)) { + gst_pad_set_caps (srcpad, GST_PAD_CAPS (tee->sinkpad)); + } - tee->srcpads = g_slist_prepend (tee->srcpads, srcpad); - tee->numsrcpads++; - return srcpad; } +static gboolean +gst_tee_event_handler (GstPad *pad, GstEvent *event) +{ + GstTee *tee; + + tee = GST_TEE (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + GST_PAD_ELEMENT_PRIVATE (pad) = gst_event_new (GST_EVENT_TYPE (event)); + break; + default: + break; + } + + return TRUE; +} + static void gst_tee_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { @@ -187,7 +207,7 @@ gst_tee_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec switch (prop_id) { case ARG_NUM_PADS: - g_value_set_int (value, tee->numsrcpads); + g_value_set_int (value, GST_ELEMENT (tee)->numsrcpads); break; case ARG_SILENT: g_value_set_boolean (value, tee->silent); @@ -208,7 +228,7 @@ static void gst_tee_chain (GstPad *pad, GstBuffer *buf) { GstTee *tee; - GSList *srcpads; + GList *pads; gint i; g_return_if_fail (pad != NULL); @@ -218,19 +238,36 @@ gst_tee_chain (GstPad *pad, GstBuffer *buf) tee = GST_TEE (gst_pad_get_parent (pad)); /* gst_trace_add_entry (NULL, 0, buf, "tee buffer");*/ - for (i=0; inumsrcpads-1; i++) - gst_buffer_ref (buf); + gst_buffer_ref_by_count (buf, GST_ELEMENT (tee)->numsrcpads); - srcpads = tee->srcpads; - while (srcpads) { - GstPad *outpad = GST_PAD (srcpads->data); - srcpads = g_slist_next (srcpads); + pads = gst_element_get_pad_list (GST_ELEMENT (tee)); + + while (pads) { + GstPad *outpad = GST_PAD (pads->data); + pads = g_list_next (pads); + + if (GST_PAD_DIRECTION (outpad) != GST_PAD_SRC) + continue; + + if (GST_PAD_ELEMENT_PRIVATE (outpad)) { + GstEvent *event = GST_EVENT (GST_PAD_ELEMENT_PRIVATE (outpad)); + + GST_PAD_ELEMENT_PRIVATE (outpad) = NULL; + if (GST_PAD_CONNECTED (outpad)) + gst_pad_push (outpad, GST_BUFFER (event)); + else + gst_event_free (event); + } - if (!tee->silent) - g_print("tee: chain ******* (%s:%s)t (%d bytes, %llu) \n", + if (!tee->silent) { + gst_element_info (GST_ELEMENT (tee), "chain ******* (%s:%s)t (%d bytes, %llu) \n", GST_DEBUG_PAD_NAME (outpad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + } - gst_pad_push (outpad, buf); + if (GST_PAD_CONNECTED (outpad)) + gst_pad_push (outpad, buf); + else + gst_buffer_unref (buf); } } @@ -247,16 +284,23 @@ gst_tee_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer* data) { GstCaps* tempcaps; gint i; - GstTee* tee=GST_TEE (GST_OBJECT_PARENT (pad)); + GstTee* tee = GST_TEE (GST_OBJECT_PARENT (pad)); + GList *pads; if (*caps==NULL) return GST_PAD_NEGOTIATE_FAIL; - // go through all the src pads - for(i=0;inumsrcpads;i++) { + /* go through all the src pads */ + pads = gst_element_get_pad_list (GST_ELEMENT (tee)); + + while (pads) { + GstPad *outpad = GST_PAD (pads->data); + pads = g_list_next (pads); - if (!(gst_pad_set_caps (GST_PAD(g_slist_nth_data(tee->srcpads,i)), - *caps))) { + if (GST_PAD_DIRECTION (outpad) != GST_PAD_SRC || !GST_PAD_CONNECTED (outpad)) + continue; + + if (!(gst_pad_set_caps (outpad, *caps))) { return GST_PAD_NEGOTIATE_FAIL; } } diff --git a/gst/elements/gsttee.h b/gst/elements/gsttee.h index d714ef5..98a94d8 100644 --- a/gst/elements/gsttee.h +++ b/gst/elements/gsttee.h @@ -53,8 +53,6 @@ struct _GstTee { GstPad *sinkpad; gboolean silent; - gint numsrcpads; - GSList *srcpads; }; struct _GstTeeClass { diff --git a/gst/gstelement.c b/gst/gstelement.c index 862891c..f333539 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -338,9 +338,7 @@ gst_element_remove_pad (GstElement *element, GstPad *pad) g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad); - //gst_object_ref (GST_OBJECT (pad)); gst_object_unparent (GST_OBJECT (pad)); - //gst_object_unref (GST_OBJECT (pad)); } /** @@ -780,6 +778,9 @@ gst_element_message (GstElement *element, const gchar *type, const gchar *info, string = g_strdup_vprintf (info, var_args); + GST_INFO (GST_CAT_EVENT, "%s sends message %s", GST_ELEMENT_NAME (element), + string); + event = gst_event_new_info (type, GST_PROPS_STRING (string), NULL); gst_element_send_event (element, event); @@ -1011,16 +1012,17 @@ gst_element_change_state (GstElement *element) GST_STATE (element) = GST_STATE_PENDING (element); GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING; - g_mutex_lock (element->state_mutex); - g_cond_signal (element->state_cond); - g_mutex_unlock (element->state_mutex); - parent = GST_ELEMENT_PARENT (element); if (parent && GST_IS_BIN (parent)) { gst_bin_child_state_change (GST_BIN (parent), old_state, GST_STATE (element), element); } + g_mutex_lock (element->state_mutex); + g_cond_signal (element->state_cond); + g_mutex_unlock (element->state_mutex); + + return GST_STATE_SUCCESS; } diff --git a/gst/gstpad.c b/gst/gstpad.c index 952534e..9e64db8 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -88,6 +88,7 @@ enum { REAL_CAPS_NEGO_FAILED, REAL_CONNECTED, REAL_DISCONNECTED, + REAL_EVENT_RECEIVED, /* FILL ME */ REAL_LAST_SIGNAL }; @@ -139,40 +140,45 @@ gst_real_pad_class_init (GstRealPadClass *klass) GObjectClass *gobject_class; GstObjectClass *gstobject_class; - gobject_class = (GObjectClass*)klass; - gstobject_class = (GstObjectClass*)klass; + gobject_class = (GObjectClass*) klass; + gstobject_class = (GstObjectClass*) klass; - real_pad_parent_class = g_type_class_ref(GST_TYPE_PAD); + real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD); - gobject_class->dispose = GST_DEBUG_FUNCPTR(gst_real_pad_dispose); - gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_real_pad_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_real_pad_get_property); + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_real_pad_dispose); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_real_pad_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_real_pad_get_property); gst_real_pad_signals[REAL_SET_ACTIVE] = - g_signal_new ("set_active", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("set_active", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRealPadClass, set_active), NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); gst_real_pad_signals[REAL_CAPS_CHANGED] = - g_signal_new ("caps_changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("caps_changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRealPadClass, caps_changed), NULL, NULL, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] = - g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); gst_real_pad_signals[REAL_CONNECTED] = - g_signal_new ("connected", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("connected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRealPadClass, connected), NULL, NULL, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); gst_real_pad_signals[REAL_DISCONNECTED] = - g_signal_new ("disconnected", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("disconnected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRealPadClass, disconnected), NULL, NULL, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + gst_real_pad_signals[REAL_EVENT_RECEIVED] = + g_signal_new ("event_received", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstRealPadClass, event_received), NULL, NULL, + gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); /* gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */ /* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */ @@ -1574,6 +1580,7 @@ gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len break; } } + /* FIXME */ while (result && ! GST_BUFFER_FLAG_IS_SET (result, GST_BUFFER_EOS) && !(GST_BUFFER_OFFSET (result) == offset && GST_BUFFER_SIZE (result) == len)); @@ -1989,6 +1996,29 @@ gst_ghost_pad_new (gchar *name, return GST_PAD(ghostpad); } +static void +gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, GstEvent *event) +{ + GList *pads = element->pads; + + while (pads) { + GstPad *eventpad = GST_PAD (pads->data); + pads = g_list_next (pads); + + /* for all pads in the opposite direction that are connected */ + if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) && GST_PAD_CONNECTED (eventpad)) { + if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) { + gst_pad_push (eventpad, GST_BUFFER (gst_event_new (GST_EVENT_TYPE (event)))); + + } + else { + GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad)); + + gst_pad_send_event (peerpad, gst_event_new (GST_EVENT_TYPE (event))); + } + } + } +} /** * gst_pad_event_default: @@ -2001,28 +2031,20 @@ void gst_pad_event_default (GstPad *pad, GstEvent *event) { GstElement *element = GST_PAD_PARENT (pad); + + g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_EVENT_RECEIVED], 0, event); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH: case GST_EVENT_EOS: -/* gst_element_signal_eos (element); */ gst_element_set_state (element, GST_STATE_PAUSED); - { - GList *pads = element->pads; - - while (pads) { - if (GST_PAD_DIRECTION (pads->data) == GST_PAD_SRC && GST_PAD_CONNECTED (pads->data)) { - gst_pad_push (GST_PAD (pads->data), GST_BUFFER (gst_event_new (GST_EVENT_TYPE (event)))); - } - pads = g_list_next (pads); - } - } + gst_pad_event_default_dispatch (pad, element, event); gst_event_free (event); /* we have to try to schedule another element because this one is disabled */ gst_element_yield (element); break; + case GST_EVENT_FLUSH: default: - g_warning ("no default handler for event\n"); + gst_pad_event_default_dispatch (pad, element, event); gst_event_free (event); break; } @@ -2057,7 +2079,7 @@ gst_pad_send_event (GstPad *pad, GstEvent *event) } if (!handled) { - GST_DEBUG(GST_CAT_EVENT, "would proceed with default behavior here\n"); + GST_DEBUG(GST_CAT_EVENT, "proceeding with default event behavior here\n"); gst_pad_event_default (pad, event); handled = TRUE; } diff --git a/gst/gstpad.h b/gst/gstpad.h index aa08ce6..bf69928 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -206,6 +206,7 @@ struct _GstRealPadClass { void (*caps_nego_failed) (GstPad *pad); void (*connected) (GstPad *pad, GstPad *peer); void (*disconnected) (GstPad *pad, GstPad *peer); + void (*event_received) (GstPad *pad, GstEvent *event); void (*eos) (GstPad *pad); }; diff --git a/gst/schedulers/gstbasicscheduler.c b/gst/schedulers/gstbasicscheduler.c index 289522c..329e0bc 100644 --- a/gst/schedulers/gstbasicscheduler.c +++ b/gst/schedulers/gstbasicscheduler.c @@ -387,7 +387,7 @@ gst_basic_scheduler_select_proxy (GstPad * pad, GstBuffer * buf) g_print ("%p %s\n", GST_ELEMENT (GST_PAD_PARENT (pad)), gst_element_get_name (GST_ELEMENT (GST_PAD_PARENT (pad)))); GST_ELEMENT (GST_PAD_PARENT (pad))->select_pad = pad; - GST_FLAG_UNSET (GST_PAD_PARENT (pad), GST_ELEMENT_COTHREAD_STOPPING); + cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad))); g_print ("done switching\n"); diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c index 6c6f83e..0335ae2 100644 --- a/plugins/elements/gsttee.c +++ b/plugins/elements/gsttee.c @@ -57,6 +57,7 @@ static void gst_tee_class_init (GstTeeClass *klass); static void gst_tee_init (GstTee *tee); static GstPad* gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp, const gchar *unused); +static gboolean gst_tee_event_handler (GstPad *pad, GstEvent *event); static void gst_tee_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); @@ -124,8 +125,6 @@ gst_tee_init (GstTee *tee) gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain)); gst_pad_set_negotiate_function (tee->sinkpad, GST_DEBUG_FUNCPTR(gst_tee_handle_negotiate_sink)); - tee->numsrcpads = 0; - tee->srcpads = NULL; tee->silent = FALSE; } @@ -145,17 +144,38 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar tee = GST_TEE (element); - name = g_strdup_printf ("src%d",tee->numsrcpads); + name = g_strdup_printf ("src%d", GST_ELEMENT (tee)->numsrcpads); srcpad = gst_pad_new_from_template (templ, name); gst_element_add_pad (GST_ELEMENT (tee), srcpad); + gst_pad_set_event_function (srcpad, gst_tee_event_handler); + GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL; + + if (GST_PAD_CAPS (tee->sinkpad)) { + gst_pad_set_caps (srcpad, GST_PAD_CAPS (tee->sinkpad)); + } - tee->srcpads = g_slist_prepend (tee->srcpads, srcpad); - tee->numsrcpads++; - return srcpad; } +static gboolean +gst_tee_event_handler (GstPad *pad, GstEvent *event) +{ + GstTee *tee; + + tee = GST_TEE (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + GST_PAD_ELEMENT_PRIVATE (pad) = gst_event_new (GST_EVENT_TYPE (event)); + break; + default: + break; + } + + return TRUE; +} + static void gst_tee_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { @@ -187,7 +207,7 @@ gst_tee_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec switch (prop_id) { case ARG_NUM_PADS: - g_value_set_int (value, tee->numsrcpads); + g_value_set_int (value, GST_ELEMENT (tee)->numsrcpads); break; case ARG_SILENT: g_value_set_boolean (value, tee->silent); @@ -208,7 +228,7 @@ static void gst_tee_chain (GstPad *pad, GstBuffer *buf) { GstTee *tee; - GSList *srcpads; + GList *pads; gint i; g_return_if_fail (pad != NULL); @@ -218,19 +238,36 @@ gst_tee_chain (GstPad *pad, GstBuffer *buf) tee = GST_TEE (gst_pad_get_parent (pad)); /* gst_trace_add_entry (NULL, 0, buf, "tee buffer");*/ - for (i=0; inumsrcpads-1; i++) - gst_buffer_ref (buf); + gst_buffer_ref_by_count (buf, GST_ELEMENT (tee)->numsrcpads); - srcpads = tee->srcpads; - while (srcpads) { - GstPad *outpad = GST_PAD (srcpads->data); - srcpads = g_slist_next (srcpads); + pads = gst_element_get_pad_list (GST_ELEMENT (tee)); + + while (pads) { + GstPad *outpad = GST_PAD (pads->data); + pads = g_list_next (pads); + + if (GST_PAD_DIRECTION (outpad) != GST_PAD_SRC) + continue; + + if (GST_PAD_ELEMENT_PRIVATE (outpad)) { + GstEvent *event = GST_EVENT (GST_PAD_ELEMENT_PRIVATE (outpad)); + + GST_PAD_ELEMENT_PRIVATE (outpad) = NULL; + if (GST_PAD_CONNECTED (outpad)) + gst_pad_push (outpad, GST_BUFFER (event)); + else + gst_event_free (event); + } - if (!tee->silent) - g_print("tee: chain ******* (%s:%s)t (%d bytes, %llu) \n", + if (!tee->silent) { + gst_element_info (GST_ELEMENT (tee), "chain ******* (%s:%s)t (%d bytes, %llu) \n", GST_DEBUG_PAD_NAME (outpad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + } - gst_pad_push (outpad, buf); + if (GST_PAD_CONNECTED (outpad)) + gst_pad_push (outpad, buf); + else + gst_buffer_unref (buf); } } @@ -247,16 +284,23 @@ gst_tee_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer* data) { GstCaps* tempcaps; gint i; - GstTee* tee=GST_TEE (GST_OBJECT_PARENT (pad)); + GstTee* tee = GST_TEE (GST_OBJECT_PARENT (pad)); + GList *pads; if (*caps==NULL) return GST_PAD_NEGOTIATE_FAIL; - // go through all the src pads - for(i=0;inumsrcpads;i++) { + /* go through all the src pads */ + pads = gst_element_get_pad_list (GST_ELEMENT (tee)); + + while (pads) { + GstPad *outpad = GST_PAD (pads->data); + pads = g_list_next (pads); - if (!(gst_pad_set_caps (GST_PAD(g_slist_nth_data(tee->srcpads,i)), - *caps))) { + if (GST_PAD_DIRECTION (outpad) != GST_PAD_SRC || !GST_PAD_CONNECTED (outpad)) + continue; + + if (!(gst_pad_set_caps (outpad, *caps))) { return GST_PAD_NEGOTIATE_FAIL; } } diff --git a/plugins/elements/gsttee.h b/plugins/elements/gsttee.h index d714ef5..98a94d8 100644 --- a/plugins/elements/gsttee.h +++ b/plugins/elements/gsttee.h @@ -53,8 +53,6 @@ struct _GstTee { GstPad *sinkpad; gboolean silent; - gint numsrcpads; - GSList *srcpads; }; struct _GstTeeClass { -- 2.7.4