gstmediasourcetrackbuffer: Improved buffered ranges calculation

Now when the buffered list is requested, the tolerance for merging two ranges
when there's a small gap between them is MAX(0.1sec, max frame duration * 2).

Previously it was hardcoded to 0.01sec. The specification suggests that it
could be something like the max frame duration * 2.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8512>
This commit is contained in:
Jordan Yelloz 2025-02-18 13:08:37 -07:00 committed by GStreamer Marge Bot
parent 3b32f53d7b
commit f5634c2aac
2 changed files with 31 additions and 6 deletions

View File

@ -217,6 +217,7 @@ typedef struct
{ {
GArray *ranges; GArray *ranges;
GstMediaSourceRange current_range; GstMediaSourceRange current_range;
GstClockTime max_duration;
} GetRangesAccumulator; } GetRangesAccumulator;
static gboolean static gboolean
@ -228,9 +229,23 @@ get_ranges_fold (const GValue * item, GetRangesAccumulator * acc,
GstClockTime start = GST_BUFFER_PTS (buffer); GstClockTime start = GST_BUFFER_PTS (buffer);
GstClockTime end = start + GST_BUFFER_DURATION (buffer); GstClockTime end = start + GST_BUFFER_DURATION (buffer);
if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
acc->max_duration = MAX (acc->max_duration, GST_BUFFER_DURATION (buffer));
}
GstMediaSourceRange *range = &acc->current_range; GstMediaSourceRange *range = &acc->current_range;
if (range->end == 0 || start <= (range->end + (GST_SECOND / 100))) { if (!GST_CLOCK_TIME_IS_VALID (acc->current_range.start)) {
acc->current_range.start = start;
}
if (!GST_CLOCK_TIME_IS_VALID (acc->current_range.end)) {
acc->current_range.end = end;
}
GstClockTime gap_tolerance = MAX (GST_SECOND / 10, acc->max_duration * 2);
GstClockTime gap = MAX (0, GST_CLOCK_DIFF (range->end, start));
if (range->end == 0 || gap <= gap_tolerance) {
range->end = end; range->end = end;
return TRUE; return TRUE;
} }
@ -247,24 +262,34 @@ gst_media_source_track_buffer_get_ranges (GstMediaSourceTrackBuffer * self)
{ {
GetRangesAccumulator acc = { GetRangesAccumulator acc = {
.ranges = g_array_new_ranges (), .ranges = g_array_new_ranges (),
.current_range = {.start = 0,.end = 0}, .max_duration = 0,
.current_range = {.start = GST_CLOCK_TIME_NONE,.end = GST_CLOCK_TIME_NONE},
}; };
/* *INDENT-OFF* */ /* *INDENT-OFF* */
GstIterator *iter = gst_media_source_sample_map_iter_samples_by_pts ( GstIterator *iter = gst_media_source_sample_map_iter_samples_by_pts (
self->samples, self->samples,
&self->new_data_mutex, &self->new_data_mutex,
&self->master_cookie, &self->master_cookie
0,
NULL
); );
/* *INDENT-ON* */ /* *INDENT-ON* */
while (gst_iterator_fold (iter, (GstIteratorFoldFunction) get_ranges_fold, while (gst_iterator_fold (iter, (GstIteratorFoldFunction) get_ranges_fold,
(GValue *) & acc, NULL) == GST_ITERATOR_RESYNC) { (GValue *) & acc, NULL) == GST_ITERATOR_RESYNC) {
gst_iterator_resync (iter); gst_iterator_resync (iter);
g_clear_pointer (&acc.ranges, g_array_unref);
acc.ranges = g_array_new_ranges ();
acc.max_duration = 0;
acc.current_range.start = GST_CLOCK_TIME_NONE;
acc.current_range.end = GST_CLOCK_TIME_NONE;
} }
gst_iterator_free (iter); gst_iterator_free (iter);
if (!GST_CLOCK_TIME_IS_VALID (acc.current_range.start)) {
acc.current_range.start = 0;
}
if (!GST_CLOCK_TIME_IS_VALID (acc.current_range.end)) {
acc.current_range.end = 0;
}
if (acc.current_range.end > 0) { if (acc.current_range.end > 0) {
g_array_append_val (acc.ranges, acc.current_range); g_array_append_val (acc.ranges, acc.current_range);
} }

View File

@ -684,7 +684,7 @@ GST_START_TEST (test_track_buffer_discontinuous_span)
GstClockTime a_start = 0; GstClockTime a_start = 0;
GstClockTime a_duration = GST_SECOND; GstClockTime a_duration = GST_SECOND;
GstClockTime b_start = a_start + a_duration + GST_SECOND; GstClockTime b_start = a_start + (a_duration * 3) + 1;
GstClockTime b_duration = a_duration; GstClockTime b_duration = a_duration;
GstSample *a = new_empty_sample_with_timing (a_start, a_start, a_duration); GstSample *a = new_empty_sample_with_timing (a_start, a_start, a_duration);
GstSample *b = new_empty_sample_with_timing (b_start, b_start, b_duration); GstSample *b = new_empty_sample_with_timing (b_start, b_start, b_duration);