mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-14 05:12:09 +00:00
queue: queue2: multiqueue: Don't work with segment.position if buffers have no timestamps
If the first buffers have no timestamp then the sink position would be initialized to 0. The source pad might output this buffer, which would then initialize the source position to 0 too. Afterwards two buffers with a valid but huge timestamp might arrive before any of them are output on the source pad. The first one would set the sink position to a huge value, the second one would notice that the difference between the huge value and 0 is certainly larger than max-size-time and consider the queue as full. Instead, simply don't update the times from buffers without timestamps and assume whatever was set before is still valid, i.e. the buffer has the same timestamp as the previous one. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7071>
This commit is contained in:
parent
e90880e988
commit
909cd6d865
3 changed files with 35 additions and 20 deletions
|
@ -1836,10 +1836,15 @@ apply_buffer (GstMultiQueue * mq, GstSingleQueue * sq, GstClockTime timestamp,
|
|||
|
||||
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
|
||||
|
||||
/* if no timestamp is set, assume it's continuous with the previous
|
||||
* time */
|
||||
if (timestamp == GST_CLOCK_TIME_NONE)
|
||||
timestamp = segment->position;
|
||||
/* if no timestamp is set, assume it didn't change compared to the previous
|
||||
* buffer and simply return here. Non-time limits might have still changed
|
||||
* and a buffering message might have to be posted */
|
||||
if (timestamp == GST_CLOCK_TIME_NONE) {
|
||||
update_buffering (mq, sq);
|
||||
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
|
||||
gst_multi_queue_post_buffering (mq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_sink && !GST_CLOCK_STIME_IS_VALID (sq->sink_start_time)) {
|
||||
sq->sink_start_time = my_segment_to_running_time (segment, timestamp);
|
||||
|
|
|
@ -642,10 +642,10 @@ apply_buffer (GstQueue * queue, GstBuffer * buffer, GstSegment * segment,
|
|||
timestamp = GST_BUFFER_DTS_OR_PTS (buffer);
|
||||
duration = GST_BUFFER_DURATION (buffer);
|
||||
|
||||
/* if no timestamp is set, assume it's continuous with the previous
|
||||
* time */
|
||||
/* if no timestamp is set, assume it didn't change compared to the previous
|
||||
* buffer and simply return here */
|
||||
if (timestamp == GST_CLOCK_TIME_NONE)
|
||||
timestamp = segment->position;
|
||||
return;
|
||||
|
||||
if (is_sink && !GST_CLOCK_STIME_IS_VALID (queue->sink_start_time) &&
|
||||
GST_CLOCK_TIME_IS_VALID (timestamp)) {
|
||||
|
@ -696,7 +696,8 @@ buffer_list_apply_time (GstBuffer ** buf, guint idx, gpointer user_data)
|
|||
data->timestamp = btime;
|
||||
}
|
||||
|
||||
if (GST_BUFFER_DURATION_IS_VALID (*buf))
|
||||
if (GST_BUFFER_DURATION_IS_VALID (*buf)
|
||||
&& GST_CLOCK_TIME_IS_VALID (data->timestamp))
|
||||
data->timestamp += GST_BUFFER_DURATION (*buf);
|
||||
|
||||
GST_TRACE ("ts now %" GST_TIME_FORMAT, GST_TIME_ARGS (data->timestamp));
|
||||
|
@ -713,11 +714,15 @@ apply_buffer_list (GstQueue * queue, GstBufferList * buffer_list,
|
|||
|
||||
data.first_timestamp = GST_CLOCK_TIME_NONE;
|
||||
|
||||
/* if no timestamp is set, assume it's continuous with the previous time */
|
||||
data.timestamp = segment->position;
|
||||
/* if no timestamp is set, assume it didn't change compared to the previous
|
||||
* buffer and simply return here without updating */
|
||||
data.timestamp = GST_CLOCK_TIME_NONE;
|
||||
|
||||
gst_buffer_list_foreach (buffer_list, buffer_list_apply_time, &data);
|
||||
|
||||
if (!GST_CLOCK_TIME_IS_VALID (data.timestamp))
|
||||
return;
|
||||
|
||||
if (is_sink && !GST_CLOCK_STIME_IS_VALID (queue->sink_start_time) &&
|
||||
GST_CLOCK_TIME_IS_VALID (data.first_timestamp)) {
|
||||
queue->sink_start_time = my_segment_to_running_time (segment,
|
||||
|
|
|
@ -896,6 +896,12 @@ apply_buffer (GstQueue2 * queue, GstBuffer * buffer, GstSegment * segment,
|
|||
GstClockTime duration, timestamp;
|
||||
|
||||
timestamp = GST_BUFFER_DTS_OR_PTS (buffer);
|
||||
|
||||
/* if no timestamp is set, assume it didn't change compared to the previous
|
||||
* buffer and simply return here */
|
||||
if (timestamp == GST_CLOCK_TIME_NONE)
|
||||
return;
|
||||
|
||||
duration = GST_BUFFER_DURATION (buffer);
|
||||
|
||||
/* If we have no duration, pick one from the bitrate if we can */
|
||||
|
@ -919,11 +925,6 @@ apply_buffer (GstQueue2 * queue, GstBuffer * buffer, GstSegment * segment,
|
|||
}
|
||||
}
|
||||
|
||||
/* if no timestamp is set, assume it's continuous with the previous
|
||||
* time */
|
||||
if (timestamp == GST_CLOCK_TIME_NONE)
|
||||
timestamp = segment->position;
|
||||
|
||||
if (is_sink && !GST_CLOCK_TIME_IS_VALID (queue->sink_start_time) &&
|
||||
GST_CLOCK_TIME_IS_VALID (timestamp)) {
|
||||
queue->sink_start_time = gst_segment_to_running_time (segment,
|
||||
|
@ -978,16 +979,16 @@ buffer_list_apply_time (GstBuffer ** buf, guint idx, gpointer data)
|
|||
*timestamp = btime;
|
||||
}
|
||||
|
||||
if (GST_BUFFER_DURATION_IS_VALID (*buf))
|
||||
if (GST_BUFFER_DURATION_IS_VALID (*buf)
|
||||
&& GST_CLOCK_TIME_IS_VALID (*timestamp)) {
|
||||
*timestamp += GST_BUFFER_DURATION (*buf);
|
||||
else if (bld->bitrate != 0) {
|
||||
} else if (bld->bitrate != 0 && GST_CLOCK_TIME_IS_VALID (*timestamp)) {
|
||||
guint64 size = gst_buffer_get_size (*buf);
|
||||
|
||||
/* If we have no duration, pick one from the bitrate if we can */
|
||||
*timestamp += gst_util_uint64_scale (bld->bitrate, 8 * GST_SECOND, size);
|
||||
}
|
||||
|
||||
|
||||
GST_TRACE ("ts now %" GST_TIME_FORMAT, GST_TIME_ARGS (*timestamp));
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1001,8 +1002,9 @@ apply_buffer_list (GstQueue2 * queue, GstBufferList * buffer_list,
|
|||
|
||||
bld.first_timestamp = GST_CLOCK_TIME_NONE;
|
||||
|
||||
/* if no timestamp is set, assume it's continuous with the previous time */
|
||||
bld.timestamp = segment->position;
|
||||
/* if no timestamp is set, assume it didn't change compared to the previous
|
||||
* buffer and simply return here without updating */
|
||||
bld.timestamp = GST_CLOCK_TIME_NONE;
|
||||
|
||||
bld.bitrate = 0;
|
||||
if (queue->use_tags_bitrate) {
|
||||
|
@ -1017,6 +1019,9 @@ apply_buffer_list (GstQueue2 * queue, GstBufferList * buffer_list,
|
|||
|
||||
gst_buffer_list_foreach (buffer_list, buffer_list_apply_time, &bld);
|
||||
|
||||
if (!GST_CLOCK_TIME_IS_VALID (bld.timestamp))
|
||||
return;
|
||||
|
||||
if (is_sink && !GST_CLOCK_TIME_IS_VALID (queue->sink_start_time) &&
|
||||
GST_CLOCK_TIME_IS_VALID (bld.first_timestamp)) {
|
||||
queue->sink_start_time = gst_segment_to_running_time (segment,
|
||||
|
|
Loading…
Reference in a new issue