2010-12-01 Philippe Normand <pnormand@igalia.com>
authorphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Dec 2010 11:41:04 +0000 (11:41 +0000)
committerphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Dec 2010 11:41:04 +0000 (11:41 +0000)
        Reviewed by Martin Robinson.

        Volume control not correctly initialized
        https://bugs.webkit.org/show_bug.cgi?id=36299

        Replaced the mute/volume Timers with g_timeouts which are (for
        now, at least) more reliable than Timers for one-shot-fire-now
        actions.

        Test: media/video-volume.html

        * platform/graphics/MediaPlayer.cpp:
        (WebCore::MediaPlayer::~MediaPlayer): Reset the raw pointers to 0
        when destructing the player.
        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
        (WebCore::mediaPlayerPrivateVolumeChangeTimeoutCallback):
        (WebCore::mediaPlayerPrivateMuteChangeTimeoutCallback):
        (WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer):
        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange):
        (WebCore::MediaPlayerPrivateGStreamer::volumeChanged):
        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfMute):
        (WebCore::MediaPlayerPrivateGStreamer::muteChanged):
        (WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): Set
        playbin2 volume/mute base on MediaPlayer related values.
        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@73014 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/graphics/MediaPlayer.cpp
WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

index dcd61b3..9fe856f 100644 (file)
@@ -1,3 +1,31 @@
+2010-12-01  Philippe Normand  <pnormand@igalia.com>
+
+        Reviewed by Martin Robinson.
+
+        Volume control not correctly initialized
+        https://bugs.webkit.org/show_bug.cgi?id=36299
+
+        Replaced the mute/volume Timers with g_timeouts which are (for
+        now, at least) more reliable than Timers for one-shot-fire-now
+        actions.
+
+        Test: media/video-volume.html
+
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::~MediaPlayer): Reset the raw pointers to 0
+        when destructing the player.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::mediaPlayerPrivateVolumeChangeTimeoutCallback):
+        (WebCore::mediaPlayerPrivateMuteChangeTimeoutCallback):
+        (WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer):
+        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange):
+        (WebCore::MediaPlayerPrivateGStreamer::volumeChanged):
+        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfMute):
+        (WebCore::MediaPlayerPrivateGStreamer::muteChanged):
+        (WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): Set
+        playbin2 volume/mute base on MediaPlayer related values.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+
 2010-12-01  Patrick Gansterer  <paroga@webkit.org>
 
         Reviewed by Andreas Kling.
index e87c53c..54b941c 100644 (file)
@@ -268,6 +268,7 @@ MediaPlayer::MediaPlayer(MediaPlayerClient* client)
 
 MediaPlayer::~MediaPlayer()
 {
+    m_mediaPlayerClient = 0;
 }
 
 void MediaPlayer::load(const String& url, const ContentType& contentType)
index 695d1f7..dbef4c9 100644 (file)
@@ -177,6 +177,13 @@ void mediaPlayerPrivateVolumeChangedCallback(GObject *element, GParamSpec *pspec
     mp->volumeChanged();
 }
 
+gboolean mediaPlayerPrivateVolumeChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
+{
+    // This is the callback of the timeout source created in ::volumeChanged.
+    player->notifyPlayerOfVolumeChange();
+    return FALSE;
+}
+
 void mediaPlayerPrivateMuteChangedCallback(GObject *element, GParamSpec *pspec, gpointer data)
 {
     // This is called when playbin receives the notify::mute signal.
@@ -184,6 +191,13 @@ void mediaPlayerPrivateMuteChangedCallback(GObject *element, GParamSpec *pspec,
     mp->muteChanged();
 }
 
+gboolean mediaPlayerPrivateMuteChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
+{
+    // This is the callback of the timeout source created in ::muteChanged.
+    player->notifyPlayerOfMute();
+    return FALSE;
+}
+
 static float playbackPosition(GstElement* playbin)
 {
 
@@ -327,8 +341,18 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
     if (m_playBin) {
         gst_element_set_state(m_playBin, GST_STATE_NULL);
         gst_object_unref(GST_OBJECT(m_playBin));
+        m_playBin = 0;
     }
 
+    m_player = 0;
+
+    if (m_muteTimerHandler)
+        g_source_remove(m_muteTimerHandler);
+    m_muteTimerHandler = 0;
+
+    if (m_volumeTimerHandler)
+        g_source_remove(m_volumeTimerHandler);
+    m_volumeTimerHandler = 0;
 }
 
 void MediaPlayerPrivateGStreamer::load(const String& url)
@@ -584,8 +608,12 @@ void MediaPlayerPrivateGStreamer::setVolume(float volume)
     g_object_set(m_playBin, "volume", static_cast<double>(volume), NULL);
 }
 
