Title: [138786] trunk/Source/WebCore
Revision
138786
Author
[email protected]
Date
2013-01-04 02:14:43 -0800 (Fri, 04 Jan 2013)

Log Message

[GStreamer] Port WebAudio backend to 1.0 APIs
https://bugs.webkit.org/show_bug.cgi?id=105293

Reviewed by Martin Robinson.

Port the AudioFileReader and AudioDestination to GStreamer 1.0
APIs. It would be preferable to rely on at least GStreamer 1.0.4
for this to work properly as that release contains two bug fixes
for the deinterleave and interleave elements.

* platform/audio/FFTFrame.cpp:
(WebCore::FFTFrame::reportMemoryUsage): Don't report GstFFTF32
structures anymore because they're opaque in GStreamer 1.0.
* platform/audio/gstreamer/AudioDestinationGStreamer.cpp:
(WebCore):
(WebCore::AudioDestinationGStreamer::AudioDestinationGStreamer):
The wavparse element in 1.0 has no sometimes-pads anymore.
* platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
(AudioFileReader): The decodebin2 element has been renamed to
decodebin in GStreamer 1.0.
(WebCore::getGStreamerAudioCaps): Audio caps description changed a
lot in GStreamer 1.0, the function now handles both APIs.
(WebCore::copyGstreamerBuffersToAudioChannel): Adapted to
GstBufferList and GstBuffer API changes.
(WebCore::onAppsinkPullRequiredCallback): Pull a sample or buffer,
depending on which API we use.
(WebCore::AudioFileReader::~AudioFileReader): Protect
GstBufferListIterators in 0.10-only code path.
(WebCore):
(WebCore::AudioFileReader::handleSample): Pull an audio sample
from appsink and insert it in the appropriate buffer list.
(WebCore::AudioFileReader::handleNewDeinterleavePad): Handle
appsink API changes from GStreamer 0.10 to 1.0.
(WebCore::AudioFileReader::decodeAudioForBusCreation): Create the
correct decodebin element.
(WebCore::AudioFileReader::createBus): Protect GstBufferListIterators
in 0.10-only code path.
* platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp:
(_WebKitWebAudioSourcePrivate): GstTask in GStreamer 1.0 uses a
GRecMutex instead of a (deprecated) GStaticRecMutex.
(getGStreamerMonoAudioCaps): Handle caps description changes
between GStreamer 0.10 and 1.0.
(webKitWebAudioGStreamerChannelPosition): POSITION_LFE in
GStreamer 1.0 is now POSITION_LFE1. Also map ChannelCenter to its
GStreamer equivalent.
(webkit_web_audio_src_class_init): Use generic setGstElementClassMetadata.
(webkit_web_audio_src_init): Handle GRecMutex initialisation.
(webKitWebAudioSrcConstructed): Set channel position on
capsfilter. This is done for GStreamer 1.0 code path only because
in 0.10 the caps have no way to store this information.
(webKitWebAudioSrcFinalize): Clear GRecMutex.
(webKitWebAudioSrcLoop): Handle GstBuffer API changes and add an
error check if buffers can't be chained to queue's source pad.
(webKitWebAudioSrcChangeState): As advised in the GStreamer docs,
fixup the state changes for this live source element: NO_PREROLL
in READY->PAUSED and start/stop the GstTask when going/coming
to/from PLAYING.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (138785 => 138786)


