Changeset 271290 in webkit
- Timestamp:
- Jan 8, 2021, 5:16:25 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/platform/glib/TestExpectations (modified) (1 diff)
-
LayoutTests/platform/gtk-wayland/TestExpectations (modified) (1 diff)
-
LayoutTests/platform/gtk/TestExpectations (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/platform/audio/gstreamer/AudioSourceProviderGStreamer.cpp (modified) (8 diffs)
-
Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp (modified) (1 diff)
-
Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r271284 r271290 1 2021-01-08 Philippe Normand <pnormand@igalia.com> 2 3 [GStreamer] WebAudio provider should clean-up its bin when the client disappears 4 https://bugs.webkit.org/show_bug.cgi?id=219245 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 Unflag tests no longer crashing. 9 10 * platform/glib/TestExpectations: 11 * platform/gtk-wayland/TestExpectations: 12 * platform/gtk/TestExpectations: 13 1 14 2021-01-07 Zalan Bujtas <zalan@apple.com> 2 15 -
trunk/LayoutTests/platform/glib/TestExpectations
r271196 r271290 452 452 453 453 webkit.org/b/218580 fast/mediastream/captureStream/canvas2d.html [ Failure Timeout ] 454 455 webkit.org/b/219245 webrtc/audio-replace-track.html [ Crash ]456 webkit.org/b/219245 webrtc/peer-connection-audio-mute.html [ Crash ]457 webkit.org/b/219245 webrtc/peer-connection-audio-mute2.html [ Crash ]458 webkit.org/b/219245 webrtc/peer-connection-audio-unmute.html [ Crash ]459 webkit.org/b/219245 webrtc/peer-connection-remote-audio-mute.html [ Crash ]460 webkit.org/b/219245 webrtc/peer-connection-remote-audio-mute2.html [ Crash ]461 454 462 455 #//////////////////////////////////////////////////////////////////////////////////////// -
trunk/LayoutTests/platform/gtk-wayland/TestExpectations
r270242 r271290 33 33 34 34 # WebRTC 35 webkit.org/b/21 9245 webkit.org/b/212892 webrtc/peer-connection-audio-mute2.html [ Failure Timeout Pass Crash ]35 webkit.org/b/212892 webrtc/peer-connection-audio-mute2.html [ Failure Timeout Pass Crash ] 36 36 37 37 # Workers -
trunk/LayoutTests/platform/gtk/TestExpectations
r271142 r271290 1405 1405 webkit.org/b/193311 fast/images/decode-render-animated-image.html [ ImageOnlyFailure Pass ] 1406 1406 1407 webkit.org/b/193318 web kit.org/b/219245 webrtc/audio-replace-track.html [ Timeout Pass Crash]1407 webkit.org/b/193318 webrtc/audio-replace-track.html [ Timeout Pass ] 1408 1408 1409 1409 webkit.org/b/193490 [ Debug ] animations/play-state-suspend.html [ Pass Failure ] -
trunk/Source/WebCore/ChangeLog
r271289 r271290 1 2021-01-08 Philippe Normand <pnormand@igalia.com> 2 3 [GStreamer] WebAudio provider should clean-up its bin when the client disappears 4 https://bugs.webkit.org/show_bug.cgi?id=219245 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 Clean-up elements downstream of the deinterleave element when the provider client changes or 9 is removed. 10 11 * platform/audio/gstreamer/AudioSourceProviderGStreamer.cpp: 12 (WebCore::copyGStreamerBuffersToAudioChannel): 13 (WebCore::AudioSourceProviderGStreamer::provideInput): 14 (WebCore::AudioSourceProviderGStreamer::handleSample): 15 (WebCore::AudioSourceProviderGStreamer::setClient): 16 (WebCore::AudioSourceProviderGStreamer::handleRemovedDeinterleavePad): 17 (WebCore::AudioSourceProviderGStreamer::deinterleavePadsConfigured): 18 * platform/graphics/gstreamer/GStreamerCommon.cpp: 19 (WebCore::disconnectSimpleBusMessageCallback): Drive-by, remove bus signal handler. 20 (WebCore::connectSimpleBusMessageCallback): 21 * platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp: Drive-by, define 22 GST_CAT_DEFAULT earlier so that all GST_DEBUG call sites actually log something. 23 1 24 2021-01-08 Xabier Rodriguez Calvar <calvaris@igalia.com> 2 25 -
trunk/Source/WebCore/platform/audio/gstreamer/AudioSourceProviderGStreamer.cpp
r270184 r271290 68 68 auto available = gst_adapter_available(adapter); 69 69 if (!available) { 70 GST_TRACE("Adapter empty, silencing bus"); 70 71 bus->zero(); 71 72 return; 72 73 } 73 74 75 GST_TRACE("%zu samples available for channel %d (%zu frames requested)", available, channelNumber, framesToProcess); 74 76 size_t bytes = framesToProcess * sizeof(float); 75 77 if (available >= bytes) { … … 151 153 void AudioSourceProviderGStreamer::provideInput(AudioBus* bus, size_t framesToProcess) 152 154 { 155 GST_TRACE("Fetching buffers from adapters"); 153 156 auto locker = holdLock(m_adapterMutex); 154 157 for (auto& it : m_adapters) … … 158 161 GstFlowReturn AudioSourceProviderGStreamer::handleSample(GstAppSink* sink, bool isPreroll) 159 162 { 163 GST_TRACE("Pulling audio sample from the sink"); 160 164 auto sample = adoptGRef(isPreroll ? gst_app_sink_try_pull_preroll(sink, 0) : gst_app_sink_try_pull_sample(sink, 0)); 161 165 if (!sample) … … 169 173 return GST_FLOW_ERROR; 170 174 175 GST_TRACE("Storing audio sample %" GST_PTR_FORMAT, sample.get()); 171 176 { 172 177 auto locker = holdLock(m_adapterMutex); 173 178 GQuark quark = g_quark_from_static_string("channel-id"); 174 179 int channelId = GPOINTER_TO_INT(g_object_get_qdata(G_OBJECT(sink), quark)); 180 GST_DEBUG("Channel ID: %d", channelId); 181 175 182 auto result = m_adapters.ensure(channelId, [&] { 176 183 return gst_adapter_new(); … … 190 197 return; 191 198 199 GST_DEBUG("Setting up client %p (previous: %p)", client, m_client); 200 bool previousClientWasValid = m_client; 192 201 m_client = client; 193 194 #if ENABLE(MEDIA_STREAM)195 if (m_pipeline)196 gst_element_set_state(m_pipeline.get(), m_client ? GST_STATE_PLAYING : GST_STATE_NULL);197 #endif198 199 // FIXME: This early return should ideally be replaced by a removal of the m_audioSinkBin from200 // its parent pipeline. https://bugs.webkit.org/show_bug.cgi?id=219245201 if (!m_client)202 return;203 202 204 203 // The volume element is used to mute audio playback towards the … … 208 207 auto volumeElement = adoptGRef(gst_bin_get_by_name(GST_BIN_CAST(m_audioSinkBin.get()), "volume")); 209 208 210 if (volumeElement) 211 g_object_set(volumeElement.get(), "mute", TRUE, nullptr); 212 213 // The audioconvert and audioresample elements are needed to 214 // ensure deinterleave and the sinks downstream receive buffers in 215 // the format specified by the capsfilter. 216 GstElement* audioQueue = gst_element_factory_make("queue", nullptr); 217 GstElement* audioConvert = gst_element_factory_make("audioconvert", nullptr); 218 GstElement* audioResample = gst_element_factory_make("audioresample", nullptr); 219 GstElement* capsFilter = gst_element_factory_make("capsfilter", nullptr); 220 GstElement* deInterleave = gst_element_factory_make("deinterleave", "deinterleave"); 221 222 g_object_set(deInterleave, "keep-positions", TRUE, nullptr); 223 m_deinterleavePadAddedHandlerId = g_signal_connect(deInterleave, "pad-added", G_CALLBACK(onGStreamerDeinterleavePadAddedCallback), this); 224 m_deinterleaveNoMorePadsHandlerId = g_signal_connect(deInterleave, "no-more-pads", G_CALLBACK(onGStreamerDeinterleaveReadyCallback), this); 225 m_deinterleavePadRemovedHandlerId = g_signal_connect(deInterleave, "pad-removed", G_CALLBACK(onGStreamerDeinterleavePadRemovedCallback), this); 226 227 auto caps = adoptGRef(gst_caps_new_simple("audio/x-raw", "rate", G_TYPE_INT, static_cast<int>(gSampleBitRate), 228 "format", G_TYPE_STRING, GST_AUDIO_NE(F32), "layout", G_TYPE_STRING, "interleaved", nullptr)); 229 g_object_set(capsFilter, "caps", caps.get(), nullptr); 230 231 gst_bin_add_many(GST_BIN_CAST(m_audioSinkBin.get()), audioQueue, audioConvert, audioResample, capsFilter, deInterleave, nullptr); 232 233 auto audioTee = adoptGRef(gst_bin_get_by_name(GST_BIN(m_audioSinkBin.get()), "audioTee")); 234 235 // Link a new src pad from tee to queue ! audioconvert ! 236 // audioresample ! capsfilter ! deinterleave. Later 237 // on each deinterleaved planar audio channel will be routed to an 238 // appsink for data extraction and processing. 239 gst_element_link_pads_full(audioTee.get(), "src_%u", audioQueue, "sink", GST_PAD_LINK_CHECK_NOTHING); 240 gst_element_link_pads_full(audioQueue, "src", audioConvert, "sink", GST_PAD_LINK_CHECK_NOTHING); 241 gst_element_link_pads_full(audioConvert, "src", audioResample, "sink", GST_PAD_LINK_CHECK_NOTHING); 242 gst_element_link_pads_full(audioResample, "src", capsFilter, "sink", GST_PAD_LINK_CHECK_NOTHING); 243 gst_element_link_pads_full(capsFilter, "src", deInterleave, "sink", GST_PAD_LINK_CHECK_NOTHING); 244 245 gst_element_sync_state_with_parent(audioQueue); 246 gst_element_sync_state_with_parent(audioConvert); 247 gst_element_sync_state_with_parent(audioResample); 248 gst_element_sync_state_with_parent(capsFilter); 249 gst_element_sync_state_with_parent(deInterleave); 209 if (volumeElement) { 210 bool shouldMute = m_client; 211 g_object_set(volumeElement.get(), "mute", shouldMute, nullptr); 212 } 213 214 auto audioTee = adoptGRef(gst_bin_get_by_name(GST_BIN_CAST(m_audioSinkBin.get()), "audioTee")); 215 if (!m_client || previousClientWasValid) { 216 auto audioQueue = adoptGRef(gst_bin_get_by_name(GST_BIN_CAST(m_audioSinkBin.get()), "queue")); 217 auto audioConvert = adoptGRef(gst_bin_get_by_name(GST_BIN_CAST(m_audioSinkBin.get()), "audioconvert")); 218 auto audioResample = adoptGRef(gst_bin_get_by_name(GST_BIN_CAST(m_audioSinkBin.get()), "audioresample")); 219 auto capsFilter = adoptGRef(gst_bin_get_by_name(GST_BIN_CAST(m_audioSinkBin.get()), "capsfilter")); 220 auto deInterleave = adoptGRef(gst_bin_get_by_name(GST_BIN_CAST(m_audioSinkBin.get()), "deinterleave")); 221 auto queueSinkPad = adoptGRef(gst_element_get_static_pad(audioQueue.get(), "sink")); 222 auto teeSrcPad = adoptGRef(gst_pad_get_peer(queueSinkPad.get())); 223 224 GST_DEBUG("Cleaning up audio deinterleave chain"); 225 gst_element_set_locked_state(m_audioSinkBin.get(), true); 226 227 gst_element_set_state(audioQueue.get(), GST_STATE_NULL); 228 gst_element_set_state(audioConvert.get(), GST_STATE_NULL); 229 gst_element_set_state(audioResample.get(), GST_STATE_NULL); 230 gst_element_set_state(capsFilter.get(), GST_STATE_NULL); 231 gst_element_set_state(deInterleave.get(), GST_STATE_NULL); 232 gst_element_unlink_many(audioTee.get(), audioQueue.get(), audioConvert.get(), audioResample.get(), capsFilter.get(), deInterleave.get(), nullptr); 233 gst_element_set_locked_state(m_audioSinkBin.get(), false); 234 gst_bin_remove_many(GST_BIN_CAST(m_audioSinkBin.get()), audioQueue.get(), audioConvert.get(), audioResample.get(), capsFilter.get(), deInterleave.get(), nullptr); 235 gst_element_release_request_pad(audioTee.get(), teeSrcPad.get()); 236 } 237 238 if (m_client) { 239 // The audioconvert and audioresample elements are needed to 240 // ensure deinterleave and the sinks downstream receive buffers in 241 // the format specified by the capsfilter. 242 auto* audioQueue = gst_element_factory_make("queue", "queue"); 243 auto* audioConvert = gst_element_factory_make("audioconvert", "audioconvert"); 244 auto* audioResample = gst_element_factory_make("audioresample", "audioresample"); 245 auto* capsFilter = gst_element_factory_make("capsfilter", "capsfilter"); 246 auto* deInterleave = gst_element_factory_make("deinterleave", "deinterleave"); 247 248 GST_DEBUG("Setting up audio deinterleave chain"); 249 g_object_set(deInterleave, "keep-positions", TRUE, nullptr); 250 m_deinterleavePadAddedHandlerId = g_signal_connect(deInterleave, "pad-added", G_CALLBACK(onGStreamerDeinterleavePadAddedCallback), this); 251 m_deinterleaveNoMorePadsHandlerId = g_signal_connect(deInterleave, "no-more-pads", G_CALLBACK(onGStreamerDeinterleaveReadyCallback), this); 252 m_deinterleavePadRemovedHandlerId = g_signal_connect(deInterleave, "pad-removed", G_CALLBACK(onGStreamerDeinterleavePadRemovedCallback), this); 253 254 auto caps = adoptGRef(gst_caps_new_simple("audio/x-raw", "rate", G_TYPE_INT, static_cast<int>(gSampleBitRate), 255 "format", G_TYPE_STRING, GST_AUDIO_NE(F32), "layout", G_TYPE_STRING, "interleaved", nullptr)); 256 g_object_set(capsFilter, "caps", caps.get(), nullptr); 257 258 gst_bin_add_many(GST_BIN_CAST(m_audioSinkBin.get()), audioQueue, audioConvert, audioResample, capsFilter, deInterleave, nullptr); 259 260 // Link a new src pad from tee to queue ! audioconvert ! 261 // audioresample ! capsfilter ! deinterleave. Later 262 // on each deinterleaved planar audio channel will be routed to an 263 // appsink for data extraction and processing. 264 gst_element_link_pads_full(audioTee.get(), "src_%u", audioQueue, "sink", GST_PAD_LINK_CHECK_NOTHING); 265 gst_element_link_pads_full(audioQueue, "src", audioConvert, "sink", GST_PAD_LINK_CHECK_NOTHING); 266 gst_element_link_pads_full(audioConvert, "src", audioResample, "sink", GST_PAD_LINK_CHECK_NOTHING); 267 gst_element_link_pads_full(audioResample, "src", capsFilter, "sink", GST_PAD_LINK_CHECK_NOTHING); 268 gst_element_link_pads_full(capsFilter, "src", deInterleave, "sink", GST_PAD_LINK_CHECK_NOTHING); 269 270 gst_element_sync_state_with_parent(audioQueue); 271 gst_element_sync_state_with_parent(audioConvert); 272 gst_element_sync_state_with_parent(audioResample); 273 gst_element_sync_state_with_parent(capsFilter); 274 gst_element_sync_state_with_parent(deInterleave); 275 } 276 277 m_deinterleaveSourcePads = 0; 278 clearAdapters(); 279 #if ENABLE(MEDIA_STREAM) 280 if (m_pipeline) 281 gst_element_set_state(m_pipeline.get(), m_client ? GST_STATE_PLAYING : GST_STATE_NULL); 282 #endif 250 283 } 251 284 … … 306 339 void AudioSourceProviderGStreamer::handleRemovedDeinterleavePad(GstPad* pad) 307 340 { 341 if (GST_PAD_DIRECTION(pad) != GST_PAD_SRC) 342 return; 343 308 344 GST_DEBUG("Pad %" GST_PTR_FORMAT " gone", pad); 309 345 m_deinterleaveSourcePads--; … … 321 357 void AudioSourceProviderGStreamer::deinterleavePadsConfigured() 322 358 { 323 GST_DEBUG("Deinterleave configured , notifying client");359 GST_DEBUG("Deinterleave configured with %d channels, notifying client", m_deinterleaveSourcePads); 324 360 m_notifier->notify(MainThreadNotification::DeinterleavePadsConfigured, [numberOfChannels = m_deinterleaveSourcePads, sampleRate = gSampleBitRate, client = m_client] { 325 361 if (client) -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp
r271197 r271290 405 405 void disconnectSimpleBusMessageCallback(GstElement* pipeline) 406 406 { 407 GRefPtr<GstBus>bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(pipeline)));407 auto bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(pipeline))); 408 408 g_signal_handlers_disconnect_by_func(bus.get(), reinterpret_cast<gpointer>(simpleBusMessageCallback), pipeline); 409 gst_bus_remove_signal_watch(bus.get()); 409 410 } 410 411 411 412 void connectSimpleBusMessageCallback(GstElement* pipeline) 412 413 { 413 GRefPtr<GstBus>bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(pipeline)));414 auto bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(pipeline))); 414 415 gst_bus_add_signal_watch_full(bus.get(), RunLoopSourcePriority::RunLoopDispatcher); 415 416 g_signal_connect(bus.get(), "message", G_CALLBACK(simpleBusMessageCallback), pipeline); -
trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp
r270906 r271290 52 52 GST_STATIC_CAPS("audio/x-raw(ANY);")); 53 53 54 GST_DEBUG_CATEGORY_STATIC(webkitMediaStreamSrcDebug); 55 #define GST_CAT_DEFAULT webkitMediaStreamSrcDebug 56 54 57 GRefPtr<GstTagList> mediaStreamTrackPrivateGetTags(MediaStreamTrackPrivate* track) 55 58 { … … 305 308 } 306 309 307 GST_DEBUG_CATEGORY_STATIC(webkitMediaStreamSrcDebug);308 #define GST_CAT_DEFAULT webkitMediaStreamSrcDebug309 310 310 #define doInit \ 311 311 G_IMPLEMENT_INTERFACE(GST_TYPE_URI_HANDLER, webkitMediaStreamSrcUriHandlerInit); \
Note:
See TracChangeset
for help on using the changeset viewer.