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.
This commit is contained in:
Wim Taymans 2001-12-25 02:15:46 +00:00
parent 4b5fc45173
commit bd128c199c
11 changed files with 206 additions and 92 deletions

View file

@ -173,10 +173,14 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
{ {
GList *sinkpads; GList *sinkpads;
gboolean connected = FALSE; 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_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)); 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); sinkpads = gst_element_get_pad_list(sink);
while (sinkpads) { while (sinkpads) {
GstPad *sinkpad = (GstPad *)sinkpads->data; 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 && if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
!GST_PAD_CONNECTED (pad) && !GST_PAD_CONNECTED(sinkpad)) !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 ((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; break;
} }
else { else {
GST_DEBUG (0,"pads incompatible %s, %s\n", GST_PAD_NAME (pad), GST_PAD_NAME (sinkpad)); 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); 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) { if (!connected) {
GST_DEBUG (0,"gstpipeline: no path to sinks for type\n"); GST_DEBUG (0,"gstpipeline: no path to sinks for type\n");
} }

View file

@ -270,6 +270,14 @@ cothread_setfunc (cothread_state * thread, cothread_func func, int argc, char **
thread->pc = (void *) func; thread->pc = (void *) func;
} }
void
cothread_stop (cothread_state * thread)
{
thread->flags &= ~COTHREAD_STARTED;
thread->pc = 0;
thread->sp = thread->top_sp;
}
/** /**
* cothread_main: * cothread_main:
* @ctx: cothread context to find main thread of * @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 */ /* we do this to avoid ever returning, we just switch to 0th thread */
cothread_switch (cothread_main (ctx)); 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 (""); GST_DEBUG_LEAVE ("");
} }

View file

@ -74,6 +74,8 @@ cothread_state* cothread_create (cothread_context *ctx);
void cothread_free (cothread_state *thread); void cothread_free (cothread_state *thread);
void cothread_setfunc (cothread_state *thread, cothread_func func, void cothread_setfunc (cothread_state *thread, cothread_func func,
int argc, char **argv); int argc, char **argv);
void cothread_stop (cothread_state *thread);
int cothread_getcurrent (void); int cothread_getcurrent (void);
void cothread_switch (cothread_state *thread); void cothread_switch (cothread_state *thread);
void cothread_set_data (cothread_state *thread, gchar *key, gpointer data); void cothread_set_data (cothread_state *thread, gchar *key, gpointer data);

View file

