Commit 6b4764ec authored by philn@webkit.org's avatar philn@webkit.org
Browse files

2010-12-07 Philippe Normand <pnormand@igalia.com>

        Reviewed by Gustavo Noronha Silva.

        [GStreamer] ::buffered() should return multiple ranges in some cases
        https://bugs.webkit.org/show_bug.cgi?id=45101

        Improved the ::buffered() method thanks to the new buffering query
        support that landed in GStreamer 0.10.31. The method now
        queries the media buffered-ranges on the pipeline and queue2
        handles it if it's buffering the media to disk.

        The webkitwebsrc element also gained BYTES duration query
        support. This is needed in the rare cases where uridecodebin
        configures its queue before the HTTP server returns the media
        Content-Length.

        Test: http/tests/media/video-buffered.html

        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
        (WebCore::MediaPlayerPrivateGStreamer::buffered):
        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
        (webkit_web_src_init):
        (webKitWebSrcQuery): Make webkitwebsrc handle the duration queries
        if it's aware of the media content-length.
        * platform/gtk/RenderThemeGtk.cpp:
        (WebCore::RenderThemeGtk::paintMediaSliderTrack): Fix position of
        the second and next buffered ranges.

LayoutTests:

        Reviewed by Gustavo Noronha Silva.

        [GStreamer] ::buffered() should return multiple ranges in some cases
        https://bugs.webkit.org/show_bug.cgi?id=45101

        New test for video.buffered attribute. The test is skipped for
        ports not returning multiple timeranges for video.buffered.

        * http/tests/media/video-buffered-expected.txt: Added.
        * http/tests/media/video-buffered.html: Added.
        * http/tests/resources/counting-captioned.mov: Added.
        * http/tests/media/video-throttled-load.cgi: added Range
        requests/responses support.
        * platform/chromium/test_expectations.txt:
        * platform/mac-leopard/Skipped:
        * platform/mac-snowleopard/Skipped:
        * platform/mac-tiger/Skipped:
        * platform/mac-wk2/Skipped:
        * platform/mac/Skipped:
        * platform/qt-mac/Skipped:
        * platform/qt-win/Skipped:
        * platform/qt-wk2/Skipped:
        * platform/qt/Skipped:
        * platform/win-wk2/Skipped:
        * platform/win/Skipped:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73454 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 08788cf8