--- trunk/Source/WebCore/ChangeLog	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/ChangeLog	2013-01-04 10:14:43 UTC (rev 138786)
@@ -1,3 +1,63 @@
+2012-12-18  Philippe Normand  <[email protected]>
+
+        [GStreamer] Port WebAudio backend to 1.0 APIs
+        https://bugs.webkit.org/show_bug.cgi?id=105293
+
+        Reviewed by Martin Robinson.
+
+        Port the AudioFileReader and AudioDestination to GStreamer 1.0
+        APIs. It would be preferable to rely on at least GStreamer 1.0.4
+        for this to work properly as that release contains two bug fixes
+        for the deinterleave and interleave elements.
+
+        * platform/audio/FFTFrame.cpp:
+        (WebCore::FFTFrame::reportMemoryUsage): Don't report GstFFTF32
+        structures anymore because they're opaque in GStreamer 1.0.
+        * platform/audio/gstreamer/AudioDestinationGStreamer.cpp:
+        (WebCore):
+        (WebCore::AudioDestinationGStreamer::AudioDestinationGStreamer):
+        The wavparse element in 1.0 has no sometimes-pads anymore.
+        * platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
+        (AudioFileReader): The decodebin2 element has been renamed to
+        decodebin in GStreamer 1.0.
+        (WebCore::getGStreamerAudioCaps): Audio caps description changed a
+        lot in GStreamer 1.0, the function now handles both APIs.
+        (WebCore::copyGstreamerBuffersToAudioChannel): Adapted to
+        GstBufferList and GstBuffer API changes.
+        (WebCore::onAppsinkPullRequiredCallback): Pull a sample or buffer,
+        depending on which API we use.
+        (WebCore::AudioFileReader::~AudioFileReader): Protect
+        GstBufferListIterators in 0.10-only code path.
+        (WebCore):
+        (WebCore::AudioFileReader::handleSample): Pull an audio sample
+        from appsink and insert it in the appropriate buffer list.
+        (WebCore::AudioFileReader::handleNewDeinterleavePad): Handle
+        appsink API changes from GStreamer 0.10 to 1.0.
+        (WebCore::AudioFileReader::decodeAudioForBusCreation): Create the
+        correct decodebin element.
+        (WebCore::AudioFileReader::createBus): Protect GstBufferListIterators
+        in 0.10-only code path.
+        * platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp:
+        (_WebKitWebAudioSourcePrivate): GstTask in GStreamer 1.0 uses a
+        GRecMutex instead of a (deprecated) GStaticRecMutex.
+        (getGStreamerMonoAudioCaps): Handle caps description changes
+        between GStreamer 0.10 and 1.0.
+        (webKitWebAudioGStreamerChannelPosition): POSITION_LFE in
+        GStreamer 1.0 is now POSITION_LFE1. Also map ChannelCenter to its
+        GStreamer equivalent.
+        (webkit_web_audio_src_class_init): Use generic setGstElementClassMetadata.
+        (webkit_web_audio_src_init): Handle GRecMutex initialisation.
+        (webKitWebAudioSrcConstructed): Set channel position on
+        capsfilter. This is done for GStreamer 1.0 code path only because
+        in 0.10 the caps have no way to store this information.
+        (webKitWebAudioSrcFinalize): Clear GRecMutex.
+        (webKitWebAudioSrcLoop): Handle GstBuffer API changes and add an
+        error check if buffers can't be chained to queue's source pad.
+        (webKitWebAudioSrcChangeState): As advised in the GStreamer docs,
+        fixup the state changes for this live source element: NO_PREROLL
+        in READY->PAUSED and start/stop the GstTask when going/coming
+        to/from PLAYING.
+
 2013-01-04  Mihnea Ovidenie  <[email protected]>
 
         [CSS Regions]Content overflowing last region displayed wrong

Modified: trunk/Source/WebCore/platform/audio/FFTFrame.cpp (138785 => 138786)


--- trunk/Source/WebCore/platform/audio/FFTFrame.cpp	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/platform/audio/FFTFrame.cpp	2013-01-04 10:14:43 UTC (rev 138786)
@@ -279,8 +279,11 @@
 #endif // USE(WEBAUDIO_FFMPEG)
 
 #if USE(WEBAUDIO_GSTREAMER)
+#ifndef GST_API_VERSION_1
+    // The GstFFTF32 structure is exposed publicly in GStreamer 0.10 only.
     info.addMember(m_fft);
     info.addMember(m_inverseFft);
+#endif
     info.addMember(m_complexData);
     info.addMember(m_realData);
     info.addMember(m_imagData);

Modified: trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp (138785 => 138786)


--- trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp	2013-01-04 10:14:43 UTC (rev 138786)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2011 Igalia S.L
+ *  Copyright (C) 2011, 2012 Igalia S.L
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -51,10 +51,12 @@
     return 44100;
 }
 
