After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 782118 - qtdemux: Fix seeking on streams with frame reordering
qtdemux: Fix seeking on streams with frame reordering
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
unspecified
Other All
: Normal normal
: 1.15.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2017-05-03 11:27 UTC by Sebastian Dröge (slomo)
Modified: 2018-03-20 12:25 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
qtdemux: Fix seeking on streams with frame reordering (3.66 KB, patch)
2017-05-03 11:27 UTC, Sebastian Dröge (slomo)
none Details | Review
qtdemux: Fix seeking on streams with frame reordering (3.32 KB, patch)
2018-03-05 11:21 UTC, Sebastian Dröge (slomo)
committed Details | Review

Description Sebastian Dröge (slomo) 2017-05-03 11:27:18 UTC
See commit message
Comment 1 Sebastian Dröge (slomo) 2017-05-03 11:27:24 UTC
Created attachment 350966 [details] [review]
qtdemux: Fix seeking on streams with frame reordering

The samples table is sorted by DTS, not PTS. As such we can only get the
correct result when using a binary search on it, if we search for the
DTS.
Also if we only ever search for the frame, where the following frame is
the first one with a PTS after the search position, we will generally
stop searching too early if frames are reordered.

In forwards playback this is not really a problem (after the decoder
reordered the frames, clipping is happening), in reverse playback
it means that we can output one or more frames too few as we stop too
early and the decoder would never receive it.
Comment 2 Sebastian Dröge (slomo) 2017-05-03 11:30:26 UTC
This assumes that DTS <= PTS. We search for the frame that has as DTS the target PTS (i.e. its PTS is >= the target PTS), and from there on search backwards to get closer to the target PTS.
Comment 3 Nicolas Dufresne (ndufresne) 2017-05-03 15:32:02 UTC
Ah, so same stop condition you mentioned on IRC, but while going backward.
Comment 4 Nicolas Dufresne (ndufresne) 2017-05-03 15:37:56 UTC
Review of attachment 350966 [details] [review]:

Looks good to me. I only have nitpick kind of comments.

::: gst/isomp4/qtdemux.c
@@ +1175,3 @@
+  /* sample->timestamp is now <= media_time, need to find the corresponding
+   * PTS now by looking backwards */
+  while (index > 0 && sample->timestamp + sample->pts_offset > mov_time) {

Maybe some parenthesis for the reader ?

@@ +1180,3 @@
   }
+
+

Maybe just one empty line will do ?

@@ +4931,2 @@
     goto eos;
+  }

Maybe you can remove that part, it does not change anything.
Comment 5 Nicolas Dufresne (ndufresne) 2017-05-03 15:45:07 UTC
Review of attachment 350966 [details] [review]:

::: gst/isomp4/qtdemux.c
@@ +1163,3 @@
+    while (index < str->n_samples - 1) {
+      if (!qtdemux_parse_samples (qtdemux, str, index + 1))
+        goto parse_failed;

Actually, there is a possible corner case. If the position is passed that last DTS, which happens when you seek to the last sample, it will reach parse_failed. While it should pick the last sample as if it was searching backward.

DTS: 0 1 2
PTS: 1 3 2

The algo works for seeking at 1 and 2, but not 3.
Comment 6 Sebastian Dröge (slomo) 2017-05-03 16:03:10 UTC
Indeed, thanks. Will update :)
Comment 7 Sebastian Dröge (slomo) 2018-03-05 11:21:28 UTC
Created attachment 369325 [details] [review]
qtdemux: Fix seeking on streams with frame reordering

The samples table is sorted by DTS, not PTS. As such we can only get the
correct result when using a binary search on it, if we search for the
DTS.
Also if we only ever search for the frame, where the following frame is
the first one with a PTS after the search position, we will generally
stop searching too early if frames are reordered.

In forwards playback this is not really a problem (after the decoder
reordered the frames, clipping is happening), in reverse playback
it means that we can output one or more frames too few as we stop too
early and the decoder would never receive it.
Comment 8 Sebastian Dröge (slomo) 2018-03-05 11:24:41 UTC
(In reply to Nicolas Dufresne (stormer) from comment #5)
> Review of attachment 350966 [details] [review] [review]:
> 
> ::: gst/isomp4/qtdemux.c
> @@ +1163,3 @@
> +    while (index < str->n_samples - 1) {
> +      if (!qtdemux_parse_samples (qtdemux, str, index + 1))
> +        goto parse_failed;
> 
> Actually, there is a possible corner case. If the position is passed that
> last DTS, which happens when you seek to the last sample, it will reach
> parse_failed. While it should pick the last sample as if it was searching
> backward.
> 
> DTS: 0 1 2
> PTS: 1 3 2
> 
> The algo works for seeking at 1 and 2, but not 3.

This is actually wrong. If we seek to 3, what will happen is that all samples up to n_samples (3) - 2 + 1 == 2 are parsed (i.e. we parsed 0, 1, 2) and then the while loop finishes and we start looking backwards from the last sample (2).

This loop would only ever run into parse_failed if the parsing itself of the sample fails. It will never ever try to call qtdemux_parse_samples() with index==n_samples.


There was a different minor bug though, which is fixed now. And your other review comments too. I'll merge this right after 1.14 unless someone finds another problem :)
Comment 9 Sebastian Dröge (slomo) 2018-03-20 12:10:31 UTC
Attachment 369325 [details] pushed as 850e678 - qtdemux: Fix seeking on streams with frame reordering