gst/: Fix gst_pad_peer_get_caps(), make it return NULL if no peer.

Original commit message from CVS:
* gst/base/gstbasetransform.c: (gst_base_transform_proxy_getcaps):
* gst/elements/gstcapsfilter.c: (gst_capsfilter_getcaps):
* gst/gstpad.c: (gst_pad_peer_get_caps):
* gst/gstqueue.c: (gst_queue_init), (gst_queue_getcaps),
(gst_queue_bufferalloc), (gst_queue_handle_sink_event),
(gst_queue_src_activate), (gst_queue_change_state):
* gst/gstqueue.h:
* gst/gstutils.c: (gst_element_get_compatible_pad_template),
(intersect_caps_func):
Fix gst_pad_peer_get_caps(), make it return NULL if no peer.
Always take QUEUE_LOCK after STREAM_LOCK or we might deadlock.
Some fixes for the peer_get_caps() change.
This commit is contained in:
Wim Taymans 2005-05-06 17:10:49 +00:00
parent 92dd87a8c5
commit d7b231e6d1
11 changed files with 64 additions and 18 deletions

View file

@ -1,3 +1,18 @@
2005-05-06 Wim Taymans <wim@fluendo.com>
* gst/base/gstbasetransform.c: (gst_base_transform_proxy_getcaps):
* gst/elements/gstcapsfilter.c: (gst_capsfilter_getcaps):
* gst/gstpad.c: (gst_pad_peer_get_caps):
* gst/gstqueue.c: (gst_queue_init), (gst_queue_getcaps),
(gst_queue_bufferalloc), (gst_queue_handle_sink_event),
(gst_queue_src_activate), (gst_queue_change_state):
* gst/gstqueue.h:
* gst/gstutils.c: (gst_element_get_compatible_pad_template),
(intersect_caps_func):
Fix gst_pad_peer_get_caps(), make it return NULL if no peer.
Always take QUEUE_LOCK after STREAM_LOCK or we might deadlock.
Some fixes for the peer_get_caps() change.
2005-05-06 Wim Taymans <wim@fluendo.com> 2005-05-06 Wim Taymans <wim@fluendo.com>
* gst/base/gstbasesink.c: (gst_basesink_preroll_queue_empty), * gst/base/gstbasesink.c: (gst_basesink_preroll_queue_empty),

View file

@ -178,11 +178,20 @@ static GstCaps *
gst_base_transform_proxy_getcaps (GstPad * pad) gst_base_transform_proxy_getcaps (GstPad * pad)
{ {
GstPad *otherpad; GstPad *otherpad;
GstBaseTransform *trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad)); GstBaseTransform *trans;
GstCaps *caps;
trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad));
otherpad = pad == trans->srcpad ? trans->sinkpad : trans->srcpad; otherpad = pad == trans->srcpad ? trans->sinkpad : trans->srcpad;
return gst_pad_peer_get_caps (otherpad); /* we can do whatever the peer can do */
caps = gst_pad_peer_get_caps (otherpad);
if (caps == NULL) {
/* no peer, then the padtemplate is enough */
caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
}
return caps;
} }
static gboolean static gboolean

View file

@ -177,6 +177,9 @@ gst_capsfilter_getcaps (GstPad * pad)
capsfilter->srcpad; capsfilter->srcpad;
caps = gst_pad_peer_get_caps (otherpad); caps = gst_pad_peer_get_caps (otherpad);
if (caps == NULL)
caps = gst_caps_new_any ();
icaps = gst_caps_intersect (caps, capsfilter->filter_caps); icaps = gst_caps_intersect (caps, capsfilter->filter_caps);
gst_caps_unref (caps); gst_caps_unref (caps);

View file

