Small cleanups

Original commit message from CVS:
Small cleanups
Only do capsnego in READY or higher
This commit is contained in:
Wim Taymans 2002-01-20 16:04:16 +00:00
parent b1bcc1875c
commit debf06d4b9
2 changed files with 106 additions and 45 deletions

View file

@ -48,6 +48,7 @@ enum {
/* FILL ME */ /* FILL ME */
}; };
#define CLASS(element) GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element))
static void gst_element_class_init (GstElementClass *klass); static void gst_element_class_init (GstElementClass *klass);
static void gst_element_init (GstElement *element); static void gst_element_init (GstElement *element);
@ -183,7 +184,7 @@ gst_element_init (GstElement *element)
static void static void
gst_element_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) gst_element_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{ {
GstElementClass *oclass = (GstElementClass *)G_OBJECT_GET_CLASS(object); GstElementClass *oclass = CLASS (object);
if (oclass->set_property) if (oclass->set_property)
(oclass->set_property)(object,prop_id,value,pspec); (oclass->set_property)(object,prop_id,value,pspec);
@ -193,7 +194,7 @@ gst_element_set_property (GObject *object, guint prop_id, const GValue *value, G
static void static void
gst_element_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) gst_element_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{ {
GstElementClass *oclass = (GstElementClass *)G_OBJECT_GET_CLASS(object); GstElementClass *oclass = CLASS (object);
if (oclass->get_property) if (oclass->get_property)
(oclass->get_property)(object,prop_id,value,pspec); (oclass->get_property)(object,prop_id,value,pspec);
@ -493,14 +494,10 @@ gst_element_class_add_padtemplate (GstElementClass *klass, GstPadTemplate *templ
GList* GList*
gst_element_get_padtemplate_list (GstElement *element) gst_element_get_padtemplate_list (GstElement *element)
{ {
GstElementClass *oclass;
g_return_val_if_fail (element != NULL, NULL); g_return_val_if_fail (element != NULL, NULL);
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
oclass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS(element)); return CLASS (element)->padtemplates;
return oclass->padtemplates;
} }
/** /**
@ -601,7 +598,7 @@ gst_element_request_pad (GstElement *element, GstPadTemplate *templ, const gchar
GstPad *newpad = NULL; GstPad *newpad = NULL;
GstElementClass *oclass; GstElementClass *oclass;
oclass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS(element)); oclass = CLASS (element);
if (oclass->request_new_pad) if (oclass->request_new_pad)
newpad = (oclass->request_new_pad)(element, templ, name); newpad = (oclass->request_new_pad)(element, templ, name);
@ -894,7 +891,7 @@ gst_element_send_event_func (GstElement *element, GstEvent *event)
void void
gst_element_send_event (GstElement *element, GstEvent *event) gst_element_send_event (GstElement *element, GstEvent *event)
{ {
GstElementClass *oclass = (GstElementClass *) G_OBJECT_GET_CLASS (element); GstElementClass *oclass = CLASS (element);
g_return_if_fail (GST_IS_ELEMENT (element)); g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail (event); g_return_if_fail (event);
@ -953,47 +950,47 @@ gst_element_set_state (GstElement *element, GstElementState state)
GstElementState curpending; GstElementState curpending;
GstElementStateReturn return_val = GST_STATE_SUCCESS; GstElementStateReturn return_val = GST_STATE_SUCCESS;
/* g_print("gst_element_set_state(\"%s\",%08lx)\n", */
/* element->name,state); */
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
GST_DEBUG_ELEMENT (GST_CAT_STATES,element, "setting state from %s to %s\n", GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "setting state from %s to %s\n",
gst_element_statename(GST_STATE(element)), gst_element_statename (GST_STATE (element)),
gst_element_statename(state)); gst_element_statename (state));
/* start with the current state */ /* start with the current state */
curpending = GST_STATE(element); curpending = GST_STATE(element);
/* loop until the final requested state is set */ /* loop until the final requested state is set */
while (GST_STATE(element) != state && GST_STATE (element) != GST_STATE_VOID_PENDING) { while (GST_STATE (element) != state && GST_STATE (element) != GST_STATE_VOID_PENDING) {
/* move the curpending state in the correct direction */ /* move the curpending state in the correct direction */
if (curpending < state) curpending<<=1; if (curpending < state)
else curpending>>=1; curpending<<=1;
else
curpending>>=1;
/* set the pending state variable */ /* set the pending state variable */
/* FIXME: should probably check to see that we don't already have one */ /* FIXME: should probably check to see that we don't already have one */
GST_STATE_PENDING (element) = curpending; GST_STATE_PENDING (element) = curpending;
if (curpending != state) if (curpending != state)
GST_DEBUG_ELEMENT (GST_CAT_STATES,element,"intermediate: setting state to %s\n", GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "intermediate: setting state to %s\n",
gst_element_statename(curpending)); gst_element_statename (curpending));
/* call the state change function so it can set the state */ /* call the state change function so it can set the state */
oclass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS(element)); oclass = CLASS (element);
if (oclass->change_state) if (oclass->change_state)
return_val = (oclass->change_state)(element); return_val = (oclass->change_state) (element);
switch (return_val) { switch (return_val) {
case GST_STATE_FAILURE: case GST_STATE_FAILURE:
GST_DEBUG_ELEMENT (GST_CAT_STATES,element,"have failed change_state return\n"); GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "have failed change_state return\n");
return return_val; return return_val;
case GST_STATE_ASYNC: case GST_STATE_ASYNC:
GST_DEBUG_ELEMENT (GST_CAT_STATES,element,"element will change state async\n"); GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "element will change state async\n");
return return_val; return return_val;
default: default:
/* Last thing we do is verify that a successful state change really /* Last thing we do is verify that a successful state change really
* did change the state... */ * did change the state... */
if (GST_STATE(element) != curpending) { if (GST_STATE (element) != curpending) {
GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "element claimed state-change success, but state didn't change\n"); GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "element claimed state-change success, but state didn't change\n");
return GST_STATE_FAILURE; return GST_STATE_FAILURE;
} }
@ -1009,12 +1006,36 @@ gst_element_negotiate_pads (GstElement *element)
{ {
GList *pads = GST_ELEMENT_PADS (element); GList *pads = GST_ELEMENT_PADS (element);
GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "negotiating pads\n");
while (pads) { while (pads) {
GstRealPad *srcpad = GST_PAD_REALIZE (pads->data); GstPad *pad = GST_PAD (pads->data);
GstRealPad *srcpad;
pads = g_list_next (pads);
if (!GST_IS_REAL_PAD (pad))
continue;
srcpad = GST_PAD_REALIZE (pad);
/* if we have a connection on this pad and it doesn't have caps
* allready, try to negotiate */
if (GST_PAD_IS_CONNECTED (srcpad) && !GST_PAD_CAPS (srcpad)) { if (GST_PAD_IS_CONNECTED (srcpad) && !GST_PAD_CAPS (srcpad)) {
GstRealPad *sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad)); GstRealPad *sinkpad;
GstElementState otherstate;
GstElement *parent;
sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
/* check the parent of the peer pad, if there is no parent do nothing */
parent = GST_PAD_PARENT (sinkpad);
if (!parent)
continue;
otherstate = GST_STATE (parent);
/* swap pads if needed */
if (!GST_PAD_IS_SRC (srcpad)) { if (!GST_PAD_IS_SRC (srcpad)) {
GstRealPad *temp; GstRealPad *temp;
@ -1023,67 +1044,108 @@ gst_element_negotiate_pads (GstElement *element)
sinkpad = temp; sinkpad = temp;
} }
if (!gst_pad_perform_negotiate (GST_PAD (srcpad), GST_PAD (sinkpad))) /* only try to negotiate if the peer element is in PAUSED or higher too */
return FALSE; if (otherstate >= GST_STATE_READY) {
GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "perform negotiate for %s:%s and %s:%s\n",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
if (!gst_pad_perform_negotiate (GST_PAD (srcpad), GST_PAD (sinkpad)))
return FALSE;
}
else {
GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "not negotiatiating %s:%s and %s:%s, not in READY yet\n",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
}
} }
pads = g_list_next (pads);
} }
return TRUE; return TRUE;
} }
static void
gst_element_clear_pad_caps (GstElement *element)
{
GList *pads = GST_ELEMENT_PADS (element);
GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "clearing pad caps\n");
while (pads) {
GstRealPad *pad = GST_PAD_REALIZE (pads->data);
if (GST_PAD_CAPS (pad)) {
GST_PAD_CAPS (pad) = NULL;
}
pads = g_list_next (pads);
}
}
static GstElementStateReturn static GstElementStateReturn
gst_element_change_state (GstElement *element) gst_element_change_state (GstElement *element)
{ {
GstElementState old_state; GstElementState old_state;
GstObject *parent; GstObject *parent;
gint old_pending, old_transition;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
old_state = GST_STATE (element); old_state = GST_STATE (element);
old_pending = GST_STATE_PENDING (element);
old_transition = GST_STATE_TRANSITION (element);
if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING || old_state == GST_STATE_PENDING (element)) { if (old_pending == GST_STATE_VOID_PENDING || old_state == GST_STATE_PENDING (element)) {
GST_INFO (GST_CAT_STATES, "no state change needed for element %s (VOID_PENDING)", GST_ELEMENT_NAME (element)); GST_INFO (GST_CAT_STATES, "no state change needed for element %s (VOID_PENDING)", GST_ELEMENT_NAME (element));
return GST_STATE_SUCCESS; return GST_STATE_SUCCESS;
} }
GST_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %d", GST_ELEMENT_NAME (element), GST_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %d", GST_ELEMENT_NAME (element),
gst_element_statename (old_state), gst_element_statename (old_state),
gst_element_statename (GST_STATE_PENDING (element)), gst_element_statename (old_pending),
GST_STATE_TRANSITION (element)); GST_STATE_TRANSITION (element));
/*"we get here after the plugin went to the ready state */ /* we set the state change early for the negotiation functions */
if (GST_STATE_TRANSITION (element) == GST_STATE_NULL_TO_READY) { GST_STATE (element) = old_pending;
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
/* if we are going to paused, we try to negotiate the pads */
if (old_transition == GST_STATE_NULL_TO_READY) {
if (!gst_element_negotiate_pads (element)) if (!gst_element_negotiate_pads (element))
return GST_STATE_FAILURE; goto failure;
}
/* going to the READY state clears all pad caps */
else if (old_transition == GST_STATE_READY_TO_NULL) {
gst_element_clear_pad_caps (element);
} }
/* tell the scheduler if we have one */ /* tell the scheduler if we have one */
if (element->sched) { if (element->sched) {
if (gst_scheduler_state_transition (element->sched, element, GST_STATE_TRANSITION (element)) if (gst_scheduler_state_transition (element->sched, element, old_transition)
!= GST_STATE_SUCCESS) { != GST_STATE_SUCCESS) {
return GST_STATE_FAILURE; goto failure;
} }
} }
GST_STATE (element) = GST_STATE_PENDING (element);
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE], g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
0, old_state, GST_STATE (element)); 0, old_state, GST_STATE (element));
parent = GST_ELEMENT_PARENT (element); parent = GST_ELEMENT_PARENT (element);
/* tell our parent about the state change */
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);
} }
/* signal the state change in case somebody is waiting for us */
g_mutex_lock (element->state_mutex); g_mutex_lock (element->state_mutex);
g_cond_signal (element->state_cond); g_cond_signal (element->state_cond);
g_mutex_unlock (element->state_mutex); g_mutex_unlock (element->state_mutex);
return GST_STATE_SUCCESS; return GST_STATE_SUCCESS;
failure:
/* undo the state change */
GST_STATE (element) = old_state;
GST_STATE_PENDING (element) = old_pending;
return GST_STATE_FAILURE;
} }
/** /**
@ -1101,7 +1163,7 @@ gst_element_get_factory (GstElement *element)
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
oclass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS(element)); oclass = CLASS (element);
return oclass->elementfactory; return oclass->elementfactory;
} }
@ -1157,7 +1219,7 @@ gst_element_save_thyself (GstObject *object,
GstElementClass *oclass; GstElementClass *oclass;
GParamSpec **specs, *spec; GParamSpec **specs, *spec;
gint nspecs, i; gint nspecs, i;
GValue value = { 0, }; GValue value;
GstElement *element; GstElement *element;
gchar *str; gchar *str;
@ -1165,7 +1227,7 @@ gst_element_save_thyself (GstObject *object,
element = GST_ELEMENT (object); element = GST_ELEMENT (object);
oclass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS(element)); oclass = CLASS (element);
xmlNewChild(parent, NULL, "name", GST_ELEMENT_NAME(element)); xmlNewChild(parent, NULL, "name", GST_ELEMENT_NAME(element));

View file

@ -588,7 +588,6 @@ gboolean
gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps) gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
{ {
GstRealPad *realsrc, *realsink; GstRealPad *realsrc, *realsink;
gboolean negotiated = FALSE;
gint num_decoupled = 0; gint num_decoupled = 0;
/* generic checks */ /* generic checks */