video-encoder-config.https.any.js (7177B)
1 // META: global=window,dedicatedworker 2 // META: script=/webcodecs/utils.js 3 4 const invalidConfigs = [ 5 { 6 comment: 'Missing codec', 7 config: { 8 width: 640, 9 height: 480, 10 }, 11 }, 12 { 13 comment: 'Empty codec', 14 config: { 15 codec: '', 16 width: 640, 17 height: 480, 18 }, 19 }, 20 { 21 comment: 'Width is 0', 22 config: { 23 codec: 'vp8', 24 width: 0, 25 height: 480, 26 }, 27 }, 28 { 29 comment: 'Height is 0', 30 config: { 31 codec: 'vp8', 32 width: 640, 33 height: 0, 34 }, 35 }, 36 { 37 comment: 'displayWidth is 0', 38 config: { 39 codec: 'vp8', 40 displayWidth: 0, 41 width: 640, 42 height: 480, 43 }, 44 }, 45 { 46 comment: 'displayHeight is 0', 47 config: { 48 codec: 'vp8', 49 width: 640, 50 displayHeight: 0, 51 height: 480, 52 }, 53 }, 54 { 55 comment: 'bitrate is present but zero', 56 config: { 57 codec: 'vp8', 58 width: 640, 59 height: 480, 60 bitrate: 0 61 }, 62 }, 63 ]; 64 65 invalidConfigs.forEach(entry => { 66 promise_test( 67 t => { 68 return promise_rejects_js( 69 t, TypeError, VideoEncoder.isConfigSupported(entry.config)); 70 }, 71 'Test that VideoEncoder.isConfigSupported() rejects invalid config: ' + 72 entry.comment); 73 }); 74 75 invalidConfigs.forEach(entry => { 76 async_test( 77 t => { 78 let codec = new VideoEncoder(getDefaultCodecInit(t)); 79 assert_throws_js(TypeError, () => { 80 codec.configure(entry.config); 81 }); 82 t.done(); 83 }, 84 'Test that VideoEncoder.configure() rejects invalid config: ' + 85 entry.comment); 86 }); 87 88 const validButUnsupportedConfigs = [ 89 { 90 comment: 'Invalid scalability mode', 91 config: {codec: 'vp8', width: 640, height: 480, scalabilityMode: 'ABC'} 92 }, 93 { 94 comment: 'Unrecognized codec', 95 config: { 96 codec: 'bogus', 97 width: 640, 98 height: 480, 99 }, 100 }, 101 { 102 comment: 'VP8 codec string not accepted by Web Codecs', 103 config: { 104 codec: 'vp08.00.10.08', 105 width: 640, 106 height: 480, 107 }, 108 }, 109 { 110 comment: 'Codec with bad casing', 111 config: { 112 codec: 'vP8', 113 width: 640, 114 height: 480, 115 }, 116 }, 117 { 118 comment: 'Width is too large', 119 config: { 120 codec: 'vp8', 121 width: 1000000, 122 height: 480, 123 }, 124 }, 125 { 126 comment: 'Height is too large', 127 config: { 128 codec: 'vp8', 129 width: 640, 130 height: 1000000, 131 }, 132 }, 133 { 134 comment: 'Too strenuous accelerated encoding parameters', 135 config: { 136 codec: 'vp8', 137 hardwareAcceleration: 'prefer-hardware', 138 width: 30000, 139 height: 30000, 140 bitrate: 1, 141 framerate: 240, 142 } 143 }, 144 { 145 comment: 'Odd sized frames for H264', 146 config: { 147 codec: 'avc1.42001E', 148 width: 641, 149 height: 480, 150 bitrate: 1000000, 151 framerate: 24, 152 } 153 }, 154 { 155 comment: 'Possible future H264 codec string', 156 config: { 157 codec: 'avc1.FF000b', 158 width: 640, 159 height: 480, 160 }, 161 }, 162 { 163 comment: 'Possible future HEVC codec string', 164 config: { 165 codec: 'hvc1.C99.6FFFFFF.L93', 166 width: 640, 167 height: 480, 168 }, 169 }, 170 { 171 comment: 'Possible future VP9 codec string', 172 config: { 173 codec: 'vp09.99.99.08', 174 width: 640, 175 height: 480, 176 }, 177 }, 178 { 179 comment: 'Possible future AV1 codec string', 180 config: { 181 codec: 'av01.9.99M.08', 182 width: 640, 183 height: 480, 184 }, 185 }, 186 { 187 comment: 'codec with spaces', 188 config: { 189 codec: ' vp09.00.10.08 ', 190 width: 640, 191 height: 480, 192 } 193 } 194 ]; 195 196 validButUnsupportedConfigs.forEach(entry => { 197 let config = entry.config; 198 promise_test( 199 async t => { 200 let support = await VideoEncoder.isConfigSupported(config); 201 assert_false(support.supported); 202 203 let new_config = support.config; 204 assert_equals(new_config.codec, config.codec); 205 assert_equals(new_config.width, config.width); 206 assert_equals(new_config.height, config.height); 207 if (config.bitrate) 208 assert_equals(new_config.bitrate, config.bitrate); 209 if (config.framerate) 210 assert_equals(new_config.framerate, config.framerate); 211 }, 212 'Test that VideoEncoder.isConfigSupported() doesn\'t support config: ' + 213 entry.comment); 214 }); 215 216 validButUnsupportedConfigs.forEach(entry => { 217 promise_test( 218 t => { 219 let isErrorCallbackCalled = false; 220 let codec = new VideoEncoder({ 221 output: t.unreached_func('unexpected output'), 222 error: t.step_func_done(e => { 223 isErrorCallbackCalled = true; 224 assert_true(e instanceof DOMException); 225 assert_equals(e.name, 'NotSupportedError'); 226 assert_equals(codec.state, 'closed', 'state'); 227 }) 228 }); 229 codec.configure(entry.config); 230 return codec.flush() 231 .then(t.unreached_func('flush succeeded unexpectedly')) 232 .catch(t.step_func(e => { 233 assert_true(isErrorCallbackCalled, "isErrorCallbackCalled"); 234 assert_true(e instanceof DOMException); 235 assert_equals(e.name, 'NotSupportedError'); 236 assert_equals(codec.state, 'closed', 'state'); 237 })); 238 }, 239 'Test that VideoEncoder.configure() doesn\'t support config: ' + 240 entry.comment); 241 }); 242 243 const validConfigs = [ 244 { 245 codec: 'avc1.42001E', 246 hardwareAcceleration: 'no-preference', 247 width: 640, 248 height: 480, 249 bitrate: 5000000, 250 framerate: 24, 251 avc: {format: 'annexb'}, 252 futureConfigFeature: 'foo', 253 }, 254 { 255 codec: 'vp8', 256 hardwareAcceleration: 'no-preference', 257 width: 800, 258 height: 600, 259 bitrate: 7000000, 260 bitrateMode: 'variable', 261 framerate: 60, 262 scalabilityMode: 'L1T2', 263 futureConfigFeature: 'foo', 264 latencyMode: 'quality', 265 avc: {format: 'annexb'} 266 }, 267 { 268 codec: 'vp09.00.10.08', 269 hardwareAcceleration: 'no-preference', 270 width: 1280, 271 height: 720, 272 bitrate: 7000000, 273 bitrateMode: 'constant', 274 framerate: 25, 275 futureConfigFeature: 'foo', 276 latencyMode: 'realtime', 277 alpha: 'discard' 278 } 279 ]; 280 281 validConfigs.forEach(config => { 282 promise_test(async t => { 283 let support = await VideoEncoder.isConfigSupported(config); 284 assert_implements_optional(support.supported); 285 286 let new_config = support.config; 287 assert_false(new_config.hasOwnProperty('futureConfigFeature')); 288 assert_equals(new_config.codec, config.codec); 289 assert_equals(new_config.width, config.width); 290 assert_equals(new_config.height, config.height); 291 if (config.bitrate) 292 assert_equals(new_config.bitrate, config.bitrate); 293 if (config.framerate) 294 assert_equals(new_config.framerate, config.framerate); 295 if (config.bitrateMode) 296 assert_equals(new_config.bitrateMode, config.bitrateMode); 297 if (config.latencyMode) 298 assert_equals(new_config.latencyMode, config.latencyMode); 299 if (config.alpha) 300 assert_equals(new_config.alpha, config.alpha); 301 if (config.avc) 302 assert_equals(new_config.avc.format, config.avc.format); 303 }, "VideoEncoder.isConfigSupported() supports:" + JSON.stringify(config)); 304 });