Changeset 101138 in webkit
- Timestamp:
- Nov 24, 2011 6:57:34 AM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r101133 r101138 1 2011-10-27 Philippe Normand <pnormand@igalia.com> 2 3 [GStreamer] WebAudio AudioDestination 4 https://bugs.webkit.org/show_bug.cgi?id=69835 5 6 Reviewed by Martin Robinson. 7 8 New GStreamer source element pulling data from the AudioBus and 9 outputing audio interleaved GstBuffers suitable for playback. 10 11 * GNUmakefile.list.am: Added the new GStreamer WebAudio element 12 source files to the build. 13 * platform/audio/gstreamer/AudioDestinationGStreamer.cpp: 14 (WebCore::onGStreamerWavparsePadAddedCallback): Function called 15 when the playback pipeline successfully parsed the audio source 16 into a WAV stream. 17 (WebCore::AudioDestinationGStreamer::AudioDestinationGStreamer): 18 Configure the initial playback pipeline up to the WAV parser. The 19 audio sink is added only after the WAV parser was configured. 20 (WebCore::AudioDestinationGStreamer::~AudioDestinationGStreamer): 21 Reset the playback pipeline and delete it. 22 (WebCore::AudioDestinationGStreamer::finishBuildingPipelineAfterWavParserPadReady): 23 Method to add the audio sink to the pipeline and link it to the 24 WAV parser. 25 (WebCore::AudioDestinationGStreamer::start): Set pipeline to 26 PLAYING, at the first run it will trigger the WAV parser and hence 27 the audio-sink plugging. 28 (WebCore::AudioDestinationGStreamer::stop): Pause the pipeline. 29 * platform/audio/gstreamer/AudioDestinationGStreamer.h: 30 * platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp: Added. 31 (getGStreamerMonoAudioCaps): Utility function to generate 32 GStreamer caps representing a single audio channel for a given 33 sample rate. 34 (webKitWebAudioGStreamerChannelPosition): Utility function to 35 convert AudioBus channel representations to GStreamer positional 36 audio channel values. 37 (webkit_web_audio_src_class_init): GObject configuration of the 38 GStreamer source element. 39 (webkit_web_audio_src_init): Initialization of the private data of 40 the element. 41 (webKitWebAudioSourceConstructed): Configure the GstBin elements 42 depending on the AudioBus layout. 43 (webKitWebAudioSourceFinalize): Clean up the GstBin and free private 44 data of the element. 45 (webKitWebAudioSourceSetProperty): GObject property setter. 46 (webKitWebAudioSourceGetProperty): GObject property getter. 47 (webKitWebAudioSourceLoop): GstTask used to pull data from the 48 AudioBus and push it as GstBuffers to the src pad of the element. 49 (webKitWebAudioSourceChangeState): Start or stop the above GstTask 50 depending on the asked state transition. 51 * platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.h: Added. 52 * platform/graphics/gstreamer/GRefPtrGStreamer.cpp: GstTask support in GRefPtr. 53 (WTF::adoptGRef): 54 (WTF::GstTask): 55 * platform/graphics/gstreamer/GRefPtrGStreamer.h: 56 1 57 2011-11-24 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> 2 58 -
trunk/Source/WebCore/GNUmakefile.list.am
r101081 r101138 4826 4826 Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.h \ 4827 4827 Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp \ 4828 Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp \ 4829 Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.h \ 4828 4830 Source/WebCore/platform/audio/gtk/AudioBusGtk.cpp 4829 4831 webcore_built_sources += \ -
trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp
r98554 r101138 26 26 #include "AudioSourceProvider.h" 27 27 #include "GOwnPtr.h" 28 #include "GRefPtrGStreamer.h" 29 #include "WebKitWebAudioSourceGStreamer.h" 30 #include <gst/gst.h> 31 #include <gst/pbutils/pbutils.h> 28 32 29 33 namespace WebCore { 34 35 // Size of the AudioBus for playback. The webkitwebaudiosrc element 36 // needs to handle this number of frames per cycle as well. 37 const unsigned framesToPull = 128; 30 38 31 39 PassOwnPtr<AudioDestination> AudioDestination::create(AudioSourceProvider& provider, float sampleRate) … … 39 47 } 40 48 49 static void onGStreamerWavparsePadAddedCallback(GstElement* element, GstPad* pad, AudioDestinationGStreamer* destination) 50 { 51 destination->finishBuildingPipelineAfterWavParserPadReady(pad); 52 } 53 41 54 AudioDestinationGStreamer::AudioDestinationGStreamer(AudioSourceProvider& provider, float sampleRate) 42 55 : m_provider(provider) 43 , m_renderBus(2, 128, true)56 , m_renderBus(2, framesToPull, true) 44 57 , m_sampleRate(sampleRate) 45 58 , m_isPlaying(false) 46 59 { 60 static bool gstInitialized = false; 61 if (!gstInitialized) 62 gstInitialized = gst_init_check(0, 0, 0); 63 ASSERT_WITH_MESSAGE(gstInitialized, "GStreamer initialization failed"); 64 65 m_pipeline = gst_pipeline_new("play"); 66 67 GstElement* webkitAudioSrc = reinterpret_cast<GstElement*>(g_object_new(WEBKIT_TYPE_WEB_AUDIO_SRC, 68 "rate", sampleRate, 69 "bus", &m_renderBus, 70 "provider", &m_provider, 71 "frames", framesToPull, NULL)); 72 73 GstElement* wavParser = gst_element_factory_make("wavparse", 0); 74 75 m_wavParserAvailable = wavParser; 76 ASSERT_WITH_MESSAGE(m_wavParserAvailable, "Failed to create GStreamer wavparse element"); 77 if (!m_wavParserAvailable) 78 return; 79 80 g_signal_connect(wavParser, "pad-added", G_CALLBACK(onGStreamerWavparsePadAddedCallback), this); 81 gst_bin_add_many(GST_BIN(m_pipeline), webkitAudioSrc, wavParser, NULL); 82 gst_element_link_pads_full(webkitAudioSrc, "src", wavParser, "sink", GST_PAD_LINK_CHECK_NOTHING); 47 83 } 48 84 49 85 AudioDestinationGStreamer::~AudioDestinationGStreamer() 50 86 { 87 gst_element_set_state(m_pipeline, GST_STATE_NULL); 88 gst_object_unref(m_pipeline); 89 } 90 91 void AudioDestinationGStreamer::finishBuildingPipelineAfterWavParserPadReady(GstPad* pad) 92 { 93 ASSERT(m_wavParserAvailable); 94 95 GRefPtr<GstElement> audioSink = gst_element_factory_make("autoaudiosink", 0); 96 m_audioSinkAvailable = audioSink; 97 98 if (!audioSink) { 99 LOG_ERROR("Failed to create GStreamer autoaudiosink element"); 100 return; 101 } 102 103 // Autoaudiosink does the real sink detection in the GST_STATE_NULL->READY transition 104 // so it's best to roll it to READY as soon as possible to ensure the underlying platform 105 // audiosink was loaded correctly. 106 GstStateChangeReturn stateChangeReturn = gst_element_set_state(audioSink.get(), GST_STATE_READY); 107 if (stateChangeReturn == GST_STATE_CHANGE_FAILURE) { 108 LOG_ERROR("Failed to change autoaudiosink element state"); 109 gst_element_set_state(audioSink.get(), GST_STATE_NULL); 110 m_audioSinkAvailable = false; 111 return; 112 } 113 114 GstElement* audioConvert = gst_element_factory_make("audioconvert", 0); 115 gst_bin_add_many(GST_BIN(m_pipeline), audioConvert, audioSink.get(), NULL); 116 117 // Link wavparse's src pad to audioconvert sink pad. 118 GRefPtr<GstPad> sinkPad = adoptGRef(gst_element_get_static_pad(audioConvert, "sink")); 119 gst_pad_link(pad, sinkPad.get()); 120 121 // Link audioconvert to audiosink and roll states. 122 gst_element_link_pads_full(audioConvert, "src", audioSink.get(), "sink", GST_PAD_LINK_CHECK_NOTHING); 123 gst_element_sync_state_with_parent(audioConvert); 124 gst_element_sync_state_with_parent(audioSink.leakRef()); 51 125 } 52 126 53 127 void AudioDestinationGStreamer::start() 54 128 { 129 ASSERT(m_wavParserAvailable); 130 if (!m_wavParserAvailable) 131 return; 132 133 gst_element_set_state(m_pipeline, GST_STATE_PLAYING); 55 134 m_isPlaying = true; 56 135 } … … 58 137 void AudioDestinationGStreamer::stop() 59 138 { 139 ASSERT(m_wavParserAvailable && m_audioSinkAvailable); 140 if (!m_wavParserAvailable || m_audioSinkAvailable) 141 return; 142 143 gst_element_set_state(m_pipeline, GST_STATE_PAUSED); 60 144 m_isPlaying = false; 61 145 } -
trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.h
r98554 r101138 23 23 #include "AudioDestination.h" 24 24 25 typedef struct _GstElement GstElement; 26 typedef struct _GstPad GstPad; 27 25 28 namespace WebCore { 26 29 … … 37 40 AudioSourceProvider& sourceProvider() const { return m_provider; } 38 41 42 void finishBuildingPipelineAfterWavParserPadReady(GstPad*); 43 39 44 private: 40 45 AudioSourceProvider& m_provider; … … 43 48 float m_sampleRate; 44 49 bool m_isPlaying; 50 bool m_wavParserAvailable; 51 bool m_audioSinkAvailable; 52 GstElement* m_pipeline; 45 53 }; 46 54 -
trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp
r101130 r101138 82 82 } 83 83 84 85 template <> GRefPtr<GstTask> adoptGRef(GstTask* ptr) 86 { 87 ASSERT(!GST_OBJECT_IS_FLOATING(GST_OBJECT(ptr))); 88 return GRefPtr<GstTask>(ptr, GRefPtrAdopt); 89 } 90 91 template <> GstTask* refGPtr<GstTask>(GstTask* ptr) 92 { 93 if (ptr) { 94 gst_object_ref(GST_OBJECT(ptr)); 95 gst_object_sink(GST_OBJECT(ptr)); 96 } 97 98 return ptr; 99 } 100 101 template <> void derefGPtr<GstTask>(GstTask* ptr) 102 { 103 if (ptr) 104 gst_object_unref(ptr); 105 } 106 84 107 } 85 108 #endif // USE(GSTREAMER) -
trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h
r101082 r101138 27 27 typedef struct _GstPad GstPad; 28 28 typedef struct _GstCaps GstCaps; 29 typedef struct _GstTask GstTask; 29 30 30 31 namespace WTF { … … 41 42 template<> void derefGPtr<GstCaps>(GstCaps* ptr); 42 43 44 template<> GRefPtr<GstTask> adoptGRef(GstTask* ptr); 45 template<> GstTask* refGPtr<GstTask>(GstTask* ptr); 46 template<> void derefGPtr<GstTask>(GstTask* ptr); 47 43 48 } 44 49
Note: See TracChangeset
for help on using the changeset viewer.