+#ifndef GST_API_VERSION_1
 static void onGStreamerWavparsePadAddedCallback(GstElement*, GstPad* pad, AudioDestinationGStreamer* destination)
 {
     destination->finishBuildingPipelineAfterWavParserPadReady(pad);
 }
+#endif
 
 AudioDestinationGStreamer::AudioDestinationGStreamer(AudioIOCallback& callback, float sampleRate)
     : m_callback(callback)
@@ -82,9 +84,16 @@
     if (!m_wavParserAvailable)
         return;
 
+#ifndef GST_API_VERSION_1
     g_signal_connect(wavParser, "pad-added", G_CALLBACK(onGStreamerWavparsePadAddedCallback), this);
+#endif
     gst_bin_add_many(GST_BIN(m_pipeline), webkitAudioSrc, wavParser, NULL);
     gst_element_link_pads_full(webkitAudioSrc, "src", wavParser, "sink", GST_PAD_LINK_CHECK_NOTHING);
+
+#ifdef GST_API_VERSION_1
+    GRefPtr<GstPad> srcPad = adoptGRef(gst_element_get_static_pad(wavParser, "src"));
+    finishBuildingPipelineAfterWavParserPadReady(srcPad.get());
+#endif
 }
 
 AudioDestinationGStreamer::~AudioDestinationGStreamer()
@@ -125,7 +134,7 @@
 
     // Link wavparse's src pad to audioconvert sink pad.
     GRefPtr<GstPad> sinkPad = adoptGRef(gst_element_get_static_pad(audioConvert, "sink"));
-    gst_pad_link(pad, sinkPad.get());
+    gst_pad_link_full(pad, sinkPad.get(), GST_PAD_LINK_CHECK_NOTHING);
 
     // Link audioconvert to audiosink and roll states.
     gst_element_link_pads_full(audioConvert, "src", audioSink.get(), "sink", GST_PAD_LINK_CHECK_NOTHING);

Modified: trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.h (138785 => 138786)


--- trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.h	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.h	2013-01-04 10:14:43 UTC (rev 138786)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2011 Philippe Normand <[email protected]>
+ *  Copyright (C) 2011, 2012 Igalia S.L
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public

Modified: trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp (138785 => 138786)


--- trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp	2013-01-04 10:14:43 UTC (rev 138786)
@@ -24,6 +24,7 @@
 #include "AudioFileReader.h"
 
 #include "AudioBus.h"
+#include "GStreamerVersioning.h"
 
 #if PLATFORM(QT)
 // Clear out offending Qt macro so the following header, gio.h, can be included.
@@ -33,7 +34,6 @@
 
 #include <gio/gio.h>
 #include <gst/app/gstappsink.h>
-#include <gst/audio/multichannel.h>
 #include <gst/gst.h>
 #include <gst/pbutils/pbutils.h>
 #include <wtf/Noncopyable.h>
@@ -41,6 +41,18 @@
 #include <wtf/gobject/GOwnPtr.h>
 #include <wtf/gobject/GRefPtr.h>
 
