Title: [272200] trunk/Source
Revision
272200
Author
[email protected]
Date
2021-02-02 02:25:52 -0800 (Tue, 02 Feb 2021)

Log Message

imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html is flaky when GPUProcess is enabled
https://bugs.webkit.org/show_bug.cgi?id=221197

Reviewed by Eric Carlson.

Source/WebCore:

When a track is removed, we should stop recording and fire an error event.
Previously, we were enqueuing a task, stopping the recording and dispatching the error event.
This could trigger the error event to be dispatched before the start event which does:
- Call start on MediaRecorderPrivate
- Wait for start to finish
- Enqueue a task and dispatch start event.
To fix this, we add a completion handler when stopping recording so that the order of events is guaranteed.

Covered by imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html no longer flaky when GPUProcess is on for MediaRecorder.

* Modules/mediarecorder/MediaRecorder.cpp:
(WebCore::MediaRecorder::stopRecordingInternal):
(WebCore::MediaRecorder::handleTrackChange):
(WebCore::MediaRecorder::trackEnded):
* Modules/mediarecorder/MediaRecorder.h:
* platform/mediarecorder/MediaRecorderPrivate.cpp:
(WebCore::MediaRecorderPrivate::stop):
* platform/mediarecorder/MediaRecorderPrivate.h:
* platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp:
(WebCore::MediaRecorderPrivateAVFImpl::stopRecording):
* platform/mediarecorder/MediaRecorderPrivateAVFImpl.h:
* platform/mediarecorder/MediaRecorderPrivateMock.cpp:
(WebCore::MediaRecorderPrivateMock::stopRecording):
* platform/mediarecorder/MediaRecorderPrivateMock.h:

Source/WebKit:

* GPUProcess/webrtc/RemoteMediaRecorder.cpp:
(WebKit::RemoteMediaRecorder::stopRecording):
* GPUProcess/webrtc/RemoteMediaRecorder.h:
* GPUProcess/webrtc/RemoteMediaRecorder.messages.in:
* WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp:
(WebKit::MediaRecorderPrivate::stopRecording):
* WebProcess/GPU/webrtc/MediaRecorderPrivate.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (272199 => 272200)


--- trunk/Source/WebCore/ChangeLog	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/ChangeLog	2021-02-02 10:25:52 UTC (rev 272200)
@@ -1,3 +1,35 @@
+2021-02-02  Youenn Fablet  <[email protected]>
+
+        imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html is flaky when GPUProcess is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=221197
+
+        Reviewed by Eric Carlson.
+
+        When a track is removed, we should stop recording and fire an error event.
+        Previously, we were enqueuing a task, stopping the recording and dispatching the error event.
+        This could trigger the error event to be dispatched before the start event which does:
+        - Call start on MediaRecorderPrivate
+        - Wait for start to finish
+        - Enqueue a task and dispatch start event.
+        To fix this, we add a completion handler when stopping recording so that the order of events is guaranteed.
+
+        Covered by imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html no longer flaky when GPUProcess is on for MediaRecorder.
+
+        * Modules/mediarecorder/MediaRecorder.cpp:
+        (WebCore::MediaRecorder::stopRecordingInternal):
+        (WebCore::MediaRecorder::handleTrackChange):
+        (WebCore::MediaRecorder::trackEnded):
+        * Modules/mediarecorder/MediaRecorder.h:
+        * platform/mediarecorder/MediaRecorderPrivate.cpp:
+        (WebCore::MediaRecorderPrivate::stop):
+        * platform/mediarecorder/MediaRecorderPrivate.h:
+        * platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp:
+        (WebCore::MediaRecorderPrivateAVFImpl::stopRecording):
+        * platform/mediarecorder/MediaRecorderPrivateAVFImpl.h:
+        * platform/mediarecorder/MediaRecorderPrivateMock.cpp:
+        (WebCore::MediaRecorderPrivateMock::stopRecording):
+        * platform/mediarecorder/MediaRecorderPrivateMock.h:
+
 2021-02-02  Carlos Garcia Campos  <[email protected]>
 
         Missing exception check with new MediaStream(0)

Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp (272199 => 272200)


--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp	2021-02-02 10:25:52 UTC (rev 272200)
@@ -311,33 +311,38 @@
     });
 }
 
