Title: [232956] trunk
Revision
232956
Author
[email protected]
Date
2018-06-19 00:20:51 -0700 (Tue, 19 Jun 2018)

Log Message

RTCRtpSender.replaceTrack(null) ends current track
https://bugs.webkit.org/show_bug.cgi?id=184911
<rdar://problem/40758138>

Reviewed by Eric Carlson.

LayoutTests/imported/w3c:

* web-platform-tests/webrtc/RTCRtpSender-replaceTrack-expected.txt:

Source/WebCore:

Before the patch, when replacing the sender track by null, the previous track was stopped.
Instead of doing that, the track now stays alive and it is the realtime source that is stopped.
This ensures that the data is no longer sent while the track can still be used elsewhere.

Covered by updated and rebased tests.

* Modules/mediastream/PeerConnectionBackend.h:
* Modules/mediastream/RTCPeerConnection.cpp:
(WebCore::RTCPeerConnection::addTransceiver):
(WebCore::RTCPeerConnection::enqueueReplaceTrackTask):
(WebCore::RTCPeerConnection::replaceTrack):
* Modules/mediastream/RTCPeerConnection.h:
* Modules/mediastream/RTCRtpSender.cpp:
(WebCore::RTCRtpSender::replaceTrack):
* Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
(WebCore::updateTrackSource):
(WebCore::LibWebRTCPeerConnectionBackend::replaceTrack):
* Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:

LayoutTests:

Added checks for readyState to ensure the track remains live.
Split the main test into several tests to ease readability.

* webrtc/video-replace-track-to-null-expected.txt:
* webrtc/video-replace-track-to-null.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (232955 => 232956)


--- trunk/LayoutTests/ChangeLog	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/LayoutTests/ChangeLog	2018-06-19 07:20:51 UTC (rev 232956)
@@ -1,3 +1,17 @@
+2018-06-19  Youenn Fablet  <[email protected]>
+
+        RTCRtpSender.replaceTrack(null) ends current track
+        https://bugs.webkit.org/show_bug.cgi?id=184911
+        <rdar://problem/40758138>
+
+        Reviewed by Eric Carlson.
+
+        Added checks for readyState to ensure the track remains live.
+        Split the main test into several tests to ease readability.
+
+        * webrtc/video-replace-track-to-null-expected.txt:
+        * webrtc/video-replace-track-to-null.html:
+
 2018-06-18  Antoine Quint  <[email protected]>
 
         [Web Animations] Implement "Starting of transitions" section from CSS Transitions

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (232955 => 232956)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2018-06-19 07:20:51 UTC (rev 232956)
@@ -1,3 +1,13 @@
+2018-06-19  Youenn Fablet  <[email protected]>
+
+        RTCRtpSender.replaceTrack(null) ends current track
+        https://bugs.webkit.org/show_bug.cgi?id=184911
+        <rdar://problem/40758138>
+
+        Reviewed by Eric Carlson.
+
+        * web-platform-tests/webrtc/RTCRtpSender-replaceTrack-expected.txt:
+
 2018-06-18  Youenn Fablet  <[email protected]>
 
         Expose RTCPeerConnectionIceEventInit constructor

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-replaceTrack-expected.txt (232955 => 232956)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-replaceTrack-expected.txt	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-replaceTrack-expected.txt	2018-06-19 07:20:51 UTC (rev 232956)
@@ -3,9 +3,9 @@
 PASS Calling replaceTrack with track of different kind should reject with TypeError 
 FAIL Calling replaceTrack on stopped sender should reject with InvalidStateError assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS Calling replaceTrack on sender with null track and not set to session description should resolve with sender.track set to given track 
-FAIL Calling replaceTrack on sender not set to session description should resolve with sender.track set to given track promise_test: Unhandled rejection with value: object "InvalidModificationError:  The object can not be modified in this way."
+PASS Calling replaceTrack on sender not set to session description should resolve with sender.track set to given track 
 PASS Calling replaceTrack(null) on sender not set to session description should resolve with sender.track set to null 
 PASS Calling replaceTrack(null) on sender set to session description should resolve with sender.track set to null 
