mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
Small cleanups
Original commit message from CVS: Small cleanups Only do capsnego in READY or higher
This commit is contained in:
parent
b1bcc1875c
commit
debf06d4b9
2 changed files with 106 additions and 45 deletions
150
gst/gstelement.c
150
gst/gstelement.c
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue