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.
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>
20 <canvas id=
"c" width=
"256" height=
"256"></canvas>
21 <div id=
"description"></div>
22 <div id=
"console"></div>
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;
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] },
43 function output(str
) {
45 bufferedLogToConsole(str
);
48 function checkPixels(tolerance
) {
49 for (let place
in expectedColors
) {
50 let color
= expectedColors
[place
];
51 let loc
= color
.location
;
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
);
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
);
69 async
function testVideoElement(filename
, isVP9
) {
70 const video
= await
loadVideoElement(filename
);
72 output("----------------------------------------------------------------");
73 output("Testing " + filename
+ " via HTMLVideoElement");
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
);
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
);
88 async
function run() {
90 const video
= document
.createElement('video');
91 if (!video
.canPlayType
) {
92 testFailed("video.canPlayType required method missing");
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.");
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
);
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.
116 // From sdk/tests/resources/ directory:
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
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
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
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
145 "video-rotation-180",
146 "video-rotation-270",
150 for (let fn
of filenames
)
151 await
testVideoElement(fn
+ ".mp4", false);
155 for (let fn
of filenames
)
156 await
testVideoElement(fn
+ ".vp9.mp4", true);
163 var successfullyParsed
= true;