Changeset 159746 in webkit


Ignore:
Timestamp:
Nov 25, 2013 6:03:25 AM (10 years ago)
Author:
commit-queue@webkit.org
Message:

[GStreamer] Seeking fails on media content provided by servers not supporting Range requests
https://bugs.webkit.org/show_bug.cgi?id=85994

Patch by Andres Gomez <Andres Gomez> on 2013-11-25
Reviewed by Philippe Normand.

Source/WebCore:

Based on the patch written by Andre Moreira Magalhaes.

When the GStreamer web source was doing a "Range" request we were
expecting to receive a 206 status reply with the "Content-Range"
header and just the requested data. Supporting "Range" requests is
not mandatory so, for the servers not supporting it they will be
replying with a 200 status and the whole content of the media
element. Now, we are properly handling these replies too.

Test: http/tests/media/media-seeking-no-ranges-server.html

  • platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:

(StreamingClient::handleResponseReceived): Do not fail when
receiving 200 as response for HTTP range requests.
(StreamingClient::handleDataReceived): Manually seek on stream
when receiving the full data after a seek.

LayoutTests:

Added test to check that seeking media files on http servers not
supporting "Range" requests doesn't trigger an error.

  • http/tests/media/media-seeking-no-ranges-server-expected.txt: Added.
  • http/tests/media/media-seeking-no-ranges-server.html: Added.
  • http/tests/media/resources/load-video.php: Added support for new

"ranges" paramenter.

  • http/tests/media/resources/serve-video.php: Added support for

new "ranges" paramenter. When "ranges" is "no" we always answer
the HTTP status "200 OK" and send the whole file.

  • platform/mac/TestExpectations: New test skipped in Mac port as

