video-rotation.html (7969B)
1 <!-- 2 Copyright (c) 2021 The Khronos Group Inc. 3 Use of this source code is governed by an MIT-style license that can be 4 found in the LICENSE.txt file. 5 --> 6 7 <!DOCTYPE html> 8 <html> 9 10 <head> 11 <meta charset="utf-8"> 12 <title>Verifies rotation metadata tag is respected when uploading videos to WebGL textures.</title> 13 <link rel="stylesheet" href="../../../resources/js-test-style.css" /> 14 <script src="../../../js/js-test-pre.js"></script> 15 <script src="../../../js/webgl-test-utils.js"></script> 16 <script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script> 17 </head> 18 19 <body onload="run()"> 20 <canvas id="c" width="256" height="256"></canvas> 21 <div id="description"></div> 22 <div id="console"></div> 23 <script> 24 "use strict"; 25 description(); 26 let wtu = WebGLTestUtils; 27 let tiu = TexImageUtils; 28 let canvas = document.getElementById("c"); 29 let gl = wtu.create3DContext(canvas); 30 let program = tiu.setupTexturedQuad(gl, gl.RGBA); 31 const resourcePath = "../../../resources/"; 32 const mp4Tolerance = 10; 33 // Significantly higher tolerance needed for VP9 tests. http://crbug.com/1219015 . 34 const vp9Tolerance = 45; 35 36 const expectedColors = { 37 top: { location: [0.5, 0.25], color: [255, 0, 0] }, 38 left: { location: [0.4, 0.5], color: [0, 0, 255] }, 39 right: { location: [0.6, 0.5], color: [255, 255, 0] }, 40 bottom: { location: [0.5, 0.75], color: [0, 255, 0] }, 41 } 42 43 function output(str) { 44 debug(str); 45 bufferedLogToConsole(str); 46 } 47 48 function checkPixels(tolerance) { 49 for (let place in expectedColors) { 50 let color = expectedColors[place]; 51 let loc = color.location; 52 let x = loc[0]; 53 let y = loc[1]; 54 output(" Checking " + place); 55 wtu.checkCanvasRect(gl, Math.floor(canvas.width * x), Math.floor(canvas.height * y), 1, 1, 56 color.color, "shouldBe " + color.color + " +/-" + tolerance, tolerance); 57 } 58 } 59 60 function loadVideoElement(filename) { 61 return new Promise((resolve) => { 62 const video = document.createElement('video'); 63 video.crossOrigin = 'anonymous'; 64 video.src = resourcePath + filename; 65 wtu.startPlayingAndWaitForVideo(video, resolve); 66 }); 67 } 68 69 async function testVideoElement(filename, isVP9) { 70 const video = await loadVideoElement(filename); 71 72 output("----------------------------------------------------------------"); 73 output("Testing " + filename + " via HTMLVideoElement"); 74 75 output(" Testing texImage2D"); 76 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video); 77 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); 78 const localTolerance = isVP9 ? vp9Tolerance : mp4Tolerance; 79 checkPixels(localTolerance); 80 81 output(" Testing texSubImage2D"); 82 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, video.videoWidth, video.videoHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 83 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, video); 84 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); 85 checkPixels(localTolerance); 86 } 87 88 async function run() { 89 await (async () => { 90 const video = document.createElement('video'); 91 if (!video.canPlayType) { 92 testFailed("video.canPlayType required method missing"); 93 return; 94 } 95 96 let supports_h264 = !!video.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/no/, ''); 97 let supports_vp9 = !!video.canPlayType('video/mp4; codecs="vp09.00.10.08"').replace(/no/, ''); 98 if (!supports_h264 && !supports_vp9) { 99 testFailed("No supported video types."); 100 return; 101 } 102 103 let tex = gl.createTexture(); 104 // Bind the texture to the default texture unit 0 105 gl.bindTexture(gl.TEXTURE_2D, tex); 106 // Set up texture parameters 107 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 108 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 109 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 110 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 111 112 // These files were created by converting exif-orientation-test.psd to mp4 113 // files, rotating them using the transpose filter, and adding rotate metadata, all 114 // using the ffmpeg command-line tool. 115 // 116 // From sdk/tests/resources/ directory: 117 // 118 // 0: 119 // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96 -pix_fmt yuv420p -y temp.mp4 120 // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=0 video-rotation-0.mp4 121 // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4 122 // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=0 video-rotation-0.vp9.mp4 123 // 124 // 90: 125 // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2 -pix_fmt yuv420p -y temp.mp4 126 // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=270 video-rotation-90.mp4 127 // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4 128 // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=270 video-rotation-90.vp9.mp4 129 // 130 // 180: 131 // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2,transpose=2 -pix_fmt yuv420p -y temp.mp4 132 // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=180 video-rotation-180.mp4 133 // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2,transpose=2 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4 134 // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=180 video-rotation-180.vp9.mp4 135 // 136 // 270: 137 // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=1 -pix_fmt yuv420p -y temp.mp4 138 // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=90 video-rotation-270.mp4 139 // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=1 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4 140 // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=90 video-rotation-270.vp9.mp4 141 142 const filenames = [ 143 "video-rotation-0", 144 "video-rotation-90", 145 "video-rotation-180", 146 "video-rotation-270", 147 ]; 148 149 if (supports_h264) { 150 for (let fn of filenames) 151 await testVideoElement(fn + ".mp4", false); 152 } 153 154 if (supports_vp9) { 155 for (let fn of filenames) 156 await testVideoElement(fn + ".vp9.mp4", true); 157 } 158 })(); 159 160 finishTest(); 161 } 162 163 var successfullyParsed = true; 164 </script> 165 </body> 166 167 </html>