+#ifdef GST_API_VERSION_1
+#include <gst/audio/audio.h>
+#else
+#include <gst/audio/multichannel.h>
+#endif
+
+#ifdef GST_API_VERSION_1
+static const char* gDecodebinName = "decodebin";
+#else
+static const char* gDecodebinName = "decodebin2";
+#endif
+
 namespace WebCore {
 
 class AudioFileReader {
@@ -52,7 +64,11 @@
 
     PassOwnPtr<AudioBus> createBus(float sampleRate, bool mixToMono);
 
+#ifdef GST_API_VERSION_1
+    GstFlowReturn handleSample(GstAppSink*);
+#else
     GstFlowReturn handleBuffer(GstAppSink*);
+#endif
     gboolean handleMessage(GstMessage*);
     void handleNewDeinterleavePad(GstPad*);
     void deinterleavePadsConfigured();
@@ -66,9 +82,13 @@
 
     float m_sampleRate;
     GstBufferList* m_frontLeftBuffers;
+    GstBufferList* m_frontRightBuffers;
+
+#ifndef GST_API_VERSION_1
     GstBufferListIterator* m_frontLeftBuffersIterator;
-    GstBufferList* m_frontRightBuffers;
     GstBufferListIterator* m_frontRightBuffersIterator;
+#endif
+
     GstElement* m_pipeline;
     unsigned m_channelSize;
     GRefPtr<GstElement> m_decodebin;
@@ -77,13 +97,21 @@
     bool m_errorOccurred;
 };
 
-static GstCaps* getGStreamerAudioCaps(int channels, float sampleRate)
-{
-    return gst_caps_new_simple("audio/x-raw-float", "rate", G_TYPE_INT, static_cast<int>(sampleRate), "channels", G_TYPE_INT, channels, "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
-}
-
 static void copyGstreamerBuffersToAudioChannel(GstBufferList* buffers, AudioChannel* audioChannel)
 {
+#ifdef GST_API_VERSION_1
+    gsize offset = 0;
+    for (unsigned i = 0; i < gst_buffer_list_length(buffers); i++) {
+        GstBuffer* buffer = gst_buffer_list_get(buffers, i);
+        if (!buffer)
+            continue;
+        GstMapInfo info;
+        gst_buffer_map(buffer, &info, GST_MAP_READ);
+        memcpy(audioChannel->mutableData() + offset, reinterpret_cast<float*>(info.data), info.size);
+        offset += info.size / sizeof(float);
+        gst_buffer_unmap(buffer, &info);
+    }
+#else
     GstBufferListIterator* iter = gst_buffer_list_iterate(buffers);
     gst_buffer_list_iterator_next_group(iter);
     GstBuffer* buffer = gst_buffer_list_iterator_merge_group(iter);
@@ -93,11 +121,16 @@
     }
 
     gst_buffer_list_iterator_free(iter);
+#endif
 }
 
-static GstFlowReturn onAppsinkNewBufferCallback(GstAppSink* sink, gpointer userData)
+static GstFlowReturn onAppsinkPullRequiredCallback(GstAppSink* sink, gpointer userData)
 {
+#ifdef GST_API_VERSION_1
+    return static_cast<AudioFileReader*>(userData)->handleSample(sink);
+#else
     return static_cast<AudioFileReader*>(userData)->handleBuffer(sink);
+#endif
 }
 
 gboolean messageCallback(GstBus*, GstMessage* message, AudioFileReader* reader)
@@ -167,12 +200,58 @@
         m_deInterleave.clear();
     }
 
+#ifndef GST_API_VERSION_1
     gst_buffer_list_iterator_free(m_frontLeftBuffersIterator);
     gst_buffer_list_iterator_free(m_frontRightBuffersIterator);
+#endif
     gst_buffer_list_unref(m_frontLeftBuffers);
     gst_buffer_list_unref(m_frontRightBuffers);
 }
 
+#ifdef GST_API_VERSION_1
+GstFlowReturn AudioFileReader::handleSample(GstAppSink* sink)
+{
+    GstSample* sample = gst_app_sink_pull_sample(sink);
+    if (!sample)
+        return GST_FLOW_ERROR;
+
+    GstBuffer* buffer = gst_sample_get_buffer(sample);
+    if (!buffer) {
+        gst_sample_unref(sample);
+        return GST_FLOW_ERROR;
+    }
+
+    GstCaps* caps = gst_sample_get_caps(sample);
+    if (!caps) {
+        gst_sample_unref(sample);
+        return GST_FLOW_ERROR;
+    }
+
+    GstAudioInfo info;
+    gst_audio_info_from_caps(&info, caps);
+    int frames = GST_CLOCK_TIME_TO_FRAMES(GST_BUFFER_DURATION(buffer), GST_AUDIO_INFO_RATE(&info));
+
+    // Check the first audio channel. The buffer is supposed to store
+    // data of a single channel anyway.
+    switch (GST_AUDIO_INFO_POSITION(&info, 0)) {
+    case GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT:
+        gst_buffer_list_add(m_frontLeftBuffers, gst_buffer_ref(buffer));
+        m_channelSize += frames;
+        break;
+    case GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT:
+        gst_buffer_list_add(m_frontRightBuffers, gst_buffer_ref(buffer));
+        break;
+    default:
+        break;
+    }
+
+    gst_sample_unref(sample);
+    return GST_FLOW_OK;
+
+}
+#endif
+
+#ifndef GST_API_VERSION_1
 GstFlowReturn AudioFileReader::handleBuffer(GstAppSink* sink)
 {
     GstBuffer* buffer = gst_app_sink_pull_buffer(sink);
@@ -226,6 +305,7 @@
     gst_caps_unref(caps);
     return GST_FLOW_OK;
 }
