[GStreamer] Implement setPreservesPitch()
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Jan 2013 16:16:42 +0000 (16:16 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Jan 2013 16:16:42 +0000 (16:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=31155

Enables audio pitch preservation by using the scaletempo GStreamer
element when required by the MediaPlayer.

Patch by Victor Jaquez <vjaquez@igalia.com> on 2013-01-24
Reviewed by Philippe Normand.

No new tests, but a layout test shall be implemented at some point
using WebAudio API.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::setPreservesPitch):
(WebCore):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
(MediaPlayerPrivateGStreamer):

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

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

index 37b9ffd..c07c7b4 100644 (file)
@@ -1,3 +1,22 @@
+2013-01-24  Victor Jaquez  <vjaquez@igalia.com>
+
+        [GStreamer] Implement setPreservesPitch()
+        https://bugs.webkit.org/show_bug.cgi?id=31155
+
+        Enables audio pitch preservation by using the scaletempo GStreamer
+        element when required by the MediaPlayer.
+
+        Reviewed by Philippe Normand.
+
+        No new tests, but a layout test shall be implemented at some point
+        using WebAudio API.
+
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::setPreservesPitch):
+        (WebCore):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+        (MediaPlayerPrivateGStreamer):
+
 2013-01-24  Zoltan Arvai  <zarvai@inf.u-szeged.hu>
 
         Removing deleted files from WebCore/Target.pri after r140399.
index 95cd541..d63216b 100644 (file)
@@ -250,6 +250,7 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player)
     , m_webkitAudioSink(0)
     , m_totalBytes(-1)
     , m_originalPreloadWasAutoAndWasOverridden(false)
+    , m_preservesPitch(false)
 {
 }
 
@@ -740,6 +741,11 @@ void MediaPlayerPrivateGStreamer::setRate(float rate)
         g_object_set(m_playBin.get(), "mute", mute, NULL);
 }
 
+void MediaPlayerPrivateGStreamer::setPreservesPitch(bool preservesPitch)
+{
+    m_preservesPitch = preservesPitch;
+}
+
 MediaPlayer::NetworkState MediaPlayerPrivateGStreamer::networkState() const
 {
     return m_networkState;
@@ -1795,6 +1801,40 @@ void MediaPlayerPrivateGStreamer::setPreload(MediaPlayer::Preload preload)
     }
 }
 
+void MediaPlayerPrivateGStreamer::createAudioSink()
+{
+    // Construct audio sink if pitch preserving is enabled.
+    if (!m_preservesPitch)
+        return;
+
+    if (!m_playBin)
+        return;
+
+    GstElement* scale = gst_element_factory_make("scaletempo", 0);
+    if (!scale) {
+        GST_WARNING("Failed to create scaletempo");
+        return;
+    }
+
+    GstElement* convert = gst_element_factory_make("audioconvert", 0);
+    GstElement* resample = gst_element_factory_make("audioresample", 0);
+    GstElement* sink = gst_element_factory_make("autoaudiosink", 0);
+
+    GstElement* audioSink = gst_bin_new("audio-sink");
+    gst_bin_add_many(GST_BIN(audioSink), scale, convert, resample, sink, NULL);
+
+    if (!gst_element_link_many(scale, convert, resample, sink, NULL)) {
+        GST_WARNING("Failed to link audio sink elements");
+        gst_object_unref(audioSink);
+        return;
+    }
+
+    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(scale, "sink"));
+    gst_element_add_pad(audioSink, gst_ghost_pad_new("sink", pad.get()));
+
+    g_object_set(m_playBin.get(), "audio-sink", audioSink, NULL);
+}
+
 void MediaPlayerPrivateGStreamer::createGSTPlayBin()
 {
     ASSERT(!m_playBin);
@@ -1830,7 +1870,7 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
 
 
 #ifndef GST_API_VERSION_1
-    m_videoSinkBin = gst_bin_new("sink");
+    m_videoSinkBin = gst_bin_new("video-sink");
 
     GstElement* videoTee = gst_element_factory_make("tee", "videoTee");
     GstElement* queue = gst_element_factory_make("queue", 0);
@@ -1907,6 +1947,7 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
     if (videoSinkPad)
         g_signal_connect(videoSinkPad.get(), "notify::caps", G_CALLBACK(mediaPlayerPrivateVideoSinkCapsChangedCallback), this);
 
+    createAudioSink();
 }
 
 }
index cbf46bc..7e5dbf8 100644 (file)
@@ -72,6 +72,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
             void seek(float);
 
             void setRate(float);
+            void setPreservesPitch(bool);
 
             void setVolume(float);
             void volumeChanged();
@@ -137,6 +138,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
             static bool isAvailable();
 
             void updateAudioSink();
+            void createAudioSink();
 
             float playbackPosition() const;
 
@@ -205,6 +207,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
             mutable IntSize m_videoSize;
             KURL m_url;
             bool m_originalPreloadWasAutoAndWasOverridden;
+            bool m_preservesPitch;
     };
 }