mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
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:
parent
4b5fc45173
commit
bd128c199c
11 changed files with 206 additions and 92 deletions
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,6 @@ struct _GstTee {
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
|
|
||||||
gboolean silent;
|
gboolean silent;
|
||||||
gint numsrcpads;
|
|
||||||
GSList *srcpads;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstTeeClass {
|
struct _GstTeeClass {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
76
gst/gstpad.c
76
gst/gstpad.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,6 @@ struct _GstTee {
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
|
|
||||||
gboolean silent;
|
gboolean silent;
|
||||||
gint numsrcpads;
|
|
||||||
GSList *srcpads;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstTeeClass {
|
struct _GstTeeClass {
|
||||||
|
|
Loading…
Reference in a new issue