test_decoderDelay.html (6058B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>Test that decoder delay is handled</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 8 </head> 9 <body> 10 <script class="testbody" type="text/javascript"> 11 SimpleTest.waitForExplicitFinish(); 12 const {AppConstants} = SpecialPowers.ChromeUtils.importESModule( 13 "resource://gre/modules/AppConstants.sys.mjs" 14 ); 15 16 var tests_half_a_second = [ 17 "half-a-second-1ch-44100-aac.mp4", 18 "half-a-second-1ch-44100-flac.flac", 19 "half-a-second-1ch-44100-libmp3lame.mp3", 20 "half-a-second-1ch-44100-libopus.opus", 21 "half-a-second-1ch-44100-libopus.webm", 22 "half-a-second-1ch-44100-libvorbis.ogg", 23 "half-a-second-1ch-44100.wav", 24 "half-a-second-1ch-48000-aac.mp4", 25 "half-a-second-1ch-48000-flac.flac", 26 "half-a-second-1ch-48000-libmp3lame.mp3", 27 "half-a-second-1ch-48000-libopus.opus", 28 "half-a-second-1ch-48000-libopus.webm", 29 "half-a-second-1ch-48000-libvorbis.ogg", 30 "half-a-second-1ch-48000.wav", 31 "half-a-second-2ch-44100-aac.mp4", 32 "half-a-second-2ch-44100-flac.flac", 33 "half-a-second-2ch-44100-libmp3lame.mp3", 34 "half-a-second-2ch-44100-libopus.opus", 35 "half-a-second-2ch-44100-libopus.webm", 36 "half-a-second-2ch-44100-libvorbis.ogg", 37 "half-a-second-2ch-44100.wav", 38 "half-a-second-2ch-48000-aac.mp4", 39 "half-a-second-2ch-48000-flac.flac", 40 "half-a-second-2ch-48000-libmp3lame.mp3", 41 "half-a-second-2ch-48000-libopus.opus", 42 "half-a-second-2ch-48000-libopus.webm", 43 "half-a-second-2ch-48000-libvorbis.ogg", 44 "half-a-second-2ch-48000.wav", 45 ]; 46 47 // Those files are almost exactly half a second, but don't have enough pre-roll/padding 48 // information in the container, or the container isn't parsed properly, so 49 // aren't trimmed appropriately. 50 // vorbis webm, opus mp4, aac adts 51 var tests_adts = [ 52 "half-a-second-1ch-44100-aac.aac", 53 "half-a-second-1ch-44100-libopus.mp4", 54 "half-a-second-1ch-44100-libvorbis.webm", 55 "half-a-second-1ch-48000-aac.aac", 56 "half-a-second-1ch-48000-libopus.mp4", 57 "half-a-second-1ch-48000-libvorbis.webm", 58 "half-a-second-2ch-44100-aac.aac", 59 "half-a-second-2ch-44100-libopus.mp4", 60 "half-a-second-2ch-44100-libvorbis.webm", 61 "half-a-second-2ch-48000-aac.aac", 62 "half-a-second-2ch-48000-libopus.mp4", 63 "half-a-second-2ch-48000-libvorbis.webm", 64 ]; 65 66 // Other files that have interesting characteristics. 67 var tests_others = [ 68 { 69 // Very short VBR file, 16 frames of audio at 44100. Padding spanning two 70 // packets. 71 "path": "sixteen-frames.mp3", 72 "frameCount": 16, 73 "samplerate": 44100, 74 "fuzz": {} 75 }, 76 { 77 // This is incorrect (the duration should be 0.5s exactly) 78 // This is tracked in https://github.com/mozilla/mp4parse-rust/issues/404 79 "path":"half-a-second-1ch-44100-aac-afconvert.mp4", 80 "frameCount": 22464, 81 "samplerate": 44100, 82 "fuzz": { 83 "android": 2 84 } 85 }, 86 { 87 // Bug 1856145 - Invalid OGG file with busted granulepos in the 88 // bytestrem, but we should be able to recover and play it properly. 89 // This triggers a bug in the decoder delay trimming logic. 90 "path": "1856145.ogg", 91 "samplerate": 8000, 92 "frameCount": 8192, 93 "fuzz" : {} 94 }, 95 { 96 // Bug 1924925 - Valid flac file that is very small. 97 "path": "tiny.flac", 98 "samplerate": 22500, 99 "frameCount": 2271, 100 "fuzz" : {} 101 } 102 ]; 103 104 var all_tests = [tests_half_a_second, tests_adts, tests_others].flat(); 105 106 var count = 0; 107 function checkDone() { 108 if (++count == all_tests.length) { 109 SimpleTest.finish(); 110 } 111 } 112 113 async function doit() { 114 var context = new OfflineAudioContext(1, 128, 48000); 115 tests_half_a_second.forEach(async testfile => { 116 var response = await fetch(testfile); 117 var buffer = await response.arrayBuffer(); 118 var decoded = await context.decodeAudioData(buffer); 119 is( 120 decoded.duration, 121 0.5, 122 "The file " + testfile + " is half a second." 123 ); 124 // Value found empirically after looking at the files. The initial 125 // amplitude should be 0 at phase 0 because those files are sine wave. 126 // The compression is sometimes lossy and the first sample is not always 127 // exactly 0.0. 128 ok( 129 Math.abs(decoded.getChannelData(0)[0]) <= 0.022, 130 `The start point for ${testfile} is correct ${ decoded.getChannelData(0)[0] }` 131 ); 132 checkDone(); 133 }); 134 tests_adts.forEach(async testfile => { 135 var response = await fetch(testfile); 136 var buffer = await response.arrayBuffer(); 137 var decoded = await context.decodeAudioData(buffer); 138 // Value found empirically after looking at the files. ADTS containers 139 // don't have encoder delay / padding info so we can't trim correctly. 140 ok( 141 Math.abs(decoded.duration - 0.5) < 0.02, 142 `The ADTS file ${testfile} is about half a second (${decoded.duration}, error: ${Math.abs(decoded.duration-0.5)}).` 143 ); 144 checkDone(); 145 }); 146 tests_others.forEach(async test => { 147 // Get an context at a specific rate to avoid duration changes due to resampling. 148 var contextAtRate = new OfflineAudioContext(1, 128, test.samplerate); 149 var response = await fetch(test.path); 150 var buffer = await response.arrayBuffer(); 151 var decoded = await contextAtRate.decodeAudioData(buffer); 152 const fuzz = test.fuzz[AppConstants.platform] ?? 0; 153 ok(Math.abs(decoded.length - test.frameCount) <= fuzz, `${test.path} is ${decoded.length} frames long`); 154 checkDone(); 155 }); 156 } 157 158 doit(); 159 </script> 160 </body> 161 </html>