From f5634c2aac2b88f384efd4f063ec9e714f85e7b2 Mon Sep 17 00:00:00 2001 From: Jordan Yelloz <jordan.yelloz@collabora.com> Date: Tue, 18 Feb 2025 13:08:37 -0700 Subject: [PATCH] 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> --- .../gst/mse/gstmediasourcetrackbuffer.c | 35 ++++++++++++++++--- .../gst-plugins-bad/tests/check/libs/mse.c | 2 +- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/mse/gstmediasourcetrackbuffer.c b/subprojects/gst-plugins-bad/gst-libs/gst/mse/gstmediasourcetrackbuffer.c index 1ed9f3944a..f121e64a61 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/mse/gstmediasourcetrackbuffer.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/mse/gstmediasourcetrackbuffer.c @@ -217,6 +217,7 @@ typedef struct { GArray *ranges; GstMediaSourceRange current_range; + GstClockTime max_duration; } GetRangesAccumulator; static gboolean @@ -228,9 +229,23 @@ get_ranges_fold (const GValue * item, GetRangesAccumulator * acc, GstClockTime start = GST_BUFFER_PTS (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; - 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; return TRUE; } @@ -247,24 +262,34 @@ gst_media_source_track_buffer_get_ranges (GstMediaSourceTrackBuffer * self) { GetRangesAccumulator acc = { .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* */ GstIterator *iter = gst_media_source_sample_map_iter_samples_by_pts ( self->samples, &self->new_data_mutex, - &self->master_cookie, - 0, - NULL + &self->master_cookie ); /* *INDENT-ON* */ while (gst_iterator_fold (iter, (GstIteratorFoldFunction) get_ranges_fold, (GValue *) & acc, NULL) == GST_ITERATOR_RESYNC) { 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); + 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) { g_array_append_val (acc.ranges, acc.current_range); } diff --git a/subprojects/gst-plugins-bad/tests/check/libs/mse.c b/subprojects/gst-plugins-bad/tests/check/libs/mse.c index 698b96a0e6..a921f2a47d 100644 --- a/subprojects/gst-plugins-bad/tests/check/libs/mse.c +++ b/subprojects/gst-plugins-bad/tests/check/libs/mse.c @@ -684,7 +684,7 @@ GST_START_TEST (test_track_buffer_discontinuous_span) GstClockTime a_start = 0; 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; 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);