+#endif
 
 gboolean AudioFileReader::handleMessage(GstMessage* message)
 {
@@ -264,20 +344,20 @@
     GstAppSinkCallbacks callbacks;
     callbacks.eos = 0;
     callbacks.new_preroll = 0;
+#ifdef GST_API_VERSION_1
+    callbacks.new_sample = onAppsinkPullRequiredCallback;
+#else
     callbacks.new_buffer_list = 0;
-    callbacks.new_buffer = onAppsinkNewBufferCallback;
+    callbacks.new_buffer = onAppsinkPullRequiredCallback;
+#endif
     gst_app_sink_set_callbacks(GST_APP_SINK(sink), &callbacks, this, 0);
 
     g_object_set(sink, "sync", FALSE, NULL);
 
-    GstCaps* caps = getGStreamerAudioCaps(1, m_sampleRate);
-    gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
-    gst_caps_unref(caps);
-
     gst_bin_add_many(GST_BIN(m_pipeline), queue, sink, NULL);
 
     GstPad* sinkPad = gst_element_get_static_pad(queue, "sink");
-    gst_pad_link(pad, sinkPad);
+    gst_pad_link_full(pad, sinkPad, GST_PAD_LINK_CHECK_NOTHING);
     gst_object_unref(GST_OBJECT(sinkPad));
 
     gst_element_link_pads_full(queue, "src", sink, "sink", GST_PAD_LINK_CHECK_NOTHING);
@@ -307,14 +387,14 @@
     g_signal_connect(m_deInterleave.get(), "pad-added", G_CALLBACK(onGStreamerDeinterleavePadAddedCallback), this);
     g_signal_connect(m_deInterleave.get(), "no-more-pads", G_CALLBACK(onGStreamerDeinterleaveReadyCallback), this);
 
-    GstCaps* caps = getGStreamerAudioCaps(2, m_sampleRate);
+    GstCaps* caps = getGstAudioCaps(2, m_sampleRate);
     g_object_set(capsFilter, "caps", caps, NULL);
     gst_caps_unref(caps);
 
     gst_bin_add_many(GST_BIN(m_pipeline), audioConvert, audioResample, capsFilter, m_deInterleave.get(), NULL);
 
     GstPad* sinkPad = gst_element_get_static_pad(audioConvert, "sink");
-    gst_pad_link(pad, sinkPad);
+    gst_pad_link_full(pad, sinkPad, GST_PAD_LINK_CHECK_NOTHING);
     gst_object_unref(GST_OBJECT(sinkPad));
 
     gst_element_link_pads_full(audioConvert, "src", audioResample, "sink", GST_PAD_LINK_CHECK_NOTHING);
@@ -350,7 +430,7 @@
         g_object_set(source, "location", m_filePath, NULL);
     }
 
-    m_decodebin = gst_element_factory_make("decodebin2", "decodebin");
+    m_decodebin = gst_element_factory_make(gDecodebinName, "decodebin");
     g_signal_connect(m_decodebin.get(), "pad-added", G_CALLBACK(onGStreamerDecodebinPadAddedCallback), this);
 
     gst_bin_add_many(GST_BIN(m_pipeline), source, m_decodebin.get(), NULL);
@@ -363,12 +443,15 @@
     m_sampleRate = sampleRate;
 
     m_frontLeftBuffers = gst_buffer_list_new();
