qtdemux: Refuse seeks in BYTES format
authorJan Schmidt <jan@centricular.com>
Tue, 22 Jun 2021 07:19:19 +0000 (17:19 +1000)
committerJan Schmidt <jan@centricular.com>
Tue, 22 Jun 2021 08:05:56 +0000 (18:05 +1000)
If downstream tries to seek in BYTES format, don't pass that through
to upstream. The byte positions downstream requests won't make any
sense in the muxed stream. There might be other formats we want to
pass through to upstream, but BYTES is not one of them. If we get a
seeking query about BYTES format, refuse that too.

This fixes a situation where we're playing a fragmented mp4 over http
and qtdemux refuses the initial seek (in TIME format), but then
h264parse/baseparse send a seek in BYTES format and everything falls
apart.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/1014>

gst/isomp4/qtdemux.c

index ac3c039..17a909d 100644 (file)
@@ -716,6 +716,13 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstObject * parent,
       GstFormat fmt;
       gboolean seekable;
 
+      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
+
+      if (fmt == GST_FORMAT_BYTES) {
+        /* We always refuse BYTES seeks from downstream */
+        break;
+      }
+
       /* try upstream first */
       res = gst_pad_query_default (pad, parent, query);
 
@@ -1608,6 +1615,7 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstObject * parent,
     case GST_EVENT_SEEK:
     {
       GstSeekFlags flags = 0;
+      GstFormat seek_format;
       gboolean instant_rate_change;
 
 #ifndef GST_DISABLE_GST_DEBUG
@@ -1617,7 +1625,8 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstObject * parent,
 
       qtdemux->received_seek = TRUE;
 
-      gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);
+      gst_event_parse_seek (event, NULL, &seek_format, &flags, NULL, NULL, NULL,
+          NULL);
       instant_rate_change = ! !(flags & GST_SEEK_FLAG_INSTANT_RATE_CHANGE);
 
       if (seqnum == qtdemux->segment_seqnum) {
@@ -1634,6 +1643,12 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstObject * parent,
         goto upstream;
       }
 
+      if (seek_format == GST_FORMAT_BYTES) {
+        GST_DEBUG_OBJECT (pad, "Rejecting seek request in bytes format");
+        gst_event_unref (event);
+        return FALSE;
+      }
+
       gst_event_parse_seek_trickmode_interval (event,
           &qtdemux->trickmode_interval);