-void MediaRecorder::stopRecordingInternal()
+void MediaRecorder::stopRecordingInternal(CompletionHandler<void()>&& completionHandler)
 {
-    if (state() != RecordingState::Recording)
+    if (state() != RecordingState::Recording) {
+        completionHandler();
         return;
+    }
 
     for (auto& track : m_tracks)
         track->removeObserver(*this);
 
     m_state = RecordingState::Inactive;
-    m_private->stop();
+    m_private->stop(WTFMove(completionHandler));
 }
 
 void MediaRecorder::handleTrackChange()
 {
     queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this] {
-        if (!m_isActive || state() == RecordingState::Inactive)
-            return;
-        stopRecordingInternal();
-        dispatchError(Exception { InvalidModificationError, "Track cannot be added to or removed from the MediaStream while recording"_s });
-        if (!m_isActive)
-            return;
+        stopRecordingInternal([this, pendingActivity = makePendingActivity(*this)] {
+            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this] {
+                if (!m_isActive)
+                    return;
+                dispatchError(Exception { InvalidModificationError, "Track cannot be added to or removed from the MediaStream while recording"_s });
 
-        dispatchEvent(createDataAvailableEvent(scriptExecutionContext(), { }, { }, 0));
+                if (!m_isActive)
+                    return;
+                dispatchEvent(createDataAvailableEvent(scriptExecutionContext(), { }, { }, 0));
 
-        if (!m_isActive)
-            return;
-        dispatchEvent(Event::create(eventNames().stopEvent, Event::CanBubble::No, Event::IsCancelable::No));
+                if (!m_isActive)
+                    return;
+                dispatchEvent(Event::create(eventNames().stopEvent, Event::CanBubble::No, Event::IsCancelable::No));
+            });
+        });
     });
 }
 
@@ -357,14 +362,17 @@
         return;
 
     queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this] {
-        if (!m_isActive || state() == RecordingState::Inactive)
-            return;
+        stopRecordingInternal([this, pendingActivity = makePendingActivity(*this)] {
+            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this] {
+                if (!m_isActive)
+                    return;
+                dispatchEvent(createDataAvailableEvent(scriptExecutionContext(), { }, { }, 0));
 
-        stopRecordingInternal();
-        dispatchEvent(createDataAvailableEvent(scriptExecutionContext(), { }, { }, 0));
-        if (!m_isActive)
-            return;
-        dispatchEvent(Event::create(eventNames().stopEvent, Event::CanBubble::No, Event::IsCancelable::No));
+                if (!m_isActive)
+                    return;
+                dispatchEvent(Event::create(eventNames().stopEvent, Event::CanBubble::No, Event::IsCancelable::No));
+            });
+        });
     });
 }
 

Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h (272199 => 272200)


--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h	2021-02-02 10:25:52 UTC (rev 272200)
@@ -99,7 +99,7 @@
     const char* activeDOMObjectName() const final;
     bool virtualHasPendingActivity() const final;
     
-    void stopRecordingInternal();
+        void stopRecordingInternal(CompletionHandler<void()>&& = [] { });
     void dispatchError(Exception&&);
 
     enum class TakePrivateRecorder { No, Yes };

Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp (272199 => 272200)


--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp	2021-02-02 10:25:52 UTC (rev 272200)
@@ -69,11 +69,11 @@
         m_shouldMuteVideo = track.muted() || !track.enabled();
 }
 
-void MediaRecorderPrivate::stop()
+void MediaRecorderPrivate::stop(CompletionHandler<void()>&& completionHandler)
 {
     setAudioSource(nullptr);
     setVideoSource(nullptr);
-    stopRecording();
+    stopRecording(WTFMove(completionHandler));
 }
 
 void MediaRecorderPrivate::pause(CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h (272199 => 272200)


--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h	2021-02-02 10:25:52 UTC (rev 272200)
@@ -63,7 +63,7 @@
     virtual void fetchData(FetchDataCallback&&) = 0;
     virtual const String& mimeType() const = 0;
 
-    void stop();
+    void stop(CompletionHandler<void()>&&);
     void pause(CompletionHandler<void()>&&);
     void resume(CompletionHandler<void()>&&);
 
@@ -85,7 +85,7 @@
     bool shouldMuteVideo() const { return m_shouldMuteVideo; }
 
 private:
-    virtual void stopRecording() = 0;
+    virtual void stopRecording(CompletionHandler<void()>&&) = 0;
     virtual void pauseRecording(CompletionHandler<void()>&&) = 0;
     virtual void resumeRecording(CompletionHandler<void()>&&) = 0;
 

Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp (272199 => 272200)


--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp	2021-02-02 10:25:52 UTC (rev 272200)
@@ -139,9 +139,10 @@
     m_writer->appendAudioSampleBuffer(data, description, mediaTime, sampleCount);
 }
 
