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