Summary: | [GStreamer][MediaStream] Capture pipeline remains active after track was stopped | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | James Hilliard <james.hilliard1> | ||||||||||
Component: | WPE WebKit | Assignee: | Nobody <webkit-unassigned> | ||||||||||
Status: | RESOLVED FIXED | ||||||||||||
Severity: | Normal | CC: | bugs-noreply, james.hilliard1, mcatanzaro, pnormand | ||||||||||
Priority: | P2 | ||||||||||||
Version: | WebKit Nightly Build | ||||||||||||
Hardware: | Other | ||||||||||||
OS: | Linux | ||||||||||||
Attachments: |
|
I can't find a `close()` method in MediaStream.idl. Can you share the test-case you're using? In case the stream is rendered to a <video>, are you pausing it and clearing its src? Created attachment 460216 [details]
reproducer(react.js based component)
Oh, wasn't close(), I'm calling stop() on the tracks like this when closing the component: if (stream) { stream.getTracks().forEach((track) => { track.stop(); }); } Probably easiest way to reproduce is just by toggling the opening and stopping the camera in: https://mozilla.github.io/webrtc-landing/gum_test.html Checking the log, I suspect the capturer pipeline is not stopped indeed. In GStreamerCapturer::~GStreamerCapturer() I think we should set the pipeline to null state. Can you try this? diff --git a/Source/WebCore/platform/mediastream/gstreamer/GStreamerCapturer.cpp b/Source/WebCore/platform/mediastream/gstreamer/GStreamerCapturer.cpp index 9e008d8f46a6..fe30d7f06ce9 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/GStreamerCapturer.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/GStreamerCapturer.cpp @@ -67,8 +67,11 @@ GStreamerCapturer::GStreamerCapturer(const char* sourceFactory, GRefPtr<GstCaps> GStreamerCapturer::~GStreamerCapturer() { - if (m_pipeline) - disconnectSimpleBusMessageCallback(pipeline()); + if (!m_pipeline) + return; + + gst_element_set_state(m_pipeline.get(), GST_STATE_NULL); + disconnectSimpleBusMessageCallback(m_pipeline.get()); } GStreamerCapturer::Observer::~Observer() Created attachment 460227 [details]
with null pipeline patch
Doesn't seem to have fixed it, added new log with patch applied.
OK then this will need further investigation. I wonder if the gst_element_set_state call isn't propagating properly due to the gst_bin_remove call: https://github.com/WebKit/WebKit/blob/dd956d5e74249681ddf904e0bbe401f308b65e0f/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp#L796-L797 Created attachment 460229 [details]
full debug enabled logs
(In reply to James Hilliard from comment #8) > I wonder if the gst_element_set_state call isn't propagating properly due to > the gst_bin_remove call: > https://github.com/WebKit/WebKit/blob/ > dd956d5e74249681ddf904e0bbe401f308b65e0f/Source/WebCore/platform/mediastream/ > gstreamer/GStreamerMediaStreamSource.cpp#L796-L797 I don't think so. There are 2 pipelines basically, the first feeds the second. first is capturer, ending in an appsink. Then when a frame reaches that sink, it is dispatched to clients observing the capturer. second is for the <video> playback, where the source is a mediastreamsrc, that is observing the capturer and getting its frames from it. Thinking this might be at least partially a gstreamer issue with decodebin3/multiqueue as some of the errors I'm seeing appear to reproduce outside of webkit: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1283 https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1281 So I noticed that this never appears in the logs which I assume means the MediaPlayerPrivateGStreamer destructor never gets called at all: https://github.com/WebKit/WebKit/blob/a01fcdab792edb2611f5122ba599c3648fc158ec/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp#L211 What should normally be triggering that destructor here? Maybe the state isn't getting synced for the pad-added callback? https://gstreamer.freedesktop.org/documentation/application-development/basics/elements.html?gi-language=c#element-states > However, when adding elements dynamically to an already-running pipeline, e.g. from within a "pad-added" signal callback, you need to set it to the desired target state yourself using gst_element_set_state () or gst_element_sync_state_with_parent (). https://github.com/WebKit/WebKit/blob/11f2fe2dbfa3c3891870bbdddb225318d3ab3b28/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCapturer.cpp#L95 This playbin3 issue looks like it might be related: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/915 One of the threads seems to be stuck in a similar place: Thread 24 (Thread 0x7ff0b6ffd640 (LWP 904) "Video_0x7ff0c5a"): #0 syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38 #1 0x00007ff13d8c3ec0 in g_cond_wait (cond=cond@entry=0x56278a240aa0, mutex=mutex@entry=0x56278a240a78) at ../glib/gthread-posix.c:1574 #2 0x00007ff13a8dbaf3 in gst_data_queue_push (queue=0x56278a240ad0 [GstDataQueue], item=item@entry=0x7ff0a800c240) at ../libs/gst/base/gstdataqueue.c:521 #3 0x00007ff0f0cbf4eb in gst_multi_queue_chain (pad=<optimized out>, parent=<optimized out>, buffer=<optimized out>) at ../plugins/elements/gstmultiqueue.c:2494 #4 0x00007ff13d6a63cd in gst_pad_chain_data_unchecked (pad=pad@entry=0x56278a237110 [GstMultiQueuePad|sink_0], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4444 #5 0x00007ff13d6a8c05 in gst_pad_push_data (pad=pad@entry=0x7ff0ac0121e0 [GstParsePad|src_0], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4708 #6 0x00007ff13d6b1759 in gst_pad_push (pad=pad@entry=0x7ff0ac0121e0 [GstParsePad|src_0], buffer=buffer@entry=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstpad.c:4827 #7 0x00007ff13d690698 in gst_proxy_pad_chain_default (pad=<optimized out>, parent=<optimized out>, buffer=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstghostpad.c:127 #8 0x00007ff13d6a63cd in gst_pad_chain_data_unchecked (pad=pad@entry=0x56278a22b3b0 [GstProxyPad|proxypad4], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4444 #9 0x00007ff13d6a8c05 in gst_pad_push_data (pad=pad@entry=0x56278a21b7e0 [GstPad|src], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4708 #10 0x00007ff13d6b1759 in gst_pad_push (pad=0x56278a21b7e0 [GstPad|src], buffer=buffer@entry=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstpad.c:4827 #11 0x00007ff0f0cdf746 in gst_type_find_element_chain (pad=<optimized out>, parent=<optimized out>, buffer=0x7ff0b000b7e0 [GstBuffer]) at ../plugins/elements/gsttypefindelement.c:920 #12 0x00007ff13d6a63cd in gst_pad_chain_data_unchecked (pad=pad@entry=0x56278a21b590 [GstPad|sink], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4444 #13 0x00007ff13d6a8c05 in gst_pad_push_data (pad=pad@entry=0x56278a22a310 [GstProxyPad|proxypad1], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4708 #14 0x00007ff13d6b1759 in gst_pad_push (pad=pad@entry=0x56278a22a310 [GstProxyPad|proxypad1], buffer=buffer@entry=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstpad.c:4827 #15 0x00007ff13d690698 in gst_proxy_pad_chain_default (pad=<optimized out>, parent=<optimized out>, buffer=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstghostpad.c:127 #16 0x00007ff13d6a63cd in gst_pad_chain_data_unchecked (pad=pad@entry=0x56278a2282c0 [GstGhostPad|sink], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4444 #17 0x00007ff13d6a8c05 in gst_pad_push_data (pad=pad@entry=0x56278a22a0b0 [GstProxyPad|proxypad0], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4708 #18 0x00007ff13d6b1759 in gst_pad_push (pad=pad@entry=0x56278a22a0b0 [GstProxyPad|proxypad0], buffer=buffer@entry=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstpad.c:4827 #19 0x00007ff13d690698 in gst_proxy_pad_chain_default (pad=<optimized out>, parent=<optimized out>, buffer=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstghostpad.c:127 #20 0x00007ff13d6a63cd in gst_pad_chain_data_unchecked (pad=pad@entry=0x56278a228050 [GstGhostPad|sink], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4444 #21 0x00007ff13d6a8c05 in gst_pad_push_data (pad=pad@entry=0x56278a21b340 [GstPad|src], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4708 #22 0x00007ff13d6b1759 in gst_pad_push (pad=0x56278a21b340 [GstPad|src], buffer=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstpad.c:4827 #23 0x00007ff13a8c648c in gst_base_transform_chain (pad=<optimized out>, parent=0x56278a2241b0 [GstCapsFilter|mimetype-filter], buffer=<optimized out>) at ../libs/gst/base/gstbasetransform.c:2381 #24 0x00007ff13d6a63cd in gst_pad_chain_data_unchecked (pad=pad@entry=0x56278a21b0f0 [GstPad|sink], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4444 #25 0x00007ff13d6a8c05 in gst_pad_push_data (pad=pad@entry=0x56278a22a570 [GstProxyPad|proxypad2], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4708 #26 0x00007ff13d6b1759 in gst_pad_push (pad=pad@entry=0x56278a22a570 [GstProxyPad|proxypad2], buffer=buffer@entry=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstpad.c:4827 #27 0x00007ff13d690698 in gst_proxy_pad_chain_default (pad=<optimized out>, parent=<optimized out>, buffer=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstghostpad.c:127 #28 0x00007ff13d6a63cd in gst_pad_chain_data_unchecked (pad=pad@entry=0x56278a228530 [GstGhostPad|sink], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4444 #29 0x00007ff13d6a8c05 in gst_pad_push_data (pad=pad@entry=0x56278a21a0c0 [GstPad|src], type=type@entry=4112, data=data@entry=0x7ff0b000b7e0) at ../gst/gstpad.c:4708 #30 0x00007ff13d6b1759 in gst_pad_push (pad=pad@entry=0x56278a21a0c0 [GstPad|src], buffer=0x7ff0b000b7e0 [GstBuffer]) at ../gst/gstpad.c:4827 #31 0x00007ff13a8c08d0 in gst_base_src_loop (pad=0x56278a21a0c0 [GstPad|src]) at ../libs/gst/base/gstbasesrc.c:3030 #32 0x00007ff13d6e7cac in gst_task_func (task=task@entry=0x56278a233290 [GstTask|Video_0x7ff0c5a0c380:src]) at ../gst/gsttask.c:384 #33 0x00007ff13d6e8e2d in default_func (tdata=<optimized out>, pool=<optimized out>) at ../gst/gsttaskpool.c:70 #34 0x00007ff13d89ac59 in g_thread_pool_thread_proxy (data=<optimized out>) at ../glib/gthreadpool.c:354 #35 0x00007ff13d89a29c in g_thread_proxy (data=0x56278a241180) at ../glib/gthread.c:827 #36 0x00007ff13d8c32d1 in linux_pthread_proxy (data=0x56278a241180) at ../glib/gthread-posix.c:1268 #37 0x00007ff13d1b4dc3 in start_thread (arg=<optimized out>) at pthread_create.c:442 #38 0x00007ff13d22e51c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 Oh, pretty sure it's this pipewire renegotiation bug, the problem seems to be that the isCapturingDisplay() doesn't actually catch the usage of pipewiresrc properly so a renegotiation occurs even when pipewiresrc is in use. https://github.com/WebKit/WebKit/commit/5e80996639ec4af8fe9a0828feda7f2b374f9106#diff-5050ca37bb2b1d47f49b0053a59bb6de270064f69dcd55525b2612f28084b91fR262-R266 The bug in pipewiresrc seems to be that the plugin will call pw_stream_connect(which AFAIU is only designed to be called once here) for each negotiate call: https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/0.3.52/src/gst/gstpipewiresrc.c#L810-815 Seeing an Conditional jump or move depends on uninitialised value relating to MediaPlayerPrivateGStreamer that may be related: https://bugs.webkit.org/show_bug.cgi?id=242561 I'm seeing an assert getting hit in the call stack for webkitMediaStreamSrcTrackEnded. ASSERTION FAILED: !isMainThread() /app/webkit/Source/WebCore/platform/AbortableTaskQueue.h(124) : void WebCore::AbortableTaskQueue::enqueueTask(WTF::Function<void()>&&) 1 0x10f16c73 WTFCrash 2 0xd923126 /app/webkit/WebKitBuild/Debug/lib/libWPEWebKit-1.1.so.0(+0x90d0126) [0xd923126] 3 0x1122626e /app/webkit/WebKitBuild/Debug/lib/libWPEWebKit-1.1.so.0(+0xc9d326e) [0x1122626e] 4 0x112a7b79 /app/webkit/WebKitBuild/Debug/lib/libWPEWebKit-1.1.so.0(+0xca54b79) [0x112a7b79] 5 0x112a7bbd /app/webkit/WebKitBuild/Debug/lib/libWPEWebKit-1.1.so.0(+0xca54bbd) [0x112a7bbd] 6 0x19839fef g_closure_invoke 7 0x1984cf16 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0(+0x28f16) [0x1984cf16] 8 0x19853c0c g_signal_emit_valist 9 0x19853d63 g_signal_emit 10 0x1983ed84 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0(+0x1ad84) [0x1983ed84] 11 0x16150c08 /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x44c08) [0x16150c08] 12 0x19840f1a g_object_notify_by_pspec 13 0x4063c688 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstplayback.so(+0x43688) [0x4063c688] 14 0x1619a126 /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x8e126) [0x1619a126] 15 0x15f41896 g_hook_list_marshal 16 0x16199895 /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x8d895) [0x16199895] 17 0x1619c68d /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x9068d) [0x1619c68d] 18 0x1619d26e /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x9126e) [0x1619d26e] 19 0x1619d728 /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x91728) [0x1619d728] 20 0x1619b000 /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x8f000) [0x1619b000] 21 0x161a6780 gst_pad_push_event 22 0x1619cbec /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x90bec) [0x1619cbec] 23 0x1619d26e /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x9126e) [0x1619d26e] 24 0x1619d728 /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x91728) [0x1619d728] 25 0x1619b000 /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x8f000) [0x1619b000] 26 0x161a6780 gst_pad_push_event 27 0x161a6d62 /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x9ad62) [0x161a6d62] 28 0x161a2d6e gst_pad_forward 29 0x161a2eb5 gst_pad_event_default 30 0x1619cbec /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x90bec) [0x1619cbec] 31 0x1619d26e /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0(+0x9126e) [0x1619d26e] ==74== Invalid write of size 4 ==74== at 0x10F16C78: WTFCrash (Assertions.cpp:328) ==74== by 0xD923125: WTFCrashWithInfo(int, char const*, char const*, int) (Assertions.h:754) ==74== by 0x1122626D: WebCore::AbortableTaskQueue::enqueueTask(WTF::Function<void ()>&&) (AbortableTaskQueue.h:124) ==74== by 0x112A7B78: WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WTF::WeakPtr<WebCore::MediaPlayerPrivateGStreamer, WTF::EmptyCounter>, unsigned int, _GstStream*)::{lambda(WebCore::VideoTrackPrivateGStreamer*)#2}::operator()(WebCore::VideoTrackPrivateGStreamer*) const (VideoTrackPrivateGStreamer.cpp:60) ==74== by 0x112A7BBC: WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WTF::WeakPtr<WebCore::MediaPlayerPrivateGStreamer, WTF::EmptyCounter>, unsigned int, _GstStream*)::{lambda(WebCore::VideoTrackPrivateGStreamer*)#2}::_FUN(WebCore::VideoTrackPrivateGStreamer*) (VideoTrackPrivateGStreamer.cpp:60) ==74== by 0x19839FEE: g_closure_invoke (gclosure.c:830) ==74== by 0x1984CF15: signal_emit_unlocked_R (gsignal.c:3742) ==74== by 0x19853C0B: g_signal_emit_valist (gsignal.c:3497) ==74== by 0x19853D62: g_signal_emit (gsignal.c:3553) ==74== by 0x1983ED83: g_object_dispatch_properties_changed (gobject.c:1212) ==74== by 0x16150C07: gst_object_dispatch_properties_changed (gstobject.c:455) ==74== by 0x19840F19: g_object_notify_by_spec_internal (gobject.c:1305) ==74== by 0x19840F19: g_object_notify_by_pspec (gobject.c:1415) ==74== by 0x4063C687: gst_parse_pad_update_tags (gstparsebin.c:3961) ==74== by 0x4063C687: gst_parse_pad_event (gstparsebin.c:4060) ==74== by 0x1619A125: probe_hook_marshal (gstpad.c:3664) ==74== by 0x15F41895: g_hook_list_marshal (ghook.c:672) ==74== by 0x16199894: do_probe_callbacks (gstpad.c:3848) ==74== by 0x1619C68C: gst_pad_send_event_unchecked (gstpad.c:5872) ==74== by 0x1619D26D: gst_pad_push_event_unchecked (gstpad.c:5544) ==74== by 0x1619D727: push_sticky (gstpad.c:4047) ==74== by 0x1619AFFF: events_foreach (gstpad.c:608) ==74== by 0x161A677F: check_sticky (gstpad.c:4106) ==74== by 0x161A677F: gst_pad_push_event (gstpad.c:5675) ==74== by 0x1619CBEB: gst_pad_send_event_unchecked (gstpad.c:5900) ==74== by 0x1619D26D: gst_pad_push_event_unchecked (gstpad.c:5544) ==74== by 0x1619D727: push_sticky (gstpad.c:4047) ==74== by 0x1619AFFF: events_foreach (gstpad.c:608) ==74== by 0x161A677F: check_sticky (gstpad.c:4106) ==74== by 0x161A677F: gst_pad_push_event (gstpad.c:5675) ==74== by 0x161A6D61: event_forward_func (gstpad.c:3125) ==74== by 0x161A2D6D: gst_pad_forward (gstpad.c:3079) ==74== by 0x161A2EB4: gst_pad_event_default (gstpad.c:3176) ==74== by 0x1619CBEB: gst_pad_send_event_unchecked (gstpad.c:5900) ==74== by 0x1619D26D: gst_pad_push_event_unchecked (gstpad.c:5544) ==74== by 0x1619D727: push_sticky (gstpad.c:4047) ==74== by 0x1619AFFF: events_foreach (gstpad.c:608) ==74== by 0x161A677F: check_sticky (gstpad.c:4106) ==74== by 0x161A677F: gst_pad_push_event (gstpad.c:5675) ==74== by 0x161A6D61: event_forward_func (gstpad.c:3125) ==74== by 0x161A2D6D: gst_pad_forward (gstpad.c:3079) ==74== by 0x161A2EB4: gst_pad_event_default (gstpad.c:3176) ==74== by 0x1619CBEB: gst_pad_send_event_unchecked (gstpad.c:5900) ==74== by 0x1619D26D: gst_pad_push_event_unchecked (gstpad.c:5544) ==74== by 0x1619D727: push_sticky (gstpad.c:4047) ==74== by 0x1619AFFF: events_foreach (gstpad.c:608) ==74== by 0x161A677F: check_sticky (gstpad.c:4106) ==74== by 0x161A677F: gst_pad_push_event (gstpad.c:5675) ==74== by 0x161A6D61: event_forward_func (gstpad.c:3125) ==74== by 0x161A2D6D: gst_pad_forward (gstpad.c:3079) ==74== by 0x161A2EB4: gst_pad_event_default (gstpad.c:3176) ==74== by 0x1619CBEB: gst_pad_send_event_unchecked (gstpad.c:5900) ==74== by 0x1619D26D: gst_pad_push_event_unchecked (gstpad.c:5544) ==74== by 0x1619D727: push_sticky (gstpad.c:4047) ==74== by 0x1619AFFF: events_foreach (gstpad.c:608) ==74== by 0x161A677F: check_sticky (gstpad.c:4106) ==74== by 0x161A677F: gst_pad_push_event (gstpad.c:5675) ==74== by 0x1619CBEB: gst_pad_send_event_unchecked (gstpad.c:5900) ==74== by 0x1619D26D: gst_pad_push_event_unchecked (gstpad.c:5544) ==74== by 0x1619D727: push_sticky (gstpad.c:4047) ==74== by 0x1619AFFF: events_foreach (gstpad.c:608) ==74== by 0x161A677F: check_sticky (gstpad.c:4106) ==74== by 0x161A677F: gst_pad_push_event (gstpad.c:5675) ==74== by 0x11310D74: webkitMediaStreamSrcTrackEnded(_WebKitMediaStreamSrc*, InternalSource&) (GStreamerMediaStreamSource.cpp:791) ==74== by 0x11310F79: InternalSource::trackEnded(WebCore::MediaStreamTrackPrivate&) (GStreamerMediaStreamSource.cpp:812) ==74== by 0x14A385B6: auto WebCore::MediaStreamTrackPrivate::endTrack()::{lambda(auto:1&)#1}::operator()<WebCore::MediaStreamTrackPrivate::Observer>(WebCore::MediaStreamTrackPrivate::Observer&) const (MediaStreamTrackPrivate.cpp:155) ==74== by 0x14A385E9: WTF::Detail::CallableWrapper<WebCore::MediaStreamTrackPrivate::endTrack()::{lambda(auto:1&)#1}, void, WebCore::MediaStreamTrackPrivate::Observer&>::call(WebCore::MediaStreamTrackPrivate::Observer&) (Function.h:53) ==74== by 0x14A3EFE4: WTF::Function<void (WebCore::MediaStreamTrackPrivate::Observer&)>::operator()(WebCore::MediaStreamTrackPrivate::Observer&) const (Function.h:82) ==74== by 0x14A3C417: WTF::WeakHashSet<WebCore::MediaStreamTrackPrivate::Observer, WTF::EmptyCounter, (WTF::EnableWeakPtrThreadingAssertions)1>::forEach(WTF::Function<void (WebCore::MediaStreamTrackPrivate::Observer&)> const&) (WeakHashSet.h:147) ==74== by 0x14A2E45A: WebCore::MediaStreamTrackPrivate::forEachObserver(WTF::Function<void (WebCore::MediaStreamTrackPrivate::Observer&)> const&) (MediaStreamTrackPrivate.cpp:89) ==74== by 0x14A2E898: WebCore::MediaStreamTrackPrivate::endTrack() (MediaStreamTrackPrivate.cpp:154) ==74== by 0x12D950F7: WebCore::MediaStreamTrack::stopTrack(WebCore::MediaStreamTrack::StopMode) (MediaStreamTrack.cpp:244) ==74== by 0x12D97482: WebCore::MediaStreamTrack::suspend(WebCore::ReasonForSuspension) (MediaStreamTrack.cpp:653) ==74== by 0x13A576A8: auto WebCore::ScriptExecutionContext::suspendActiveDOMObjects(WebCore::ReasonForSuspension)::{lambda(auto:1&)#1}::operator()<WebCore::ActiveDOMObject>(WebCore::ActiveDOMObject&) const (ScriptExecutionContext.cpp:302) ==74== by 0x13A576DF: WTF::Detail::CallableWrapper<WebCore::ScriptExecutionContext::suspendActiveDOMObjects(WebCore::ReasonForSuspension)::{lambda(auto:1&)#1}, WebCore::ScriptExecutionContext::ShouldContinue, WebCore::ActiveDOMObject&>::call(WebCore::ActiveDOMObject&) (Function.h:53) ==74== by 0x13A5AA4E: WTF::Function<WebCore::ScriptExecutionContext::ShouldContinue (WebCore::ActiveDOMObject&)>::operator()(WebCore::ActiveDOMObject&) const (Function.h:82) ==74== by 0x13A4EFE5: WebCore::ScriptExecutionContext::forEachActiveDOMObject(WTF::Function<WebCore::ScriptExecutionContext::ShouldContinue (WebCore::ActiveDOMObject&)> const&) const (ScriptExecutionContext.cpp:273) ==74== by 0x13A4F157: WebCore::ScriptExecutionContext::suspendActiveDOMObjects(WebCore::ReasonForSuspension) (ScriptExecutionContext.cpp:301) ==74== by 0x1388F5B8: WebCore::Document::suspendActiveDOMObjects(WebCore::ReasonForSuspension) (Document.cpp:2824) ==74== by 0x138A3FEB: WebCore::Document::suspendScheduledTasks(WebCore::ReasonForSuspension) (Document.cpp:6788) ==74== by 0x1389EDEB: WebCore::Document::suspend(WebCore::ReasonForSuspension) (Document.cpp:5774) ==74== by 0x13C36554: WebCore::CachedFrame::CachedFrame(WebCore::Frame&) (CachedFrame.cpp:169) ==74== by 0x13C3CC95: std::_MakeUniq<WebCore::CachedFrame>::__single_object std::make_unique<WebCore::CachedFrame, WebCore::Frame&>(WebCore::Frame&) (unique_ptr.h:962) ==74== by 0x13C3B58B: decltype(auto) WTF::makeUnique<WebCore::CachedFrame, WebCore::Frame&>(WebCore::Frame&) (StdLibExtras.h:540) ==74== by 0x13C37214: WebCore::CachedPage::CachedPage(WebCore::Page&) (CachedPage.cpp:61) ==74== by 0x13C3BF15: std::_MakeUniq<WebCore::CachedPage>::__single_object std::make_unique<WebCore::CachedPage, WebCore::Page&>(WebCore::Page&) (unique_ptr.h:962) ==74== by 0x13C3B305: decltype(auto) WTF::makeUnique<WebCore::CachedPage, WebCore::Page&>(WebCore::Page&) (StdLibExtras.h:540) ==74== by 0x13C34450: WebCore::BackForwardCache::trySuspendPage(WebCore::Page&, WebCore::BackForwardCache::ForceSuspension) (BackForwardCache.cpp:460) ==74== by 0x13C344EE: WebCore::BackForwardCache::addIfCacheable(WebCore::HistoryItem&, WebCore::Page*) (BackForwardCache.cpp:471) ==74== by 0x142BFF6C: WebCore::FrameLoader::commitProvisionalLoad() (FrameLoader.cpp:2040) ==74== by 0x142665F2: WebCore::DocumentLoader::commitIfReady() (DocumentLoader.cpp:412) ==74== by 0x1426C200: WebCore::DocumentLoader::commitLoad(WebCore::SharedBuffer const&) (DocumentLoader.cpp:1178) ==74== by 0x1426D388: WebCore::DocumentLoader::dataReceived(WebCore::SharedBuffer const&) (DocumentLoader.cpp:1373) ==74== by 0x1426D0E7: WebCore::DocumentLoader::dataReceived(WebCore::CachedResource&, WebCore::SharedBuffer const&) (DocumentLoader.cpp:1347) ==74== by 0x143A2A52: WebCore::CachedRawResource::notifyClientsDataWasReceived(WebCore::SharedBuffer const&) (CachedRawResource.cpp:145) ==74== by 0x143A252A: WebCore::CachedRawResource::updateBuffer(WebCore::FragmentedSharedBuffer const&) (CachedRawResource.cpp:81) ==74== by 0x1433945C: WebCore::SubresourceLoader::didReceiveBuffer(WebCore::FragmentedSharedBuffer const&, long long, WebCore::DataPayloadType) (SubresourceLoader.cpp:559) ==74== by 0x14323A3F: WebCore::ResourceLoader::didReceiveData(WebCore::SharedBuffer const&, long long, WebCore::DataPayloadType) (ResourceLoader.cpp:560) ==74== by 0xED59FD9: WebKit::WebResourceLoader::didReceiveData(IPC::SharedBufferReference&&, long) (WebResourceLoader.cpp:243) ==74== by 0xDF022C8: void IPC::callMemberFunctionImpl<WebKit::WebResourceLoader, void (WebKit::WebResourceLoader::*)(IPC::SharedBufferReference&&, long), std::tuple<IPC::SharedBufferReference, long>, 0ul, 1ul>(WebKit::WebResourceLoader*, void (WebKit::WebResourceLoader::*)(IPC::SharedBufferReference&&, long), std::tuple<IPC::SharedBufferReference, long>&&, std::integer_sequence<unsigned long, 0ul, 1ul>) (HandleMessage.h:131) ==74== by 0xDF01053: void IPC::callMemberFunction<WebKit::WebResourceLoader, void (WebKit::WebResourceLoader::*)(IPC::SharedBufferReference&&, long), std::tuple<IPC::SharedBufferReference, long>, std::integer_sequence<unsigned long, 0ul, 1ul> >(std::tuple<IPC::SharedBufferReference, long>&&, WebKit::WebResourceLoader*, void (WebKit::WebResourceLoader::*)(IPC::SharedBufferReference&&, long)) (HandleMessage.h:137) ==74== by 0xDF00255: void IPC::handleMessage<Messages::WebResourceLoader::DidReceiveData, WebKit::WebResourceLoader, void (WebKit::WebResourceLoader::*)(IPC::SharedBufferReference&&, long)>(IPC::Connection&, IPC::Decoder&, WebKit::WebResourceLoader*, void (WebKit::WebResourceLoader::*)(IPC::SharedBufferReference&&, long)) (HandleMessage.h:259) ==74== by 0xDEFF838: WebKit::WebResourceLoader::didReceiveWebResourceLoaderMessage(IPC::Connection&, IPC::Decoder&) (WebResourceLoaderMessageReceiver.cpp:76) ==74== by 0xED50A06: WebKit::NetworkProcessConnection::didReceiveMessage(IPC::Connection&, IPC::Decoder&) (NetworkProcessConnection.cpp:102) ==74== by 0xE5537A5: IPC::Connection::dispatchMessage(IPC::Decoder&) (Connection.cpp:1108) ==74== by 0xE553A3C: IPC::Connection::dispatchMessage(std::unique_ptr<IPC::Decoder, std::default_delete<IPC::Decoder> >) (Connection.cpp:1153) ==74== by 0xE553FE3: IPC::Connection::dispatchOneIncomingMessage() (Connection.cpp:1222) ==74== by 0xE5534B5: IPC::Connection::enqueueIncomingMessage(std::unique_ptr<IPC::Decoder, std::default_delete<IPC::Decoder> >)::{lambda()#1}::operator()() (Connection.cpp:1072) ==74== by 0xE55A599: WTF::Detail::CallableWrapper<IPC::Connection::enqueueIncomingMessage(std::unique_ptr<IPC::Decoder, std::default_delete<IPC::Decoder> >)::{lambda()#1}, void>::call() (Function.h:53) ==74== by 0xD99E63C: WTF::Function<void ()>::operator()() const (Function.h:82) ==74== by 0x10F6D6C2: WTF::RunLoop::performWork() (RunLoop.cpp:133) ==74== by 0x11018C67: WTF::RunLoop::RunLoop()::{lambda(void*)#1}::operator()(void*) const (RunLoopGLib.cpp:80) ==74== by 0x11018C8B: WTF::RunLoop::RunLoop()::{lambda(void*)#1}::_FUN(void*) (RunLoopGLib.cpp:82) ==74== by 0x11018BFA: WTF::RunLoop::{lambda(_GSource*, int (*)(void*), void*)#1}::operator()(_GSource*, int (*)(void*), void*) const (RunLoopGLib.cpp:53) ==74== by 0x11018C48: WTF::RunLoop::{lambda(_GSource*, int (*)(void*), void*)#1}::_FUN(_GSource*, int (*)(void*), void*) (RunLoopGLib.cpp:56) ==74== by 0x15F52293: g_main_dispatch (gmain.c:3381) ==74== by 0x15F52293: g_main_context_dispatch (gmain.c:4099) ==74== by 0x15F52637: g_main_context_iterate.constprop.0 (gmain.c:4175) ==74== by 0x15F52942: g_main_loop_run (gmain.c:4373) ==74== by 0x110192B3: WTF::RunLoop::run() (RunLoopGLib.cpp:108) ==74== by 0xEFB8674: WebKit::AuxiliaryProcessMainBase<WebKit::WebProcess, true>::run(int, char**) (AuxiliaryProcessMain.h:70) ==74== by 0xEFB5D26: int WebKit::AuxiliaryProcessMain<WebKit::WebProcessMainWPE>(int, char**) (AuxiliaryProcessMain.h:96) ==74== by 0xEFB227E: WebKit::WebProcessMain(int, char**) (WebProcessMainWPE.cpp:75) ==74== by 0x109908: main (WebProcessMain.cpp:31) ==74== Address 0xbbadbeef is not stack'd, malloc'd or (recently) free'd ==74== Pull request: https://github.com/WebKit/WebKit/pull/2605 Committed 253192@main (a4d18a005735): <https://commits.webkit.org/253192@main> Reviewed commits have been landed. Closing PR #2605 and removing active labels. |
Created attachment 460198 [details] WPEWebkit debug logs. On an updated latest WPE WebKit with pipewire I'm seeing that MediaStream close() fails to properly stop a camera stream, the pipeline appears to pause and then restart in the background eating up resources. Logs attached. Some potentially relevant FIXME's I'm seeing: 0:00:00.584451289 5339 0x55eb0d384580 FIXME default gstutils.c:4025:gst_pad_create_stream_id_internal:<Video_0x7f765925ae00:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id 0:00:00.703271418 5339 0x55eb0d384580 FIXME decodebin3 gstdecodebin3.c:1226:update_requested_selection:<decodebin3-0> Implement EXPOSE_ALL_MODE 0:00:00.896543034 5339 0x55eb0d75ac00 FIXME default gstutils.c:4025:gst_pad_create_stream_id_internal:<videosrc:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id 0:00:01.044883717 5339 0x55eb0d384580 FIXME decodebin3 gstdecodebin3-parse.c:436:unblock_pending_input:<decodebin3-0> Re-use existing input streams if/when possible 0:00:01.077272968 5339 0x7f763c016c00 FIXME decodebin3 gstdecodebin3.c:1753:get_output_for_slot:<decodebin3-0> emit autoplug-continue 0:00:01.077492259 5339 0x7f763c016c00 FIXME decodebin3 gstdecodebin3.c:1756:get_output_for_slot:<decodebin3-0> Handle EXPOSE_ALL_MODE 0:00:01.270496174 5339 0x7f763c016c00 FIXME videodecoder gstvideodecoder.c:1193:gst_video_decoder_drain_out:<jpegdec0> Sub-class should implement drain() 0:00:01.315239328 5339 0x55eb0d75ac00 FIXME decodebin3 gstdecodebin3.c:1226:update_requested_selection:<decodebin3-1> Implement EXPOSE_ALL_MODE 0:00:01.321216104 5339 0x55eb0d75ac00 FIXME decodebin3 gstdecodebin3-parse.c:436:unblock_pending_input:<decodebin3-1> Re-use existing input streams if/when possible 0:00:01.356439505 5339 0x7f764c01cd80 FIXME decodebin3 gstdecodebin3.c:1753:get_output_for_slot:<decodebin3-1> emit autoplug-continue 0:00:01.356643290 5339 0x7f764c01cd80 FIXME decodebin3 gstdecodebin3.c:1756:get_output_for_slot:<decodebin3-1> Handle EXPOSE_ALL_MODE 0:00:06.362283274 5339 0x55eb0d211810 FIXME playbin3 gstplaybin3.c:3227:reconfigure_output:<mediastream-media-player-0> Release combiner 0:00:06.405355883 5339 0x7f764c01cd80 FIXME decodebin3 gstdecodebin3.c:2064:multiqueue_src_probe:<multiqueue1:src_0> EOS on multiqueue source pad. input:0x7f7648012fd0 0:00:06.410205056 5339 0x55eb0d211810 FIXME decodebin3 gstdecodebin3-parse.c:151:check_all_streams_for_eos:<multiqueue1:sink_0> Remove input stream