Modified: releases/WebKitGTK/webkit-1.10/Source/WebCore/ChangeLog (128319 => 128320)
--- releases/WebKitGTK/webkit-1.10/Source/WebCore/ChangeLog 2012-09-12 16:02:10 UTC (rev 128319)
+++ releases/WebKitGTK/webkit-1.10/Source/WebCore/ChangeLog 2012-09-12 16:03:22 UTC (rev 128320)
@@ -1,3 +1,43 @@
+2012-08-20 Philippe Normand <pnorm...@igalia.com>
+
+ [GStreamer] Audio device not closed after playing sound
+ https://bugs.webkit.org/show_bug.cgi?id=89122
+
+ Reviewed by Martin Robinson.
+
+ Set the GStreamer pipeline to NULL instead of PAUSED on EOS. This
+ allows the audio-sink to release its connection to the audio
+ device. This is done only if the Media element is not
+ looping. To make the MediaPlayerPrivate layer aware of that
+ information the MediaPlayerClient interface was updated with a new
+ method mediaPlayerIsLooping, implemented by the HTMLMediaElement.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::mediaPlayerIsLooping): Implementation of
+ MediaPlayerClient::mediaPlayerLoop, proxies to ::loop();
+ * html/HTMLMediaElement.h:
+ (HTMLMediaElement):
+ * platform/graphics/MediaPlayer.h:
+ (WebCore::MediaPlayerClient::mediaPlayerIsLooping): New method allowing
+ the MediaPlayer and its backend to know if a playback loop is
+ requested by the client.
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer):
+ (WebCore::MediaPlayerPrivateGStreamer::playbackPosition): Report
+ seek time or media duration if EOS was reached. These early
+ returns are needed because the position query doesn't work on a
+ NULL pipeline.
+ (WebCore::MediaPlayerPrivateGStreamer::changePipelineState):
+ Refactored to use an early return.
+ (WebCore::MediaPlayerPrivateGStreamer::prepareToPlay): Reset the
+ seeking flag.
+ (WebCore::MediaPlayerPrivateGStreamer::play): reset m_isEndReached.
+ (WebCore::MediaPlayerPrivateGStreamer::pause): Don't pause on EOS.
+ (WebCore::MediaPlayerPrivateGStreamer::seek): Refactor, call
+ currentTime() after we're sure playbin is valid and no error occured.
+ (WebCore::MediaPlayerPrivateGStreamer::paused): Fake paused state
+ on EOS.
+
2012-08-23 John Griggs <jgri...@rim.com>
Replace access ot HTMLMediaElement from MediaPlayerPrivateBlackBerry with methods in MediaPlayerClient - updated with notes from initial reviews. https://bugs.webkit.org/show_bug.cgi?id=84291
Modified: releases/WebKitGTK/webkit-1.10/Source/WebCore/html/HTMLMediaElement.cpp (128319 => 128320)
--- releases/WebKitGTK/webkit-1.10/Source/WebCore/html/HTMLMediaElement.cpp 2012-09-12 16:02:10 UTC (rev 128319)
+++ releases/WebKitGTK/webkit-1.10/Source/WebCore/html/HTMLMediaElement.cpp 2012-09-12 16:03:22 UTC (rev 128320)
@@ -4415,6 +4415,11 @@
return paused();
}
+bool HTMLMediaElement::mediaPlayerIsLooping() const
+{
+ return loop();
+}
+
HostWindow* HTMLMediaElement::mediaPlayerHostWindow()
{
return mediaPlayerOwningDocument()->view()->hostWindow();
Modified: releases/WebKitGTK/webkit-1.10/Source/WebCore/html/HTMLMediaElement.h (128319 => 128320)
--- releases/WebKitGTK/webkit-1.10/Source/WebCore/html/HTMLMediaElement.h 2012-09-12 16:02:10 UTC (rev 128319)
+++ releases/WebKitGTK/webkit-1.10/Source/WebCore/html/HTMLMediaElement.h 2012-09-12 16:03:22 UTC (rev 128320)
@@ -429,6 +429,7 @@
virtual void mediaPlayerPause() OVERRIDE;
virtual void mediaPlayerPlay() OVERRIDE;
virtual bool mediaPlayerIsPaused() const OVERRIDE;
+ virtual bool mediaPlayerIsLooping() const OVERRIDE;
virtual HostWindow* mediaPlayerHostWindow() OVERRIDE;
virtual IntRect mediaPlayerWindowClipRect() OVERRIDE;
Modified: releases/WebKitGTK/webkit-1.10/Source/WebCore/platform/graphics/MediaPlayer.h (128319 => 128320)
--- releases/WebKitGTK/webkit-1.10/Source/WebCore/platform/graphics/MediaPlayer.h 2012-09-12 16:02:10 UTC (rev 128319)
+++ releases/WebKitGTK/webkit-1.10/Source/WebCore/platform/graphics/MediaPlayer.h 2012-09-12 16:03:22 UTC (rev 128320)
@@ -197,6 +197,7 @@
virtual void mediaPlayerPause() { }
virtual void mediaPlayerPlay() { }
virtual bool mediaPlayerIsPaused() const { return true; }
+ virtual bool mediaPlayerIsLooping() const { return false; }
virtual HostWindow* mediaPlayerHostWindow() { return 0; }
virtual IntRect mediaPlayerWindowClipRect() { return IntRect(); }
};
Modified: releases/WebKitGTK/webkit-1.10/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (128319 => 128320)
--- releases/WebKitGTK/webkit-1.10/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 2012-09-12 16:02:10 UTC (rev 128319)
+++ releases/WebKitGTK/webkit-1.10/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 2012-09-12 16:03:22 UTC (rev 128320)
@@ -211,6 +211,7 @@
, m_seekTime(0)
, m_changingRate(false)
, m_endTime(numeric_limits<float>::infinity())
+ , m_isEndReached(false)
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
, m_isStreaming(false)
@@ -333,6 +334,17 @@
float MediaPlayerPrivateGStreamer::playbackPosition() const
{
+ if (m_isEndReached) {
+ // Position queries on a null pipeline return 0. If we're at
+ // the end of the stream the pipeline is null but we want to
+ // report either the seek time or the duration because this is
+ // what the Media element spec expects us to do.
+ if (m_seeking)
+ return m_seekTime;
+ if (m_mediaDuration)
+ return m_mediaDuration;
+ }
+
float ret = 0.0f;
GstQuery* query = gst_query_new_position(GST_FORMAT_TIME);
@@ -365,13 +377,15 @@
GstState pending;
gst_element_get_state(m_playBin, ¤tState, &pending, 0);
- if (currentState != newState && pending != newState) {
- GstStateChangeReturn ret = gst_element_set_state(m_playBin, newState);
- GstState pausedOrPlaying = newState == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
- if (currentState != pausedOrPlaying && ret == GST_STATE_CHANGE_FAILURE) {
- loadingFailed(MediaPlayer::Empty);
- return false;
- }
+ LOG_MEDIA_MESSAGE("Current state: %s, pending: %s", gst_element_state_get_name(currentState), gst_element_state_get_name(pending));
+ if (currentState == newState || pending == newState)
+ return true;
+
+ GstStateChangeReturn setStateResult = gst_element_set_state(m_playBin, newState);
+ GstState pausedOrPlaying = newState == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
+ if (currentState != pausedOrPlaying && setStateResult == GST_STATE_CHANGE_FAILURE) {
+ loadingFailed(MediaPlayer::Empty);
+ return false;
}
return true;
}
@@ -379,6 +393,7 @@
void MediaPlayerPrivateGStreamer::prepareToPlay()
{
m_isEndReached = false;
+ m_seeking = false;
if (m_delayingLoad) {
m_delayingLoad = false;
@@ -388,12 +403,17 @@
void MediaPlayerPrivateGStreamer::play()
{
- if (changePipelineState(GST_STATE_PLAYING))
+ if (changePipelineState(GST_STATE_PLAYING)) {
+ m_isEndReached = false;
LOG_MEDIA_MESSAGE("Play");
+ }
}
void MediaPlayerPrivateGStreamer::pause()
{
+ if (m_isEndReached)
+ return;
+
if (changePipelineState(GST_STATE_PAUSED))
LOG_MEDIA_MESSAGE("Pause");
}
@@ -457,16 +477,18 @@
void MediaPlayerPrivateGStreamer::seek(float time)
{
- // Avoid useless seeking.
- if (time == playbackPosition())
- return;
-
if (!m_playBin)
return;
if (m_errorOccured)
return;
+ LOG_MEDIA_MESSAGE("Seek attempt to %f secs", time);
+
+ // Avoid useless seeking.
+ if (time == currentTime())
+ return;
+
// Extract the integer part of the time (seconds) and the
// fractional part (microseconds). Attempt to round the
// microseconds so no floating point precision is lost and we can
@@ -494,6 +516,11 @@
bool MediaPlayerPrivateGStreamer::paused() const
{
+ if (m_isEndReached) {
+ LOG_MEDIA_MESSAGE("Ignoring pause at EOS");
+ return true;
+ }
+
GstState state;
gst_element_get_state(m_playBin, &state, 0, 0);
return state == GST_STATE_PAUSED;
@@ -1134,8 +1161,9 @@
// Cache the duration without emiting the durationchange
// event because it's taken care of by the media element
// in this precise case.
- cacheDuration();
- } else if (maxTimeLoaded() == duration()) {
+ if (!m_isEndReached)
+ cacheDuration();
+ } else if ((state == GST_STATE_NULL) || (maxTimeLoaded() == duration())) {
m_networkState = MediaPlayer::Loaded;
m_readyState = MediaPlayer::HaveEnoughData;
} else {
@@ -1399,19 +1427,23 @@
void MediaPlayerPrivateGStreamer::didEnd()
{
- // EOS was reached but the position is not always 0 in case of
- // reverse playback. So to not confuse the HTMLMediaElement, we
- // synchronize position and duration values.
+ // Synchronize position and duration values to not confuse the
+ // HTMLMediaElement. In some cases like reverse playback the
+ // position is not always reported as 0 for instance.
float now = currentTime();
- if (now > 0 && m_playbackRate < 0) {
+ if (now > 0 && now <= duration() && m_mediaDuration != now) {
+ m_mediaDurationKnown = true;
m_mediaDuration = now;
- m_mediaDurationKnown = true;
m_player->durationChanged();
}
m_isEndReached = true;
+ timeChanged();
- timeChanged();
+ if (!m_player->mediaPlayerClient()->mediaPlayerIsLooping()) {
+ m_paused = true;
+ gst_element_set_state(m_playBin, GST_STATE_NULL);
+ }
}
void MediaPlayerPrivateGStreamer::cacheDuration()