@ -57,6 +57,7 @@ static void gst_tee_class_init (GstTeeClass *klass);
static void gst_tee_init (GstTee *tee); static void gst_tee_init (GstTee *tee);
static GstPad* gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp, const gchar *unused); 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, static void gst_tee_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec); 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_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)); gst_pad_set_negotiate_function (tee->sinkpad, GST_DEBUG_FUNCPTR(gst_tee_handle_negotiate_sink));
tee->numsrcpads = 0;
tee->srcpads = NULL;
tee->silent = FALSE; tee->silent = FALSE;
} }
@ -145,17 +144,38 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
tee = GST_TEE (element); 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); srcpad = gst_pad_new_from_template (templ, name);
gst_element_add_pad (GST_ELEMENT (tee), srcpad); gst_element_add_pad (GST_ELEMENT (tee), srcpad);
gst_pad_set_event_function (srcpad, gst_tee_event_handler);
GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL;
tee->srcpads = g_slist_prepend (tee->srcpads, srcpad); if (GST_PAD_CAPS (tee->sinkpad)) {
tee->numsrcpads++; gst_pad_set_caps (srcpad, GST_PAD_CAPS (tee->sinkpad));
}
return srcpad; 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 static void
gst_tee_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) 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) { switch (prop_id) {
case ARG_NUM_PADS: case ARG_NUM_PADS:
g_value_set_int (value, tee->numsrcpads); g_value_set_int (value, GST_ELEMENT (tee)->numsrcpads);
break; break;
case ARG_SILENT: case ARG_SILENT:
g_value_set_boolean (value, tee->silent); g_value_set_boolean (value, tee->silent);
@ -208,7 +228,7 @@ static void
gst_tee_chain (GstPad *pad, GstBuffer *buf) gst_tee_chain (GstPad *pad, GstBuffer *buf)
{ {
GstTee *tee; GstTee *tee;
GSList *srcpads; GList *pads;
gint i; gint i;
g_return_if_fail (pad != NULL); 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)); tee = GST_TEE (gst_pad_get_parent (pad));
/* gst_trace_add_entry (NULL, 0, buf, "tee buffer");*/ /* gst_trace_add_entry (NULL, 0, buf, "tee buffer");*/
for (i=0; i<tee->numsrcpads-1; i++) gst_buffer_ref_by_count (buf, GST_ELEMENT (tee)->numsrcpads);
gst_buffer_ref (buf);
srcpads = tee->srcpads; pads = gst_element_get_pad_list (GST_ELEMENT (tee));
while (srcpads) {
GstPad *outpad = GST_PAD (srcpads->data);
srcpads = g_slist_next (srcpads);
if (!tee->silent) while (pads) {
g_print("tee: chain ******* (%s:%s)t (%d bytes, %llu) \n", 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) {
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_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; GstCaps* tempcaps;
gint i; gint i;
GstTee* tee=GST_TEE (GST_OBJECT_PARENT (pad)); GstTee* tee = GST_TEE (GST_OBJECT_PARENT (pad));
GList *pads;
if (*caps==NULL) if (*caps==NULL)
return GST_PAD_NEGOTIATE_FAIL; return GST_PAD_NEGOTIATE_FAIL;
// go through all the src pads /* go through all the src pads */
for(i=0;i<tee->numsrcpads;i++) { pads = gst_element_get_pad_list (GST_ELEMENT (tee));
if (!(gst_pad_set_caps (GST_PAD(g_slist_nth_data(tee->srcpads,i)), while (pads) {
*caps))) { GstPad *outpad = GST_PAD (pads->data);
pads = g_list_next (pads);
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; return GST_PAD_NEGOTIATE_FAIL;
} }
} }

View file

@ -53,8 +53,6 @@ struct _GstTee {
GstPad *sinkpad; GstPad *sinkpad;
gboolean silent; gboolean silent;
gint numsrcpads;
GSList *srcpads;
}; };
struct _GstTeeClass { struct _GstTeeClass {

View file

@ -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); 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_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); 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); event = gst_event_new_info (type, GST_PROPS_STRING (string), NULL);
gst_element_send_event (element, event); 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 (element) = GST_STATE_PENDING (element);
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING; 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); parent = GST_ELEMENT_PARENT (element);
if (parent && GST_IS_BIN (parent)) { if (parent && GST_IS_BIN (parent)) {
gst_bin_child_state_change (GST_BIN (parent), old_state, GST_STATE (element), element); 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; return GST_STATE_SUCCESS;
} }

View file

@ -88,6 +88,7 @@ enum {
REAL_CAPS_NEGO_FAILED, REAL_CAPS_NEGO_FAILED,
REAL_CONNECTED, REAL_CONNECTED,
REAL_DISCONNECTED, REAL_DISCONNECTED,
REAL_EVENT_RECEIVED,
/* FILL ME */ /* FILL ME */
REAL_LAST_SIGNAL REAL_LAST_SIGNAL
}; };
@ -139,40 +140,45 @@ gst_real_pad_class_init (GstRealPadClass *klass)
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstObjectClass *gstobject_class; GstObjectClass *gstobject_class;
gobject_class = (GObjectClass*)klass; gobject_class = (GObjectClass*) klass;
gstobject_class = (GstObjectClass*)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->dispose = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_real_pad_set_property); 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->get_property = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
gst_real_pad_signals[REAL_SET_ACTIVE] = 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, G_STRUCT_OFFSET (GstRealPadClass, set_active), NULL, NULL,
gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1,
G_TYPE_BOOLEAN); G_TYPE_BOOLEAN);
gst_real_pad_signals[REAL_CAPS_CHANGED] = 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, G_STRUCT_OFFSET (GstRealPadClass, caps_changed), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER); G_TYPE_POINTER);
gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] = 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, G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER); G_TYPE_POINTER);
gst_real_pad_signals[REAL_CONNECTED] = 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, G_STRUCT_OFFSET (GstRealPadClass, connected), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER); G_TYPE_POINTER);
gst_real_pad_signals[REAL_DISCONNECTED] = 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, G_STRUCT_OFFSET (GstRealPadClass, disconnected), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER); 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_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */
/* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */ /* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */
@ -1574,6 +1580,7 @@ gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len
break; break;
} }
} }
/* FIXME */
while (result && ! GST_BUFFER_FLAG_IS_SET (result, GST_BUFFER_EOS) while (result && ! GST_BUFFER_FLAG_IS_SET (result, GST_BUFFER_EOS)
&& !(GST_BUFFER_OFFSET (result) == offset && && !(GST_BUFFER_OFFSET (result) == offset &&
GST_BUFFER_SIZE (result) == len)); GST_BUFFER_SIZE (result) == len));
@ -1989,6 +1996,29 @@ gst_ghost_pad_new (gchar *name,
return GST_PAD(ghostpad); 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: * gst_pad_event_default:
@ -2002,27 +2032,19 @@ gst_pad_event_default (GstPad *pad, GstEvent *event)
{ {
GstElement *element = GST_PAD_PARENT (pad); GstElement *element = GST_PAD_PARENT (pad);
switch (GST_EVENT_TYPE (event)) { g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_EVENT_RECEIVED], 0, 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) { switch (GST_EVENT_TYPE (event)) {
if (GST_PAD_DIRECTION (pads->data) == GST_PAD_SRC && GST_PAD_CONNECTED (pads->data)) { case GST_EVENT_EOS:
gst_pad_push (GST_PAD (pads->data), GST_BUFFER (gst_event_new (GST_EVENT_TYPE (event)))); gst_element_set_state (element, GST_STATE_PAUSED);
} gst_pad_event_default_dispatch (pad, element, event);
pads = g_list_next (pads);
}
}
gst_event_free (event); gst_event_free (event);
/* we have to try to schedule another element because this one is disabled */ /* we have to try to schedule another element because this one is disabled */
gst_element_yield (element); gst_element_yield (element);
break; break;
case GST_EVENT_FLUSH:
default: default:
g_warning ("no default handler for event\n"); gst_pad_event_default_dispatch (pad, element, event);
gst_event_free (event); gst_event_free (event);
break; break;
} }
@ -2057,7 +2079,7 @@ gst_pad_send_event (GstPad *pad, GstEvent *event)
} }
if (!handled) { 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); gst_pad_event_default (pad, event);
handled = TRUE; handled = TRUE;
} }

