[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373
kov at webkit.org
kov at webkit.org
Thu Apr 8 02:17:53 UTC 2010
The following commit has been merged in the webkit-1.2 branch:
commit adc662a8d44ca8a17b417014a0c2fb2e88a5dc56
Author: kov at webkit.org <kov at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Mar 9 18:43:51 2010 +0000
2010-03-09 Gustavo Noronha Silva <gustavo.noronha at collabora.co.uk>
Reviewed by Dirk Schulze.
[GStreamer] Buffering logic is not correct, and does not work very well
https://bugs.webkit.org/show_bug.cgi?id=35706
Fix buffering to match GStreamer expectancies regarding the
pipeline state, so that videos which really need buffering to play
correctly also work, while maintaining the convenience of
on-disk-buffering. This required a bit of shuffling of state
change handling.
No behaviour change expected.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
(WebCore::MediaPlayerPrivate::processBufferingStats):
(WebCore::MediaPlayerPrivate::fillTimerFired):
(WebCore::MediaPlayerPrivate::updateStates):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55733 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b5f0580..9cf22fc 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -5,6 +5,28 @@
[GStreamer] Buffering logic is not correct, and does not work very well
https://bugs.webkit.org/show_bug.cgi?id=35706
+ Fix buffering to match GStreamer expectancies regarding the
+ pipeline state, so that videos which really need buffering to play
+ correctly also work, while maintaining the convenience of
+ on-disk-buffering. This required a bit of shuffling of state
+ change handling.
+
+ No behaviour change expected.
+
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
+ (WebCore::MediaPlayerPrivate::processBufferingStats):
+ (WebCore::MediaPlayerPrivate::fillTimerFired):
+ (WebCore::MediaPlayerPrivate::updateStates):
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+
+2010-03-09 Gustavo Noronha Silva <gustavo.noronha at collabora.co.uk>
+
+ Reviewed by Dirk Schulze.
+
+ [GStreamer] Buffering logic is not correct, and does not work very well
+ https://bugs.webkit.org/show_bug.cgi?id=35706
+
Do not call pause(), but set the GStreamer state directly. This is
just a GStreamer implementation detail, and this will avoid having
side effects in case we change the pause implementation in the
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index aa20fa5..b46e29c 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -276,7 +276,6 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_endTime(numeric_limits<float>::infinity())
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
- , m_startedPlaying(false)
, m_isStreaming(false)
, m_size(IntSize())
, m_buffer(0)
@@ -285,12 +284,14 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_resetPipeline(false)
, m_paused(true)
, m_seeking(false)
+ , m_buffering(false)
, m_playbackRate(1)
, m_errorOccured(false)
, m_mediaDuration(0)
, m_startedBuffering(false)
, m_fillTimer(this, &MediaPlayerPrivate::fillTimerFired)
, m_maxTimeLoaded(0)
+ , m_bufferingPercentage(0)
{
if (doGstInit())
createGSTPlayBin();
@@ -646,13 +647,26 @@ PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
void MediaPlayerPrivate::processBufferingStats(GstMessage* message)
{
- GstBufferingMode mode;
+ // This is the immediate buffering that needs to happen so we have
+ // enough to play right now.
+ m_buffering = true;
+ const GstStructure *structure = gst_message_get_structure(message);
+ gst_structure_get_int(structure, "buffer-percent", &m_bufferingPercentage);
+
+ LOG_VERBOSE(Media, "[Buffering] Buffering: %d%%.", m_bufferingPercentage);
+ GstBufferingMode mode;
gst_message_parse_buffering_stats(message, &mode, 0, 0, 0);
- if (mode != GST_BUFFERING_DOWNLOAD)
+ if (mode != GST_BUFFERING_DOWNLOAD) {
+ updateStates();
return;
+ }
+ // This is on-disk buffering, that allows us to download much more
+ // than needed for right now.
if (!m_startedBuffering) {
+ LOG_VERBOSE(Media, "[Buffering] Starting on-disk buffering.");
+
m_startedBuffering = true;
if (m_fillTimer.isActive())
@@ -680,7 +694,7 @@ void MediaPlayerPrivate::fillTimerFired(Timer<MediaPlayerPrivate>*)
if (stop != -1)
fillStatus = 100.0 * stop / GST_FORMAT_PERCENT_MAX;
- LOG_VERBOSE(Media, "Download buffer filled up to %f%%", fillStatus);
+ LOG_VERBOSE(Media, "[Buffering] Download buffer filled up to %f%%", fillStatus);
if (!m_mediaDuration)
durationChanged();
@@ -689,7 +703,7 @@ void MediaPlayerPrivate::fillTimerFired(Timer<MediaPlayerPrivate>*)
// available. Otherwise we can't compute it.
if (m_mediaDuration) {
m_maxTimeLoaded = static_cast<float>((fillStatus * m_mediaDuration) / 100.0);
- LOG_VERBOSE(Media, "Updated maxTimeLoaded: %f", m_maxTimeLoaded);
+ LOG_VERBOSE(Media, "[Buffering] Updated maxTimeLoaded: %f", m_maxTimeLoaded);
}
if (fillStatus != 100.0) {
@@ -770,10 +784,6 @@ void MediaPlayerPrivate::cancelLoad()
void MediaPlayerPrivate::updateStates()
{
- // There is no (known) way to get such level of information about
- // the state of GStreamer, therefore, when in PAUSED state,
- // we are sure we can display the first frame and go to play
-
if (!m_playBin)
return;
@@ -797,44 +807,64 @@ void MediaPlayerPrivate::updateStates()
m_resetPipeline = state <= GST_STATE_READY;
- if (state == GST_STATE_READY)
+ // Try to figure out ready and network states.
+ if (state == GST_STATE_READY) {
m_readyState = MediaPlayer::HaveNothing;
- else if (state == GST_STATE_PAUSED)
+ m_networkState = MediaPlayer::Empty;
+ } else if (maxTimeLoaded() == duration()) {
+ m_networkState = MediaPlayer::Loaded;
m_readyState = MediaPlayer::HaveEnoughData;
+ } else {
+ m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
+ m_networkState = MediaPlayer::Loading;
+ }
+
+ if (m_buffering && state != GST_STATE_READY) {
+ m_readyState = MediaPlayer::HaveCurrentData;
+ m_networkState = MediaPlayer::Loading;
+ }
+
+ // Now let's try to get the states in more detail using
+ // information from GStreamer, while we sync states where
+ // needed.
+ if (state == GST_STATE_PAUSED) {
+ if (m_buffering && m_bufferingPercentage == 100) {
+ m_buffering = false;
+ m_bufferingPercentage = 0;
+ m_readyState = MediaPlayer::HaveEnoughData;
+
+ LOG_VERBOSE(Media, "[Buffering] Complete.");
- if (state == GST_STATE_PLAYING) {
+ if (!m_paused) {
+ LOG_VERBOSE(Media, "[Buffering] Restarting playback.");
+ gst_element_set_state(m_playBin, GST_STATE_PLAYING);
+ }
+ } else if (!m_buffering)
+ m_paused = true;
+ } else if (state == GST_STATE_PLAYING) {
m_readyState = MediaPlayer::HaveEnoughData;
m_paused = false;
- m_startedPlaying = true;
+
if (!m_mediaDuration) {
float newDuration = duration();
if (!isinf(newDuration))
m_mediaDuration = newDuration;
}
+
+ if (m_buffering) {
+ m_readyState = MediaPlayer::HaveNothing;
+ m_networkState = MediaPlayer::Loading;
+
+ LOG_VERBOSE(Media, "[Buffering] Pausing stream for buffering.");
+
+ gst_element_set_state(m_playBin, GST_STATE_PAUSED);
+ }
} else
m_paused = true;
// Is on-disk buffering in progress?
- if (m_fillTimer.isActive()) {
+ if (m_fillTimer.isActive())
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();
@@ -882,20 +912,16 @@ void MediaPlayerPrivate::updateStates()
m_paused = true;
// Live pipelines go in PAUSED without prerolling.
m_isStreaming = true;
- } else if (state == GST_STATE_PLAYING) {
- m_startedPlaying = true;
+ } else if (state == GST_STATE_PLAYING)
m_paused = false;
- }
-
- if (m_paused && !m_startedPlaying)
- gst_element_set_state(m_playBin, GST_STATE_PLAYING);
if (m_seeking) {
shouldUpdateAfterSeek = true;
m_seeking = false;
- if (m_paused)
+ if (!m_paused)
gst_element_set_state(m_playBin, GST_STATE_PLAYING);
- }
+ } else if (!m_paused)
+ gst_element_set_state(m_playBin, GST_STATE_PLAYING);
m_networkState = MediaPlayer::Loading;
break;
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
index 073a45d..6ef9ad1 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
@@ -149,7 +149,6 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
bool m_isEndReached;
MediaPlayer::NetworkState m_networkState;
MediaPlayer::ReadyState m_readyState;
- bool m_startedPlaying;
mutable bool m_isStreaming;
IntSize m_size;
GstBuffer* m_buffer;
@@ -158,12 +157,14 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
bool m_resetPipeline;
bool m_paused;
bool m_seeking;
+ bool m_buffering;
float m_playbackRate;
bool m_errorOccured;
float m_mediaDuration;
bool m_startedBuffering;
Timer<MediaPlayerPrivate> m_fillTimer;
float m_maxTimeLoaded;
+ int m_bufferingPercentage;
};
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list