| <!doctype html> |
| <meta charset=utf-8> |
| <meta name="timeout" content="long"> |
| <title>RTCPeerConnection Video detector test</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="RTCPeerConnection-helper.js"></script> |
| <script> |
| 'use strict'; |
| |
| // This test verifies that the helper function "detectSignal" from |
| // RTCPeerConnectionHelper, which is used to detect changes in a video |
| // signal, performs properly for a range of "signal" values. |
| |
| // If it fails, it indicates that the video codec used in this particular |
| // browser at this time doesn't reproduce the luma signal reliably enough |
| // for this particular application, which may lead to other tests that |
| // use the "detectSignal" helper failing without an obvious cause. |
| |
| // The most likely failure is timeout - which will happen if the |
| // luma value detected doesn't settle within the margin of error before |
| // the test times out. |
| |
| async function signalSettlementTime(t, v, sender, signal, backgroundTrack) { |
| const detectionStream = await getNoiseStream({video: {signal}}); |
| const [detectionTrack] = detectionStream.getTracks(); |
| try { |
| await sender.replaceTrack(detectionTrack); |
| const framesBefore = v.getVideoPlaybackQuality().totalVideoFrames; |
| await detectSignal(t, v, signal); |
| const framesAfter = v.getVideoPlaybackQuality().totalVideoFrames; |
| await sender.replaceTrack(backgroundTrack); |
| await detectSignal(t, v, 100); |
| return framesAfter - framesBefore; |
| } finally { |
| detectionTrack.stop(); |
| } |
| } |
| |
| promise_test(async t => { |
| const v = document.createElement('video'); |
| v.autoplay = true; |
| const pc1 = new RTCPeerConnection(); |
| const pc2 = new RTCPeerConnection(); |
| t.add_cleanup(() => pc1.close()); |
| t.add_cleanup(() => pc2.close()); |
| const stream1 = await getNoiseStream({video: {signal: 100}}); |
| const [track1] = stream1.getTracks(); |
| t.add_cleanup(() => track1.stop()); |
| |
| const sender = pc1.addTrack(track1); |
| const haveTrackEvent = new Promise(r => pc2.ontrack = r); |
| exchangeIceCandidates(pc1, pc2); |
| await exchangeOfferAnswer(pc1, pc2); |
| v.srcObject = new MediaStream([(await haveTrackEvent).track]); |
| await new Promise(r => v.onloadedmetadata = r); |
| // The basic signal is a track with signal 100. We replace this |
| // with tracks with signal from 0 to 255 and see if they are all |
| // reliably detected. |
| await detectSignal(t, v, 100); |
| // A few buffered frames are received with the old content, and a few |
| // frames may not have settled on exactly the right value. In testing, |
| // this test passes with maxFrames = 3; give a little more margin. |
| const maxFrames = 7; |
| // Test values 0 and 255 |
| let maxCount = await signalSettlementTime(t, v, sender, 0, track1); |
| assert_less_than(maxCount, maxFrames, |
| 'Should get the black value within ' + maxFrames + ' frames'); |
| maxCount = Math.max( |
| await signalSettlementTime(t, v, sender, 255, track1), maxCount); |
| assert_less_than(maxCount, maxFrames, |
| 'Should get the white value within ' + maxFrames + ' frames'); |
| // Test a set of other values - far enough apart to make the test fast. |
| for (let signal = 2; signal <= 255; signal += 47) { |
| if (Math.abs(signal - 100) > 10) { |
| const count = await signalSettlementTime(t, v, sender, signal, track1); |
| maxCount = Math.max(count, maxCount); |
| assert_less_than(maxCount, 10, |
| 'Should get value ' + signal + ' within ' + maxFrames + ' frames'); |
| } |
| } |
| assert_less_than(maxCount, 10, 'Should get the right value within 10 frames'); |
| }, 'Signal detector detects track change within reasonable time'); |
| </script> |