OLD | NEW |
---|---|
1 <html> | 1 <html> |
2 <head> | 2 <head> |
3 <script type="text/javascript" src="webrtc_test_utilities.js"></script> | 3 <script type="text/javascript" src="webrtc_test_utilities.js"></script> |
4 <script type="text/javascript" src="depth_stream_test_utilities.js"></script> | 4 <script type="text/javascript" src="depth_stream_test_utilities.js"></script> |
5 <script type="text/javascript"> | 5 <script type="text/javascript"> |
6 | 6 |
7 function cubemapFaces(gl) { | |
8 return [gl.TEXTURE_CUBE_MAP_POSITIVE_X, | |
9 gl.TEXTURE_CUBE_MAP_NEGATIVE_X, | |
10 gl.TEXTURE_CUBE_MAP_POSITIVE_Y, | |
11 gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, | |
12 gl.TEXTURE_CUBE_MAP_POSITIVE_Z, | |
13 gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]; | |
14 } | |
15 | |
7 $ = function(id) { | 16 $ = function(id) { |
8 return document.getElementById(id); | 17 return document.getElementById(id); |
9 }; | 18 }; |
10 | 19 |
11 setAllEventsOccuredHandler(function() { | 20 setAllEventsOccuredHandler(function() { |
12 reportTestSuccess(); | 21 reportTestSuccess(); |
13 }); | 22 }); |
14 | 23 |
15 // testVideoToImageBitmap is a layout test that we run here because | 24 // testVideoToImageBitmap and the tests bellow are layout tests that we |
phoglund_chromium
2016/11/17 10:11:25
Nit: below
aleksandar.stojiljkovic
2016/11/17 16:03:17
Done.
| |
16 // it requires --use-fake-device-for-media-capture. | 25 // run here because they require --use-fake-device-for-media-capture. |
17 function getDepthStreamAndCallCreateImageBitmap() { | 26 function getDepthStreamAndCallCreateImageBitmap() { |
18 console.log('Calling getDepthStreamAndCallCreateImageBitmap'); | 27 console.log('Calling getDepthStreamAndCallCreateImageBitmap'); |
19 getFake16bitStream().then(function(stream) { | 28 getFake16bitStream().then(function(stream) { |
20 detectVideoInLocalView1(stream, function() { | 29 detectVideoInLocalView1(stream, function() { |
21 testVideoToImageBitmap('local-view-1', function() { | 30 testVideoToImageBitmap('local-view-1', function() { |
22 stream.getVideoTracks()[0].stop(); | 31 stream.getVideoTracks()[0].stop(); |
23 waitForVideoToStop('local-view-1'); | 32 waitForVideoToStop('local-view-1'); |
24 }, failedCallback); | 33 }, failedCallback); |
25 }); | 34 }); |
26 }, | 35 }, |
27 failedCallback); | 36 failedCallback); |
28 } | 37 } |
29 | 38 |
39 function depthStreamToRGBAUint8Texture() { | |
40 console.log('Calling depthStreamToRGBAUint8Texture'); | |
41 getFake16bitStream().then(function(stream) { | |
42 detectVideoInLocalView1(stream, function() { | |
43 testVideoToRGBA8Texture('local-view-1', function(skip_info) { | |
44 if (skip_info) { | |
45 console.log("SKIP depthStreamToRGBAUint8Texture: " + | |
46 skip_info); | |
47 } | |
48 stream.getVideoTracks()[0].stop(); | |
49 waitForVideoToStop('local-view-1'); | |
50 }, failedCallback); | |
51 }); | |
52 }, | |
53 failedCallback); | |
54 } | |
55 | |
56 function depthStreamToRGBAFloatTexture() { | |
57 console.log('Calling depthStreamToRGBAFloatTexture'); | |
58 getFake16bitStream().then(function(stream) { | |
59 detectVideoInLocalView1(stream, function() { | |
60 testVideoToRGBA32FTexture('local-view-1', function(skip_info) { | |
61 if (skip_info) { | |
62 console.log("SKIP depthStreamToRGBAFloatTexture: " + | |
63 skip_info); | |
64 } | |
65 stream.getVideoTracks()[0].stop(); | |
66 waitForVideoToStop('local-view-1'); | |
67 }, failedCallback); | |
68 }); | |
69 }, | |
70 failedCallback); | |
71 } | |
72 | |
30 function failedCallback(error) { | 73 function failedCallback(error) { |
31 failTest('GetUserMedia call failed with error name ' + error.name); | 74 failTest('GetUserMedia call failed with error name ' + error.name); |
32 } | 75 } |
33 | 76 |
34 function attachMediaStream(stream, videoElement) { | 77 function attachMediaStream(stream, videoElement) { |
35 var localStreamUrl = URL.createObjectURL(stream); | 78 var localStreamUrl = URL.createObjectURL(stream); |
36 $(videoElement).src = localStreamUrl; | 79 $(videoElement).src = localStreamUrl; |
37 } | 80 } |
38 | 81 |
39 function detectVideoInLocalView1(stream, callback) { | 82 function detectVideoInLocalView1(stream, callback) { |
40 attachMediaStream(stream, 'local-view-1'); | 83 attachMediaStream(stream, 'local-view-1'); |
41 detectVideoPlaying('local-view-1', callback); | 84 detectVideoPlaying('local-view-1', callback); |
42 } | 85 } |
86 | |
87 function testVideoToImageBitmap(videoElementName, success, error) { | |
88 var bitmaps = {}; | |
89 var video = $(videoElementName); | |
90 var canvas = document.createElement('canvas'); | |
91 canvas.width = 96; | |
92 canvas.height = 96; | |
93 document.body.appendChild(canvas); | |
94 var p1 = createImageBitmap(video).then(function(imageBitmap) { | |
95 return runImageBitmapTest(imageBitmap, canvas, false); }); | |
96 var p2 = createImageBitmap(video, | |
97 {imageOrientation: "none", premultiplyAlpha: "premultiply"}).then( | |
98 function(imageBitmap) { | |
99 return runImageBitmapTest(imageBitmap, canvas, false); }); | |
100 var p3 = createImageBitmap(video, | |
101 {imageOrientation: "none", premultiplyAlpha: "default"}).then( | |
102 function(imageBitmap) { | |
103 return runImageBitmapTest(imageBitmap, canvas, false); }); | |
104 var p4 = createImageBitmap(video, | |
105 {imageOrientation: "none", premultiplyAlpha: "none"}).then( | |
106 function(imageBitmap) { | |
107 return runImageBitmapTest(imageBitmap, canvas, false); }); | |
108 var p5 = createImageBitmap(video, | |
109 {imageOrientation: "flipY", premultiplyAlpha: "premultiply"}).then( | |
110 function(imageBitmap) { | |
111 return runImageBitmapTest(imageBitmap, canvas, true); }); | |
112 var p6 = createImageBitmap(video, | |
113 {imageOrientation: "flipY", premultiplyAlpha: "default"}).then( | |
114 function(imageBitmap) { | |
115 return runImageBitmapTest(imageBitmap, canvas, true); }); | |
116 var p7 = createImageBitmap(video, | |
117 {imageOrientation: "flipY", premultiplyAlpha: "none"}).then( | |
118 function(imageBitmap) { | |
119 return runImageBitmapTest(imageBitmap, canvas, true); }); | |
120 return Promise.all([p1, p2, p3, p4, p5, p6, p7]).then(success(), reason => { | |
121 return error({name: reason}); | |
122 }); | |
123 } | |
124 | |
125 function runImageBitmapTest(bitmap, canvas, flip_y) { | |
126 var context = canvas.getContext('2d'); | |
127 context.drawImage(bitmap,0,0); | |
phoglund_chromium
2016/11/17 10:11:25
Nit: bitmap, 0, 0
aleksandar.stojiljkovic
2016/11/17 16:03:17
Done.
| |
128 var imageData = context.getImageData(0, 0, canvas.width, canvas.height); | |
129 // Fake capture device 96x96 depth image is gradient. See also | |
130 // Draw16BitGradient in fake_video_capture_device.cc. | |
131 var color_step = 255.0 / (canvas.width + canvas.height); | |
132 return verifyPixels(imageData.data, canvas.width, canvas.height, flip_y, | |
133 color_step, 255, 2); | |
134 } | |
135 | |
136 function testVideoToRGBA32FTexture(videoElementName, success, error) { | |
137 var video = $(videoElementName); | |
138 var canvas = document.createElement('canvas'); | |
139 canvas.width = 96; | |
140 canvas.height = 96; | |
141 var gl = canvas.getContext('webgl'); | |
142 if(!gl) | |
143 return error({name:"WebGL is not available."}); | |
144 if(!gl.getExtension("OES_texture_float")) | |
145 return error({name:"OES_texture_float extension is not available."}); | |
146 return testVideoToTexture(gl, video, gl.RGBA, gl.RGBA, gl.FLOAT, | |
147 readAndVerifyRGBA32F, success, error); | |
148 } | |
149 | |
150 function testVideoToRGBA8Texture(videoElementName, success, error) { | |
151 var video = $(videoElementName); | |
152 var canvas = document.createElement('canvas'); | |
153 canvas.width = 96; | |
154 canvas.height = 96; | |
155 var gl = canvas.getContext('webgl'); | |
156 if(!gl) | |
157 return error({name:"WebGL is not available."}); | |
158 return testVideoToTexture(gl, video, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, | |
159 readAndVerifyRGBA8, success, error); | |
160 } | |
161 | |
162 function testVideoToTexture(gl, video, internalformat, format, type, | |
163 readAndVerifyFunction, success, error) { | |
164 // Create framebuffer that we will use for reading back the texture. | |
165 var fb = gl.createFramebuffer(); | |
166 gl.bindFramebuffer(gl.FRAMEBUFFER, fb); | |
167 var tests = []; | |
168 // Premultiply alpha is ignored but we just test both values. | |
169 var cases = [ | |
170 {flip_y: false, premultiply_alpha: true}, | |
171 {flip_y: true, premultiply_alpha: false} | |
172 ]; | |
173 for (var i in cases) { | |
174 var flip_y = cases[i].flip_y; | |
175 var premultiply = cases[i].premultiply_alpha; | |
176 uploadVideoToTexture2D(gl, video, internalformat, format, type, flip_y, | |
177 premultiply); | |
178 tests.push(readAndVerifyFunction(gl, video.width, video.height, flip_y)); | |
179 uploadVideoToSubTexture2D(gl, video, internalformat, format, type, flip_y, | |
180 premultiply); | |
181 tests.push(readAndVerifyFunction(gl, video.width, video.height, flip_y)); | |
182 | |
183 // cubemap texImage2D. | |
184 var tex = uploadVideoToTextureCubemap(gl, video, internalformat, format, | |
185 type, flip_y, premultiply); | |
186 for (var i = 0; i < cubemapFaces(gl).length; ++i) { | |
187 // Attach the texture to framebuffer for readback. | |
188 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, | |
189 cubemapFaces(gl)[i], tex, 0); | |
190 tests.push(readAndVerifyFunction(gl, video.width, video.height, | |
191 flip_y)); | |
192 } | |
193 | |
194 // cubemap texSubImage2D. | |
195 tex = uploadVideoToSubTextureCubemap(gl, video, internalformat, format, | |
196 type, flip_y, premultiply); | |
197 for (var i = 0; i < cubemapFaces(gl).length; ++i) { | |
198 // Attach the texture to framebuffer for readback. | |
199 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, | |
200 cubemapFaces(gl)[i], tex, 0); | |
201 tests.push(readAndVerifyFunction(gl, video.width, video.height, | |
202 flip_y)); | |
203 } | |
204 } | |
205 return Promise.all(tests).then(success(), reason => { | |
206 return error({name: reason}); | |
207 }); | |
208 } | |
209 | |
210 // Test setup helper method: create the texture and set texture parameters. | |
211 // For cubemap, target is gl.TEXTURE_CUBE_MAP. For gl.TEXTURE_2D, it is | |
212 // gl.TEXTURE_2D. | |
213 function createTexture(gl, target, video, flip_y, premultiply_alpha) { | |
214 var tex = gl.createTexture(); | |
215 gl.bindTexture(target, tex); | |
216 gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); | |
217 gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); | |
218 gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | |
219 gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | |
220 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip_y); | |
221 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiply_alpha); | |
222 return tex; | |
223 } | |
224 | |
225 function uploadVideoToTexture2D(gl, video, internalformat, format, type, | |
226 flip_y, premultiply_alpha) { | |
227 var tex = createTexture(gl, gl.TEXTURE_2D, video, flip_y, | |
228 premultiply_alpha); | |
229 // Attach the texture to framebuffer for readback. | |
230 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, | |
231 tex, 0); | |
232 gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, video); | |
233 return tex; | |
234 } | |
235 | |
236 function uploadVideoToSubTexture2D(gl, video, internalformat, format, type, | |
237 flip_y, premultiply_alpha) { | |
238 var tex = createTexture(gl, gl.TEXTURE_2D, video, flip_y, | |
239 premultiply_alpha); | |
240 // Attach the texture to framebuffer for readback. | |
241 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, | |
242 tex, 0); | |
243 gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, video.width, video.height, | |
244 0, format, type, null); | |
245 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, format, type, video); | |
246 return tex; | |
247 } | |
248 | |
249 function uploadVideoToTextureCubemap(gl, video, internalformat, format, type, | |
250 flip_y, premultiply_alpha) { | |
251 var tex = createTexture(gl, gl.TEXTURE_CUBE_MAP, video, flip_y, | |
252 premultiply_alpha); | |
253 for (var i = 0; i < cubemapFaces(gl).length; ++i) { | |
254 gl.texImage2D(cubemapFaces(gl)[i], 0, internalformat, format, type, | |
255 video); | |
256 } | |
257 return tex; | |
258 } | |
259 | |
260 function uploadVideoToSubTextureCubemap(gl, video, internalformat, format, | |
261 type, flip_y, premultiply_alpha) { | |
262 var tex = createTexture(gl, gl.TEXTURE_CUBE_MAP, video, flip_y, | |
263 premultiply_alpha); | |
264 for (var i = 0; i < cubemapFaces(gl).length; ++i) { | |
265 gl.texImage2D(cubemapFaces(gl)[i], 0, internalformat, video.width, | |
266 video.height, 0, format, type, null); | |
267 gl.texSubImage2D(cubemapFaces(gl)[i], 0, 0, 0, format, type, video); | |
268 } | |
269 return tex; | |
270 } | |
271 | |
272 function readAndVerifyRGBA8(gl, width, height, flip_y) { | |
273 var arr = new Uint8Array(width * height * 4); | |
274 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, arr); | |
275 var color_step = 255.0 / (width + height); | |
276 return verifyPixels(arr, width, height, flip_y, color_step, | |
277 255 /*wrap_around*/, 2 /*tolerance*/); | |
278 } | |
279 | |
280 function readAndVerifyRGBA32F(gl, width, height, flip_y) { | |
281 var arr = new Float32Array(width * height * 4); | |
282 gl.readPixels(0, 0, width, height, gl.RGBA, gl.FLOAT, arr); | |
283 var color_step = 1.0 / (width + height); | |
284 return verifyPixels(arr, width, height, flip_y, color_step, | |
285 1.0 /*wrap_around*/, 1.5/65535 /*tolerance*/); | |
286 } | |
43 </script> | 287 </script> |
44 </head> | 288 </head> |
45 <body> | 289 <body> |
46 <table border="0"> | 290 <table border="0"> |
47 <!-- Canvases are named after their corresponding video elements. --> | |
48 <tr> | 291 <tr> |
49 <td><video id="local-view-1" width="96" height="96" autoplay | 292 <td><video id="local-view-1" width="96" height="96" autoplay |
50 style="display:none"></video></td> | 293 style="display:none"></video></td> |
294 <!-- The canvas is used to detect when video starts and stops. --> | |
51 <td><canvas id="local-view-1-canvas" width="96" height="96" | 295 <td><canvas id="local-view-1-canvas" width="96" height="96" |
52 style="display:none"></canvas></td> | 296 style="display:none"></canvas></td> |
53 </tr> | 297 </tr> |
54 </table> | 298 </table> |
55 </body> | 299 </body> |
56 </html> | 300 </html> |
OLD | NEW |