[MediaStream] A stream's first video frame should be rendered
[WebKit-https.git] / LayoutTests / fast / mediastream / MediaStream-video-element-video-tracks-disabled-then-enabled.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4     <script src="../../resources/js-test-pre.js"></script>
5 </head>
6 <body onload="start()">
7 <p id="description"></p>
8 <div id="console"></div>
9 <video controls width="680" height="360"></video>
10 <canvas width="680" height="360"></canvas>
11 <script>
12     let canvas;
13     let context;
14     let mediaStream;
15     let video;
16     
17     let buffer;
18
19     function isPixelBlack(pixel)
20     {
21         return pixel[0] === 0 && pixel[1] === 0 && pixel[2] === 0 && pixel[3] === 255;
22     }
23
24     function isPixelTransparent(pixel)
25     {
26         return pixel[0] === 0 && pixel[1] === 0 && pixel[2] === 0 && pixel[3] === 0;
27     }
28
29     function isPixelWhite(pixel)
30     {
31         return pixel[0] === 255 && pixel[1] === 255 && pixel[2] === 255 && pixel[3] === 255;
32     }
33
34     function canvasShouldBeBlack()
35     {
36         return !mediaStream.getVideoTracks()[0].enabled;
37     }
38     
39     function attempt(numberOfTries, call, callback)
40     {
41         if (numberOfTries <= 0) {
42             testFailed('Pixel check did not succeed after multiple tries.');
43             return;
44         }
45
46         let attemptSucceeded = call();
47         if (attemptSucceeded) {
48             testPassed(canvasShouldBeBlack() ? 'pixel was black.' : 'pixel was white.');
49             callback();
50
51             return;
52         }
53         
54         setTimeout(() => { attempt(--numberOfTries, call, callback); }, 50);
55     }
56
57     function repeatWithVideoPlayingAndFinishTest()
58     {
59         if (video.paused) {
60             debug('<br> ===== play video =====');
61             evalAndLog('video.play()');
62             beginTestRound();
63         } else {
64             debug('');
65             video.pause();
66             finishJSTest();
67         }
68     }
69
70     function reenableTrack()
71     {
72         mediaStream.getVideoTracks()[0].enabled = true;
73         debug(`<br> === video track reenabled, should render current frame ===`);
74
75         // The video is not guaranteed to render non-black frames before the canvas is drawn to and the pixels are checked.
76         // A timeout is used to ensure that the pixel check is done after the video renders non-black frames.
77         attempt(10, checkPixels, repeatWithVideoPlayingAndFinishTest);
78     }
79
80     function checkPixels()
81     {
82         context.clearRect(0, 0, canvas.width, canvas.height);
83         buffer = context.getImageData(30, 242, 1, 1).data;
84         if (!isPixelTransparent(buffer))
85             testFailed('pixel was not transparent after clearing canvas.');
86
87         context.drawImage(video, 0, 0, canvas.width, canvas.height);
88         buffer = context.getImageData(30, 242, 1, 1).data;
89
90         if (!canvasShouldBeBlack())
91             return isPixelWhite(buffer);
92         else
93             return isPixelBlack(buffer);
94     }
95
96     function disableAllTracks()
97     {
98         mediaStream.getVideoTracks()[0].enabled = false;
99         debug('<br> === all video tracks disabled ===');
100         
101         // The video is not guaranteed to render black frames before the canvas is drawn to and the pixels are checked.
102         // A timeout is used to ensure that the pixel check is done after the video renders black frames.
103         attempt(10, checkPixels, reenableTrack);
104     }
105
106     function beginTestRound()
107     {
108         debug('<br> === beginning round of pixel tests ===');
109         attempt(10, checkPixels, disableAllTracks);
110     }
111
112     function canplay()
113     {
114         canvas = document.querySelector('canvas');
115         context = canvas.getContext('2d');
116
117         beginTestRound();
118     }
119
120     function start()
121     {
122         description("Tests that re-enabling a video MediaStreamTrack when all tracks were previously disabled causes captured media to display.");
123         if (window.testRunner)
124             testRunner.setUserMediaPermission(true);
125
126         video = document.querySelector('video');
127         video.addEventListener('canplay', canplay);
128
129         navigator.mediaDevices.getUserMedia({ video : true })
130             .then((stream) => {
131                 mediaStream = stream;
132                 testPassed('mediaDevices.getUserMedia generated a stream successfully.');
133                 evalAndLog('video.srcObject = mediaStream');
134             });
135     }
136
137     window.jsTestIsAsync = true;
138 </script>
139 <script src="../../resources/js-test-post.js"></script>
140 </body>
141 </html>