@ -1807,7 +1807,8 @@ was_dispatching:
* Gets the capabilities of the peer connected to this pad. * Gets the capabilities of the peer connected to this pad.
* *
* Returns: the #GstCaps of the peer pad. This function returns a new caps, so use * Returns: the #GstCaps of the peer pad. This function returns a new caps, so use
* gst_caps_unref to get rid of it. * gst_caps_unref to get rid of it. this function returns NULL if there is no
* peer pad or when this function is called recursively from a getcaps function.
*/ */
GstCaps * GstCaps *
gst_pad_peer_get_caps (GstPad * pad) gst_pad_peer_get_caps (GstPad * pad)
@ -1846,7 +1847,7 @@ lost_ghostpad:
no_peer: no_peer:
{ {
GST_UNLOCK (realpad); GST_UNLOCK (realpad);
return gst_caps_new_any (); return NULL;
} }
was_dispatching: was_dispatching:
{ {

View file

@ -339,7 +339,6 @@ gst_queue_init (GstQueue * queue)
queue->leaky = GST_QUEUE_NO_LEAK; queue->leaky = GST_QUEUE_NO_LEAK;
queue->may_deadlock = TRUE; queue->may_deadlock = TRUE;
queue->block_timeout = GST_CLOCK_TIME_NONE; queue->block_timeout = GST_CLOCK_TIME_NONE;
queue->interrupt = FALSE;
queue->flush = FALSE; queue->flush = FALSE;
queue->qlock = g_mutex_new (); queue->qlock = g_mutex_new ();
@ -386,6 +385,8 @@ gst_queue_getcaps (GstPad * pad)
otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad); otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad);
result = gst_pad_peer_get_caps (otherpad); result = gst_pad_peer_get_caps (otherpad);
if (result == NULL)
result = gst_caps_new_any ();
return result; return result;
} }
@ -860,9 +861,10 @@ gst_queue_src_activate (GstPad * pad, GstActivateMode mode)
} }
} else { } else {
/* step 1, unblock chain and loop functions */ /* step 1, unblock chain and loop functions */
queue->interrupt = TRUE; GST_QUEUE_MUTEX_LOCK;
g_cond_signal (queue->item_add); g_cond_signal (queue->item_add);
g_cond_signal (queue->item_del); g_cond_signal (queue->item_del);
GST_QUEUE_MUTEX_UNLOCK;
/* step 2, make sure streaming finishes */ /* step 2, make sure streaming finishes */
GST_STREAM_LOCK (pad); GST_STREAM_LOCK (pad);
@ -889,16 +891,16 @@ gst_queue_change_state (GstElement * element)
/* lock the queue so another thread (not in sync with this thread's state) /* lock the queue so another thread (not in sync with this thread's state)
* can't call this queue's _loop (or whatever) */ * can't call this queue's _loop (or whatever) */
GST_QUEUE_MUTEX_LOCK;
switch (GST_STATE_TRANSITION (element)) { switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY: case GST_STATE_NULL_TO_READY:
GST_QUEUE_MUTEX_LOCK;
gst_queue_locked_flush (queue); gst_queue_locked_flush (queue);
GST_QUEUE_MUTEX_UNLOCK;
break; break;
case GST_STATE_READY_TO_PAUSED: case GST_STATE_READY_TO_PAUSED:
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
queue->interrupt = FALSE;
break; break;
default: default:
break; break;
@ -910,14 +912,15 @@ gst_queue_change_state (GstElement * element)
case GST_STATE_PLAYING_TO_PAUSED: case GST_STATE_PLAYING_TO_PAUSED:
break; break;
case GST_STATE_PAUSED_TO_READY: case GST_STATE_PAUSED_TO_READY:
GST_QUEUE_MUTEX_LOCK;
gst_queue_locked_flush (queue); gst_queue_locked_flush (queue);
GST_QUEUE_MUTEX_UNLOCK;
break; break;
case GST_STATE_READY_TO_NULL: case GST_STATE_READY_TO_NULL:
break; break;
default: default:
break; break;
} }
GST_QUEUE_MUTEX_UNLOCK;
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change"); GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change");

View file

@ -79,7 +79,6 @@ struct _GstQueue {
/* it the queue should fail on possible deadlocks */ /* it the queue should fail on possible deadlocks */
gboolean may_deadlock; gboolean may_deadlock;
gboolean interrupt;
gboolean flush; gboolean flush;
GMutex *qlock; /* lock for queue (vs object lock) */ GMutex *qlock; /* lock for queue (vs object lock) */

View file

@ -1545,6 +1545,8 @@ intersect_caps_func (GstPad * pad, GValue * ret, GstPad * orig)
existing = g_value_get_pointer (ret); existing = g_value_get_pointer (ret);
peercaps = gst_pad_peer_get_caps (pad); peercaps = gst_pad_peer_get_caps (pad);
if (peercaps == NULL)
peercaps = gst_caps_new_any ();
g_value_set_pointer (ret, gst_caps_intersect (existing, peercaps)); g_value_set_pointer (ret, gst_caps_intersect (existing, peercaps));
gst_caps_unref (existing); gst_caps_unref (existing);
gst_caps_unref (peercaps); gst_caps_unref (peercaps);

View file

@ -178,11 +178,20 @@ static GstCaps *
gst_base_transform_proxy_getcaps (GstPad * pad) gst_base_transform_proxy_getcaps (GstPad * pad)
{ {
GstPad *otherpad; GstPad *otherpad;
GstBaseTransform *trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad)); GstBaseTransform *trans;
GstCaps *caps;
trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad));
otherpad = pad == trans->srcpad ? trans->sinkpad : trans->srcpad; otherpad = pad == trans->srcpad ? trans->sinkpad : trans->srcpad;
return gst_pad_peer_get_caps (otherpad); /* we can do whatever the peer can do */
caps = gst_pad_peer_get_caps (otherpad);
if (caps == NULL) {
/* no peer, then the padtemplate is enough */
caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
}
return caps;
} }
static gboolean static gboolean

