// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
async function main(arg) {
// Reduce frame size first, then increase frame size. The last item is the
// largest frame size, which will be used for creating source.
const frame_size_params = [
{
width: 320,
height: 240,
bitrate: 500_000,
},
{
width: 160,
height: 120,
bitrate: 300_000,
},
{
width: FRAME_WIDTH,
height: FRAME_HEIGHT,
bitrate: 800_000,
}
];
const frames_in_one_pass = 10;
let errors = 0;
let decoder_param_index = 0;
let output_trunks = 0;
let source = await createFrameSource(
arg.source_type, frame_size_params[frame_size_params.length - 1].width,
frame_size_params[frame_size_params.length - 1].height);
if (!source) {
TEST.skip('Unsupported source: ' + arg.source_type);
return;
}
const init = {
output(chunk, metadata) {
TEST.assert(decoder_param_index < frame_size_params.length);
if (metadata.decoderConfig) {
TEST.assert(
output_trunks == 0,
'metadata.decoderConfig is only available for the first frame ' +
'after configuration change.');
// Some platform requires 16x16 alignment.
TEST.assert(
metadata.decoderConfig.codedWidth >=
frame_size_params[decoder_param_index].width - 16 &&
metadata.decoderConfig.codedWidth <=
frame_size_params[decoder_param_index].width + 16,
'Unexpected codedWidth.');
TEST.assert(
metadata.decoderConfig.codedHeight >=
frame_size_params[decoder_param_index].height - 16 &&
metadata.decoderConfig.codedHeight <=
frame_size_params[decoder_param_index].height + 16,
'Unexpected codedHeight.');
}
output_trunks++;
if (output_trunks == frames_in_one_pass) {
decoder_param_index++;
output_trunks = 0;
}
},
error(e) {
errors++;
TEST.log(e);
}
};
let encoder = new VideoEncoder(init);
for (const param of frame_size_params) {
const encoder_config = {
...param,
codec: arg.codec,
acceleration: 'prefer-hardware',
};
let supported = false;
try {
supported =
(await VideoEncoder.isConfigSupported(encoder_config)).supported;
} catch (e) {
TEST.assert(
false, 'Failed to check if the given configuration is supported.');
}
if (!supported) {
TEST.skip('Unsupported configuration: ' + JSON.stringify(encoder_config));
return;
}
encoder.configure(encoder_config);
for (let i = 0; i < frames_in_one_pass; i++) {
let frame = await source.getNextFrame();
encoder.encode(frame);
frame.close();
await waitForNextFrame();
}
}
await encoder.flush();
encoder.close();
source.close();
TEST.assert(
decoder_param_index == frame_size_params.length,
`Decoder config should be changed ${frame_size_params.length} times.`);
TEST.assert(
output_trunks == 0,
`Decoder should output ${
frames_in_one_pass} frames for the last config.`);
TEST.assert(errors == 0, 'Encoding errors occurred during the test');
TEST.log('Test completed');
}