mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
queue2: avoid ping-pong between 0% and 100% buffering messages
If upstream is pushing buffers larger than our limits, only 1 buffer is ever in the queue at a time. Once that single buffer has left the queue, a 0% buffering message would be posted followed immediately by a 100% buffering message when the next buffer was inserted into the queue a very short time later. As per the recommendations, This would result in the application pausing for a short while causing the appearance of a short stutter. The first step of a solution involves not posting a buffering message if there is still data waiting on the sink pad for insertion into the queue. This successfully drops the 0% messages from being posted however a message is still posted on each transition to 100% when the new buffer arrives resulting in a string of 100% buffering messages. We silence these by storing the last posted buffering percentage and only posting a new message when it is different from or last posted message.
This commit is contained in:
parent
e1be065293
commit
c4ccff7861
2 changed files with 24 additions and 8 deletions
|
@ -531,6 +531,7 @@ gst_queue2_init (GstQueue2 * queue)
|
||||||
|
|
||||||
g_mutex_init (&queue->buffering_post_lock);
|
g_mutex_init (&queue->buffering_post_lock);
|
||||||
queue->buffering_percent = 100;
|
queue->buffering_percent = 100;
|
||||||
|
queue->last_posted_buffering_percent = -1;
|
||||||
|
|
||||||
/* tempfile related */
|
/* tempfile related */
|
||||||
queue->temp_template = NULL;
|
queue->temp_template = NULL;
|
||||||
|
@ -1056,17 +1057,31 @@ static GstMessage *
|
||||||
gst_queue2_get_buffering_message (GstQueue2 * queue)
|
gst_queue2_get_buffering_message (GstQueue2 * queue)
|
||||||
{
|
{
|
||||||
GstMessage *msg = NULL;
|
GstMessage *msg = NULL;
|
||||||
|
|
||||||
if (queue->percent_changed) {
|
if (queue->percent_changed) {
|
||||||
gint percent = queue->buffering_percent;
|
/* Don't change the buffering level if the sinkpad is waiting for
|
||||||
|
* space to become available. This prevents the situation where,
|
||||||
|
* upstream is pushing buffers larger than our limits so only 1 buffer
|
||||||
|
* is ever in the queue at a time.
|
||||||
|
* Changing the level causes a buffering message to be posted saying that
|
||||||
|
* we are buffering which the application may pause to wait for another
|
||||||
|
* 100% buffering message which would be posted very soon after the
|
||||||
|
* waiting sink thread adds it's buffer to the queue */
|
||||||
|
/* FIXME: This situation above can still occur later if
|
||||||
|
* the sink pad is waiting to push a serialized event into the queue and
|
||||||
|
* the queue becomes empty for a short period of time. */
|
||||||
|
if (!queue->waiting_del
|
||||||
|
&& queue->last_posted_buffering_percent != queue->buffering_percent) {
|
||||||
|
gint percent = queue->buffering_percent;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (queue, "Going to post buffering: %d%%", percent);
|
||||||
|
msg = gst_message_new_buffering (GST_OBJECT_CAST (queue), percent);
|
||||||
|
|
||||||
|
gst_message_set_buffering_stats (msg, queue->mode, queue->avg_in,
|
||||||
|
queue->avg_out, queue->buffering_left);
|
||||||
|
|
||||||
|
queue->last_posted_buffering_percent = percent;
|
||||||
|
}
|
||||||
queue->percent_changed = FALSE;
|
queue->percent_changed = FALSE;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (queue, "Going to post buffering: %d%%", percent);
|
|
||||||
msg = gst_message_new_buffering (GST_OBJECT_CAST (queue), percent);
|
|
||||||
|
|
||||||
gst_message_set_buffering_stats (msg, queue->mode, queue->avg_in,
|
|
||||||
queue->avg_out, queue->buffering_left);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
|
|
|
@ -119,6 +119,7 @@ struct _GstQueue2
|
||||||
/* current buffering state */
|
/* current buffering state */
|
||||||
gboolean is_buffering;
|
gboolean is_buffering;
|
||||||
gint buffering_percent;
|
gint buffering_percent;
|
||||||
|
gint last_posted_buffering_percent;
|
||||||
|
|
||||||
/* for measuring input/output rates */
|
/* for measuring input/output rates */
|
||||||
GTimer *in_timer;
|
GTimer *in_timer;
|
||||||
|
|
Loading…
Reference in a new issue