+    m_frontRightBuffers = gst_buffer_list_new();
+
+#ifndef GST_API_VERSION_1
     m_frontLeftBuffersIterator = gst_buffer_list_iterate(m_frontLeftBuffers);
     gst_buffer_list_iterator_add_group(m_frontLeftBuffersIterator);
 
-    m_frontRightBuffers = gst_buffer_list_new();
     m_frontRightBuffersIterator = gst_buffer_list_iterate(m_frontRightBuffers);
     gst_buffer_list_iterator_add_group(m_frontRightBuffersIterator);
+#endif
 
     GRefPtr<GMainContext> context = g_main_context_new();
     g_main_context_push_thread_default(context.get());

Modified: trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp (138785 => 138786)


--- trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp	2013-01-04 10:14:43 UTC (rev 138786)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2011 Igalia S.L
+ *  Copyright (C) 2011, 2012 Igalia S.L
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,11 @@
 #include <wtf/gobject/GOwnPtr.h>
 #include "GRefPtrGStreamer.h"
 #include "GStreamerVersioning.h"
+#ifdef GST_API_VERSION_1
+#include <gst/audio/audio.h>
+#else
 #include <gst/audio/multichannel.h>
+#endif
 #include <gst/pbutils/pbutils.h>
 
 using namespace WebCore;
@@ -45,6 +49,7 @@
     GstBinClass parentClass;
 };
 
+#define WEBKIT_WEB_AUDIO_SRC_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEBAUDIO_SRC, WebKitWebAudioSourcePrivate))
 struct _WebKitWebAudioSourcePrivate {
     gfloat sampleRate;
     AudioBus* bus;
@@ -55,7 +60,11 @@
     GRefPtr<GstElement> wavEncoder;
 
     GRefPtr<GstTask> task;
+#ifdef GST_API_VERSION_1
+    GRecMutex mutex;
+#else
     GStaticRecMutex mutex;
+#endif
 
     GSList* pads; // List of queue sink pads. One queue for each planar audio channel.
     GstPad* sourcePad; // src pad of the element, interleaved wav data is pushed to it.
@@ -85,10 +94,17 @@
 
 static GstCaps* getGStreamerMonoAudioCaps(float sampleRate)
 {
+#ifdef GST_API_VERSION_1
+    return gst_caps_new_simple("audio/x-raw", "rate", G_TYPE_INT, static_cast<int>(sampleRate),
+        "channels", G_TYPE_INT, 1,
+        "format", G_TYPE_STRING, gst_audio_format_to_string(GST_AUDIO_FORMAT_F32),
+        "layout", G_TYPE_STRING, "non-interleaved", NULL);
+#else
     return gst_caps_new_simple("audio/x-raw-float", "rate", G_TYPE_INT, static_cast<int>(sampleRate),
-                               "channels", G_TYPE_INT, 1,
-                               "endianness", G_TYPE_INT, G_BYTE_ORDER,
-                               "width", G_TYPE_INT, 32, NULL);
+        "channels", G_TYPE_INT, 1,
+        "endianness", G_TYPE_INT, G_BYTE_ORDER,
+        "width", G_TYPE_INT, 32, NULL);
+#endif
 }
 
 static GstAudioChannelPosition webKitWebAudioGStreamerChannelPosition(int channelIndex)
@@ -103,11 +119,14 @@
         position = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
         break;
     case AudioBus::ChannelCenter:
-        // Center and mono are the same.
-        position = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
+        position = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
         break;
     case AudioBus::ChannelLFE:
+#ifdef GST_API_VERSION_1
+        position = GST_AUDIO_CHANNEL_POSITION_LFE1;
+#else
         position = GST_AUDIO_CHANNEL_POSITION_LFE;
+#endif
         break;
     case AudioBus::ChannelSurroundLeft:
         position = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
@@ -134,11 +153,7 @@
     GstElementClass* elementClass = GST_ELEMENT_CLASS(webKitWebAudioSrcClass);
 
     gst_element_class_add_pad_template(elementClass, gst_static_pad_template_get(&srcTemplate));
