From 3019fa666410d23faf3f453eb6a5540d4fcb8fd4 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Mon, 2 Dec 2024 23:38:07 +1100 Subject: [PATCH] Resync WebCodec's Audio{Decoder,Encoder} web-platform-tests. https://bugs.webkit.org/show_bug.cgi?id=283900 rdar://140781718 Reviewed by NOBODY (OOPS!). Upstream commit: https://github.com/web-platform-tests/wpt/commit/76dfa54e5df7f8cee7501cc6d598cf647c2b8564 Make modifications to our code to pass some new tests that caused failures. All of them are about non-normalised changes with non-specified specification. Corresponding WPT or spec bugs were opened as mentioned in the related code comments. We have two failures marked as expected as they are clearly not spec compliant https://github.com/web-platform-tests/wpt/issues/49636 * LayoutTests/TestExpectations: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/README.md: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/WEB_FEATURES.yml: Added. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.js: (createDefaultAudioData): (pow2): (isInteger): (epsilon): (get_type_values): (typeToArrayType): (arrayTypeToType): (check_array_equality): (conversionTest): * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.worker-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.js: (description.new.Uint8Array): * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.worker-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.js: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.worker-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.html: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.js: (pcm): * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker.html: * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_flac-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_f32-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s16-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s24-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s32-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_u8-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_ulaw-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_vorbis-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_flac-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_f32-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s16-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s24-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s32-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_u8-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_ulaw-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_vorbis-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/idlharness.https.any.js: (async idlArray): * LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-f32.wav: Added. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s16.wav: Added. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s24.wav: Added. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s32.wav: Added. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-u8.wav: Added. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-ulaw.wav: Renamed from LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-mulaw.wav. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-vorbis.ogg: Added. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx.flac: Added. * LayoutTests/imported/w3c/web-platform-tests/webcodecs/w3c-import.log: * Source/WebCore/Modules/webcodecs/WebCodecsAudioDecoder.cpp: (WebCore::isValidDecoderConfig): * Source/WebCore/Modules/webcodecs/WebCodecsAudioEncoder.cpp: (WebCore::isSupportedEncoderCodec): (WebCore::isValidEncoderConfig): --- LayoutTests/TestExpectations | 6 + .../web-platform-tests/webcodecs/README.md | 26 +- .../webcodecs/WEB_FEATURES.yml | 3 + .../webcodecs/audio-data.any-expected.txt | 23 +- .../webcodecs/audio-data.any.js | 556 +++++++++++------- .../audio-data.any.worker-expected.txt | 23 +- .../audio-decoder.https.any-expected.txt | 12 + .../webcodecs/audio-decoder.https.any.js | 66 ++- ...udio-decoder.https.any.worker-expected.txt | 10 + ...udio-encoder-config.https.any-expected.txt | 10 +- .../audio-encoder-config.https.any.js | 31 +- ...coder-config.https.any.worker-expected.txt | 10 +- ...audioDecoder-codec-specific.https.any.html | 9 +- .../audioDecoder-codec-specific.https.any.js | 147 ++++- ...coder-codec-specific.https.any.worker.html | 9 +- ...ecific.https.any.worker_flac-expected.txt} | 0 ...fic.https.any.worker_pcm_f32-expected.txt} | 0 ...ific.https.any.worker_pcm_s16-expected.txt | 11 + ...ific.https.any.worker_pcm_s24-expected.txt | 11 + ...ific.https.any.worker_pcm_s32-expected.txt | 11 + ...cific.https.any.worker_pcm_u8-expected.txt | 11 + ...fic.https.any.worker_pcm_ulaw-expected.txt | 11 + ...cific.https.any.worker_vorbis-expected.txt | 11 + ...codec-specific.https.any_flac-expected.txt | 11 + ...ec-specific.https.any_pcm_f32-expected.txt | 11 + ...ec-specific.https.any_pcm_s16-expected.txt | 11 + ...ec-specific.https.any_pcm_s24-expected.txt | 11 + ...ec-specific.https.any_pcm_s32-expected.txt | 11 + ...dec-specific.https.any_pcm_u8-expected.txt | 11 + ...c-specific.https.any_pcm_ulaw-expected.txt | 11 + ...dec-specific.https.any_vorbis-expected.txt | 11 + .../webcodecs/idlharness.https.any.js | 2 +- .../webcodecs/sfx-pcm-f32.wav | Bin 0 -> 41074 bytes .../webcodecs/sfx-pcm-s16.wav | Bin 0 -> 20558 bytes .../webcodecs/sfx-pcm-s24.wav | Bin 0 -> 30822 bytes .../webcodecs/sfx-pcm-s32.wav | Bin 0 -> 41062 bytes .../webcodecs/sfx-pcm-u8.wav | Bin 0 -> 10318 bytes .../webcodecs/{sfx-mulaw.wav => sfx-ulaw.wav} | Bin .../webcodecs/sfx-vorbis.ogg | Bin 0 -> 4443 bytes .../w3c/web-platform-tests/webcodecs/sfx.flac | Bin 0 -> 13123 bytes .../webcodecs/w3c-import.log | 10 +- LayoutTests/platform/glib/TestExpectations | 11 + .../webcodecs/WebCodecsAudioDecoder.cpp | 36 +- .../webcodecs/WebCodecsAudioEncoder.cpp | 19 +- 44 files changed, 861 insertions(+), 312 deletions(-) create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/WEB_FEATURES.yml rename LayoutTests/imported/w3c/web-platform-tests/webcodecs/{audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt => audioDecoder-codec-specific.https.any.worker_flac-expected.txt} (100%) rename LayoutTests/imported/w3c/web-platform-tests/webcodecs/{audioDecoder-codec-specific.https.any_pcm_mulaw-expected.txt => audioDecoder-codec-specific.https.any.worker_pcm_f32-expected.txt} (100%) create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s16-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s24-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s32-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_u8-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_ulaw-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_vorbis-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_flac-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_f32-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s16-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s24-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s32-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_u8-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_ulaw-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_vorbis-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-f32.wav create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s16.wav create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s24.wav create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s32.wav create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-u8.wav rename LayoutTests/imported/w3c/web-platform-tests/webcodecs/{sfx-mulaw.wav => sfx-ulaw.wav} (100%) create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-vorbis.ogg create mode 100644 LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx.flac diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations index 1f34f059e9d8d..2d5a94c6cc490 100644 --- a/LayoutTests/TestExpectations +++ b/LayoutTests/TestExpectations @@ -5761,6 +5761,12 @@ imported/w3c/web-platform-tests/html/canvas/offscreen/text/canvas.2d.fontStretch imported/w3c/web-platform-tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-expanded.html [ ImageOnlyFailure ] imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage.any.worker.html [ Failure ] +# Flac and Vorbis decoding requires an extra description which isn't provided. +imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.html?flac [ Failure ] +imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.html?vorbis [ Failure ] +imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker.html?flac [ Failure ] +imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker.html?vorbis [ Failure ] + # HEVC support may not be available to all platforms. imported/w3c/web-platform-tests/webcodecs/full-cycle-test.https.any.html?h265_annexb [ Pass Failure ] imported/w3c/web-platform-tests/webcodecs/full-cycle-test.https.any.html?h265_hevc [ Pass Failure ] diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/README.md b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/README.md index 0a1324a1ac46c..dce4ef3650eab 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/README.md +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/README.md @@ -114,16 +114,16 @@ sox -n -r 48000 sfx.wav synth 1 sine 480 ffmpeg -i sfx.wav -frames:a 10 -acodec aac -b:a 96K sfx.adts ``` -### sfx-alaw.wav +### sfx.mp3 ``` sox -n -r 48000 sfx.wav synth 1 sine 480 -ffmpeg -i sfx.wav -frames:a 10 -acodec pcm_alaw sfx-alaw.wav +ffmpeg -i sfx.wav -frames:a 10 -acodec libmp3lame -b:a 96K sfx.mp3 ``` -### sfx.mp3 +### sfx.flac ``` sox -n -r 48000 sfx.wav synth 1 sine 480 -ffmpeg -i sfx.wav -frames:a 10 -acodec libmp3lame -b:a 96K sfx.mp3 +ffmpeg -i sfx.wav -frames:a 10 sfx.flac ``` ### sfx-aac.mp4 @@ -132,16 +132,30 @@ sox -n -r 48000 sfx.wav synth 1 sine 480 ffmpeg -i sfx.wav -frames:a 10 -acodec aac -b:a 96K sfx-aac.mp4 ``` -### sfx-mulaw.wav +### sfx-*.wav ``` sox -n -r 48000 sfx.wav synth 1 sine 480 -ffmpeg -i sfx.wav -frames:a 10 -acodec pcm_mulaw sfx-mulaw.wav +for codec in s16 s24 s32 f32 +do + # Add "le" suffix + ffmpeg -i sfx.wav -frames:a 10 -acodec pcm_"$codec"le sfx-pcm-$codec.wav +done +ffmpeg -i sfx.wav -frames:a 10 -acodec pcm_u8 sfx-pcm-u8.wav +for codec in alaw mulaw +do + ffmpeg -i sfx.wav -frames:a 10 -acodec pcm_$codec sfx-$codec.wav +done ``` ### sfx-opus.ogg ``` sox -n -r 48000 sfx.wav synth 1 sine 480 ffmpeg -i sfx.wav -frames:a 10 -acodec libopus -b:a 96K sfx-opus.ogg + +### sfx-vorbis.ogg +``` +sox -n -r 48000 sfx.wav synth 1 sine 480 +ffmpeg -i sfx.wav -frames:a 10 -acodec libvorbis -b:a 96K sfx-vorbis.ogg ``` ### av1.mp4 diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/WEB_FEATURES.yml b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/WEB_FEATURES.yml new file mode 100644 index 0000000000000..89681db88506d --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: webcodecs + files: "**" diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any-expected.txt index bc6d40f96ddb8..a5da49896a2c2 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any-expected.txt @@ -2,9 +2,22 @@ PASS Verify AudioData constructors PASS Verify closing and cloning AudioData PASS Test we can construct AudioData with a negative timestamp. -PASS Test conversion of uint8 data to float32 -PASS Test conversion of int16 data to float32 -PASS Test conversion of int32 data to float32 -PASS Test conversion of float32 data to float32 -PASS Test copying out planar and interleaved data +PASS Test input array is copied on construction +PASS Test that copyTo throws if copying from interleaved with a non-zero planeIndex +PASS Test conversion of u8 to u8 +PASS Test conversion of u8 to s16 +PASS Test conversion of u8 to s32 +PASS Test conversion of u8 to f32 +PASS Test conversion of s16 to u8 +PASS Test conversion of s16 to s16 +PASS Test conversion of s16 to s32 +PASS Test conversion of s16 to f32 +PASS Test conversion of s32 to u8 +PASS Test conversion of s32 to s16 +PASS Test conversion of s32 to s32 +PASS Test conversion of s32 to f32 +PASS Test conversion of f32 to u8 +PASS Test conversion of f32 to s16 +PASS Test conversion of f32 to s32 +PASS Test conversion of f32 to f32 diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.js b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.js index 4c2d96ab80edb..c18606e2b7054 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.js +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.js @@ -2,19 +2,20 @@ // META: script=/common/media.js // META: script=/webcodecs/utils.js -var defaultInit = - { - timestamp: 1234, - channels: 2, - sampleRate: 8000, - frames: 100, - } - -function -createDefaultAudioData() { +var defaultInit = { + timestamp: 1234, + channels: 2, + sampleRate: 8000, + frames: 100, +}; + +function createDefaultAudioData() { return make_audio_data( - defaultInit.timestamp, defaultInit.channels, defaultInit.sampleRate, - defaultInit.frames); + defaultInit.timestamp, + defaultInit.channels, + defaultInit.sampleRate, + defaultInit.frames + ); } test(t => { @@ -128,230 +129,329 @@ test(t => { data.close(); }, 'Test we can construct AudioData with a negative timestamp.'); - -// Each test vector represents two channels of data in the following arbitrary -// layout: . -const testVectorFrames = 5; -const testVectorChannels = 2; -const testVectorInterleavedResult = - [[-1.0, 1.0, 0.5, 0.0, 0.0], [0.0, -1.0, -0.5, 1.0, 0.0]]; -const testVectorPlanarResult = - [[-1.0, 0.0, 1.0, -1.0, 0.5], [-0.5, 0.0, 1.0, 0.0, 0.0]]; - -test(t => { - const INT8_MIN = (-0x7f - 1); - const INT8_MAX = 0x7f; - const UINT8_MAX = 0xff; - - const testVectorUint8 = [ - 0, -INT8_MIN, UINT8_MAX, 0, INT8_MAX / 2 + 128, INT8_MIN / 2 + 128, - -INT8_MIN, UINT8_MAX, -INT8_MIN, -INT8_MIN - ]; - - let data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Uint8Array(testVectorUint8), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 'u8' - }); - - const epsilon = 1.0 / (UINT8_MAX - 1); - - let dest = new Float32Array(data.numberOfFrames); - data.copyTo(dest, {planeIndex: 0, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorInterleavedResult[0], epsilon, 'interleaved channel 0'); - data.copyTo(dest, {planeIndex: 1, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorInterleavedResult[1], epsilon, 'interleaved channel 1'); - - data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Uint8Array(testVectorUint8), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 'u8-planar' - }); - - data.copyTo(dest, {planeIndex: 0, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorPlanarResult[0], epsilon, 'planar channel 0'); - data.copyTo(dest, {planeIndex: 1, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorPlanarResult[1], epsilon, 'planar channel 1'); -}, 'Test conversion of uint8 data to float32'); - -test(t => { - const INT16_MIN = (-0x7fff - 1); - const INT16_MAX = 0x7fff; - const testVectorInt16 = [ - INT16_MIN, 0, INT16_MAX, INT16_MIN, INT16_MAX / 2, INT16_MIN / 2, 0, - INT16_MAX, 0, 0 - ]; - - let data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Int16Array(testVectorInt16), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 's16' - }); - - const epsilon = 1.0 / (INT16_MAX + 1); - - let dest = new Float32Array(data.numberOfFrames); - data.copyTo(dest, {planeIndex: 0, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorInterleavedResult[0], epsilon, 'interleaved channel 0'); - data.copyTo(dest, {planeIndex: 1, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorInterleavedResult[1], epsilon, 'interleaved channel 1'); - - data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Int16Array(testVectorInt16), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 's16-planar' - }); - - data.copyTo(dest, {planeIndex: 0, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorPlanarResult[0], epsilon, 'planar channel 0'); - data.copyTo(dest, {planeIndex: 1, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorPlanarResult[1], epsilon, 'planar channel 1'); -}, 'Test conversion of int16 data to float32'); - test(t => { - const INT32_MIN = (-0x7fffffff - 1); - const INT32_MAX = 0x7fffffff; - const testVectorInt32 = [ - INT32_MIN, 0, INT32_MAX, INT32_MIN, INT32_MAX / 2, INT32_MIN / 2, 0, - INT32_MAX, 0, 0 - ]; - - let data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Int32Array(testVectorInt32), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 's32' - }); - - const epsilon = 1.0 / INT32_MAX; - - let dest = new Float32Array(data.numberOfFrames); - data.copyTo(dest, {planeIndex: 0, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorInterleavedResult[0], epsilon, 'interleaved channel 0'); - data.copyTo(dest, {planeIndex: 1, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorInterleavedResult[1], epsilon, 'interleaved channel 1'); - - data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Int32Array(testVectorInt32), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 's32-planar' - }); - - data.copyTo(dest, {planeIndex: 0, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorPlanarResult[0], epsilon, 'planar channel 0'); - data.copyTo(dest, {planeIndex: 1, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorPlanarResult[1], epsilon, 'planar channel 1'); -}, 'Test conversion of int32 data to float32'); + var data = new Float32Array([0]); + let audio_data_init = { + timestamp: 0, + data: data, + numberOfFrames: 1, + numberOfChannels: 1, + sampleRate: 44100, + format: 'f32', + }; + let audioData = new AudioData(audio_data_init); + assert_not_equals(data.length, 0, "Input data is copied when constructing an AudioData"); +}, 'Test input array is copied on construction'); test(t => { - const testVectorFloat32 = - [-1.0, 0.0, 1.0, -1.0, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0]; - - let data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Float32Array(testVectorFloat32), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 'f32' - }); - - const epsilon = 0; - - let dest = new Float32Array(data.numberOfFrames); - data.copyTo(dest, {planeIndex: 0, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorInterleavedResult[0], epsilon, 'interleaved channel 0'); - data.copyTo(dest, {planeIndex: 1, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorInterleavedResult[1], epsilon, 'interleaved channel 1'); - - data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Float32Array(testVectorFloat32), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 'f32-planar' - }); + let audio_data_init = { + timestamp: 0, + data: new Float32Array([1,2,3,4,5,6,7,8]), + numberOfFrames: 4, + numberOfChannels: 2, + sampleRate: 44100, + format: 'f32', + }; + let audioData = new AudioData(audio_data_init); + let dest = new Float32Array(8); + assert_throws_js( + RangeError, () => audioData.copyTo(dest, {planeIndex: 1}), + 'copyTo from interleaved data with non-zero planeIndex throws'); + audioData.close(); +}, 'Test that copyTo throws if copying from interleaved with a non-zero planeIndex'); + +// Indices to pick a particular specific value in a specific sample-format +const MIN = 0; // Minimum sample value, max amplitude +const MAX = 1; // Maximum sample value, max amplitude +const HALF = 2; // Half the maximum sample value, positive +const NEGATIVE_HALF = 3; // Half the maximum sample value, negative +const BIAS = 4; // Center of the range, silence +const DISCRETE_STEPS = 5; // Number of different value for a type. + +function pow2(p) { + return 2 ** p; +} +// Rounding operations for conversion, currently always floor (round towards +// zero). +let r = Math.floor.bind(this); + +const TEST_VALUES = { + u8: [0, 255, 191, 64, 128, 256], + s16: [ + -pow2(15), + pow2(15) - 1, + r((pow2(15) - 1) / 2), + r(-pow2(15) / 2), + 0, + pow2(16), + ], + s32: [ + -pow2(31), + pow2(31) - 1, + r((pow2(31) - 1) / 2), + r(-pow2(31) / 2), + 0, + pow2(32), + ], + f32: [-1.0, 1.0, 0.5, -0.5, 0, pow2(24)], +}; + +const TEST_TEMPLATE = { + channels: 2, + frames: 5, + // Each test is run with an element of the cartesian product of a pair of + // elements of the set of type in [u8, s16, s32, f32] + // For each test, this template is copied and the values replaced with the + // appropriate values for this particular type. + // For each test, copy this template and replace the number by the appropriate + // number for this type + testInput: [MIN, BIAS, MAX, MIN, HALF, NEGATIVE_HALF, BIAS, MAX, BIAS, BIAS], + testInterleavedResult: [MIN, NEGATIVE_HALF, BIAS, BIAS, MAX, MAX, MIN, BIAS, HALF, BIAS], + testVectorInterleavedResult: [ + [MIN, MAX, HALF, BIAS, BIAS], + [BIAS, MIN, NEGATIVE_HALF, MAX, BIAS], + ], + testVectorPlanarResult: [ + [MIN, BIAS, MAX, MIN, HALF], + [NEGATIVE_HALF, BIAS, MAX, BIAS, BIAS], + ], +}; + +function isInteger(type) { + switch (type) { + case "u8": + case "s16": + case "s32": + return true; + case "f32": + return false; + default: + throw "invalid type"; + } +} - data.copyTo(dest, {planeIndex: 0, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorPlanarResult[0], epsilon, 'planar channel 0'); - data.copyTo(dest, {planeIndex: 1, format: 'f32-planar'}); - assert_array_approx_equals( - dest, testVectorPlanarResult[1], epsilon, 'planar channel 1'); -}, 'Test conversion of float32 data to float32'); +// This is the complex part: carefully select an acceptable error value +// depending on various factors: expected destination value, source type, +// destination type. This is designed to be strict but reachable with simple +// sample format transformation (no dithering or complex transformation). +function epsilon(expectedDestValue, sourceType, destType) { + // Strict comparison if not converting + if (sourceType == destType) { + return 0.0; + } + // There are three cases in which the maximum value cannot be reached, when + // converting from a smaller integer sample type to a wider integer sample + // type: + // - u8 to s16 + // - u8 to s32 + // - s16 to u32 + if (expectedDestValue == TEST_VALUES[destType][MAX]) { + if (sourceType == "u8" && destType == "s16") { + return expectedDestValue - 32511; // INT16_MAX - 2 << 7 + 1 + } else if (sourceType == "u8" && destType == "s32") { + return expectedDestValue - 2130706432; // INT32_MAX - (2 << 23) + 1 + } else if (sourceType == "s16" && destType == "s32") { + return expectedDestValue - 2147418112; // INT32_MAX - UINT16_MAX + } + } + // Min and bias value are correctly mapped for all integer sample-types + if (isInteger(sourceType) && isInteger(destType)) { + if (expectedDestValue == TEST_VALUES[destType][MIN] || + expectedDestValue == TEST_VALUES[destType][BIAS]) { + return 0.0; + } + } + // If converting from float32 to u8 or s16, allow choosing the rounding + // direction. s32 has higher resolution than f32 in [-1.0,1.0] (24 bits of + // mantissa) + if (!isInteger(sourceType) && isInteger(destType) && destType != "s32") { + return 1.0; + } + // In all other cases, expect an accuracy that depends on the source type and + // the destination type. + // The resolution of the source type. + var sourceResolution = TEST_VALUES[sourceType][DISCRETE_STEPS]; + // The resolution of the destination type. + var destResolution = TEST_VALUES[destType][DISCRETE_STEPS]; + // Computations should be exact if going from high resolution to low resolution. + if (sourceResolution > destResolution) { + return 0.0; + } else { + // Something that approaches the precision imbalance + return destResolution / sourceResolution; + } +} -test(t => { - const testVectorFloat32 = - [-1.0, 0.0, 1.0, -1.0, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0]; +// Fill the template above with the values for a particular type +function get_type_values(type) { + let cloned = structuredClone(TEST_TEMPLATE); + cloned.testInput = Array.from( + cloned.testInput, + idx => TEST_VALUES[type][idx] + ); + cloned.testInterleavedResult = Array.from( + cloned.testInterleavedResult, + idx => TEST_VALUES[type][idx] + ); + cloned.testVectorInterleavedResult = Array.from( + cloned.testVectorInterleavedResult, + c => { + return Array.from(c, idx => { + return TEST_VALUES[type][idx]; + }); + } + ); + cloned.testVectorPlanarResult = Array.from( + cloned.testVectorPlanarResult, + c => { + return Array.from(c, idx => { + return TEST_VALUES[type][idx]; + }); + } + ); + return cloned; +} - let data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Float32Array(testVectorFloat32), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 'f32' - }); +function typeToArrayType(type) { + switch (type) { + case "u8": + return Uint8Array; + case "s16": + return Int16Array; + case "s32": + return Int32Array; + case "f32": + return Float32Array; + default: + throw "Unexpected"; + } +} - const epsilon = 0; +function arrayTypeToType(array) { + switch (array.constructor) { + case Uint8Array: + return "u8"; + case Int16Array: + return "s16"; + case Int32Array: + return "s32"; + case Float32Array: + return "f32"; + default: + throw "Unexpected"; + } +} - // Call copyTo() without specifying a format, for interleaved data. - let dest = new Float32Array(data.numberOfFrames * testVectorChannels); - data.copyTo(dest, {planeIndex: 0}); - assert_array_approx_equals( - dest, testVectorFloat32, epsilon, 'interleaved data'); +function check_array_equality(values, expected, sourceType, message, assert_func) { + if (values.length != expected.length) { + throw "Array not of the same length"; + } + for (var i = 0; i < values.length; i++) { + var eps = epsilon(expected[i], sourceType, arrayTypeToType(values)); + assert_func( + Math.abs(expected[i] - values[i]) <= eps, + `Got ${values[i]} but expected result ${ + expected[i] + } at index ${i} when converting from ${sourceType} to ${arrayTypeToType( + values + )}, epsilon ${eps}` + ); + } + assert_func( + true, + `${values} is equal to ${expected} when converting from ${sourceType} to ${arrayTypeToType( + values + )}` + ); +} - assert_throws_js(RangeError, () => { - data.copyTo(dest, {planeIndex: 1}); - }, 'Interleaved AudioData cannot copy out planeIndex > 0'); +function conversionTest(sourceType, destinationType) { + test(function (t) { + var test = get_type_values(sourceType); + var result = get_type_values(destinationType); + + var sourceArrayCtor = typeToArrayType(sourceType); + var destArrayCtor = typeToArrayType(destinationType); + + let data = new AudioData({ + timestamp: defaultInit.timestamp, + data: new sourceArrayCtor(test.testInput), + numberOfFrames: test.frames, + numberOfChannels: test.channels, + sampleRate: defaultInit.sampleRate, + format: sourceType, + }); + + // All conversions can be supported, but conversion of any type to f32-planar + // MUST be supported. + var assert_func = destinationType == "f32" ? assert_true : assert_implements_optional; + let dest = new destArrayCtor(data.numberOfFrames); + data.copyTo(dest, { planeIndex: 0, format: destinationType + "-planar" }); + check_array_equality( + dest, + result.testVectorInterleavedResult[0], + sourceType, + "interleaved channel 0", + assert_func + ); + data.copyTo(dest, { planeIndex: 1, format: destinationType + "-planar" }); + check_array_equality( + dest, + result.testVectorInterleavedResult[1], + sourceType, + "interleaved channel 0", + assert_func + ); + let destInterleaved = new destArrayCtor(data.numberOfFrames * data.numberOfChannels); + data.copyTo(destInterleaved, { planeIndex: 0, format: destinationType }); + check_array_equality( + destInterleaved, + result.testInput, + sourceType, + "copyTo from interleaved to interleaved (conversion only)", + assert_implements_optional + ); + + data = new AudioData({ + timestamp: defaultInit.timestamp, + data: new sourceArrayCtor(test.testInput), + numberOfFrames: test.frames, + numberOfChannels: test.channels, + sampleRate: defaultInit.sampleRate, + format: sourceType + "-planar", + }); + + data.copyTo(dest, { planeIndex: 0, format: destinationType + "-planar" }); + check_array_equality( + dest, + result.testVectorPlanarResult[0], + sourceType, + "planar channel 0", + assert_func, + ); + data.copyTo(dest, { planeIndex: 1, format: destinationType + "-planar" }); + check_array_equality( + dest, + result.testVectorPlanarResult[1], + sourceType, + "planar channel 1", + assert_func + ); + // Copy to interleaved from planar: all channels are copied + data.copyTo(destInterleaved, {planeIndex: 0, format: destinationType}); + check_array_equality( + destInterleaved, + result.testInterleavedResult, + sourceType, + "planar to interleaved", + assert_func + ); + }, `Test conversion of ${sourceType} to ${destinationType}`); +} - data = new AudioData({ - timestamp: defaultInit.timestamp, - data: new Float32Array(testVectorFloat32), - numberOfFrames: testVectorFrames, - numberOfChannels: testVectorChannels, - sampleRate: defaultInit.sampleRate, - format: 'f32-planar' +const TYPES = ["u8", "s16", "s32", "f32"]; + TYPES.forEach(sourceType => { + TYPES.forEach(destinationType => { + conversionTest(sourceType, destinationType); }); - - // Call copyTo() without specifying a format, for planar data. - dest = new Float32Array(data.numberOfFrames); - data.copyTo(dest, {planeIndex: 0}); - assert_array_approx_equals( - dest, testVectorPlanarResult[0], epsilon, 'planar channel 0'); - data.copyTo(dest, {planeIndex: 1}); - assert_array_approx_equals( - dest, testVectorPlanarResult[1], epsilon, 'planar channel 1'); -}, 'Test copying out planar and interleaved data'); +}); diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.worker-expected.txt index bc6d40f96ddb8..a5da49896a2c2 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.worker-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-data.any.worker-expected.txt @@ -2,9 +2,22 @@ PASS Verify AudioData constructors PASS Verify closing and cloning AudioData PASS Test we can construct AudioData with a negative timestamp. -PASS Test conversion of uint8 data to float32 -PASS Test conversion of int16 data to float32 -PASS Test conversion of int32 data to float32 -PASS Test conversion of float32 data to float32 -PASS Test copying out planar and interleaved data +PASS Test input array is copied on construction +PASS Test that copyTo throws if copying from interleaved with a non-zero planeIndex +PASS Test conversion of u8 to u8 +PASS Test conversion of u8 to s16 +PASS Test conversion of u8 to s32 +PASS Test conversion of u8 to f32 +PASS Test conversion of s16 to u8 +PASS Test conversion of s16 to s16 +PASS Test conversion of s16 to s32 +PASS Test conversion of s16 to f32 +PASS Test conversion of s32 to u8 +PASS Test conversion of s32 to s16 +PASS Test conversion of s32 to s32 +PASS Test conversion of s32 to f32 +PASS Test conversion of f32 to u8 +PASS Test conversion of f32 to s16 +PASS Test conversion of f32 to s32 +PASS Test conversion of f32 to f32 diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any-expected.txt index f5776642e9643..8d6995fb25173 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any-expected.txt @@ -1,3 +1,7 @@ +CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Config is not valid +CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Config is not valid + +Harness Error (FAIL), message = Unhandled rejection: Config is not valid PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Missing codec PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Empty codec @@ -5,12 +9,16 @@ PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Missing PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Missing numberOfChannels PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Zero sampleRate PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Zero channels +PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Opus with >2 channels but no description +PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Valid configuration except detached description PASS Test that AudioDecoder.configure() rejects invalid config: Missing codec PASS Test that AudioDecoder.configure() rejects invalid config: Empty codec PASS Test that AudioDecoder.configure() rejects invalid config: Missing sampleRate PASS Test that AudioDecoder.configure() rejects invalid config: Missing numberOfChannels PASS Test that AudioDecoder.configure() rejects invalid config: Zero sampleRate PASS Test that AudioDecoder.configure() rejects invalid config: Zero channels +PASS Test that AudioDecoder.configure() rejects invalid config: Opus with >2 channels but no description +PASS Test that AudioDecoder.configure() rejects invalid config: Valid configuration except detached description PASS Test that AudioDecoder.isConfigSupported() doesn't support config: Unrecognized codec PASS Test that AudioDecoder.isConfigSupported() doesn't support config: Video codec PASS Test that AudioDecoder.isConfigSupported() doesn't support config: Ambiguous codec @@ -23,6 +31,10 @@ PASS Test that AudioDecoder.configure() doesn't support config: Ambiguous codec PASS Test that AudioDecoder.configure() doesn't support config: Codec with MIME type PASS Test that AudioDecoder.configure() doesn't support config: Possible future opus codec string PASS Test that AudioDecoder.configure() doesn't support config: Possible future aac codec string +FAIL Test that AudioDecoder.configure() doesn't support config: Opus with more than two channels and without description Config is not valid +FAIL Test that AudioDecoder.configure() doesn't support config: Opus with more than two channels and with a description that is too short Config is not valid +PASS Test that AudioDecoder.configure() doesn't support config: vorbis requires a description +PASS Test that AudioDecoder.configure() doesn't support config: flac requires a description PASS Test AudioDecoder construction PASS Verify unconfigured AudioDecoder operations diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.js b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.js index 79ba22157abba..7e041a48f0ab9 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.js +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.js @@ -1,6 +1,10 @@ // META: global=window,dedicatedworker // META: script=/webcodecs/utils.js + +const detachedArrayBuffer = new ArrayBuffer(4); +var b = detachedArrayBuffer.transferToFixedLength(); + const invalidConfigs = [ { comment: 'Missing codec', @@ -47,6 +51,23 @@ const invalidConfigs = [ numberOfChannels: 0, }, }, + { + comment: 'Opus with >2 channels but no description', + config: { + codec: 'opus', + sampleRate: 48000, + numberOfChannels: 6, + } + }, + { + comment: 'Valid configuration except detached description', + config: { + codec: 'opus', + sampleRate: 8000, + numberOfChannels: 1, + description: detachedArrayBuffer, + }, + }, ]; invalidConfigs.forEach(entry => { @@ -123,6 +144,45 @@ const validButUnsupportedConfigs = [ }, ]; +// Those configurations are supported, but attempting to configure an +// AudioDecoder will fail, because `description` is invalid for this particular +// codec +var supportedButErrorOnConfiguration = [ + { + comment: 'Opus with more than two channels and without description', + config: { + codec: 'opus', + sampleRate: '48000', + numberOfChannels: 3, + }, + }, + { + comment: 'Opus with more than two channels and with a description that is too short', + config: { + codec: 'opus', + sampleRate: '48000', + numberOfChannels: 3, + description: new Uint8Array(9), // at least 10 bytes are required for multichannel + }, + }, + { + comment: 'vorbis requires a description', + config: { + codec: 'vorbis', + sampleRate: '48000', + numberOfChannels: 2 + }, + }, + { + comment: 'flac requires a description', + config: { + codec: 'flac', + sampleRate: '48000', + numberOfChannels: 2 + }, + }, +]; + validButUnsupportedConfigs.forEach(entry => { promise_test( t => { @@ -134,10 +194,14 @@ validButUnsupportedConfigs.forEach(entry => { entry.comment); }); -validButUnsupportedConfigs.forEach(entry => { +var shouldError = validButUnsupportedConfigs.concat(supportedButErrorOnConfiguration); + +shouldError.forEach(entry => { promise_test( t => { let isErrorCallbackCalled = false; + let supported = AudioDecoder.isConfigSupported(entry.config); + assert_implements_optional(supported, entry.config.codec + ' unsupported'); let codec = new AudioDecoder({ output: t.unreached_func('unexpected output'), error: t.step_func_done(e => { diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.worker-expected.txt index f5776642e9643..947a7c0005976 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.worker-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-decoder.https.any.worker-expected.txt @@ -1,16 +1,22 @@ +Harness Error (FAIL), message = Unhandled rejection: Config is not valid + PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Missing codec PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Empty codec PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Missing sampleRate PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Missing numberOfChannels PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Zero sampleRate PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Zero channels +PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Opus with >2 channels but no description +PASS Test that AudioDecoder.isConfigSupported() rejects invalid config: Valid configuration except detached description PASS Test that AudioDecoder.configure() rejects invalid config: Missing codec PASS Test that AudioDecoder.configure() rejects invalid config: Empty codec PASS Test that AudioDecoder.configure() rejects invalid config: Missing sampleRate PASS Test that AudioDecoder.configure() rejects invalid config: Missing numberOfChannels PASS Test that AudioDecoder.configure() rejects invalid config: Zero sampleRate PASS Test that AudioDecoder.configure() rejects invalid config: Zero channels +PASS Test that AudioDecoder.configure() rejects invalid config: Opus with >2 channels but no description +PASS Test that AudioDecoder.configure() rejects invalid config: Valid configuration except detached description PASS Test that AudioDecoder.isConfigSupported() doesn't support config: Unrecognized codec PASS Test that AudioDecoder.isConfigSupported() doesn't support config: Video codec PASS Test that AudioDecoder.isConfigSupported() doesn't support config: Ambiguous codec @@ -23,6 +29,10 @@ PASS Test that AudioDecoder.configure() doesn't support config: Ambiguous codec PASS Test that AudioDecoder.configure() doesn't support config: Codec with MIME type PASS Test that AudioDecoder.configure() doesn't support config: Possible future opus codec string PASS Test that AudioDecoder.configure() doesn't support config: Possible future aac codec string +FAIL Test that AudioDecoder.configure() doesn't support config: Opus with more than two channels and without description Config is not valid +FAIL Test that AudioDecoder.configure() doesn't support config: Opus with more than two channels and with a description that is too short Config is not valid +PASS Test that AudioDecoder.configure() doesn't support config: vorbis requires a description +PASS Test that AudioDecoder.configure() doesn't support config: flac requires a description PASS Test AudioDecoder construction PASS Verify unconfigured AudioDecoder operations diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any-expected.txt index 7c21124715834..3cae87a6a3c5f 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any-expected.txt @@ -6,11 +6,13 @@ PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Missing PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Zero sampleRate PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Zero channels PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Bit rate too big +PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Bit rate present but equal to zero PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Opus complexity too big PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Opus packetlossperc too big PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Opus frame duration too small PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Opus frame duration too big PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Invalid Opus frameDuration +PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Bitrate is too low for Opus PASS Test that AudioEncoder.configure() rejects invalid config: Missing codec PASS Test that AudioEncoder.configure() rejects invalid config: Empty codec PASS Test that AudioEncoder.configure() rejects invalid config: Missing sampleRate @@ -18,19 +20,19 @@ PASS Test that AudioEncoder.configure() rejects invalid config: Missing numberOf PASS Test that AudioEncoder.configure() rejects invalid config: Zero sampleRate PASS Test that AudioEncoder.configure() rejects invalid config: Zero channels PASS Test that AudioEncoder.configure() rejects invalid config: Bit rate too big +PASS Test that AudioEncoder.configure() rejects invalid config: Bit rate present but equal to zero PASS Test that AudioEncoder.configure() rejects invalid config: Opus complexity too big PASS Test that AudioEncoder.configure() rejects invalid config: Opus packetlossperc too big PASS Test that AudioEncoder.configure() rejects invalid config: Opus frame duration too small PASS Test that AudioEncoder.configure() rejects invalid config: Opus frame duration too big PASS Test that AudioEncoder.configure() rejects invalid config: Invalid Opus frameDuration -PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Bitrate is too low +PASS Test that AudioEncoder.configure() rejects invalid config: Bitrate is too low for Opus PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Unrecognized codec PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Sample rate is too small PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Sample rate is too large PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Way too many channels PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Possible future opus codec string PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Possible future aac codec string -PASS Test that AudioEncoder.configure() doesn't support config: Bitrate is too low PASS Test that AudioEncoder.configure() doesn't support config: Unrecognized codec PASS Test that AudioEncoder.configure() doesn't support config: Sample rate is too small PASS Test that AudioEncoder.configure() doesn't support config: Sample rate is too large @@ -41,7 +43,7 @@ PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":800 PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2} PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"bitrate":128000,"bitrateMode":"constant","bogus":123} PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"bitrate":128000,"bitrateMode":"variable","bogus":123} -PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{"complexity":5,"frameDuration":20000,"packetlossperc":10,"useinbandfec":true}} -PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{"format":"opus","complexity":10,"frameDuration":60000,"packetlossperc":20,"usedtx":true,"bogus":456}} +PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{"complexity":5,"signal":"music","application":"audio","frameDuration":20000,"packetlossperc":10,"useinbandfec":true}} +PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{"format":"opus","signal":"voice","application":"lowdelay","complexity":10,"frameDuration":60000,"packetlossperc":20,"usedtx":true,"bogus":456}} PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{}} diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.js b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.js index 3be8eb3f6d36d..ad5d56ca492a6 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.js +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.js @@ -56,6 +56,15 @@ const invalidConfigs = [ bitrate: 6e9, }, }, + { + comment: 'Bit rate present but equal to zero', + config: { + codec: 'opus', + sampleRate: 8000, + numberOfChannels: 2, + bitrate: 0, + }, + }, { comment: 'Opus complexity too big', config: { @@ -111,6 +120,15 @@ const invalidConfigs = [ }, }, }, + { + comment: 'Bitrate is too low for Opus', + config: { + codec: 'opus', + sampleRate: 48000, + numberOfChannels: 2, + bitrate: 1, + }, + }, ]; invalidConfigs.forEach(entry => { @@ -137,15 +155,6 @@ invalidConfigs.forEach(entry => { }); const validButUnsupportedConfigs = [ - { - comment: 'Bitrate is too low', - config: { - codec: 'opus', - sampleRate: 48000, - numberOfChannels: 2, - bitrate: 1, - }, - }, { comment: 'Unrecognized codec', config: { @@ -272,6 +281,8 @@ const validConfigs = [ numberOfChannels: 2, opus: { complexity: 5, + signal: 'music', + application: 'audio', frameDuration: 20000, packetlossperc: 10, useinbandfec: true, @@ -283,6 +294,8 @@ const validConfigs = [ numberOfChannels: 2, opus: { format: 'opus', + signal: 'voice', + application: 'lowdelay', complexity: 10, frameDuration: 60000, packetlossperc: 20, // Irrelevant without useinbandfec, but still valid. diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.worker-expected.txt index 7c21124715834..3cae87a6a3c5f 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.worker-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.worker-expected.txt @@ -6,11 +6,13 @@ PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Missing PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Zero sampleRate PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Zero channels PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Bit rate too big +PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Bit rate present but equal to zero PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Opus complexity too big PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Opus packetlossperc too big PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Opus frame duration too small PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Opus frame duration too big PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Invalid Opus frameDuration +PASS Test that AudioEncoder.isConfigSupported() rejects invalid config: Bitrate is too low for Opus PASS Test that AudioEncoder.configure() rejects invalid config: Missing codec PASS Test that AudioEncoder.configure() rejects invalid config: Empty codec PASS Test that AudioEncoder.configure() rejects invalid config: Missing sampleRate @@ -18,19 +20,19 @@ PASS Test that AudioEncoder.configure() rejects invalid config: Missing numberOf PASS Test that AudioEncoder.configure() rejects invalid config: Zero sampleRate PASS Test that AudioEncoder.configure() rejects invalid config: Zero channels PASS Test that AudioEncoder.configure() rejects invalid config: Bit rate too big +PASS Test that AudioEncoder.configure() rejects invalid config: Bit rate present but equal to zero PASS Test that AudioEncoder.configure() rejects invalid config: Opus complexity too big PASS Test that AudioEncoder.configure() rejects invalid config: Opus packetlossperc too big PASS Test that AudioEncoder.configure() rejects invalid config: Opus frame duration too small PASS Test that AudioEncoder.configure() rejects invalid config: Opus frame duration too big PASS Test that AudioEncoder.configure() rejects invalid config: Invalid Opus frameDuration -PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Bitrate is too low +PASS Test that AudioEncoder.configure() rejects invalid config: Bitrate is too low for Opus PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Unrecognized codec PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Sample rate is too small PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Sample rate is too large PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Way too many channels PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Possible future opus codec string PASS Test that AudioEncoder.isConfigSupported() doesn't support config: Possible future aac codec string -PASS Test that AudioEncoder.configure() doesn't support config: Bitrate is too low PASS Test that AudioEncoder.configure() doesn't support config: Unrecognized codec PASS Test that AudioEncoder.configure() doesn't support config: Sample rate is too small PASS Test that AudioEncoder.configure() doesn't support config: Sample rate is too large @@ -41,7 +43,7 @@ PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":800 PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2} PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"bitrate":128000,"bitrateMode":"constant","bogus":123} PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"bitrate":128000,"bitrateMode":"variable","bogus":123} -PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{"complexity":5,"frameDuration":20000,"packetlossperc":10,"useinbandfec":true}} -PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{"format":"opus","complexity":10,"frameDuration":60000,"packetlossperc":20,"usedtx":true,"bogus":456}} +PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{"complexity":5,"signal":"music","application":"audio","frameDuration":20000,"packetlossperc":10,"useinbandfec":true}} +PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{"format":"opus","signal":"voice","application":"lowdelay","complexity":10,"frameDuration":60000,"packetlossperc":20,"usedtx":true,"bogus":456}} PASS AudioEncoder.isConfigSupported() supports: {"codec":"opus","sampleRate":48000,"numberOfChannels":2,"opus":{}} diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.html b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.html index a705d27672bd7..1863b4bf2e3a0 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.html +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.html @@ -4,4 +4,11 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.js b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.js index 92513be087011..32eb6598c6645 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.js +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.js @@ -5,7 +5,14 @@ // META: variant=?mp3 // META: variant=?opus // META: variant=?pcm_alaw -// META: variant=?pcm_mulaw +// META: variant=?pcm_ulaw +// META: variant=?pcm_u8 +// META: variant=?pcm_s16 +// META: variant=?pcm_s24 +// META: variant=?pcm_s32 +// META: variant=?pcm_f32 +// META: variant=?flac +// META: variant=?vorbis const ADTS_AAC_DATA = { src: 'sfx.adts', @@ -82,37 +89,68 @@ const OPUS_DATA = { duration: 20000 }; -const PCM_ALAW_DATA = { - src: 'sfx-alaw.wav', +const FLAC_DATA = { + src: 'sfx.flac', config: { - codec: 'alaw', + codec: 'flac', sampleRate: 48000, numberOfChannels: 1, + description: { offset: 0, size: 8287 } }, - // Any arbitrary grouping should work. chunks: [ - {offset: 0, size: 2048}, {offset: 2048, size: 2048}, - {offset: 4096, size: 2048}, {offset: 6144, size: 2048}, - {offset: 8192, size: 2048}, {offset: 10240, size: 92} + { offset: 8288, size: 2276 }, + { offset: 10564, size: 2038 }, + { offset: 12602, size: 521 }, ], - duration: 35555 + duration: 20000 }; -const PCM_MULAW_DATA = { - src: 'sfx-mulaw.wav', +function pcm(codec, dataOffset) { + return { + src: `sfx-${codec}.wav`, + config: { + codec: codec, + sampleRate: 48000, + numberOfChannels: 1, + }, + + // Chunk are arbitrary and will be generated lazily + chunks: [], + offset: dataOffset, + duration: 0 + } +} + +const PCM_ULAW_DATA = pcm("ulaw", 0x5c); +const PCM_ALAW_DATA = pcm("alaw", 0x5c); +const PCM_U8_DATA = pcm("pcm-u8", 0x4e); +const PCM_S16_DATA = pcm("pcm-s16", 0x4e); +const PCM_S24_DATA = pcm("pcm-s24", 0x66); +const PCM_S32_DATA = pcm("pcm-s32", 0x66); +const PCM_F32_DATA = pcm("pcm-f32", 0x72); + +const VORBIS_DATA = { + src: 'sfx-vorbis.ogg', config: { - codec: 'ulaw', - sampleRate: 48000, + codec: 'vorbis', + description: [ + 2, + 30, + 62, + {offset: 28, size: 30}, + {offset: 101, size: 62}, + {offset: 163, size: 3771} + ], numberOfChannels: 1, + sampleRate: 48000, }, - - // Any arbitrary grouping should work. chunks: [ - {offset: 0, size: 2048}, {offset: 2048, size: 2048}, - {offset: 4096, size: 2048}, {offset: 6144, size: 2048}, - {offset: 8192, size: 2048}, {offset: 10240, size: 92} + {offset: 3968, size: 44}, {offset: 4012, size: 21}, + {offset: 4033, size: 57}, {offset: 4090, size: 37}, + {offset: 4127, size: 37}, {offset: 4164, size: 107}, + {offset: 4271, size: 172} ], - duration: 35555 + duration: 21333 }; // Allows mutating `callbacks` after constructing the AudioDecoder, wraps calls @@ -151,7 +189,14 @@ promise_setup(async () => { '?mp4_aac': MP4_AAC_DATA, '?opus': OPUS_DATA, '?pcm_alaw': PCM_ALAW_DATA, - '?pcm_mulaw': PCM_MULAW_DATA, + '?pcm_ulaw': PCM_ULAW_DATA, + '?pcm_u8': PCM_U8_DATA, + '?pcm_s16': PCM_S16_DATA, + '?pcm_s24': PCM_S24_DATA, + '?pcm_s32': PCM_S32_DATA, + '?pcm_f32': PCM_F32_DATA, + '?flac': FLAC_DATA, + '?vorbis': VORBIS_DATA, }[location.search]; // Don't run any tests if the codec is not supported. @@ -174,10 +219,55 @@ promise_setup(async () => { CONFIG = {...data.config}; if (data.config.description) { - CONFIG.description = view(buf, data.config.description); + // The description for decoding vorbis is expected to be in Xiph extradata format. + // https://w3c.github.io/webcodecs/vorbis_codec_registration.html#audiodecoderconfig-description + if (Array.isArray(data.config.description)) { + const length = data.config.description.reduce((sum, value) => sum + ((typeof value === 'number') ? 1 : value.size), 0); + const description = new Uint8Array(length); + + data.config.description.reduce((offset, value) => { + if (typeof value === 'number') { + description[offset] = value; + + return offset + 1; + } + + description.set(view(buf, value), offset); + + return offset + value.size; + }, 0); + + CONFIG.description = description; + } else { + CONFIG.description = view(buf, data.config.description); + } } - CHUNK_DATA = data.chunks.map((chunk, i) => view(buf, chunk)); + CHUNK_DATA = []; + // For PCM, split in chunks of 1200 bytes and compute the rest + if (data.chunks.length == 0) { + let offset = data.offset; + // 1200 is divisible by 2 and 3 and is a plausible packet length + // for PCM: this means that there won't be samples split in two packet + let PACKET_LENGTH = 1200; + let bytesPerSample = 0; + switch (data.config.codec) { + case "pcm-s16": bytesPerSample = 2; break; + case "pcm-s24": bytesPerSample = 3; break; + case "pcm-s32": bytesPerSample = 4; break; + case "pcm-f32": bytesPerSample = 4; break; + default: bytesPerSample = 1; break; + } + while (offset < buf.byteLength) { + let size = Math.min(buf.byteLength - offset, PACKET_LENGTH); + assert_equals(size % bytesPerSample, 0); + CHUNK_DATA.push(view(buf, {offset, size})); + offset += size; + } + data.duration = 1000 * 1000 * PACKET_LENGTH / data.config.sampleRate / bytesPerSample; + } else { + CHUNK_DATA = data.chunks.map((chunk, i) => view(buf, chunk)); + } CHUNKS = CHUNK_DATA.map((encodedData, i) => new EncodedAudioChunk({ type: 'key', @@ -257,7 +347,7 @@ promise_test(async t => { }); await decoder.flush(); - assert_equals(outputs, CHUNKS.length, 'outputs'); + assert_equals(outputs, CONFIG.codec === 'vorbis' ? CHUNKS.length - 1 : CHUNKS.length, 'outputs'); }, 'Test decoding'); promise_test(async t => { @@ -273,9 +363,11 @@ promise_test(async t => { decoder.configure(CONFIG); decoder.decode(new EncodedAudioChunk( {type: 'key', timestamp: -42, data: CHUNK_DATA[0]})); + decoder.decode(new EncodedAudioChunk( + {type: 'key', timestamp: CHUNKS[0].duration - 42, data: CHUNK_DATA[1]})); await decoder.flush(); - assert_equals(outputs, 1, 'outputs'); + assert_equals(outputs, CONFIG.codec === 'vorbis' ? 1 : 2, 'outputs'); }, 'Test decoding a with negative timestamp'); promise_test(async t => { @@ -290,13 +382,14 @@ promise_test(async t => { decoder.configure(CONFIG); decoder.decode(CHUNKS[0]); + decoder.decode(CHUNKS[1]); await decoder.flush(); - assert_equals(outputs, 1, 'outputs'); + assert_equals(outputs, CONFIG.codec === 'vorbis' ? 1 : 2, 'outputs'); - decoder.decode(CHUNKS[0]); + decoder.decode(CHUNKS[2]); await decoder.flush(); - assert_equals(outputs, 2, 'outputs'); + assert_equals(outputs, CONFIG.codec === 'vorbis' ? 2 : 3, 'outputs'); }, 'Test decoding after flush'); promise_test(async t => { diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker.html b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker.html index a705d27672bd7..1863b4bf2e3a0 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker.html +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker.html @@ -4,4 +4,11 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_flac-expected.txt similarity index 100% rename from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_mulaw-expected.txt rename to LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_flac-expected.txt diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_mulaw-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_f32-expected.txt similarity index 100% rename from LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_mulaw-expected.txt rename to LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_f32-expected.txt diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s16-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s16-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s16-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s24-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s24-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s24-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s32-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s32-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_s32-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_u8-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_u8-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_u8-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_ulaw-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_ulaw-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_pcm_ulaw-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_vorbis-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_vorbis-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any.worker_vorbis-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_flac-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_flac-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_flac-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_f32-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_f32-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_f32-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s16-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s16-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s16-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s24-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s24-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s24-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s32-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s32-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_s32-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_u8-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_u8-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_u8-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_ulaw-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_ulaw-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_pcm_ulaw-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_vorbis-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_vorbis-expected.txt new file mode 100644 index 0000000000000..a897b642cb0de --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/audioDecoder-codec-specific.https.any_vorbis-expected.txt @@ -0,0 +1,11 @@ + +PASS Test isConfigSupported() +PASS Test that AudioDecoder.isConfigSupported() returns a parsed configuration +PASS Test configure() +PASS Verify closed AudioDecoder operations +PASS Test decoding +PASS Test decoding a with negative timestamp +PASS Test decoding after flush +PASS Test reset during flush +PASS AudioDecoder decodeQueueSize test + diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/idlharness.https.any.js b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/idlharness.https.any.js index b69a4c9fa7074..f1ed92a159831 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/idlharness.https.any.js +++ b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/idlharness.https.any.js @@ -29,7 +29,7 @@ var defaultVideoChunkInit = { data: new Uint8Array([9, 10, 11, 12]) }; -idl_test(['webcodecs'], ['dom', 'html', 'WebIDL'], async idlArray => { +idl_test(['webcodecs'], ['dom', 'html', 'webidl'], async idlArray => { self.imageBody = await fetch('four-colors.png').then(response => response.arrayBuffer()); diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-f32.wav b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-f32.wav new file mode 100644 index 0000000000000000000000000000000000000000..d1c0fa2bd9354c81eebabd3a43db66cef2df8307 GIT binary patch literal 41074 zcmeI5PiqrV6veMv7j8s1L3C3PK@elQsYP*~E*c0Fi?&*!8-tR9qEHOBHdyl!TneI; ztcnY9ubKND1Q+fK?p+AF5v=C~zlFa*$joHkdv^$#Klh#cJ2yM+_Jf^>m20=>dyo3l zXCvaz{(%^N)WY|JF%{F%(0fX&hxCp(7Q={lG531C*S**G_E4jR&eHNpEq1QA7duPs z<)d0&=sxYuwwg1u&6!p!?sxm$*wJRaZoC>^SzU?h+g_<&?rv9G7vEN&w?0+%{@3c^ z?yu^{xg+JovqqU~o-TvxLizCKQdzw^U&f~v%iftgWpwLq$A~I8yPX;!4GriZc~&D(=*A zq>f|q>2+`S_ukL@yPey+ANS{e-M`22cplf|I}XR=xE!D3bi9sR$1&#j;P>GF!T*Ev z71s~0A49I^++T5j#r-bNA3T5XJjnAo&*$Vz$d{16BA-Y;k^C=ja*Gm!K~}?}Ppd{gw1&=;6>OqEAFGihdXUE_!P8?daR7H=y2t`VZIT zP>(}B4)sygt5L5;{UG(6)N@i_OT9Do&eWg71Aqqrp8-AtybSmy@Jryy!1sag18)ib z75poBWIhkThl39XuMb`y{6u(`@GRkrnpbJAtMw%CUg5pM--U+^4;enS_2%Yy>pl@) zIJ|K9?eO&B>EmyJ-voXW_sM0`V#ad z=u6O-pf5pRg1!WO34X%(JL9*F-!}f|x*x!g9zXhtt_YqbJWF_%@GRk3!n1^D*+}y` z$d`~WAzwnignSA467nVFOURcDQgx}R`$P04=u6O-jMmbAP~tn{mx^C1eyRAS;+KkF XDt@W(OYlp@FSS^A3-9&+;l2I^F-X3w literal 0 HcmV?d00001 diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s16.wav b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s16.wav new file mode 100644 index 0000000000000000000000000000000000000000..34b6d982d2c8354d58902c189e5f625e77f49a29 GIT binary patch literal 20558 zcmeI4ze@sP7{}i(f^-OJ2^y*`xWR03N-(s8qp-}(Df~f{L_wU9NYtGX(cs}AVv7__ z;SdCE7YI4I)o{>QTZ=TM5J}yi(eUAxyXD}xyZ3#b@ALV7S5-w(R)k2*uP`x}93cy6&4y-Gwjt~2KL=&ro~l9Td}h3_NlxPQ{rfAyx`Ke3L#j~)wB z{v{{xkM5e=*O|!1RiYN1Tdal~0o^|_V@}(XKVxo>YgmYG@9T5$Lw?g<-=B?k{AtH( zJ!J1vxA!;6x^~&A*ky02e-Sz#It!ml#h@XKpdl5*r$c9<^ZtdmWS2V??J`-vze(L@ z?^+K#R{Y6mzdviQ^4s9Y*JroKbMQX+uJ}J#uUL24KiJQyOQ^4?6RF$jKj@?AYw6F? z8PH46uh8Mp6VZ3ksnOe+8!*RV9>rXZIVba4=FZH|;ThmE;7j0r;FjR8;Njr<;1l62 z;a=f);gI3N;oIT#@f+a(z{i3g2Y(bkFZ^ow?(jk4=fszaPZ+;5zHR*H~p=#w6YI_)q(nkOtl1R{4WCa{)R_7 zt`5HH^m#ocK2M3)YaPLnpeec@ZxiA#6W!T2=}AYqCkq8TImMBXFLSf}`hDg6ld7!c z+VYRh$2BcQYwafsU6JIzgTjHflh&{h5Jk1|EuKK?3cJ|I1 zcjJ1)!(VrPc5m&rZ4_*;AGWUM53RU=z4II`u6gEDZ|A-}n;m^P(^EO!?t1g-siTXf zR~@TG?Rr;z)KmR+md;fK#ZffHRAj|h7Ufb#;%K39AP`Mu(|o&Q1R z49pprUojVD-p)M^_k-L!bMMSL18Xv@U$NH5x+rVNtRb`B&fWz3IP7_`KgeDxd#UU@ zvqw)o1GOL2$xu^7O%e51)T&X}M-3$PqSV$>TT2}>HQUs;V*zjz7!!;M#sp)6F~OK% zOfV)G6O0MQ1Y?3R!I)r7FeVrij0wgBV}dckm|#pWCKwZp3C09tf-%9EU`#M37!!;M z#sp)6F~OK%OfV)G6O0MQ1Y?3R!I)r7FeVrij0wgBV}dckm|#pWCKwZp3C09tf-%9E TU`#M37!!;M#sp(>e~if;NSmn0 literal 0 HcmV?d00001 diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s32.wav b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-pcm-s32.wav new file mode 100644 index 0000000000000000000000000000000000000000..85b33faff14014d2206c2401df9de76065e9a560 GIT binary patch literal 41062 zcmeI)+e?#i9LMqB=ApxdJw^wxD7!L**1Q=82}QOT4$EA6l{!f~PCQa5pY=5dQFIn96d8yO4_Rs2K_3ZkAH<`NY zxpkXI3+c$yn#rcGzi&2Ik8EuzuDRWoXu8|EY_4^GW>dD;Zg;R$SblWNO#KPBd&W(D z3Z~+X&(65R#dD8u<v2mi15{NVG0&vU+C@%@VLyBvRT{K4@c$LAcMvtGh_3F}v^C$gT%`Y!A3thbYY zkVlb6kq?sBlGl=-lb_SiKz|ASCG`8ye?|Wl{c!Xr(w|7bDE+(i@6u0Ae>?r{cmuov z{sWJL$H7P8)$nTgK|Cj(6JLvW#yjKB@#mZmfb%nOeg@8$!TC!#e+lQ4Q9mL69Dj~K z$DiZR@#pw+{5k#{e~v%LpX1N*=lFB{IsP1fjz7nrHt5-L`)D{OJ=q8p`uC5+VXTovcmtG?Zi|g!y?m*jShtLC#=e zVdLQ87nYD!($F)pcJd5}NXW=9AGKpNtVYw-X#N;2OGeAY(fVVwt{rVNjJB^v+lixX z>e0TzXg_MS&pFz69vx>G9WNOjTN)jQ8y!y^9eW)eLmnM(ADuTConslDj~bm<8=Zq3 mol6~^cOIQTA6;uOx-MgMeaYxroY6H!qwB9m*Q!x>%^d)#e+ydx literal 0 HcmV?d00001 diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-mulaw.wav b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-ulaw.wav similarity index 100% rename from LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-mulaw.wav rename to LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-ulaw.wav diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-vorbis.ogg b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx-vorbis.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e3eb4fcae1a05dd45f3fd27888e4efbb13483437 GIT binary patch literal 4443 zcmai14O~-4wjTr`0mKM_293T1N#P>wGYD#^?D8Qh0aPvoB$QeMQ6Yd52(E8Sr4lG0 zAVQ=VqK}URO(3W!DEL!)!btjiKOopZma<?QyJjueEm%BQMM z!aWFl8i0H1#6D{?eY!JOL0y}*`l>8^;BVn`-#USCJ3;|$x-Nr$6|8}KT^IYtX8Mn1 zMvQ?e2#frF`O1hFP=tASYgI}vX<7Leqgir+Ev=3eY-^GP6AJ6TXUK=-PX{=5@&~nQ zYR&bFMbR~G9qQ^DqX$z5o$rG$vEDVq5e!Uc#(4tRutW?5p|Fgp!bg?#ghRt zG4@;d1c2YR+@$Fb?`7naSqiAkMrP%rto?SCwd@{Dxu~>k4OgAF5qEY|W$iU;&Ok^? zF{1cwV}!B^#mb6ek6!mv{oZ|^MALkE&~N(0WlFFu8&K@&3n(san>>=)!dWL$wHf$J zR5F~4sZ0?CPGuyO2U0HBsQA!v|KoaX-ooJz>b0Ngk@hU8!`@y|%lvuK zyx8otxNjumXYvznN+!l~CdNuPe^l^WV7-eR1VJM;#-vP8!tPe&tq&rb9Q-zNGN|1L z=vNQ8hPApzjCcCMT}_ zO~9DKW@1e8LF5o2;=(DrzpldKedN@-mwmUgY;kCXYh1<0yQ{Vp$<>FB{GhJ4{!Qd; zFFsmbe6+B5s<6zxs4BTguIZ>x?QNOv{Fn7zZuPSA< zu;Rl?`@|wGEJ9ZB*whV`JDLSh5fa$q)>ys_AH*ih@m}@=I?m-BRYVPPNDHOCY|F!W z6ih{r8pOKk(*D2)ioBsfcZ3)h%-{)f_elyt6gPBtr|Y#!pD-#b%pv3&RXFAlF?P^r zz{fW-n%C#R8;$0TJ4Nu?SrHBq5r2#3IfU>WdDp8Vcx`Fde1x~6d3T(6qwT_Rr!Qlx zBooUb;^5T)RLNLX&SpbeLiHO~5mY0q<-DK21=%Nfapd$K$^rT&;k z?yk|OHSKAd7Hxd}LruM=w{@GQrMb8DcvDO2G*DZPX<9us8qcQI<`){z>GorqPHk`N ziJF$C>Gq#&E_+UQ?$orjG_^h^sGZtrea3X>(k~jZzQ(3Uo$Aic^y$uw{`NF_gXYnB zkG@MMdRu>*?)>-D5@sY%az~bMKNj>z+q~;Y{7imp+9zGw7rnq>{R*! z7}Gyp@~15;%T(Lsuv3k;M$O6xU`Iz9T% zgCO>|`W^IhOX&&Y%YksXRcn)z*fT@ECK}ggyzsmKT+(pdmfXD`uwh1E!=X2zj=5x3 z?n*Oc$(*7_Q9N{vEDHXJp^Ro*GBek6b#&QAZVFR&!$Z%AE(`5ZRN8a5W3mz4s!p|$ zE2@(jaM8)e8-gDhN+)izmu!TeqSoKwm&{9~cuy&l21CiJ(*yxnP1P#xg19OrHH_;O z(+@yy7ztdbR@z5}s@s5-O6e5FWw%q~)7b_(tWes=hhlnaRGODwzF5xyR#yq(Mi~#P zWx(oCUImw{Jy?PFD=G%I)l1Kh4{wuD z_%_B}Y1?8%DOx=UXQ^mm+>>oiqICA;d~ULq5U$oa#g~EbD3NcYA%!5sr}-P?nOv>m z23`t;#I(PT%K!4yTg?S2UV4K-O9=Nkd9VV6Pu}L2aAYF_U{!&az>4_Pj>f7KAjt83 zZIib%Q+=P`;5QR8!r%*$xxeFC44gW-<|rVSEUYDt5F%^?3-Q6wWQw?-<3SGU=eViG z;XxS2>klNc+6FlorZaFzER|E3hnFr!gkhkC7vvqru(gaR(wSM$i6f)c5XE{1oI94z zDq7wUO-W6pxTt907Zo)TY)i|u3-WMI91L{Fq#L;&SU!at%2Gj&YfXoIE_Fz@i4Gew zog<&y3T)X0jI3yHk9pE?uABNRu&7o7P*Cam`6=4dHv>r8e1mrw3!t!7d!?Gc1fj>U zp~uE^goVnjPynp~H%Y#NG z8zBfd_Xh@yVX7>GAj7Q@^4JL((TT{U%)JL{;mn+cb`xhNmt$2YTZ8EtvI-o;fl6wz zE!a*MLl9*A#|(f*s&6(0V5R2=bG5onq86sgAZYd-0}!`O%0*lthz2?k`gXPzI$^#b zWVsuS?BSDSR3euFW-MVBPzA;8DMc^|(^W%`(?}yy5BSIu`9}#5;8hO<&J>+!6q#l3 z6O;En^8cfR8uF}pG4Qq4(-x3SS@{}!<7;B-n0{yuyEy=OX zR_L|Wf|#`{vH3QhgpL$DNc1jO!;UQ%N(-=uN-4OfE||-4X8}qu4B!J1E#q?!W#YI8 zOI1Z29XI$~FW_y(QW@|Rkm5&DoxVYcx*50*QyKXCyddPb@G2eBFCqpz8eYzG;w zO5&U5uUd&m0Qn=1pM;n!~Rn#b4 z^iUxviQI5Fk;}f^EQ{f~AJ{u0Zf?u&hf5-ZgqBj6%f1RQqtbdnkkkT0wI?nNu|Ku2 z_}<>z+Sa;TnmLkejwsR|+XIE0Z0#L1U)2lz(56p6@3G3YEiFC0&*q``h1m(;N*Gdx z1+!3RMlH|Hb4dU5cXKwJy-4;8QP~;qz;}%o(uz3@7Z*9F%x?eOa>{{u750@5GJr2a zC(Lr^qFmS6g@uJ%%Nj1N(6uJbOcJ0l6_U4+^Dbg}NIww>(TyrSmT)3(l+66MSno~n>p=hr4I|JC8uct+Zv zg9lDrE0A97v*ksKw2tWR^Z$C)e>i!Q_iOW+zJ%uwn|@yMpgZx^($@bR_U?anNA$_P z>whY}_-J_7Ow+OU{gI72LD%W;n{ty+u8fNQH8w7%X;eP!vFFf_n-#10FOMJS_{%Tb zf9_f{`Q+-I@AfR3e4;+5d%ddvPSo*lU$46L{_oQ-k37D8W63vnDifY|iEsIP4($0T Nd+xr1iR^ar{{p*(CfEP~ literal 0 HcmV?d00001 diff --git a/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx.flac b/LayoutTests/imported/w3c/web-platform-tests/webcodecs/sfx.flac new file mode 100644 index 0000000000000000000000000000000000000000..a8d313c562573d66a0e072aae4c70ba11480908c GIT binary patch literal 13123 zcmeI$Z%ou?90%~q?!|Khx0X{Vnb~NI)#-`XbHR}9woq!rwDVuQ9iX6B?r?4}HViXx z^B*a!H|ho=Scb!C%;Js!0t$*CdMWCO%G`#8U4&#RWFX>nfK$C;$bZ02F`% zPyh-*0Vn_kpa2wr0#E=7KmjNK1)u;FfC5ke3P6GXyTG%DsQ}q6AP6v`FGfCjt#{s@ z#jg$#Wg-hx?423Ir+ml#<@ zi-|CP2?nzIy@y?o*DvZQcv^eIek0AEX7B4vZCKoyvoOh9hRIqcfop`4h)N6)8C6cq zy!@VN-mm@HqkR+UBlROAzLENlN4@#mALplXf~@cq1I`m+A}$efBBp5UD{<)Y0`1RWE@!+MONEatEQ8Lef3{)e+SX{{@(f(!=7np2WUobK4Xsc~& z^R?AB>^PCWamT>>WhRosPWxTo-FjcWZ*;KEv460&;s|$9 z*2E>KBBJLBnboE6%N)_1Nqfu3vRWoaA2sAT^78C?j`Zmd+s{n5*O4^GQ6vT5{vfEBD*6OcGd)YvYY$c z2d;W<9;i9&I+7%p$}DDJQ3(SC$`S^NjloDMMZCT3K`?);#j~`!zvuI<<-Z8~yjVB} z*l3wW3kd@Wxad-uD~wrPV%|{y)RSXt>B)THi68$ex4^r%j3ikCaC$k)MN0`l((f$g zzQo)m6@xw5!!7-H268sr{%Q@K#Bm&jT6VO7;K%z+;nGimIS!Jwar>(UnxVbsMJP|)GH)eM znH65(7wP{uV(A4dutKZm?~=MIO`&Ewf;P<;Xl(Cc@s=M?VWO;z^`ho3lLKx=+&w~&E>iRlBG$sx).isEmpty()) - return false; - - if (!config.numberOfChannels || !config.sampleRate) - return false; - - return true; -} - static AudioDecoder::Config createAudioDecoderConfig(const WebCodecsAudioDecoderConfig& config) { std::span description; @@ -93,6 +82,31 @@ static AudioDecoder::Config createAudioDecoderConfig(const WebCodecsAudioDecoder return { description, config.sampleRate, config.numberOfChannels }; } +static bool isValidDecoderConfig(const WebCodecsAudioDecoderConfig& config) +{ + if (StringView(config.codec).trim(isASCIIWhitespace).isEmpty()) + return false; + + if (!config.numberOfChannels || !config.sampleRate) + return false; + + auto descriptionSize = createAudioDecoderConfig(config).description.size(); + + // FIXME: Not yet per spec, but being tested and tracked by https://github.com/w3c/webcodecs/issues/826 + // And handled that way by all other UAs. + // If we have a config.description, ensures it's not an empty one. + if (config.description && !descriptionSize) + return false; + + // FIXME: WPT issue: https://github.com/web-platform-tests/wpt/issues/49636 is causing a test to fail when it shouldn't + // Opus with more than two channels require a description + // Extra spec issue: https://github.com/w3c/webcodecs/issues/861 : configure shouldn't throw on invalid config. + if (config.codec == "opus"_s && config.numberOfChannels > 2 && descriptionSize < 10) + return false; + + return true; +} + ExceptionOr WebCodecsAudioDecoder::configure(ScriptExecutionContext&, WebCodecsAudioDecoderConfig&& config) { if (!isValidDecoderConfig(config)) diff --git a/Source/WebCore/Modules/webcodecs/WebCodecsAudioEncoder.cpp b/Source/WebCore/Modules/webcodecs/WebCodecsAudioEncoder.cpp index 68a16cb563a25..f38231853eb23 100644 --- a/Source/WebCore/Modules/webcodecs/WebCodecsAudioEncoder.cpp +++ b/Source/WebCore/Modules/webcodecs/WebCodecsAudioEncoder.cpp @@ -90,11 +90,6 @@ static bool isSupportedEncoderCodec(const WebCodecsAudioEncoderConfig& config) if (config.sampleRate < 3000 || config.sampleRate > 384000) return false; - // FIXME: New WPT requires this to reject as non valid. For now we just state that it's not supported (webkit.org/b/283900) - // https://w3c.github.io/webcodecs/opus_codec_registration.html#opus-encoder-config - if (codec == "opus"_s && config.bitrate && (*config.bitrate < 6000 || *config.bitrate > 510000)) - return false; - return true; } @@ -106,14 +101,22 @@ static bool isValidEncoderConfig(const WebCodecsAudioEncoderConfig& config) if (!config.sampleRate || !config.numberOfChannels) return false; - // FIXME: This isn't per spec, but both Chrome and Firefox checks that the bitrate is now greater than INT_MAX + // FIXME: This isn't per spec, but both Chrome and Firefox checks that the bitrate is not greater than INT_MAX // Even though the spec made it a `long long` // https://github.com/web-platform-tests/wpt/issues/49634 if (config.bitrate && *config.bitrate > std::numeric_limits::max()) return false; - // FIXME: The opus and flac checks will probably need to move so that they trigger NotSupported - // errors in the future. + // FIXME: https://github.com/w3c/webcodecs/issues/860 + // Not per spec yet, but tested by w3c/web-platform-tests/webcodecs/audio-encoder-config.https.any.js 'Bit rate present but equal to zero' + if (config.bitrate && !config.bitrate) + return false; + + // FIXME: New WPT requires this to reject as non valid. For now we just state that it's not supported (webkit.org/b/283900) + // https://w3c.github.io/webcodecs/opus_codec_registration.html#opus-encoder-config + if (config.codec == "opus"_s && config.bitrate && (*config.bitrate < 6000 || *config.bitrate > 510000)) + return false; + if (auto opusConfig = config.opus) { if (!opusConfig->isValid()) return false;