diff --git a/ChangeLog b/ChangeLog index db2a727bb1..16c4f92659 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-05-06 Wim Taymans + + * 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 * gst/base/gstbasesink.c: (gst_basesink_preroll_queue_empty), diff --git a/gst/base/gstbasetransform.c b/gst/base/gstbasetransform.c index 7c2baff278..5947067977 100644 --- a/gst/base/gstbasetransform.c +++ b/gst/base/gstbasetransform.c @@ -178,11 +178,20 @@ static GstCaps * gst_base_transform_proxy_getcaps (GstPad * pad) { 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; - 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 diff --git a/gst/elements/gstcapsfilter.c b/gst/elements/gstcapsfilter.c index b6e7774a2f..2081312d0e 100644 --- a/gst/elements/gstcapsfilter.c +++ b/gst/elements/gstcapsfilter.c @@ -177,6 +177,9 @@ gst_capsfilter_getcaps (GstPad * pad) capsfilter->srcpad; caps = gst_pad_peer_get_caps (otherpad); + if (caps == NULL) + caps = gst_caps_new_any (); + icaps = gst_caps_intersect (caps, capsfilter->filter_caps); gst_caps_unref (caps); diff --git a/gst/gstpad.c b/gst/gstpad.c index 7eb0f0a63c..391ed12bda 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1807,7 +1807,8 @@ was_dispatching: * 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 - * 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 * gst_pad_peer_get_caps (GstPad * pad) @@ -1846,7 +1847,7 @@ lost_ghostpad: no_peer: { GST_UNLOCK (realpad); - return gst_caps_new_any (); + return NULL; } was_dispatching: { diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 3999c6d57d..0596538c09 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -339,7 +339,6 @@ gst_queue_init (GstQueue * queue) queue->leaky = GST_QUEUE_NO_LEAK; queue->may_deadlock = TRUE; queue->block_timeout = GST_CLOCK_TIME_NONE; - queue->interrupt = FALSE; queue->flush = FALSE; queue->qlock = g_mutex_new (); @@ -386,6 +385,8 @@ gst_queue_getcaps (GstPad * pad) otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad); result = gst_pad_peer_get_caps (otherpad); + if (result == NULL) + result = gst_caps_new_any (); return result; } @@ -860,9 +861,10 @@ gst_queue_src_activate (GstPad * pad, GstActivateMode mode) } } else { /* 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_del); + GST_QUEUE_MUTEX_UNLOCK; /* step 2, make sure streaming finishes */ 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) * can't call this queue's _loop (or whatever) */ - GST_QUEUE_MUTEX_LOCK; switch (GST_STATE_TRANSITION (element)) { case GST_STATE_NULL_TO_READY: + GST_QUEUE_MUTEX_LOCK; gst_queue_locked_flush (queue); + GST_QUEUE_MUTEX_UNLOCK; break; case GST_STATE_READY_TO_PAUSED: break; case GST_STATE_PAUSED_TO_PLAYING: - queue->interrupt = FALSE; break; default: break; @@ -910,14 +912,15 @@ gst_queue_change_state (GstElement * element) case GST_STATE_PLAYING_TO_PAUSED: break; case GST_STATE_PAUSED_TO_READY: + GST_QUEUE_MUTEX_LOCK; gst_queue_locked_flush (queue); + GST_QUEUE_MUTEX_UNLOCK; break; case GST_STATE_READY_TO_NULL: break; default: break; } - GST_QUEUE_MUTEX_UNLOCK; GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change"); diff --git a/gst/gstqueue.h b/gst/gstqueue.h index 9ff1c86805..220a5cb456 100644 --- a/gst/gstqueue.h +++ b/gst/gstqueue.h @@ -79,7 +79,6 @@ struct _GstQueue { /* it the queue should fail on possible deadlocks */ gboolean may_deadlock; - gboolean interrupt; gboolean flush; GMutex *qlock; /* lock for queue (vs object lock) */ diff --git a/gst/gstutils.c b/gst/gstutils.c index e9648ca950..0345bf4295 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -1545,6 +1545,8 @@ intersect_caps_func (GstPad * pad, GValue * ret, GstPad * orig) existing = g_value_get_pointer (ret); 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)); gst_caps_unref (existing); gst_caps_unref (peercaps); diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index 7c2baff278..5947067977 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -178,11 +178,20 @@ static GstCaps * gst_base_transform_proxy_getcaps (GstPad * pad) { 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; - 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 diff --git a/plugins/elements/gstcapsfilter.c b/plugins/elements/gstcapsfilter.c index b6e7774a2f..2081312d0e 100644 --- a/plugins/elements/gstcapsfilter.c +++ b/plugins/elements/gstcapsfilter.c @@ -177,6 +177,9 @@ gst_capsfilter_getcaps (GstPad * pad) capsfilter->srcpad; caps = gst_pad_peer_get_caps (otherpad); + if (caps == NULL) + caps = gst_caps_new_any (); + icaps = gst_caps_intersect (caps, capsfilter->filter_caps); gst_caps_unref (caps); diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 3999c6d57d..0596538c09 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -339,7 +339,6 @@ gst_queue_init (GstQueue * queue) queue->leaky = GST_QUEUE_NO_LEAK; queue->may_deadlock = TRUE; queue->block_timeout = GST_CLOCK_TIME_NONE; - queue->interrupt = FALSE; queue->flush = FALSE; queue->qlock = g_mutex_new (); @@ -386,6 +385,8 @@ gst_queue_getcaps (GstPad * pad) otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad); result = gst_pad_peer_get_caps (otherpad); + if (result == NULL) + result = gst_caps_new_any (); return result; } @@ -860,9 +861,10 @@ gst_queue_src_activate (GstPad * pad, GstActivateMode mode) } } else { /* 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_del); + GST_QUEUE_MUTEX_UNLOCK; /* step 2, make sure streaming finishes */ 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) * can't call this queue's _loop (or whatever) */ - GST_QUEUE_MUTEX_LOCK; switch (GST_STATE_TRANSITION (element)) { case GST_STATE_NULL_TO_READY: + GST_QUEUE_MUTEX_LOCK; gst_queue_locked_flush (queue); + GST_QUEUE_MUTEX_UNLOCK; break; case GST_STATE_READY_TO_PAUSED: break; case GST_STATE_PAUSED_TO_PLAYING: - queue->interrupt = FALSE; break; default: break; @@ -910,14 +912,15 @@ gst_queue_change_state (GstElement * element) case GST_STATE_PLAYING_TO_PAUSED: break; case GST_STATE_PAUSED_TO_READY: + GST_QUEUE_MUTEX_LOCK; gst_queue_locked_flush (queue); + GST_QUEUE_MUTEX_UNLOCK; break; case GST_STATE_READY_TO_NULL: break; default: break; } - GST_QUEUE_MUTEX_UNLOCK; GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change"); diff --git a/plugins/elements/gstqueue.h b/plugins/elements/gstqueue.h index 9ff1c86805..220a5cb456 100644 --- a/plugins/elements/gstqueue.h +++ b/plugins/elements/gstqueue.h @@ -79,7 +79,6 @@ struct _GstQueue { /* it the queue should fail on possible deadlocks */ gboolean may_deadlock; - gboolean interrupt; gboolean flush; GMutex *qlock; /* lock for queue (vs object lock) */