-FAIL Calling replaceTrack on sender with stopped track and and set to session description should resolve with sender.track set to given track promise_test: Unhandled rejection with value: object "InvalidModificationError:  The object can not be modified in this way."
-FAIL Calling replaceTrack on sender with similar track and and set to session description should resolve with sender.track set to new track promise_test: Unhandled rejection with value: object "InvalidModificationError:  The object can not be modified in this way."
+PASS Calling replaceTrack on sender with stopped track and and set to session description should resolve with sender.track set to given track 
+PASS Calling replaceTrack on sender with similar track and and set to session description should resolve with sender.track set to new track 
 

Modified: trunk/LayoutTests/webrtc/video-replace-track-to-null-expected.txt (232955 => 232956)


--- trunk/LayoutTests/webrtc/video-replace-track-to-null-expected.txt	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/LayoutTests/webrtc/video-replace-track-to-null-expected.txt	2018-06-19 07:20:51 UTC (rev 232956)
@@ -1,3 +1,6 @@
 
-PASS Stopping sending video using replaceTrack 
+PASS Set-up test 
+PASS Test that frame counter increases 
+PASS Test replaceTrack with null track 
+PASS Test that frame counter no longer increases 
 

Modified: trunk/LayoutTests/webrtc/video-replace-track-to-null.html (232955 => 232956)


--- trunk/LayoutTests/webrtc/video-replace-track-to-null.html	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/LayoutTests/webrtc/video-replace-track-to-null.html	2018-06-19 07:20:51 UTC (rev 232956)
@@ -59,41 +59,49 @@
     return testFrameEncodedStopped(connection, ++count, framesEncodedNumber);
 }
 
