- Revision
- 236090
- Author
- [email protected]
- Date
- 2018-09-17 15:22:15 -0700 (Mon, 17 Sep 2018)
Log Message
track.onmute isn't called for a remote MediaStreamTrack when its counter part track is removed from the peer connection
https://bugs.webkit.org/show_bug.cgi?id=176281
<rdar://problem/44525674>
Reviewed by Eric Carlson.
Source/WebCore:
Listen to libwebrtc remove track callbacks.
Implement handling as per https://w3c.github.io/webrtc-pc/#process-remote-track-removal.
This triggers a mute event on the track.
Test: webrtc/remove-track.html
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
(WebCore::LibWebRTCMediaEndpoint::removeRemoteTrack):
(WebCore::LibWebRTCMediaEndpoint::OnRemoveTrack):
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h:
* Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
(WebCore::LibWebRTCPeerConnectionBackend::shouldOfferAllowToReceive const):
Drive by fix: Plan B code path does not mandate having an rtc backend for each sender.
LayoutTests:
* webrtc/remove-track-expected.txt: Added.
* webrtc/remove-track.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (236089 => 236090)
--- trunk/LayoutTests/ChangeLog 2018-09-17 22:21:32 UTC (rev 236089)
+++ trunk/LayoutTests/ChangeLog 2018-09-17 22:22:15 UTC (rev 236090)
@@ -1,3 +1,14 @@
+2018-09-17 Youenn Fablet <[email protected]>
+
+ track.onmute isn't called for a remote MediaStreamTrack when its counter part track is removed from the peer connection
+ https://bugs.webkit.org/show_bug.cgi?id=176281
+ <rdar://problem/44525674>
+
+ Reviewed by Eric Carlson.
+
+ * webrtc/remove-track-expected.txt: Added.
+ * webrtc/remove-track.html: Added.
+
2018-09-17 Dawei Fenton <[email protected]>
Fixed typo in TestExpectations file.
Added: trunk/LayoutTests/webrtc/remove-track-expected.txt (0 => 236090)
--- trunk/LayoutTests/webrtc/remove-track-expected.txt (rev 0)
+++ trunk/LayoutTests/webrtc/remove-track-expected.txt 2018-09-17 22:22:15 UTC (rev 236090)
@@ -0,0 +1,5 @@
+
+PASS Setup audio video exchange
+PASS Remove video track
+PASS Remove audio track
+
Added: trunk/LayoutTests/webrtc/remove-track.html (0 => 236090)
--- trunk/LayoutTests/webrtc/remove-track.html (rev 0)
+++ trunk/LayoutTests/webrtc/remove-track.html 2018-09-17 22:22:15 UTC (rev 236090)
@@ -0,0 +1,72 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing basic video exchange from offerer to receiver</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src =""
+ <script>
+let firstConnection, secondConnection;
+let stream;
+let remoteAudioTrack, remoteVideoTrack;
+promise_test(async (test) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+
+ stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
+ await new Promise((resolve, reject) => {
+ createConnections((connection) => {
+ firstConnection = connection;
+ firstConnection.addTrack(stream.getVideoTracks()[0], stream);
+ firstConnection.addTrack(stream.getAudioTracks()[0], stream);
+ }, (connection) => {
+ secondConnection = connection;
+ secondConnection._ontrack_ = (trackEvent) => {
+ if (!remoteVideoTrack) {
+ remoteVideoTrack = trackEvent.track;
+ return;
+ }
+ remoteAudioTrack = trackEvent.track;
+ resolve();
+ };
+ });
+ setTimeout(() => reject("Test timed out"), 5000);
+ });
+}, "Setup audio video exchange");
+
+async function renegotiate()
+{
+ let d = await firstConnection.createOffer();
+ await firstConnection.setLocalDescription(d);
+ await secondConnection.setRemoteDescription(firstConnection.localDescription);
+ d = await secondConnection.createAnswer();
+ await secondConnection.setLocalDescription(d);
+}
+
+promise_test((test) => {
+ const promise = new Promise((resolve, reject) => {
+ remoteVideoTrack._onmute_ = resolve;
+ setTimeout(() => reject("Test timed out"), 5000);
+ });
+
+ firstConnection.removeTrack(firstConnection.getSenders()[0]);
+ renegotiate();
+ return promise;
+}, "Remove video track");
+
+promise_test((test) => {
+ const promise = new Promise((resolve, reject) => {
+ remoteAudioTrack._onmute_ = resolve;
+ setTimeout(() => reject("Test timed out"), 5000);
+ });
+
+ firstConnection.removeTrack(firstConnection.getSenders()[1]);
+ renegotiate();
+ return promise;
+}, "Remove audio track");
+ </script>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (236089 => 236090)
--- trunk/Source/WebCore/ChangeLog 2018-09-17 22:21:32 UTC (rev 236089)
+++ trunk/Source/WebCore/ChangeLog 2018-09-17 22:22:15 UTC (rev 236090)
@@ -1,3 +1,25 @@
+2018-09-17 Youenn Fablet <[email protected]>
+
+ track.onmute isn't called for a remote MediaStreamTrack when its counter part track is removed from the peer connection
+ https://bugs.webkit.org/show_bug.cgi?id=176281
+ <rdar://problem/44525674>
+
+ Reviewed by Eric Carlson.
+
+ Listen to libwebrtc remove track callbacks.
+ Implement handling as per https://w3c.github.io/webrtc-pc/#process-remote-track-removal.
+ This triggers a mute event on the track.
+
+ Test: webrtc/remove-track.html
+
+ * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+ (WebCore::LibWebRTCMediaEndpoint::removeRemoteTrack):
+ (WebCore::LibWebRTCMediaEndpoint::OnRemoveTrack):
+ * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h:
+ * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
+ (WebCore::LibWebRTCPeerConnectionBackend::shouldOfferAllowToReceive const):
+ Drive by fix: Plan B code path does not mandate having an rtc backend for each sender.
+
2018-09-17 Simon Fraser <[email protected]>
Add more Fullscreen logging
Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp (236089 => 236090)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp 2018-09-17 22:21:32 UTC (rev 236089)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp 2018-09-17 22:22:15 UTC (rev 236090)
@@ -445,6 +445,22 @@
fireTrackEvent(makeRef(newTransceiver.receiver()), newTransceiver.receiver().track(), rtcReceiver->streams(), makeRef(newTransceiver));
}
+void LibWebRTCMediaEndpoint::removeRemoteTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>&& receiver)
+{
+ // FIXME: Support plan B code path.
+ if (!RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled())
+ return;
+
+ auto* transceiver = m_peerConnectionBackend.existingTransceiver([&receiver](auto& transceiverBackend) {
+ auto* rtcTransceiver = transceiverBackend.rtcTransceiver();
+ return rtcTransceiver && receiver.get() == rtcTransceiver->receiver().get();
+ });
+ if (!transceiver)
+ return;
+
+ transceiver->receiver().track().source().setMuted(true);
+}
+
template<typename T>
std::optional<LibWebRTCMediaEndpoint::Backends> LibWebRTCMediaEndpoint::createTransceiverBackends(T&& trackOrKind, const RTCRtpTransceiverInit& init, LibWebRTCRtpSenderBackend::Source&& source)
{
@@ -546,6 +562,14 @@
});
}
+void LibWebRTCMediaEndpoint::OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)
+{
+ callOnMainThread([protectedThis = makeRef(*this), receiver = WTFMove(receiver)]() mutable {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->removeRemoteTrack(WTFMove(receiver));
+ });
+}
std::unique_ptr<RTCDataChannelHandler> LibWebRTCMediaEndpoint::createDataChannel(const String& label, const RTCDataChannelInit& options)
{
Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h (236089 => 236090)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h 2018-09-17 22:21:32 UTC (rev 236089)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h 2018-09-17 22:22:15 UTC (rev 236090)
@@ -118,6 +118,7 @@
void OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>) final;
void OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&) final;
void OnTrack(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>) final;
+ void OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>) final;
void OnRenegotiationNeeded() final;
void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState) final;
@@ -135,6 +136,7 @@
void addRemoteTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>&&, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&);
void removeRemoteStream(webrtc::MediaStreamInterface&);
void newTransceiver(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>&&);
+ void removeRemoteTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>&&);
void fireTrackEvent(Ref<RTCRtpReceiver>&&, Ref<MediaStreamTrack>&&, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&, RefPtr<RTCRtpTransceiver>&&);
Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp (236089 => 236090)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp 2018-09-17 22:21:32 UTC (rev 236089)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp 2018-09-17 22:22:15 UTC (rev 236090)
@@ -486,8 +486,8 @@
if (transceiver->direction() != RTCRtpTransceiverDirection::Sendrecv)
continue;
- auto& backend = static_cast<LibWebRTCRtpSenderBackend&>(*transceiver->sender().backend());
- if (!backend.rtcSender())
+ auto* backend = static_cast<LibWebRTCRtpSenderBackend*>(transceiver->sender().backend());
+ if (backend && !backend->rtcSender())
return true;
}
return false;