+2005-11-21 Andy Wingo <wingo@pobox.com>
+
+ * check/gst/gstevent.c (create_custom_events): Check that
+ FLUSH_STOP is serialized.
+
+ * check/elements/identity.c (event_func):
+ * check/elements/fakesrc.c (event_func): No stream lock, the core
+ takes it.
+
+ * gst/base/gstbasetransform.c (gst_base_transform_event): No more
+ stream lock taking, yay.
+
+ * gst/gstevent.h (GST_EVENT_FLUSH_STOP): Marked as serialized to
+ ensure that core takes the stream lock.
+
+ * gst/base/gstbasesrc.c (gst_base_src_do_seek): Update for stream
+ lock name change.
+
+ * gst/base/gstbasesink.c (gst_base_sink_event): No need to take
+ the stream lock for EOS, NEWSEGMENT, or FLUSH_STOP, the core does
+ it already. For the flush start we do take it though so we get the
+ right preroll state change messages.
+
+ * gst/gstqueue.c (gst_queue_sink_activate_push): No need to take
+ the stream lock here, the core does it for us.
+
+ * gst/gstpad.h (GST_PAD_GET_STREAM_LOCK): Renamed from
+ GST_STREAM_GET_LOCK.
+ (GST_PAD_STREAM_LOCK, GST_PAD_STREAM_TRYLOCK)
+ (GST_PAD_STREAM_UNLOCK, GST_PAD_STREAM_UNLOCK_FULL)
+ (GST_PAD_STREAM_LOCK_FULL): Renamed from GST_STREAM_*.
+ (GST_PAD_GET_PREROLL_LOCK): Renamed from GST_PREROLL_GET_LOCK.
+ (GST_PAD_PREROLL_LOCK, GST_PAD_PREROLL_TRYLOCK)
+ (GST_PAD_PREROLL_UNLOCK): Renamed from GST_PREROLL_*.
+
+ * gst/gstpad.c: Update for stream lock name change.
+
+ * gst/base/gstbasesink.c: Update for preroll lock name change.
+
2005-11-21 Wim Taymans <wim@fluendo.com>
* gst/gstclock.c: (gst_clock_init), (gst_clock_set_master),
event_func (GstPad * pad, GstEvent * event)
{
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
- /* we take the lock here because it's good practice to so, even though
- * no buffers will be pushed anymore anyway */
- GST_STREAM_LOCK (pad);
have_eos = TRUE;
- GST_STREAM_UNLOCK (pad);
gst_event_unref (event);
return TRUE;
}
event_func (GstPad * pad, GstEvent * event)
{
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
- /* we take the lock here because it's good practice to so, even though
- * no buffers will be pushed anymore anyway */
- GST_STREAM_LOCK (pad);
have_eos = TRUE;
- GST_STREAM_UNLOCK (pad);
gst_event_unref (event);
return TRUE;
}
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
fail_unless (GST_EVENT_IS_UPSTREAM (event));
fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
- fail_if (GST_EVENT_IS_SERIALIZED (event));
+ fail_unless (GST_EVENT_IS_SERIALIZED (event));
gst_event_unref (event);
}
/* EOS */
switch (prop_id) {
case PROP_PREROLL_QUEUE_LEN:
/* preroll lock necessary to serialize with finish_preroll */
- GST_PREROLL_LOCK (sink->sinkpad);
+ GST_PAD_PREROLL_LOCK (sink->sinkpad);
sink->preroll_queue_max_len = g_value_get_uint (value);
- GST_PREROLL_UNLOCK (sink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
break;
case PROP_SYNC:
sink->sync = g_value_get_boolean (value);
/* we release the preroll lock while pushing so that we
* can still flush it while blocking on the clock or
* inside the element. */
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
if (G_LIKELY (is_buffer)) {
GST_DEBUG_OBJECT (basesink, "popped buffer %p", obj);
ret = GST_FLOW_OK;
}
- GST_PREROLL_LOCK (pad);
+ GST_PAD_PREROLL_LOCK (pad);
}
GST_DEBUG_OBJECT (basesink, "queue empty");
}
basesink->events_queued = 0;
basesink->have_preroll = FALSE;
/* and signal any waiters now */
- GST_PREROLL_SIGNAL (pad);
+ GST_PAD_PREROLL_SIGNAL (pad);
}
/* with PREROLL_LOCK */
gint length;
gboolean have_event;
- GST_PREROLL_LOCK (pad);
+ GST_PAD_PREROLL_LOCK (pad);
/* push object on the queue */
GST_DEBUG_OBJECT (basesink, "push %p on preroll_queue", obj);
g_queue_push_tail (basesink->preroll_queue, obj);
if (length > basesink->preroll_queue_max_len && !have_event) {
/* block until the state changes, or we get a flush, or something */
GST_DEBUG_OBJECT (basesink, "waiting to finish preroll");
- GST_PREROLL_WAIT (pad);
+ GST_PAD_PREROLL_WAIT (pad);
GST_DEBUG_OBJECT (basesink, "done preroll");
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
GST_OBJECT_UNLOCK (pad);
}
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
return GST_FLOW_OK;
buffers to drain */
basesink->have_preroll = FALSE;
ret = gst_base_sink_preroll_queue_empty (basesink, pad);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
return ret;
}
buf = GST_BUFFER (g_queue_pop_tail (basesink->preroll_queue));
gst_buffer_unref (buf);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
return GST_FLOW_OK;
}
{
GST_OBJECT_UNLOCK (pad);
gst_base_sink_preroll_queue_flush (basesink, pad);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "pad is flushing");
return GST_FLOW_WRONG_STATE;
}
stopping:
{
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "stopping");
return GST_FLOW_WRONG_STATE;
{
GstFlowReturn ret;
- GST_STREAM_LOCK (pad);
/* EOS also finishes the preroll */
ret =
gst_base_sink_handle_object (basesink, pad, GST_MINI_OBJECT (event));
- GST_STREAM_UNLOCK (pad);
break;
}
case GST_EVENT_NEWSEGMENT:
{
GstFlowReturn ret;
- GST_STREAM_LOCK (pad);
ret =
gst_base_sink_handle_object (basesink, pad, GST_MINI_OBJECT (event));
- GST_STREAM_UNLOCK (pad);
break;
}
case GST_EVENT_FLUSH_START:
}
GST_OBJECT_UNLOCK (basesink);
- GST_PREROLL_LOCK (pad);
+ GST_PAD_PREROLL_LOCK (pad);
/* we need preroll after the flush */
GST_DEBUG_OBJECT (basesink, "flushing, need preroll after flush");
basesink->need_preroll = TRUE;
/* unlock from a possible state change/preroll */
gst_base_sink_preroll_queue_flush (basesink, pad);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
/* and we need to commit our state again on the next
* prerolled buffer */
- GST_STREAM_LOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
gst_element_lost_state (GST_ELEMENT (basesink));
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "event unref %p %p", basesink, event);
gst_event_unref (event);
break;
/* now we are completely unblocked and the _chain method
* will return */
- GST_STREAM_LOCK (pad);
GST_OBJECT_LOCK (basesink);
basesink->flushing = FALSE;
GST_OBJECT_UNLOCK (basesink);
/* we need new segment info after the flush. */
gst_segment_init (&basesink->segment, GST_FORMAT_TIME);
- GST_STREAM_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "event unref %p %p", basesink, event);
gst_event_unref (event);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
/* if we are still EOS, we can post the EOS message */
if (basesink->eos) {
/* ok, now we can post the message */
gst_message_new_eos (GST_OBJECT_CAST (basesink)));
basesink->eos_queued = FALSE;
}
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
break;
default:
break;
bclass = GST_BASE_SINK_GET_CLASS (basesink);
/* step 1, unblock clock sync (if any) or any other blocking thing */
- GST_PREROLL_LOCK (pad);
+ GST_PAD_PREROLL_LOCK (pad);
GST_OBJECT_LOCK (basesink);
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
"flushing out data thread, need preroll to FALSE");
basesink->need_preroll = FALSE;
gst_base_sink_preroll_queue_flush (basesink, pad);
- GST_PREROLL_SIGNAL (pad);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_SIGNAL (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
/* step 2, make sure streaming finishes */
result = gst_pad_stop_task (pad);
GstFormat format;
gboolean eos;
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
eos = basesink->eos;
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
if (eos) {
res = gst_base_sink_peer_query (basesink, query);
/* need to complete preroll before this state change completes, there
* is no data flow in READY so we can safely assume we need to preroll. */
basesink->offset = 0;
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
basesink->have_preroll = FALSE;
GST_DEBUG_OBJECT (basesink, "READY to PAUSED, need preroll to FALSE");
basesink->need_preroll = TRUE;
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
gst_segment_init (&basesink->segment, GST_FORMAT_TIME);
basesink->have_newsegment = FALSE;
ret = GST_STATE_CHANGE_ASYNC;
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
/* no preroll needed */
basesink->need_preroll = FALSE;
GST_DEBUG_OBJECT (basesink,
"PAUSED to PLAYING, !eos, have_preroll, need preroll to FALSE");
/* now let it play */
- GST_PREROLL_SIGNAL (basesink->sinkpad);
+ GST_PAD_PREROLL_SIGNAL (basesink->sinkpad);
}
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
break;
default:
break;
bclass = GST_BASE_SINK_GET_CLASS (basesink);
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
GST_OBJECT_LOCK (basesink);
/* unlock clock wait if any */
if (basesink->clock_id) {
basesink->need_preroll = TRUE;
ret = GST_STATE_CHANGE_ASYNC;
}
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
break;
}
case GST_STATE_CHANGE_PAUSED_TO_READY:
/* grab streaming lock, this should eventually be possible, either
* because the task is paused or out streaming thread stopped
* because our peer is flushing. */
- GST_STREAM_LOCK (src->srcpad);
+ GST_PAD_STREAM_LOCK (src->srcpad);
/* now configure the segment */
gst_base_src_configure_segment (src, event);
src->srcpad);
/* and release the lock again so we can continue streaming */
- GST_STREAM_UNLOCK (src->srcpad);
+ GST_PAD_STREAM_UNLOCK (src->srcpad);
return TRUE;
GstBaseTransform *trans;
GstBaseTransformClass *bclass;
gboolean ret = FALSE;
- gboolean unlock;
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (bclass->event)
bclass->event (trans, event);
- unlock = FALSE;
-
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
break;
case GST_EVENT_FLUSH_STOP:
- GST_STREAM_LOCK (pad);
- unlock = TRUE;
/* we need new segment info after the flush. */
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
break;
case GST_EVENT_EOS:
- GST_STREAM_LOCK (pad);
- unlock = TRUE;
break;
case GST_EVENT_TAG:
- GST_STREAM_LOCK (pad);
- unlock = TRUE;
break;
case GST_EVENT_NEWSEGMENT:
{
gint64 start, stop, time;
gboolean update;
- GST_STREAM_LOCK (pad);
- unlock = TRUE;
gst_event_parse_newsegment (event, &update, &rate, &format, &start, &stop,
&time);
break;
}
ret = gst_pad_event_default (pad, event);
- if (unlock)
- GST_STREAM_UNLOCK (pad);
gst_object_unref (trans);
GST_EVENT_UNKNOWN = GST_EVENT_MAKE_TYPE (0, 0),
/* bidirectional events */
GST_EVENT_FLUSH_START = GST_EVENT_MAKE_TYPE (1, FLAG(BOTH)),
- GST_EVENT_FLUSH_STOP = GST_EVENT_MAKE_TYPE (2, FLAG(BOTH)),
+ GST_EVENT_FLUSH_STOP = GST_EVENT_MAKE_TYPE (2, FLAG(BOTH) | FLAG(SERIALIZED)),
/* downstream serialized events */
GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
GST_EVENT_NEWSEGMENT = GST_EVENT_MAKE_TYPE (6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
break;
case GST_ACTIVATE_NONE:
/* ensures that streaming stops */
- GST_STREAM_LOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
/* while we're at it set activation mode */
GST_OBJECT_LOCK (pad);
GST_DEBUG_OBJECT (pad, "setting ACTIVATE_MODE %d", new_mode);
GST_PAD_ACTIVATE_MODE (pad) = new_mode;
GST_OBJECT_UNLOCK (pad);
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
break;
}
}
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
- GST_STREAM_LOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
GST_DEBUG_FUNCPTR_NAME (chainfunc), GST_DEBUG_PAD_NAME (pad),
gst_flow_get_name (ret));
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return ret;
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pushing, but pad was flushing");
GST_OBJECT_UNLOCK (pad);
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_WRONG_STATE;
}
dropping:
{
gst_buffer_unref (buffer);
GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_OK;
}
not_negotiated:
gst_buffer_unref (buffer);
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pushing buffer but pad did not accept");
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_NOT_NEGOTIATED;
}
no_function:
GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
("push on pad %s:%s but it has no chainfunction",
GST_DEBUG_PAD_NAME (pad)));
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_ERROR;
}
}
g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC, GST_FLOW_ERROR);
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
- GST_STREAM_LOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto dropping;
}
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return ret;
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pulling range, but pad was flushing");
GST_OBJECT_UNLOCK (pad);
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_WRONG_STATE;
}
no_function:
GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
("pullrange on pad %s:%s but it has no getrangefunction",
GST_DEBUG_PAD_NAME (pad)));
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_ERROR;
}
dropping:
{
GST_DEBUG ("Dropping data after FALSE probe return");
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
gst_buffer_unref (*buffer);
*buffer = NULL;
return GST_FLOW_UNEXPECTED;
}
if (serialized)
- GST_STREAM_LOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
result = eventfunc (GST_PAD_CAST (pad), event);
if (serialized)
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return result;
task = GST_PAD_TASK (pad);
if (task == NULL) {
task = gst_task_create (func, data);
- gst_task_set_lock (task, GST_STREAM_GET_LOCK (pad));
+ gst_task_set_lock (task, GST_PAD_GET_STREAM_LOCK (pad));
GST_PAD_TASK (pad) = task;
}
gst_task_start (task);
gst_task_pause (task);
GST_OBJECT_UNLOCK (pad);
- GST_STREAM_LOCK (pad);
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return TRUE;
gst_task_stop (task);
GST_OBJECT_UNLOCK (pad);
- GST_STREAM_LOCK (pad);
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
gst_task_join (task);
{
GST_OBJECT_UNLOCK (pad);
- GST_STREAM_LOCK (pad);
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
return TRUE;
}
#define GST_PAD_SET_FLUSHING(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLUSHING))
#define GST_PAD_UNSET_FLUSHING(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLUSHING))
-#define GST_STREAM_GET_LOCK(pad) (GST_PAD_CAST(pad)->stream_rec_lock)
-#define GST_STREAM_LOCK(pad) (g_static_rec_mutex_lock(GST_STREAM_GET_LOCK(pad)))
-#define GST_STREAM_TRYLOCK(pad) (g_static_rec_mutex_trylock(GST_STREAM_GET_LOCK(pad)))
-#define GST_STREAM_UNLOCK(pad) (g_static_rec_mutex_unlock(GST_STREAM_GET_LOCK(pad)))
-#define GST_STREAM_UNLOCK_FULL(pad) (g_static_rec_mutex_unlock_full(GST_STREAM_GET_LOCK(pad)))
-#define GST_STREAM_LOCK_FULL(pad,t) (g_static_rec_mutex_lock_full(GST_STREAM_GET_LOCK(pad), t))
-
-#define GST_PREROLL_GET_LOCK(pad) (GST_PAD_CAST(pad)->preroll_lock)
-#define GST_PREROLL_LOCK(pad) (g_mutex_lock(GST_PREROLL_GET_LOCK(pad)))
-#define GST_PREROLL_TRYLOCK(pad) (g_mutex_trylock(GST_PREROLL_GET_LOCK(pad)))
-#define GST_PREROLL_UNLOCK(pad) (g_mutex_unlock(GST_PREROLL_GET_LOCK(pad)))
-#define GST_PREROLL_GET_COND(pad) (GST_PAD_CAST(pad)->preroll_cond)
-#define GST_PREROLL_WAIT(pad) g_cond_wait (GST_PREROLL_GET_COND (pad), GST_PREROLL_GET_LOCK (pad))
-#define GST_PREROLL_TIMED_WAIT(pad, timeval) g_cond_timed_wait (GST_PREROLL_GET_COND (pad), GST_PREROLL_GET_LOCK (pad),\
- timeval)
-#define GST_PREROLL_SIGNAL(pad) g_cond_signal (GST_PREROLL_GET_COND (pad));
-#define GST_PREROLL_BROADCAST(pad) g_cond_broadcast (GST_PREROLL_GET_COND (pad));
+#define GST_PAD_GET_STREAM_LOCK(pad) (GST_PAD_CAST(pad)->stream_rec_lock)
+#define GST_PAD_STREAM_LOCK(pad) (g_static_rec_mutex_lock(GST_PAD_GET_STREAM_LOCK(pad)))
+#define GST_PAD_STREAM_TRYLOCK(pad) (g_static_rec_mutex_trylock(GST_PAD_GET_STREAM_LOCK(pad)))
+#define GST_PAD_STREAM_UNLOCK(pad) (g_static_rec_mutex_unlock(GST_PAD_GET_STREAM_LOCK(pad)))
+#define GST_PAD_STREAM_UNLOCK_FULL(pad) (g_static_rec_mutex_unlock_full(GST_PAD_GET_STREAM_LOCK(pad)))
+#define GST_PAD_STREAM_LOCK_FULL(pad,t) (g_static_rec_mutex_lock_full(GST_PAD_GET_STREAM_LOCK(pad), t))
+
+#define GST_PAD_GET_PREROLL_LOCK(pad) (GST_PAD_CAST(pad)->preroll_lock)
+#define GST_PAD_PREROLL_LOCK(pad) (g_mutex_lock(GST_PAD_GET_PREROLL_LOCK(pad)))
+#define GST_PAD_PREROLL_TRYLOCK(pad) (g_mutex_trylock(GST_PAD_GET_PREROLL_LOCK(pad)))
+#define GST_PAD_PREROLL_UNLOCK(pad) (g_mutex_unlock(GST_PAD_GET_PREROLL_LOCK(pad)))
+
+#define GST_PAD_GET_PREROLL_COND(pad) (GST_PAD_CAST(pad)->preroll_cond)
+#define GST_PAD_PREROLL_WAIT(pad) \
+ g_cond_wait (GST_PAD_GET_PREROLL_COND (pad), GST_PAD_GET_PREROLL_LOCK (pad))
+#define GST_PAD_PREROLL_TIMED_WAIT(pad, timeval) \
+ g_cond_timed_wait (GST_PAD_GET_PREROLL_COND (pad), GST_PAD_GET_PREROLL_LOCK (pad), timeval)
+#define GST_PAD_PREROLL_SIGNAL(pad) g_cond_signal (GST_PAD_GET_PREROLL_COND (pad));
+#define GST_PAD_PREROLL_BROADCAST(pad) g_cond_broadcast (GST_PAD_GET_PREROLL_COND (pad));
#define GST_PAD_BLOCK_GET_COND(pad) (GST_PAD_CAST(pad)->block_cond)
#define GST_PAD_BLOCK_WAIT(pad) (g_cond_wait(GST_PAD_BLOCK_GET_COND (pad), GST_OBJECT_GET_LOCK (pad)))
queue->srcresult = GST_FLOW_WRONG_STATE;
gst_queue_locked_flush (queue);
GST_QUEUE_MUTEX_UNLOCK (queue);
-
- /* and make sure the chain function finishes */
- GST_STREAM_LOCK (pad);
- GST_STREAM_UNLOCK (pad);
}
gst_object_unref (queue);
switch (prop_id) {
case PROP_PREROLL_QUEUE_LEN:
/* preroll lock necessary to serialize with finish_preroll */
- GST_PREROLL_LOCK (sink->sinkpad);
+ GST_PAD_PREROLL_LOCK (sink->sinkpad);
sink->preroll_queue_max_len = g_value_get_uint (value);
- GST_PREROLL_UNLOCK (sink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
break;
case PROP_SYNC:
sink->sync = g_value_get_boolean (value);
/* we release the preroll lock while pushing so that we
* can still flush it while blocking on the clock or
* inside the element. */
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
if (G_LIKELY (is_buffer)) {
GST_DEBUG_OBJECT (basesink, "popped buffer %p", obj);
ret = GST_FLOW_OK;
}
- GST_PREROLL_LOCK (pad);
+ GST_PAD_PREROLL_LOCK (pad);
}
GST_DEBUG_OBJECT (basesink, "queue empty");
}
basesink->events_queued = 0;
basesink->have_preroll = FALSE;
/* and signal any waiters now */
- GST_PREROLL_SIGNAL (pad);
+ GST_PAD_PREROLL_SIGNAL (pad);
}
/* with PREROLL_LOCK */
gint length;
gboolean have_event;
- GST_PREROLL_LOCK (pad);
+ GST_PAD_PREROLL_LOCK (pad);
/* push object on the queue */
GST_DEBUG_OBJECT (basesink, "push %p on preroll_queue", obj);
g_queue_push_tail (basesink->preroll_queue, obj);
if (length > basesink->preroll_queue_max_len && !have_event) {
/* block until the state changes, or we get a flush, or something */
GST_DEBUG_OBJECT (basesink, "waiting to finish preroll");
- GST_PREROLL_WAIT (pad);
+ GST_PAD_PREROLL_WAIT (pad);
GST_DEBUG_OBJECT (basesink, "done preroll");
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
GST_OBJECT_UNLOCK (pad);
}
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
return GST_FLOW_OK;
buffers to drain */
basesink->have_preroll = FALSE;
ret = gst_base_sink_preroll_queue_empty (basesink, pad);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
return ret;
}
buf = GST_BUFFER (g_queue_pop_tail (basesink->preroll_queue));
gst_buffer_unref (buf);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
return GST_FLOW_OK;
}
{
GST_OBJECT_UNLOCK (pad);
gst_base_sink_preroll_queue_flush (basesink, pad);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "pad is flushing");
return GST_FLOW_WRONG_STATE;
}
stopping:
{
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "stopping");
return GST_FLOW_WRONG_STATE;
{
GstFlowReturn ret;
- GST_STREAM_LOCK (pad);
/* EOS also finishes the preroll */
ret =
gst_base_sink_handle_object (basesink, pad, GST_MINI_OBJECT (event));
- GST_STREAM_UNLOCK (pad);
break;
}
case GST_EVENT_NEWSEGMENT:
{
GstFlowReturn ret;
- GST_STREAM_LOCK (pad);
ret =
gst_base_sink_handle_object (basesink, pad, GST_MINI_OBJECT (event));
- GST_STREAM_UNLOCK (pad);
break;
}
case GST_EVENT_FLUSH_START:
}
GST_OBJECT_UNLOCK (basesink);
- GST_PREROLL_LOCK (pad);
+ GST_PAD_PREROLL_LOCK (pad);
/* we need preroll after the flush */
GST_DEBUG_OBJECT (basesink, "flushing, need preroll after flush");
basesink->need_preroll = TRUE;
/* unlock from a possible state change/preroll */
gst_base_sink_preroll_queue_flush (basesink, pad);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
/* and we need to commit our state again on the next
* prerolled buffer */
- GST_STREAM_LOCK (pad);
+ GST_PAD_STREAM_LOCK (pad);
gst_element_lost_state (GST_ELEMENT (basesink));
- GST_STREAM_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "event unref %p %p", basesink, event);
gst_event_unref (event);
break;
/* now we are completely unblocked and the _chain method
* will return */
- GST_STREAM_LOCK (pad);
GST_OBJECT_LOCK (basesink);
basesink->flushing = FALSE;
GST_OBJECT_UNLOCK (basesink);
/* we need new segment info after the flush. */
gst_segment_init (&basesink->segment, GST_FORMAT_TIME);
- GST_STREAM_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "event unref %p %p", basesink, event);
gst_event_unref (event);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
/* if we are still EOS, we can post the EOS message */
if (basesink->eos) {
/* ok, now we can post the message */
gst_message_new_eos (GST_OBJECT_CAST (basesink)));
basesink->eos_queued = FALSE;
}
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
break;
default:
break;
bclass = GST_BASE_SINK_GET_CLASS (basesink);
/* step 1, unblock clock sync (if any) or any other blocking thing */
- GST_PREROLL_LOCK (pad);
+ GST_PAD_PREROLL_LOCK (pad);
GST_OBJECT_LOCK (basesink);
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
"flushing out data thread, need preroll to FALSE");
basesink->need_preroll = FALSE;
gst_base_sink_preroll_queue_flush (basesink, pad);
- GST_PREROLL_SIGNAL (pad);
- GST_PREROLL_UNLOCK (pad);
+ GST_PAD_PREROLL_SIGNAL (pad);
+ GST_PAD_PREROLL_UNLOCK (pad);
/* step 2, make sure streaming finishes */
result = gst_pad_stop_task (pad);
GstFormat format;
gboolean eos;
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
eos = basesink->eos;
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
if (eos) {
res = gst_base_sink_peer_query (basesink, query);
/* need to complete preroll before this state change completes, there
* is no data flow in READY so we can safely assume we need to preroll. */
basesink->offset = 0;
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
basesink->have_preroll = FALSE;
GST_DEBUG_OBJECT (basesink, "READY to PAUSED, need preroll to FALSE");
basesink->need_preroll = TRUE;
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
gst_segment_init (&basesink->segment, GST_FORMAT_TIME);
basesink->have_newsegment = FALSE;
ret = GST_STATE_CHANGE_ASYNC;
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
/* no preroll needed */
basesink->need_preroll = FALSE;
GST_DEBUG_OBJECT (basesink,
"PAUSED to PLAYING, !eos, have_preroll, need preroll to FALSE");
/* now let it play */
- GST_PREROLL_SIGNAL (basesink->sinkpad);
+ GST_PAD_PREROLL_SIGNAL (basesink->sinkpad);
}
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
break;
default:
break;
bclass = GST_BASE_SINK_GET_CLASS (basesink);
- GST_PREROLL_LOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_LOCK (basesink->sinkpad);
GST_OBJECT_LOCK (basesink);
/* unlock clock wait if any */
if (basesink->clock_id) {
basesink->need_preroll = TRUE;
ret = GST_STATE_CHANGE_ASYNC;
}
- GST_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
break;
}
case GST_STATE_CHANGE_PAUSED_TO_READY:
/* grab streaming lock, this should eventually be possible, either
* because the task is paused or out streaming thread stopped
* because our peer is flushing. */
- GST_STREAM_LOCK (src->srcpad);
+ GST_PAD_STREAM_LOCK (src->srcpad);
/* now configure the segment */
gst_base_src_configure_segment (src, event);
src->srcpad);
/* and release the lock again so we can continue streaming */
- GST_STREAM_UNLOCK (src->srcpad);
+ GST_PAD_STREAM_UNLOCK (src->srcpad);
return TRUE;
GstBaseTransform *trans;
GstBaseTransformClass *bclass;
gboolean ret = FALSE;
- gboolean unlock;
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (bclass->event)
bclass->event (trans, event);
- unlock = FALSE;
-
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
break;
case GST_EVENT_FLUSH_STOP:
- GST_STREAM_LOCK (pad);
- unlock = TRUE;
/* we need new segment info after the flush. */
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
break;
case GST_EVENT_EOS:
- GST_STREAM_LOCK (pad);
- unlock = TRUE;
break;
case GST_EVENT_TAG:
- GST_STREAM_LOCK (pad);
- unlock = TRUE;
break;
case GST_EVENT_NEWSEGMENT:
{
gint64 start, stop, time;
gboolean update;
- GST_STREAM_LOCK (pad);
- unlock = TRUE;
gst_event_parse_newsegment (event, &update, &rate, &format, &start, &stop,
&time);
break;
}
ret = gst_pad_event_default (pad, event);
- if (unlock)
- GST_STREAM_UNLOCK (pad);
gst_object_unref (trans);
queue->srcresult = GST_FLOW_WRONG_STATE;
gst_queue_locked_flush (queue);
GST_QUEUE_MUTEX_UNLOCK (queue);
-
- /* and make sure the chain function finishes */
- GST_STREAM_LOCK (pad);
- GST_STREAM_UNLOCK (pad);
}
gst_object_unref (queue);
event_func (GstPad * pad, GstEvent * event)
{
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
- /* we take the lock here because it's good practice to so, even though
- * no buffers will be pushed anymore anyway */
- GST_STREAM_LOCK (pad);
have_eos = TRUE;
- GST_STREAM_UNLOCK (pad);
gst_event_unref (event);
return TRUE;
}
event_func (GstPad * pad, GstEvent * event)
{
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
- /* we take the lock here because it's good practice to so, even though
- * no buffers will be pushed anymore anyway */
- GST_STREAM_LOCK (pad);
have_eos = TRUE;
- GST_STREAM_UNLOCK (pad);
gst_event_unref (event);
return TRUE;
}
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
fail_unless (GST_EVENT_IS_UPSTREAM (event));
fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
- fail_if (GST_EVENT_IS_SERIALIZED (event));
+ fail_unless (GST_EVENT_IS_SERIALIZED (event));
gst_event_unref (event);
}
/* EOS */