-    gst_element_class_set_details_simple(elementClass,
-                                         "WebKit WebAudio source element",
-                                         "Source",
-                                         "Handles WebAudio data from WebCore",
-                                         "Philippe Normand <[email protected]>");
+    setGstElementClassMetadata(elementClass, "WebKit WebAudio source element", "Source", "Handles WebAudio data from WebCore", "Philippe Normand <[email protected]>");
 
     objectClass->constructed = webKitWebAudioSrcConstructed;
     objectClass->finalize = webKitWebAudioSrcFinalize;
@@ -185,9 +200,14 @@
     priv->provider = 0;
     priv->bus = 0;
 
+#ifdef GST_API_VERSION_1
+    g_rec_mutex_init(&priv->mutex);
+    priv->task = gst_task_new(reinterpret_cast<GstTaskFunction>(webKitWebAudioSrcLoop), src, reinterpret_cast<GDestroyNotify>(g_object_unref));
+#else
     g_static_rec_mutex_init(&priv->mutex);
+    priv->task = gst_task_create(reinterpret_cast<GstTaskFunction>(webKitWebAudioSrcLoop), src);
+#endif
 
-    priv->task = gst_task_create(reinterpret_cast<GstTaskFunction>(webKitWebAudioSrcLoop), src);
     gst_task_set_lock(priv->task.get(), &priv->mutex);
 }
 
@@ -224,7 +244,16 @@
         GstElement* audioconvert = gst_element_factory_make("audioconvert", 0);
 
         GRefPtr<GstCaps> monoCaps = adoptGRef(getGStreamerMonoAudioCaps(priv->sampleRate));
+
+#ifdef GST_API_VERSION_1
+        GstAudioInfo info;
+        gst_audio_info_from_caps(&info, monoCaps.get());
+        GST_AUDIO_INFO_POSITION(&info, 0) = webKitWebAudioGStreamerChannelPosition(channelIndex);
+        GRefPtr<GstCaps> caps = adoptGRef(gst_audio_info_to_caps(&info));
+        g_object_set(capsfilter, "caps", caps.get(), NULL);
+#else
         g_object_set(capsfilter, "caps", monoCaps.get(), NULL);
+#endif
 
         // Configure the queue for minimal latency.
         g_object_set(queue, "max-size-buffers", static_cast<guint>(1), NULL);
@@ -250,7 +279,11 @@
     WebKitWebAudioSrc* src = ""
     WebKitWebAudioSourcePrivate* priv = src->priv;
 
+#ifdef GST_API_VERSION_1
+    g_rec_mutex_clear(&priv->mutex);
+#else
     g_static_rec_mutex_free(&priv->mutex);
+#endif
 
     g_slist_free_full(priv->pads, reinterpret_cast<GDestroyNotify>(gst_object_unref));
 
@@ -321,7 +354,14 @@
         GstBuffer* channelBuffer = gst_buffer_new_and_alloc(bufferSize);
         ASSERT(channelBuffer);
         channelBufferList = g_slist_prepend(channelBufferList, channelBuffer);
+#ifdef GST_API_VERSION_1
+        GstMapInfo info;
+        gst_buffer_map(channelBuffer, &info, GST_MAP_READ);
+        priv->bus->setChannelMemory(i, reinterpret_cast<float*>(info.data), priv->framesToPull);
+        gst_buffer_unmap(channelBuffer, &info);
+#else
         priv->bus->setChannelMemory(i, reinterpret_cast<float*>(GST_BUFFER_DATA(channelBuffer)), priv->framesToPull);
+#endif
     }
     channelBufferList = g_slist_reverse(channelBufferList);
 
@@ -332,13 +372,17 @@
         GstPad* pad = static_cast<GstPad*>(g_slist_nth_data(priv->pads, i));
         GstBuffer* channelBuffer = static_cast<GstBuffer*>(g_slist_nth_data(channelBufferList, i));
 
