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>
+
* gst/base/gstbasesink.c: (gst_basesink_preroll_queue_empty),
(gst_basesink_handle_buffer), (gst_basesink_chain_unlocked),
(gst_basesink_activate):
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
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);
* 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)
no_peer:
{
GST_UNLOCK (realpad);
- return gst_caps_new_any ();
+ return NULL;
}
was_dispatching:
{
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 ();
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;
}
}
} 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);
/* 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;
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");
/* it the queue should fail on possible deadlocks */
gboolean may_deadlock;
- gboolean interrupt;
gboolean flush;
GMutex *qlock; /* lock for queue (vs object lock) */
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);
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
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);
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 ();
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;
}
}
} 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);
/* 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;
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");
/* it the queue should fail on possible deadlocks */
gboolean may_deadlock;
- gboolean interrupt;
gboolean flush;
GMutex *qlock; /* lock for queue (vs object lock) */