View file

@ -177,6 +177,9 @@ gst_capsfilter_getcaps (GstPad * pad)
capsfilter->srcpad; capsfilter->srcpad;
caps = gst_pad_peer_get_caps (otherpad); caps = gst_pad_peer_get_caps (otherpad);
if (caps == NULL)
caps = gst_caps_new_any ();
icaps = gst_caps_intersect (caps, capsfilter->filter_caps); icaps = gst_caps_intersect (caps, capsfilter->filter_caps);
gst_caps_unref (caps); gst_caps_unref (caps);

View file

@ -339,7 +339,6 @@ gst_queue_init (GstQueue * queue)
queue->leaky = GST_QUEUE_NO_LEAK; queue->leaky = GST_QUEUE_NO_LEAK;
queue->may_deadlock = TRUE; queue->may_deadlock = TRUE;
queue->block_timeout = GST_CLOCK_TIME_NONE; queue->block_timeout = GST_CLOCK_TIME_NONE;
queue->interrupt = FALSE;
queue->flush = FALSE; queue->flush = FALSE;
queue->qlock = g_mutex_new (); queue->qlock = g_mutex_new ();
@ -386,6 +385,8 @@ gst_queue_getcaps (GstPad * pad)
otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad); otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad);
result = gst_pad_peer_get_caps (otherpad); result = gst_pad_peer_get_caps (otherpad);
if (result == NULL)
result = gst_caps_new_any ();
return result; return result;
} }
@ -860,9 +861,10 @@ gst_queue_src_activate (GstPad * pad, GstActivateMode mode)
} }
} else { } else {
/* step 1, unblock chain and loop functions */ /* step 1, unblock chain and loop functions */
queue->interrupt = TRUE; GST_QUEUE_MUTEX_LOCK;
g_cond_signal (queue->item_add); g_cond_signal (queue->item_add);
g_cond_signal (queue->item_del); g_cond_signal (queue->item_del);
GST_QUEUE_MUTEX_UNLOCK;
/* step 2, make sure streaming finishes */ /* step 2, make sure streaming finishes */
GST_STREAM_LOCK (pad); GST_STREAM_LOCK (pad);
@ -889,16 +891,16 @@ gst_queue_change_state (GstElement * element)
/* lock the queue so another thread (not in sync with this thread's state) /* lock the queue so another thread (not in sync with this thread's state)
* can't call this queue's _loop (or whatever) */ * can't call this queue's _loop (or whatever) */
GST_QUEUE_MUTEX_LOCK;
switch (GST_STATE_TRANSITION (element)) { switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY: case GST_STATE_NULL_TO_READY:
GST_QUEUE_MUTEX_LOCK;
gst_queue_locked_flush (queue); gst_queue_locked_flush (queue);
GST_QUEUE_MUTEX_UNLOCK;
break; break;
case GST_STATE_READY_TO_PAUSED: case GST_STATE_READY_TO_PAUSED:
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
queue->interrupt = FALSE;
break; break;
default: default:
break; break;
@ -910,14 +912,15 @@ gst_queue_change_state (GstElement * element)
case GST_STATE_PLAYING_TO_PAUSED: case GST_STATE_PLAYING_TO_PAUSED:
break; break;
case GST_STATE_PAUSED_TO_READY: case GST_STATE_PAUSED_TO_READY:
GST_QUEUE_MUTEX_LOCK;
gst_queue_locked_flush (queue); gst_queue_locked_flush (queue);
GST_QUEUE_MUTEX_UNLOCK;
break; break;
case GST_STATE_READY_TO_NULL: case GST_STATE_READY_TO_NULL:
break; break;
default: default:
break; break;
} }
GST_QUEUE_MUTEX_UNLOCK;
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change"); GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change");

View file

@ -79,7 +79,6 @@ struct _GstQueue {
/* it the queue should fail on possible deadlocks */ /* it the queue should fail on possible deadlocks */
gboolean may_deadlock; gboolean may_deadlock;
gboolean interrupt;
gboolean flush; gboolean flush;
GMutex *qlock; /* lock for queue (vs object lock) */ GMutex *qlock; /* lock for queue (vs object lock) */