+#ifndef GST_API_VERSION_1
         GRefPtr<GstCaps> monoCaps = adoptGRef(getGStreamerMonoAudioCaps(priv->sampleRate));
         GstStructure* structure = gst_caps_get_structure(monoCaps.get(), 0);
         GstAudioChannelPosition channelPosition = webKitWebAudioGStreamerChannelPosition(i);
         gst_audio_set_channel_positions(structure, &channelPosition);
         gst_buffer_set_caps(channelBuffer, monoCaps.get());
+#endif
 
-        gst_pad_chain(pad, channelBuffer);
+        GstFlowReturn ret = gst_pad_chain(pad, channelBuffer);
+        if (ret != GST_FLOW_OK)
+            GST_ELEMENT_ERROR(src, CORE, PAD, ("Internal WebAudioSrc error"), ("Failed to push buffer on %s", GST_DEBUG_PAD_NAME(pad)));
     }
 
     g_slist_free(channelBufferList);
@@ -375,11 +419,15 @@
     switch (transition) {
     case GST_STATE_CHANGE_READY_TO_PAUSED:
         GST_DEBUG_OBJECT(src, "READY->PAUSED");
+        returnValue = GST_STATE_CHANGE_NO_PREROLL;
+        break;
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+        GST_DEBUG_OBJECT(src, "PAUSED->PLAYING");
         if (!gst_task_start(src->priv->task.get()))
             returnValue = GST_STATE_CHANGE_FAILURE;
         break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-        GST_DEBUG_OBJECT(src, "PAUSED->READY");
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+        GST_DEBUG_OBJECT(src, "PLAYING->PAUSED");
         if (!gst_task_join(src->priv->task.get()))
             returnValue = GST_STATE_CHANGE_FAILURE;
         break;

Modified: trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.h (138785 => 138786)


--- trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.h	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.h	2013-01-04 10:14:43 UTC (rev 138786)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2011 Igalia S.L
+ *  Copyright (C) 2011, 2012 Igalia S.L
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp (138785 => 138786)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp	2013-01-04 10:14:43 UTC (rev 138786)
@@ -25,6 +25,12 @@
 #include "IntSize.h"
 #include <wtf/UnusedParam.h>
 
+#ifdef GST_API_VERSION_1
+#include <gst/audio/audio.h>
+#else
+#include <gst/audio/multichannel.h>
+#endif
+
 void webkitGstObjectRefSink(GstObject* gstObject)
 {
 #ifdef GST_API_VERSION_1
@@ -141,4 +147,22 @@
     gst_element_found_tags_for_pad(element, pad, tags);
 #endif
 }
+
+#if ENABLE(WEB_AUDIO)
+GstCaps* getGstAudioCaps(int channels, float sampleRate)
+{
+#ifdef GST_API_VERSION_1
+    return gst_caps_new_simple("audio/x-raw", "rate", G_TYPE_INT, static_cast<int>(sampleRate),
+        "channels", G_TYPE_INT, channels,
+        "format", G_TYPE_STRING, gst_audio_format_to_string(GST_AUDIO_FORMAT_F32),
+        "layout", G_TYPE_STRING, "interleaved", NULL);
+#else
+    return gst_caps_new_simple("audio/x-raw-float", "rate", G_TYPE_INT, static_cast<int>(sampleRate),
+        "channels", G_TYPE_INT, channels,
+        "endianness", G_TYPE_INT, G_BYTE_ORDER,
+        "width", G_TYPE_INT, 32, NULL);
+#endif
+}
+#endif
+
 #endif // USE(GSTREAMER)

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h (138785 => 138786)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h	2013-01-04 10:13:27 UTC (rev 138785)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h	2013-01-04 10:14:43 UTC (rev 138786)
@@ -39,5 +39,8 @@
 void setGstElementClassMetadata(GstElementClass*, const char* name, const char* longName, const char* description, const char* author);
 bool gstObjectIsFloating(GstObject*);
 void notifyGstTagsOnPad(GstElement*, GstPad*, GstTagList*);
+#if ENABLE(WEB_AUDIO)
+GstCaps* getGstAudioCaps(int channels, float sampleRate);
+#endif
 #endif // USE(GSTREAMER)
 #endif // GStreamerVersioning_h
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to