[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756
philn at webkit.org
philn at webkit.org
Fri Feb 26 22:22:21 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit 102567a174519dd2eb9696746a3b71d1956cfaf2
Author: philn at webkit.org <philn at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Feb 17 08:37:38 2010 +0000
2010-02-15 Philippe Normand <pnormand at igalia.com>
Reviewed by Gustavo Noronha Silva.
[GStreamer] Should handle BUFFERING messages
https://bugs.webkit.org/show_bug.cgi?id=30004
* configure.ac: Bump gstreamer -core/-plugins-base requirements to
0.10.25 which is the minimum required version for on-disk buffering.
2010-01-07 Philippe Normand <pnormand at igalia.com>
Reviewed by Gustavo Noronha Silva.
[GStreamer] Should handle BUFFERING messages
https://bugs.webkit.org/show_bug.cgi?id=30004
Draw the buffering status in the media controls. The timebar is
now 2 pixels shorter so dragging it at same absolute position than
before produces a seek at a new position in the media, this
explains the rebaselining of the controls-drag-timebar test.
* platform/gtk/media/controls-after-reload-expected.txt:
* platform/gtk/media/controls-drag-timebar-expected.txt:
* platform/gtk/media/controls-strict-expected.txt:
* platform/gtk/media/controls-styling-expected.txt:
* platform/gtk/media/video-controls-rendering-expected.txt:
Re-baselined due to 1px left/right border added in controls timeline.
2010-01-07 Philippe Normand <pnormand at igalia.com>
Reviewed by Gustavo Noronha Silva.
[GStreamer] Should handle BUFFERING messages
https://bugs.webkit.org/show_bug.cgi?id=30004
Initial support for on-disk buffering of videos. This works only
for Quicktime and flv though.
* css/mediaControlsGtk.css:
* platform/gtk/RenderThemeGtk.cpp:
(WebCore::RenderThemeGtk::paintMediaSliderTrack): Draw the
buffering status in the media controls.
* platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
(WebCore::mediaPlayerPrivateMessageCallback): Defer buffering
messages handling to processBufferingStats().
(WebCore::bufferingTimeoutCallback): Closure called periodically
during the on-disk buffering process.
(WebCore::MediaPlayerPrivate::MediaPlayerPrivate): New instance
variables and create playbin2 here instead of doing it in load().
(WebCore::MediaPlayerPrivate::~MediaPlayerPrivate): New instance
variables.
(WebCore::MediaPlayerPrivate::load): Simply set uri on playbin2
instead of creating the pipeline and setting uri all together.
(WebCore::MediaPlayerPrivate::processBufferingStats): Start a new
timeout source if the player is starting on-disk buffering.
(WebCore::MediaPlayerPrivate::queryBufferingStats): Method called
200ms during on-disk buffering to update the maxTimeLoaded and few
other private variables.
(WebCore::MediaPlayerPrivate::maxTimeSeekable):
(WebCore::MediaPlayerPrivate::maxTimeLoaded):
(WebCore::MediaPlayerPrivate::bytesLoaded): Fixed implementations
regarding buffering.
(WebCore::MediaPlayerPrivate::totalBytes): Improved logging.
(WebCore::MediaPlayerPrivate::updateStates): Start playback if it
was internally paused at beginning of on-disk buffering and set
ready/network states depending on the state of the on-disk
buffering process.
(WebCore::MediaPlayerPrivate::didEnd): Emit durationChanged.
(WebCore::MediaPlayerPrivate::setAutobuffer): Edit playbin2 flags
property depending on autoBuffer value.
(WebCore::MediaPlayerPrivate::createGSTPlayBin): Don't set uri
there, it is now done in load().
* platform/graphics/gtk/MediaPlayerPrivateGStreamer.h: New methods
and instance variables.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54878 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/ChangeLog b/ChangeLog
index 9a70337..669f9c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-02-15 Philippe Normand <pnormand at igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GStreamer] Should handle BUFFERING messages
+ https://bugs.webkit.org/show_bug.cgi?id=30004
+
+ * configure.ac: Bump gstreamer -core/-plugins-base requirements to
+ 0.10.25 which is the minimum required version for on-disk buffering.
+
2010-02-16 Xan Lopez <xlopez at igalia.com>
Reviewed by Gustavo Noronha.
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2350b6b..0f36537 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2010-01-07 Philippe Normand <pnormand at igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GStreamer] Should handle BUFFERING messages
+ https://bugs.webkit.org/show_bug.cgi?id=30004
+
+ Draw the buffering status in the media controls. The timebar is
+ now 2 pixels shorter so dragging it at same absolute position than
+ before produces a seek at a new position in the media, this
+ explains the rebaselining of the controls-drag-timebar test.
+
+ * platform/gtk/media/controls-after-reload-expected.txt:
+ * platform/gtk/media/controls-drag-timebar-expected.txt:
+ * platform/gtk/media/controls-strict-expected.txt:
+ * platform/gtk/media/controls-styling-expected.txt:
+ * platform/gtk/media/video-controls-rendering-expected.txt:
+ Re-baselined due to 1px left/right border added in controls timeline.
+
2010-02-17 Xan Lopez <xlopez at igalia.com>
Skip tests requiring new results.
diff --git a/LayoutTests/platform/gtk/media/controls-after-reload-expected.txt b/LayoutTests/platform/gtk/media/controls-after-reload-expected.txt
index 08d9c92..98b8804 100644
--- a/LayoutTests/platform/gtk/media/controls-after-reload-expected.txt
+++ b/LayoutTests/platform/gtk/media/controls-after-reload-expected.txt
@@ -17,8 +17,8 @@ layer at (8,44) size 320x240
layer at (8,264) size 320x20
RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
RenderButton {INPUT} at (0,0) size 20x20
- RenderFlexibleBox {DIV} at (20,0) size 240x20
- RenderSlider {INPUT} at (0,0) size 240x20
+ RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+ RenderSlider {INPUT} at (1,0) size 238x20
RenderBlock {DIV} at (2,4) size 12x12
RenderButton {INPUT} at (260,0) size 20x20
RenderButton {INPUT} at (280,0) size 20x20
diff --git a/LayoutTests/platform/gtk/media/controls-drag-timebar-expected.txt b/LayoutTests/platform/gtk/media/controls-drag-timebar-expected.txt
index 688b449..6936be4 100644
--- a/LayoutTests/platform/gtk/media/controls-drag-timebar-expected.txt
+++ b/LayoutTests/platform/gtk/media/controls-drag-timebar-expected.txt
@@ -4,7 +4,7 @@ RUN(video.autoplay = true)
RUN(video.src = 'content/test.mp4')
EVENT(playing)
EVENT(seeked)
-Time: 2.2
+Time: 2.1
EVENT(seeked)
Time: 2.7
EVENT(seeked)
diff --git a/LayoutTests/platform/gtk/media/controls-strict-expected.txt b/LayoutTests/platform/gtk/media/controls-strict-expected.txt
index 2508c1c..f04023e 100644
--- a/LayoutTests/platform/gtk/media/controls-strict-expected.txt
+++ b/LayoutTests/platform/gtk/media/controls-strict-expected.txt
@@ -17,8 +17,8 @@ layer at (8,52) size 320x240
layer at (8,272) size 320x20
RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
RenderButton {INPUT} at (0,0) size 20x20
- RenderFlexibleBox {DIV} at (20,0) size 240x20
- RenderSlider {INPUT} at (0,0) size 240x20
+ RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+ RenderSlider {INPUT} at (1,0) size 238x20
RenderBlock {DIV} at (2,4) size 12x12
RenderButton {INPUT} at (260,0) size 20x20
RenderButton {INPUT} at (280,0) size 20x20
diff --git a/LayoutTests/platform/gtk/media/controls-styling-expected.txt b/LayoutTests/platform/gtk/media/controls-styling-expected.txt
index 7b97183..f9d170c 100644
--- a/LayoutTests/platform/gtk/media/controls-styling-expected.txt
+++ b/LayoutTests/platform/gtk/media/controls-styling-expected.txt
@@ -21,8 +21,8 @@ layer at (18,44) size 320x240
layer at (18,264) size 320x20
RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
RenderButton {INPUT} at (0,0) size 20x20
- RenderFlexibleBox {DIV} at (20,0) size 240x20
- RenderSlider {INPUT} at (0,0) size 240x20
+ RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+ RenderSlider {INPUT} at (1,0) size 238x20
RenderBlock {DIV} at (2,4) size 12x12
RenderButton {INPUT} at (260,0) size 20x20
RenderButton {INPUT} at (280,0) size 20x20
@@ -32,8 +32,8 @@ layer at (8,284) size 320x240
layer at (8,504) size 320x20
RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
RenderButton {INPUT} at (0,0) size 20x20
- RenderFlexibleBox {DIV} at (20,0) size 240x20
- RenderSlider {INPUT} at (0,0) size 240x20
+ RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+ RenderSlider {INPUT} at (1,0) size 238x20
RenderBlock {DIV} at (2,4) size 12x12
RenderButton {INPUT} at (260,0) size 20x20
RenderButton {INPUT} at (280,0) size 20x20
diff --git a/LayoutTests/platform/gtk/media/video-controls-rendering-expected.txt b/LayoutTests/platform/gtk/media/video-controls-rendering-expected.txt
index add29fe..ec8c14f 100644
--- a/LayoutTests/platform/gtk/media/video-controls-rendering-expected.txt
+++ b/LayoutTests/platform/gtk/media/video-controls-rendering-expected.txt
@@ -20,8 +20,8 @@ layer at (8,44) size 320x240
layer at (8,264) size 320x20
RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
RenderButton {INPUT} at (0,0) size 20x20
- RenderFlexibleBox {DIV} at (20,0) size 240x20
- RenderSlider {INPUT} at (0,0) size 240x20
+ RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+ RenderSlider {INPUT} at (1,0) size 238x20
RenderBlock {DIV} at (2,4) size 12x12
RenderButton {INPUT} at (260,0) size 20x20
RenderButton {INPUT} at (280,0) size 20x20
@@ -31,8 +31,8 @@ layer at (8,284) size 320x240
layer at (8,504) size 320x20
RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
RenderButton {INPUT} at (0,0) size 20x20
- RenderFlexibleBox {DIV} at (20,0) size 240x20
- RenderSlider {INPUT} at (0,0) size 240x20
+ RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+ RenderSlider {INPUT} at (1,0) size 238x20
RenderBlock {DIV} at (2,4) size 12x12
RenderButton {INPUT} at (260,0) size 20x20
RenderButton {INPUT} at (280,0) size 20x20
@@ -44,8 +44,8 @@ layer at (8,524) size 320x240
layer at (8,744) size 320x20
RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
RenderButton {INPUT} at (0,0) size 20x20
- RenderFlexibleBox {DIV} at (20,0) size 240x20
- RenderSlider {INPUT} at (0,0) size 240x20
+ RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+ RenderSlider {INPUT} at (1,0) size 238x20
RenderBlock {DIV} at (2,4) size 12x12
RenderButton {INPUT} at (260,0) size 20x20
RenderButton {INPUT} at (280,0) size 20x20
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4c6be7a..db89770 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,50 @@
+2010-01-07 Philippe Normand <pnormand at igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GStreamer] Should handle BUFFERING messages
+ https://bugs.webkit.org/show_bug.cgi?id=30004
+
+ Initial support for on-disk buffering of videos. This works only
+ for Quicktime and flv though.
+
+ * css/mediaControlsGtk.css:
+ * platform/gtk/RenderThemeGtk.cpp:
+ (WebCore::RenderThemeGtk::paintMediaSliderTrack): Draw the
+ buffering status in the media controls.
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::mediaPlayerPrivateMessageCallback): Defer buffering
+ messages handling to processBufferingStats().
+ (WebCore::bufferingTimeoutCallback): Closure called periodically
+ during the on-disk buffering process.
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): New instance
+ variables and create playbin2 here instead of doing it in load().
+ (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate): New instance
+ variables.
+ (WebCore::MediaPlayerPrivate::load): Simply set uri on playbin2
+ instead of creating the pipeline and setting uri all together.
+ (WebCore::MediaPlayerPrivate::processBufferingStats): Start a new
+ timeout source if the player is starting on-disk buffering.
+ (WebCore::MediaPlayerPrivate::queryBufferingStats): Method called
+ 200ms during on-disk buffering to update the maxTimeLoaded and few
+ other private variables.
+ (WebCore::MediaPlayerPrivate::maxTimeSeekable):
+ (WebCore::MediaPlayerPrivate::maxTimeLoaded):
+ (WebCore::MediaPlayerPrivate::bytesLoaded): Fixed implementations
+ regarding buffering.
+ (WebCore::MediaPlayerPrivate::totalBytes): Improved logging.
+ (WebCore::MediaPlayerPrivate::updateStates): Start playback if it
+ was internally paused at beginning of on-disk buffering and set
+ ready/network states depending on the state of the on-disk
+ buffering process.
+ (WebCore::MediaPlayerPrivate::didEnd): Emit durationChanged.
+ (WebCore::MediaPlayerPrivate::setAutobuffer): Edit playbin2 flags
+ property depending on autoBuffer value.
+ (WebCore::MediaPlayerPrivate::createGSTPlayBin): Don't set uri
+ there, it is now done in load().
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.h: New methods
+ and instance variables.
+
2010-02-16 Chris Evans <cevans at chromium.org>
Reviewed by Adam Barth.
diff --git a/WebCore/css/mediaControlsGtk.css b/WebCore/css/mediaControlsGtk.css
index 8e98ab1..cc6da14 100644
--- a/WebCore/css/mediaControlsGtk.css
+++ b/WebCore/css/mediaControlsGtk.css
@@ -41,6 +41,8 @@ audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-bu
audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls-timeline-container {
height: 20px;
+ border-left: 1px solid rgba(255, 255, 255, 0.2);
+ border-right: 1px solid rgba(255, 255, 255, 0.2);
}
audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline {
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index 55fa180..cbc64a1 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2007 Collabora Ltd. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp at atoker.com>
* Copyright (C) 2009 Gustavo Noronha Silva <gns at gnome.org>
+ * Copyright (C) 2009, 2010 Igalia S.L
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -55,6 +56,21 @@
#include <webkit/webkitwebview.h>
#include <wtf/gtk/GOwnPtr.h>
+// GstPlayFlags flags from playbin2. It is the policy of GStreamer to
+// not publicly expose element-specific enums. That's why this
+// GstPlayFlags enum has been copied here.
+typedef enum {
+ GST_PLAY_FLAG_VIDEO = 0x00000001,
+ GST_PLAY_FLAG_AUDIO = 0x00000002,
+ GST_PLAY_FLAG_TEXT = 0x00000004,
+ GST_PLAY_FLAG_VIS = 0x00000008,
+ GST_PLAY_FLAG_SOFT_VOLUME = 0x00000010,
+ GST_PLAY_FLAG_NATIVE_AUDIO = 0x00000020,
+ GST_PLAY_FLAG_NATIVE_VIDEO = 0x00000040,
+ GST_PLAY_FLAG_DOWNLOAD = 0x00000080,
+ GST_PLAY_FLAG_BUFFERING = 0x000000100
+} GstPlayFlags;
+
using namespace std;
namespace WebCore {
@@ -76,7 +92,6 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
GOwnPtr<gchar> debug;
MediaPlayer::NetworkState error;
MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
- gint percent = 0;
bool issueError = true;
bool attemptNextLocation = false;
@@ -126,8 +141,7 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
mp->updateStates();
break;
case GST_MESSAGE_BUFFERING:
- gst_message_parse_buffering(message, &percent);
- LOG_VERBOSE(Media, "Buffering %d", percent);
+ mp->processBufferingStats(message);
break;
case GST_MESSAGE_DURATION:
LOG_VERBOSE(Media, "Duration changed");
@@ -185,6 +199,12 @@ gboolean notifyMuteIdleCallback(gpointer data)
return FALSE;
}
+gboolean bufferingTimeoutCallback(gpointer data)
+{
+ MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
+ return mp->queryBufferingStats();
+}
+
static float playbackPosition(GstElement* playbin)
{
@@ -289,14 +309,24 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_playbackRate(1)
, m_errorOccured(false)
, m_volumeIdleId(0)
- , m_mediaDuration(0.0)
+ , m_mediaDuration(0)
, m_muteIdleId(0)
+ , m_startedBuffering(false)
+ , m_fillTimeoutId(0)
+ , m_maxTimeLoaded(0)
+ , m_fillStatus(0)
{
- doGstInit();
+ if (doGstInit())
+ createGSTPlayBin();
}
MediaPlayerPrivate::~MediaPlayerPrivate()
{
+ if (m_fillTimeoutId) {
+ g_source_remove(m_fillTimeoutId);
+ m_fillTimeoutId = 0;
+ }
+
if (m_volumeIdleId) {
g_source_remove(m_volumeIdleId);
m_volumeIdleId = 0;
@@ -349,7 +379,7 @@ void MediaPlayerPrivate::load(const String& url)
m_player->readyStateChanged();
}
- createGSTPlayBin(url);
+ g_object_set(m_playBin, "uri", url.utf8().data(), NULL);
pause();
}
@@ -651,16 +681,79 @@ PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
return timeRanges.release();
}
+void MediaPlayerPrivate::processBufferingStats(GstMessage* message)
+{
+ GstBufferingMode mode;
+
+ gst_message_parse_buffering_stats(message, &mode, 0, 0, 0);
+ if (mode != GST_BUFFERING_DOWNLOAD)
+ return;
+
+ if (!m_startedBuffering) {
+ m_startedBuffering = true;
+
+ if (m_fillTimeoutId > 0)
+ g_source_remove(m_fillTimeoutId);
+
+ m_fillTimeoutId = g_timeout_add(200, (GSourceFunc) bufferingTimeoutCallback, this);
+ }
+}
+
+bool MediaPlayerPrivate::queryBufferingStats()
+{
+ GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT);
+
+ if (!gst_element_query(m_playBin, query)) {
+ gst_query_unref(query);
+ return TRUE;
+ }
+
+ gint64 start, stop;
+
+ gst_query_parse_buffering_range(query, 0, &start, &stop, 0);
+ gst_query_unref(query);
+
+ if (stop != -1)
+ m_fillStatus = 100.0 * stop / GST_FORMAT_PERCENT_MAX;
+ else
+ m_fillStatus = 100.0;
+
+ LOG_VERBOSE(Media, "Download buffer filled up to %f%%", m_fillStatus);
+
+ if (!m_mediaDuration)
+ durationChanged();
+
+ // Update maxTimeLoaded only if the media duration is
+ // available. Otherwise we can't compute it.
+ if (m_mediaDuration) {
+ m_maxTimeLoaded = static_cast<float>((m_fillStatus * m_mediaDuration) / 100.0);
+ LOG_VERBOSE(Media, "Updated maxTimeLoaded: %f", m_maxTimeLoaded);
+ }
+
+ if (m_fillStatus != 100.0) {
+ updateStates();
+ return TRUE;
+ }
+
+ // Media is now fully loaded. It will play even if network
+ // connection is cut. Buffering is done, remove the fill source
+ // from the main loop.
+ m_fillTimeoutId = 0;
+ m_startedBuffering = false;
+ updateStates();
+ return FALSE;
+}
+
float MediaPlayerPrivate::maxTimeSeekable() const
{
if (m_errorOccured)
return 0.0;
- // TODO
LOG_VERBOSE(Media, "maxTimeSeekable");
- if (m_isStreaming)
- return numeric_limits<float>::infinity();
// infinite duration means live stream
+ if (isinf(duration()))
+ return 0.0;
+
return maxTimeLoaded();
}
@@ -669,29 +762,28 @@ float MediaPlayerPrivate::maxTimeLoaded() const
if (m_errorOccured)
return 0.0;
- // TODO
- LOG_VERBOSE(Media, "maxTimeLoaded");
- notImplemented();
- return duration();
+ float loaded = m_maxTimeLoaded;
+ if (!loaded && !m_fillTimeoutId)
+ loaded = duration();
+ LOG_VERBOSE(Media, "maxTimeLoaded: %f", loaded);
+ return loaded;
}
unsigned MediaPlayerPrivate::bytesLoaded() const
{
- notImplemented();
- LOG_VERBOSE(Media, "bytesLoaded");
- /*if (!m_playBin)
+ if (!m_playBin)
+ return 0;
+
+ if (!m_mediaDuration)
return 0;
- float dur = duration();
- float maxTime = maxTimeLoaded();
- if (!dur)
- return 0;*/
- return 1; // totalBytes() * maxTime / dur;
+ unsigned loaded = totalBytes() * maxTimeLoaded() / m_mediaDuration;
+ LOG_VERBOSE(Media, "bytesLoaded: %d", loaded);
+ return loaded;
}
unsigned MediaPlayerPrivate::totalBytes() const
{
- LOG_VERBOSE(Media, "totalBytes");
if (!m_source)
return 0;
@@ -701,6 +793,7 @@ unsigned MediaPlayerPrivate::totalBytes() const
GstFormat fmt = GST_FORMAT_BYTES;
gint64 length = 0;
gst_element_query_duration(m_source, &fmt, &length);
+ LOG_VERBOSE(Media, "totalBytes %" G_GINT64_FORMAT, length);
return length;
}
@@ -751,6 +844,7 @@ void MediaPlayerPrivate::updateStates()
if (state == GST_STATE_PLAYING) {
m_readyState = MediaPlayer::HaveEnoughData;
m_paused = false;
+ m_startedPlaying = true;
if (!m_mediaDuration) {
float newDuration = duration();
if (!isinf(newDuration))
@@ -759,6 +853,28 @@ void MediaPlayerPrivate::updateStates()
} else
m_paused = true;
+ // Is on-disk buffering in progress?
+ if (m_fillTimeoutId) {
+ m_networkState = MediaPlayer::Loading;
+ // Buffering has just started, we should now have enough
+ // data to restart playback if it was internally paused by
+ // GStreamer.
+ if (m_paused && !m_startedPlaying)
+ gst_element_set_state(m_playBin, GST_STATE_PLAYING);
+ }
+
+ if (maxTimeLoaded() == duration()) {
+ m_networkState = MediaPlayer::Loaded;
+ if (state == GST_STATE_READY)
+ m_readyState = MediaPlayer::HaveNothing;
+ else if (state == GST_STATE_PAUSED)
+ m_readyState = MediaPlayer::HaveEnoughData;
+ } else
+ if (state == GST_STATE_READY)
+ m_readyState = MediaPlayer::HaveNothing;
+ else if (m_paused)
+ m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
+
if (m_changingRate) {
m_player->rateChanged();
m_changingRate = false;
@@ -769,7 +885,6 @@ void MediaPlayerPrivate::updateStates()
m_seeking = false;
}
- m_networkState = MediaPlayer::Loaded;
break;
case GST_STATE_CHANGE_ASYNC:
LOG_VERBOSE(Media, "Async: State: %s, pending: %s",
@@ -939,8 +1054,11 @@ void MediaPlayerPrivate::didEnd()
// not always 0. So to not confuse the HTMLMediaElement we
// synchronize position and duration values.
float now = currentTime();
- if (now > 0)
+ if (now > 0) {
m_mediaDuration = now;
+ m_player->durationChanged();
+ }
+
gst_element_set_state(m_playBin, GST_STATE_PAUSED);
timeChanged();
@@ -1191,7 +1309,19 @@ bool MediaPlayerPrivate::supportsFullscreen() const
return true;
}
-void MediaPlayerPrivate::createGSTPlayBin(String url)
+void MediaPlayerPrivate::setAutobuffer(bool autoBuffer)
+{
+ ASSERT(m_playBin);
+
+ GstPlayFlags flags;
+ g_object_get(m_playBin, "flags", &flags, NULL);
+ if (autoBuffer)
+ g_object_set(m_playBin, "flags", flags | GST_PLAY_FLAG_DOWNLOAD, NULL);
+ else
+ g_object_set(m_playBin, "flags", flags & ~GST_PLAY_FLAG_DOWNLOAD, NULL);
+}
+
+void MediaPlayerPrivate::createGSTPlayBin()
{
ASSERT(!m_playBin);
m_playBin = gst_element_factory_make("playbin2", "play");
@@ -1201,8 +1331,6 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this);
gst_object_unref(bus);
- g_object_set(m_playBin, "uri", url.utf8().data(), NULL);
-
g_signal_connect(m_playBin, "notify::volume", G_CALLBACK(mediaPlayerPrivateVolumeChangedCallback), this);
g_signal_connect(m_playBin, "notify::source", G_CALLBACK(mediaPlayerPrivateSourceChangedCallback), this);
g_signal_connect(m_playBin, "notify::mute", G_CALLBACK(mediaPlayerPrivateMuteChangedCallback), this);
@@ -1221,7 +1349,7 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
} else {
m_fpsSink = 0;
g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
- LOG(Media, "Can't display FPS statistics, you need gst-plugins-bad >= 0.10.18");
+ LOG_VERBOSE(Media, "Can't display FPS statistics, you need gst-plugins-bad >= 0.10.18");
}
} else
g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
index 34257ca..e19b686 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
@@ -2,6 +2,7 @@
* Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Collabora Ltd. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp at atoker.com>
+ * Copyright (C) 2009, 2010 Igalia S.L
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -86,6 +87,9 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
void muteChanged();
void muteChangedCallback();
+ void setAutobuffer(bool);
+ bool queryBufferingStats();
+
MediaPlayer::NetworkState networkState() const;
MediaPlayer::ReadyState readyState() const;
@@ -128,9 +132,11 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
float maxTimeLoaded() const;
void startEndPointTimerIfNeeded();
- void createGSTPlayBin(String url);
+ void createGSTPlayBin();
bool changePipelineState(GstState state);
+ void processBufferingStats(GstMessage* message);
+
private:
MediaPlayer* m_player;
GstElement* m_playBin;
@@ -157,6 +163,10 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
guint m_volumeIdleId;
gfloat m_mediaDuration;
guint m_muteIdleId;
+ bool m_startedBuffering;
+ guint m_fillTimeoutId;
+ float m_maxTimeLoaded;
+ gdouble m_fillStatus;
};
}
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp
index 727788a..e19e2fa 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.cpp
+++ b/WebCore/platform/gtk/RenderThemeGtk.cpp
@@ -27,9 +27,11 @@
#include "AffineTransform.h"
#include "CString.h"
#include "GOwnPtr.h"
+#include "Gradient.h"
#include "GraphicsContext.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
+#include "MediaControlElements.h"
#include "NotImplemented.h"
#include "RenderBox.h"
#include "RenderObject.h"
@@ -686,9 +688,46 @@ bool RenderThemeGtk::paintMediaSeekForwardButton(RenderObject* o, const RenderOb
bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- paintInfo.context->fillRect(FloatRect(r), m_panelColor, DeviceColorSpace);
- paintInfo.context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2,
- r.width(), m_mediaSliderHeight)), m_sliderColor, DeviceColorSpace);
+ GraphicsContext* context = paintInfo.context;
+
+ context->fillRect(FloatRect(r), m_panelColor, DeviceColorSpace);
+ context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2,
+ r.width(), m_mediaSliderHeight)), m_sliderColor, DeviceColorSpace);
+
+ RenderStyle* style = o->style();
+ HTMLMediaElement* mediaElement = toParentMediaElement(o);
+
+ if (!mediaElement)
+ return false;
+
+ // Draw the buffered ranges. This code is highly inspired from
+ // Chrome.
+ // FIXME: Draw multiple ranges if there are multiple buffered
+ // ranges. The current implementation of the player is always
+ // buffering a single range anyway.
+ IntRect bufferedRect = r;
+ bufferedRect.inflate(-style->borderLeftWidth());
+ bufferedRect.setWidth((bufferedRect.width() * mediaElement->percentLoaded()));
+
+ // Don't bother drawing an empty area.
+ if (bufferedRect.isEmpty())
+ return false;
+
+ IntPoint sliderTopLeft = bufferedRect.location();
+ IntPoint sliderTopRight = sliderTopLeft;
+ sliderTopRight.move(0, bufferedRect.height());
+
+ RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
+ Color startColor = m_panelColor;
+ gradient->addColorStop(0.0, startColor);
+ gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));
+
+ context->save();
+ context->setStrokeStyle(NoStroke);
+ context->setFillGradient(gradient);
+ context->fillRect(bufferedRect);
+ context->restore();
+
return false;
}
diff --git a/configure.ac b/configure.ac
index 3b1ddd3..6e01ce4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -211,7 +211,7 @@ GTK_REQUIRED_VERSION=2.10
LIBXSLT_REQUIRED_VERSION=1.1.7
SQLITE_REQUIRED_VERSION=3.0
GSTREAMER_REQUIRED_VERSION=0.10
-GSTREAMER_PLUGINS_BASE_REQUIRED_VERSION=0.10.23
+GSTREAMER_PLUGINS_BASE_REQUIRED_VERSION=0.10.25
ENCHANT_REQUIRED_VERSION=0.22
GAIL_REQUIRED_VERSION=1.8
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list