Bug 189444 - [GStreamer] webkitwebsrc fails to handle non seekable sources
Summary: [GStreamer] webkitwebsrc fails to handle non seekable sources
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKitGTK (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-09-07 17:20 PDT by Alicia Boya García
Modified: 2019-03-22 07:27 PDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alicia Boya García 2018-09-07 17:20:24 PDT
Background: The HTTP response header Accept-Ranges specifies whether the server accepts Range (partial) requests. The valid values are "bytes" (ranges allowed) or "none" (ranges not allowed).

Accept-Ranges is not always used and what to assume in its absence AFAIK is not specified by the HTTP 1.1 RFC. (MDN seems to imply that "none" is the default, but I could not find a source to confirm that.)

In the case of webkitwebsrc, this is the condition to determine whether a given source is seekable:

priv->seekable = length > 0 && g_ascii_strcasecmp("none", response.httpHeaderField(HTTPHeaderName::AcceptRanges).utf8().data());

That is, the length of the response must be defined in the headers (i.e. it won't attempt to seek if the response is chunked) and Accept-Ranges must not be explicitly set to "none".

If the source is deemed to be seekable but when later webkitwebsrc receives a seek this turns out to be a wrong guess, the HTTP response will be consumed until the seek target position is reached. This is wasteful, but at least playback works this way.

So far so good. The problem is the other case, when priv->seekable is set to false. By the time that code is run, the pipeline has already been running to the point all elements potentially interested in seeks have already queried the seekability of the source and received a positive response. That is potentially problematic, but let's keep going.

Following that code, there is this other one:

    // notify size/duration
    if (length > 0) {
        if (!priv->haveSize || (static_cast<long long>(priv->size) != length)) {
            priv->haveSize = TRUE;
            priv->size = length;
            gst_app_src_set_size(priv->appsrc, length);
        }
    } else {
        gst_app_src_set_size(priv->appsrc, -1);
        if (!priv->seekable)
            gst_app_src_set_stream_type(priv->appsrc, GST_APP_STREAM_TYPE_STREAM);
    }

gst_app_src_set_size() makes sense there. Something stranger is that `gst_app_src_set_stream_type(priv->appsrc, GST_APP_STREAM_TYPE_STREAM)` is only called in the case where the file size is unknown. The only effect this call has at this point is that appsrc will automatically reject any seeks and will stop advertising support for seeks (not that it matters at this point, as mentioned before).

appsrc rejecting seeks will not make any difference in practice though, because webKitWebSrcSeek() will return FALSE immediately if !priv->seekable.

Seeks will still happen though. The next problem is that downloadbuffer does not handle failed seeks at all, effectively stalling forever. https://bugzilla.gnome.org/show_bug.cgi?id=797098
Comment 1 Philippe Normand 2019-03-18 10:28:55 PDT
This might no longer be an issue now that bug #195631 is fixed.
Comment 2 Philippe Normand 2019-03-22 07:27:07 PDT
I'm closing this because I believe this is now fixed but if the issue happens again please reopen the bug :)