-promise_test((test) => {
+var sender;
+var sendingTrack;
+var connection;
+promise_test(async (test) => {
     if (window.testRunner)
         testRunner.setUserMediaPermission(true);
 
-    var sender;
-    var frontStream;
-    var connection;
-    return navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
-        frontStream = stream;
-    }).then(() => {
-        return new Promise((resolve, reject) => {
-            createConnections((firstConnection) => {
-                connection = firstConnection;
-                sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
-            }, (secondConnection) => {
-                secondConnection._ontrack_ = (trackEvent) => {
-                    resolve(trackEvent.streams[0]);
-                };
-            });
-            setTimeout(() => reject("Test timed out"), 5000);
+    const frontStream = await navigator.mediaDevices.getUserMedia({ video: true });
+
+    const remoteStream = await new Promise((resolve, reject) => {
+        createConnections((firstConnection) => {
+            connection = firstConnection;
+            sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
+        }, (secondConnection) => {
+            secondConnection._ontrack_ = (trackEvent) => {
+                resolve(trackEvent.streams[0]);
+            };
         });
-    }).then((remoteStream) => {
-        video.srcObject = remoteStream;
-        return video.play();
-    }).then(() => {
-        return testFrameEncodedStarted(connection);
-    }).then(() => {
-    }).then(() => {
-        promise = sender.replaceTrack(null);
-        assert_true(!!sender.track);
-        return promise;
-    }).then(() => {
-        return testFrameEncodedStopped(connection);
+        setTimeout(() => reject("Test timed out"), 5000);
     });
-}, "Stopping sending video using replaceTrack");
+
+    video.srcObject = remoteStream;
+    await video.play();
+}, "Set-up test");
+
+promise_test(async (test) => {
+    await testFrameEncodedStarted(connection);
+
+    sendingTrack = sender.track;
+    assert_equals(sendingTrack.readyState, "live");
+}, "Test that frame counter increases");
+
+promise_test(async (test) => {
+    promise = sender.replaceTrack(null);
+    assert_true(!!sender.track);
+    await promise;
+    assert_equals(sender.track, null);
+}, "Test replaceTrack with null track");
+
+promise_test(async (test) => {
+    await testFrameEncodedStopped(connection);
+    assert_equals(sendingTrack.readyState, "live");
+}, "Test that frame counter no longer increases");
         </script>
     </body>
 </html>

Modified: trunk/Source/WebCore/ChangeLog (232955 => 232956)


--- trunk/Source/WebCore/ChangeLog	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/Source/WebCore/ChangeLog	2018-06-19 07:20:51 UTC (rev 232956)
@@ -1,3 +1,30 @@
+2018-06-19  Youenn Fablet  <[email protected]>
+
+        RTCRtpSender.replaceTrack(null) ends current track
+        https://bugs.webkit.org/show_bug.cgi?id=184911
+        <rdar://problem/40758138>
+
+        Reviewed by Eric Carlson.
+
+        Before the patch, when replacing the sender track by null, the previous track was stopped.
+        Instead of doing that, the track now stays alive and it is the realtime source that is stopped.
+        This ensures that the data is no longer sent while the track can still be used elsewhere.
+
+        Covered by updated and rebased tests.
+
+        * Modules/mediastream/PeerConnectionBackend.h:
+        * Modules/mediastream/RTCPeerConnection.cpp:
+        (WebCore::RTCPeerConnection::addTransceiver):
+        (WebCore::RTCPeerConnection::enqueueReplaceTrackTask):
+        (WebCore::RTCPeerConnection::replaceTrack):
+        * Modules/mediastream/RTCPeerConnection.h:
+        * Modules/mediastream/RTCRtpSender.cpp:
+        (WebCore::RTCRtpSender::replaceTrack):
+        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
+        (WebCore::updateTrackSource):
+        (WebCore::LibWebRTCPeerConnectionBackend::replaceTrack):
+        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:
+
 2018-06-18  Chris Dumez  <[email protected]>
 
         Better pack ResourceRequest

Modified: trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h (232955 => 232956)


--- trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h	2018-06-19 07:20:51 UTC (rev 232956)
@@ -101,7 +101,7 @@
     virtual Vector<RefPtr<MediaStream>> getRemoteStreams() const = 0;
 
     virtual Ref<RTCRtpReceiver> createReceiver(const String& transceiverMid, const String& trackKind, const String& trackId) = 0;
-    virtual void replaceTrack(RTCRtpSender&, Ref<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&) = 0;
+    virtual void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&) = 0;
     virtual void notifyAddedTrack(RTCRtpSender&) { }
     virtual void notifyRemovedTrack(RTCRtpSender&) { }
 

Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp (232955 => 232956)


--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp	2018-06-19 07:20:51 UTC (rev 232956)
@@ -199,6 +199,7 @@
     const String& trackKind = track->kind();
 
     auto sender = RTCRtpSender::create(WTFMove(track), Vector<String>(), *this);
+    m_backend->notifyAddedTrack(sender);
     return completeAddTransceiver(WTFMove(sender), init, trackId, trackKind);
 }
 
@@ -566,13 +567,20 @@
     dispatchEvent(event);
 }
 