View file

@ -206,6 +206,7 @@ struct _GstRealPadClass {
void (*caps_nego_failed) (GstPad *pad); void (*caps_nego_failed) (GstPad *pad);
void (*connected) (GstPad *pad, GstPad *peer); void (*connected) (GstPad *pad, GstPad *peer);
void (*disconnected) (GstPad *pad, GstPad *peer); void (*disconnected) (GstPad *pad, GstPad *peer);
void (*event_received) (GstPad *pad, GstEvent *event);
void (*eos) (GstPad *pad); void (*eos) (GstPad *pad);
}; };

View file

@ -387,7 +387,7 @@ gst_basic_scheduler_select_proxy (GstPad * pad, GstBuffer * buf)
g_print ("%p %s\n", GST_ELEMENT (GST_PAD_PARENT (pad)), g_print ("%p %s\n", GST_ELEMENT (GST_PAD_PARENT (pad)),
gst_element_get_name (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_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))); cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
g_print ("done switching\n"); g_print ("done switching\n");

View file

@ -57,6 +57,7 @@ static void gst_tee_class_init (GstTeeClass *klass);
static void gst_tee_init (GstTee *tee); static void gst_tee_init (GstTee *tee);
static GstPad* gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp, const gchar *unused); 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, static void gst_tee_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec); 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_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)); gst_pad_set_negotiate_function (tee->sinkpad, GST_DEBUG_FUNCPTR(gst_tee_handle_negotiate_sink));
tee->numsrcpads = 0;
tee->srcpads = NULL;
tee->silent = FALSE; tee->silent = FALSE;
} }
@ -145,17 +144,38 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
tee = GST_TEE (element); 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); srcpad = gst_pad_new_from_template (templ, name);
gst_element_add_pad (GST_ELEMENT (tee), srcpad); gst_element_add_pad (GST_ELEMENT (tee), srcpad);
gst_pad_set_event_function (srcpad, gst_tee_event_handler);
GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL;
tee->srcpads = g_slist_prepend (tee->srcpads, srcpad); if (GST_PAD_CAPS (tee->sinkpad)) {
tee->numsrcpads++; gst_pad_set_caps (srcpad, GST_PAD_CAPS (tee->sinkpad));
}
return srcpad; 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 static void
gst_tee_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) 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) { switch (prop_id) {
case ARG_NUM_PADS: case ARG_NUM_PADS:
g_value_set_int (value, tee->numsrcpads); g_value_set_int (value, GST_ELEMENT (tee)->numsrcpads);
break; break;
case ARG_SILENT: case ARG_SILENT:
g_value_set_boolean (value, tee->silent); g_value_set_boolean (value, tee->silent);
@ -208,7 +228,7 @@ static void
gst_tee_chain (GstPad *pad, GstBuffer *buf) gst_tee_chain (GstPad *pad, GstBuffer *buf)
{ {
GstTee *tee; GstTee *tee;
GSList *srcpads; GList *pads;
gint i; gint i;
g_return_if_fail (pad != NULL); 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)); tee = GST_TEE (gst_pad_get_parent (pad));
/* gst_trace_add_entry (NULL, 0, buf, "tee buffer");*/ /* gst_trace_add_entry (NULL, 0, buf, "tee buffer");*/
for (i=0; i<tee->numsrcpads-1; i++) gst_buffer_ref_by_count (buf, GST_ELEMENT (tee)->numsrcpads);
gst_buffer_ref (buf);
srcpads = tee->srcpads; pads = gst_element_get_pad_list (GST_ELEMENT (tee));
while (srcpads) {
GstPad *outpad = GST_PAD (srcpads->data);
srcpads = g_slist_next (srcpads);
if (!tee->silent) while (pads) {
g_print("tee: chain ******* (%s:%s)t (%d bytes, %llu) \n", 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) {
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_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; GstCaps* tempcaps;
gint i; gint i;
GstTee* tee=GST_TEE (GST_OBJECT_PARENT (pad)); GstTee* tee = GST_TEE (GST_OBJECT_PARENT (pad));
GList *pads;
if (*caps==NULL) if (*caps==NULL)
return GST_PAD_NEGOTIATE_FAIL; return GST_PAD_NEGOTIATE_FAIL;
// go through all the src pads /* go through all the src pads */
for(i=0;i<tee->numsrcpads;i++) { pads = gst_element_get_pad_list (GST_ELEMENT (tee));
if (!(gst_pad_set_caps (GST_PAD(g_slist_nth_data(tee->srcpads,i)), while (pads) {
*caps))) { GstPad *outpad = GST_PAD (pads->data);
pads = g_list_next (pads);
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; return GST_PAD_NEGOTIATE_FAIL;
} }
} }

View file

@ -53,8 +53,6 @@ struct _GstTee {
GstPad *sinkpad; GstPad *sinkpad;
gboolean silent; gboolean silent;
gint numsrcpads;
GSList *srcpads;
}; };
struct _GstTeeClass { struct _GstTeeClass {