ontrack events should be fired even if an existing transceiver exists
https://bugs.webkit.org/show_bug.cgi?id=189477
Reviewed by Eric Carlson.
Source/WebCore:
In case of an OnTrack callback from libwebrtc, make sure the ontrack event is called even if a transceiver already exists for that track.
Covered by updated video-addTransceiver.html
New test video-addLegacyTransceiver.html keeps testing the old transceiver behavior.
Test: webrtc/video-addLegacyTransceiver.html
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
(WebCore::LibWebRTCMediaEndpoint::newTransceiver):
LayoutTests:
* webrtc/video-addLegacyTransceiver-expected.txt: Added.
* webrtc/video-addLegacyTransceiver.html: Copied from LayoutTests/webrtc/video-addTransceiver.html.
* webrtc/video-addTransceiver.html:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@235869 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 6100f1e..3a4d6d0 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2018-09-10 Youenn Fablet <youenn@apple.com>
+
+ ontrack events should be fired even if an existing transceiver exists
+ https://bugs.webkit.org/show_bug.cgi?id=189477
+
+ Reviewed by Eric Carlson.
+
+ * webrtc/video-addLegacyTransceiver-expected.txt: Added.
+ * webrtc/video-addLegacyTransceiver.html: Copied from LayoutTests/webrtc/video-addTransceiver.html.
+ * webrtc/video-addTransceiver.html:
+
2018-09-10 Megan Gardner <megan_gardner@apple.com>
Correctly interpret from angle for conic gradients
diff --git a/LayoutTests/webrtc/video-addLegacyTransceiver-expected.txt b/LayoutTests/webrtc/video-addLegacyTransceiver-expected.txt
new file mode 100644
index 0000000..8790e6b
--- /dev/null
+++ b/LayoutTests/webrtc/video-addLegacyTransceiver-expected.txt
@@ -0,0 +1,6 @@
+
+
+PASS Setting up calls with addTransceiver but with no track
+PASS Setting up calls with addTransceiver with a track
+PASS Basic video exchange set up with addTransceiver
+
diff --git a/LayoutTests/webrtc/video-addLegacyTransceiver.html b/LayoutTests/webrtc/video-addLegacyTransceiver.html
new file mode 100644
index 0000000..3ca754c
--- /dev/null
+++ b/LayoutTests/webrtc/video-addLegacyTransceiver.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing basic video exchange from offerer to receiver</title>
+ <script src="../resources/testharness.js"></script>
+ <script src="../resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <video id="video" autoplay=""></video>
+ <canvas id="canvas" width="640" height="480"></canvas>
+ <script src ="routines.js"></script>
+ <script>
+if (window.testRunner)
+ testRunner.setWebRTCUnifiedPlanEnabled(false);
+
+promise_test((test) => {
+ var pc = new RTCPeerConnection();
+ pc.addTransceiver("video");
+
+ return pc.createOffer().then((offer) => {
+ assert_true(offer.sdp.indexOf("mid:video") !== -1);
+ assert_true(offer.sdp.indexOf("a=recvonly") !== -1);
+
+ pc.addTransceiver("audio");
+ return pc.createOffer();
+ }).then((offer) => {
+ assert_true(offer.sdp.indexOf("mid:audio") !== -1);
+ });
+}, "Setting up calls with addTransceiver but with no track");
+
+promise_test((test) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+
+ return navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
+ var pc = new RTCPeerConnection();
+ pc.addTransceiver("video");
+ pc.getSenders()[0].replaceTrack(stream.getVideoTracks()[0]);
+
+ return pc.createOffer().then((offer) => {
+ assert_true(offer.sdp.indexOf("mid:video") !== -1);
+ // Replacing the track is not done yet so we still set it as a recvonly.
+ assert_true(offer.sdp.indexOf("a=recvonly") !== -1);
+ });
+ });
+}, "Setting up calls with addTransceiver with a track");
+
+function testImage()
+{
+ canvas.width = video.videoWidth;
+ canvas.height = video.videoHeight;
+ canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
+
+ imageData = canvas.getContext('2d').getImageData(10, 325, 250, 1);
+ data = imageData.data;
+
+ var index = 20;
+ assert_true(data[index] < 100);
+ assert_true(data[index + 1] < 100);
+ assert_true(data[index + 2] < 100);
+
+ index = 80;
+ assert_true(data[index] > 200);
+ assert_true(data[index + 1] > 200);
+ assert_true(data[index + 2] > 200);
+
+ index += 80;
+ assert_true(data[index] > 200);
+ assert_true(data[index + 1] > 200);
+ assert_true(data[index + 2] < 100);
+}
+
+promise_test((test) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+
+ return navigator.mediaDevices.getUserMedia({ video: true}).then((stream) => {
+ return new Promise((resolve, reject) => {
+ createConnections((firstConnection) => {
+ var track = stream.getVideoTracks()[0];
+ firstConnection.addTransceiver("video");
+ return firstConnection.getSenders()[0].replaceTrack(stream.getVideoTracks()[0]);
+ }, (secondConnection) => {
+ secondConnection.ontrack = (trackEvent) => {
+ resolve(trackEvent.streams[0]);
+ };
+ });
+ setTimeout(() => reject("Test timed out"), 5000);
+ });
+ }).then((stream) => {
+ video.srcObject = stream;
+ return video.play();
+ }).then(() => {
+ testImage();
+ });
+}, "Basic video exchange set up with addTransceiver");
+
+ </script>
+ </body>
+</html>
diff --git a/LayoutTests/webrtc/video-addTransceiver.html b/LayoutTests/webrtc/video-addTransceiver.html
index 3ca754c..42c7c99 100644
--- a/LayoutTests/webrtc/video-addTransceiver.html
+++ b/LayoutTests/webrtc/video-addTransceiver.html
@@ -11,39 +11,32 @@
<canvas id="canvas" width="640" height="480"></canvas>
<script src ="routines.js"></script>
<script>
-if (window.testRunner)
- testRunner.setWebRTCUnifiedPlanEnabled(false);
-
-promise_test((test) => {
+promise_test(async (test) => {
var pc = new RTCPeerConnection();
pc.addTransceiver("video");
- return pc.createOffer().then((offer) => {
- assert_true(offer.sdp.indexOf("mid:video") !== -1);
- assert_true(offer.sdp.indexOf("a=recvonly") !== -1);
+ let offer = await pc.createOffer();
+ assert_true(offer.sdp.indexOf("m=video") !== -1, "mid");
+ assert_true(offer.sdp.indexOf("a=sendrecv") !== -1, "recvonly");
- pc.addTransceiver("audio");
- return pc.createOffer();
- }).then((offer) => {
- assert_true(offer.sdp.indexOf("mid:audio") !== -1);
- });
+ pc.addTransceiver("audio");
+ offer = await pc.createOffer();
+ assert_true(offer.sdp.indexOf("m=audio") !== -1, "m=audio");
}, "Setting up calls with addTransceiver but with no track");
-promise_test((test) => {
+promise_test(async (test) => {
if (window.testRunner)
testRunner.setUserMediaPermission(true);
- return navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
- var pc = new RTCPeerConnection();
- pc.addTransceiver("video");
- pc.getSenders()[0].replaceTrack(stream.getVideoTracks()[0]);
+ const stream = await navigator.mediaDevices.getUserMedia({ video: true });
+ var pc = new RTCPeerConnection();
+ pc.addTransceiver("video", {direction:"recvonly"});
+ pc.getSenders()[0].replaceTrack(stream.getVideoTracks()[0]);
- return pc.createOffer().then((offer) => {
- assert_true(offer.sdp.indexOf("mid:video") !== -1);
- // Replacing the track is not done yet so we still set it as a recvonly.
- assert_true(offer.sdp.indexOf("a=recvonly") !== -1);
- });
- });
+ const offer = await pc.createOffer();
+ assert_true(offer.sdp.indexOf("m=video") !== -1, "m=video");
+ // Replacing the track is not done yet so we still set it as a recvonly.
+ assert_true(offer.sdp.indexOf("a=recvonly") !== -1, "a=recvonly");
}, "Setting up calls with addTransceiver with a track");
function testImage()
@@ -71,29 +64,27 @@
assert_true(data[index + 2] < 100);
}
-promise_test((test) => {
+promise_test(async (test) => {
if (window.testRunner)
testRunner.setUserMediaPermission(true);
- return navigator.mediaDevices.getUserMedia({ video: true}).then((stream) => {
- return new Promise((resolve, reject) => {
- createConnections((firstConnection) => {
- var track = stream.getVideoTracks()[0];
- firstConnection.addTransceiver("video");
- return firstConnection.getSenders()[0].replaceTrack(stream.getVideoTracks()[0]);
- }, (secondConnection) => {
- secondConnection.ontrack = (trackEvent) => {
- resolve(trackEvent.streams[0]);
- };
- });
- setTimeout(() => reject("Test timed out"), 5000);
+ const stream = await navigator.mediaDevices.getUserMedia({ video: true});
+ const track = await new Promise((resolve, reject) => {
+ createConnections((firstConnection) => {
+ var track = stream.getVideoTracks()[0];
+ firstConnection.addTransceiver("video");
+ return firstConnection.getSenders()[0].replaceTrack(stream.getVideoTracks()[0]);
+ }, (secondConnection) => {
+ secondConnection.addTransceiver("video");
+ secondConnection.ontrack = (trackEvent) => {
+ resolve(trackEvent.track);
+ };
});
- }).then((stream) => {
- video.srcObject = stream;
- return video.play();
- }).then(() => {
- testImage();
+ setTimeout(() => reject("Test timed out"), 5000);
});
+ video.srcObject = new MediaStream([track]);
+ await video.play();
+ testImage();
}, "Basic video exchange set up with addTransceiver");
</script>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 102a590..737b51e 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2018-09-10 Youenn Fablet <youenn@apple.com>
+
+ ontrack events should be fired even if an existing transceiver exists
+ https://bugs.webkit.org/show_bug.cgi?id=189477
+
+ Reviewed by Eric Carlson.
+
+ In case of an OnTrack callback from libwebrtc, make sure the ontrack event is called even if a transceiver already exists for that track.
+
+ Covered by updated video-addTransceiver.html
+ New test video-addLegacyTransceiver.html keeps testing the old transceiver behavior.
+ Test: webrtc/video-addLegacyTransceiver.html
+
+ * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+ (WebCore::LibWebRTCMediaEndpoint::newTransceiver):
+
2018-09-10 Megan Gardner <megan_gardner@apple.com>
Correctly interpret from angle for conic gradients
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp
index 01b4aa2..3e07af5 100644
--- a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp
@@ -427,7 +427,9 @@
return rtcTransceiver.get() == transceiverBackend.rtcTransceiver();
});
if (transceiver) {
- setExistingReceiverSourceTrack(transceiver->receiver().track().source(), *rtcTransceiver->receiver());
+ auto rtcReceiver = rtcTransceiver->receiver();
+ setExistingReceiverSourceTrack(transceiver->receiver().track().source(), *rtcReceiver);
+ fireTrackEvent(makeRef(transceiver->receiver()), transceiver->receiver().track(), rtcReceiver->streams(), makeRef(*transceiver));
return;
}