| <!doctype html> |
| <meta charset=utf-8> |
| <meta name="timeout" content="long"> |
| <title>Relay canvas via PeerConnections</title> |
| <script src=/resources/testharness.js></script> |
| <script src=/resources/testharnessreport.js></script> |
| <script src="RTCPeerConnection-helper.js"></script> |
| <script> |
| 'use strict'; |
| |
| // This test checks that canvas capture works relayed between several peer connections. |
| |
| function GreenFrameWebGL(width, height) { |
| const canvas = |
| Object.assign(document.createElement('canvas'), {width, height}); |
| const ctx = canvas.getContext('webgl'); |
| if (ctx === null) return; |
| requestAnimationFrame(function draw () { |
| ctx.clearColor(0.0, 1.0, 0.0, 1.0); |
| ctx.clear(ctx.COLOR_BUFFER_BIT); |
| requestAnimationFrame(draw); |
| }); |
| return canvas.captureStream(); |
| } |
| |
| |
| |
| promise_test(async t => { |
| |
| // Build a chain |
| // canvas -track-> pc1 -network-> pcRelayIn -track-> |
| // pcRelayOut -network-> pc2 -track-> video |
| const pc1 = new RTCPeerConnection(); |
| t.add_cleanup(() => pc1.close()); |
| const pcRelayIn = new RTCPeerConnection(); |
| t.add_cleanup(() => pcRelayIn.close()); |
| |
| const pcRelayOut = new RTCPeerConnection(); |
| t.add_cleanup(() => pcRelayOut.close()); |
| const pc2 = new RTCPeerConnection(); |
| t.add_cleanup(() => pc2.close()); |
| |
| // Attach canvas to pc1. |
| const stream = GreenFrameWebGL(640, 480); |
| const [track] = stream.getTracks(); |
| pc1.addTrack(track); |
| |
| const v = document.createElement('video'); |
| v.autoplay = true; |
| |
| // Setup pc1->pcRelayIn video stream. |
| const haveTrackEvent1 = new Promise(r => pcRelayIn.ontrack = r); |
| exchangeIceCandidates(pc1, pcRelayIn); |
| await pc1.setLocalDescription(); |
| await pcRelayIn.setRemoteDescription(pc1.localDescription); |
| await pcRelayIn.setLocalDescription(); |
| await pc1.setRemoteDescription(pcRelayIn.localDescription); |
| |
| // Plug output of pcRelayIn to pcRelayOut. |
| pcRelayOut.addTrack((await haveTrackEvent1).track); |
| |
| // Setup pcRelayOut->pc2 video stream. |
| const haveTrackEvent2 = new Promise(r => pc2.ontrack = r); |
| exchangeIceCandidates(pcRelayOut, pc2); |
| await pcRelayOut.setLocalDescription(); |
| await pc2.setRemoteDescription(pcRelayOut.localDescription); |
| await pc2.setLocalDescription(); |
| await pcRelayOut.setRemoteDescription(pc2.localDescription); |
| |
| // Display pc2 received track in video element. |
| v.srcObject = new MediaStream([(await haveTrackEvent2).track]); |
| await new Promise(r => v.onloadedmetadata = r); |
| |
| // Wait some time to ensure that frames got through. |
| await new Promise(resolve => t.step_timeout(resolve, 1000)); |
| |
| // Uses Helper.js GetVideoSignal to query |v| pixel value at a certain position. |
| const pixelValue = getVideoSignal(v); |
| |
| // Expected value computed based on GetVideoSignal code, which takes green pixel data |
| // with coefficient 0.72. |
| assert_approx_equals(pixelValue, 0.72*255, 2); |
| }, "Two PeerConnections relaying a canvas source"); |
| </script> |