-void MediaPlayerPrivateGStreamer::volumeChangedTimerFired(Timer<MediaPlayerPrivateGStreamer>*)
+void MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange()
 {
+    m_volumeTimerHandler = 0;
+
+    if (!m_player || !m_playBin)
+        return;
     double volume;
     g_object_get(m_playBin, "volume", &volume, NULL);
     m_player->volumeChanged(static_cast<float>(volume));
@@ -593,8 +621,9 @@ void MediaPlayerPrivateGStreamer::volumeChangedTimerFired(Timer<MediaPlayerPriva
 
 void MediaPlayerPrivateGStreamer::volumeChanged()
 {
-    Timer<MediaPlayerPrivateGStreamer> volumeChangedTimer(this, &MediaPlayerPrivateGStreamer::volumeChangedTimerFired);
-    volumeChangedTimer.startOneShot(0);
+    if (m_volumeTimerHandler)
+        g_source_remove(m_volumeTimerHandler);
+    m_volumeTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateVolumeChangeTimeoutCallback), this);
 }
 
 void MediaPlayerPrivateGStreamer::setRate(float rate)
@@ -1158,8 +1187,13 @@ void MediaPlayerPrivateGStreamer::setMuted(bool muted)
     g_object_set(m_playBin, "mute", muted, NULL);
 }
 
-void MediaPlayerPrivateGStreamer::muteChangedTimerFired(Timer<MediaPlayerPrivateGStreamer>*)
+void MediaPlayerPrivateGStreamer::notifyPlayerOfMute()
 {
+    m_muteTimerHandler = 0;
+
+    if (!m_player || !m_playBin)
+        return;
+
     gboolean muted;
     g_object_get(m_playBin, "mute", &muted, NULL);
     m_player->muteChanged(static_cast<bool>(muted));
@@ -1167,8 +1201,9 @@ void MediaPlayerPrivateGStreamer::muteChangedTimerFired(Timer<MediaPlayerPrivate
 
 void MediaPlayerPrivateGStreamer::muteChanged()
 {
-    Timer<MediaPlayerPrivateGStreamer> muteChangedTimer(this, &MediaPlayerPrivateGStreamer::muteChangedTimerFired);
-    muteChangedTimer.startOneShot(0);
+    if (m_muteTimerHandler)
+        g_source_remove(m_muteTimerHandler);
+    m_muteTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateMuteChangeTimeoutCallback), this);
 }
 
 void MediaPlayerPrivateGStreamer::loadingFailed(MediaPlayer::NetworkState error)
@@ -1401,6 +1436,8 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
     g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this);
     gst_object_unref(bus);
 
+    g_object_set(m_playBin, "mute", m_player->muted(), "volume", m_player->volume(), 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);
index 800ca6d..23095ec 100644 (file)
@@ -43,11 +43,14 @@ class GraphicsContext;
 class IntSize;
 class IntRect;
 class GStreamerGWorld;
+class MediaPlayerPrivateGStreamer;
 
 gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
 void mediaPlayerPrivateVolumeChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
 void mediaPlayerPrivateMuteChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
 void mediaPlayerPrivateSourceChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
+gboolean mediaPlayerPrivateVolumeChangeTimeoutCallback(MediaPlayerPrivateGStreamer*);
+gboolean mediaPlayerPrivateMuteChangeTimeoutCallback(MediaPlayerPrivateGStreamer*);
 
 class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
         friend gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
@@ -81,12 +84,12 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
 
             void setVolume(float);
             void volumeChanged();
-            void volumeChangedTimerFired(Timer<MediaPlayerPrivateGStreamer>*);
+            void notifyPlayerOfVolumeChange();
 
             bool supportsMuting() const;
             void setMuted(bool);
             void muteChanged();
-            void muteChangedTimerFired(Timer<MediaPlayerPrivateGStreamer>*);
+            void notifyPlayerOfMute();
 
             void setPreload(MediaPlayer::Preload);
             void fillTimerFired(Timer<MediaPlayerPrivateGStreamer>*);
@@ -176,6 +179,8 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
             bool m_delayingLoad;
             bool m_mediaDurationKnown;
             RefPtr<GStreamerGWorld> m_gstGWorld;
+            guint m_volumeTimerHandler;
+            guint m_muteTimerHandler;
     };
 }