-void RTCPeerConnection::enqueueReplaceTrackTask(RTCRtpSender& sender, Ref<MediaStreamTrack>&& withTrack, DOMPromiseDeferred<void>&& promise)
+void RTCPeerConnection::enqueueReplaceTrackTask(RTCRtpSender& sender, RefPtr<MediaStreamTrack>&& withTrack, DOMPromiseDeferred<void>&& promise)
 {
     scriptExecutionContext()->postTask([protectedThis = makeRef(*this), protectedSender = makeRef(sender), promise = WTFMove(promise), withTrack = WTFMove(withTrack)](ScriptExecutionContext&) mutable {
         if (protectedThis->isClosed())
             return;
+
+        if (!withTrack) {
+            protectedSender->setTrackToNull();
+            promise.resolve();
+            return;
+        }
+
         bool hasTrack = protectedSender->track();
-        protectedSender->setTrack(WTFMove(withTrack));
+        protectedSender->setTrack(withTrack.releaseNonNull());
         if (!hasTrack)
             protectedThis->m_backend->notifyAddedTrack(protectedSender.get());
         promise.resolve();
@@ -583,20 +591,12 @@
 {
     INFO_LOG(LOGIDENTIFIER);
 
-    if (!withTrack) {
-        scriptExecutionContext()->postTask([protectedSender = makeRef(sender), promise = WTFMove(promise)](ScriptExecutionContext&) mutable {
-            protectedSender->setTrackToNull();
-            promise.resolve();
-        });
-        return;
-    }
-    
-    if (!sender.track()) {
+    if (!sender.track() && withTrack) {
         enqueueReplaceTrackTask(sender, withTrack.releaseNonNull(), WTFMove(promise));
         return;
     }
 
-    m_backend->replaceTrack(sender, withTrack.releaseNonNull(), WTFMove(promise));
+    m_backend->replaceTrack(sender, WTFMove(withTrack), WTFMove(promise));
 }
 
 RTCRtpParameters RTCPeerConnection::getParameters(RTCRtpSender& sender) const

Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h (232955 => 232956)


--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h	2018-06-19 07:20:51 UTC (rev 232956)
@@ -153,7 +153,7 @@
     void disableICECandidateFiltering() { m_backend->disableICECandidateFiltering(); }
     void enableICECandidateFiltering() { m_backend->enableICECandidateFiltering(); }
 
-    void enqueueReplaceTrackTask(RTCRtpSender&, Ref<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&);
+    void enqueueReplaceTrackTask(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&);
 
     void clearController() { m_controller = nullptr; }
 

Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp (232955 => 232956)


--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp	2018-06-19 07:20:51 UTC (rev 232956)
@@ -89,9 +89,6 @@
         return;
     }
 
-    if (!withTrack && m_track)
-        m_track->stopTrack();
-
     m_backend->replaceTrack(*this, WTFMove(withTrack), WTFMove(promise));
 }
 

Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp (232955 => 232956)


--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp	2018-06-19 07:20:51 UTC (rev 232956)
@@ -372,12 +372,23 @@
     m_remoteStreams.append(WTFMove(mediaStream));
 }
 
-void LibWebRTCPeerConnectionBackend::replaceTrack(RTCRtpSender& sender, Ref<MediaStreamTrack>&& track, DOMPromiseDeferred<void>&& promise)
+template<typename Source>
+static inline bool updateTrackSource(Source& source, MediaStreamTrack* track)
 {
+    if (!track) {
+        source->stop();
+        return true;
+    }
+    return source->setSource(track->privateTrack());
+}
+
+void LibWebRTCPeerConnectionBackend::replaceTrack(RTCRtpSender& sender, RefPtr<MediaStreamTrack>&& track, DOMPromiseDeferred<void>&& promise)
+{
     ASSERT(sender.track());
+
     auto* currentTrack = sender.track();
 
-    ASSERT(currentTrack->source().type() == track->source().type());
+    ASSERT(!track || currentTrack->source().type() == track->source().type());
     switch (currentTrack->source().type()) {
     case RealtimeMediaSource::Type::None:
         ASSERT_NOT_REACHED();
@@ -386,7 +397,7 @@
     case RealtimeMediaSource::Type::Audio: {
         for (auto& audioSource : m_audioSources) {
             if (&audioSource->source() == &currentTrack->privateTrack()) {
-                if (!audioSource->setSource(track->privateTrack())) {
+                if (!updateTrackSource(audioSource, track.get())) {
                     promise.reject(InvalidModificationError);
                     return;
                 }
@@ -400,7 +411,7 @@
     case RealtimeMediaSource::Type::Video: {
         for (auto& videoSource : m_videoSources) {
             if (&videoSource->source() == &currentTrack->privateTrack()) {
-                if (!videoSource->setSource(track->privateTrack())) {
+                if (!updateTrackSource(videoSource, track.get())) {
                     promise.reject(InvalidModificationError);
                     return;
                 }

Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h (232955 => 232956)


--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h	2018-06-19 07:14:49 UTC (rev 232955)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h	2018-06-19 07:20:51 UTC (rev 232956)
@@ -73,7 +73,7 @@
     RefPtr<RTCSessionDescription> currentRemoteDescription() const final;
     RefPtr<RTCSessionDescription> pendingRemoteDescription() const final;
 
-    void replaceTrack(RTCRtpSender&, Ref<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&) final;
+    void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&) final;
     RTCRtpParameters getParameters(RTCRtpSender&) const final;
 
     void emulatePlatformEvent(const String&) final { }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to