-void MediaRecorderPrivateAVFImpl::stopRecording()
+void MediaRecorderPrivateAVFImpl::stopRecording(CompletionHandler<void()>&& completionHandler)
 {
     m_writer->stopRecording();
+    completionHandler();
 }
 
 void MediaRecorderPrivateAVFImpl::pauseRecording(CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h (272199 => 272200)


--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h	2021-02-02 10:25:52 UTC (rev 272200)
@@ -55,7 +55,7 @@
     void startRecording(StartRecordingCallback&&) final;
     const String& mimeType() const final;
 
-    void stopRecording() final;
+    void stopRecording(CompletionHandler<void()>&&) final;
     void pauseRecording(CompletionHandler<void()>&&) final;
     void resumeRecording(CompletionHandler<void()>&&) final;
 

Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp (272199 => 272200)


--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp	2021-02-02 10:25:52 UTC (rev 272200)
@@ -52,8 +52,9 @@
 {
 }
 
-void MediaRecorderPrivateMock::stopRecording()
+void MediaRecorderPrivateMock::stopRecording(CompletionHandler<void()>&& completionHandler)
 {
+    completionHandler();
 }
 
 void MediaRecorderPrivateMock::pauseRecording(CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.h (272199 => 272200)


--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.h	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.h	2021-02-02 10:25:52 UTC (rev 272200)
@@ -45,7 +45,7 @@
     void videoSampleAvailable(MediaSample&) final;
     void fetchData(FetchDataCallback&&) final;
     void audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final;
-    void stopRecording() final;
+    void stopRecording(CompletionHandler<void()>&&) final;
     void pauseRecording(CompletionHandler<void()>&&) final;
     void resumeRecording(CompletionHandler<void()>&&) final;
     const String& mimeType() const final;

Modified: trunk/Source/WebKit/ChangeLog (272199 => 272200)


--- trunk/Source/WebKit/ChangeLog	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebKit/ChangeLog	2021-02-02 10:25:52 UTC (rev 272200)
@@ -1,3 +1,18 @@
+2021-02-02  Youenn Fablet  <[email protected]>
+
+        imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html is flaky when GPUProcess is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=221197
+
+        Reviewed by Eric Carlson.
+
+        * GPUProcess/webrtc/RemoteMediaRecorder.cpp:
+        (WebKit::RemoteMediaRecorder::stopRecording):
+        * GPUProcess/webrtc/RemoteMediaRecorder.h:
+        * GPUProcess/webrtc/RemoteMediaRecorder.messages.in:
+        * WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp:
+        (WebKit::MediaRecorderPrivate::stopRecording):
+        * WebProcess/GPU/webrtc/MediaRecorderPrivate.h:
+
 2021-02-02  Carlos Garcia Campos  <[email protected]>
 
         [SOUP] Stop using SoupBuffer in preparation for libsoup3

Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.cpp (272199 => 272200)


--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.cpp	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.cpp	2021-02-02 10:25:52 UTC (rev 272200)
@@ -112,9 +112,10 @@
     });
 }
 
-void RemoteMediaRecorder::stopRecording()
+void RemoteMediaRecorder::stopRecording(CompletionHandler<void()>&& completionHandler)
 {
     m_writer->stopRecording();
+    completionHandler();
 }
 
 void RemoteMediaRecorder::pause(CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.h (272199 => 272200)


--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.h	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.h	2021-02-02 10:25:52 UTC (rev 272200)
@@ -73,7 +73,7 @@
     void audioSamplesAvailable(MediaTime, uint64_t numberOfFrames);
     void videoSampleAvailable(WebCore::RemoteVideoSample&&);
     void fetchData(CompletionHandler<void(IPC::DataReference&&, double)>&&);
-    void stopRecording();
+    void stopRecording(CompletionHandler<void()>&&);
     void pause(CompletionHandler<void()>&&);
     void resume(CompletionHandler<void()>&&);
 

Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.messages.in (272199 => 272200)


--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.messages.in	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.messages.in	2021-02-02 10:25:52 UTC (rev 272200)
@@ -28,7 +28,7 @@
     AudioSamplesAvailable(MediaTime time, uint64_t numberOfFrames)
     VideoSampleAvailable(WebCore::RemoteVideoSample sample)
     FetchData() -> (IPC::DataReference buffer, double timeCode) Async
-    StopRecording()
+    StopRecording() -> () Async
     Pause() -> () Async
     Resume() -> () Async
 }

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp (272199 => 272200)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp	2021-02-02 10:25:52 UTC (rev 272200)
@@ -132,10 +132,10 @@
     }, m_identifier);
 }
 
-void MediaRecorderPrivate::stopRecording()
+void MediaRecorderPrivate::stopRecording(CompletionHandler<void()>&& completionHandler)
 {
     m_isStopped = true;
-    m_connection->send(Messages::RemoteMediaRecorder::StopRecording { }, m_identifier);
+    m_connection->sendWithAsyncReply(Messages::RemoteMediaRecorder::StopRecording { }, WTFMove(completionHandler), m_identifier);
 }
 
 void MediaRecorderPrivate::pauseRecording(CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h (272199 => 272200)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h	2021-02-02 09:33:36 UTC (rev 272199)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h	2021-02-02 10:25:52 UTC (rev 272200)
@@ -56,7 +56,7 @@
     // WebCore::MediaRecorderPrivate
     void videoSampleAvailable(WebCore::MediaSample&) final;
     void fetchData(CompletionHandler<void(RefPtr<WebCore::SharedBuffer>&&, const String& mimeType, double)>&&) final;
-    void stopRecording() final;
+    void stopRecording(CompletionHandler<void()>&&) final;
     void startRecording(StartRecordingCallback&&) final;
     void audioSamplesAvailable(const WTF::MediaTime&, const WebCore::PlatformAudioData&, const WebCore::AudioStreamDescription&, size_t) final;
     const String& mimeType() const final;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to