mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
basesrc: use new GCond for async state change
Use a new GCond, protected with the object lock, to signal completion of the async state change. We can't reuse the live lock because that one can be locked when the create function blocks. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=686723
This commit is contained in:
parent
3ae671fb9b
commit
9f42bd643e
1 changed files with 31 additions and 29 deletions
|
@ -183,6 +183,12 @@ GST_DEBUG_CATEGORY_STATIC (gst_base_src_debug);
|
||||||
#define GST_LIVE_SIGNAL(elem) g_cond_signal (GST_LIVE_GET_COND (elem));
|
#define GST_LIVE_SIGNAL(elem) g_cond_signal (GST_LIVE_GET_COND (elem));
|
||||||
#define GST_LIVE_BROADCAST(elem) g_cond_broadcast (GST_LIVE_GET_COND (elem));
|
#define GST_LIVE_BROADCAST(elem) g_cond_broadcast (GST_LIVE_GET_COND (elem));
|
||||||
|
|
||||||
|
|
||||||
|
#define GST_ASYNC_GET_COND(elem) (&GST_BASE_SRC_CAST(elem)->priv->async_cond)
|
||||||
|
#define GST_ASYNC_WAIT(elem) g_cond_wait (GST_ASYNC_GET_COND (elem), GST_OBJECT_GET_LOCK (elem))
|
||||||
|
#define GST_ASYNC_SIGNAL(elem) g_cond_signal (GST_ASYNC_GET_COND (elem));
|
||||||
|
|
||||||
|
|
||||||
/* BaseSrc signals and args */
|
/* BaseSrc signals and args */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -251,6 +257,8 @@ struct _GstBaseSrcPrivate
|
||||||
GstBufferPool *pool;
|
GstBufferPool *pool;
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
GstAllocationParams params;
|
GstAllocationParams params;
|
||||||
|
|
||||||
|
GCond async_cond;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
@ -444,6 +452,7 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
|
||||||
basesrc->priv->do_timestamp = DEFAULT_DO_TIMESTAMP;
|
basesrc->priv->do_timestamp = DEFAULT_DO_TIMESTAMP;
|
||||||
g_atomic_int_set (&basesrc->priv->have_events, FALSE);
|
g_atomic_int_set (&basesrc->priv->have_events, FALSE);
|
||||||
|
|
||||||
|
g_cond_init (&basesrc->priv->async_cond);
|
||||||
basesrc->priv->start_result = GST_FLOW_FLUSHING;
|
basesrc->priv->start_result = GST_FLOW_FLUSHING;
|
||||||
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTED);
|
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTED);
|
||||||
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
||||||
|
@ -462,6 +471,7 @@ gst_base_src_finalize (GObject * object)
|
||||||
|
|
||||||
g_mutex_clear (&basesrc->live_lock);
|
g_mutex_clear (&basesrc->live_lock);
|
||||||
g_cond_clear (&basesrc->live_cond);
|
g_cond_clear (&basesrc->live_cond);
|
||||||
|
g_cond_clear (&basesrc->priv->async_cond);
|
||||||
|
|
||||||
event_p = &basesrc->pending_seek;
|
event_p = &basesrc->pending_seek;
|
||||||
gst_event_replace (event_p, NULL);
|
gst_event_replace (event_p, NULL);
|
||||||
|
@ -3091,6 +3101,8 @@ gst_base_src_start (GstBaseSrc * basesrc)
|
||||||
gboolean result;
|
gboolean result;
|
||||||
|
|
||||||
GST_LIVE_LOCK (basesrc);
|
GST_LIVE_LOCK (basesrc);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (basesrc);
|
||||||
if (GST_BASE_SRC_IS_STARTING (basesrc))
|
if (GST_BASE_SRC_IS_STARTING (basesrc))
|
||||||
goto was_starting;
|
goto was_starting;
|
||||||
if (GST_BASE_SRC_IS_STARTED (basesrc))
|
if (GST_BASE_SRC_IS_STARTED (basesrc))
|
||||||
|
@ -3098,12 +3110,12 @@ gst_base_src_start (GstBaseSrc * basesrc)
|
||||||
|
|
||||||
basesrc->priv->start_result = GST_FLOW_FLUSHING;
|
basesrc->priv->start_result = GST_FLOW_FLUSHING;
|
||||||
GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
||||||
|
gst_segment_init (&basesrc->segment, basesrc->segment.format);
|
||||||
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
|
|
||||||
basesrc->num_buffers_left = basesrc->num_buffers;
|
basesrc->num_buffers_left = basesrc->num_buffers;
|
||||||
basesrc->running = FALSE;
|
basesrc->running = FALSE;
|
||||||
basesrc->priv->segment_pending = FALSE;
|
basesrc->priv->segment_pending = FALSE;
|
||||||
GST_OBJECT_LOCK (basesrc);
|
|
||||||
gst_segment_init (&basesrc->segment, basesrc->segment.format);
|
|
||||||
GST_OBJECT_UNLOCK (basesrc);
|
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
GST_LIVE_UNLOCK (basesrc);
|
||||||
|
|
||||||
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
|
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
|
||||||
|
@ -3128,12 +3140,14 @@ gst_base_src_start (GstBaseSrc * basesrc)
|
||||||
was_starting:
|
was_starting:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (basesrc, "was starting");
|
GST_DEBUG_OBJECT (basesrc, "was starting");
|
||||||
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
GST_LIVE_UNLOCK (basesrc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
was_started:
|
was_started:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (basesrc, "was started");
|
GST_DEBUG_OBJECT (basesrc, "was started");
|
||||||
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
GST_LIVE_UNLOCK (basesrc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -3236,12 +3250,12 @@ gst_base_src_start_complete (GstBaseSrc * basesrc, GstFlowReturn ret)
|
||||||
goto no_get_range;
|
goto no_get_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LIVE_LOCK (basesrc);
|
GST_OBJECT_LOCK (basesrc);
|
||||||
GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_FLAG_STARTED);
|
GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_FLAG_STARTED);
|
||||||
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
||||||
basesrc->priv->start_result = ret;
|
basesrc->priv->start_result = ret;
|
||||||
GST_LIVE_SIGNAL (basesrc);
|
GST_ASYNC_SIGNAL (basesrc);
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
|
|
||||||
GST_PAD_STREAM_UNLOCK (basesrc->srcpad);
|
GST_PAD_STREAM_UNLOCK (basesrc->srcpad);
|
||||||
|
|
||||||
|
@ -3267,11 +3281,11 @@ no_get_range:
|
||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
{
|
{
|
||||||
GST_LIVE_LOCK (basesrc);
|
GST_OBJECT_LOCK (basesrc);
|
||||||
basesrc->priv->start_result = ret;
|
basesrc->priv->start_result = ret;
|
||||||
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
||||||
GST_LIVE_SIGNAL (basesrc);
|
GST_ASYNC_SIGNAL (basesrc);
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3289,28 +3303,16 @@ gst_base_src_start_wait (GstBaseSrc * basesrc)
|
||||||
{
|
{
|
||||||
GstFlowReturn result;
|
GstFlowReturn result;
|
||||||
|
|
||||||
GST_LIVE_LOCK (basesrc);
|
GST_OBJECT_LOCK (basesrc);
|
||||||
if (G_UNLIKELY (basesrc->priv->flushing))
|
|
||||||
goto flushing;
|
|
||||||
|
|
||||||
while (GST_BASE_SRC_IS_STARTING (basesrc)) {
|
while (GST_BASE_SRC_IS_STARTING (basesrc)) {
|
||||||
GST_LIVE_WAIT (basesrc);
|
GST_ASYNC_WAIT (basesrc);
|
||||||
if (G_UNLIKELY (basesrc->priv->flushing))
|
|
||||||
goto flushing;
|
|
||||||
}
|
}
|
||||||
result = basesrc->priv->start_result;
|
result = basesrc->priv->start_result;
|
||||||
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (basesrc, "got %s", gst_flow_get_name (result));
|
GST_DEBUG_OBJECT (basesrc, "got %s", gst_flow_get_name (result));
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* ERRORS */
|
|
||||||
flushing:
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (basesrc, "we are flushing");
|
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
|
||||||
return GST_FLOW_FLUSHING;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -3326,15 +3328,15 @@ gst_base_src_stop (GstBaseSrc * basesrc)
|
||||||
/* stop the task */
|
/* stop the task */
|
||||||
gst_pad_stop_task (basesrc->srcpad);
|
gst_pad_stop_task (basesrc->srcpad);
|
||||||
|
|
||||||
GST_LIVE_LOCK (basesrc);
|
GST_OBJECT_LOCK (basesrc);
|
||||||
if (!GST_BASE_SRC_IS_STARTED (basesrc) && !GST_BASE_SRC_IS_STARTING (basesrc))
|
if (!GST_BASE_SRC_IS_STARTED (basesrc) && !GST_BASE_SRC_IS_STARTING (basesrc))
|
||||||
goto was_stopped;
|
goto was_stopped;
|
||||||
|
|
||||||
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTING);
|
||||||
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTED);
|
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_FLAG_STARTED);
|
||||||
basesrc->priv->start_result = GST_FLOW_FLUSHING;
|
basesrc->priv->start_result = GST_FLOW_FLUSHING;
|
||||||
GST_LIVE_SIGNAL (basesrc);
|
GST_ASYNC_SIGNAL (basesrc);
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
|
|
||||||
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
|
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
|
||||||
if (bclass->stop)
|
if (bclass->stop)
|
||||||
|
@ -3347,7 +3349,7 @@ gst_base_src_stop (GstBaseSrc * basesrc)
|
||||||
was_stopped:
|
was_stopped:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (basesrc, "was started");
|
GST_DEBUG_OBJECT (basesrc, "was started");
|
||||||
GST_LIVE_UNLOCK (basesrc);
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue