add an optional timeout for when queue blocks. when timeout is reached a GST_EVENT_FILLER is sent downstream

Original commit message from CVS:
add an optional timeout for when queue blocks. when timeout is reached a GST_EVENT_FILLER is sent downstream
This is needed for gst-player since videosink has to be in the same thread as the ui, and spider blocks when there is no video (thus freezing the ui).
This commit is contained in:
Steve Baker 2002-06-03 15:44:28 +00:00
parent 13da8d6e09
commit 8713cd5e0e
4 changed files with 56 additions and 2 deletions

View file

@ -66,6 +66,7 @@ enum {
ARG_LEVEL,
ARG_MAX_LEVEL,
ARG_MAY_DEADLOCK,
ARG_BLOCK_TIMEOUT,
};
@ -156,6 +157,11 @@ gst_queue_class_init (GstQueueClass *klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAY_DEADLOCK,
g_param_spec_boolean ("may_deadlock", "May Deadlock", "The queue may deadlock if it's full and not PLAYING",
TRUE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BLOCK_TIMEOUT,
g_param_spec_int ("block_timeout", "Timeout for Block",
"Microseconds until blocked queue times out and returns filler event. "
"Value of -1 disables timeout",
-1, G_MAXINT, -1, G_PARAM_READWRITE));
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_queue_dispose);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property);
@ -223,6 +229,7 @@ gst_queue_init (GstQueue *queue)
queue->size_bytes = 100 * 1024; /* 100KB */
queue->size_time = 1000000000LL; /* 1sec */
queue->may_deadlock = TRUE;
queue->block_timeout = -1;
queue->qlock = g_mutex_new ();
queue->reader = FALSE;
@ -469,7 +476,19 @@ restart:
if (queue->reader)
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "WARNING: multiple readers on queue!");
queue->reader = TRUE;
g_cond_wait (queue->not_empty, queue->qlock);
if (queue->block_timeout > -1){
GTimeVal timeout;
g_get_current_time(&timeout);
g_time_val_add(&timeout, queue->block_timeout);
if (!g_cond_timed_wait (queue->not_empty, queue->qlock, &timeout)){
g_mutex_unlock (queue->qlock);
return GST_BUFFER(gst_event_new_filler());
}
}
else {
g_cond_wait (queue->not_empty, queue->qlock);
}
queue->reader = FALSE;
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "got not_empty signal");
}
@ -637,6 +656,9 @@ gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GPa
case ARG_MAY_DEADLOCK:
queue->may_deadlock = g_value_get_boolean (value);
break;
case ARG_BLOCK_TIMEOUT:
queue->block_timeout = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -666,6 +688,9 @@ gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe
case ARG_MAY_DEADLOCK:
g_value_set_boolean (value, queue->may_deadlock);
break;
case ARG_BLOCK_TIMEOUT:
g_value_set_int (value, queue->block_timeout);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;

View file

@ -74,6 +74,8 @@ struct _GstQueue {
guint64 size_time; /* size of queue in time */
gint leaky; /* whether the queue is leaky, and if so at which end */
gint block_timeout; /* microseconds until a blocked queue times out and returns GST_EVENT_FILLER.
* A value of -1 will block forever. */
gboolean may_deadlock; /* it the queue should fail on possible deadlocks */
gboolean interrupt;

View file

@ -66,6 +66,7 @@ enum {
ARG_LEVEL,
ARG_MAX_LEVEL,
ARG_MAY_DEADLOCK,
ARG_BLOCK_TIMEOUT,
};
@ -156,6 +157,11 @@ gst_queue_class_init (GstQueueClass *klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAY_DEADLOCK,
g_param_spec_boolean ("may_deadlock", "May Deadlock", "The queue may deadlock if it's full and not PLAYING",
TRUE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BLOCK_TIMEOUT,
g_param_spec_int ("block_timeout", "Timeout for Block",
"Microseconds until blocked queue times out and returns filler event. "
"Value of -1 disables timeout",
-1, G_MAXINT, -1, G_PARAM_READWRITE));
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_queue_dispose);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property);
@ -223,6 +229,7 @@ gst_queue_init (GstQueue *queue)
queue->size_bytes = 100 * 1024; /* 100KB */
queue->size_time = 1000000000LL; /* 1sec */
queue->may_deadlock = TRUE;
queue->block_timeout = -1;
queue->qlock = g_mutex_new ();
queue->reader = FALSE;
@ -469,7 +476,19 @@ restart:
if (queue->reader)
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "WARNING: multiple readers on queue!");
queue->reader = TRUE;
g_cond_wait (queue->not_empty, queue->qlock);
if (queue->block_timeout > -1){
GTimeVal timeout;
g_get_current_time(&timeout);
g_time_val_add(&timeout, queue->block_timeout);
if (!g_cond_timed_wait (queue->not_empty, queue->qlock, &timeout)){
g_mutex_unlock (queue->qlock);
return GST_BUFFER(gst_event_new_filler());
}
}
else {
g_cond_wait (queue->not_empty, queue->qlock);
}
queue->reader = FALSE;
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "got not_empty signal");
}
@ -637,6 +656,9 @@ gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GPa
case ARG_MAY_DEADLOCK:
queue->may_deadlock = g_value_get_boolean (value);
break;
case ARG_BLOCK_TIMEOUT:
queue->block_timeout = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -666,6 +688,9 @@ gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe
case ARG_MAY_DEADLOCK:
g_value_set_boolean (value, queue->may_deadlock);
break;
case ARG_BLOCK_TIMEOUT:
g_value_set_int (value, queue->block_timeout);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;

View file

@ -74,6 +74,8 @@ struct _GstQueue {
guint64 size_time; /* size of queue in time */
gint leaky; /* whether the queue is leaky, and if so at which end */
gint block_timeout; /* microseconds until a blocked queue times out and returns GST_EVENT_FILLER.
* A value of -1 will block forever. */
gboolean may_deadlock; /* it the queue should fail on possible deadlocks */
gboolean interrupt;