Chromium Code Reviews| 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 |