| <!DOCTYPE html> |
| <!-- |
| Test how video encoder supports "quantizer" and QP values provided for each |
| frame. |
| --> |
| <html> |
| |
| <head> |
| <title>Encode test</title> |
| <script src="webcodecs_common.js"></script> |
| <script type="text/javascript"> |
| 'use strict'; |
| |
| function get_qp_range(codec) { |
| if (codec.includes('av01')) { |
| return {min: 1, max: 255}; |
| } |
| if (codec.includes('vp9')) { |
| return {min: 1, max: 255}; |
| } |
| if (codec.includes('avc')) { |
| return {min: 10, max: 51}; |
| } |
| if (codec.includes('hvc')) { |
| return {min: 1, max: 51}; |
| } |
| return null; |
| } |
| |
| function set_qp(codec, options, value) { |
| if (codec.includes('av01')) { |
| options.av1 = {quantizer: value}; |
| } |
| if (codec.includes('vp9')) { |
| options.vp9 = {quantizer: value}; |
| } |
| if (codec.includes('avc')) { |
| options.avc = {quantizer: value}; |
| } |
| if (codec.includes('hvc')) { |
| options.hevc = {quantizer: value}; |
| } |
| } |
| |
| async function main(arg) { |
| // Use 16x16 aligned resolution since some platforms require that. |
| // See https://crbug.com/1084702. |
| const width = 640; |
| const height = 480; |
| const qp_range = get_qp_range(arg.codec); |
| const frames_to_encode = qp_range.max - qp_range.min + 1; |
| let errors = 0; |
| let chunks = []; |
| |
| const encoder_config = { |
| codec: arg.codec, |
| hardwareAcceleration: arg.acceleration, |
| width: width, |
| height: height, |
| bitrateMode: "quantizer", |
| framerate: 24 |
| }; |
| |
| TEST.log('Starting test with arguments: ' + JSON.stringify(arg)); |
| let support = await VideoEncoder.isConfigSupported(encoder_config); |
| if (!support.supported) { |
| TEST.skip('Unsupported codec: ' + arg.codec); |
| return; |
| } |
| |
| let source = await createFrameSource(arg.source_type, width, height); |
| if (!source) { |
| TEST.skip('Unsupported source: ' + arg.source_type); |
| return; |
| } |
| |
| const init = { |
| output(chunk, metadata) { |
| chunks.push(chunk); |
| }, |
| error(e) { |
| errors++; |
| TEST.log(e); |
| } |
| }; |
| |
| let encoder = new VideoEncoder(init); |
| encoder.configure(encoder_config); |
| |
| let qp = qp_range.min; |
| for (let i = 0; i < frames_to_encode; i++) { |
| let frame = await source.getNextFrame(); |
| if (qp < qp_range.max) { |
| qp++; |
| } else { |
| qp = qp_range.min; |
| } |
| let encode_options = {keyFrame: false}; |
| set_qp(arg.codec, encode_options, qp); |
| encoder.encode(frame, encode_options); |
| frame.close(); |
| } |
| await encoder.flush(); |
| |
| TEST.assert( |
| chunks.length == frames_to_encode, |
| 'Output count mismatch: ' + chunks.length); |
| |
| TEST.assert(errors == 0, 'Encoding errors occurred during the test'); |
| TEST.log('Test completed'); |
| } |
| addManualTestButton([{ |
| 'source_type': 'offscreen', |
| 'codec': 'avc1.64001E', |
| 'acceleration':'prefer-hardware' |
| }, |
| { |
| 'source_type': 'offscreen', |
| 'codec': 'hvc1.1.6.L93.B0', |
| 'acceleration':'prefer-hardware' |
| }, |
| { |
| 'source_type': 'offscreen', |
| 'codec': 'av01.0.04M.08', |
| 'acceleration':'prefer-software' |
| }]); |
| </script> |
| </head> |
| |
| <body> |
| </body> |
| |
| </html> |