queue: Use full running time for level calculation

Ensures we have proper time level estimation for the cases where
the incoming buffers have PTS/DTS outside of the segment start/stop
values.

https://bugzilla.gnome.org/show_bug.cgi?id=762995
This commit is contained in:
Edward Hervey 2016-03-02 17:47:33 +01:00 committed by Sebastian Dröge
parent 7dd76b626e
commit f87ec5e014
2 changed files with 27 additions and 9 deletions

View file

@ -465,8 +465,8 @@ gst_queue_init (GstQueue * queue)
gst_queue_array_new_for_struct (sizeof (GstQueueItem),
DEFAULT_MAX_SIZE_BUFFERS * 3 / 2);
queue->sinktime = GST_CLOCK_TIME_NONE;
queue->srctime = GST_CLOCK_TIME_NONE;
queue->sinktime = GST_CLOCK_STIME_NONE;
queue->srctime = GST_CLOCK_STIME_NONE;
queue->sink_tainted = TRUE;
queue->src_tainted = TRUE;
@ -501,6 +501,23 @@ gst_queue_finalize (GObject * object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* Convenience function */
static inline GstClockTimeDiff
my_segment_to_running_time (GstSegment * segment, GstClockTime val)
{
GstClockTimeDiff res = GST_CLOCK_STIME_NONE;
if (GST_CLOCK_TIME_IS_VALID (val)) {
gboolean sign =
gst_segment_to_running_time_full (segment, GST_FORMAT_TIME, val, &val);
if (sign > 0)
res = val;
else if (sign < 0)
res = -val;
}
return res;
}
/* calculate the diff between running time on the sink and src of the queue.
* This is the total amount of time in the queue. */
static void
@ -511,7 +528,7 @@ update_time_level (GstQueue * queue)
if (queue->sink_tainted) {
GST_LOG_OBJECT (queue, "update sink time");
queue->sinktime =
gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
my_segment_to_running_time (&queue->sink_segment,
queue->sink_segment.position);
queue->sink_tainted = FALSE;
}
@ -520,14 +537,14 @@ update_time_level (GstQueue * queue)
if (queue->src_tainted) {
GST_LOG_OBJECT (queue, "update src time");
queue->srctime =
gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
my_segment_to_running_time (&queue->src_segment,
queue->src_segment.position);
queue->src_tainted = FALSE;
}
src_time = queue->srctime;
GST_LOG_OBJECT (queue, "sink %" GST_TIME_FORMAT ", src %" GST_TIME_FORMAT,
GST_TIME_ARGS (sink_time), GST_TIME_ARGS (src_time));
GST_LOG_OBJECT (queue, "sink %" GST_STIME_FORMAT ", src %" GST_STIME_FORMAT,
GST_STIME_ARGS (sink_time), GST_STIME_ARGS (src_time));
if (sink_time >= src_time)
queue->cur_level.time = sink_time - src_time;
@ -611,7 +628,8 @@ apply_buffer (GstQueue * queue, GstBuffer * buffer, GstSegment * segment,
if (duration != GST_CLOCK_TIME_NONE)
timestamp += duration;
GST_LOG_OBJECT (queue, "position updated to %" GST_TIME_FORMAT,
GST_LOG_OBJECT (queue, "%s position updated to %" GST_TIME_FORMAT,
segment == &queue->sink_segment ? "sink" : "src",
GST_TIME_ARGS (timestamp));
segment->position = timestamp;
@ -702,7 +720,7 @@ gst_queue_locked_flush (GstQueue * queue, gboolean full)
gst_segment_init (&queue->src_segment, GST_FORMAT_TIME);
queue->head_needs_discont = queue->tail_needs_discont = FALSE;
queue->sinktime = queue->srctime = GST_CLOCK_TIME_NONE;
queue->sinktime = queue->srctime = GST_CLOCK_STIME_NONE;
queue->sink_tainted = queue->src_tainted = TRUE;
/* we deleted a lot of something */

View file

@ -98,7 +98,7 @@ struct _GstQueue {
GstSegment src_segment;
/* position of src/sink */
GstClockTime sinktime, srctime;
GstClockTimeDiff sinktime, srctime;
/* TRUE if either position needs to be recalculated */
gboolean sink_tainted, src_tainted;