test_HEAAC_extradata.html (3033B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>HE-AAC decoding test</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script type="text/javascript" src="mediasource.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 8 </head> 9 <body> 10 <pre id="test"> 11 <script class="testbody" type="text/javascript"> 12 13 14 SimpleTest.waitForExplicitFinish(); 15 16 const SOURCE_FILE = "whitenoise-he-aac-5s.mp4"; 17 18 // This test checks when decoding HE-AAC using MediaSource or HTTP playback, the 19 // audio is decoded correctly (in particular with the SBR part). This means 20 // that the extradata describing the encoded AAC stream have been communicated 21 // correctly to the audio decoder. For this, we check that there is energy 22 // above 10kHz using the Web Audio API when playing white noise, which has 23 // maximum energy accross the audible spectrum. 24 25 // Return the index corresponding for a particular frequency in an array 26 // containing frequency data from a FFT. 27 function binIndexForFrequency(frequency, fftSize, sampleRate) { 28 return (1 + Math.round((frequency * fftSize) / sampleRate)); 29 } 30 31 async function checkHighFrequencyContent(element) { 32 const ac = new AudioContext(); 33 await ac.resume(); 34 const mediaElementSource = ac.createMediaElementSource(element); 35 const analyser = new AnalyserNode(ac); 36 37 // Undo the volume scaling applied globally during test. This is fine because 38 // the audio isn't routed to an actual audio output device in this test, it's 39 // just analyzed with the Web Audio API. 40 const gain = new GainNode(ac); 41 const testVolumeScaling = 42 parseFloat(SpecialPowers.getCharPref("media.volume_scale")); 43 gain.gain.value = 1 / parseFloat(testVolumeScaling); 44 mediaElementSource.connect(gain).connect(analyser) 45 46 const spectrum = new Float32Array(analyser.frequencyBinCount); 47 const indexFor15kHz = 48 binIndexForFrequency(15000, analyser.fftSize, ac.sampleRate); 49 // Wait a few hundreds of milliseconds 50 while (!element.ended) { 51 await once(element, "timeupdate"); 52 analyser.getFloatFrequencyData(spectrum); 53 if (spectrum[indexFor15kHz] > -50) { 54 ok(spectrum[indexFor15kHz] > -50, 55 `Energy present at 15kHz (bin index: ${indexFor15kHz}) when playing white noise encoded in HE-AAC ${spectrum[indexFor15kHz]}`); 56 return; 57 } 58 } 59 ok(false, 60 `No energy present at 15kHz (bin index: ${indexFor15kHz}) when playing white noise encoded in HE-AAC (last value ${spectrum[indexFor15kHz]})`); 61 } 62 63 runWithMSE(async (ms, el) => { 64 // First check with MSE playback 65 el.controls = true; 66 await once(ms, "sourceopen"); 67 68 const audiosb = ms.addSourceBuffer('audio/mp4; codecs="mp4a.40.5"'); 69 await fetchAndLoad(audiosb, SOURCE_FILE, [""], ""); 70 ms.endOfStream(); 71 el.play(); 72 once(el, "playing"); 73 74 await checkHighFrequencyContent(el); 75 76 // Redo the same test, with HTTP playback 77 el.src = SOURCE_FILE; 78 el.play(); 79 once(el, "playing"); 80 81 await checkHighFrequencyContent(el); 82 83 SimpleTest.finish(); 84 }); 85 86 </script> 87 </pre> 88 </body> 89 </html>