From 6dad5345ea387967c632159cde0515dd3ac85512 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Piotr=20Brzezi=C5=84ski?= Date: Mon, 20 Mar 2023 16:35:45 +0100 Subject: [PATCH] qtdemux: Fix seek adjustment with SNAP_AFTER flag With GST_SEEK_FLAG_SNAP_AFTER present, the previous version would adjust seek time based on the keyframe farthest away from desired_time. This was incorrect, because we always want the *earliest* suitable keyframe to seek to, not the last one. With this fix, in case of the SNAP_AFTER, we now look for the closest keyframe that can be found after desired_time. Behaviour for SNAP_BEFORE should remain unchanged. Part-of: --- subprojects/gst-plugins-good/gst/isomp4/qtdemux.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c index 5723fce..b9b1c3f 100644 --- a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c +++ b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c @@ -1125,7 +1125,7 @@ gst_qtdemux_adjust_seek (GstQTDemux * qtdemux, gint64 desired_time, gint64 min_byte_offset = -1; guint i; - min_offset = desired_time; + min_offset = next ? G_MAXUINT64 : desired_time; /* for each stream, find the index of the sample in the segment * and move back to the previous keyframe. */ @@ -1184,10 +1184,10 @@ gst_qtdemux_adjust_seek (GstQTDemux * qtdemux, gint64 desired_time, index++; if (!empty_segment) { - /* find previous keyframe */ + /* find previous or next keyframe */ kindex = gst_qtdemux_find_keyframe (qtdemux, str, index, next); - /* we will settle for one before if none found after */ + /* if looking for next one, we will settle for one before if none found after */ if (next && kindex == -1) kindex = gst_qtdemux_find_keyframe (qtdemux, str, index, FALSE); @@ -1213,8 +1213,12 @@ gst_qtdemux_adjust_seek (GstQTDemux * qtdemux, gint64 desired_time, /* this keyframe is inside the segment, convert back to * segment time */ seg_time = (media_time - seg->media_start) + seg->time; - if ((!next && (seg_time < min_offset)) || - (next && (seg_time > min_offset))) + + /* Adjust the offset based on the earliest suitable keyframe found, + * based on which GST_SEEK_FLAG_SNAP_* is present (indicated by 'next'). + * For SNAP_BEFORE we look for the earliest keyframe before desired_time, + * and in case of SNAP_AFTER - for the closest one after it. */ + if (seg_time < min_offset) min_offset = seg_time; } } -- 2.7.4