304 lines
7 KiB
JavaScript
304 lines
7 KiB
JavaScript
// META: global=window,dedicatedworker
|
|
// META: script=/webcodecs/utils.js
|
|
|
|
const invalidConfigs = [
|
|
{
|
|
comment: 'Missing codec',
|
|
config: {
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Empty codec',
|
|
config: {
|
|
codec: '',
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Width is 0',
|
|
config: {
|
|
codec: 'vp8',
|
|
width: 0,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Height is 0',
|
|
config: {
|
|
codec: 'vp8',
|
|
width: 640,
|
|
height: 0,
|
|
},
|
|
},
|
|
{
|
|
comment: 'displayWidth is 0',
|
|
config: {
|
|
codec: 'vp8',
|
|
displayWidth: 0,
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'displayHeight is 0',
|
|
config: {
|
|
codec: 'vp8',
|
|
width: 640,
|
|
displayHeight: 0,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'bitrate is present but zero',
|
|
config: {
|
|
codec: 'vp8',
|
|
width: 640,
|
|
height: 480,
|
|
bitrate: 0
|
|
},
|
|
},
|
|
];
|
|
|
|
invalidConfigs.forEach(entry => {
|
|
promise_test(
|
|
t => {
|
|
return promise_rejects_js(
|
|
t, TypeError, VideoEncoder.isConfigSupported(entry.config));
|
|
},
|
|
'Test that VideoEncoder.isConfigSupported() rejects invalid config: ' +
|
|
entry.comment);
|
|
});
|
|
|
|
invalidConfigs.forEach(entry => {
|
|
async_test(
|
|
t => {
|
|
let codec = new VideoEncoder(getDefaultCodecInit(t));
|
|
assert_throws_js(TypeError, () => {
|
|
codec.configure(entry.config);
|
|
});
|
|
t.done();
|
|
},
|
|
'Test that VideoEncoder.configure() rejects invalid config: ' +
|
|
entry.comment);
|
|
});
|
|
|
|
const validButUnsupportedConfigs = [
|
|
{
|
|
comment: 'Invalid scalability mode',
|
|
config: {codec: 'vp8', width: 640, height: 480, scalabilityMode: 'ABC'}
|
|
},
|
|
{
|
|
comment: 'Unrecognized codec',
|
|
config: {
|
|
codec: 'bogus',
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'VP8 codec string not accepted by Web Codecs',
|
|
config: {
|
|
codec: 'vp08.00.10.08',
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Codec with bad casing',
|
|
config: {
|
|
codec: 'vP8',
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Width is too large',
|
|
config: {
|
|
codec: 'vp8',
|
|
width: 1000000,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Height is too large',
|
|
config: {
|
|
codec: 'vp8',
|
|
width: 640,
|
|
height: 1000000,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Too strenuous accelerated encoding parameters',
|
|
config: {
|
|
codec: 'vp8',
|
|
hardwareAcceleration: 'prefer-hardware',
|
|
width: 30000,
|
|
height: 30000,
|
|
bitrate: 1,
|
|
framerate: 240,
|
|
}
|
|
},
|
|
{
|
|
comment: 'Odd sized frames for H264',
|
|
config: {
|
|
codec: 'avc1.42001E',
|
|
width: 641,
|
|
height: 480,
|
|
bitrate: 1000000,
|
|
framerate: 24,
|
|
}
|
|
},
|
|
{
|
|
comment: 'Possible future H264 codec string',
|
|
config: {
|
|
codec: 'avc1.FF000b',
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Possible future HEVC codec string',
|
|
config: {
|
|
codec: 'hvc1.C99.6FFFFFF.L93',
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Possible future VP9 codec string',
|
|
config: {
|
|
codec: 'vp09.99.99.08',
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'Possible future AV1 codec string',
|
|
config: {
|
|
codec: 'av01.9.99M.08',
|
|
width: 640,
|
|
height: 480,
|
|
},
|
|
},
|
|
{
|
|
comment: 'codec with spaces',
|
|
config: {
|
|
codec: ' vp09.00.10.08 ',
|
|
width: 640,
|
|
height: 480,
|
|
}
|
|
}
|
|
];
|
|
|
|
validButUnsupportedConfigs.forEach(entry => {
|
|
let config = entry.config;
|
|
promise_test(
|
|
async t => {
|
|
let support = await VideoEncoder.isConfigSupported(config);
|
|
assert_false(support.supported);
|
|
|
|
let new_config = support.config;
|
|
assert_equals(new_config.codec, config.codec);
|
|
assert_equals(new_config.width, config.width);
|
|
assert_equals(new_config.height, config.height);
|
|
if (config.bitrate)
|
|
assert_equals(new_config.bitrate, config.bitrate);
|
|
if (config.framerate)
|
|
assert_equals(new_config.framerate, config.framerate);
|
|
},
|
|
'Test that VideoEncoder.isConfigSupported() doesn\'t support config: ' +
|
|
entry.comment);
|
|
});
|
|
|
|
validButUnsupportedConfigs.forEach(entry => {
|
|
promise_test(
|
|
t => {
|
|
let isErrorCallbackCalled = false;
|
|
let codec = new VideoEncoder({
|
|
output: t.unreached_func('unexpected output'),
|
|
error: t.step_func_done(e => {
|
|
isErrorCallbackCalled = true;
|
|
assert_true(e instanceof DOMException);
|
|
assert_equals(e.name, 'NotSupportedError');
|
|
assert_equals(codec.state, 'closed', 'state');
|
|
})
|
|
});
|
|
codec.configure(entry.config);
|
|
return codec.flush()
|
|
.then(t.unreached_func('flush succeeded unexpectedly'))
|
|
.catch(t.step_func(e => {
|
|
assert_true(isErrorCallbackCalled, "isErrorCallbackCalled");
|
|
assert_true(e instanceof DOMException);
|
|
assert_equals(e.name, 'NotSupportedError');
|
|
assert_equals(codec.state, 'closed', 'state');
|
|
}));
|
|
},
|
|
'Test that VideoEncoder.configure() doesn\'t support config: ' +
|
|
entry.comment);
|
|
});
|
|
|
|
const validConfigs = [
|
|
{
|
|
codec: 'avc1.42001E',
|
|
hardwareAcceleration: 'no-preference',
|
|
width: 640,
|
|
height: 480,
|
|
bitrate: 5000000,
|
|
framerate: 24,
|
|
avc: {format: 'annexb'},
|
|
futureConfigFeature: 'foo',
|
|
},
|
|
{
|
|
codec: 'vp8',
|
|
hardwareAcceleration: 'no-preference',
|
|
width: 800,
|
|
height: 600,
|
|
bitrate: 7000000,
|
|
bitrateMode: 'variable',
|
|
framerate: 60,
|
|
scalabilityMode: 'L1T2',
|
|
futureConfigFeature: 'foo',
|
|
latencyMode: 'quality',
|
|
avc: {format: 'annexb'}
|
|
},
|
|
{
|
|
codec: 'vp09.00.10.08',
|
|
hardwareAcceleration: 'no-preference',
|
|
width: 1280,
|
|
height: 720,
|
|
bitrate: 7000000,
|
|
bitrateMode: 'constant',
|
|
framerate: 25,
|
|
futureConfigFeature: 'foo',
|
|
latencyMode: 'realtime',
|
|
alpha: 'discard'
|
|
}
|
|
];
|
|
|
|
validConfigs.forEach(config => {
|
|
promise_test(async t => {
|
|
let support = await VideoEncoder.isConfigSupported(config);
|
|
assert_implements_optional(support.supported);
|
|
|
|
let new_config = support.config;
|
|
assert_false(new_config.hasOwnProperty('futureConfigFeature'));
|
|
assert_equals(new_config.codec, config.codec);
|
|
assert_equals(new_config.width, config.width);
|
|
assert_equals(new_config.height, config.height);
|
|
if (config.bitrate)
|
|
assert_equals(new_config.bitrate, config.bitrate);
|
|
if (config.framerate)
|
|
assert_equals(new_config.framerate, config.framerate);
|
|
if (config.bitrateMode)
|
|
assert_equals(new_config.bitrateMode, config.bitrateMode);
|
|
if (config.latencyMode)
|
|
assert_equals(new_config.latencyMode, config.latencyMode);
|
|
if (config.alpha)
|
|
assert_equals(new_config.alpha, config.alpha);
|
|
if (config.avc)
|
|
assert_equals(new_config.avc.format, config.avc.format);
|
|
}, "VideoEncoder.isConfigSupported() supports:" + JSON.stringify(config));
|
|
});
|