static void single_queue_underrun_cb (GstDataQueue * dq, GstSingleQueue * sq);
static void update_buffering (GstMultiQueue * mq, GstSingleQueue * sq);
+static void gst_multi_queue_post_buffering (GstMultiQueue * mq);
static void gst_single_queue_flush_queue (GstSingleQueue * sq, gboolean full);
g_mutex_unlock (&q->qlock); \
} G_STMT_END
+#define SET_PERCENT(mq, perc) G_STMT_START { \
+ if (perc != mq->percent) { \
+ mq->percent = perc; \
+ mq->percent_changed = TRUE; \
+ GST_DEBUG_OBJECT (mq, "buffering %d percent", perc); \
+ } \
+} G_STMT_END
+
static void gst_multi_queue_finalize (GObject * object);
static void gst_multi_queue_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
mqueue->high_time = GST_CLOCK_TIME_NONE;
g_mutex_init (&mqueue->qlock);
+ g_mutex_init (&mqueue->buffering_post_lock);
}
static void
/* free/unref instance data */
g_mutex_clear (&mqueue->qlock);
+ g_mutex_clear (&mqueue->buffering_post_lock);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
mq->max_size.bytes = g_value_get_uint (value);
SET_CHILD_PROPERTY (mq, bytes);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
+ gst_multi_queue_post_buffering (mq);
break;
case PROP_MAX_SIZE_BUFFERS:
{
}
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
+ gst_multi_queue_post_buffering (mq);
break;
}
mq->max_size.time = g_value_get_uint64 (value);
SET_CHILD_PROPERTY (mq, time);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
+ gst_multi_queue_post_buffering (mq);
break;
case PROP_EXTRA_SIZE_BYTES:
mq->extra_size.bytes = g_value_get_uint (value);
case PROP_USE_BUFFERING:
mq->use_buffering = g_value_get_boolean (value);
if (!mq->use_buffering && mq->buffering) {
- GstMessage *message;
-
+ GST_MULTI_QUEUE_MUTEX_LOCK (mq);
mq->buffering = FALSE;
GST_DEBUG_OBJECT (mq, "buffering 100 percent");
- message = gst_message_new_buffering (GST_OBJECT_CAST (mq), 100);
-
- gst_element_post_message (GST_ELEMENT_CAST (mq), message);
+ SET_PERCENT (mq, 100);
+ GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
}
if (mq->use_buffering) {
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
}
+ gst_multi_queue_post_buffering (mq);
break;
case PROP_LOW_PERCENT:
mq->low_percent = g_value_get_int (value);
SET_CHILD_PROPERTY (mqueue, visible);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue);
+ gst_multi_queue_post_buffering (mqueue);
break;
}
update_buffering (GstMultiQueue * mq, GstSingleQueue * sq)
{
gint percent;
- gboolean post = FALSE;
/* nothing to dowhen we are not in buffering mode */
if (!mq->use_buffering)
percent = get_percentage (sq);
if (mq->buffering) {
- post = TRUE;
if (percent >= mq->high_percent) {
mq->buffering = FALSE;
}
/* make sure it increases */
percent = MAX (mq->percent, percent);
- if (percent == mq->percent)
- /* don't post if nothing changed */
- post = FALSE;
- else
- /* else keep last value we posted */
- mq->percent = percent;
+ SET_PERCENT (mq, percent);
} else {
GList *iter;
gboolean is_buffering = TRUE;
if (is_buffering && percent < mq->low_percent) {
mq->buffering = TRUE;
- mq->percent = percent;
- post = TRUE;
+ SET_PERCENT (mq, percent);
}
}
- if (post) {
- GstMessage *message;
+}
+
+static void
+gst_multi_queue_post_buffering (GstMultiQueue * mq)
+{
+ GstMessage *msg = NULL;
+
+ g_mutex_lock (&mq->buffering_post_lock);
+ GST_MULTI_QUEUE_MUTEX_LOCK (mq);
+ if (mq->percent_changed) {
+ gint percent = mq->percent;
+
+ mq->percent_changed = FALSE;
- /* scale to high percent so that it becomes the 100% mark */
percent = percent * 100 / mq->high_percent;
/* clip */
if (percent > 100)
percent = 100;
- GST_DEBUG_OBJECT (mq, "buffering %d percent", percent);
- message = gst_message_new_buffering (GST_OBJECT_CAST (mq), percent);
-
- gst_element_post_message (GST_ELEMENT_CAST (mq), message);
- } else {
- GST_DEBUG_OBJECT (mq, "filled %d percent", percent);
+ GST_DEBUG_OBJECT (mq, "Going to post buffering: %d%%", percent);
+ msg = gst_message_new_buffering (GST_OBJECT_CAST (mq), percent);
}
+ GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
+
+ if (msg != NULL)
+ gst_element_post_message (GST_ELEMENT_CAST (mq), msg);
+
+ g_mutex_unlock (&mq->buffering_post_lock);
}
/* calculate the diff between running time on the sink and src of the queue.
update_time_level (mq, sq);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
+ gst_multi_queue_post_buffering (mq);
}
/* take a buffer and update segment, updating the time level of the queue. */
/* calc diff with other end */
update_time_level (mq, sq);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
+ gst_multi_queue_post_buffering (mq);
}
static GstClockTime
update_buffering (mq, sq);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
+ gst_multi_queue_post_buffering (mq);
if (result != GST_FLOW_OK && result != GST_FLOW_NOT_LINKED
&& result != GST_FLOW_EOS)
update_buffering (mq, sq);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
single_queue_overrun_cb (sq->queue, sq);
+ gst_multi_queue_post_buffering (mq);
break;
case GST_EVENT_SEGMENT:
apply_segment (mq, sq, sref, &sq->sink_segment);
GST_MULTI_QUEUE_MUTEX_LOCK (sq->mqueue);
update_buffering (sq->mqueue, sq);
GST_MULTI_QUEUE_MUTEX_UNLOCK (sq->mqueue);
+ gst_multi_queue_post_buffering (sq->mqueue);
}
static void