media playback download control is passed to AVFoundation that
doesn't like fancy PHP URLs like the one used in the test and, in
addition, they won't care about HTTP servers not supporting
"Range" requests.

Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r159744 r159746  
     12013-11-25  Andres Gomez  <agomez@igalia.com>
     2
     3        [GStreamer] Seeking fails on media content provided by servers not supporting Range requests
     4        https://bugs.webkit.org/show_bug.cgi?id=85994
     5
     6        Reviewed by Philippe Normand.
     7
     8        Added test to check that seeking media files on http servers not
     9        supporting "Range" requests doesn't trigger an error.
     10
     11        * http/tests/media/media-seeking-no-ranges-server-expected.txt: Added.
     12        * http/tests/media/media-seeking-no-ranges-server.html: Added.
     13        * http/tests/media/resources/load-video.php: Added support for new
     14        "ranges" paramenter.
     15        * http/tests/media/resources/serve-video.php: Added support for
     16        new "ranges" paramenter. When "ranges" is "no" we always answer
     17        the HTTP status "200 OK" and send the whole file.
     18        * platform/mac/TestExpectations: New test skipped in Mac port as
     19        media playback download control is passed to AVFoundation that
     20        doesn't like fancy PHP URLs like the one used in the test and, in
     21        addition, they won't care about HTTP servers not supporting
     22        "Range" requests.
     23
    1242013-11-25  Mario Sanchez Prada  <mario.prada@samsung.com>
    225
  • trunk/LayoutTests/http/tests/media/resources/load-video.php

    r116960 r159746  
    33    $fileName = $_GET["name"];
    44    $type = $_GET["type"];
     5    if (array_key_exists("ranges", $_GET))
     6        $ranges = $_GET["ranges"];
    57
    68    $_GET = array();
    79    $_GET['name'] = $fileName;
    810    $_GET['type'] = $type;
    9     @include("./serve-video.php");
     11    if (isset($ranges))
     12        $_GET["ranges"] = $ranges;
     13    @include("./serve-video.php");
    1014
    1115?>
  • trunk/LayoutTests/http/tests/media/resources/serve-video.php

    r157577 r159746  
    33    $fileName = $_GET["name"];
    44    $type = $_GET["type"];
     5    if (array_key_exists("ranges", $_GET))
     6        $ranges = $_GET["ranges"];
    57
    68    $fileSize = filesize($fileName);
    79    $start = 0;
    810    $end = $fileSize - 1;
    9     $contentRange = $_SERVER["HTTP_RANGE"];
     11    if ($ranges != "no")
     12        $contentRange = $_SERVER["HTTP_RANGE"];
    1013    if (isset($contentRange)) {
    11         $range = explode("-", substr($contentRange, strlen("bytes="))); 
    12         $start = intval($range[0]); 
     14        $range = explode("-", substr($contentRange, strlen("bytes=")));
     15        $start = intval($range[0]);
    1316        if (!empty($range[1]))
    1417            $end = intval($range[1]);
     
    2326    header("Etag: " . '"' . $fileSize . "-" . filemtime($fileName) . '"');
    2427    header("Content-Type: " . $type);
    25     header("Accept-Ranges: bytes");
     28    if ($ranges != "no")
     29        header("Accept-Ranges: bytes");
    2630    header("Content-Length: " . ($end - $start + 1));
    27     if ($contentRange)
    28                 header("Content-Range: bytes " . $start . "-" . $end . "/" . $fileSize);
     31    if (isset($contentRange))
     32        header("Content-Range: bytes " . $start . "-" . $end . "/" . $fileSize);
    2933    header("Connection: close");
    3034
  • trunk/LayoutTests/platform/mac/TestExpectations

    r159550 r159746  
    591591media/media-fullscreen-not-in-document.html
    592592
     593# Media playback control is passed to AVFoundation that doesn't like fancy PHP URLs like the one used in the test and, in addition, they won't care about HTTP servers not supporting "Range" requests
     594http/tests/media/media-seeking-no-ranges-server.html
     595
    593596# <rdar://problem/11358748> http/tests/multipart/multipart-wait-before-boundary.html fails on ML as of r115745
    594597http/tests/multipart/multipart-wait-before-boundary.html
  • trunk/Source/WebCore/ChangeLog

    r159745 r159746  
     12013-11-25  Andres Gomez  <agomez@igalia.com>
     2
     3        [GStreamer] Seeking fails on media content provided by servers not supporting Range requests
     4        https://bugs.webkit.org/show_bug.cgi?id=85994
     5
     6        Reviewed by Philippe Normand.
     7
     8        Based on the patch written by Andre Moreira Magalhaes.
     9
     10        When the GStreamer web source was doing a "Range" request we were
     11        expecting to receive a 206 status reply with the "Content-Range"
     12        header and just the requested data. Supporting "Range" requests is
     13        not mandatory so, for the servers not supporting it they will be
     14        replying with a 200 status and the whole content of the media
     15        element. Now, we are properly handling these replies too.
     16
     17        Test: http/tests/media/media-seeking-no-ranges-server.html
     18
     19        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
     20        (StreamingClient::handleResponseReceived): Do not fail when
     21        receiving 200 as response for HTTP range requests.
     22        (StreamingClient::handleDataReceived): Manually seek on stream
     23        when receiving the full data after a seek.
     24
    1252013-11-25  Radu Stavila  <stavila@adobe.com>
    226
  • trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp

    r159730 r159746  
    840840    GMutexLocker locker(GST_OBJECT_GET_LOCK(src));
    841841
    842     // If we seeked we need 206 == PARTIAL_CONTENT
    843     if (priv->requestedOffset && response.httpStatusCode() != 206) {
    844         locker.unlock();
    845         GST_ELEMENT_ERROR(src, RESOURCE, READ, (0), (0));
    846         gst_app_src_end_of_stream(priv->appsrc);
    847         webKitWebSrcStop(src);
     842    if (priv->seekID) {
     843        GST_DEBUG_OBJECT(src, "Seek in progress, ignoring response");
    848844        return;
    849845    }
    850846
     847    if (priv->requestedOffset) {
     848        // Seeking ... we expect a 206 == PARTIAL_CONTENT
     849        if (response.httpStatusCode() == 200) {
     850            // Range request didn't have a ranged response; resetting offset.
     851            priv->offset = 0;
     852        } else if (response.httpStatusCode() != 206) {
     853            // Range request completely failed.
     854            locker.unlock();
     855            GST_ELEMENT_ERROR(src, RESOURCE, READ, ("Received unexpected %d HTTP status code", response.httpStatusCode()), (0));
     856            gst_app_src_end_of_stream(priv->appsrc);
     857            webKitWebSrcStop(src);
     858            return;
     859        }
     860    }
     861
    851862    long long length = response.expectedContentLength();
    852     if (length > 0)
     863    if (length > 0 && priv->requestedOffset && response.httpStatusCode() == 206)
    853864        length += priv->requestedOffset;
    854865
     
    933944        priv->buffer.clear();
    934945        return;
     946    }
     947
     948    if (priv->offset < priv->requestedOffset) {
     949        // Range request failed; seeking manually.
     950        if (priv->offset + length <= priv->requestedOffset) {
     951            // Discard all the buffers coming before the requested seek position.
     952            priv->offset += length;
     953            priv->buffer.clear();
     954            return;
     955        }
     956
     957        if (priv->offset + length > priv->requestedOffset) {
     958            guint64 offset = priv->requestedOffset - priv->offset;
     959            data += offset;
     960            length -= offset;
     961            if (priv->buffer)
     962                gst_buffer_resize(priv->buffer.get(), offset, -1);
     963            priv->offset = priv->requestedOffset;
     964        }
     965
     966        priv->requestedOffset = 0;
    935967    }
    936968
Note: See TracChangeset for help on using the changeset viewer.