[iOS] Switching cameras in a WebRTC call makes black frames being sent
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Jun 2017 23:16:38 +0000 (23:16 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Jun 2017 23:16:38 +0000 (23:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=173486

Patch by Youenn Fablet <youenn@apple.com> on 2017-06-16
Reviewed by Eric Carlson.

Source/WebCore:

Test: webrtc/video-replace-muted-track.html

* platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp:
(WebCore::RealtimeOutgoingVideoSource::updateBlackFramesSending):
Ensuring the timer is stopped if needed.
(WebCore::RealtimeOutgoingVideoSource::initializeFromSource):
Calling updateBlackFramesSending to stop sending frame if needed.

LayoutTests:

* webrtc/video-replace-muted-track-expected.txt: Added.
* webrtc/video-replace-muted-track.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@218426 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/webrtc/video-replace-muted-track-expected.txt [new file with mode: 0644]
LayoutTests/webrtc/video-replace-muted-track.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp

index e822992..966bb4c 100644 (file)
@@ -1,3 +1,13 @@
+2017-06-16  Youenn Fablet  <youenn@apple.com>
+
+        [iOS] Switching cameras in a WebRTC call makes black frames being sent
+        https://bugs.webkit.org/show_bug.cgi?id=173486
+
+        Reviewed by Eric Carlson.
+
+        * webrtc/video-replace-muted-track-expected.txt: Added.
+        * webrtc/video-replace-muted-track.html: Added.
+
 2017-06-16  Ryan Haddad  <ryanhaddad@apple.com>
 
         Remove a test that was accidentally checked in with r218408.
diff --git a/LayoutTests/webrtc/video-replace-muted-track-expected.txt b/LayoutTests/webrtc/video-replace-muted-track-expected.txt
new file mode 100644 (file)
index 0000000..d6b4915
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS Switching from disabled to enabled track 
+
diff --git a/LayoutTests/webrtc/video-replace-muted-track.html b/LayoutTests/webrtc/video-replace-muted-track.html
new file mode 100644 (file)
index 0000000..d6d9841
--- /dev/null
@@ -0,0 +1,105 @@
+<!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>
+<div id="log"></div>
+        <video id="video" autoplay=""></video>
+        <canvas id="canvas" width="640" height="480"></canvas>
+        <script src ="routines.js"></script>
+        <script>
+function isVideoBlack()
+{
+    canvas.width = video.videoWidth;
+    canvas.height = video.videoHeight;
+    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
+
+    imageData = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
+    data = imageData.data;
+    for (var cptr = 0; cptr < canvas.width * canvas.height; ++cptr) {
+        // Approximatively black pixels.
+        if (data[4 * cptr] > 10 || data[4 * cptr + 1] > 10 || data[4 * cptr + 2] > 10)
+            return false;
+    }
+    return true;
+}
+
+var stopPolling = false;
+function pollVideoBlackCheck(expected, resolve, delay)
+{
+    if (isVideoBlack() === expected || stopPolling) {
+        resolve();
+        return;
+    }
+
+    setTimeout(() => pollVideoBlackCheck(expected, resolve), delay);
+}
+
+function checkVideoBlack(expected, duration, id, delay)
+{
+    stopPolling = false;
+    return new Promise((resolve, reject) => {
+        pollVideoBlackCheck(expected, resolve, delay);
+        setTimeout(() => {
+            reject("checkVideoBlack timed out for " + id + ", expected " + expected);
+            stopPolling = true;
+        }, duration);
+    });
+}
+
+function grabImagePixels()
+{
+    canvas.width = video.videoWidth;
+    canvas.height = video.videoHeight;
+    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
+
+    imageData = canvas.getContext('2d').getImageData(20, 20, 2, 2);
+    return imageData.data;
+}
+
+promise_test((test) => {
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(true);
+
+    var sender;
+    var firstTrack;
+    return navigator.mediaDevices.getUserMedia({ video: { facingMode: { exact: ["user"] } } }).then((stream) => {
+        frontStream = stream;
+        return new Promise((resolve, reject) => {
+            createConnections((firstConnection) => {
+                firstTrack = frontStream.getVideoTracks()[0];
+                sender = firstConnection.addTrack(firstTrack, frontStream);
+           }, (secondConnection) => {
+                secondConnection.ontrack = (trackEvent) => {
+                    resolve(trackEvent.streams[0]);
+                };
+            });
+            setTimeout(() => reject("Test timed out"), 5000);
+        });
+    }).then((remoteStream) => {
+        video.srcObject = remoteStream;
+        return video.play();
+    }).then(() => {
+        firstTrack.enabled = false;
+        return waitFor(200);
+    }).then(() => {
+        return navigator.mediaDevices.getUserMedia({ video: { facingMode: { exact: ["environment"] } } });
+    }).then((stream) => {
+        return sender.replaceTrack(stream.getVideoTracks()[0]);
+    }).then(() => {
+        return waitFor(200);
+    }).then(() => {
+        // Let's ensure we have some non black frames sent.
+        return checkVideoBlack(false, 5000, "test2", 200);
+    }).then(() => {
+        // Let's ensure there are no black frames sent.
+        return checkVideoBlack(true, 2000, "test3", 50).then(assert_unreached, () => { });
+    });
+}, "Switching from disabled to enabled track");
+        </script>
+    </body>
+</html>
index 0cc4c58..7bc2679 100644 (file)
@@ -1,5 +1,20 @@
 2017-06-16  Youenn Fablet  <youenn@apple.com>
 
+        [iOS] Switching cameras in a WebRTC call makes black frames being sent
+        https://bugs.webkit.org/show_bug.cgi?id=173486
+
+        Reviewed by Eric Carlson.
+
+        Test: webrtc/video-replace-muted-track.html
+
+        * platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp:
+        (WebCore::RealtimeOutgoingVideoSource::updateBlackFramesSending):
+        Ensuring the timer is stopped if needed.
+        (WebCore::RealtimeOutgoingVideoSource::initializeFromSource):
+        Calling updateBlackFramesSending to stop sending frame if needed.
+
+2017-06-16  Youenn Fablet  <youenn@apple.com>
+
         Remove replaceTrack restriction about video resolution
         https://bugs.webkit.org/show_bug.cgi?id=173490
 
index 5270c06..c974043 100644 (file)
@@ -74,8 +74,9 @@ void RealtimeOutgoingVideoSource::stop()
 
 void RealtimeOutgoingVideoSource::updateBlackFramesSending()
 {
-    if (!m_muted && m_enabled && m_blackFrameTimer.isActive()) {
-        m_blackFrameTimer.stop();
+    if (!m_muted && m_enabled) {
+        if (m_blackFrameTimer.isActive())
+            m_blackFrameTimer.stop();
         return;
     }
 
@@ -109,7 +110,7 @@ void RealtimeOutgoingVideoSource::initializeFromSource()
     m_muted = m_videoSource->muted();
     m_enabled = m_videoSource->enabled();
 
-    sendBlackFramesIfNeeded();
+    updateBlackFramesSending();
 }
 
 bool RealtimeOutgoingVideoSource::GetStats(Stats*)