Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: content/test/data/media/getusermedia-depth-capture.html

Issue 2476693002: WebGL & 16-bit video stream: upload to FLOAT texture. (Closed)
Patch Set: Fixes. phoglung@, hubbe@, thanks. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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>
OLDNEW
« no previous file with comments | « content/test/data/media/depth_stream_test_utilities.js ('k') | media/renderers/skcanvas_video_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698