2010-12-07 Philippe Normand <pnormand@igalia.com>
Reviewed by Gustavo Noronha Silva.
[GStreamer] ::buffered() should return multiple ranges in some cases
https://bugs.webkit.org/show_bug.cgi?id=45101
New test for video.buffered attribute. The test is skipped for
ports not returning multiple timeranges for video.buffered.
* http/tests/media/video-buffered-expected.txt: Added.
* http/tests/media/video-buffered.html: Added.
* http/tests/resources/counting-captioned.mov: Added.
* http/tests/media/video-throttled-load.cgi: added Range
requests/responses support.
* platform/chromium/test_expectations.txt:
* platform/mac-leopard/Skipped:
* platform/mac-snowleopard/Skipped:
* platform/mac-tiger/Skipped:
* platform/mac-wk2/Skipped:
* platform/mac/Skipped:
* platform/qt-mac/Skipped:
* platform/qt-win/Skipped:
* platform/qt-wk2/Skipped:
* platform/qt/Skipped:
* platform/win-wk2/Skipped:
* platform/win/Skipped:
2010-12-07 Yael Aharon <yael.aharon@nokia.com>
Reviewed by Antonio Gomes.
......
Start playing a video with preloading enabled, do a seek near the end and check multiple buffered timeranges have been created.
EXPECTED (video.buffered.length == '1') OK
RUN(video.currentTime = video.duration - 0.5)
EVENT(ended)
EXPECTED (video.buffered.length == '2') OK
END OF TEST
<html>
<head>
</head>
<body onload="start()">
<p>Start playing a video with preloading enabled, do a seek near the
end and check multiple buffered timeranges have been created.</p>
<video id="video" preload="auto" autobuffer></video>
<script src=../../../media/video-test.js></script>
<script src=../../../media/media-file.js></script>
<script>
function delayedSeek() {
testExpected("video.buffered.length", 1, "==");
run("video.currentTime = video.duration - 0.5");
waitForEvent("ended", ended);
}
function ended() {
testExpected("video.buffered.length", 2, "==");
endTest();
}
function start () {
video = document.getElementById('video');
video.src = "http://127.0.0.1:8000/media/video-throttled-load.cgi?nph=1&name=resources/counting-captioned.mov&throttle=20&type=video/quicktime";
video.play();
setTimeout(delayedSeek, 1000);
}
</script>
</body>
</html>
......@@ -19,21 +19,62 @@ my $chunkPerSec = $kbPerSec * 1024 / CHUNK_SIZE_BYTES;
# Get MIME type if provided. Default to video/mp4.
my $type = $query->param('type') || "video/mp4";
# Print HTTP Header, disabling cache.
print "Content-type: " . $type . "\n";
print "Content-Length: " . $filesize . "\n";
print "Cache-Control: no-cache\n";
my $nph = $query->param('nph') || 0;
CGI->nph($nph);
my $contentRange = $ENV{'HTTP_RANGE'};
my $rangeEnd = $filesize - 1;
my @parsedRange = (0, $rangeEnd);
if ($nph) {
# Handle HTTP Range requests.
my $httpContentRange;
my $httpStatus;
if ($contentRange) {
my @values = split('=', $contentRange);
my $rangeType = $values[0];
@parsedRange = split("-", $values[1]);
if (!$parsedRange[1]) {
$parsedRange[1] = $rangeEnd;
}
$httpStatus = "206 Partial Content";
$httpContentRange = "bytes " . $parsedRange[0] . "-" . $parsedRange[1] . "/" . $filesize;
} else {
$httpStatus = "200 OK";
}
print "Status: " . $httpStatus . "\n";
print "Connection: close\n";
print "Content-Length: " . $filesize . "\n";
print "Content-Type: " . $type . "\n";
print "Accept-Ranges: bytes\n";
if ($httpContentRange) {
print "Content-Range: " . $httpContentRange . "\n";
}
} else {
# Print HTTP Header, disabling cache.
print "Cache-Control: no-cache\n";
print "Content-Length: " . $filesize . "\n";
print "Content-Type: " . $type . "\n";
}
print "\n";
open FILE, $name or die;
binmode FILE;
my ($data, $n);
my $total = 0;
seek(FILE, $parsedRange[0], 0);
while (($n = read FILE, $data, 1024) != 0) {
print $data;
$total += $n;
if ($total >= $filesize) {
if (($total >= $filesize) || ($total > $parsedRange[1])) {
last;
}
......
......@@ -786,6 +786,9 @@ BUG13907 BUG60355 : http/tests/security/local-video-src-from-remote.html = PASS
// KNOWNISSUE : * we don't have test-par-16-9.ogv generated in WebKit * we don't handle aspect ratio correctly.
BUG59635 : media/video-display-aspect-ratio.html = PASS FAIL TIMEOUT
// video.buffered multiple TimeRanges support.
BUG49165 SKIP : http/tests/media/video-buffered.html = PASS
// These tests need to be changed to not rely on setTimeout().
BUG13907 BUG60740 SLOW WIN DEBUG : media/video-played-collapse.html = PASS FAIL
BUG13907 BUG60740 SLOW WIN DEBUG : media/video-seek-past-end-playing.html = PASS FAIL
......
......@@ -50,6 +50,9 @@ media/video-controls-zoomed.html
media/video-zoom-controls.html
media/video-volume.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
# Disable flakey webgl test to make the bots green again.
# https://bugs.webkit.org/show_bug.cgi?id=33924
fast/canvas/webgl/texImage2DImageDataTest.html
......
......@@ -73,6 +73,9 @@ media/unsupported-tracks.html
# https://bugs.webkit.org/show_bug.cgi?id=33434
media/video-error-does-not-exist.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
# Test times out due to CoreGraphics bug
# <rdar://problem/7499927>
fast/images/size-failure.html
......
......@@ -99,6 +99,9 @@ http/tests/navigation/parsed-iframe-dynamic-form-back-entry.html
# https://bugs.webkit.org/show_bug.cgi?id=33323 - http/tests/media/video-error-abort.html times out
http/tests/media/video-error-abort.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
# Fails on all mac variants
# https://bugs.webkit.org/show_bug.cgi?id=34933
media/video-display-aspect-ratio.html
......
......@@ -2290,3 +2290,6 @@ platform/mac/fast/events/objc-keyboard-event-creation.html
# WebKit2 does not (should not?) support setting WebKitUsePreHTML5ParserQuirks
# in its WebPreferences implementation.
fast/parser/pre-html5-parser-quirks.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
......@@ -252,6 +252,9 @@ fast/viewport
# see also https://bugs.webkit.org/show_bug.cgi?id=45021
media/context-menu-actions.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
# FileSystem API is not supported.
fast/filesystem
......
# This test requires ogg codecs
media/media-can-play-ogg.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
# This test requires ogg codecs
media/media-can-play-ogg.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
......@@ -2460,3 +2460,5 @@ http/tests/security/aboutBlank/security-context-grandchildren-writeln-lexical.ht
# https://bugs.webkit.org/show_bug.cgi?id=49321
http/tests/history/popstate-fires-with-pending-requests.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
......@@ -661,6 +661,9 @@ media/media-can-play-mpeg4-video.html
# https://bugs.webkit.org/show_bug.cgi?id=48617
media/video-seek-by-small-increment.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
# ============================================================================= #
# Crashing tests due to re-enabled Phonon support in Buildbot's Qt #
# Skip these until a proper solution for the Phonon related crashes found. #
......
......@@ -147,3 +147,6 @@ http/tests/xmlhttprequest/cross-origin-cookie-storage.html
# Unexplained test timeouts.
fast/js/exceptions-thrown-in-callbacks.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
......@@ -299,6 +299,9 @@ editing/selection/context-menu-on-text.html
# and https://bugs.webkit.org/show_bug.cgi?id=45021
media/context-menu-actions.html
# requires video.buffered to be able to return multiple timeranges
http/tests/media/video-buffered.html
# Assertion failure in replaySavedEvents http://webkit.org/b/21796
editing/pasteboard/drop-text-events.html
editing/selection/drag-in-iframe.html
......
2010-12-07 Philippe Normand <pnormand@igalia.com>
Reviewed by Gustavo Noronha Silva.
[GStreamer] ::buffered() should return multiple ranges in some cases
https://bugs.webkit.org/show_bug.cgi?id=45101
Improved the ::buffered() method thanks to the new buffering query
support that landed in GStreamer 0.10.31. The method now
queries the media buffered-ranges on the pipeline and queue2
handles it if it's buffering the media to disk.
The webkitwebsrc element also gained BYTES duration query
support. This is needed in the rare cases where uridecodebin
configures its queue before the HTTP server returns the media
Content-Length.
Test: http/tests/media/video-buffered.html
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::buffered):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
(webkit_web_src_init):
(webKitWebSrcQuery): Make webkitwebsrc handle the duration queries
if it's aware of the media content-length.
* platform/gtk/RenderThemeGtk.cpp:
(WebCore::RenderThemeGtk::paintMediaSliderTrack): Fix position of
the second and next buffered ranges.
2010-12-07 Yael Aharon <yael.aharon@nokia.com>
Reviewed by Antonio Gomes.
......
......@@ -747,9 +747,40 @@ MediaPlayer::ReadyState MediaPlayerPrivateGStreamer::readyState() const
PassRefPtr<TimeRanges> MediaPlayerPrivateGStreamer::buffered() const
{
RefPtr<TimeRanges> timeRanges = TimeRanges::create();
if (m_errorOccured || m_isStreaming)
return timeRanges.release();
#if GST_CHECK_VERSION(0, 10, 31)
float mediaDuration(duration());
if (!mediaDuration || isinf(mediaDuration))
return timeRanges.release();
GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT);
if (!gst_element_query(m_playBin, query)) {
gst_query_unref(query);
return timeRanges.release();
}
gint64 rangeStart = 0, rangeStop = 0;
for (guint index = 0; index < gst_query_get_n_buffering_ranges(query); index++) {
if (gst_query_parse_nth_buffering_range(query, index, &rangeStart, &rangeStop))
timeRanges->add(static_cast<float>((rangeStart * mediaDuration) / 100),
static_cast<float>((rangeStop * mediaDuration) / 100));
}
// Fallback to the more general maxTimeLoaded() if no range has
// been found.
if (!timeRanges->length())
if (float loaded = maxTimeLoaded())
timeRanges->add(0, loaded);
gst_query_unref(query);
#else
float loaded = maxTimeLoaded();
if (!m_errorOccured && !m_isStreaming && loaded > 0)
timeRanges->add(0, loaded);
#endif
return timeRanges.release();
}
......
......@@ -110,6 +110,7 @@ static void webKitWebSrcFinalize(GObject* object);
static void webKitWebSrcSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* pspec);
static void webKitWebSrcGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* pspec);
static GstStateChangeReturn webKitWebSrcChangeState(GstElement* element, GstStateChange transition);
static gboolean webKitWebSrcQuery(GstPad* pad, GstQuery* query);
static void webKitWebSrcNeedDataCb(GstAppSrc* appsrc, guint length, gpointer userData);
static void webKitWebSrcEnoughDataCb(GstAppSrc* appsrc, gpointer userData);
......@@ -221,6 +222,7 @@ static void webkit_web_src_init(WebKitWebSrc* src,
padTemplate);
gst_element_add_pad(GST_ELEMENT(src), priv->srcpad);
gst_pad_set_query_function(priv->srcpad, webKitWebSrcQuery);
priv->appsrc = GST_APP_SRC(gst_element_factory_make("appsrc", 0));
if (!priv->appsrc) {
......@@ -476,6 +478,36 @@ static GstStateChangeReturn webKitWebSrcChangeState(GstElement* element, GstStat
return ret;
}
static gboolean webKitWebSrcQuery(GstPad* pad, GstQuery* query)
{
WebKitWebSrc* src = WEBKIT_WEB_SRC(gst_pad_get_parent(pad));
gboolean result = FALSE;
switch (GST_QUERY_TYPE(query)) {
case GST_QUERY_DURATION:
{
GstFormat format;
gst_query_parse_duration(query, &format, NULL);
GST_DEBUG_OBJECT(src, "duration query in format %s", gst_format_get_name(format));
if ((format == GST_FORMAT_BYTES) && (src->priv->size > 0)) {
gst_query_set_duration(query, format, src->priv->size);
result = TRUE;
}
break;
}
default:
break;
}
if (!result)
result = gst_pad_query_default(pad, query);
gst_object_unref(src);
return result;
}
// uri handler interface
static GstURIType webKitWebSrcUriGetType(void)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment