Changeset 111119 in webkit
- Timestamp:
- Mar 17, 2012 4:30:21 AM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r111118 r111119 1 2012-03-12 Philippe Normand <pnormand@igalia.com> 2 3 [GStreamer] run AudioFileReader in a nested loop 4 https://bugs.webkit.org/show_bug.cgi?id=80823 5 6 Reviewed by Martin Robinson. 7 8 Use a separate main loop for the file reader, this approach is 9 much cleaner than polling the default GLib main context. 10 11 * platform/audio/gstreamer/AudioFileReaderGStreamer.cpp: 12 (AudioFileReader): 13 (WebCore::enteredMainLoopCallback): 14 (WebCore): 15 (WebCore::AudioFileReader::AudioFileReader): 16 (WebCore::AudioFileReader::handleMessage): 17 (WebCore::AudioFileReader::start): 18 (WebCore::AudioFileReader::createBus): 19 1 20 2012-02-07 Robert Hogan <robert@webkit.org> 2 21 -
trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp
r105626 r111119 1 1 /* 2 * Copyright (C) 2011 Igalia S.L2 * Copyright (C) 2011, 2012 Igalia S.L 3 3 * Copyright (C) 2011 Zan Dobersek <zandobersek@gmail.com> 4 4 * … … 25 25 26 26 #include "AudioBus.h" 27 #include "GOwnPtr.h"28 #include "GRefPtr.h"29 27 #include <gio/gio.h> 30 28 #include <gst/app/gstappsink.h> … … 34 32 #include <wtf/Noncopyable.h> 35 33 #include <wtf/PassOwnPtr.h> 34 #include <wtf/gobject/GOwnPtr.h> 35 #include <wtf/gobject/GRefPtr.h> 36 36 37 37 namespace WebCore { … … 51 51 void deinterleavePadsConfigured(); 52 52 void plugDeinterleave(GstPad*); 53 void decodeAudioForBusCreation(); 53 54 54 55 private: … … 63 64 GstBufferListIterator* m_frontRightBuffersIterator; 64 65 GstElement* m_pipeline; 65 bool m_eos;66 66 unsigned m_channelSize; 67 68 gulong m_deinterleavePadAddedSignalHandlerId;69 gulong m_deinterleaveNoMorePadSignalHandlerId;67 GRefPtr<GstElement> m_decodebin; 68 GRefPtr<GstElement> m_deInterleave; 69 GRefPtr<GMainLoop> m_loop; 70 70 }; 71 71 … … 113 113 } 114 114 115 gboolean enteredMainLoopCallback(gpointer userData) 116 { 117 AudioFileReader* reader = reinterpret_cast<AudioFileReader*>(userData); 118 reader->decodeAudioForBusCreation(); 119 return FALSE; 120 } 121 115 122 AudioFileReader::AudioFileReader(const char* filePath) 116 123 : m_data(0) 117 124 , m_dataSize(0) 118 125 , m_filePath(filePath) 119 , m_ eos(false)126 , m_channelSize(0) 120 127 { 121 128 } … … 125 132 , m_dataSize(dataSize) 126 133 , m_filePath(0) 127 , m_ eos(false)134 , m_channelSize(0) 128 135 { 129 136 } … … 177 184 switch (GST_MESSAGE_TYPE(message)) { 178 185 case GST_MESSAGE_EOS: 179 m_eos = true;186 g_main_loop_quit(m_loop.get()); 180 187 break; 181 188 case GST_MESSAGE_WARNING: … … 242 249 GstElement* audioResample = gst_element_factory_make("audioresample", 0); 243 250 GstElement* capsFilter = gst_element_factory_make("capsfilter", 0); 244 GstElement*deInterleave = gst_element_factory_make("deinterleave", "deinterleave");245 246 g_object_set( deInterleave, "keep-positions", TRUE, NULL);247 m_deinterleavePadAddedSignalHandlerId = g_signal_connect(deInterleave, "pad-added", G_CALLBACK(onGStreamerDeinterleavePadAddedCallback), this);248 m_deinterleaveNoMorePadSignalHandlerId = g_signal_connect(deInterleave, "no-more-pads", G_CALLBACK(onGStreamerDeinterleaveReadyCallback), this);251 m_deInterleave = gst_element_factory_make("deinterleave", "deinterleave"); 252 253 g_object_set(m_deInterleave.get(), "keep-positions", TRUE, NULL); 254 g_signal_connect(m_deInterleave.get(), "pad-added", G_CALLBACK(onGStreamerDeinterleavePadAddedCallback), this); 255 g_signal_connect(m_deInterleave.get(), "no-more-pads", G_CALLBACK(onGStreamerDeinterleaveReadyCallback), this); 249 256 250 257 GstCaps* caps = getGStreamerAudioCaps(2, m_sampleRate); … … 252 259 gst_caps_unref(caps); 253 260 254 gst_bin_add_many(GST_BIN(m_pipeline), audioConvert, audioResample, capsFilter, deInterleave, NULL);261 gst_bin_add_many(GST_BIN(m_pipeline), audioConvert, audioResample, capsFilter, m_deInterleave.get(), NULL); 255 262 256 263 GstPad* sinkPad = gst_element_get_static_pad(audioConvert, "sink"); … … 260 267 gst_element_link_pads_full(audioConvert, "src", audioResample, "sink", GST_PAD_LINK_CHECK_NOTHING); 261 268 gst_element_link_pads_full(audioResample, "src", capsFilter, "sink", GST_PAD_LINK_CHECK_NOTHING); 262 gst_element_link_pads_full(capsFilter, "src", deInterleave, "sink", GST_PAD_LINK_CHECK_NOTHING);269 gst_element_link_pads_full(capsFilter, "src", m_deInterleave.get(), "sink", GST_PAD_LINK_CHECK_NOTHING); 263 270 264 271 gst_element_sync_state_with_parent(audioConvert); 265 272 gst_element_sync_state_with_parent(audioResample); 266 273 gst_element_sync_state_with_parent(capsFilter); 267 gst_element_sync_state_with_parent(deInterleave); 268 } 269 270 271 PassOwnPtr<AudioBus> AudioFileReader::createBus(float sampleRate, bool mixToMono) 272 { 273 m_sampleRate = sampleRate; 274 275 static bool gstInitialized = false; 276 if (!gstInitialized) 277 gstInitialized = gst_init_check(0, 0, 0); 278 279 if (!gstInitialized) 280 return nullptr; 281 282 m_frontLeftBuffers = gst_buffer_list_new(); 283 m_frontLeftBuffersIterator = gst_buffer_list_iterate(m_frontLeftBuffers); 284 gst_buffer_list_iterator_add_group(m_frontLeftBuffersIterator); 285 286 m_frontRightBuffers = gst_buffer_list_new(); 287 m_frontRightBuffersIterator = gst_buffer_list_iterate(m_frontRightBuffers); 288 gst_buffer_list_iterator_add_group(m_frontRightBuffersIterator); 289 274 gst_element_sync_state_with_parent(m_deInterleave.get()); 275 } 276 277 void AudioFileReader::decodeAudioForBusCreation() 278 { 290 279 // Build the pipeline (giostreamsrc | filesrc) ! decodebin2 291 280 // A deinterleave element is added once a src pad becomes available in decodebin. 292 281 m_pipeline = gst_pipeline_new(0); 293 282 294 G stBus* bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline));295 gst_bus_add_signal_watch(bus );296 g ulong busSignalHandlerId = g_signal_connect(bus, "message", G_CALLBACK(messageCallback), this);283 GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline))); 284 gst_bus_add_signal_watch(bus.get()); 285 g_signal_connect(bus.get(), "message", G_CALLBACK(messageCallback), this); 297 286 298 287 GstElement* source; … … 307 296 } 308 297 309 GstElement* decodebin = gst_element_factory_make("decodebin2", "decodebin"); 310 gulong decodebinPadAddedSignalHandlerId = g_signal_connect(decodebin, "pad-added", G_CALLBACK(onGStreamerDecodebinPadAddedCallback), this); 311 312 gst_bin_add_many(GST_BIN(m_pipeline), source, decodebin, NULL); 313 gst_element_link_pads_full(source, "src", decodebin, "sink", GST_PAD_LINK_CHECK_NOTHING); 314 315 m_eos = false; 316 m_channelSize = 0; 298 m_decodebin = gst_element_factory_make("decodebin2", "decodebin"); 299 g_signal_connect(m_decodebin.get(), "pad-added", G_CALLBACK(onGStreamerDecodebinPadAddedCallback), this); 300 301 gst_bin_add_many(GST_BIN(m_pipeline), source, m_decodebin.get(), NULL); 302 gst_element_link_pads_full(source, "src", m_decodebin.get(), "sink", GST_PAD_LINK_CHECK_NOTHING); 317 303 gst_element_set_state(m_pipeline, GST_STATE_PAUSED); 318 while (!m_eos) 319 g_main_context_iteration(0, FALSE); 320 321 g_signal_handler_disconnect(bus, busSignalHandlerId); 322 gst_object_unref(bus); 323 324 g_signal_handler_disconnect(decodebin, decodebinPadAddedSignalHandlerId); 325 326 if (GstElement* deinterleave = gst_bin_get_by_name(GST_BIN(m_pipeline), "deinterleave")) { 327 if (g_signal_handler_is_connected(deinterleave, m_deinterleavePadAddedSignalHandlerId)) 328 g_signal_handler_disconnect(deinterleave, m_deinterleavePadAddedSignalHandlerId); 329 if (g_signal_handler_is_connected(deinterleave, m_deinterleaveNoMorePadSignalHandlerId)) 330 g_signal_handler_disconnect(deinterleave, m_deinterleaveNoMorePadSignalHandlerId); 331 gst_object_unref(deinterleave); 332 } 304 } 305 306 PassOwnPtr<AudioBus> AudioFileReader::createBus(float sampleRate, bool mixToMono) 307 { 308 m_sampleRate = sampleRate; 309 310 static bool gstInitialized = false; 311 if (!gstInitialized) 312 gstInitialized = gst_init_check(0, 0, 0); 313 314 if (!gstInitialized) 315 return nullptr; 316 317 m_frontLeftBuffers = gst_buffer_list_new(); 318 m_frontLeftBuffersIterator = gst_buffer_list_iterate(m_frontLeftBuffers); 319 gst_buffer_list_iterator_add_group(m_frontLeftBuffersIterator); 320 321 m_frontRightBuffers = gst_buffer_list_new(); 322 m_frontRightBuffersIterator = gst_buffer_list_iterate(m_frontRightBuffers); 323 gst_buffer_list_iterator_add_group(m_frontRightBuffersIterator); 324 325 GRefPtr<GMainContext> context = g_main_context_new(); 326 g_main_context_push_thread_default(context.get()); 327 m_loop = adoptGRef(g_main_loop_new(context.get(), FALSE)); 328 329 // Start the pipeline processing just after the loop is started. 330 GSource* timeoutSource = g_timeout_source_new(0); 331 g_source_attach(timeoutSource, context.get()); 332 g_source_set_callback(timeoutSource, reinterpret_cast<GSourceFunc>(enteredMainLoopCallback), this, 0); 333 334 g_main_loop_run(m_loop.get()); 335 g_main_context_pop_thread_default(context.get()); 336 337 GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline))); 338 g_signal_handlers_disconnect_by_func(bus.get(), reinterpret_cast<gpointer>(messageCallback), this); 339 340 g_signal_handlers_disconnect_by_func(m_decodebin.get(), reinterpret_cast<gpointer>(onGStreamerDecodebinPadAddedCallback), this); 341 g_signal_handlers_disconnect_by_func(m_deInterleave.get(), reinterpret_cast<gpointer>(onGStreamerDeinterleavePadAddedCallback), this); 342 g_signal_handlers_disconnect_by_func(m_deInterleave.get(), reinterpret_cast<gpointer>(onGStreamerDeinterleaveReadyCallback), this); 333 343 334 344 unsigned channels = mixToMono ? 1 : 2; … … 348 358 gst_object_unref(GST_OBJECT(m_pipeline)); 349 359 360 m_decodebin.clear(); 361 m_deInterleave.clear(); 350 362 return audioBus.release(); 351 363 } -
trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp
r109005 r111119 121 121 } 122 122 123 template <> GRefPtr<GstBus> adoptGRef(GstBus* ptr) 124 { 125 ASSERT(!GST_OBJECT_IS_FLOATING(GST_OBJECT(ptr))); 126 return GRefPtr<GstBus>(ptr, GRefPtrAdopt); 127 } 128 129 template <> GstBus* refGPtr<GstBus>(GstBus* ptr) 130 { 131 if (ptr) 132 webkitGstObjectRefSink(GST_OBJECT(ptr)); 133 134 return ptr; 135 } 136 137 template <> void derefGPtr<GstBus>(GstBus* ptr) 138 { 139 if (ptr) 140 gst_object_unref(ptr); 141 } 142 123 143 } 124 144 #endif // USE(GSTREAMER) -
trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h
r102791 r111119 29 29 typedef struct _GstCaps GstCaps; 30 30 typedef struct _GstTask GstTask; 31 typedef struct _GstBus GstBus; 31 32 32 33 namespace WTF { … … 51 52 template<> void derefGPtr<GstTask>(GstTask* ptr); 52 53 54 template<> GRefPtr<GstBus> adoptGRef(GstBus* ptr); 55 template<> GstBus* refGPtr<GstBus>(GstBus* ptr); 56 template<> void derefGPtr<GstBus>(GstBus* ptr); 57 53 58 } 54 59
Note: See TracChangeset
for help on using the changeset viewer.