diff options
Diffstat (limited to '')
1430 files changed, 44481 insertions, 0 deletions
diff --git a/dom/media/test/16bit_wave_extrametadata.wav b/dom/media/test/16bit_wave_extrametadata.wav Binary files differnew file mode 100644 index 0000000000..443ec73a3d --- /dev/null +++ b/dom/media/test/16bit_wave_extrametadata.wav diff --git a/dom/media/test/16bit_wave_extrametadata.wav^headers^ b/dom/media/test/16bit_wave_extrametadata.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/16bit_wave_extrametadata.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/320x240.ogv b/dom/media/test/320x240.ogv Binary files differnew file mode 100644 index 0000000000..093158432a --- /dev/null +++ b/dom/media/test/320x240.ogv diff --git a/dom/media/test/320x240.ogv^headers^ b/dom/media/test/320x240.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/320x240.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/448636.ogv b/dom/media/test/448636.ogv Binary files differnew file mode 100644 index 0000000000..628df924f8 --- /dev/null +++ b/dom/media/test/448636.ogv diff --git a/dom/media/test/448636.ogv^headers^ b/dom/media/test/448636.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/448636.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/A4.ogv b/dom/media/test/A4.ogv Binary files differnew file mode 100644 index 0000000000..de99616ece --- /dev/null +++ b/dom/media/test/A4.ogv diff --git a/dom/media/test/A4.ogv^headers^ b/dom/media/test/A4.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/A4.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/TestPatternHDR.mp4 b/dom/media/test/TestPatternHDR.mp4 Binary files differnew file mode 100644 index 0000000000..2aeb5d7f05 --- /dev/null +++ b/dom/media/test/TestPatternHDR.mp4 diff --git a/dom/media/test/VID_0001.ogg b/dom/media/test/VID_0001.ogg Binary files differnew file mode 100644 index 0000000000..0068b9af85 --- /dev/null +++ b/dom/media/test/VID_0001.ogg diff --git a/dom/media/test/VID_0001.ogg^headers^ b/dom/media/test/VID_0001.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/VID_0001.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/adts.aac b/dom/media/test/adts.aac Binary files differnew file mode 100644 index 0000000000..208515464a --- /dev/null +++ b/dom/media/test/adts.aac diff --git a/dom/media/test/adts.aac^headers^ b/dom/media/test/adts.aac^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/adts.aac^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/allowed.sjs b/dom/media/test/allowed.sjs new file mode 100644 index 0000000000..4460cd05af --- /dev/null +++ b/dom/media/test/allowed.sjs @@ -0,0 +1,61 @@ +function parseQuery(request, key) { + var params = request.queryString.split("&"); + for (var j = 0; j < params.length; ++j) { + var p = params[j]; + if (p == key) { + return true; + } + if (p.indexOf(key + "=") == 0) { + return p.substring(key.length + 1); + } + if (!p.includes("=") && key == "") { + return p; + } + } + return false; +} + +var types = { + js: "text/javascript", + m4s: "video/mp4", + mp4: "video/mp4", + ogg: "video/ogg", + ogv: "video/ogg", + oga: "audio/ogg", + webm: "video/webm", + wav: "audio/x-wav", +}; + +// Return file with name as per the query string with access control +// allow headers. +function handleRequest(request, response) { + var resource = parseQuery(request, ""); + + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + var paths = "tests/dom/media/test/" + resource; + var split = paths.split("/"); + for (var i = 0; i < split.length; ++i) { + file.append(split[i]); + } + fis.init(file, -1, -1, false); + dump("file=" + file + "\n"); + bis.setInputStream(fis); + var bytes = bis.readBytes(bis.available()); + response.setStatusLine(request.httpVersion, 206, "Partial Content"); + response.setHeader( + "Content-Range", + "bytes 0-" + (bytes.length - 1) + "/" + bytes.length + ); + response.setHeader("Content-Length", "" + bytes.length, false); + var ext = resource.substring(resource.lastIndexOf(".") + 1); + response.setHeader("Content-Type", types[ext], false); + response.setHeader("Access-Control-Allow-Origin", "*"); + response.write(bytes, bytes.length); + bis.close(); +} diff --git a/dom/media/test/ambisonics.mp4 b/dom/media/test/ambisonics.mp4 Binary files differnew file mode 100644 index 0000000000..4f5bcdfd26 --- /dev/null +++ b/dom/media/test/ambisonics.mp4 diff --git a/dom/media/test/ambisonics.mp4^headers^ b/dom/media/test/ambisonics.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/ambisonics.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/audio-gaps-short.ogg b/dom/media/test/audio-gaps-short.ogg Binary files differnew file mode 100644 index 0000000000..e01a24bfda --- /dev/null +++ b/dom/media/test/audio-gaps-short.ogg diff --git a/dom/media/test/audio-gaps-short.ogg^headers^ b/dom/media/test/audio-gaps-short.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/audio-gaps-short.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/audio-gaps.ogg b/dom/media/test/audio-gaps.ogg Binary files differnew file mode 100644 index 0000000000..ce96748ccd --- /dev/null +++ b/dom/media/test/audio-gaps.ogg diff --git a/dom/media/test/audio-gaps.ogg^headers^ b/dom/media/test/audio-gaps.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/audio-gaps.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/audio-overhang.ogg b/dom/media/test/audio-overhang.ogg Binary files differnew file mode 100644 index 0000000000..c07986e7a1 --- /dev/null +++ b/dom/media/test/audio-overhang.ogg diff --git a/dom/media/test/audio-overhang.ogg^headers^ b/dom/media/test/audio-overhang.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/audio-overhang.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/audio.wav b/dom/media/test/audio.wav Binary files differnew file mode 100644 index 0000000000..c6fd5cb869 --- /dev/null +++ b/dom/media/test/audio.wav diff --git a/dom/media/test/audio.wav^headers^ b/dom/media/test/audio.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/audio.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/av1.mp4 b/dom/media/test/av1.mp4 Binary files differnew file mode 100644 index 0000000000..28de929a29 --- /dev/null +++ b/dom/media/test/av1.mp4 diff --git a/dom/media/test/av1.mp4^headers^ b/dom/media/test/av1.mp4^headers^ new file mode 100644 index 0000000000..2567dc2fe5 --- /dev/null +++ b/dom/media/test/av1.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
\ No newline at end of file diff --git a/dom/media/test/background_video.js b/dom/media/test/background_video.js new file mode 100644 index 0000000000..508f8fd89a --- /dev/null +++ b/dom/media/test/background_video.js @@ -0,0 +1,224 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This file expects manager to be defined in the global scope. +/* global manager */ +/* import-globals-from manifest.js */ + +"use strict"; + +function startTest(test) { + info(test.desc); + SimpleTest.waitForExplicitFinish(); + SpecialPowers.pushPrefEnv({ set: test.prefs }, () => { + manager.runTests(test.tests, test.runTest); + }); +} + +function nextVideoEnded(video) { + return nextEvent(video, "ended"); +} + +function nextVideoPlaying(video) { + return nextEvent(video, "playing"); +} + +function nextVideoResumes(video) { + return nextEvent(video, "mozexitvideosuspend"); +} + +function nextVideoSuspends(video) { + return nextEvent(video, "mozentervideosuspend"); +} + +/** + * @param {string} url video src. + * @returns {HTMLMediaElement} The created video element. + */ +function appendVideoToDoc(url, token, width, height) { + // Default size of (160, 120) is used by other media tests. + if (width === undefined) { + width = 160; + } + if (height === undefined) { + height = (3 * width) / 4; + } + + let v = document.createElement("video"); + v.token = token; + v.width = width; + v.height = height; + v.src = url; + document.body.appendChild(v); + return v; +} + +function appendVideoToDocWithoutLoad(token, width, height) { + // Default size of (160, 120) is used by other media tests. + if (width === undefined) { + width = 160; + } + if (height === undefined) { + height = (3 * width) / 4; + } + + let v = document.createElement("video"); + v.token = token; + document.body.appendChild(v); + v.width = width; + v.height = height; + return v; +} + +function loadAndWaitUntilLoadedmetadata(video, url, preloadType = "metadata") { + return new Promise((resolve, reject) => { + video.preload = preloadType; + video.addEventListener( + "loadedmetadata", + () => { + resolve(); + }, + true + ); + video.src = url; + }); +} + +/** + * @param {HTMLMediaElement} video Video element with under test. + * @returns {Promise} Promise that is resolved when video 'visibilitychanged' event fires. + */ +function waitUntilVisible(video) { + let videoChrome = SpecialPowers.wrap(video); + if (videoChrome.isInViewPort) { + return Promise.resolve(); + } + + return new Promise(resolve => { + videoChrome.addEventListener("visibilitychanged", () => { + if (videoChrome.isInViewPort) { + ok(true, `${video.token} is visible.`); + videoChrome.removeEventListener("visibilitychanged", this); + resolve(); + } + }); + }); +} + +/** + * @param {HTMLMediaElement} video Video element under test. + * @returns {Promise} Promise that is resolved when video 'playing' event fires. + */ +function waitUntilPlaying(video) { + var p = once(video, "playing", () => { + ok(true, `${video.token} played.`); + }); + Log(video.token, "Start playing"); + video.play(); + return p; +} + +/** + * @param {HTMLMediaElement} video Video element under test. + * @returns {Promise} Promise which is resolved when video 'ended' event fires. + */ +function waitUntilEnded(video) { + Log(video.token, "Waiting for ended"); + if (video.ended) { + ok(true, video.token + " already ended"); + return Promise.resolve(); + } + + return once(video, "ended", () => { + ok(true, `${video.token} ended`); + }); +} + +/** + * @param {HTMLMediaElement} video Video element under test. + * @returns {Promise} Promise that is resolved when video decode starts + * suspend timer. + */ +function testSuspendTimerStartedWhenHidden(video) { + var p = once(video, "mozstartvideosuspendtimer").then(() => { + ok(true, `${video.token} suspend begins`); + }); + Log(video.token, "Set Hidden"); + video.setVisible(false); + return p; +} + +/** + * @param {HTMLMediaElement} video Video element under test. + * @returns {Promise} Promise that is resolved when video decode suspends. + */ +function testVideoSuspendsWhenHidden(video) { + let p = once(video, "mozentervideosuspend").then(() => { + ok(true, `${video.token} suspends`); + }); + Log(video.token, "Set hidden"); + video.setVisible(false); + return p; +} + +/** + * @param {HTMLMediaElement} video Video element under test. + * @returns {Promise} Promise that is resolved when video decode resumes. + */ +function testVideoResumesWhenShown(video) { + var p = once(video, "mozexitvideosuspend").then(() => { + ok(true, `${video.token} resumes`); + }); + Log(video.token, "Set visible"); + video.setVisible(true); + return p; +} + +/** + * @param {HTMLMediaElement} video Video element under test. + * @returns {Promise} Promise that is resolved when video decode resumes. + */ +function testVideoOnlySeekCompletedWhenShown(video) { + var p = once(video, "mozvideoonlyseekcompleted").then(() => { + ok(true, `${video.token} resumes`); + }); + Log(video.token, "Set visible"); + video.setVisible(true); + return p; +} + +/** + * @param {HTMLVideoElement} video Video element under test. + * @returns {Promise} Promise that is resolved if video ends and rejects if video suspends. + */ +function checkVideoDoesntSuspend(video) { + let p = Promise.race([ + waitUntilEnded(video).then(() => { + ok(true, `${video.token} ended before decode was suspended`); + }), + once(video, "mozentervideosuspend", () => { + Promise.reject(new Error(`${video.token} suspended`)); + }), + ]); + Log(video.token, "Set hidden."); + video.setVisible(false); + return p; +} + +/** + * @param {HTMLMediaElement} video Video element under test. + * @param {number} time video current time to wait til. + * @returns {Promise} Promise that is resolved once currentTime passes time. + */ +function waitTil(video, time) { + Log(video.token, `Waiting for time to reach ${time}s`); + return new Promise(resolve => { + video.addEventListener("timeupdate", function timeUpdateEvent() { + if (video.currentTime > time) { + video.removeEventListener(name, timeUpdateEvent); + resolve(); + } + }); + }); +} diff --git a/dom/media/test/badtags.ogg b/dom/media/test/badtags.ogg Binary files differnew file mode 100644 index 0000000000..12d8358730 --- /dev/null +++ b/dom/media/test/badtags.ogg diff --git a/dom/media/test/badtags.ogg^headers^ b/dom/media/test/badtags.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/badtags.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bear-640x360-a_frag-cenc-key_rotation.mp4 b/dom/media/test/bear-640x360-a_frag-cenc-key_rotation.mp4 Binary files differnew file mode 100644 index 0000000000..dc4f197ffa --- /dev/null +++ b/dom/media/test/bear-640x360-a_frag-cenc-key_rotation.mp4 diff --git a/dom/media/test/bear-640x360-v_frag-cenc-key_rotation.mp4 b/dom/media/test/bear-640x360-v_frag-cenc-key_rotation.mp4 Binary files differnew file mode 100644 index 0000000000..916c64e9ee --- /dev/null +++ b/dom/media/test/bear-640x360-v_frag-cenc-key_rotation.mp4 diff --git a/dom/media/test/beta-phrasebook.ogg b/dom/media/test/beta-phrasebook.ogg Binary files differnew file mode 100644 index 0000000000..7e6ef77ec4 --- /dev/null +++ b/dom/media/test/beta-phrasebook.ogg diff --git a/dom/media/test/beta-phrasebook.ogg^headers^ b/dom/media/test/beta-phrasebook.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/beta-phrasebook.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/big-buck-bunny-cenc-avc3-1.m4s b/dom/media/test/big-buck-bunny-cenc-avc3-1.m4s Binary files differnew file mode 100644 index 0000000000..266ec4c100 --- /dev/null +++ b/dom/media/test/big-buck-bunny-cenc-avc3-1.m4s diff --git a/dom/media/test/big-buck-bunny-cenc-avc3-1.m4s^headers^ b/dom/media/test/big-buck-bunny-cenc-avc3-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/big-buck-bunny-cenc-avc3-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/big-buck-bunny-cenc-avc3-init.mp4 b/dom/media/test/big-buck-bunny-cenc-avc3-init.mp4 Binary files differnew file mode 100644 index 0000000000..7aeb3eca8a --- /dev/null +++ b/dom/media/test/big-buck-bunny-cenc-avc3-init.mp4 diff --git a/dom/media/test/big-buck-bunny-cenc-avc3-init.mp4^headers^ b/dom/media/test/big-buck-bunny-cenc-avc3-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/big-buck-bunny-cenc-avc3-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/big-short.wav b/dom/media/test/big-short.wav Binary files differnew file mode 100644 index 0000000000..c850e5fd14 --- /dev/null +++ b/dom/media/test/big-short.wav diff --git a/dom/media/test/big-short.wav^headers^ b/dom/media/test/big-short.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/big-short.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/big.wav b/dom/media/test/big.wav Binary files differnew file mode 100644 index 0000000000..5f66bc1f02 --- /dev/null +++ b/dom/media/test/big.wav diff --git a/dom/media/test/big.wav^headers^ b/dom/media/test/big.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/big.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc-audio-key1.xml b/dom/media/test/bipbop-cenc-audio-key1.xml new file mode 100644 index 0000000000..a1672eecef --- /dev/null +++ b/dom/media/test/bipbop-cenc-audio-key1.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + This XML file describes the encryption applied to |bipbop_<res>-cenc*|. To + generate the encrypted files, run bipbop-cenc.sh +--> + +<GPACDRM type="CENC AES-CTR"> + + <DRMInfo type="pssh" version="1"> + <!-- + SystemID specified in + https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/cenc-format.html + --> + <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b" /> + <!-- Number of KeyIDs = 1 --> + <BS bits="32" value="1" /> + <!-- KeyID --> + <BS ID128="0x7e571d047e571d047e571d047e571d21" /> + </DRMInfo> + + <CrypTrack trackID="2" isEncrypted="1" IV_size="16" saiSavedBox="senc" + first_IV="0x00000000000000000000000000000000"> + <key KID="0x7e571d047e571d047e571d047e571d21" + value="0x7e5744447e5744447e5744447e574421" /> + </CrypTrack> + +</GPACDRM> diff --git a/dom/media/test/bipbop-cenc-audio-key2.xml b/dom/media/test/bipbop-cenc-audio-key2.xml new file mode 100644 index 0000000000..b706609052 --- /dev/null +++ b/dom/media/test/bipbop-cenc-audio-key2.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + This XML file describes the encryption applied to |bipbop_<res>-cenc*|. To + generate the encrypted files, run bipbop-cenc.sh +--> + +<GPACDRM type="CENC AES-CTR"> + + <DRMInfo type="pssh" version="1"> + <!-- + SystemID specified in + https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/cenc-format.html + --> + <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b" /> + <!-- Number of KeyIDs = 1 --> + <BS bits="32" value="1" /> + <!-- KeyID --> + <BS ID128="0x7e571d047e571d047e571d047e571d22" /> + </DRMInfo> + + <CrypTrack trackID="2" isEncrypted="1" IV_size="16" saiSavedBox="senc" + first_IV="0x00000000000000000000000000000000"> + <key KID="0x7e571d047e571d047e571d047e571d22" + value="0x7e5744447e5744447e5744447e574422" /> + </CrypTrack> + +</GPACDRM> diff --git a/dom/media/test/bipbop-cenc-audio1.m4s b/dom/media/test/bipbop-cenc-audio1.m4s Binary files differnew file mode 100644 index 0000000000..63cfd66f7e --- /dev/null +++ b/dom/media/test/bipbop-cenc-audio1.m4s diff --git a/dom/media/test/bipbop-cenc-audio1.m4s^headers^ b/dom/media/test/bipbop-cenc-audio1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-cenc-audio1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc-audio2.m4s b/dom/media/test/bipbop-cenc-audio2.m4s Binary files differnew file mode 100644 index 0000000000..04a6cb6ff9 --- /dev/null +++ b/dom/media/test/bipbop-cenc-audio2.m4s diff --git a/dom/media/test/bipbop-cenc-audio2.m4s^headers^ b/dom/media/test/bipbop-cenc-audio2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-cenc-audio2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc-audio3.m4s b/dom/media/test/bipbop-cenc-audio3.m4s Binary files differnew file mode 100644 index 0000000000..ad0cd72f90 --- /dev/null +++ b/dom/media/test/bipbop-cenc-audio3.m4s diff --git a/dom/media/test/bipbop-cenc-audio3.m4s^headers^ b/dom/media/test/bipbop-cenc-audio3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-cenc-audio3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc-audioinit.mp4 b/dom/media/test/bipbop-cenc-audioinit.mp4 Binary files differnew file mode 100644 index 0000000000..b827aa49aa --- /dev/null +++ b/dom/media/test/bipbop-cenc-audioinit.mp4 diff --git a/dom/media/test/bipbop-cenc-audioinit.mp4^headers^ b/dom/media/test/bipbop-cenc-audioinit.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-cenc-audioinit.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc-video-10s.mp4 b/dom/media/test/bipbop-cenc-video-10s.mp4 Binary files differnew file mode 100644 index 0000000000..abbe4561fd --- /dev/null +++ b/dom/media/test/bipbop-cenc-video-10s.mp4 diff --git a/dom/media/test/bipbop-cenc-video-10s.mp4^headers^ b/dom/media/test/bipbop-cenc-video-10s.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-cenc-video-10s.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc-video-key1.xml b/dom/media/test/bipbop-cenc-video-key1.xml new file mode 100644 index 0000000000..f0d9878fa2 --- /dev/null +++ b/dom/media/test/bipbop-cenc-video-key1.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + This XML file describes the encryption applied to |bipbop_<res>-cenc*|. To + generate the encrypted files, run bipbop-cenc.sh +--> + +<GPACDRM type="CENC AES-CTR"> + + <DRMInfo type="pssh" version="1"> + <!-- + SystemID specified in + https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/cenc-format.html + --> + <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b" /> + <!-- Number of KeyIDs = 1 --> + <BS bits="32" value="1" /> + <!-- KeyID --> + <BS ID128="0x7e571d037e571d037e571d037e571d11" /> + </DRMInfo> + + <CrypTrack trackID="1" isEncrypted="1" IV_size="16" saiSavedBox="senc" + first_IV="0x00000000000000000000000000000000"> + <key KID="0x7e571d037e571d037e571d037e571d11" + value="0x7e5733337e5733337e5733337e573311" /> + </CrypTrack> + +</GPACDRM> diff --git a/dom/media/test/bipbop-cenc-video-key2.xml b/dom/media/test/bipbop-cenc-video-key2.xml new file mode 100644 index 0000000000..1f320e6336 --- /dev/null +++ b/dom/media/test/bipbop-cenc-video-key2.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + This XML file describes the encryption applied to |bipbop_<res>-cenc*|. To + generate the encrypted files, run bipbop-cenc.sh +--> + +<GPACDRM type="CENC AES-CTR"> + + <DRMInfo type="pssh" version="1"> + <!-- + SystemID specified in + https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/cenc-format.html + --> + <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b" /> + <!-- Number of KeyIDs = 1 --> + <BS bits="32" value="1" /> + <!-- KeyID --> + <BS ID128="0x7e571d037e571d037e571d037e571d12" /> + </DRMInfo> + + <CrypTrack trackID="1" isEncrypted="1" IV_size="16" saiSavedBox="senc" + first_IV="0x00000000000000000000000000000000"> + <key KID="0x7e571d037e571d037e571d037e571d12" + value="0x7e5733337e5733337e5733337e573312" /> + </CrypTrack> + +</GPACDRM> diff --git a/dom/media/test/bipbop-cenc-video1.m4s b/dom/media/test/bipbop-cenc-video1.m4s Binary files differnew file mode 100644 index 0000000000..755013c11c --- /dev/null +++ b/dom/media/test/bipbop-cenc-video1.m4s diff --git a/dom/media/test/bipbop-cenc-video1.m4s^headers^ b/dom/media/test/bipbop-cenc-video1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-cenc-video1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc-video2.m4s b/dom/media/test/bipbop-cenc-video2.m4s Binary files differnew file mode 100644 index 0000000000..c884bd95fc --- /dev/null +++ b/dom/media/test/bipbop-cenc-video2.m4s diff --git a/dom/media/test/bipbop-cenc-video2.m4s^headers^ b/dom/media/test/bipbop-cenc-video2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-cenc-video2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc-videoinit.mp4 b/dom/media/test/bipbop-cenc-videoinit.mp4 Binary files differnew file mode 100644 index 0000000000..aa87d0bbe6 --- /dev/null +++ b/dom/media/test/bipbop-cenc-videoinit.mp4 diff --git a/dom/media/test/bipbop-cenc-videoinit.mp4^headers^ b/dom/media/test/bipbop-cenc-videoinit.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-cenc-videoinit.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-cenc.sh b/dom/media/test/bipbop-cenc.sh new file mode 100644 index 0000000000..a00c38ae80 --- /dev/null +++ b/dom/media/test/bipbop-cenc.sh @@ -0,0 +1,29 @@ +mkdir work.tmp + +for r in 225w_175kbps 300_215kbps 300wp_227kbps 360w_253kbps 480_624kbps 480wp_663kbps 480_959kbps 480wp_1001kbps +do + for k in 1 2 + do + # Encrypt bipbop_<res>.mp4 with the keys specified in this file, + # and output to |bipbop_<res>-cenc-{video,audio}.mp4| + MP4Box -crypt bipbop-cenc-audio-key${k}.xml -rem 1 -out work.tmp/bipbop_${r}-cenc-audio-key${k}.mp4 bipbop_${r}.mp4 + MP4Box -crypt bipbop-cenc-video-key${k}.xml -rem 2 -out work.tmp/bipbop_${r}-cenc-video-key${k}.mp4 bipbop_${r}.mp4 + + # Fragment |bipbop_<res>-cenc-*.mp4| into 500ms segments: + MP4Box -dash 500 -rap -segment-name work.tmp/bipbop_${r}-cenc-audio-key${k}- -subsegs-per-sidx 5 work.tmp/bipbop_${r}-cenc-audio-key${k}.mp4 + MP4Box -dash 500 -rap -segment-name work.tmp/bipbop_${r}-cenc-video-key${k}- -subsegs-per-sidx 5 work.tmp/bipbop_${r}-cenc-video-key${k}.mp4 + + # The above command will generate a set of fragments |bipbop_<res>-cenc-{video,audio}-*.m4s + # and |bipbop_<res>-cenc-{video,audio}-init.mp4| containing just the init segment. + + # Remove unneeded mpd files. + rm bipbop_${r}-cenc-{audio,video}-key${k}_dash.mpd + done +done + +# Only keep the first 4 audio & 2 video segments: +cp work.tmp/*-init[.]mp4 ./ +cp work.tmp/*audio*-[1234][.]m4s ./ +cp work.tmp/*video*-[12][.]m4s ./ + +rm -Rf work.tmp diff --git a/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-audio.mp4 b/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-audio.mp4 Binary files differnew file mode 100644 index 0000000000..5e5e30c255 --- /dev/null +++ b/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-audio.mp4 diff --git a/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^ b/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-video.mp4 b/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-video.mp4 Binary files differnew file mode 100644 index 0000000000..447c657475 --- /dev/null +++ b/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-video.mp4 diff --git a/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^ b/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop-frag-cenc.xml b/dom/media/test/bipbop-frag-cenc.xml new file mode 100644 index 0000000000..6f6a4d90a9 --- /dev/null +++ b/dom/media/test/bipbop-frag-cenc.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + This XML file describes the encryption applied to |bipbop-cenc*|. To + generate the bipbop-cenc files, run the following commands: + + Encrypt bipbop-no-edts.mp4 with the keys specified in this file, + and output to |bipbop-cenc-{video,audio}.mp4| + MP4Box -crypt bipbop-frag-cenc.xml -rem 2 -out bipbop-cenc-video.mp4 bipbop-no-edts.mp4 + MP4Box -crypt bipbop-frag-cenc.xml -rem 1 -out bipbop-cenc-audio.mp4 bipbop-no-edts.mp4 + + Fragment |bipbop-cenc-*.mp4| into 500ms segments: + MP4Box -dash 500 -rap -segment-name bipbop-cenc-video -subsegs-per-sidx 5 bipbop-cenc-video.mp4 + MP4Box -dash 500 -rap -segment-name bipbop-cenc-audio -subsegs-per-sidx 5 bipbop-cenc-audio.mp4 + + The above command will generate a set of fragments in |bipbop-cenc-{video,audio}*.m4s + and |bipbop-cenc-{video,audio}init.mp4| containing just the init segment. + + To cut down the duration, we throw out all but the first 3 audio & 2 video segments: + rm bipbop-cenc-audio{[^123],[123][^.]}.m4s + rm bipbop-cenc-video{[^12],[12][^.]}.m4s + + MP4Box will also have generated some *.mpd files we don't need: + rm bipbop-cenc-*.mpd + + Delete intermediate encrypted files: + rm bipbop-cenc-{audio,video}.mp4 +--> + +<GPACDRM type="CENC AES-CTR"> + + <DRMInfo type="pssh" version="1"> + <!-- + SystemID specified in + https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/cenc-format.html + --> + <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b" /> + <!-- Number of KeyIDs = 2 --> + <BS bits="32" value="2" /> + <!-- KeyID --> + <BS ID128="0x7e571d037e571d037e571d037e571d03" /> + <BS ID128="0x7e571d047e571d047e571d047e571d04" /> + </DRMInfo> + + <CrypTrack trackID="1" isEncrypted="1" IV_size="16" saiSavedBox="senc" + first_IV="0x00000000000000000000000000000000"> + <key KID="0x7e571d037e571d037e571d037e571d03" + value="0x7e5733337e5733337e5733337e573333" /> + </CrypTrack> + + <CrypTrack trackID="2" isEncrypted="1" IV_size="16" saiSavedBox="senc" + first_IV="0x00000000000000000000000000000000"> + <key KID="0x7e571d047e571d047e571d047e571d04" + value="0x7e5744447e5744447e5744447e574444" /> + </CrypTrack> + +</GPACDRM> diff --git a/dom/media/test/bipbop-lateaudio.mp4 b/dom/media/test/bipbop-lateaudio.mp4 Binary files differnew file mode 100644 index 0000000000..5b4cc57095 --- /dev/null +++ b/dom/media/test/bipbop-lateaudio.mp4 diff --git a/dom/media/test/bipbop-lateaudio.mp4^headers^ b/dom/media/test/bipbop-lateaudio.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop-lateaudio.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop-no-edts.mp4 b/dom/media/test/bipbop-no-edts.mp4 Binary files differnew file mode 100644 index 0000000000..63435887df --- /dev/null +++ b/dom/media/test/bipbop-no-edts.mp4 diff --git a/dom/media/test/bipbop.mp4 b/dom/media/test/bipbop.mp4 Binary files differnew file mode 100644 index 0000000000..017d658f31 --- /dev/null +++ b/dom/media/test/bipbop.mp4 diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-1.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..e2bd754c7e --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-1.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-2.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..347835feee --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-2.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-3.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-3.m4s Binary files differnew file mode 100644 index 0000000000..64b0da69a0 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-3.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-4.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-4.m4s Binary files differnew file mode 100644 index 0000000000..864f4248af --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-4.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-init.mp4 b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..40c3a7bb98 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-init.mp4 diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-1.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..a8896e069a --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-1.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-2.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..0f0a35ce79 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-2.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-3.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-3.m4s Binary files differnew file mode 100644 index 0000000000..fece52ff42 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-3.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-4.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-4.m4s Binary files differnew file mode 100644 index 0000000000..70e61e3d5f --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-4.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-init.mp4 b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..986e5fb186 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-init.mp4 diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-1.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..547950e516 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-1.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-init.mp4 b/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..3214f131d4 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-init.mp4 diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-1.m4s b/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..08713078d9 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-1.m4s diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-init.mp4 b/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..0b13fed5f0 --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-init.mp4 diff --git a/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_225w_175kbps.mp4 b/dom/media/test/bipbop_225w_175kbps.mp4 Binary files differnew file mode 100644 index 0000000000..abe37b9f9d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps.mp4 diff --git a/dom/media/test/bipbop_225w_175kbps.mp4^headers^ b/dom/media/test/bipbop_225w_175kbps.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_225w_175kbps.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-1.m4s b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..e2bd754c7e --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-1.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-2.m4s b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..347835feee --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-2.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-3.m4s b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-3.m4s Binary files differnew file mode 100644 index 0000000000..64b0da69a0 --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-3.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-4.m4s b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-4.m4s Binary files differnew file mode 100644 index 0000000000..864f4248af --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-4.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-init.mp4 b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..21f3863274 --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-init.mp4 diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-1.m4s b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..a8896e069a --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-1.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-2.m4s b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..0f0a35ce79 --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-2.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-3.m4s b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-3.m4s Binary files differnew file mode 100644 index 0000000000..fece52ff42 --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-3.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-4.m4s b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-4.m4s Binary files differnew file mode 100644 index 0000000000..70e61e3d5f --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-4.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-init.mp4 b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..bc741cdf86 --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-init.mp4 diff --git a/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key1-1.m4s b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..9c6818d06f --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-1.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key1-2.m4s b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..f327aaa573 --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-2.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key1-init.mp4 b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..543f18c24b --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-init.mp4 diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key2-1.m4s b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..f850ceaf0a --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-1.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key2-2.m4s b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..a28a106daf --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-2.m4s diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key2-init.mp4 b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..a05a879970 --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-init.mp4 diff --git a/dom/media/test/bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300_215kbps.mp4 b/dom/media/test/bipbop_300_215kbps.mp4 Binary files differnew file mode 100644 index 0000000000..084d477430 --- /dev/null +++ b/dom/media/test/bipbop_300_215kbps.mp4 diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-1.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..e2bd754c7e --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-1.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-2.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..347835feee --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-2.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-3.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-3.m4s Binary files differnew file mode 100644 index 0000000000..64b0da69a0 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-3.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-4.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-4.m4s Binary files differnew file mode 100644 index 0000000000..864f4248af --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-4.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-init.mp4 b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..40c3a7bb98 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-init.mp4 diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-1.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..a8896e069a --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-1.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-2.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..0f0a35ce79 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-2.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-3.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-3.m4s Binary files differnew file mode 100644 index 0000000000..fece52ff42 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-3.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-4.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-4.m4s Binary files differnew file mode 100644 index 0000000000..70e61e3d5f --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-4.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-init.mp4 b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..986e5fb186 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-init.mp4 diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-1.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..9c6818d06f --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-1.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-2.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..ce2e64eb33 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-2.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-init.mp4 b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..8592a5b0a3 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-init.mp4 diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-1.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..f850ceaf0a --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-1.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-2.m4s b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..d07ce9753e --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-2.m4s diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-init.mp4 b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..9d2fa23dd4 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-init.mp4 diff --git a/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_300wp_227kbps.mp4 b/dom/media/test/bipbop_300wp_227kbps.mp4 Binary files differnew file mode 100644 index 0000000000..1499355313 --- /dev/null +++ b/dom/media/test/bipbop_300wp_227kbps.mp4 diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-1.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..e2bd754c7e --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-1.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-2.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..347835feee --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-2.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-3.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-3.m4s Binary files differnew file mode 100644 index 0000000000..64b0da69a0 --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-3.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-4.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-4.m4s Binary files differnew file mode 100644 index 0000000000..864f4248af --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-4.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-init.mp4 b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..40c3a7bb98 --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-init.mp4 diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-1.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..a8896e069a --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-1.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-2.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..0f0a35ce79 --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-2.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-3.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-3.m4s Binary files differnew file mode 100644 index 0000000000..fece52ff42 --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-3.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-4.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-4.m4s Binary files differnew file mode 100644 index 0000000000..70e61e3d5f --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-4.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-init.mp4 b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..986e5fb186 --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-init.mp4 diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-1.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..a571d47cfb --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-1.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-init.mp4 b/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..42dbfec1ed --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-init.mp4 diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-1.m4s b/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..9e4224cac8 --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-1.m4s diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-init.mp4 b/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..21763ecbdd --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-init.mp4 diff --git a/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-clearkey-audio.webm b/dom/media/test/bipbop_360w_253kbps-clearkey-audio.webm Binary files differnew file mode 100644 index 0000000000..4be8f340c3 --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-clearkey-audio.webm diff --git a/dom/media/test/bipbop_360w_253kbps-clearkey-audio.webm^headers^ b/dom/media/test/bipbop_360w_253kbps-clearkey-audio.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-clearkey-audio.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp8.webm b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp8.webm Binary files differnew file mode 100644 index 0000000000..56cf4c483c --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp8.webm diff --git a/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^ b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp9.webm b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp9.webm Binary files differnew file mode 100644 index 0000000000..9f411d0e34 --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp9.webm diff --git a/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^ b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_360w_253kbps.mp4 b/dom/media/test/bipbop_360w_253kbps.mp4 Binary files differnew file mode 100644 index 0000000000..6c796f4e1f --- /dev/null +++ b/dom/media/test/bipbop_360w_253kbps.mp4 diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-1.m4s b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..e2bd754c7e --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-1.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-2.m4s b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..347835feee --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-2.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-3.m4s b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-3.m4s Binary files differnew file mode 100644 index 0000000000..64b0da69a0 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-3.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-4.m4s b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-4.m4s Binary files differnew file mode 100644 index 0000000000..864f4248af --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-4.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-init.mp4 b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..e626fa4564 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-init.mp4 diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-1.m4s b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..a8896e069a --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-1.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-2.m4s b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..0f0a35ce79 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-2.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-3.m4s b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-3.m4s Binary files differnew file mode 100644 index 0000000000..fece52ff42 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-3.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-4.m4s b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-4.m4s Binary files differnew file mode 100644 index 0000000000..70e61e3d5f --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-4.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-init.mp4 b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..d7cbb2b6b0 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-init.mp4 diff --git a/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key1-1.m4s b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..805f4bbf3f --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-1.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key1-2.m4s b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..5bf9994733 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-2.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key1-init.mp4 b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..77c7daba5a --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-init.mp4 diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key2-1.m4s b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..c5127beec9 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-1.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key2-2.m4s b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..b0ff51f74a --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-2.m4s diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key2-init.mp4 b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..cfa099c043 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-init.mp4 diff --git a/dom/media/test/bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_624kbps.mp4 b/dom/media/test/bipbop_480_624kbps.mp4 Binary files differnew file mode 100644 index 0000000000..27928b85f4 --- /dev/null +++ b/dom/media/test/bipbop_480_624kbps.mp4 diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-1.m4s b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..e2bd754c7e --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-1.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-2.m4s b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..347835feee --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-2.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-3.m4s b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-3.m4s Binary files differnew file mode 100644 index 0000000000..64b0da69a0 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-3.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-4.m4s b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-4.m4s Binary files differnew file mode 100644 index 0000000000..864f4248af --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-4.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-init.mp4 b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..c9106aad99 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-init.mp4 diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-1.m4s b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..a8896e069a --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-1.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-2.m4s b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..0f0a35ce79 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-2.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-3.m4s b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-3.m4s Binary files differnew file mode 100644 index 0000000000..fece52ff42 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-3.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-4.m4s b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-4.m4s Binary files differnew file mode 100644 index 0000000000..70e61e3d5f --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-4.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-init.mp4 b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..888b20ab63 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-init.mp4 diff --git a/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key1-1.m4s b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..796ad13670 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-1.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key1-2.m4s b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..d02be53198 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-2.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key1-init.mp4 b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..6e0c60f986 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-init.mp4 diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key2-1.m4s b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..06778e6f2b --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-1.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key2-2.m4s b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..4c1c603e8d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-2.m4s diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key2-init.mp4 b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..f4a98eca97 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-init.mp4 diff --git a/dom/media/test/bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480_959kbps.mp4 b/dom/media/test/bipbop_480_959kbps.mp4 Binary files differnew file mode 100644 index 0000000000..4a9f2ee823 --- /dev/null +++ b/dom/media/test/bipbop_480_959kbps.mp4 diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..e2bd754c7e --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..347835feee --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s Binary files differnew file mode 100644 index 0000000000..64b0da69a0 --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s Binary files differnew file mode 100644 index 0000000000..864f4248af --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4 b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..416bc7a7ca --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4 diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..a8896e069a --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..0f0a35ce79 --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s Binary files differnew file mode 100644 index 0000000000..fece52ff42 --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s Binary files differnew file mode 100644 index 0000000000..70e61e3d5f --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4 b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..73d542cfe0 --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4 diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-1.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..796ad13670 --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-1.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-2.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..80824e9ffc --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-2.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-init.mp4 b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..5db21d091b --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-init.mp4 diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-1.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..06778e6f2b --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-1.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-2.m4s b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..38a081187a --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-2.m4s diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-init.mp4 b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..bc8bddf505 --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-init.mp4 diff --git a/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_1001kbps.mp4 b/dom/media/test/bipbop_480wp_1001kbps.mp4 Binary files differnew file mode 100644 index 0000000000..600376cf83 --- /dev/null +++ b/dom/media/test/bipbop_480wp_1001kbps.mp4 diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-1.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..e2bd754c7e --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-1.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-2.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..347835feee --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-2.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-3.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-3.m4s Binary files differnew file mode 100644 index 0000000000..64b0da69a0 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-3.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-4.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-4.m4s Binary files differnew file mode 100644 index 0000000000..864f4248af --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-4.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-init.mp4 b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..416bc7a7ca --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-init.mp4 diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-1.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..a8896e069a --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-1.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-2.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..0f0a35ce79 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-2.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-3.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-3.m4s Binary files differnew file mode 100644 index 0000000000..fece52ff42 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-3.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-4.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-4.m4s Binary files differnew file mode 100644 index 0000000000..70e61e3d5f --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-4.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-init.mp4 b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..73d542cfe0 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-init.mp4 diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-1.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-1.m4s Binary files differnew file mode 100644 index 0000000000..805f4bbf3f --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-1.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-2.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-2.m4s Binary files differnew file mode 100644 index 0000000000..0a40d1cb73 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-2.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-init.mp4 b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-init.mp4 Binary files differnew file mode 100644 index 0000000000..5db21d091b --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-init.mp4 diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-1.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-1.m4s Binary files differnew file mode 100644 index 0000000000..c5127beec9 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-1.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-2.m4s b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-2.m4s Binary files differnew file mode 100644 index 0000000000..3f344022a4 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-2.m4s diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-init.mp4 b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-init.mp4 Binary files differnew file mode 100644 index 0000000000..bc8bddf505 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-init.mp4 diff --git a/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bipbop_480wp_663kbps.mp4 b/dom/media/test/bipbop_480wp_663kbps.mp4 Binary files differnew file mode 100644 index 0000000000..3cc1da69d2 --- /dev/null +++ b/dom/media/test/bipbop_480wp_663kbps.mp4 diff --git a/dom/media/test/bipbop_audio_aac_22.05k.mp4 b/dom/media/test/bipbop_audio_aac_22.05k.mp4 Binary files differnew file mode 100644 index 0000000000..e89ba40a10 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_22.05k.mp4 diff --git a/dom/media/test/bipbop_audio_aac_22.05k.mp4^headers^ b/dom/media/test/bipbop_audio_aac_22.05k.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_22.05k.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_audio_aac_44.1k.mp4 b/dom/media/test/bipbop_audio_aac_44.1k.mp4 Binary files differnew file mode 100644 index 0000000000..9a13333c12 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_44.1k.mp4 diff --git a/dom/media/test/bipbop_audio_aac_44.1k.mp4^headers^ b/dom/media/test/bipbop_audio_aac_44.1k.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_44.1k.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_audio_aac_48k.mp4 b/dom/media/test/bipbop_audio_aac_48k.mp4 Binary files differnew file mode 100644 index 0000000000..0224350449 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_48k.mp4 diff --git a/dom/media/test/bipbop_audio_aac_48k.mp4^headers^ b/dom/media/test/bipbop_audio_aac_48k.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_48k.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_audio_aac_88.2k.mp4 b/dom/media/test/bipbop_audio_aac_88.2k.mp4 Binary files differnew file mode 100644 index 0000000000..a653be973f --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_88.2k.mp4 diff --git a/dom/media/test/bipbop_audio_aac_88.2k.mp4^headers^ b/dom/media/test/bipbop_audio_aac_88.2k.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_88.2k.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_audio_aac_8k.mp4 b/dom/media/test/bipbop_audio_aac_8k.mp4 Binary files differnew file mode 100644 index 0000000000..fb704090d6 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_8k.mp4 diff --git a/dom/media/test/bipbop_audio_aac_8k.mp4^headers^ b/dom/media/test/bipbop_audio_aac_8k.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_8k.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_audio_aac_96k.mp4 b/dom/media/test/bipbop_audio_aac_96k.mp4 Binary files differnew file mode 100644 index 0000000000..30579f59a4 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_96k.mp4 diff --git a/dom/media/test/bipbop_audio_aac_96k.mp4^headers^ b/dom/media/test/bipbop_audio_aac_96k.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_audio_aac_96k.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_10_0_audio_1.m4s b/dom/media/test/bipbop_cbcs_10_0_audio_1.m4s Binary files differnew file mode 100644 index 0000000000..98ff850161 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_10_0_audio_1.m4s diff --git a/dom/media/test/bipbop_cbcs_10_0_audio_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_10_0_audio_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_10_0_audio_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_10_0_audio_init.mp4 b/dom/media/test/bipbop_cbcs_10_0_audio_init.mp4 Binary files differnew file mode 100644 index 0000000000..ef462e0d66 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_10_0_audio_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_10_0_audio_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_10_0_audio_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_10_0_audio_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_10_0_video_1.m4s b/dom/media/test/bipbop_cbcs_10_0_video_1.m4s Binary files differnew file mode 100644 index 0000000000..73a90b9a5b --- /dev/null +++ b/dom/media/test/bipbop_cbcs_10_0_video_1.m4s diff --git a/dom/media/test/bipbop_cbcs_10_0_video_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_10_0_video_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_10_0_video_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_10_0_video_init.mp4 b/dom/media/test/bipbop_cbcs_10_0_video_init.mp4 Binary files differnew file mode 100644 index 0000000000..266e846e9b --- /dev/null +++ b/dom/media/test/bipbop_cbcs_10_0_video_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_10_0_video_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_10_0_video_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_10_0_video_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_1_9_audio_1.m4s b/dom/media/test/bipbop_cbcs_1_9_audio_1.m4s Binary files differnew file mode 100644 index 0000000000..98ff850161 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_1_9_audio_1.m4s diff --git a/dom/media/test/bipbop_cbcs_1_9_audio_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_1_9_audio_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_1_9_audio_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_1_9_audio_init.mp4 b/dom/media/test/bipbop_cbcs_1_9_audio_init.mp4 Binary files differnew file mode 100644 index 0000000000..8f5521eaa3 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_1_9_audio_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_1_9_audio_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_1_9_audio_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_1_9_audio_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_1_9_video_1.m4s b/dom/media/test/bipbop_cbcs_1_9_video_1.m4s Binary files differnew file mode 100644 index 0000000000..7606c23199 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_1_9_video_1.m4s diff --git a/dom/media/test/bipbop_cbcs_1_9_video_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_1_9_video_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_1_9_video_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_1_9_video_init.mp4 b/dom/media/test/bipbop_cbcs_1_9_video_init.mp4 Binary files differnew file mode 100644 index 0000000000..f9f20f9aec --- /dev/null +++ b/dom/media/test/bipbop_cbcs_1_9_video_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_1_9_video_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_1_9_video_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_1_9_video_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_5_5_audio_1.m4s b/dom/media/test/bipbop_cbcs_5_5_audio_1.m4s Binary files differnew file mode 100644 index 0000000000..98ff850161 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_5_5_audio_1.m4s diff --git a/dom/media/test/bipbop_cbcs_5_5_audio_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_5_5_audio_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_5_5_audio_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_5_5_audio_init.mp4 b/dom/media/test/bipbop_cbcs_5_5_audio_init.mp4 Binary files differnew file mode 100644 index 0000000000..3118a175f1 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_5_5_audio_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_5_5_audio_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_5_5_audio_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_5_5_audio_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_5_5_video_1.m4s b/dom/media/test/bipbop_cbcs_5_5_video_1.m4s Binary files differnew file mode 100644 index 0000000000..8ed5b11aa0 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_5_5_video_1.m4s diff --git a/dom/media/test/bipbop_cbcs_5_5_video_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_5_5_video_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_5_5_video_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_5_5_video_init.mp4 b/dom/media/test/bipbop_cbcs_5_5_video_init.mp4 Binary files differnew file mode 100644 index 0000000000..be9731c4c6 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_5_5_video_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_5_5_video_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_5_5_video_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_5_5_video_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_7_7_audio_1.m4s b/dom/media/test/bipbop_cbcs_7_7_audio_1.m4s Binary files differnew file mode 100644 index 0000000000..98ff850161 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_7_7_audio_1.m4s diff --git a/dom/media/test/bipbop_cbcs_7_7_audio_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_7_7_audio_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_7_7_audio_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_7_7_audio_init.mp4 b/dom/media/test/bipbop_cbcs_7_7_audio_init.mp4 Binary files differnew file mode 100644 index 0000000000..3017ff231e --- /dev/null +++ b/dom/media/test/bipbop_cbcs_7_7_audio_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_7_7_audio_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_7_7_audio_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_7_7_audio_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_7_7_video_1.m4s b/dom/media/test/bipbop_cbcs_7_7_video_1.m4s Binary files differnew file mode 100644 index 0000000000..c3d41c16c6 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_7_7_video_1.m4s diff --git a/dom/media/test/bipbop_cbcs_7_7_video_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_7_7_video_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_7_7_video_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_7_7_video_init.mp4 b/dom/media/test/bipbop_cbcs_7_7_video_init.mp4 Binary files differnew file mode 100644 index 0000000000..994e319e57 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_7_7_video_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_7_7_video_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_7_7_video_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_7_7_video_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_9_8_audio_1.m4s b/dom/media/test/bipbop_cbcs_9_8_audio_1.m4s Binary files differnew file mode 100644 index 0000000000..98ff850161 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_9_8_audio_1.m4s diff --git a/dom/media/test/bipbop_cbcs_9_8_audio_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_9_8_audio_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_9_8_audio_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_9_8_audio_init.mp4 b/dom/media/test/bipbop_cbcs_9_8_audio_init.mp4 Binary files differnew file mode 100644 index 0000000000..0f436af510 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_9_8_audio_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_9_8_audio_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_9_8_audio_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_9_8_audio_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_9_8_video_1.m4s b/dom/media/test/bipbop_cbcs_9_8_video_1.m4s Binary files differnew file mode 100644 index 0000000000..1bb3dd493c --- /dev/null +++ b/dom/media/test/bipbop_cbcs_9_8_video_1.m4s diff --git a/dom/media/test/bipbop_cbcs_9_8_video_1.m4s^headers^ b/dom/media/test/bipbop_cbcs_9_8_video_1.m4s^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_9_8_video_1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_cbcs_9_8_video_init.mp4 b/dom/media/test/bipbop_cbcs_9_8_video_init.mp4 Binary files differnew file mode 100644 index 0000000000..df5f9a13b8 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_9_8_video_init.mp4 diff --git a/dom/media/test/bipbop_cbcs_9_8_video_init.mp4^headers^ b/dom/media/test/bipbop_cbcs_9_8_video_init.mp4^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_cbcs_9_8_video_init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm b/dom/media/test/bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm Binary files differnew file mode 100644 index 0000000000..7d0935aead --- /dev/null +++ b/dom/media/test/bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm diff --git a/dom/media/test/bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^ b/dom/media/test/bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm b/dom/media/test/bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm Binary files differnew file mode 100644 index 0000000000..39d20e1e87 --- /dev/null +++ b/dom/media/test/bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm diff --git a/dom/media/test/bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^ b/dom/media/test/bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm b/dom/media/test/bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm Binary files differnew file mode 100644 index 0000000000..4d6a68fbc6 --- /dev/null +++ b/dom/media/test/bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm diff --git a/dom/media/test/bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^ b/dom/media/test/bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/bipbop_short_vp8.webm b/dom/media/test/bipbop_short_vp8.webm Binary files differnew file mode 100644 index 0000000000..7c47b3d7e8 --- /dev/null +++ b/dom/media/test/bipbop_short_vp8.webm diff --git a/dom/media/test/bipbop_short_vp8.webm^headers^ b/dom/media/test/bipbop_short_vp8.webm^headers^ new file mode 100644 index 0000000000..12a01c4a22 --- /dev/null +++ b/dom/media/test/bipbop_short_vp8.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store
diff --git a/dom/media/test/black100x100-aspect3to2.ogv b/dom/media/test/black100x100-aspect3to2.ogv Binary files differnew file mode 100644 index 0000000000..81fe51ffb3 --- /dev/null +++ b/dom/media/test/black100x100-aspect3to2.ogv diff --git a/dom/media/test/black100x100-aspect3to2.ogv^headers^ b/dom/media/test/black100x100-aspect3to2.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/black100x100-aspect3to2.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bogus.duh b/dom/media/test/bogus.duh new file mode 100644 index 0000000000..528ae275d0 --- /dev/null +++ b/dom/media/test/bogus.duh @@ -0,0 +1,45 @@ +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus diff --git a/dom/media/test/bogus.ogv b/dom/media/test/bogus.ogv new file mode 100644 index 0000000000..528ae275d0 --- /dev/null +++ b/dom/media/test/bogus.ogv @@ -0,0 +1,45 @@ +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus diff --git a/dom/media/test/bogus.ogv^headers^ b/dom/media/test/bogus.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bogus.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bogus.wav b/dom/media/test/bogus.wav new file mode 100644 index 0000000000..528ae275d0 --- /dev/null +++ b/dom/media/test/bogus.wav @@ -0,0 +1,45 @@ +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus +bogus bogus bogus diff --git a/dom/media/test/bogus.wav^headers^ b/dom/media/test/bogus.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bogus.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/browser/browser.toml b/dom/media/test/browser/browser.toml new file mode 100644 index 0000000000..cf25369576 --- /dev/null +++ b/dom/media/test/browser/browser.toml @@ -0,0 +1,26 @@ +[DEFAULT] +subsuite = "media-bc" +prefs = ["gfx.font_loader.delay=0"] +support-files = [ + "file_empty_page.html", + "file_media.html", + "../av1.mp4", + "../bipbop_short_vp8.webm", + "../bunny_hd_5s.mp4", + "../eme_standalone.js", + "../gizmo.mp4", + "../gizmo.webm", + "../sintel-short-clearkey-subsample-encrypted-video.webm", + "../small-shot.flac", + "../small-shot.m4a", + "../small-shot.mp3", + "../small-shot.ogg", + "../TestPatternHDR.mp4", +] + +["browser_encrypted_play_time_telemetry.js"] +skip-if = ["apple_silicon"] # Disabled due to bleedover with other tests when run in regular suites; passes in "failures" jobs + +["browser_tab_visibility_and_play_time.js"] + +["browser_telemetry_video_hardware_decoding_support.js"] diff --git a/dom/media/test/browser/browser_encrypted_play_time_telemetry.js b/dom/media/test/browser/browser_encrypted_play_time_telemetry.js new file mode 100644 index 0000000000..ff4f2753ec --- /dev/null +++ b/dom/media/test/browser/browser_encrypted_play_time_telemetry.js @@ -0,0 +1,269 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This test verifies that telemetry gathered around encrypted media playtime +// is gathered as expected. + +"use strict"; + +/* import-globals-from ../eme_standalone.js */ + +// Clears any existing telemetry data that has been accumulated. Returns a +// promise the will be resolved once the telemetry store is clear. +async function clearTelemetry() { + // There's an arbitrary interval of 2 seconds in which the content + // processes sync their event data with the parent process, we wait + // this out to ensure that we clear everything that is left over from + // previous tests and don't receive random events in the middle of our tests. + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + await new Promise(resolve => setTimeout(resolve, 2000)); + + Services.telemetry.clearEvents(); + return TestUtils.waitForCondition(() => { + let events = Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_ALL_CHANNELS, + true + ).content; + return !events || !events.length; + }); +} + +// Opens a tab containing a blank page, returns a promise that will resolve +// to that tab. +async function openTab() { + const emptyPageUri = + "https://example.com/browser/dom/media/test/browser/file_empty_page.html"; + return BrowserTestUtils.openNewForegroundTab(window.gBrowser, emptyPageUri); +} + +// Creates and configures a video element for EME playback in `tab`. Does not +// start playback for the element. Returns a promise that will resolve once +// the element is setup and ready for playback. +async function loadEmeVideo(tab) { + const emeHelperUri = + gTestPath.substr(0, gTestPath.lastIndexOf("/")) + "/eme_standalone.js"; + return SpecialPowers.spawn( + tab.linkedBrowser, + [emeHelperUri], + async _emeHelperUri => { + // Begin helper functions. + async function once(target, name) { + return new Promise(r => + target.addEventListener(name, r, { once: true }) + ); + } + + // Helper to clone data into content so the EME helper can use the data. + function cloneIntoContent(data) { + return Cu.cloneInto(data, content.wrappedJSObject); + } + // End helper functions. + + // Load the EME helper into content. + Services.scriptloader.loadSubScript(_emeHelperUri, content); + // Setup EME with the helper. + let video = content.document.createElement("video"); + video.id = "media"; + content.document.body.appendChild(video); + let emeHelper = new content.wrappedJSObject.EmeHelper(); + emeHelper.SetKeySystem( + content.wrappedJSObject.EmeHelper.GetClearkeyKeySystemString() + ); + emeHelper.SetInitDataTypes(cloneIntoContent(["webm"])); + emeHelper.SetVideoCapabilities( + cloneIntoContent([{ contentType: 'video/webm; codecs="vp9"' }]) + ); + emeHelper.AddKeyIdAndKey( + "2cdb0ed6119853e7850671c3e9906c3c", + "808b9adac384de1e4f56140f4ad76194" + ); + emeHelper.onerror = error => { + is(false, `Got unexpected error from EME helper: ${error}`); + }; + await emeHelper.ConfigureEme(video); + // Done setting up EME. + + // Setup MSE. + const ms = new content.wrappedJSObject.MediaSource(); + video.src = content.wrappedJSObject.URL.createObjectURL(ms); + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + const videoFile = "sintel-short-clearkey-subsample-encrypted-video.webm"; + let fetchResponse = await content.fetch(videoFile); + sb.appendBuffer(await fetchResponse.arrayBuffer()); + await once(sb, "updateend"); + ms.endOfStream(); + await once(ms, "sourceended"); + } + ); +} + +// Plays the media in `tab` until the 'ended' event is fire. Returns a promise +// that resolves once that state has been reached. +async function playMediaThrough(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async () => { + let video = content.document.getElementById("media"); + await Promise.all([new Promise(r => (video.onended = r)), video.play()]); + }); +} + +// Plays the media in `tab` until the 'timeupdate' event is fire. Returns a +// promise that resolves once that state has been reached. +async function playMediaToTimeUpdate(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async () => { + let video = content.document.getElementById("media"); + await Promise.all([ + new Promise(r => (video.ontimeupdate = r)), + video.play(), + ]); + }); +} + +// Aborts existing loads and replaces the media on the media element with an +// unencrypted file. +async function replaceMediaWithUnencrypted(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async () => { + let video = content.document.getElementById("media"); + video.src = "gizmo.mp4"; + video.load(); + }); +} + +// Clears/nulls the media keys on the media in `tab`. +async function clearMediaKeys(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async () => { + let video = content.document.getElementById("media"); + await video.setMediaKeys(null); + }); +} + +// Wait for telemetry information to be received from the content process +// then get the relevant histograms for the tests and return the sums of +// those histograms. If a histogram does not exist this will return a 0 +// sum. Returns a promise the resolves to an object with sums for +// - VIDEO_PLAY_TIME_MS +// - VIDEO_ENCRYPTED_PLAY_TIME_MS +// - VIDEO_CLEARKEY_PLAY_TIME_MS +// This function clears the histograms as it gets them. +async function getTelemetrySums() { + // The telemetry was gathered in the content process, so we have to wait + // until is arrived in the parent to check it. At time of writing there's + // not a more elegant way of doing this than polling. + return TestUtils.waitForCondition(() => { + let histograms = Services.telemetry.getSnapshotForHistograms( + "main", + true + ).content; + // All the histogram data should come at the same time, so we just check + // for playtime here as we always expect it in these tests, but we'll + // grab other values if present. + if (histograms.VIDEO_PLAY_TIME_MS) { + // We only expect to have one value for each histogram, so returning the + // sums is a short hand for returning that one value. + return { + VIDEO_PLAY_TIME_MS: histograms.VIDEO_PLAY_TIME_MS.sum, + VIDEO_ENCRYPTED_PLAY_TIME_MS: histograms.VIDEO_ENCRYPTED_PLAY_TIME_MS + ? histograms.VIDEO_ENCRYPTED_PLAY_TIME_MS.sum + : 0, + VIDEO_CLEARKEY_PLAY_TIME_MS: histograms.VIDEO_CLEARKEY_PLAY_TIME_MS + ? histograms.VIDEO_CLEARKEY_PLAY_TIME_MS.sum + : 0, + }; + } + return null; + }, "recorded telemetry from playing media"); +} + +// Clear telemetry before other tests. Internally the tests clear the telemetry +// when they check it, so we shouldn't need to do this between tests. +add_task(clearTelemetry); + +add_task(async function testEncryptedMediaPlayback() { + let testTab = await openTab(); + + await loadEmeVideo(testTab); + await playMediaThrough(testTab); + + BrowserTestUtils.removeTab(testTab); + + let telemetrySums = await getTelemetrySums(); + + ok(telemetrySums, "Should get play time telemetry"); + is( + telemetrySums.VIDEO_PLAY_TIME_MS, + telemetrySums.VIDEO_ENCRYPTED_PLAY_TIME_MS, + "Play time should be the same as encrypted play time" + ); + is( + telemetrySums.VIDEO_PLAY_TIME_MS, + telemetrySums.VIDEO_CLEARKEY_PLAY_TIME_MS, + "Play time should be the same as clearkey play time" + ); + Assert.greater( + telemetrySums.VIDEO_PLAY_TIME_MS, + 0, + "Should have a play time greater than zero" + ); +}); + +add_task(async function testChangingFromEncryptedToUnencrypted() { + let testTab = await openTab(); + + await loadEmeVideo(testTab); + await replaceMediaWithUnencrypted(testTab); + await playMediaToTimeUpdate(testTab); + + BrowserTestUtils.removeTab(testTab); + + let telemetrySums = await getTelemetrySums(); + + ok(telemetrySums, "Should get play time telemetry"); + is( + telemetrySums.VIDEO_ENCRYPTED_PLAY_TIME_MS, + 0, + "Encrypted play time should be 0" + ); + is( + telemetrySums.VIDEO_PLAY_TIME_MS, + telemetrySums.VIDEO_CLEARKEY_PLAY_TIME_MS, + "Play time should be the same as clearkey play time because the media element still has a media keys attached" + ); + Assert.greater( + telemetrySums.VIDEO_PLAY_TIME_MS, + 0, + "Should have a play time greater than zero" + ); +}); + +add_task( + async function testChangingFromEncryptedToUnencryptedAndClearingMediaKeys() { + let testTab = await openTab(); + + await loadEmeVideo(testTab); + await replaceMediaWithUnencrypted(testTab); + await clearMediaKeys(testTab); + await playMediaToTimeUpdate(testTab); + + BrowserTestUtils.removeTab(testTab); + + let telemetrySums = await getTelemetrySums(); + + ok(telemetrySums, "Should get play time telemetry"); + is( + telemetrySums.VIDEO_ENCRYPTED_PLAY_TIME_MS, + 0, + "Encrypted play time should be 0" + ); + is( + telemetrySums.VIDEO_CLEARKEY_PLAY_TIME_MS, + 0, + "Clearkey play time should be 0" + ); + Assert.greater( + telemetrySums.VIDEO_PLAY_TIME_MS, + 0, + "Should have a play time greater than zero" + ); + } +); diff --git a/dom/media/test/browser/browser_partial.js b/dom/media/test/browser/browser_partial.js new file mode 100644 index 0000000000..572287b392 --- /dev/null +++ b/dom/media/test/browser/browser_partial.js @@ -0,0 +1,56 @@ +async function test() { + waitForExplicitFinish(); + const target = + "https://example.com/browser/dom/media/test/browser/file_empty_page.html"; + + info("Loading download page..."); + + let tab = BrowserTestUtils.addTab(gBrowser, target); + + registerCleanupFunction(function () { + gBrowser.removeTab(tab); + window.restore(); + }); + + gBrowser.selectedTab = tab; + BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, target).then( + async () => { + info("Page loaded."); + let allDownloads = await Downloads.getList(Downloads.ALL); + let started = new Promise(resolve => { + // With no download modal, the download will begin on its own, so we need + // to wait to be notified by the downloads list when that happens. + let downloadView = { + onDownloadAdded(download) { + ok(true, "Download was started."); + download.cancel(); + allDownloads.removeView(this); + allDownloads.removeFinished(); + resolve(); + }, + }; + allDownloads.addView(downloadView); + }); + + let revoked = SpecialPowers.spawn( + tab.linkedBrowser, + [], + () => + new Promise(resolve => { + let link = content.document.createElement("a"); + link.href = "force_octet_stream.mp4"; + content.document.body.appendChild(link); + info("Clicking HTMLAnchorElement..."); + link.click(); + info("Clicked HTMLAnchorElement."); + resolve(); + }) + ); + + info("Waiting for async activities..."); + await Promise.all([revoked, started]); + ok(true, "Exiting test."); + finish(); + } + ); +} diff --git a/dom/media/test/browser/browser_tab_visibility_and_play_time.js b/dom/media/test/browser/browser_tab_visibility_and_play_time.js new file mode 100644 index 0000000000..4d33826091 --- /dev/null +++ b/dom/media/test/browser/browser_tab_visibility_and_play_time.js @@ -0,0 +1,218 @@ +/** + * This test is used to ensure that invisible play time would be accumulated + * when tab is in background. It also checks the HDR video accumulation time. + * However, this test won't directly check the reported telemetry result, + * because we can't check the snapshot histogram in the content process. + * The actual probe checking happens in `test_accumulated_play_time.html`. + */ +"use strict"; + +const PAGE_URL = + "https://example.com/browser/dom/media/test/browser/file_media.html"; + +// This HDR tests will only pass on platforms that accurately report color +// depth in their VideoInfo structures. Presently, that is only true for +// macOS. + +const reportsColorDepthFromVideoData = AppConstants.platform == "macosx"; + +add_task(async function testChangingTabVisibilityAffectsInvisiblePlayTime() { + const originalTab = gBrowser.selectedTab; + const mediaTab = await openMediaTab(PAGE_URL); + + info(`measuring play time when tab is in foreground`); + await startMedia({ + mediaTab, + shouldAccumulateTime: true, + shouldAccumulateInvisibleTime: false, + shouldAccumulateHDRTime: reportsColorDepthFromVideoData, + }); + await pauseMedia(mediaTab); + + info(`measuring play time when tab is in background`); + await BrowserTestUtils.switchTab(window.gBrowser, originalTab); + await startMedia({ + mediaTab, + shouldAccumulateTime: true, + shouldAccumulateInvisibleTime: true, + shouldAccumulateHDRTime: reportsColorDepthFromVideoData, + }); + await pauseMedia(mediaTab); + + BrowserTestUtils.removeTab(mediaTab); +}); + +/** + * Following are helper functions. + */ +async function openMediaTab(url) { + info(`open tab for media playback`); + const tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser, url); + info(`add content helper functions and variables`); + await SpecialPowers.spawn(tab.linkedBrowser, [], _ => { + content.waitForOnTimeUpdate = element => { + return new Promise(resolve => { + element.addEventListener( + "timeupdate", + e => { + resolve(); + }, + { once: true } + ); + }); + }; + + content.sleep = ms => { + return new Promise(resolve => content.setTimeout(resolve, ms)); + }; + + content.assertAttributeDefined = (videoChrome, checkType) => { + Assert.notEqual(videoChrome[checkType], undefined, `${checkType} exists`); + }; + content.assertValueEqualTo = (videoChrome, checkType, expectedValue) => { + content.assertAttributeDefined(videoChrome, checkType); + is( + videoChrome[checkType], + expectedValue, + `${checkType} equals to ${expectedValue}` + ); + }; + content.assertValueConstantlyIncreases = async (videoChrome, checkType) => { + content.assertAttributeDefined(videoChrome, checkType); + const valueSnapshot = videoChrome[checkType]; + await content.waitForOnTimeUpdate(videoChrome); + Assert.greater( + videoChrome[checkType], + valueSnapshot, + `${checkType} keeps increasing` + ); + }; + content.assertValueKeptUnchanged = async (videoChrome, checkType) => { + content.assertAttributeDefined(videoChrome, checkType); + const valueSnapshot = videoChrome[checkType]; + await content.sleep(1000); + Assert.equal( + videoChrome[checkType], + valueSnapshot, + `${checkType} keeps unchanged` + ); + }; + }); + return tab; +} + +function startMedia({ + mediaTab, + shouldAccumulateTime, + shouldAccumulateInvisibleTime, + shouldAccumulateHDRTime, +}) { + return SpecialPowers.spawn( + mediaTab.linkedBrowser, + [ + shouldAccumulateTime, + shouldAccumulateInvisibleTime, + shouldAccumulateHDRTime, + ], + async (accumulateTime, accumulateInvisibleTime, accumulateHDRTime) => { + const video = content.document.getElementById("video"); + ok( + await video.play().then( + () => true, + () => false + ), + "video started playing" + ); + const videoChrome = SpecialPowers.wrap(video); + if (accumulateTime) { + await content.assertValueConstantlyIncreases( + videoChrome, + "totalVideoPlayTime" + ); + } else { + await content.assertValueKeptUnchanged( + videoChrome, + "totalVideoPlayTime" + ); + } + if (accumulateInvisibleTime) { + await content.assertValueConstantlyIncreases( + videoChrome, + "invisiblePlayTime" + ); + } else { + await content.assertValueKeptUnchanged( + videoChrome, + "invisiblePlayTime" + ); + } + + const videoHDR = content.document.getElementById("videoHDR"); + + // HDR test video might not decode on all platforms, so catch + // the play() command and exit early in such a case. Failure to + // decode might manifest as a timeout, so add a rejection race + // to catch that. + let didDecode = true; + const playPromise = videoHDR.play().then( + () => true, + () => false + ); + /* eslint-disable mozilla/no-arbitrary-setTimeout */ + const tooSlowPromise = new Promise(resolve => + setTimeout(() => { + info("videoHDR timed out."); + didDecode = false; + resolve(false); + }, 1000) + ); + /* eslint-enable mozilla/no-arbitrary-setTimeout */ + + let didPlay = await Promise.race(playPromise, tooSlowPromise).catch( + err => { + info("videoHDR failed to decode with error: " + err.message); + didDecode = false; + return false; + } + ); + + if (!didDecode) { + return; + } + + ok(didPlay, "videoHDR started playing"); + const videoHDRChrome = SpecialPowers.wrap(videoHDR); + if (accumulateHDRTime) { + await content.assertValueConstantlyIncreases( + videoHDRChrome, + "totalVideoHDRPlayTime" + ); + } else { + await content.assertValueKeptUnchanged( + videoHDRChrome, + "totalVideoHDRPlayTime" + ); + } + } + ); +} + +function pauseMedia(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async _ => { + const video = content.document.getElementById("video"); + video.pause(); + ok(true, "video paused"); + const videoChrome = SpecialPowers.wrap(video); + await content.assertValueKeptUnchanged(videoChrome, "totalVideoPlayTime"); + await content.assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + + const videoHDR = content.document.getElementById("videoHDR"); + videoHDR.pause(); + ok(true, "videoHDR paused"); + const videoHDRChrome = SpecialPowers.wrap(videoHDR); + await content.assertValueKeptUnchanged( + videoHDRChrome, + "totalVideoHDRPlayTime" + ); + }); +} diff --git a/dom/media/test/browser/browser_telemetry_video_hardware_decoding_support.js b/dom/media/test/browser/browser_telemetry_video_hardware_decoding_support.js new file mode 100644 index 0000000000..3b1b41c03f --- /dev/null +++ b/dom/media/test/browser/browser_telemetry_video_hardware_decoding_support.js @@ -0,0 +1,106 @@ +/** + * This test is used to ensure that the scalar which indicates whether hardware + * decoding is supported for a specific video codec type can be recorded + * correctly. + */ +"use strict"; + +add_task(async function setupTestingPref() { + await SpecialPowers.pushPrefEnv({ + set: [ + // In order to test av1 in the chrome process, see https://bit.ly/3oF0oan + ["media.rdd-process.enabled", false], + ], + }); +}); + +const ALL_SCALAR = "media.video_hardware_decoding_support"; +const HD_SCALAR = "media.video_hd_hardware_decoding_support"; + +add_task(async function testVideoCodecs() { + // There are still other video codecs, but we only care about these popular + // codec types. + const testFiles = [ + { fileName: "gizmo.mp4", type: "video/avc" }, + { fileName: "gizmo.webm", type: "video/vp9" }, + { fileName: "bipbop_short_vp8.webm", type: "video/vp8" }, + { fileName: "av1.mp4", type: "video/av1" }, + { fileName: "bunny_hd_5s.mp4", type: "video/avc", hd: true }, + ]; + + for (const file of testFiles) { + const { fileName, type, hd } = file; + let video = document.createElement("video"); + video.src = GetTestWebBasedURL(fileName); + await video.play(); + let snapshot = Services.telemetry.getSnapshotForKeyedScalars( + "main", + false + ).parent; + ok( + snapshot.hasOwnProperty(ALL_SCALAR), + `Found stored scalar '${ALL_SCALAR}'` + ); + ok( + snapshot[ALL_SCALAR].hasOwnProperty(type), + `Found key '${type}' in '${ALL_SCALAR}'` + ); + if (hd) { + ok( + snapshot.hasOwnProperty(HD_SCALAR), + `HD video '${fileName}' should record a scalar '${HD_SCALAR}'` + ); + ok( + snapshot[HD_SCALAR].hasOwnProperty(type), + `Found key '${type}' in '${HD_SCALAR}'` + ); + } else { + ok( + !snapshot.hasOwnProperty(HD_SCALAR), + `SD video won't store a scalar '${HD_SCALAR}'` + ); + } + video.src = ""; + Services.telemetry.clearScalars(); + } +}); + +add_task(async function testAudioCodecs() { + const testFiles = [ + "small-shot.ogg", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.flac", + ]; + for (const file of testFiles) { + let audio = document.createElement("audio"); + info(GetTestWebBasedURL(file)); + audio.src = GetTestWebBasedURL(file); + await audio.play(); + let snapshot = Services.telemetry.getSnapshotForKeyedScalars( + "main", + false + ).parent; + ok( + !snapshot || + (!snapshot.hasOwnProperty(ALL_SCALAR) && + !snapshot.hasOwnProperty(HD_SCALAR)), + `Did not record scalar for ${file}` + ); + audio.src = ""; + } +}); + +/** + * Return a web-based URL for a given file based on the testing directory. + * @param {String} fileName + * file that caller wants its web-based url + */ +function GetTestWebBasedURL(fileName) { + return ( + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.org" + ) + fileName + ); +} diff --git a/dom/media/test/browser/file_empty_page.html b/dom/media/test/browser/file_empty_page.html new file mode 100644 index 0000000000..cd1b7830be --- /dev/null +++ b/dom/media/test/browser/file_empty_page.html @@ -0,0 +1,8 @@ +<!DOCTYPE html>
+<html>
+<head>
+<title>An empty page</title>
+</head>
+<body>
+</body>
+</html>
diff --git a/dom/media/test/browser/file_media.html b/dom/media/test/browser/file_media.html new file mode 100644 index 0000000000..36dca8d01c --- /dev/null +++ b/dom/media/test/browser/file_media.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> +<title>Non-Autoplay page</title> +</head> +<body> +<video id="video" src="gizmo.mp4" loop></video> +<video id="videoHDR" src="TestPatternHDR.mp4" loop></video> +</body> +</html> diff --git a/dom/media/test/browser/wmfme/browser.toml b/dom/media/test/browser/wmfme/browser.toml new file mode 100644 index 0000000000..422ea29228 --- /dev/null +++ b/dom/media/test/browser/wmfme/browser.toml @@ -0,0 +1,13 @@ +[DEFAULT] +subsuite = "media-bc" +tags = "media-engine-compatible" +run-if = ["wmfme"] +support-files = [ + "head.js", + "file_video.html", + "../../gizmo.mp4", +] + +["browser_wmfme_crash.js"] + +["browser_wmfme_max_crashes.js"] diff --git a/dom/media/test/browser/wmfme/browser_wmfme_crash.js b/dom/media/test/browser/wmfme/browser_wmfme_crash.js new file mode 100644 index 0000000000..57064cfe8d --- /dev/null +++ b/dom/media/test/browser/wmfme/browser_wmfme_crash.js @@ -0,0 +1,52 @@ +"use strict"; + +/** + * This test aims to ensure that the media engine playback will recover from a + * crash and keep playing without any problem. + */ +add_task(async function setupTestingPref() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.wmf.media-engine.enabled", 1], + ["media.wmf.media-engine.channel-decoder.enabled", true], + ], + }); +}); + +const VIDEO_PAGE = GetTestWebBasedURL("file_video.html"); + +add_task(async function testPlaybackRecoveryFromCrash() { + info(`Create a tab and load test page`); + let tab = await BrowserTestUtils.openNewForegroundTab( + window.gBrowser, + "about:blank" + ); + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, VIDEO_PAGE); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + + await playVideo(tab); + + info("Ensure video is running via the media engine framework"); + await assertRunningProcessAndDecoderName(tab, { + expectedProcess: "Utility MF Media Engine CDM", + expectedDecoder: "media engine video stream", + }); + + const pidBeforeCrash = await getMFCDMProcessId(); + await crashUtilityProcess(pidBeforeCrash); + + info("The CDM process should be recreated which makes media keep playing"); + await assertRunningProcessAndDecoderName(tab, { + expectedProcess: "Utility MF Media Engine CDM", + expectedDecoder: "media engine video stream", + }); + + const pidAfterCrash = await getMFCDMProcessId(); + isnot( + pidBeforeCrash, + pidAfterCrash, + `new process ${pidAfterCrash} is not previous crashed one ${pidBeforeCrash}` + ); + + BrowserTestUtils.removeTab(tab); +}); diff --git a/dom/media/test/browser/wmfme/browser_wmfme_max_crashes.js b/dom/media/test/browser/wmfme/browser_wmfme_max_crashes.js new file mode 100644 index 0000000000..8cc8dc08b8 --- /dev/null +++ b/dom/media/test/browser/wmfme/browser_wmfme_max_crashes.js @@ -0,0 +1,69 @@ +"use strict"; + +/** + * This test aims to ensure that the MFCDM process won't be recovered once the + * amount of crashes has exceeded the amount of value which we tolerate. + */ +add_task(async function setupTestingPref() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.wmf.media-engine.enabled", 1], + ["media.wmf.media-engine.channel-decoder.enabled", true], + ], + }); +}); + +const VIDEO_PAGE = GetTestWebBasedURL("file_video.html"); + +add_task(async function testPlaybackRecoveryFromCrash() { + const maxCrashes = Services.prefs.getIntPref( + "media.wmf.media-engine.max-crashes" + ); + info(`The amount of tolerable crashes=${maxCrashes}`); + + info(`Create a tab and load test page`); + let tab = await BrowserTestUtils.openNewForegroundTab( + window.gBrowser, + "about:blank" + ); + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, VIDEO_PAGE); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + + await playVideo(tab); + + info("Ensure video is running via the media engine framework"); + await assertRunningProcessAndDecoderName(tab, { + expectedProcess: "Utility MF Media Engine CDM", + expectedDecoder: "media engine video stream", + }); + + let pidBeforeCrash, pidAfterCrash; + for (let idx = 0; idx < maxCrashes; idx++) { + pidBeforeCrash = await getMFCDMProcessId(); + await crashUtilityProcess(pidBeforeCrash); + + info("The CDM process should be recreated which makes media keep playing"); + await assertRunningProcessAndDecoderName(tab, { + expectedProcess: "Utility MF Media Engine CDM", + expectedDecoder: "media engine video stream", + }); + + pidAfterCrash = await getMFCDMProcessId(); + isnot( + pidBeforeCrash, + pidAfterCrash, + `new process ${pidAfterCrash} is not previous crashed one ${pidBeforeCrash}` + ); + } + + info("This crash should result in not spawning MFCDM process again"); + pidBeforeCrash = await getMFCDMProcessId(); + await crashUtilityProcess(pidBeforeCrash); + + await assertNotEqualRunningProcessAndDecoderName(tab, { + givenProcess: "Utility MF Media Engine CDM", + givenDecoder: "media engine video stream", + }); + + BrowserTestUtils.removeTab(tab); +}); diff --git a/dom/media/test/browser/wmfme/file_video.html b/dom/media/test/browser/wmfme/file_video.html new file mode 100644 index 0000000000..3c70268fbb --- /dev/null +++ b/dom/media/test/browser/wmfme/file_video.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<head> +<title>video</title> +</head> +<body> +<video id="v" src="gizmo.mp4" controls loop></video> +</body> +</html> diff --git a/dom/media/test/browser/wmfme/head.js b/dom/media/test/browser/wmfme/head.js new file mode 100644 index 0000000000..1e6f3b18bb --- /dev/null +++ b/dom/media/test/browser/wmfme/head.js @@ -0,0 +1,201 @@ +"use strict"; + +/** + * Return a web-based URL for a given file based on the testing directory. + * @param {String} fileName + * file that caller wants its web-based url + * @param {Boolean} cors [optional] + * if set, then return a url with different origin + */ +function GetTestWebBasedURL(fileName) { + const origin = "https://example.com"; + return ( + getRootDirectory(gTestPath).replace("chrome://mochitests/content", origin) + + fileName + ); +} + +/** + * Return current process Id for the Media Foundation CDM process. + */ +async function getMFCDMProcessId() { + const process = (await ChromeUtils.requestProcInfo()).children.find( + p => + p.type === "utility" && + p.utilityActors.find(a => a.actorName === "mfMediaEngineCDM") + ); + return process.pid; +} + +/** + * Make the utility process with given process id crash. + * @param {int} pid + * the process id for the process which is going to crash + */ +async function crashUtilityProcess(utilityPid) { + info(`Crashing process ${utilityPid}`); + SimpleTest.expectChildProcessCrash(); + + const crashMan = Services.crashmanager; + const utilityProcessGone = TestUtils.topicObserved( + "ipc:utility-shutdown", + (subject, data) => { + info(`ipc:utility-shutdown: data=${data} subject=${subject}`); + return parseInt(data, 10) === utilityPid; + } + ); + + info("Prune any previous crashes"); + const future = new Date(Date.now() + 1000 * 60 * 60 * 24); + await crashMan.pruneOldCrashes(future); + + info("Crash Utility Process"); + const ProcessTools = Cc["@mozilla.org/processtools-service;1"].getService( + Ci.nsIProcessToolsService + ); + + info(`Crash Utility Process ${utilityPid}`); + ProcessTools.crash(utilityPid); + + info(`Waiting for utility process ${utilityPid} to go away.`); + let [subject, data] = await utilityProcessGone; + Assert.strictEqual( + parseInt(data, 10), + utilityPid, + `Should match the crashed PID ${utilityPid} with ${data}` + ); + ok( + subject instanceof Ci.nsIPropertyBag2, + "Subject needs to be a nsIPropertyBag2 to clean up properly" + ); + + const dumpID = subject.getPropertyAsAString("dumpID"); + ok(dumpID, "There should be a dumpID"); + + await crashMan.ensureCrashIsPresent(dumpID); + await crashMan.getCrashes().then(crashes => { + is(crashes.length, 1, "There should be only one record"); + const crash = crashes[0]; + ok( + crash.isOfType( + crashMan.processTypes[Ci.nsIXULRuntime.PROCESS_TYPE_UTILITY], + crashMan.CRASH_TYPE_CRASH + ), + "Record should be a utility process crash" + ); + Assert.strictEqual(crash.id, dumpID, "Record should have an ID"); + }); + + let minidumpDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile); + minidumpDirectory.append("minidumps"); + + let dumpfile = minidumpDirectory.clone(); + dumpfile.append(dumpID + ".dmp"); + if (dumpfile.exists()) { + info(`Removal of ${dumpfile.path}`); + dumpfile.remove(false); + } + + let extrafile = minidumpDirectory.clone(); + extrafile.append(dumpID + ".extra"); + info(`Removal of ${extrafile.path}`); + if (extrafile.exists()) { + extrafile.remove(false); + } +} + +/** + * Make video in the tab play. + * @param {object} tab + * the tab contains at least one video element + */ +async function playVideo(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async _ => { + const video = content.document.querySelector("video"); + ok( + await video.play().then( + () => true, + () => false + ), + "video started playing" + ); + }); +} + +/** + * Check whether the video playback is performed in the right process and right decoder. + * @param {object} tab + * the tab which has a playing video + * @param {string} expectedProcess + * the expected process name + * @param {string} expectedDecoder + * the expected decoder name + */ +async function assertRunningProcessAndDecoderName( + tab, + { expectedProcess, expectedDecoder } = {} +) { + return SpecialPowers.spawn( + tab.linkedBrowser, + [expectedProcess, expectedDecoder], + // eslint-disable-next-line no-shadow + async (expectedProcess, expectedDecoder) => { + const video = content.document.querySelector("video"); + ok(!video.paused, "checking a playing video"); + + const debugInfo = await SpecialPowers.wrap(video).mozRequestDebugInfo(); + const videoDecoderName = debugInfo.decoder.reader.videoDecoderName; + + const isExpectedDecoder = + videoDecoderName.indexOf(`${expectedDecoder}`) == 0; + ok( + isExpectedDecoder, + `Playback running by decoder '${videoDecoderName}', expected '${expectedDecoder}'` + ); + + const isExpectedProcess = + videoDecoderName.indexOf(`(${expectedProcess} remote)`) > 0; + ok( + isExpectedProcess, + `Playback running in process '${videoDecoderName}', expected '${expectedProcess}'` + ); + } + ); +} + +/** + * Check whether the video playback is not performed in the given process and given decoder. + * @param {object} tab + * the tab which has a playing video + * @param {string} givenProcess + * the process name on which the video playback should not be running + * @param {string} givenDecoder + * the decoder name with which the video playback should not be running + */ +async function assertNotEqualRunningProcessAndDecoderName( + tab, + { givenProcess, givenDecoder } = {} +) { + return SpecialPowers.spawn( + tab.linkedBrowser, + [givenProcess, givenDecoder], + // eslint-disable-next-line no-shadow + async (givenProcess, givenDecoder) => { + const video = content.document.querySelector("video"); + ok(!video.paused, "checking a playing video"); + + const debugInfo = await SpecialPowers.wrap(video).mozRequestDebugInfo(); + const videoDecoderName = debugInfo.decoder.reader.videoDecoderName; + const pattern = /(.+?)\s+\((\S+)\s+remote\)/; + const match = videoDecoderName.match(pattern); + if (match) { + const decoder = match[1]; + const process = match[2]; + isnot(decoder, givenDecoder, `Decoder name is not equal`); + isnot(process, givenProcess, `Process name is not equal`); + } else { + ok(false, "failed to match decoder/process name?"); + } + } + ); +} diff --git a/dom/media/test/bug1066943.webm b/dom/media/test/bug1066943.webm Binary files differnew file mode 100644 index 0000000000..64a24ec898 --- /dev/null +++ b/dom/media/test/bug1066943.webm diff --git a/dom/media/test/bug1066943.webm^headers^ b/dom/media/test/bug1066943.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug1066943.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug1301226-odd.wav b/dom/media/test/bug1301226-odd.wav Binary files differnew file mode 100644 index 0000000000..dd2df4e4dd --- /dev/null +++ b/dom/media/test/bug1301226-odd.wav diff --git a/dom/media/test/bug1301226-odd.wav^headers^ b/dom/media/test/bug1301226-odd.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug1301226-odd.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug1301226.wav b/dom/media/test/bug1301226.wav Binary files differnew file mode 100644 index 0000000000..0128486f07 --- /dev/null +++ b/dom/media/test/bug1301226.wav diff --git a/dom/media/test/bug1301226.wav^headers^ b/dom/media/test/bug1301226.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug1301226.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug1377278.webm b/dom/media/test/bug1377278.webm Binary files differnew file mode 100644 index 0000000000..802019f39f --- /dev/null +++ b/dom/media/test/bug1377278.webm diff --git a/dom/media/test/bug1377278.webm^headers^ b/dom/media/test/bug1377278.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug1377278.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug1535980.webm b/dom/media/test/bug1535980.webm Binary files differnew file mode 100644 index 0000000000..efc43959bf --- /dev/null +++ b/dom/media/test/bug1535980.webm diff --git a/dom/media/test/bug1535980.webm^headers^ b/dom/media/test/bug1535980.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug1535980.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug1799787.webm b/dom/media/test/bug1799787.webm Binary files differnew file mode 100644 index 0000000000..e6e613a59a --- /dev/null +++ b/dom/media/test/bug1799787.webm diff --git a/dom/media/test/bug1799787.webm^headers^ b/dom/media/test/bug1799787.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug1799787.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug461281.ogg b/dom/media/test/bug461281.ogg Binary files differnew file mode 100644 index 0000000000..d7f6a0ccf4 --- /dev/null +++ b/dom/media/test/bug461281.ogg diff --git a/dom/media/test/bug461281.ogg^headers^ b/dom/media/test/bug461281.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug461281.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug482461-theora.ogv b/dom/media/test/bug482461-theora.ogv Binary files differnew file mode 100644 index 0000000000..941b8d8efd --- /dev/null +++ b/dom/media/test/bug482461-theora.ogv diff --git a/dom/media/test/bug482461-theora.ogv^headers^ b/dom/media/test/bug482461-theora.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug482461-theora.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug482461.ogv b/dom/media/test/bug482461.ogv Binary files differnew file mode 100644 index 0000000000..6cf6aed330 --- /dev/null +++ b/dom/media/test/bug482461.ogv diff --git a/dom/media/test/bug482461.ogv^headers^ b/dom/media/test/bug482461.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug482461.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug495129.ogv b/dom/media/test/bug495129.ogv Binary files differnew file mode 100644 index 0000000000..44eb9296f5 --- /dev/null +++ b/dom/media/test/bug495129.ogv diff --git a/dom/media/test/bug495129.ogv^headers^ b/dom/media/test/bug495129.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug495129.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug495794.ogg b/dom/media/test/bug495794.ogg Binary files differnew file mode 100644 index 0000000000..1c19a64061 --- /dev/null +++ b/dom/media/test/bug495794.ogg diff --git a/dom/media/test/bug495794.ogg^headers^ b/dom/media/test/bug495794.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug495794.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug498380.ogv b/dom/media/test/bug498380.ogv Binary files differnew file mode 100644 index 0000000000..1179ecb70a --- /dev/null +++ b/dom/media/test/bug498380.ogv diff --git a/dom/media/test/bug498380.ogv^headers^ b/dom/media/test/bug498380.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug498380.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug498855-1.ogv b/dom/media/test/bug498855-1.ogv Binary files differnew file mode 100644 index 0000000000..95a524da4c --- /dev/null +++ b/dom/media/test/bug498855-1.ogv diff --git a/dom/media/test/bug498855-1.ogv^headers^ b/dom/media/test/bug498855-1.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug498855-1.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug498855-2.ogv b/dom/media/test/bug498855-2.ogv Binary files differnew file mode 100644 index 0000000000..795a308ae1 --- /dev/null +++ b/dom/media/test/bug498855-2.ogv diff --git a/dom/media/test/bug498855-2.ogv^headers^ b/dom/media/test/bug498855-2.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug498855-2.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug498855-3.ogv b/dom/media/test/bug498855-3.ogv Binary files differnew file mode 100644 index 0000000000..714858dfed --- /dev/null +++ b/dom/media/test/bug498855-3.ogv diff --git a/dom/media/test/bug498855-3.ogv^headers^ b/dom/media/test/bug498855-3.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug498855-3.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug499519.ogv b/dom/media/test/bug499519.ogv Binary files differnew file mode 100644 index 0000000000..62c0922d36 --- /dev/null +++ b/dom/media/test/bug499519.ogv diff --git a/dom/media/test/bug499519.ogv^headers^ b/dom/media/test/bug499519.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug499519.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug500311.ogv b/dom/media/test/bug500311.ogv Binary files differnew file mode 100644 index 0000000000..2cf27ef1ee --- /dev/null +++ b/dom/media/test/bug500311.ogv diff --git a/dom/media/test/bug500311.ogv^headers^ b/dom/media/test/bug500311.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug500311.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug501279.ogg b/dom/media/test/bug501279.ogg Binary files differnew file mode 100644 index 0000000000..e266f07ee8 --- /dev/null +++ b/dom/media/test/bug501279.ogg diff --git a/dom/media/test/bug501279.ogg^headers^ b/dom/media/test/bug501279.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug501279.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug504613.ogv b/dom/media/test/bug504613.ogv Binary files differnew file mode 100644 index 0000000000..5c7fd015e9 --- /dev/null +++ b/dom/media/test/bug504613.ogv diff --git a/dom/media/test/bug504613.ogv^headers^ b/dom/media/test/bug504613.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug504613.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug504644.ogv b/dom/media/test/bug504644.ogv Binary files differnew file mode 100644 index 0000000000..46fb4a876b --- /dev/null +++ b/dom/media/test/bug504644.ogv diff --git a/dom/media/test/bug504644.ogv^headers^ b/dom/media/test/bug504644.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug504644.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug504843.ogv b/dom/media/test/bug504843.ogv Binary files differnew file mode 100644 index 0000000000..94b4750865 --- /dev/null +++ b/dom/media/test/bug504843.ogv diff --git a/dom/media/test/bug504843.ogv^headers^ b/dom/media/test/bug504843.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug504843.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug506094.ogv b/dom/media/test/bug506094.ogv Binary files differnew file mode 100644 index 0000000000..142b7b9ad1 --- /dev/null +++ b/dom/media/test/bug506094.ogv diff --git a/dom/media/test/bug506094.ogv^headers^ b/dom/media/test/bug506094.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug506094.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug516323.indexed.ogv b/dom/media/test/bug516323.indexed.ogv Binary files differnew file mode 100644 index 0000000000..7bd76eeccc --- /dev/null +++ b/dom/media/test/bug516323.indexed.ogv diff --git a/dom/media/test/bug516323.indexed.ogv^headers^ b/dom/media/test/bug516323.indexed.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug516323.indexed.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug516323.ogv b/dom/media/test/bug516323.ogv Binary files differnew file mode 100644 index 0000000000..8f2f38b983 --- /dev/null +++ b/dom/media/test/bug516323.ogv diff --git a/dom/media/test/bug516323.ogv^headers^ b/dom/media/test/bug516323.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug516323.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug520493.ogg b/dom/media/test/bug520493.ogg Binary files differnew file mode 100644 index 0000000000..6eb23198f4 --- /dev/null +++ b/dom/media/test/bug520493.ogg diff --git a/dom/media/test/bug520493.ogg^headers^ b/dom/media/test/bug520493.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug520493.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug520500.ogg b/dom/media/test/bug520500.ogg Binary files differnew file mode 100644 index 0000000000..b91d3dd97d --- /dev/null +++ b/dom/media/test/bug520500.ogg diff --git a/dom/media/test/bug520500.ogg^headers^ b/dom/media/test/bug520500.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug520500.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug520908.ogv b/dom/media/test/bug520908.ogv Binary files differnew file mode 100644 index 0000000000..093158432a --- /dev/null +++ b/dom/media/test/bug520908.ogv diff --git a/dom/media/test/bug520908.ogv^headers^ b/dom/media/test/bug520908.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug520908.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug523816.ogv b/dom/media/test/bug523816.ogv Binary files differnew file mode 100644 index 0000000000..ca9a31b6da --- /dev/null +++ b/dom/media/test/bug523816.ogv diff --git a/dom/media/test/bug523816.ogv^headers^ b/dom/media/test/bug523816.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug523816.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug533822.ogg b/dom/media/test/bug533822.ogg Binary files differnew file mode 100644 index 0000000000..a8e506910e --- /dev/null +++ b/dom/media/test/bug533822.ogg diff --git a/dom/media/test/bug533822.ogg^headers^ b/dom/media/test/bug533822.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug533822.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug556821.ogv b/dom/media/test/bug556821.ogv Binary files differnew file mode 100644 index 0000000000..8d76fee45e --- /dev/null +++ b/dom/media/test/bug556821.ogv diff --git a/dom/media/test/bug556821.ogv^headers^ b/dom/media/test/bug556821.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug556821.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug557094.ogv b/dom/media/test/bug557094.ogv Binary files differnew file mode 100644 index 0000000000..b4fc0799a6 --- /dev/null +++ b/dom/media/test/bug557094.ogv diff --git a/dom/media/test/bug557094.ogv^headers^ b/dom/media/test/bug557094.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug557094.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bug604067.webm b/dom/media/test/bug604067.webm Binary files differnew file mode 100644 index 0000000000..86bdfdc91f --- /dev/null +++ b/dom/media/test/bug604067.webm diff --git a/dom/media/test/bug604067.webm^headers^ b/dom/media/test/bug604067.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/bug604067.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/bunny.webm b/dom/media/test/bunny.webm Binary files differnew file mode 100644 index 0000000000..823439d1c5 --- /dev/null +++ b/dom/media/test/bunny.webm diff --git a/dom/media/test/bunny_hd_5s.mp4 b/dom/media/test/bunny_hd_5s.mp4 Binary files differnew file mode 100644 index 0000000000..975a159574 --- /dev/null +++ b/dom/media/test/bunny_hd_5s.mp4 diff --git a/dom/media/test/can_play_type_dash.js b/dom/media/test/can_play_type_dash.js new file mode 100644 index 0000000000..b4760545db --- /dev/null +++ b/dom/media/test/can_play_type_dash.js @@ -0,0 +1,27 @@ +function check_dash(v, enabled) { + function check(type, expected) { + is(v.canPlayType(type), enabled ? expected : "", type); + } + + // DASH types + check("application/dash+xml", "probably"); + + // Supported Webm codecs + check("application/dash+xml; codecs=vorbis", "probably"); + check("application/dash+xml; codecs=vorbis", "probably"); + check("application/dash+xml; codecs=vorbis,vp8", "probably"); + check("application/dash+xml; codecs=vorbis,vp8.0", "probably"); + check('application/dash+xml; codecs="vorbis,vp8"', "probably"); + check('application/dash+xml; codecs="vorbis,vp8.0"', "probably"); + check('application/dash+xml; codecs="vp8, vorbis"', "probably"); + check('application/dash+xml; codecs="vp8.0, vorbis"', "probably"); + check("application/dash+xml; codecs=vp8", "probably"); + check("application/dash+xml; codecs=vp8.0", "probably"); + + // Unsupported codecs + check("application/dash+xml; codecs=xyz", ""); + check("application/dash+xml; codecs=xyz,vorbis", ""); + check("application/dash+xml; codecs=vorbis,xyz", ""); + check("application/dash+xml; codecs=xyz,vp8.0", ""); + check("application/dash+xml; codecs=vp8.0,xyz", ""); +} diff --git a/dom/media/test/can_play_type_ogg.js b/dom/media/test/can_play_type_ogg.js new file mode 100644 index 0000000000..79bf8a554c --- /dev/null +++ b/dom/media/test/can_play_type_ogg.js @@ -0,0 +1,72 @@ +function check_ogg(v, enabled, finish) { + function check(type, expected) { + is(v.canPlayType(type), enabled ? expected : "", type); + } + + function basic_test() { + return new Promise(function (resolve, reject) { + // Ogg types + check("video/ogg", "maybe"); + check("audio/ogg", "maybe"); + check("application/ogg", "maybe"); + + // Supported Ogg codecs + check("audio/ogg; codecs=vorbis", "probably"); + check("video/ogg; codecs=vorbis", "probably"); + check("video/ogg; codecs=vorbis,theora", "probably"); + check('video/ogg; codecs="vorbis, theora"', "probably"); + check("video/ogg; codecs=theora", "probably"); + + resolve(); + }); + } + + // Verify Opus support + function verify_opus_support() { + return new Promise(function (resolve, reject) { + var OpusEnabled = SpecialPowers.getBoolPref( + "media.opus.enabled", + undefined + ); + if (OpusEnabled != undefined) { + resolve(); + } else { + console.log( + "media.opus.enabled pref not found; skipping Opus validation" + ); + reject(); + } + }); + } + + function opus_enable() { + return SpecialPowers.pushPrefEnv({ + set: [["media.opus.enabled", true]], + }).then(function () { + check("audio/ogg; codecs=opus", "probably"); + }); + } + + function opus_disable() { + return SpecialPowers.pushPrefEnv({ + set: [["media.opus.enabled", false]], + }).then(function () { + check("audio/ogg; codecs=opus", ""); + }); + } + + function unspported_ogg() { + // Unsupported Ogg codecs + check("video/ogg; codecs=xyz", ""); + check("video/ogg; codecs=xyz,vorbis", ""); + check("video/ogg; codecs=vorbis,xyz", ""); + + finish.call(); + } + + basic_test() + .then(verify_opus_support) + .then(opus_enable) + .then(opus_disable) + .then(unspported_ogg, unspported_ogg); +} diff --git a/dom/media/test/can_play_type_wave.js b/dom/media/test/can_play_type_wave.js new file mode 100644 index 0000000000..a5e087aa40 --- /dev/null +++ b/dom/media/test/can_play_type_wave.js @@ -0,0 +1,30 @@ +function check_wave(v, enabled) { + function check(type, expected) { + is(v.canPlayType(type), enabled ? expected : "", type); + } + + // Wave types + check("audio/wave", "maybe"); + check("audio/wav", "maybe"); + check("audio/x-wav", "maybe"); + check("audio/x-pn-wav", "maybe"); + + // Supported Wave codecs + check("audio/wave; codecs=1", "probably"); + check("audio/wave; codecs=3", "probably"); + check("audio/wave; codecs=6", "probably"); + check("audio/wave; codecs=7", "probably"); + // "no codecs" should be supported, I guess + check("audio/wave; codecs=", "maybe"); + check('audio/wave; codecs=""', "maybe"); + + // Unsupported Wave codecs + check("audio/wave; codecs=0", ""); + check("audio/wave; codecs=2", ""); + check("audio/wave; codecs=xyz,1", ""); + check("audio/wave; codecs=1,xyz", ""); + check('audio/wave; codecs="xyz, 1"', ""); + // empty codec names + check("audio/wave; codecs=,", ""); + check('audio/wave; codecs="0, 1,"', ""); +} diff --git a/dom/media/test/can_play_type_webm.js b/dom/media/test/can_play_type_webm.js new file mode 100644 index 0000000000..315a8ef3d9 --- /dev/null +++ b/dom/media/test/can_play_type_webm.js @@ -0,0 +1,39 @@ +async function check_webm(v, enabled) { + function check(type, expected) { + is( + v.canPlayType(type), + enabled ? expected : "", + type + "='" + expected + "'" + ); + } + + // WebM types + check("video/webm", "maybe"); + check("audio/webm", "maybe"); + + var video = ["vp8", "vp8.0", "vp9", "vp9.0"]; + var audio = ["vorbis", "opus"]; + + audio.forEach(function (acodec) { + check("audio/webm; codecs=" + acodec, "probably"); + check("video/webm; codecs=" + acodec, "probably"); + }); + video.forEach(function (vcodec) { + check("video/webm; codecs=" + vcodec, "probably"); + audio.forEach(function (acodec) { + check('video/webm; codecs="' + vcodec + ", " + acodec + '"', "probably"); + check('video/webm; codecs="' + acodec + ", " + vcodec + '"', "probably"); + }); + }); + + // Unsupported WebM codecs + check("video/webm; codecs=xyz", ""); + check("video/webm; codecs=xyz,vorbis", ""); + check("video/webm; codecs=vorbis,xyz", ""); + + await SpecialPowers.pushPrefEnv({ set: [["media.av1.enabled", true]] }); + check('video/webm; codecs="av1"', "probably"); + + await SpecialPowers.pushPrefEnv({ set: [["media.av1.enabled", false]] }); + check('video/webm; codecs="av1"', ""); +} diff --git a/dom/media/test/cancellable_request.sjs b/dom/media/test/cancellable_request.sjs new file mode 100644 index 0000000000..ffeb0c7818 --- /dev/null +++ b/dom/media/test/cancellable_request.sjs @@ -0,0 +1,162 @@ +function parseQuery(request, key) { + var params = request.queryString.split("&"); + for (var j = 0; j < params.length; ++j) { + var p = params[j]; + if (p == key) { + return true; + } + if (p.indexOf(key + "=") == 0) { + return p.substring(key.length + 1); + } + if (!p.includes("=") && key == "") { + return p; + } + } + return false; +} + +function push32BE(array, input) { + array.push(String.fromCharCode((input >> 24) & 0xff)); + array.push(String.fromCharCode((input >> 16) & 0xff)); + array.push(String.fromCharCode((input >> 8) & 0xff)); + array.push(String.fromCharCode(input & 0xff)); +} + +function push32LE(array, input) { + array.push(String.fromCharCode(input & 0xff)); + array.push(String.fromCharCode((input >> 8) & 0xff)); + array.push(String.fromCharCode((input >> 16) & 0xff)); + array.push(String.fromCharCode((input >> 24) & 0xff)); +} + +function push16LE(array, input) { + array.push(String.fromCharCode(input & 0xff)); + array.push(String.fromCharCode((input >> 8) & 0xff)); +} + +function buildWave(samples, sample_rate) { + const RIFF_MAGIC = 0x52494646; + const WAVE_MAGIC = 0x57415645; + const FRMT_MAGIC = 0x666d7420; + const DATA_MAGIC = 0x64617461; + const RIFF_SIZE = 44; + + var header = []; + push32BE(header, RIFF_MAGIC); + push32LE(header, RIFF_SIZE + samples.length * 2); + push32BE(header, WAVE_MAGIC); + push32BE(header, FRMT_MAGIC); + push32LE(header, 16); + push16LE(header, 1); + push16LE(header, 1); + push32LE(header, sample_rate); + push32LE(header, sample_rate); + push16LE(header, 2); + push16LE(header, 16); + push32BE(header, DATA_MAGIC); + push32LE(header, samples.length * 2); + for (var i = 0; i < samples.length; ++i) { + push16LE(header, samples[i], 2); + } + return header; +} + +const CC = Components.Constructor; +const Timer = CC("@mozilla.org/timer;1", "nsITimer", "initWithCallback"); +const BinaryOutputStream = CC( + "@mozilla.org/binaryoutputstream;1", + "nsIBinaryOutputStream", + "setOutputStream" +); + +function poll(f) { + if (f()) { + return; + } + new Timer( + function () { + poll(f); + }, + 100, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} + +function handleRequest(request, response) { + var cancel = parseQuery(request, "cancelkey"); + if (cancel) { + setState(cancel[1], "cancelled"); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write("Cancel approved!"); + return; + } + + var samples = []; + for (var i = 0; i < 1000000; ++i) { + samples.push(0); + } + var bytes = buildWave(samples, 44100).join(""); + + var key = parseQuery(request, "key"); + response.setHeader("Content-Type", "audio/x-wav"); + response.setHeader("Content-Length", "" + bytes.length, false); + + var out = new BinaryOutputStream(response.bodyOutputStream); + + var start = 0, + end = bytes.length - 1; + if (request.hasHeader("Range")) { + var rangeMatch = request.getHeader("Range").match(/^bytes=(\d+)?-(\d+)?$/); + + if (rangeMatch[1] !== undefined) { + start = parseInt(rangeMatch[1], 10); + } + + if (rangeMatch[2] !== undefined) { + end = parseInt(rangeMatch[2], 10); + } + + // No start given, so the end is really the count of bytes from the + // end of the file. + if (start === undefined) { + start = Math.max(0, bytes.length - end); + end = bytes.length - 1; + } + + // start and end are inclusive + if (end === undefined || end >= bytes.length) { + end = bytes.length - 1; + } + + if (end < start) { + response.setStatusLine(request.httpVersion, 200, "OK"); + start = 0; + end = bytes.length - 1; + } else { + response.setStatusLine(request.httpVersion, 206, "Partial Content"); + var contentRange = "bytes " + start + "-" + end + "/" + bytes.length; + response.setHeader("Content-Range", contentRange); + } + } + + if (start > 0) { + // Send all requested data + out.write(bytes.slice(start, end + 1), end + 1 - start); + return; + } + + // Write the first 1.2M of the Wave file. We know the cache size is set to + // 100K so this will fill the cache and and cause a "suspend" event on + // the loading element. + out.write(bytes, 1200000); + + response.processAsync(); + // Now wait for the message to cancel this response + poll(function () { + if (getState(key[1]) != "cancelled") { + return false; + } + response.finish(); + return true; + }); +} diff --git a/dom/media/test/chain.ogg b/dom/media/test/chain.ogg Binary files differnew file mode 100644 index 0000000000..3535b280f4 --- /dev/null +++ b/dom/media/test/chain.ogg diff --git a/dom/media/test/chain.ogg^headers^ b/dom/media/test/chain.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/chain.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/chain.ogv b/dom/media/test/chain.ogv Binary files differnew file mode 100644 index 0000000000..3e684b64a5 --- /dev/null +++ b/dom/media/test/chain.ogv diff --git a/dom/media/test/chain.ogv^headers^ b/dom/media/test/chain.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/chain.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/chain.opus b/dom/media/test/chain.opus Binary files differnew file mode 100644 index 0000000000..9fa67f94c3 --- /dev/null +++ b/dom/media/test/chain.opus diff --git a/dom/media/test/chain.opus^headers^ b/dom/media/test/chain.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/chain.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/chained-audio-video.ogg b/dom/media/test/chained-audio-video.ogg Binary files differnew file mode 100644 index 0000000000..adda68bb47 --- /dev/null +++ b/dom/media/test/chained-audio-video.ogg diff --git a/dom/media/test/chained-audio-video.ogg^headers^ b/dom/media/test/chained-audio-video.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/chained-audio-video.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/chained-video.ogv b/dom/media/test/chained-video.ogv Binary files differnew file mode 100644 index 0000000000..a6288ef6c9 --- /dev/null +++ b/dom/media/test/chained-video.ogv diff --git a/dom/media/test/chained-video.ogv^headers^ b/dom/media/test/chained-video.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/chained-video.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/chrome/chrome.toml b/dom/media/test/chrome/chrome.toml new file mode 100644 index 0000000000..57d1843841 --- /dev/null +++ b/dom/media/test/chrome/chrome.toml @@ -0,0 +1,12 @@ +[DEFAULT] +subsuite = "media" +support-files = [ + "../gizmo.mp4", + "../gizmo-noaudio.mp4", + "../TestPatternHDR.mp4", + "../tone2s-silence4s-tone2s.opus", +] + +["test_accumulated_play_time.html"] + +["test_telemetry_source_buffer_type.html"] diff --git a/dom/media/test/chrome/test_accumulated_play_time.html b/dom/media/test/chrome/test_accumulated_play_time.html new file mode 100644 index 0000000000..e59c0377b2 --- /dev/null +++ b/dom/media/test/chrome/test_accumulated_play_time.html @@ -0,0 +1,694 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test Video Play Time Related Permanent Telemetry Probes</title> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +/** + * This test is used to ensure that we accumulate time for video playback + * correctly, and the results would be used in Telemetry probes. + * Currently this test covers following probes + * - VIDEO_PLAY_TIME_MS + * - VIDEO_HDR_PLAY_TIME_MS + * - VIDEO_HIDDEN_PLAY_TIME_MS + * - VIDEO_HIDDEN_PLAY_TIME_PERCENTAGE + * - VIDEO_INFERRED_DECODE_SUSPEND_PERCENTAGE + * - VIDEO_VISIBLE_PLAY_TIME_MS + * - MEDIA_PLAY_TIME_MS + * - MUTED_PLAY_TIME_PERCENT + * - AUDIBLE_PLAY_TIME_PERCENT + */ +const videoHistNames = [ + "VIDEO_PLAY_TIME_MS", + "VIDEO_HIDDEN_PLAY_TIME_MS" +]; +const videoHDRHistNames = [ + "VIDEO_HDR_PLAY_TIME_MS" +]; +const videoKeyedHistNames = [ + "VIDEO_HIDDEN_PLAY_TIME_PERCENTAGE", + "VIDEO_INFERRED_DECODE_SUSPEND_PERCENTAGE", + "VIDEO_VISIBLE_PLAY_TIME_MS" +]; +const audioKeyedHistNames = [ + "MUTED_PLAY_TIME_PERCENT", + "AUDIBLE_PLAY_TIME_PERCENT" +]; + +add_task(async function setTestPref() { + await SpecialPowers.pushPrefEnv({ + set: [["media.testing-only-events", true], + ["media.test.video-suspend", true], + ["media.suspend-background-video.enabled", true], + ["media.suspend-background-video.delay-ms", 0], + ["dom.media.silence_duration_for_audibility", 0.1] + ]}); +}); + +add_task(async function testTotalPlayTime() { + const video = document.createElement('video'); + video.src = "gizmo.mp4"; + document.body.appendChild(video); + + info(`all accumulated time should be zero`); + const videoChrome = SpecialPowers.wrap(video); + await new Promise(r => video.onloadeddata = r); + assertValueEqualTo(videoChrome, "totalVideoPlayTime", 0); + assertValueEqualTo(videoChrome, "invisiblePlayTime", 0); + + info(`start accumulating play time after media starts`); + video.autoplay = true; + await Promise.all([ + once(video, "playing"), + once(video, "moztotalplaytimestarted"), + ]); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + assertValueKeptUnchanged(videoChrome, "videoDecodeSuspendedTime"); + + info(`should not accumulate time for paused video`); + video.pause(); + await once(video, "moztotalplaytimepaused"); + assertValueKeptUnchanged(videoChrome, "totalVideoPlayTime"); + assertValueEqualTo(videoChrome, "totalVideoPlayTime", 0); + + info(`should start accumulating time again`); + let rv = await Promise.all([ + onceWithTrueReturn(video, "moztotalplaytimestarted"), + video.play().then(_ => true, _ => false), + ]); + ok(returnTrueWhenAllValuesAreTrue(rv), "video started again"); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + await cleanUpMediaAndCheckTelemetry(video); +}); + +// The testHDRPlayTime task will only pass on platforms that accurately report +// color depth in their VideoInfo structures. Presently, that is only true for +// macOS. +const {AppConstants} = ChromeUtils.importESModule( + "resource://gre/modules/AppConstants.sys.mjs" +); +const reportsColorDepthFromVideoData = (AppConstants.platform == "macosx"); +if (reportsColorDepthFromVideoData) { + add_task(async function testHDRPlayTime() { + // This task is different from the others because the HTMLMediaElement does + // not expose a chrome property for video hdr play time. But we do capture + // telemety for VIDEO_HDR_PLAY_TIME_MS. To ensure that this telemetry is + // generated, this task follows the same structure as the other tasks, but + // doesn't actually check the properties of the video player, other than to + // confirm that video has played for at least some time. + const video = document.createElement('video'); + video.src = "TestPatternHDR.mp4"; // This is an HDR video with no audio. + document.body.appendChild(video); + + info(`load the HDR video`); + const videoChrome = SpecialPowers.wrap(video); + await new Promise(r => video.onloadeddata = r); + + info(`start accumulating play time after media starts`); + video.autoplay = true; + await Promise.all([ + once(video, "playing"), + once(video, "moztotalplaytimestarted"), + ]); + // Check that we have at least some video play time, because the + // HDR play time telemetry is emitted by the same process. + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + await cleanUpMediaAndCheckTelemetry(video, {hasVideo: true, hasAudio: false, hasVideoHDR: true}); + }); +} + +add_task(async function testVisiblePlayTime() { + const video = document.createElement('video'); + video.src = "gizmo.mp4"; + document.body.appendChild(video); + + info(`all accumulated time should be zero`); + const videoChrome = SpecialPowers.wrap(video); + await new Promise(r => video.onloadeddata = r); + assertValueEqualTo(videoChrome, "totalVideoPlayTime", 0); + assertValueEqualTo(videoChrome, "visiblePlayTime", 0); + assertValueEqualTo(videoChrome, "invisiblePlayTime", 0); + + info(`start accumulating play time after media starts`); + video.autoplay = true; + await Promise.all([ + once(video, "playing"), + once(video, "moztotalplaytimestarted"), + ]); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + await assertValueConstantlyIncreases(videoChrome, "visiblePlayTime"); + assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + + info(`make video invisible`); + video.style.display = "none"; + await once(video, "mozinvisibleplaytimestarted"); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + await assertValueConstantlyIncreases(videoChrome, "invisiblePlayTime"); + assertValueKeptUnchanged(videoChrome, "visiblePlayTime"); + await cleanUpMediaAndCheckTelemetry(video); +}); + +add_task(async function testAudibleAudioPlayTime() { + const audio = document.createElement('audio'); + audio.src = "tone2s-silence4s-tone2s.opus"; + audio.controls = true; + audio.loop = true; + document.body.appendChild(audio); + + info(`all accumulated time should be zero`); + const audioChrome = SpecialPowers.wrap(audio); + await new Promise(r => audio.onloadeddata = r); + assertValueEqualTo(audioChrome, "totalVideoPlayTime", 0); + assertValueEqualTo(audioChrome, "totalAudioPlayTime", 0); + assertValueEqualTo(audioChrome, "mutedPlayTime", 0); + assertValueEqualTo(audioChrome, "audiblePlayTime", 0); + + info(`start accumulating play time after media starts`); + await Promise.all([ + audio.play(), + once(audio, "moztotalplaytimestarted"), + ]); + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "mutedPlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + info(`audio becomes inaudible for 4s`); + await once(audio, "mozinaudibleaudioplaytimestarted"); + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + assertValueKeptUnchanged(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "mutedPlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + info(`audio becomes audible after 4s`); + await once(audio, "mozinaudibleaudioplaytimepaused"); + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "mutedPlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + await cleanUpMediaAndCheckTelemetry(audio, {hasVideo: false}); +}); + +add_task(async function testHiddenPlayTime() { + const invisibleReasons = ["notInTree", "notInConnectedTree", "invisibleInDisplay"]; + for (let reason of invisibleReasons) { + const video = document.createElement('video'); + video.src = "gizmo.mp4"; + video.loop = true; + info(`invisible video due to '${reason}'`); + + if (reason == "notInConnectedTree") { + let disconnected = document.createElement("div") + disconnected.appendChild(video); + } else if (reason == "invisibleInDisplay") { + document.body.appendChild(video); + video.style.display = "none"; + } else if (reason == "notInTree") { + // video is already created in the `notInTree` situation. + } else { + ok(false, "undefined reason"); + } + + info(`start invisible video should start accumulating timers`); + const videoChrome = SpecialPowers.wrap(video); + let rv = await Promise.all([ + onceWithTrueReturn(video, "mozinvisibleplaytimestarted"), + video.play().then(_ => true, _ => false), + ]); + ok(returnTrueWhenAllValuesAreTrue(rv), "video started playing"); + await assertValueConstantlyIncreases(videoChrome, "invisiblePlayTime"); + + info(`should not accumulate time for paused video`); + video.pause(); + await once(video, "mozinvisibleplaytimepaused"); + assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + + info(`should start accumulating time again`); + rv = await Promise.all([ + onceWithTrueReturn(video, "mozinvisibleplaytimestarted"), + video.play().then(_ => true, _ => false), + ]); + ok(returnTrueWhenAllValuesAreTrue(rv), "video started again"); + await assertValueConstantlyIncreases(videoChrome, "invisiblePlayTime"); + + info(`make video visible should stop accumulating invisible related time`); + if (reason == "notInTree" || reason == "notInConnectedTree") { + document.body.appendChild(video); + } else if (reason == "invisibleInDisplay") { + video.style.display = "block"; + } else { + ok(false, "undefined reason"); + } + await once(video, "mozinvisibleplaytimepaused"); + assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + await cleanUpMediaAndCheckTelemetry(video); + } +}); + +add_task(async function testAudioProbesWithoutAudio() { + const video = document.createElement('video'); + video.src = "gizmo-noaudio.mp4"; + video.loop = true; + document.body.appendChild(video); + + info(`all accumulated time should be zero`); + const videoChrome = SpecialPowers.wrap(video); + await new Promise(r => video.onloadeddata = r); + assertValueEqualTo(videoChrome, "totalVideoPlayTime", 0); + assertValueEqualTo(videoChrome, "totalAudioPlayTime", 0); + assertValueEqualTo(videoChrome, "mutedPlayTime", 0); + assertValueEqualTo(videoChrome, "audiblePlayTime", 0); + + info(`start accumulating play time after media starts`); + await Promise.all([ + video.play(), + once(video, "moztotalplaytimestarted"), + ]); + + async function checkInvariants() { + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + assertValueKeptUnchanged(videoChrome, "audiblePlayTime"); + assertValueKeptUnchanged(videoChrome, "mutedPlayTime"); + assertValueKeptUnchanged(videoChrome, "totalAudioPlayTime"); + } + + checkInvariants(); + + video.muted = true; + + checkInvariants(); + + video.currentTime = 0.0; + await once(video, "seeked"); + + checkInvariants(); + + video.muted = false; + + checkInvariants(); + + video.volume = 0.0; + + checkInvariants(); + + video.volume = 1.0; + + checkInvariants(); + + video.muted = true; + + checkInvariants(); + + video.currentTime = 0.0; + + checkInvariants(); + + await cleanUpMediaAndCheckTelemetry(video, {hasAudio: false}); +}); + +add_task(async function testMutedAudioPlayTime() { + const audio = document.createElement('audio'); + audio.src = "gizmo.mp4"; + audio.controls = true; + audio.loop = true; + document.body.appendChild(audio); + + info(`all accumulated time should be zero`); + const audioChrome = SpecialPowers.wrap(audio); + await new Promise(r => audio.onloadeddata = r); + assertValueEqualTo(audioChrome, "totalVideoPlayTime", 0); + assertValueEqualTo(audioChrome, "totalAudioPlayTime", 0); + assertValueEqualTo(audioChrome, "mutedPlayTime", 0); + assertValueEqualTo(audioChrome, "audiblePlayTime", 0); + + info(`start accumulating play time after media starts`); + await Promise.all([ + audio.play(), + once(audio, "moztotalplaytimestarted"), + ]); + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "mutedPlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + audio.muted = true; + await once(audio, "mozmutedaudioplaytimestarted"); + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "mutedPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + audio.currentTime = 0.0; + await once(audio, "seeked"); + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "mutedPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + audio.muted = false; + await once(audio, "mozmutedeaudioplaytimepaused"); + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "mutedPlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + audio.volume = 0.0; + await once(audio, "mozmutedaudioplaytimestarted"); + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "mutedPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + audio.volume = 1.0; + await once(audio, "mozmutedeaudioplaytimepaused"); + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "mutedPlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + audio.muted = true; + await once(audio, "mozmutedaudioplaytimestarted"); + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "mutedPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + audio.currentTime = 0.0; + + await assertValueConstantlyIncreases(audioChrome, "totalAudioPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "mutedPlayTime"); + await assertValueConstantlyIncreases(audioChrome, "audiblePlayTime"); + assertValueKeptUnchanged(audioChrome, "totalVideoPlayTime"); + + // The media has a video track, but it's being played back in an + // HTMLAudioElement, without video frame location. + await cleanUpMediaAndCheckTelemetry(audio, {hasVideo: false}); +}); + +// Note that video suspended time is not always align with the invisible play +// time even if `media.suspend-background-video.delay-ms` is `0`, because not all +// invisible videos would be suspended under current strategy. +add_task(async function testDecodeSuspendedTime() { + const video = document.createElement('video'); + video.src = "gizmo.mp4"; + video.loop = true; + document.body.appendChild(video); + + info(`start video should start accumulating timers`); + const videoChrome = SpecialPowers.wrap(video); + let rv = await Promise.all([ + onceWithTrueReturn(video, "moztotalplaytimestarted"), + video.play().then(_ => true, _ => false), + ]); + ok(returnTrueWhenAllValuesAreTrue(rv), "video started playing"); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + assertValueKeptUnchanged(videoChrome, "videoDecodeSuspendedTime"); + + info(`make it invisible and force to suspend decoding`); + video.setVisible(false); + await once(video, "mozvideodecodesuspendedstarted"); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + await assertValueConstantlyIncreases(videoChrome, "invisiblePlayTime"); + await assertValueConstantlyIncreases(videoChrome, "videoDecodeSuspendedTime"); + + info(`make it visible and resume decoding`); + video.setVisible(true); + await Promise.all([ + once(video, "mozinvisibleplaytimepaused"), + once(video, "mozvideodecodesuspendedpaused"), + ]); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + assertValueKeptUnchanged(videoChrome, "videoDecodeSuspendedTime"); + await cleanUpMediaAndCheckTelemetry(video); +}); + +add_task(async function reuseSameElementForPlayback() { + const video = document.createElement('video'); + video.src = "gizmo.mp4"; + document.body.appendChild(video); + + info(`start accumulating play time after media starts`); + const videoChrome = SpecialPowers.wrap(video); + let rv = await Promise.all([ + onceWithTrueReturn(video, "moztotalplaytimestarted"), + video.play().then(_ => true, _ => false), + ]); + ok(returnTrueWhenAllValuesAreTrue(rv), "video started again"); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + + info(`reset its src and all accumulated value should be reset after then`); + // After setting its src to nothing, that would trigger a failed load and set + // the error. If the following step tries to set the new resource and `play()` + // , then they should be done after receving the `error` from that failed load + // first. + await Promise.all([ + once(video, "error"), + cleanUpMediaAndCheckTelemetry(video), + ]); + // video doesn't have a decoder, so the return value would be -1 (error). + assertValueEqualTo(videoChrome, "totalVideoPlayTime", -1); + assertValueEqualTo(videoChrome, "invisiblePlayTime", -1); + + info(`resue same element, make it visible and start playback again`); + video.src = "gizmo.mp4"; + rv = await Promise.all([ + onceWithTrueReturn(video, "moztotalplaytimestarted"), + video.play().then(_ => true, _ => false), + ]); + ok(returnTrueWhenAllValuesAreTrue(rv), "video started"); + await assertValueConstantlyIncreases(videoChrome, "totalVideoPlayTime"); + await cleanUpMediaAndCheckTelemetry(video); +}); + +add_task(async function testNoReportedTelemetryResult() { + info(`No result for empty video`); + const video = document.createElement('video'); + assertAllProbeRelatedAttributesKeptUnchanged(video); + await assertNoReportedTelemetryResult(video); + + info(`No result for video which hasn't started playing`); + video.src = "gizmo.mp4"; + document.body.appendChild(video); + ok(await once(video, "loadeddata").then(_ => true), "video loaded data"); + assertAllProbeRelatedAttributesKeptUnchanged(video); + await assertNoReportedTelemetryResult(video); + + info(`No result for video with error`); + video.src = "filedoesnotexist.mp4"; + ok(await video.play().then(_ => false, _ => true), "video failed to play"); + ok(video.error != undefined, "video got error"); + assertAllProbeRelatedAttributesKeptUnchanged(video); + await assertNoReportedTelemetryResult(video); +}); + +/** + * Following are helper functions + */ +async function cleanUpMediaAndCheckTelemetry(media, { reportExpected = true, hasVideo = true, hasAudio = true, hasVideoHDR = false } = {}) { + media.src = ""; + await checkReportedTelemetry(media, reportExpected, hasVideo, hasAudio, hasVideoHDR); +} + +async function assertNoReportedTelemetryResult(media) { + await checkReportedTelemetry(media, false, true, true); +} + +async function checkReportedTelemetry(media, reportExpected, hasVideo, hasAudio, hasVideoHDR) { + const reportResultPromise = once(media, "mozreportedtelemetry"); + info(`check telemetry result, reportExpected=${reportExpected}`); + if (reportExpected) { + await reportResultPromise; + } + for (const name of videoHistNames) { + try { + const hist = SpecialPowers.Services.telemetry.getHistogramById(name); + /** + * Histogram's snapshot looks like that + * { + * "bucket_count": X, + * "histogram_type": Y, + * "sum": Z, + * "range": [min, max], + * "values": { "value1" : "num1", "value2" : "num2", ...} + * } + */ + const entriesNums = Object.entries(hist.snapshot().values).length; + if (reportExpected && hasVideo) { + ok(entriesNums > 0, `Reported result for ${name}`); + } else { + ok(entriesNums == 0, `Reported nothing for ${name}`); + } + hist.clear(); + } catch (e) { + ok(false , `histogram '${name}' doesn't exist`); + } + } + // videoHDRHistNames are checked for total time, not for number of samples. + for (const name of videoHDRHistNames) { + try { + const hist = SpecialPowers.Services.telemetry.getHistogramById(name); + const totalTimeMS = hist.snapshot().sum; + if (reportExpected && hasVideoHDR) { + ok(totalTimeMS > 0, `Reported some time for ${name}`); + } else { + ok(totalTimeMS == 0, `Reported no time for ${name}`); + } + hist.clear(); + } catch (e) { + ok(false , `histogram '${name}' doesn't exist`); + } + } + for (const name of videoKeyedHistNames) { + try { + const hist = SpecialPowers.Services.telemetry.getKeyedHistogramById(name); + /** + * Keyed Histogram's snapshot looks like that + * { + * "Key1" : { + * "bucket_count": X, + * "histogram_type": Y, + * "sum": Z, + * "range": [min, max], + * "values": { "value1" : "num1", "value2" : "num2", ...} + * }, + * "Key2" : {...}, + * } + */ + const items = Object.entries(hist.snapshot()); + if (items.length) { + for (const [key, value] of items) { + const entriesNums = Object.entries(value.values).length; + ok(reportExpected && entriesNums > 0, `Reported ${key} for ${name}`); + } + } else if (reportExpected) { + ok(!hasVideo, `No video telemetry reported but no video track in the media`); + } else { + ok(true, `No video telemetry expected, none reported`); + } + // Avoid to pollute next test task. + hist.clear(); + } catch (e) { + ok(false , `keyed histogram '${name}' doesn't exist`); + } + } + + // In any case, the combined probe MEDIA_PLAY_TIME_MS should be reported, if + // expected + { + const hist = + SpecialPowers.Services.telemetry.getKeyedHistogramById("MEDIA_PLAY_TIME_MS"); + const items = Object.entries(hist.snapshot()); + if (items.length) { + for (const item of items) { + ok(item[0].includes("V") != -1 || !hasVideo, "Video time is reported if video was present"); + } + hist.clear(); + } else { + ok(!reportExpected, "MEDIA_PLAY_TIME_MS should always be reported if a report is expected"); + } + } + + for (const name of audioKeyedHistNames) { + try { + const hist = SpecialPowers.Services.telemetry.getKeyedHistogramById(name); + const items = Object.entries(hist.snapshot()); + if (items.length) { + for (const [key, value] of items) { + const entriesNums = Object.entries(value.values).length; + ok(reportExpected && entriesNums > 0, `Reported ${key} for ${name}`); + } + } else { + ok(!reportExpected || !hasAudio, `No audio telemetry expected, none reported`); + } + // Avoid to pollute next test task. + hist.clear(); + } catch (e) { + ok(false , `keyed histogram '${name}' doesn't exist`); + } + } +} + +function once(target, name) { + return new Promise(r => target.addEventListener(name, r, { once: true })); +} + +function onceWithTrueReturn(target, name) { + return once(target, name).then(_ => true); +} + +function returnTrueWhenAllValuesAreTrue(arr) { + for (let val of arr) { + if (!val) { + return false; + } + } + return true; +} + +// Block the main thread for a number of milliseconds +function blockMainThread(durationMS) { + const start = Date.now(); + while (Date.now() - start < durationMS) { /* spin */ } +} + +// Allows comparing two values from the system clocks that are not gathered +// atomically. Allow up to 1ms of fuzzing when lhs and rhs are seconds. +function timeFuzzyEquals(lhs, rhs, str) { + ok(Math.abs(lhs - rhs) < 1e-3, str); +} + +function assertAttributeDefined(mediaChrome, checkType) { + ok(mediaChrome[checkType] != undefined, `${checkType} exists`); +} + +function assertValueEqualTo(mediaChrome, checkType, expectedValue) { + assertAttributeDefined(mediaChrome, checkType); + is(mediaChrome[checkType], expectedValue, `${checkType} equals to ${expectedValue}`); +} + +async function assertValueConstantlyIncreases(mediaChrome, checkType) { + assertAttributeDefined(mediaChrome, checkType); + const valueSnapshot = mediaChrome[checkType]; + // 30ms is long enough to have a low-resolution system clock tick, but short + // enough to not slow the test down. + blockMainThread(30); + const current = mediaChrome[checkType]; + ok(current > valueSnapshot, `${checkType} keeps increasing (${current} > ${valueSnapshot})`); +} + +function assertValueKeptUnchanged(mediaChrome, checkType) { + assertAttributeDefined(mediaChrome, checkType); + const valueSnapshot = mediaChrome[checkType]; + // 30ms is long enough to have a low-resolution system clock tick, but short + // enough to not slow the test down. + blockMainThread(30); + const newValue = mediaChrome[checkType]; + timeFuzzyEquals(newValue, valueSnapshot, `${checkType} keeps unchanged (${newValue} vs. ${valueSnapshot})`); +} + +function assertAllProbeRelatedAttributesKeptUnchanged(video) { + const videoChrome = SpecialPowers.wrap(video); + assertValueKeptUnchanged(videoChrome, "totalVideoPlayTime"); + assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + assertValueKeptUnchanged(videoChrome, "videoDecodeSuspendedTime"); +} + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/chrome/test_telemetry_source_buffer_type.html b/dom/media/test/chrome/test_telemetry_source_buffer_type.html new file mode 100644 index 0000000000..85ccfd1000 --- /dev/null +++ b/dom/media/test/chrome/test_telemetry_source_buffer_type.html @@ -0,0 +1,105 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Telemetry : test permanent probe MSE_SOURCE_BUFFER_TYPE</title> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +/** + * This test is used for the permanent Telemetry probe MSE_SOURCE_BUFFER_TYPE. + * which is used to measure the usage of mime type used in MSE. + */ +const VIDEO_HEVC = "video/hevc"; +const VIDEO_WEBM = "video/webm"; +const AUDIO_WEBM = "audio/webm"; +const VIDEO_MP4 = "video/mp4"; +const AUDIO_MP4 = "audio/mp4"; +const VIDEO_MP2T = "video/mp2t"; +const AUDIO_MP2T = "audio/mp2t"; +const AUDIO_MP3 = "audio/mpeg"; +const AUDIO_AAC = "audio/aac"; + +// The order follows `MSE_SOURCE_BUFFER_TYPE` in `Histogram.json`. +const gLabelNames = [VIDEO_HEVC, VIDEO_WEBM, AUDIO_WEBM, VIDEO_MP4, AUDIO_MP4, + VIDEO_MP2T, AUDIO_MP2T, AUDIO_MP3, AUDIO_AAC]; + +add_task(async function setTestPref() { + await SpecialPowers.pushPrefEnv({ + set: [["media.testing-only-events", true]]}); +}); + +add_task(async function testSourceBufferTypeProbe() { + for (let label of gLabelNames) { + // HEVC will be tested in another task. + if (label == VIDEO_HEVC) { + continue; + } + info(`calling 'isTypeSupported()' should increase the probe value`); + MediaSource.isTypeSupported(label); + assertLabelValueEqualTo(label, 1); + + info(`calling 'addSourceBuffer()' should increase the probe value`); + try { + const source = new MediaSource(); + source.addSourceBuffer(label); + } catch (e) { + info(`ignore error for unsupported type ${label}`); + } + assertLabelValueEqualTo(label, 2); + } +}); + +add_task(async function testSourceBufferHEVCTypeProbe() { + // These are all possible mime types for HEVC + const mimeTypes = [ + "video/mp4; codecs=\"hvc1\"", + "video/mp4; codecs=\"hev1\"", + "video/mp4; codecs=\"hvc1.1.6.L93.B0\"", + "video/mp4; codecs=\"hev1.1.6.L93.B0\"", + ]; + for (let idx = 0; idx < mimeTypes.length; idx++) { + const mimeType = mimeTypes[idx]; + info(`calling 'isTypeSupported()' should increase the probe value`); + MediaSource.isTypeSupported(mimeType); + assertLabelValueEqualTo(VIDEO_HEVC, idx * 2 + 1); + + info(`calling 'addSourceBuffer()' should increase the probe value`); + try { + const source = new MediaSource(); + source.addSourceBuffer(mimeType); + } catch (e) { + info(`ignore error for unsupported type ${mimeType}`); + } + assertLabelValueEqualTo(VIDEO_HEVC, idx * 2 + 2); + } +}); + +/** + * Following are helper functions + */ +async function assertLabelValueEqualTo(labelName, value) { + const hist = SpecialPowers.Services.telemetry.getHistogramById("MSE_SOURCE_BUFFER_TYPE"); + /** + * Histogram's snapshot looks like that + * { + * "bucket_count": X, + * "histogram_type": Y, + * "sum": Z, + * "range": [min, max], + * "values": { "value1" : "num1", "value2" : "num2", ...} + * } + */ + if (!gLabelNames.includes(labelName)) { + ok(false, `undefined label name=${labelName}`); + return; + } + const labelIdx = gLabelNames.indexOf(labelName); + is(hist.snapshot().values[labelIdx], value, `${labelName} equal to ${value}`); +} + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/chromeHelper.js b/dom/media/test/chromeHelper.js new file mode 100644 index 0000000000..a89d12d6dd --- /dev/null +++ b/dom/media/test/chromeHelper.js @@ -0,0 +1,23 @@ +/* -*- Mode: javascript; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* eslint-env mozilla/chrome-script */ + +"use strict"; + +// eslint-disable-next-line mozilla/use-services +const dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService( + Ci.nsIProperties +); + +addMessageListener("media-test:getcwd", () => { + let cwd; + try { + cwd = dirSvc.get("CurWorkD", Ci.nsIFile).path; + } finally { + sendAsyncMessage("media-test:cwd", cwd); + } +}); diff --git a/dom/media/test/cloneElementVisually_helpers.js b/dom/media/test/cloneElementVisually_helpers.js new file mode 100644 index 0000000000..52e6cca36e --- /dev/null +++ b/dom/media/test/cloneElementVisually_helpers.js @@ -0,0 +1,232 @@ +const TEST_VIDEO_1 = + "http://mochi.test:8888/tests/dom/media/test/bipbop_225w_175kbps.mp4"; +const TEST_VIDEO_2 = + "http://mochi.test:8888/tests/dom/media/test/pixel_aspect_ratio.mp4"; +const LONG_VIDEO = "http://mochi.test:8888/tests/dom/media/test/gizmo.mp4"; + +/** + * Ensure that the original <video> is prepped and ready to play + * before starting any other tests. + */ +async function setup() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.test.video-suspend", true], + ["media.suspend-background-video.enabled", true], + ["media.suspend-background-video.delay-ms", 500], + ["media.dormant-on-pause-timeout-ms", 0], + ["media.cloneElementVisually.testing", true], + ], + }); + + let originalVideo = document.getElementById("original"); + await setVideoSrc(originalVideo, TEST_VIDEO_1); +} + +/** + * Given a canvas, as well as a width and height of something to be + * blitted onto that canvas, makes any necessary adjustments to the + * canvas to work with the current display resolution. + * + * @param canvas (<canvas> element) + * The canvas to be adjusted. + * @param width (int) + * The width of the image to be blitted. + * @param height (int) + * The height of the image to be blitted. + * @return CanvasRenderingContext2D (SpecialPowers wrapper) + */ +function getWrappedScaledCanvasContext(canvas, width, height) { + let devRatio = window.devicePixelRatio || 1; + let ctx = SpecialPowers.wrap(canvas.getContext("2d")); + let backingRatio = ctx.webkitBackingStorePixelRatio || 1; + + let ratio = 1; + ratio = devRatio / backingRatio; + canvas.width = ratio * width; + canvas.height = ratio * height; + canvas.style.width = width + "px"; + canvas.style.height = height + "px"; + ctx.scale(ratio, ratio); + + return ctx; +} + +/** + * Given a <video> element in the DOM, figures out its location, and captures + * a snapshot of what it's currently presenting. + * + * @param video (<video> element) + * @return ImageData (SpecialPowers wrapper) + */ +function captureFrameImageData(video) { + // Flush layout first, just in case the decoder has recently + // updated the dimensions of the video. + let rect = video.getBoundingClientRect(); + + let width = video.videoWidth; + let height = video.videoHeight; + + let canvas = document.createElement("canvas"); + let ctx = getWrappedScaledCanvasContext(canvas, width, height); + ctx.drawWindow(window, rect.left, rect.top, width, height, "rgb(0,0,0)"); + + return ctx.getImageData(0, 0, width, height); +} + +/** + * Given two <video> elements, captures snapshots of what they're currently + * displaying, and asserts that they're identical. + * + * @param video1 (<video> element) + * A video element to compare against. + * @param video2 (<video> element) + * A video to compare with video1. + * @return Promise + * @resolves + * Resolves as true if the two videos match. + */ +async function assertVideosMatch(video1, video2) { + let video1Frame = captureFrameImageData(video1); + let video2Frame = captureFrameImageData(video2); + + let left = document.getElementById("left"); + let leftCtx = getWrappedScaledCanvasContext( + left, + video1Frame.width, + video1Frame.height + ); + leftCtx.putImageData(video1Frame, 0, 0); + + let right = document.getElementById("right"); + let rightCtx = getWrappedScaledCanvasContext( + right, + video2Frame.width, + video2Frame.height + ); + rightCtx.putImageData(video2Frame, 0, 0); + + if (video1Frame.data.length != video2Frame.data.length) { + return false; + } + + let leftDataURL = left.toDataURL(); + let rightDataURL = right.toDataURL(); + + if (leftDataURL != rightDataURL) { + dump("Left frame: " + leftDataURL + "\n\n"); + dump("Right frame: " + rightDataURL + "\n\n"); + + return false; + } + + return true; +} + +/** + * Testing helper function that constructs a node clone of a video, + * injects it into the DOM, and then runs an async testing function. + * This also does the work of removing the clone before resolving. + * + * @param video (<video> element) + * The video to clone the node from. + * @param asyncFn (async function) + * A test function that will be passed the new clone as its + * only argument. + * @return Promise + * @resolves + * When the asyncFn resolves and the clone has been removed + * from the DOM. + */ +async function withNewClone(video, asyncFn) { + let clone = video.cloneNode(); + clone.id = "clone"; + clone.src = ""; + let content = document.getElementById("content"); + content.appendChild(clone); + + try { + await asyncFn(clone); + } finally { + clone.remove(); + } +} + +/** + * Sets the src on a video and waits until its ready. + * + * @param video (<video> element) + * The video to set the src on. + * @param src (string) + * The URL to set as the source on a video. + * @return Promise + * @resolves + * When the video fires the "canplay" event. + */ +async function setVideoSrc(video, src) { + let promiseReady = waitForEventOnce(video, "canplay"); + video.src = src; + await promiseReady; +} + +/** + * Returns a Promise once target emits a particular event + * once. + * + * @param target (DOM node) + * The target to monitor for the event. + * @param event (string) + * The name of the event to wait for. + * @return Promise + * @resolves + * When the event fires, and resolves to the event. + */ +function waitForEventOnce(target, event) { + return new Promise(resolve => { + target.addEventListener(event, resolve, { once: true }); + }); +} + +/** + * Polls the video debug data as a hacky way of knowing when + * when the decoders have shut down. + * + * @param video (<video> element) + * @return Promise + * @resolves + * When the decoder has shut down. + */ +function waitForShutdownDecoder(video) { + return SimpleTest.promiseWaitForCondition(async () => { + let readerData = await SpecialPowers.wrap(video).mozRequestDebugInfo(); + return readerData.decoder.reader.audioDecoderName == "shutdown"; + }, "Video decoder should eventually shut down."); +} + +/** + * Ensures that both hiding and pausing the video causes the + * video to suspend and make dormant its decoders, respectively. + * + * @param video (<video element) + */ +async function ensureVideoSuspendable(video) { + video = SpecialPowers.wrap(video); + + ok(!video.hasSuspendTaint(), "Should be suspendable"); + + // First, we'll simulate putting the video in the background by + // making it invisible. + let suspendPromise = waitForEventOnce(video, "mozentervideosuspend"); + video.setVisible(false); + await suspendPromise; + ok(true, "Suspended after the video was made invisible."); + video.setVisible(true); + + ok(!video.hasSuspendTaint(), "Should still be suspendable."); + + // Next, we'll pause the video. + await video.pause(); + await waitForShutdownDecoder(video); + ok(true, "Shutdown decoder after the video was paused."); + await video.play(); +} diff --git a/dom/media/test/contentType.sjs b/dom/media/test/contentType.sjs new file mode 100644 index 0000000000..5a371564cf --- /dev/null +++ b/dom/media/test/contentType.sjs @@ -0,0 +1,77 @@ +// Parse the query string, and give us the value for a certain key, or false if +// it does not exist. +function parseQuery(request, key) { + var params = request.queryString.split("?")[0].split("&"); + for (var j = 0; j < params.length; ++j) { + var p = params[j]; + if (p == key) { + return true; + } + if (p.indexOf(key + "=") == 0) { + return p.substring(key.length + 1); + } + if (!p.includes("=") && key == "") { + return p; + } + } + return false; +} + +function handleRequest(request, response) { + try { + // Get the filename to send back. + var filename = parseQuery(request, "file"); + + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + var paths = "tests/dom/media/test/" + filename; + dump(paths + "\n"); + var split = paths.split("/"); + for (var i = 0; i < split.length; ++i) { + file.append(split[i]); + } + fis.init(file, -1, -1, false); + + // handle range requests + var partialstart = 0, + partialend = file.fileSize - 1; + if (request.hasHeader("Range")) { + var range = request.getHeader("Range"); + var parts = range.replace(/bytes=/, "").split("-"); + partialstart = parts[0]; + partialend = parts[1]; + if (!partialend.length) { + partialend = file.fileSize - 1; + } + response.setStatusLine(request.httpVersion, 206, "Partial Content"); + var contentRange = + "bytes " + partialstart + "-" + partialend + "/" + file.fileSize; + response.setHeader("Content-Range", contentRange); + } + + fis.seek(Ci.nsISeekableStream.NS_SEEK_SET, partialstart); + bis.setInputStream(fis); + + var sendContentType = parseQuery(request, "nomime"); + if (!sendContentType) { + var contentType = parseQuery(request, "type"); + if (!contentType) { + // This should not happen. + dump("No type specified without having 'nomime' in parameters."); + return; + } + response.setHeader("Content-Type", contentType, false); + } + response.setHeader("Content-Length", "" + bis.available(), false); + + var bytes = bis.readBytes(bis.available()); + response.write(bytes, bytes.length); + } catch (e) { + dump("ERROR : " + e + "\n"); + } +} diff --git a/dom/media/test/crashtests/0-timescale.html b/dom/media/test/crashtests/0-timescale.html new file mode 100644 index 0000000000..db845096dd --- /dev/null +++ b/dom/media/test/crashtests/0-timescale.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +</head> +<body> +<!-- This video file has a timescale of 0 in the mdhd atom --> +<video src="0-timescale.mp4" + autoplay + onerror="document.documentElement.className=undefined" + onloadedmetadata="this.src=''; document.documentElement.className=undefined"> +<!-- Note we reset 'src' to release decoder resources and cubeb streams to prevent OOM or OpenCubeb() failures. --> +</video> +</body> +</html> diff --git a/dom/media/test/crashtests/0-timescale.mp4 b/dom/media/test/crashtests/0-timescale.mp4 Binary files differnew file mode 100644 index 0000000000..32df5dc5a5 --- /dev/null +++ b/dom/media/test/crashtests/0-timescale.mp4 diff --git a/dom/media/test/crashtests/1012609.html b/dom/media/test/crashtests/1012609.html new file mode 100644 index 0000000000..1dad783a07 --- /dev/null +++ b/dom/media/test/crashtests/1012609.html @@ -0,0 +1,9 @@ +<script> +try{var r0=new AudioContext();}catch(e){} +try{var r32=r0.createOscillator();}catch(e){} +try{var r58=r0.createPeriodicWave(new Float32Array(1997),new Float32Array(1997));}catch(e){} +try{r32.start(0);}catch(e){} +try{r32.setPeriodicWave(r58);}catch(e){} +try{r32.frequency.value=-1;}catch(e){} +</script> + diff --git a/dom/media/test/crashtests/1015662.html b/dom/media/test/crashtests/1015662.html new file mode 100644 index 0000000000..20407c807d --- /dev/null +++ b/dom/media/test/crashtests/1015662.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<body> +<video><track src="javascript:5"></track></video> +</body> diff --git a/dom/media/test/crashtests/1028458.html b/dom/media/test/crashtests/1028458.html new file mode 100644 index 0000000000..bb01e3343a --- /dev/null +++ b/dom/media/test/crashtests/1028458.html @@ -0,0 +1,23 @@ +<html class="reftest-wait"> +<audio id="testAudio" controls></audio> +<script type="text/javascript"> +navigator.mozGetUserMedia({audio: true, fake: true}, function(stream) { + stream.getAudioTracks()[0].enabled = false; + var testAudio = document.getElementById('testAudio'); + // Wait some time for good measure + var eventReceived = 0; + testAudio.addEventListener("timeupdate", function() { + if (++eventReceived == 3) { + document.querySelector("html").className = ""; + } + }) + testAudio.srcObject = stream; + testAudio.play(); + }, function(err) { + // Don't go orange if we can't get an audio input stream, + // as this is not what we are trying to test and can happen on Windows. + document.querySelector("html").className = ""; + }); +</script> + +</html> diff --git a/dom/media/test/crashtests/1041466.html b/dom/media/test/crashtests/1041466.html new file mode 100644 index 0000000000..0f064d186c --- /dev/null +++ b/dom/media/test/crashtests/1041466.html @@ -0,0 +1,21 @@ +<html> +<script> +try{var Context1= new (window.webkitAudioContext || window.AudioContext)()}catch(e){} +try{var Delay0=Context1.createDelay();}catch(e){} +try{var ScriptProcessor0=Context1.createScriptProcessor(512,26,7);}catch(e){} +try{var ChannelSplitter0=Context1.createChannelSplitter(91);}catch(e){} +try{var Gain1=Context1.createGain();}catch(e){} +try{var WaveShaper0=Context1.createWaveShaper();}catch(e){} +try{var Analyser1=Context1.createAnalyser();}catch(e){} +try{Gain1.connect(Delay0);}catch(e){} +try{Analyser1.connect(BiquadFilter0);}catch(e){} +try{Gain1.connect(Context1.destination);}catch(e){} +try{WaveShaper0.connect(ScriptProcessor0);}catch(e){} +try{ChannelSplitter0.connect(BiquadFilter1);}catch(e){} +try{Delay0.connect(Gain1);}catch(e){} +try{ScriptProcessor0.connect(Context1.destination);}catch(e){} +try{WaveShaper0.connect(Gain1);}catch(e){} +try{WaveShaper0.connect(ChannelSplitter0);}catch(e){} +try{ScriptProcessor0.connect(WaveShaper0);}catch(e){} +</script> +</html> diff --git a/dom/media/test/crashtests/1045650.html b/dom/media/test/crashtests/1045650.html new file mode 100644 index 0000000000..32acd2ce75 --- /dev/null +++ b/dom/media/test/crashtests/1045650.html @@ -0,0 +1,18 @@ +<html><body><script> + +var r0=new AudioContext(); + +var splitter=r0.createChannelSplitter(); +var delay=r0.createDelay(); +var scriptp=r0.createScriptProcessor(); +var cmerger=r0.createChannelMerger(); +var gain=r0.createGain(); + +splitter.connect(delay,2); +delay.connect(scriptp); +scriptp.connect(cmerger); +cmerger.connect(splitter); +gain.connect(gain); +gain.connect(cmerger); + +</script></body></html> diff --git a/dom/media/test/crashtests/1080986.html b/dom/media/test/crashtests/1080986.html new file mode 100644 index 0000000000..1de3075169 --- /dev/null +++ b/dom/media/test/crashtests/1080986.html @@ -0,0 +1,3 @@ +<html> +<audio autoplay src="1080986.wav"></audio> +</html> diff --git a/dom/media/test/crashtests/1080986.wav b/dom/media/test/crashtests/1080986.wav Binary files differnew file mode 100644 index 0000000000..b96c59b7ec --- /dev/null +++ b/dom/media/test/crashtests/1080986.wav diff --git a/dom/media/test/crashtests/1122218.html b/dom/media/test/crashtests/1122218.html new file mode 100644 index 0000000000..984487dd21 --- /dev/null +++ b/dom/media/test/crashtests/1122218.html @@ -0,0 +1,24 @@ +<html> +<head> +<script> +function boom() { + var r0=new AudioContext(); + + var cm=r0.createChannelMerger(20); + + var o1=r0.createOscillator(); + var o2=r0.createOscillator(); + + var pw=r0.createPeriodicWave(new Float32Array(4),new Float32Array(4)); + o2.setPeriodicWave(pw); + + o1.connect(cm); + cm.connect(o2.frequency); + + o1.start(); + o2.start(0.476); +} +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/1127188.html b/dom/media/test/crashtests/1127188.html new file mode 100644 index 0000000000..650f07dd47 --- /dev/null +++ b/dom/media/test/crashtests/1127188.html @@ -0,0 +1,3 @@ +<script> + (new AudioContext).close(); +</script> diff --git a/dom/media/test/crashtests/1157994.html b/dom/media/test/crashtests/1157994.html new file mode 100644 index 0000000000..2e3001302a --- /dev/null +++ b/dom/media/test/crashtests/1157994.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + var ac = new AudioContext(); + // first "suspended" -> "running" transition + ac.onstatechange = function() { + ac.onstatechange = null; + ac.suspend(); + ac.close(); + } +} + +</script> +</head> +<body onload="boom();"></body> +</html> + diff --git a/dom/media/test/crashtests/1158427.html b/dom/media/test/crashtests/1158427.html new file mode 100644 index 0000000000..b544a942a1 --- /dev/null +++ b/dom/media/test/crashtests/1158427.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + dump("before capture\n"); + document.createElement("audio").mozCaptureStreamUntilEnded(); + dump("before context\n"); + new window.AudioContext(); + dump("before gc\n"); + SpecialPowers.forceCC(); + dump("after gc\n"); +} + +</script> +</head> +<body onload="boom();"></body> +</html> + diff --git a/dom/media/test/crashtests/1180881.html b/dom/media/test/crashtests/1180881.html new file mode 100644 index 0000000000..d5bf2f5642 --- /dev/null +++ b/dom/media/test/crashtests/1180881.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<head> +</head> +<body> +<video src="1180881.webm" autoplay></video> +</body> +</html> diff --git a/dom/media/test/crashtests/1180881.webm b/dom/media/test/crashtests/1180881.webm Binary files differnew file mode 100644 index 0000000000..2fb2be7a7f --- /dev/null +++ b/dom/media/test/crashtests/1180881.webm diff --git a/dom/media/test/crashtests/1185176.html b/dom/media/test/crashtests/1185176.html new file mode 100644 index 0000000000..d5e9b68a29 --- /dev/null +++ b/dom/media/test/crashtests/1185176.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> + +function boom() +{ + var ac = new window.AudioContext(); + var oscillator = ac.createOscillator(); + oscillator.start(0); + oscillator.stop(0.1); + setTimeout(function() { + oscillator.channelCount = 1; + oscillator.channelCountMode = "explicit"; + oscillator.channelInterpretation = "speakers"; + document.documentElement.removeAttribute("class"); + }, 1000); +} + +</script> +</head> +<body onload="boom();"></body> +</html> + diff --git a/dom/media/test/crashtests/1185191.html b/dom/media/test/crashtests/1185191.html new file mode 100644 index 0000000000..4ed5ba2ee2 --- /dev/null +++ b/dom/media/test/crashtests/1185191.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> + +function boom() +{ + var a = new AudioContext(); + var b = new BroadcastChannel("x"); + a.addEventListener("statechange", bye, false); +} + +function bye() +{ + document.documentElement.removeAttribute("class"); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/1185192.html b/dom/media/test/crashtests/1185192.html new file mode 100644 index 0000000000..46fa311aa2 --- /dev/null +++ b/dom/media/test/crashtests/1185192.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + new Audio().mozCaptureStreamUntilEnded(); + var ac = new window.AudioContext(); + ac.resume(); + ac.close(); +} + +</script> +</head> +<body onload="boom();"></body> +</html> + diff --git a/dom/media/test/crashtests/1197935.html b/dom/media/test/crashtests/1197935.html new file mode 100644 index 0000000000..dd8ad0382d --- /dev/null +++ b/dom/media/test/crashtests/1197935.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<head> +</head> +<body> +<video src="1197935.mp4" autoplay></video> +</body> +</html> diff --git a/dom/media/test/crashtests/1197935.mp4 b/dom/media/test/crashtests/1197935.mp4 Binary files differnew file mode 100644 index 0000000000..f00de75627 --- /dev/null +++ b/dom/media/test/crashtests/1197935.mp4 diff --git a/dom/media/test/crashtests/1223670.html b/dom/media/test/crashtests/1223670.html new file mode 100644 index 0000000000..94cad43e23 --- /dev/null +++ b/dom/media/test/crashtests/1223670.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> + +function boom() +{ + + var ac = new window.AudioContext("publicnotification"); + + setTimeout(function() { + document.documentElement.removeAttribute("class"); + var htmlAudio = new Audio(); + var stream = htmlAudio.mozCaptureStreamUntilEnded(); + ac.createMediaStreamSource(stream); + }, 0); +} + +</script> +</head> +<body onload="boom();"> +</body> +</html> diff --git a/dom/media/test/crashtests/1236639.html b/dom/media/test/crashtests/1236639.html new file mode 100644 index 0000000000..5c4634a4d4 --- /dev/null +++ b/dom/media/test/crashtests/1236639.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<head> + <title>Bug 1236639: Crash on audio playback due to invalid XING headers</title> +</head> +<body> +<audio autoplay src="1236639.mp3"></audio> +</body> +</html> diff --git a/dom/media/test/crashtests/1236639.mp3 b/dom/media/test/crashtests/1236639.mp3 Binary files differnew file mode 100644 index 0000000000..8ef96e8cc7 --- /dev/null +++ b/dom/media/test/crashtests/1236639.mp3 diff --git a/dom/media/test/crashtests/1257700.html b/dom/media/test/crashtests/1257700.html new file mode 100644 index 0000000000..5377b17da5 --- /dev/null +++ b/dom/media/test/crashtests/1257700.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<head> +</head> +<body> +<video src="1257700.webm" autoplay></video> +</body> +</html> diff --git a/dom/media/test/crashtests/1257700.webm b/dom/media/test/crashtests/1257700.webm Binary files differnew file mode 100644 index 0000000000..63e53c8c0a --- /dev/null +++ b/dom/media/test/crashtests/1257700.webm diff --git a/dom/media/test/crashtests/1267263.html b/dom/media/test/crashtests/1267263.html new file mode 100644 index 0000000000..a4d0e621cd --- /dev/null +++ b/dom/media/test/crashtests/1267263.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + vid.setMediaKeys(null); + vid.fastSeek(111); +} + +</script> +</head> + +<body onload="boom();"> + <video id="vid" src="../../../../layout/reftests/webm-video/frames.webm"></video> +</body> +</html> diff --git a/dom/media/test/crashtests/1270303.html b/dom/media/test/crashtests/1270303.html new file mode 100644 index 0000000000..23608bb2b8 --- /dev/null +++ b/dom/media/test/crashtests/1270303.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<head> +</head> +<body> +<video src="1270303.webm" autoplay></video> +</body> +</html> diff --git a/dom/media/test/crashtests/1270303.webm b/dom/media/test/crashtests/1270303.webm Binary files differnew file mode 100644 index 0000000000..c9b0003d6b --- /dev/null +++ b/dom/media/test/crashtests/1270303.webm diff --git a/dom/media/test/crashtests/1291702.html b/dom/media/test/crashtests/1291702.html new file mode 100644 index 0000000000..54f17b45b8 --- /dev/null +++ b/dom/media/test/crashtests/1291702.html @@ -0,0 +1,72 @@ +<script> +Logger={}; Logger.JSError=function(e){}; +try { o0 = new Audio("media/audio/mono-uncompressed-8bit-44100hz.wav") } catch(e) { Logger.JSError(e); } +try { o1 = o0.mozCaptureStreamUntilEnded() } catch(e) { Logger.JSError(e); } +try { o2 = new window.AudioContext(); } catch(e) { Logger.JSError(e); } +try { o3 = o2.createBufferSource(); } catch(e) { Logger.JSError(e); } +try { o5 = o2.createChannelMerger(3); } catch(e) { Logger.JSError(e); } +try { o3.start(0) } catch(e) { Logger.JSError(e); } +try { o2.listener.setPosition(0.0417049336344248, 0.9932504594310304, 32) } catch(e) { Logger.JSError(e); } +try { o5.disconnect(0) } catch(e) { Logger.JSError(e); } +try { o0.mozGetMetadata() } catch(e) { Logger.JSError(e); } +try { o3.channelCount = 1; } catch(e) { Logger.JSError(e); } +try { o3.buffer = function anonymous() { +var buffer = o2.createBuffer(1, 512, o2.sampleRate);for(var c=0;c<1;c++) {var data = buffer.getChannelData(c);for(var i=0;i<512;i++) {data[i] = i % 512}}return buffer; +}(); } catch(e) { Logger.JSError(e); } +try { o3.loop = false; } catch(e) { Logger.JSError(e); } +try { o0.preservesPitch = false; } catch(e) { Logger.JSError(e); } +try { o2.destination.channelCount = 1; } catch(e) { Logger.JSError(e); } +try { o3.loopStart = 8; } catch(e) { Logger.JSError(e); } +try { o3.playbackRate.value = 0.46271130895770884; } catch(e) { Logger.JSError(e); } +try { o2.listener.setVelocity(0.34781960219792546, 4, 2048) } catch(e) { Logger.JSError(e); } +try { o5.connect(o5, 0, 0) } catch(e) { Logger.JSError(e); } +try { o3.loopStart = -0.24696638021780326; } catch(e) { Logger.JSError(e); } +try { o0.mozSetup(1, 44100) } catch(e) { Logger.JSError(e); } +try { o3.buffer.copyToChannel(function anonymous() { +var buffer=new Float32Array(256);for(var i=0;i<256;i++){buffer[i]=i / 256}return buffer; +}(), 1, 2048, 64) } catch(e) { Logger.JSError(e); } +try { o3.loop = false; } catch(e) { Logger.JSError(e); } +try { setInterval(function anonymous() { +try { o0.pause() } catch(e) { Logger.JSError(e); } +}, 12.902067779658143) } catch(e) { Logger.JSError(e); } +try { o2.listener.setPosition(256, 256, 16) } catch(e) { Logger.JSError(e); } +try { o3.playbackRate.setValueCurveAtTime(function anonymous() { +var buffer=new Float32Array(4);for(var i=0;i<4;i++){buffer[i]=i / 4}return buffer; +}(), 2, 0.40792575814014437) } catch(e) { Logger.JSError(e); } +try { o3.playbackRate.value = 0.4997270553139334; } catch(e) { Logger.JSError(e); } +try { o0.loop = true; } catch(e) { Logger.JSError(e); } +try { o3.loopStart = 4; } catch(e) { Logger.JSError(e); } +try { setInterval(function anonymous() { +try { o3.buffer = function anonymous() { +var buffer = o2.createBuffer(1, 1, o2.sampleRate);for(var c=0;c<1;c++) {var data = buffer.getChannelData(c);for(var i=0;i<1;i++) {data[i] = Math.sin(Math.sin(i))}}return buffer; +}() } catch(e) { Logger.JSError(e); } +}, 54.32078602859342) } catch(e) { Logger.JSError(e); } +try { o3.connect(o2.destination); } catch(e) { Logger.JSError(e); } +try { o3.channelCountMode = 'max'; } catch(e) { Logger.JSError(e); } +try { setInterval(function anonymous() { +try { o3.channelCount = 1; } catch(e) { Logger.JSError(e); } +}, 55.448587039802966) } catch(e) { Logger.JSError(e); } +try { o3.playbackRate.cancelScheduledValues(0.7190983131805198) } catch(e) { Logger.JSError(e); } +try { o3.playbackRate.cancelScheduledValues(16) } catch(e) { Logger.JSError(e); } +try { o3.connect(o5, 0, 2) } catch(e) { Logger.JSError(e); } +try { o3.loopEnd = 0.5864771678080962; } catch(e) { Logger.JSError(e); } +try { o0.playbackRate = 0.2781783298771312; } catch(e) { Logger.JSError(e); } +try { o0.loop = false; } catch(e) { Logger.JSError(e); } +try { setInterval(function anonymous() { +try { o5.disconnect(0) } catch(e) { Logger.JSError(e); } +}, 29.75776777646425) } catch(e) { Logger.JSError(e); } +try { o3.playbackRate.setValueCurveAtTime(function anonymous() { +var buffer=new Float32Array(8);for(var i=0;i<8;i++){buffer[i]=8 % 8}return buffer; +}(), 0.4972710112336257, 64) } catch(e) { Logger.JSError(e); } +try { setInterval(function anonymous() { +try { o0.controls = false; } catch(e) { Logger.JSError(e); } +}, 22.550249570567694) } catch(e) { Logger.JSError(e); } +try { o2.listener.setOrientation(0.6531494410366634, 64, 0.5120918081402992, -64, 0.32912433155093446, 256) } catch(e) { Logger.JSError(e); } +try { o3.loop = true; } catch(e) { Logger.JSError(e); } +try { o3.connect(o5, 0, 0) } catch(e) { Logger.JSError(e); } +try { o3.buffer = function anonymous() { +var buffer = o2.createBuffer(1, 2048, 48000);for(var c=0;c<1;c++) {var data = buffer.getChannelData(c);for(var i=0;i<2048;i++) {data[i] = Math.sin(Math.sin(2048 * 0.2519529190035427))}}return buffer; +}(); } catch(e) { Logger.JSError(e); } +try { o3.disconnect(0) } catch(e) { Logger.JSError(e); } +</script> + diff --git a/dom/media/test/crashtests/1368490.html b/dom/media/test/crashtests/1368490.html new file mode 100644 index 0000000000..8a2d9f9674 --- /dev/null +++ b/dom/media/test/crashtests/1368490.html @@ -0,0 +1,30 @@ +<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+ <title> Bug 1368490 : Crash if media recorder source stream reduces number of channels. </title>
+</head>
+<meta charset="utf-8">
+<script type="text/javascript">
+
+function boom() {
+ let audioContext = new window.AudioContext();
+ let oscillator = audioContext.createOscillator();
+ let dst = audioContext.createMediaStreamDestination();
+ oscillator.channelCount = 4;
+ dst.channelCount = 4;
+ oscillator.connect(dst, 0, 0);
+ oscillator.start();
+ mediaRec = new MediaRecorder(dst.stream);
+
+ mediaRec.start(100);
+ setTimeout(() => {
+ dst.channelCount = 1;
+ setTimeout(() => {
+ mediaRec.stop();
+ document.documentElement.removeAttribute("class");
+ }, 100);
+ }, 100);
+}
+</script>
+<body onload="boom();"></body>
+</html>
diff --git a/dom/media/test/crashtests/1378826.html b/dom/media/test/crashtests/1378826.html new file mode 100644 index 0000000000..e1913cd0f5 --- /dev/null +++ b/dom/media/test/crashtests/1378826.html @@ -0,0 +1,46 @@ +<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<title>Bug 1378826 : Removing last video track from recorder stream crashes.</title>
+</head>
+<body>
+<canvas id="canvas"></canvas>
+<script type="text/javascript">
+
+function wait(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
+
+function boom() {
+ let canvas = document.getElementById("canvas");
+ let ctx = canvas.getContext('2d');
+ ctx.fillRect(10, 10, 100, 100);
+ let stream = canvas.captureStream();
+ let rec = new MediaRecorder(stream);
+ // At the time of fixing this bug onstop would fire, but this may change in
+ // future. As such defensively listen for onerror too to prevent this test
+ // timing out.
+ let stoppedPromise = new Promise(y => (rec.onstop = y,
+ rec.onerror = e => y));
+ rec.onstart = () => {
+ // Remove the video track from the stream we're recording
+ stream.removeTrack(stream.getTracks()[0]);
+ // Recorder should stop or error in response to the above
+ return stoppedPromise
+ .then(() => {
+ // Little wait to help get bad writes if they're going to happen
+ wait(100)
+ .then(() => {
+ // Didn't crash, finish
+ document.documentElement.removeAttribute("class");
+ });
+ });
+ };
+ rec.start();
+}
+
+window.onload = boom;
+
+</script>
+</body>
+</html>
diff --git a/dom/media/test/crashtests/1384248.html b/dom/media/test/crashtests/1384248.html new file mode 100644 index 0000000000..5d9c60edda --- /dev/null +++ b/dom/media/test/crashtests/1384248.html @@ -0,0 +1,10 @@ +<html> + <head> + <script> + try { o1 = document.createElement('audio') } catch(e) { } + try { o2 = document.implementation.createDocument('', '', null).adoptNode(o1); } catch(e) { }; + try { o3 = new AudioContext('alarm') } catch(e) { } + try { o3.createMediaElementSource(o1) } catch(e) { } + </script> + </head> +</html> diff --git a/dom/media/test/crashtests/1388372.html b/dom/media/test/crashtests/1388372.html new file mode 100644 index 0000000000..977ebddf53 --- /dev/null +++ b/dom/media/test/crashtests/1388372.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +navigator.mediaDevices.getUserMedia({audio: { + echoCancellation: false, + noiseSuppression: false, + autoGainControl: false + }, fake: true +}).then((stream) => { + document.documentElement.removeAttribute("class"); +}) +</script> +</html> diff --git a/dom/media/test/crashtests/1389304.html b/dom/media/test/crashtests/1389304.html new file mode 100644 index 0000000000..df419c51d7 --- /dev/null +++ b/dom/media/test/crashtests/1389304.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: Negative duration.</title> +</head> +<body> + +<video id="v" controls src="1389304.mp4"> +</video> +<p id="msg"></p> + +<script type="text/javascript"> + +function log(x) { + msg.innerHTML = x + "<br>"; +} + +v.play(); +v.onended = function() { + log("endded!"); + let seekable = v.seekable; + for (let i = 0; i < seekable.length; ++i) { + let start = seekable.start(i); + let end = seekable.end(i); + log(`[${i}]: start=${start} end=${end}`); + } +} + +</script> + +</body> +</html> diff --git a/dom/media/test/crashtests/1389304.mp4 b/dom/media/test/crashtests/1389304.mp4 Binary files differnew file mode 100644 index 0000000000..25cd746972 --- /dev/null +++ b/dom/media/test/crashtests/1389304.mp4 diff --git a/dom/media/test/crashtests/1393272.webm b/dom/media/test/crashtests/1393272.webm Binary files differnew file mode 100644 index 0000000000..1f1cade6dc --- /dev/null +++ b/dom/media/test/crashtests/1393272.webm diff --git a/dom/media/test/crashtests/1411322.html b/dom/media/test/crashtests/1411322.html new file mode 100644 index 0000000000..772b68f0cc --- /dev/null +++ b/dom/media/test/crashtests/1411322.html @@ -0,0 +1,18 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 1411322: Shutdown after getting memory reports from MediaRecorder</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<audio id="audio"></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +let recorder = new MediaRecorder(audio.mozCaptureStream()); +recorder.start(); +SpecialPowers.getMemoryReports(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/crashtests/1414444.mp4 b/dom/media/test/crashtests/1414444.mp4 Binary files differnew file mode 100644 index 0000000000..4041852100 --- /dev/null +++ b/dom/media/test/crashtests/1414444.mp4 diff --git a/dom/media/test/crashtests/1450845.html b/dom/media/test/crashtests/1450845.html new file mode 100644 index 0000000000..451d116e83 --- /dev/null +++ b/dom/media/test/crashtests/1450845.html @@ -0,0 +1,34 @@ +<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+ <title>Bug 1450845: Avoid seek to next frame when already seeking</title>
+ <script>
+ async function boom() {
+ let video = document.getElementById('video');
+
+ // Internally play causes a seek, make sure we don't crash during this
+ video.play();
+ try {
+ await document.getElementById('video').seekToNextFrame();
+ } catch (e) {
+ // We don't mind if the promise was rejected so long as we don't crash
+ }
+ // Didn't crash
+
+ // Stop playback and cause a seek to 0
+ video.pause();
+ video.currentTime = 0;
+ try {
+ await document.getElementById('video').seekToNextFrame();
+ } finally {
+ // Didn't crash
+ document.documentElement.removeAttribute("class");
+ }
+ }
+ window.addEventListener('load', boom)
+ </script>
+</head>
+<body>
+ <video id='video' src='data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBQoWBAhhTgGcBAAAAAAAB6BFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEwTbuMU6uEHFO7a1OsggHL7AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEUqTYCNTGF2ZjU3LjI5LjEwMVdBjUxhdmY1Ny4yOS4xMDFzpJBAb17Yv2oNAF1ZEESuco33RImIQFCAAAAAAAAWVK5rAQAAAAAAADyuAQAAAAAAADPXgQFzxYEBnIEAIrWcg3VuZIaFVl9WUDmDgQEj44OEAfygVeABAAAAAAAAB7CCAUC6gfAfQ7Z1AQAAAAAAAEfngQCjqYEAAICCSYNCABPwDvYAOCQcGFQAAFBh9jAAABML7AAATEnjdRwIJ+gAo5eBACEAhgBAkpwATEAABCasAABekcXgAB'>
+</body>
+</html>
diff --git a/dom/media/test/crashtests/1489160.html b/dom/media/test/crashtests/1489160.html new file mode 100644 index 0000000000..c4f643700c --- /dev/null +++ b/dom/media/test/crashtests/1489160.html @@ -0,0 +1,10 @@ +<html> +<head> +<script> +audio = new AudioContext() +audio.close() +audio.close() +</script> +</head> +</html> + diff --git a/dom/media/test/crashtests/1494073.html b/dom/media/test/crashtests/1494073.html new file mode 100644 index 0000000000..41e7a36554 --- /dev/null +++ b/dom/media/test/crashtests/1494073.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title>Bug 1494073: Setting playback rate too high</title> + <script> + function finish() { + document.documentElement.removeAttribute("class"); + } + var src="data:audio/wav;base64,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" + var audio=new Audio(src) + audio.onended = finish; + audio.onerror = finish; + try{audio.play()}catch(e){} + try{audio.preload=1}catch(e){} + try{audio.muted=1}catch(e){} + try{audio.playbackRate=567312.2079031984}catch(e){} + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/1517199.html b/dom/media/test/crashtests/1517199.html new file mode 100644 index 0000000000..10c994f845 --- /dev/null +++ b/dom/media/test/crashtests/1517199.html @@ -0,0 +1,17 @@ +<html class="reftest-wait"> +<head> +<script> +(async _ => { + const video = document.createElement("video"); + video.mozCaptureStreamUntilEnded(); + video.src = "test.mp4"; + video.playbackRate = 2; + await new Promise(r => video.onloadedmetadata = r); + video.currentTime = video.duration - 1; + await video.play(); + await new Promise(r => video.onended = r); + document.documentElement.removeAttribute("class"); +})(); +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/1526044.html b/dom/media/test/crashtests/1526044.html new file mode 100644 index 0000000000..1914dfc2f5 --- /dev/null +++ b/dom/media/test/crashtests/1526044.html @@ -0,0 +1,19 @@ +<script> + function start () { + try { o1 = new AudioContext({}) } catch (e) { } + try { o2 = new DynamicsCompressorNode(o1, {}) } catch (e) { } + try { o3 = o2.attack } catch (e) { } + try { o4 = new XMLHttpRequest({mozAnon: true, mozSystem: true}) } catch (e) { } + try { o4.open('GET', '', false) } catch (e) { } + try { o4.send() } catch (e) { } + for (let i = 0; i < 20; i++) { + try { o5 = o1.createGain() } catch (e) { } + try { o1.suspend().then(function () { }) } catch (e) { } + try { o5.connect(o3) } catch (e) { } + } + setTimeout('location.reload()', 200) + } + + window.addEventListener('load', start) +</script> + diff --git a/dom/media/test/crashtests/1530897.webm b/dom/media/test/crashtests/1530897.webm Binary files differnew file mode 100644 index 0000000000..ac2224157a --- /dev/null +++ b/dom/media/test/crashtests/1530897.webm diff --git a/dom/media/test/crashtests/1538727.html b/dom/media/test/crashtests/1538727.html new file mode 100644 index 0000000000..6371d54383 --- /dev/null +++ b/dom/media/test/crashtests/1538727.html @@ -0,0 +1,14 @@ +<script> +const canvas = document.createElement('canvas') +const context = canvas.getContext('2d', {}) +const xhr = new XMLHttpRequest({}) +const stream = canvas.captureStream(new Float64Array([1593177632.1689904])[0]) +recorder = new MediaRecorder(stream) +recorder.start(100) +xhr.open('G', '', false) +xhr.send() +recorder.stop() +tracks = stream.getVideoTracks() +track = tracks[(1051736525 % tracks.length)] +stream.removeTrack(track) +</script> diff --git a/dom/media/test/crashtests/1545133.html b/dom/media/test/crashtests/1545133.html new file mode 100644 index 0000000000..fb7039aae3 --- /dev/null +++ b/dom/media/test/crashtests/1545133.html @@ -0,0 +1,34 @@ +<html class="reftest-wait"> +<head> +<script> +const xhr = new XMLHttpRequest() + +async function boom () { + await new Promise(r => setTimeout(r, 100)) + + SpecialPowers.forceCC() + SpecialPowers.forceCC() + SpecialPowers.forceCC() + + document.documentElement.removeAttribute("class") +} + +function start () { + const context = new AudioContext({}) + const filter = new BiquadFilterNode(context, {}) + const destination = context.createMediaStreamDestination() + const processor = context.createScriptProcessor(8192, 8, 8) + processor.connect(filter.Q) + processor.disconnect() + xhr.open('G', '', false) + xhr.send() + context.createMediaStreamSource(destination.stream) + processor.connect(filter.Q) + context.close() + context.addEventListener('statechange', boom, true) +} + +document.addEventListener('DOMContentLoaded', start) +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/1547784.html b/dom/media/test/crashtests/1547784.html new file mode 100644 index 0000000000..ee270491f1 --- /dev/null +++ b/dom/media/test/crashtests/1547784.html @@ -0,0 +1,33 @@ +<html class="reftest-wait"> +<head> + <script> + const doc = new Document(); + const video = document.createElementNS('http://www.w3.org/1999/xhtml', 'video'); + const source = new MediaSource(); + + navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{ '': [{ '': '' }] }]) + .then(keySystemAccess => { + return keySystemAccess.createMediaKeys(); + }).then(_ => { + video.src = URL.createObjectURL(source); + source.addEventListener('sourceopen', () => { + doc.adoptNode(video); + }); + }); + + navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{ '': [{ '': '' }] }]) + .then(keySystemAccess => { + return keySystemAccess.createMediaKeys(); + }).then(mediaKeys => { + return video.setMediaKeys(mediaKeys); + }).then(() => { + video.src = URL.createObjectURL(source); + document.documentElement.removeAttribute("class"); + }).catch(e => { + // Catch JS errors caused by raciness in the test. So long as we're + // not crashing we're good. + document.documentElement.removeAttribute("class"); + }); + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/1547899.html b/dom/media/test/crashtests/1547899.html new file mode 100644 index 0000000000..4ffd90c565 --- /dev/null +++ b/dom/media/test/crashtests/1547899.html @@ -0,0 +1,20 @@ +<html> +<head> + <script> + function start () { + const video = document.getElementById('id_0') + const stream_1 = new MediaStream() + const stream_2 = video.mozCaptureStreamUntilEnded() + const track = stream_2.getTracks()[0] + + video.srcObject = stream_1 + stream_1.addTrack(track) + } + + window.addEventListener('load', start) + </script> +</head> +<body> +<video id="id_0" src="data:audio/mpeg;base64,ZQr/+1DEAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAAAsAAAnKABcXFxcXFxcXFy4uLi4uLi4uLkVFRUVFRUVFRV1dXV1dXV1dXXR0dHR0dHR0dIuLi4uLi4uLi6KioqKioqKiorq6urq6urq6utHR0dHR0dHR0ejo6Ojo6Ojo6P///////////wAAADlMQU1FMy45OHIBpQAAAAAuHQAAFEAkBElCAABAAAAJyuGI2MQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//tQxAAABmQjXHSRAAH6IfB3OVIDAADLlmjIxWKxWTyIABgmGydGjRox4f8Tg+D4OAgc/BwEDn+UBD+qwH/+8Tny7///KO4IYDgcDgcDgcDgcCgQAAAKKBUFc/nnP30a5O0zyYzMNMkzKlPva2GXgMIBbwDQEAYDQNXGLT2EIgEhoFnQNDb4BAPD9wTFYGJBWJw/8AUWgMBQgIEg4KmAKGP/wRG0csCIWDaQxcFhYvv/8WYMUpEIkXhvnRef//kmsuLPH5OvSoAFKxrJIm26DP/7UsQ"> +</body> +</html> diff --git a/dom/media/test/crashtests/1560215.html b/dom/media/test/crashtests/1560215.html new file mode 100644 index 0000000000..1b76e218d7 --- /dev/null +++ b/dom/media/test/crashtests/1560215.html @@ -0,0 +1,20 @@ +<html class="reftest-wait"> +<head> + <script> + async function start () { + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + context.fillStyle = "red" + context.fillRect(0, 0, 1, 1) + const recorder = new MediaRecorder( + canvas.captureStream(), { videoBitsPerSecond: 16 }) + recorder.start(100) + await new Promise(r => recorder.onstart = r) + recorder.pause() + document.documentElement.removeAttribute("class") + } + + window.addEventListener('load', start) + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/1569645.html b/dom/media/test/crashtests/1569645.html new file mode 100644 index 0000000000..b1f1247f26 --- /dev/null +++ b/dom/media/test/crashtests/1569645.html @@ -0,0 +1,23 @@ +<html> +<head> + <script> + function start () { + const canvas = document.getElementById("c") + canvas.getContext("2d") + const video = canvas.captureStream() + const ac = new AudioContext() + const dest = ac.createMediaStreamDestination() + const recorder = new MediaRecorder( + new MediaStream([...video.getTracks(), ...dest.stream.getTracks()]), { + 'mimeType': 'audio/ogg' + }) + recorder.start() + } + + window.addEventListener('load', start) + </script> +</head> +<body> +<canvas id="c"></canvas> +</body> +</html> diff --git a/dom/media/test/crashtests/1575271.html b/dom/media/test/crashtests/1575271.html new file mode 100644 index 0000000000..ceda986553 --- /dev/null +++ b/dom/media/test/crashtests/1575271.html @@ -0,0 +1,25 @@ +<html class="reftest-wait"> +<head> +<script> + async function start () { + const canvas = document.createElement("canvas") + const context = canvas.getContext("2d") + context.fillStyle = "blue" + context.fillRect(0, 0, canvas.width, canvas.height) + const stream = canvas.captureStream() + const track = stream.getTracks()[0] + const recorder = new MediaRecorder(stream) + recorder.start() + await new Promise(r => recorder.onstart = r) + recorder.pause() + stream.removeTrack(track) + recorder.resume() + await new Promise(r => recorder.onstop = r) + document.documentElement.removeAttribute("class") + } + + window.addEventListener('load', start) +</script> +</head> +</html> + diff --git a/dom/media/test/crashtests/1577184.html b/dom/media/test/crashtests/1577184.html new file mode 100644 index 0000000000..a38c4a1265 --- /dev/null +++ b/dom/media/test/crashtests/1577184.html @@ -0,0 +1,15 @@ +<html> +<head> +<script> +function start () { + const frame = document.createElementNS('http://www.w3.org/1999/xhtml', 'frame') + document.documentElement.appendChild(frame) + frame.contentWindow.eval('window.top.context=new AudioContext()') + document.documentElement.innerHTML = '' + context.createMediaElementSource(new Audio('')) +} + +document.addEventListener('DOMContentLoaded', start) +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/1587248.html b/dom/media/test/crashtests/1587248.html new file mode 100644 index 0000000000..10c555e2b1 --- /dev/null +++ b/dom/media/test/crashtests/1587248.html @@ -0,0 +1,23 @@ +<html class="reftest-wait"> +<head> +<script> +function start () { + const audio = document.getElementById('id_4') + const doc = new Document() + const stream = new MediaStream() + const track = document.createElementNS('http://www.w3.org/1999/xhtml', 'track') + audio.srcObject = stream + track.textContent = '�' + setTimeout(() => { + track.replaceChild(audio, track.childNodes[0]) + audio.play().then(function (arg4) { }) + document.documentElement.removeAttribute("class") + }, 157) + doc.adoptNode(audio) +} + +document.addEventListener('DOMContentLoaded', start) +</script> +</head> +<audio class="" id="id_4" itemscope></audio> +</html> diff --git a/dom/media/test/crashtests/1594466.html b/dom/media/test/crashtests/1594466.html new file mode 100644 index 0000000000..276c5fe3d1 --- /dev/null +++ b/dom/media/test/crashtests/1594466.html @@ -0,0 +1,22 @@ +<html> +<head> +<script> +function start() { + const ac = new AudioContext(); + const {stream: audioStream} = ac.createMediaStreamDestination(); + const [audioTrack] = audioStream.getTracks(); + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + const [videoTrack] = canvas.captureStream().getTracks(); + + const rec = new MediaRecorder(new MediaStream([audioTrack, videoTrack]), { + mimeType: 'video/webm; codecs="vp8, opus"' + }); + rec.start(); +} + +document.addEventListener('DOMContentLoaded', start) +</script> +</head> +</html> + diff --git a/dom/media/test/crashtests/1601385.html b/dom/media/test/crashtests/1601385.html new file mode 100644 index 0000000000..7192809076 --- /dev/null +++ b/dom/media/test/crashtests/1601385.html @@ -0,0 +1,12 @@ +<html> +<head> +<script> +const video = document.createElement("video"); +video.srcObject = new MediaStream(); +video.mozCaptureStreamUntilEnded(); +video.src = "sound.ogg"; +video.srcObject = undefined; +</script> +</head> +</html> + diff --git a/dom/media/test/crashtests/1601422.html b/dom/media/test/crashtests/1601422.html new file mode 100644 index 0000000000..9ff3c1a07a --- /dev/null +++ b/dom/media/test/crashtests/1601422.html @@ -0,0 +1,20 @@ +<html class="reftest-wait"> +<head> +<script> +(async _ => { + try { + const video = document.createElement('video') + video.preload = 'metadata' + video.src = 'sound.ogg' + await new Promise(r => video.onloadedmetadata = r) + const stream_1 = video.mozCaptureStreamUntilEnded() + video.src = '' + const stream_2 = video.mozCaptureStreamUntilEnded() + } finally { + document.documentElement.removeAttribute("class") + } +})() +</script> +</head> +</html> + diff --git a/dom/media/test/crashtests/1604941.html b/dom/media/test/crashtests/1604941.html new file mode 100644 index 0000000000..5a9265ea1b --- /dev/null +++ b/dom/media/test/crashtests/1604941.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> + +async function boom() +{ + await SpecialPowers.pushPrefEnv({"set": [ + ["media.cubeb.force_null_context", true], + ]}); + new Audio().mozCaptureStreamUntilEnded(); + var ac = new window.AudioContext(); + ac.resume(); + ac.close(); + document.documentElement.removeAttribute("class"); +} + +</script> +</head> +<body onload="boom();"></body> +</html> + diff --git a/dom/media/test/crashtests/1608286.html b/dom/media/test/crashtests/1608286.html new file mode 100644 index 0000000000..9f52605be6 --- /dev/null +++ b/dom/media/test/crashtests/1608286.html @@ -0,0 +1,50 @@ +<html class="reftest-wait">
+<head>
+ <script>
+ function test() {
+ function checkResolve(value) {
+ // Let the test timeout and fail
+ throw new Error("This promise should not resolve");
+ }
+
+ function checkReject(reason) {
+ if (reason.message !== "Browsing context is no longer available") {
+ // Let the test timeout and fail
+ throw new Error("Unexpected rejected promise reason");
+ }
+ // Otherwise, successfully rejected a request not attached to a
+ // window without crashing
+ }
+
+ var i = document.querySelector("iframe");
+ var nav = i.contentWindow.navigator;
+ i.remove();
+
+ // First, check with valid args
+ nav.requestMediaKeySystemAccess(
+ "com.widevine.alpha",
+ [{
+ initDataTypes: ["webm"],
+ videoCapabilities: [{ contentType: 'video/webm; codecs="vp9"' }]
+ }]
+ ).then(
+ checkResolve,
+ (reason) => {
+ checkReject(reason);
+
+ // Then, check with invalid args
+ nav.requestMediaKeySystemAccess("", []).then(
+ checkResolve,
+ (reason) => {
+ checkReject(reason);
+ document.documentElement.removeAttribute("class");
+ }
+ );
+ });
+ }
+ </script>
+</head>
+<body onload="test()">
+ <iframe></iframe>
+</body>
+</html>
diff --git a/dom/media/test/crashtests/1673525.html b/dom/media/test/crashtests/1673525.html new file mode 100644 index 0000000000..51de202999 --- /dev/null +++ b/dom/media/test/crashtests/1673525.html @@ -0,0 +1,15 @@ +<html> +<head> + <script> + document.addEventListener("DOMContentLoaded", () => { + const audio = document.getElementById("audio"); + audio.autoplay = true; + audio.mozCaptureStream(); + }) + </script> +</head> +<body> + <!-- The data URL is crafted from a fuzzed mp3 so the base64 can be decoded back to an mp3 as needed --> + <audio id="audio" src="data:audio/mpeg;base64,//tQxAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAALAAAJygAXFxcXFxcXFxcuLi4uLi4uLi5FRUVFRUVFRUVdXV1dXV1dXV10dHR0dHR0dHSLi4uLi4uLi4uioqKioqKioqK6urq6urq6urrR0dHR0dHR0dHo6Ojo6Ojo6Oj///////////8AAAA5TEFNRTMuOThyAaUAAAAALh0AABRAJARJQgAAQAAACcrhiNjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7UMQAAAZkI1x0kQAB+iHwdzlSAwAAy5ZoyMVisVk8iAAYJhsnRo0aMeH/E4Pg+DgIHPwcBA5/lAQ/qsB//vE58u///yjuCGA4HA4HA4HA4HAoEAAACigVBXP55z99GuTtM8mMzDTJMypT72thl4DCAW8A0BAGA0DVxi09hCIBIaBZ0DQ2+AQDw/cExWBiQVicP/AFFoDAUICBIOCpgChj/8ERtHLAiFg2kMXBYWL7//FmDFKRCJF4b50Xn//5JrLizx+Tr0qABSsaySJtugz/+1LEBIALgQmLvLUAMXkorjzSjuWd/+FbPOduga79Dhef0OFYNhp+FEPDPRyRvOEERl/Uwbv9F/UuQN5yt9WPM5xwqlB4+hzmfmoYmcceWPD8s3WA8FhYEPkhR0SgMHw="></audio> +</body> +</html> diff --git a/dom/media/test/crashtests/1673526-1.html b/dom/media/test/crashtests/1673526-1.html new file mode 100644 index 0000000000..925dbae6ab --- /dev/null +++ b/dom/media/test/crashtests/1673526-1.html @@ -0,0 +1,20 @@ +<html> +<head> +<script> +window.addEventListener('load', async () => { + const frame = document.createElement('frame') + document.documentElement.appendChild(frame) + const pc = new RTCPeerConnection({}) + await pc.createOffer({ 'offerToReceiveAudio': true }) + const [{receiver}] = pc.getTransceivers() + const track = pc.addTrack(receiver.track) + pc.removeTrack(track) + const [track2] = (await frame.contentWindow.navigator.mediaDevices.getUserMedia({ + 'audio': {}, + 'fake': true + })).getTracks() + pc.addTrack(track2) +}) +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/1673526-2.html b/dom/media/test/crashtests/1673526-2.html new file mode 100644 index 0000000000..ddae9520fc --- /dev/null +++ b/dom/media/test/crashtests/1673526-2.html @@ -0,0 +1,20 @@ +<html> +<head> +<script> +window.addEventListener('load', async () => { + const frame = document.createElement('frame') + document.documentElement.appendChild(frame) + const pc = new RTCPeerConnection({}) + await pc.createOffer({ 'offerToReceiveAudio': true }) + const [{sender, receiver}] = pc.getTransceivers() + await sender.replaceTrack(receiver.track) + await sender.replaceTrack(null) + const stream = await frame.contentWindow.navigator.mediaDevices.getUserMedia({ + 'audio': {}, + 'fake': true + }) + await sender.replaceTrack(stream.getTracks()[0]) +}) +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/1693043.html b/dom/media/test/crashtests/1693043.html new file mode 100644 index 0000000000..f73323bbd7 --- /dev/null +++ b/dom/media/test/crashtests/1693043.html @@ -0,0 +1,21 @@ +<html class="reftest-wait"> +<head> +<script> +async function boom() { + const audio = document.createElement("audio"); + audio.preload = "metadata"; + audio.src = "sound.ogg"; + await new Promise(r => audio.onloadedmetadata = r); + const s = audio.mozCaptureStream(); + const recorder = new MediaRecorder( + new MediaStream(s.getTracks()), + { audioBitsPerSecond: 3994678619 } + ); + recorder.start(); + document.documentElement.removeAttribute("class"); +} +</script> +</head> +<body onload="boom()"> +</body> +</html> diff --git a/dom/media/test/crashtests/1696511.html b/dom/media/test/crashtests/1696511.html new file mode 100644 index 0000000000..de66fa3a67 --- /dev/null +++ b/dom/media/test/crashtests/1696511.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html class='reftest-wait'> +<head> +<script> +document.addEventListener('DOMContentLoaded', async () => { + const canvas = document.createElement('canvas') + canvas.height = 27530 + const context = canvas.getContext('2d') + context.strokeRect(5, 5, canvas.width - 5, canvas.height - 5) + const stream = canvas.captureStream() + const recorder = new MediaRecorder(stream) + recorder.start() + const stopped = new Promise(r => recorder.onstop = r) + await new Promise(r => setTimeout(r, 100)) + stream.getTracks().forEach(t => t.stop()) + await stopped + document.documentElement.removeAttribute("class") +}) +</script> +</head> +</html> + diff --git a/dom/media/test/crashtests/1697521.html b/dom/media/test/crashtests/1697521.html new file mode 100644 index 0000000000..b44c02e227 --- /dev/null +++ b/dom/media/test/crashtests/1697521.html @@ -0,0 +1,19 @@ +<html> +<head> +<script> +async function boom() { + const canvas = document.createElement("canvas"); + canvas.getContext("2d"); + const recorder = new MediaRecorder(new MediaStream([ + ...canvas.captureStream().getTracks(), + ...canvas.captureStream().getTracks(), + ])); + recorder.start(); + recorder.requestData(); +} +</script> +</head> +<body onload="boom()"> +</body> +</html> + diff --git a/dom/media/test/crashtests/1708790.html b/dom/media/test/crashtests/1708790.html new file mode 100644 index 0000000000..ee97a31c81 --- /dev/null +++ b/dom/media/test/crashtests/1708790.html @@ -0,0 +1,22 @@ +<html class="reftest-wait"> +<head> +<script> +(async _ => { + try { + const audio = document.createElement('audio'); + audio.src = 'sound.ogg'; + const ac = new AudioContext(); + const src = ac.createMediaElementSource(audio); + src.connect(ac.destination); + await audio.play(); + audio.pause(); + audio.volume = 0.5; + audio.playbackRate = 0.5; + audio.preservesPitch = false; + } finally { + document.documentElement.removeAttribute("class") + } +})() +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/1709130.html b/dom/media/test/crashtests/1709130.html new file mode 100644 index 0000000000..2c6d7dc690 --- /dev/null +++ b/dom/media/test/crashtests/1709130.html @@ -0,0 +1,19 @@ +<html class="reftest-wait"> +<head> +<script> +(async _ => { + const video = document.createElement("video"); + video.mozCaptureStreamUntilEnded(); + video.src = "test.mp4"; + await video.play(); + for (let i = 0; i < 23; i++) { + console.log("nop"); + await video.seekToNextFrame(); + video.removeAttribute("readonly"); + } + setTimeout("self.close()", 100); + document.documentElement.removeAttribute("class"); +})(); +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/1734008.html b/dom/media/test/crashtests/1734008.html new file mode 100644 index 0000000000..31c8d31dae --- /dev/null +++ b/dom/media/test/crashtests/1734008.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> + <script> + window.addEventListener("load", async () => { + const object = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject") + const video = document.createElementNS("http://www.w3.org/1999/xhtml", "video") + document.documentElement.appendChild(video) + video.setAttribute("src", "1734008.webm") + video.mozCaptureStream() + const xhr = new XMLHttpRequest() + xhr.open("POST", "FOOBAR", false) + xhr.send() + const document_0 = new Document() + const adopted = document_0.adoptNode(document.documentElement) + object.insertBefore(adopted, object.childNodes[(216679474 % object.childNodes.length)]) + try { await video.play() } catch (e) {} + setTimeout("location.reload()", 500) + }) + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/1734008.webm b/dom/media/test/crashtests/1734008.webm Binary files differnew file mode 100644 index 0000000000..07d2052879 --- /dev/null +++ b/dom/media/test/crashtests/1734008.webm diff --git a/dom/media/test/crashtests/1741677.html b/dom/media/test/crashtests/1741677.html new file mode 100644 index 0000000000..0c442e830d --- /dev/null +++ b/dom/media/test/crashtests/1741677.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<html class="reftest-wait"> +<script> + const script = ` + navigator.mediaCapabilities.decodingInfo({ + type: 'file', + audio: { contentType: "audio/flac" } + }).then(postMessage("done")); + `; + let worker = new Worker(URL.createObjectURL(new Blob([script]))); + // Stop test completion and crash from racing each other. + worker.onmessage = () => document.documentElement.removeAttribute("class"); +</script> +</html> diff --git a/dom/media/test/crashtests/1748272.html b/dom/media/test/crashtests/1748272.html new file mode 100644 index 0000000000..53953e7c0e --- /dev/null +++ b/dom/media/test/crashtests/1748272.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> + <script> + window.addEventListener("load", () => { + const audio = new Audio(); + const context = new AudioContext({ "sampleRate": 15772.7 }) + context.createMediaElementSource(audio); + }); + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/1752917.html b/dom/media/test/crashtests/1752917.html new file mode 100644 index 0000000000..84752a174f --- /dev/null +++ b/dom/media/test/crashtests/1752917.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <script> + window.addEventListener("load", () => { + const context = new AudioContext({}) + const node = new DelayNode(context, {}) + const abort = new AbortController() + let processor = context.createScriptProcessor(4096, 1, 26) + processor.addEventListener("audioprocess", () => {}, { "signal": abort.signal }) + processor.connect(node.delayTime) + processor = undefined + SpecialPowers.forceGC() + abort.abort(undefined) + }); + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/1762620.html b/dom/media/test/crashtests/1762620.html new file mode 100644 index 0000000000..b4c705c84f --- /dev/null +++ b/dom/media/test/crashtests/1762620.html @@ -0,0 +1,8 @@ +<audio id='fuzzed' controls> + <source src='fuzzed.wav'> +</audio> +<script> + var m = document.getElementById('fuzzed') + m.addEventListener('canplay', m.play, true) +</script> + diff --git a/dom/media/test/crashtests/1765842.html b/dom/media/test/crashtests/1765842.html new file mode 100644 index 0000000000..8b77ec998a --- /dev/null +++ b/dom/media/test/crashtests/1765842.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<head> +</head> +<body> + <video src="1765842.webm" type="video/webm" autoplay="true" controls></video> +</body> +</html> diff --git a/dom/media/test/crashtests/1765842.webm b/dom/media/test/crashtests/1765842.webm Binary files differnew file mode 100644 index 0000000000..62eb5d779d --- /dev/null +++ b/dom/media/test/crashtests/1765842.webm diff --git a/dom/media/test/crashtests/1787281.html b/dom/media/test/crashtests/1787281.html new file mode 100644 index 0000000000..e5586dbf2f --- /dev/null +++ b/dom/media/test/crashtests/1787281.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +</head> +<body> + <video id=a src="1787281.mp4" autoplay="true" controls></video> + <script> + a.onended = function() { + document.documentElement.className = ""; + } + </script> +</body> +</html> diff --git a/dom/media/test/crashtests/1787281.mp4 b/dom/media/test/crashtests/1787281.mp4 Binary files differnew file mode 100644 index 0000000000..8481cf034c --- /dev/null +++ b/dom/media/test/crashtests/1787281.mp4 diff --git a/dom/media/test/crashtests/1798778.html b/dom/media/test/crashtests/1798778.html new file mode 100644 index 0000000000..300d84afa1 --- /dev/null +++ b/dom/media/test/crashtests/1798778.html @@ -0,0 +1,11 @@ +<html class="reftest-wait"> +<head> +<audio id=a src="adts-truncated.aac" controls></audio> +<script> + a.play(); + a.onerror = function() { + document.documentElement.removeAttribute("class"); + } +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/1830206.html b/dom/media/test/crashtests/1830206.html new file mode 100644 index 0000000000..69f72176fd --- /dev/null +++ b/dom/media/test/crashtests/1830206.html @@ -0,0 +1,12 @@ +<html class="reftest-wait"> +<video id='a'> + <source src='1830206.mp4'> +</video> +<script> + function done() { + document.documentElement.removeAttribute("class"); + } + a.addEventListener('error', done, true) + a.addEventListener('ended', done, true) + a.play(); +</script> diff --git a/dom/media/test/crashtests/1830206.mp4 b/dom/media/test/crashtests/1830206.mp4 Binary files differnew file mode 100644 index 0000000000..5a95a4dffa --- /dev/null +++ b/dom/media/test/crashtests/1830206.mp4 diff --git a/dom/media/test/crashtests/1833894.mp4 b/dom/media/test/crashtests/1833894.mp4 Binary files differnew file mode 100644 index 0000000000..a5c20e4846 --- /dev/null +++ b/dom/media/test/crashtests/1833894.mp4 diff --git a/dom/media/test/crashtests/1833896.mp4 b/dom/media/test/crashtests/1833896.mp4 Binary files differnew file mode 100644 index 0000000000..6d40590c8a --- /dev/null +++ b/dom/media/test/crashtests/1833896.mp4 diff --git a/dom/media/test/crashtests/1835118.adts b/dom/media/test/crashtests/1835118.adts Binary files differnew file mode 100644 index 0000000000..cf68dfb274 --- /dev/null +++ b/dom/media/test/crashtests/1835118.adts diff --git a/dom/media/test/crashtests/1835164.html b/dom/media/test/crashtests/1835164.html new file mode 100644 index 0000000000..702e082954 --- /dev/null +++ b/dom/media/test/crashtests/1835164.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<audio id=a src=1835164.opus controls autoplay></audio> +<script> +a.onloadedmetadata = function() { + a.currentTime = 1e40; + a.play(); +} +a.onplaying = function() { + document.documentElement.removeAttribute("class"); +} +</script> +</html> diff --git a/dom/media/test/crashtests/1835164.opus b/dom/media/test/crashtests/1835164.opus Binary files differnew file mode 100644 index 0000000000..124fdbfda1 --- /dev/null +++ b/dom/media/test/crashtests/1835164.opus diff --git a/dom/media/test/crashtests/1839193.adts b/dom/media/test/crashtests/1839193.adts Binary files differnew file mode 100644 index 0000000000..0bc06397cb --- /dev/null +++ b/dom/media/test/crashtests/1839193.adts diff --git a/dom/media/test/crashtests/1839193.html b/dom/media/test/crashtests/1839193.html new file mode 100644 index 0000000000..9892908882 --- /dev/null +++ b/dom/media/test/crashtests/1839193.html @@ -0,0 +1,9 @@ +<html class="reftest-wait"> +<audio id=a src=1839193.adts controls></audio> +<script> + a.play(); + a.onerror = a.onended = () => { + document.documentElement.removeAttribute("class") + } +</script> +</html> diff --git a/dom/media/test/crashtests/1840002.webm b/dom/media/test/crashtests/1840002.webm Binary files differnew file mode 100644 index 0000000000..0ad6d513e7 --- /dev/null +++ b/dom/media/test/crashtests/1840002.webm diff --git a/dom/media/test/crashtests/1845350.mp4 b/dom/media/test/crashtests/1845350.mp4 Binary files differnew file mode 100644 index 0000000000..e22af449c2 --- /dev/null +++ b/dom/media/test/crashtests/1845350.mp4 diff --git a/dom/media/test/crashtests/1848660.html b/dom/media/test/crashtests/1848660.html new file mode 100644 index 0000000000..7bebb9c896 --- /dev/null +++ b/dom/media/test/crashtests/1848660.html @@ -0,0 +1,10 @@ +<html class="reftest-wait"> +<audio id='a'> +<source src='1848660.wav'> +</audio> +<script> +function done() { + document.documentElement.removeAttribute("class"); +} +a.addEventListener('error', done, true) +</script> diff --git a/dom/media/test/crashtests/1848660.wav b/dom/media/test/crashtests/1848660.wav new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/dom/media/test/crashtests/1848660.wav diff --git a/dom/media/test/crashtests/1850453.flac b/dom/media/test/crashtests/1850453.flac Binary files differnew file mode 100644 index 0000000000..dfca92a634 --- /dev/null +++ b/dom/media/test/crashtests/1850453.flac diff --git a/dom/media/test/crashtests/1850453.html b/dom/media/test/crashtests/1850453.html new file mode 100644 index 0000000000..d2aa54bc6a --- /dev/null +++ b/dom/media/test/crashtests/1850453.html @@ -0,0 +1,12 @@ +<html class="reftest-wait"> +<audio id=a src=1850453.flac controls></audio> +<script> + a.play(); + a.onplaying = function() { + a.currentTime = 0.5; + } + a.onseeked = function () { + document.documentElement.removeAttribute("class") + } +</script> +</html> diff --git a/dom/media/test/crashtests/1859384.mp4 b/dom/media/test/crashtests/1859384.mp4 Binary files differnew file mode 100644 index 0000000000..b0efba5718 --- /dev/null +++ b/dom/media/test/crashtests/1859384.mp4 diff --git a/dom/media/test/crashtests/1859600.mp4 b/dom/media/test/crashtests/1859600.mp4 Binary files differnew file mode 100644 index 0000000000..9bfd9fa359 --- /dev/null +++ b/dom/media/test/crashtests/1859600.mp4 diff --git a/dom/media/test/crashtests/1860840.mp4 b/dom/media/test/crashtests/1860840.mp4 Binary files differnew file mode 100644 index 0000000000..d3736a232f --- /dev/null +++ b/dom/media/test/crashtests/1860840.mp4 diff --git a/dom/media/test/crashtests/1864450.html b/dom/media/test/crashtests/1864450.html new file mode 100644 index 0000000000..1d2d758ff8 --- /dev/null +++ b/dom/media/test/crashtests/1864450.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> + const ac = new OfflineAudioContext({length: 136, sampleRate: 48000}); + const filterNode = new BiquadFilterNode(ac); + filterNode.frequency.setValueCurveAtTime([0.2, 0.3], 0, 1); + filterNode.frequency.linearRampToValueAtTime(0.8, 1); + ac.startRendering().then(() => { + filterNode.frequency.value; + document.documentElement.removeAttribute("class"); + }); +</script> diff --git a/dom/media/test/crashtests/1872787.html b/dom/media/test/crashtests/1872787.html new file mode 100644 index 0000000000..d02a67138e --- /dev/null +++ b/dom/media/test/crashtests/1872787.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>crashtest for bug 1872787</title> +<script> +document.addEventListener("DOMContentLoaded", () => { + let a = document.createElementNS("http://www.w3.org/1999/xhtml", "video"); + document.documentElement.appendChild(a); + let b = new AudioContext({"sampleRate": 12000}); + let _ = new MediaElementAudioSourceNode(b, {"mediaElement": a}); + a.mozCaptureStreamUntilEnded(); + // There is nothing to wait for but that no exceptions are thrown. + document.documentElement.removeAttribute("class"); +}) +</script> diff --git a/dom/media/test/crashtests/255ch.wav b/dom/media/test/crashtests/255ch.wav Binary files differnew file mode 100644 index 0000000000..d9ee36d5bf --- /dev/null +++ b/dom/media/test/crashtests/255ch.wav diff --git a/dom/media/test/crashtests/459439-1.html b/dom/media/test/crashtests/459439-1.html new file mode 100644 index 0000000000..7bb0131d51 --- /dev/null +++ b/dom/media/test/crashtests/459439-1.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +var i = 0; +function boom() +{ + var div = document.getElementById("div"); + var audio = document.getElementById("audio"); + + audio.onload = null; + + div.textContent = "FAIL"; + audio.src += ""; + div.textContent = "PASS?"; + + ++i; + + setTimeout(done, 1); +} + +function done() +{ + // Note we reset 'src' to release decoder resources and cubeb streams to + // prevent OOM or OpenCubeb() failures. + var audio = document.getElementById("audio"); + audio.src = ""; + document.documentElement.removeAttribute("class"); +} +</script> +</head> +<body> +<audio id="audio" autoplay src="sound.ogg" oncanplaythrough="setTimeout(boom, 1);"></audio> +<div id="div"></div> +</body> +</html> diff --git a/dom/media/test/crashtests/466607-1.html b/dom/media/test/crashtests/466607-1.html new file mode 100644 index 0000000000..e154223efe --- /dev/null +++ b/dom/media/test/crashtests/466607-1.html @@ -0,0 +1,14 @@ +<html> +<head> +<script type="text/javascript"> + +function boom() +{ + document.body.appendChild(document.createElementNS("bar", "audio")); + document.body.appendChild(document.createElementNS("bar", "video")); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/466945-1.html b/dom/media/test/crashtests/466945-1.html new file mode 100644 index 0000000000..ac1ba29e36 --- /dev/null +++ b/dom/media/test/crashtests/466945-1.html @@ -0,0 +1,25 @@ +<html class="reftest-wait"> +<head> +<script type="text/javascript"> + +var s; + +function boom() +{ + s = document.createElement("span"); + s.innerHTML = "<video src='data:text/html,' autoplay='autoplay'><\/video>"; + document.body.appendChild(document.createElement("iframe")); + setTimeout(boom2, 0); +} + +function boom2() +{ + s.innerHTML = ""; + document.documentElement.removeAttribute("class"); +} + +</script> +</head> + +<body onload="setTimeout(boom, 0);"></body> +</html> diff --git a/dom/media/test/crashtests/468763-1.html b/dom/media/test/crashtests/468763-1.html new file mode 100644 index 0000000000..d21e5bc388 --- /dev/null +++ b/dom/media/test/crashtests/468763-1.html @@ -0,0 +1 @@ +<html><head></head><body><video src="nosuchprotocol:"></video></body></html>
\ No newline at end of file diff --git a/dom/media/test/crashtests/474744-1.html b/dom/media/test/crashtests/474744-1.html new file mode 100644 index 0000000000..8a7c70cf05 --- /dev/null +++ b/dom/media/test/crashtests/474744-1.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<script type="text/javascript"> + +function boom() +{ + document.body.innerHTML += "<video src='aim:yaz'><\/video>"; +} + +</script> +</head> +<body onload="boom();"> +</body> +</html> diff --git a/dom/media/test/crashtests/481136-1.html b/dom/media/test/crashtests/481136-1.html new file mode 100644 index 0000000000..bd264058d9 --- /dev/null +++ b/dom/media/test/crashtests/481136-1.html @@ -0,0 +1,3 @@ +<html> +<div><object data='sound.ogg'></div> +</html> diff --git a/dom/media/test/crashtests/492286-1.xhtml b/dom/media/test/crashtests/492286-1.xhtml new file mode 100644 index 0000000000..627ac38723 --- /dev/null +++ b/dom/media/test/crashtests/492286-1.xhtml @@ -0,0 +1 @@ +<source xmlns="http://www.w3.org/1999/xhtml"/>
\ No newline at end of file diff --git a/dom/media/test/crashtests/493915-1.html b/dom/media/test/crashtests/493915-1.html new file mode 100644 index 0000000000..2a6ae9bd6c --- /dev/null +++ b/dom/media/test/crashtests/493915-1.html @@ -0,0 +1,18 @@ +<html> +<head> +<script type="text/javascript"> + +function boom() +{ + s = document.createElement("span"); + a = document.createElement("audio"); + a['src'] = "javascript:4"; + a['loopend'] = 3; + s.appendChild(a); +} + +</script> +</head> + +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/495794-1.html b/dom/media/test/crashtests/495794-1.html new file mode 100644 index 0000000000..2db69206a1 --- /dev/null +++ b/dom/media/test/crashtests/495794-1.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <body> + <audio src="495794-1.ogg" autoplay onended="this.src=''; document.documentElement.className=undefined"></audio> + <!-- Note we reset 'src' to release decoder resources and cubeb streams to prevent OOM or OpenCubeb() failures. --> + </body> +</html> + diff --git a/dom/media/test/crashtests/495794-1.ogg b/dom/media/test/crashtests/495794-1.ogg Binary files differnew file mode 100644 index 0000000000..1c19a64061 --- /dev/null +++ b/dom/media/test/crashtests/495794-1.ogg diff --git a/dom/media/test/crashtests/497734-1.xhtml b/dom/media/test/crashtests/497734-1.xhtml new file mode 100644 index 0000000000..6df055da39 --- /dev/null +++ b/dom/media/test/crashtests/497734-1.xhtml @@ -0,0 +1,21 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script type="text/javascript"> + +function boom() +{ + + div = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); + div.appendChild(document.getElementById("v")); + document.body.appendChild(div); +} + +</script> +</head> + +<body onload="boom();"> + +<video id="v"><source></source></video> + +</body> +</html> diff --git a/dom/media/test/crashtests/497734-2.html b/dom/media/test/crashtests/497734-2.html new file mode 100644 index 0000000000..990ac4af46 --- /dev/null +++ b/dom/media/test/crashtests/497734-2.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<script> + +function boom() +{ + audio1 = document.createElement("audio"); + (audio1).appendChild(document.createElement("source")); + (audio1).appendChild(document.createElement("source")); + setTimeout(function() { + audio2 = document.createElement("audio"); + audio2.appendChild(audio1); + }, 100); +} + +</script> +<body onload="boom();"></body> diff --git a/dom/media/test/crashtests/576612-1.html b/dom/media/test/crashtests/576612-1.html new file mode 100644 index 0000000000..04f993e780 --- /dev/null +++ b/dom/media/test/crashtests/576612-1.html @@ -0,0 +1,15 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> +function boom() +{ + + var v = document.getElementById("v"); + v.src = "data:text/plain,_"; + document.documentElement.appendChild(v); + +} +</script> +</head> +<body onload="boom();"><video id="v" src="data:video/ogg;codecs="theora,vorbis",1"></video></body> +</html> diff --git a/dom/media/test/crashtests/691096-1.html b/dom/media/test/crashtests/691096-1.html new file mode 100644 index 0000000000..3c3ebfc12a --- /dev/null +++ b/dom/media/test/crashtests/691096-1.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> +var ITERATIONS = 200; + +function stoptest (evt) +{ + if (evt) { + // Note we reset 'src' to release decoder resources and cubeb streams to + // prevent OOM or OpenCubeb() failures. + evt.target.src = ""; + } + document.documentElement.removeAttribute("class"); +} + +function boom() +{ + for (var i = 0; i < ITERATIONS; ++i) { + a = document.createElementNS("http://www.w3.org/1999/xhtml", "audio"); + a.addEventListener("loadedmetadata", stoptest); + a.setAttributeNS(null, "autoplay", ""); + a.setAttributeNS(null, "src", "sound.ogg"); + } + setTimeout(stoptest, 250); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/752784-1.html b/dom/media/test/crashtests/752784-1.html new file mode 100644 index 0000000000..4644eeb89a --- /dev/null +++ b/dom/media/test/crashtests/752784-1.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<script> +function boom() +{ + document.getElementById("a").mozCaptureStream(); +} +</script> +</head> + +<body onload="boom();"> +<audio id="a" src="sound.ogg"> +</body> +</html> diff --git a/dom/media/test/crashtests/789075-1.html b/dom/media/test/crashtests/789075-1.html new file mode 100644 index 0000000000..6cd673fb75 --- /dev/null +++ b/dom/media/test/crashtests/789075-1.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +</head> +<body> +<video src="789075.webm" preload="metadata" id="v"> +</video> +<!-- Note we reset 'src' to release decoder resources and cubeb streams to prevent OOM or OpenCubeb() failures. --> +<script type="application/javascript"> + var video = document.getElementById("v"); + video.onloadeddata = function () { + video.play(); + }; + video.onended = function () { + video.src=""; + document.documentElement.className = undefined; + }; +</script> +</body> +</html> diff --git a/dom/media/test/crashtests/789075.webm b/dom/media/test/crashtests/789075.webm Binary files differnew file mode 100644 index 0000000000..602e53fca2 --- /dev/null +++ b/dom/media/test/crashtests/789075.webm diff --git a/dom/media/test/crashtests/795892-1.html b/dom/media/test/crashtests/795892-1.html new file mode 100644 index 0000000000..d73cea7f2e --- /dev/null +++ b/dom/media/test/crashtests/795892-1.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> +function boom() +{ + var a = document.getElementById("a"); + a.play(); + a.onplaying = function () { + a.onplaying = null; + // Note we reset 'src' to release decoder resources and cubeb streams to + // prevent OOM or OpenCubeb() failures. + a.src = ""; + document.documentElement.className = ""; + } +} +</script> +</head> + +<body> +<video id="a" src="cors.webm" crossorigin preload="metadata" onloadedmetadata="boom();"> +</body> +</html> diff --git a/dom/media/test/crashtests/844563.html b/dom/media/test/crashtests/844563.html new file mode 100644 index 0000000000..a3cb91838d --- /dev/null +++ b/dom/media/test/crashtests/844563.html @@ -0,0 +1,5 @@ +<script> +var a = document.createElementNS("http://www.w3.org/1999/xhtml", "audio"); +a.preservesPitch = a; +</script> + diff --git a/dom/media/test/crashtests/846612.html b/dom/media/test/crashtests/846612.html new file mode 100644 index 0000000000..070c375381 --- /dev/null +++ b/dom/media/test/crashtests/846612.html @@ -0,0 +1,8 @@ +<script> +document.addEventListener("DOMContentLoaded", function() { + var a = document.querySelector("audio"); + a.playbackRate = 2; + a.play(); +}); +</script> +<audio src="495794-1.ogg"></audio> diff --git a/dom/media/test/crashtests/852838.html b/dom/media/test/crashtests/852838.html new file mode 100644 index 0000000000..0bea29351b --- /dev/null +++ b/dom/media/test/crashtests/852838.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> + <head> + <script> + var o0 = new window.AudioContext(); + var o1 = o0.createBuffer(536870912, 1, 8192); + </script> + </head> + <body> + </body> +</html> diff --git a/dom/media/test/crashtests/865004.html b/dom/media/test/crashtests/865004.html new file mode 100644 index 0000000000..4da39071c4 --- /dev/null +++ b/dom/media/test/crashtests/865004.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + var ac = new AudioContext(); + for (var j = 0; j < 200; ++j) { + ac.createScriptProcessor(undefined); + } + document.documentElement.removeAttribute("class"); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/865537-1.html b/dom/media/test/crashtests/865537-1.html new file mode 100644 index 0000000000..4065eb3608 --- /dev/null +++ b/dom/media/test/crashtests/865537-1.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML> +<html> +<body onload="doTest()"> +<base href="../unknown"> +<div id="test3"></div> +<video id="test4"><source src="white.webm"></video> +<script> +function doTest() { + test3.appendChild(test4); +} +</script> +</body> +</html> diff --git a/dom/media/test/crashtests/865550.html b/dom/media/test/crashtests/865550.html new file mode 100644 index 0000000000..b8626e8d67 --- /dev/null +++ b/dom/media/test/crashtests/865550.html @@ -0,0 +1,22 @@ +<html class="reftest-wait"> + <head> + <script> + var i = 0; + var interval; + function crash() { + var o0 = new AudioContext(); + o1 = o0.createBufferSource(); + ++i; + if (i == 2000) { + document.documentElement.removeAttribute("class"); + clearInterval(interval); + } + } + function start() { + interval = setInterval("crash()", 0) + } + </script> + </head> + <body onload="start()"> + </body> +</html> diff --git a/dom/media/test/crashtests/868504.html b/dom/media/test/crashtests/868504.html new file mode 100644 index 0000000000..94090c1c09 --- /dev/null +++ b/dom/media/test/crashtests/868504.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + new AudioContext().createBufferSource().playbackRate.linearRampToValueAtTime(0, -1); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/874869.html b/dom/media/test/crashtests/874869.html new file mode 100644 index 0000000000..1fe3dbd2fc --- /dev/null +++ b/dom/media/test/crashtests/874869.html @@ -0,0 +1,15 @@ +<script> +var Context0= new AudioContext() +var Panner0=Context0.createPanner(); +var BufferSource3=Context0.createBufferSource(); +Panner0.channelCount=0; +BufferSource3.connect(Panner0); +BufferSource3.buffer=function(){ + var length=1; + var Buffer=Context0.createBuffer(1,length,'44200'); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = 255;}; + return Buffer; +}(); + +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/874915.html b/dom/media/test/crashtests/874915.html new file mode 100644 index 0000000000..59218b3da3 --- /dev/null +++ b/dom/media/test/crashtests/874915.html @@ -0,0 +1,24 @@ +<script> +var Context0= new AudioContext() +var BufferSource6=Context0.createBufferSource(); + +setInterval(function(){ +BufferSource6.buffer=function(){ + var length=11283; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(624))}; + return Buffer; +}(); +},0) + +BufferSource6.start(0.15831333969254047,0.23571860056836158,0.529235512483865); + +BufferSource6.buffer=function(){ + var length=48517; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(365))}; + return Buffer; +}(); +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/874934.html b/dom/media/test/crashtests/874934.html new file mode 100644 index 0000000000..350ce28101 --- /dev/null +++ b/dom/media/test/crashtests/874934.html @@ -0,0 +1,23 @@ +<script> +var Context0= new AudioContext() +var BufferSource0=Context0.createBufferSource(); +BufferSource0.start(0.01932738965842873,0.33345631847623736,0.3893404237460345); +BufferSource0.buffer=function(){ + var length=35887; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(0.39765272522345185))}; + return Buffer; +}(); + +BufferSource0.buffer=function(){ + var length=15952; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(85))}; + return Buffer; +}(); + +BufferSource0.playbackRate.value=20.401213286832185; + +</script> diff --git a/dom/media/test/crashtests/874952.html b/dom/media/test/crashtests/874952.html new file mode 100644 index 0000000000..a9a398fdb2 --- /dev/null +++ b/dom/media/test/crashtests/874952.html @@ -0,0 +1,11 @@ +<script> +var Context0= new AudioContext() +var ChannelSplitter0=Context0.createChannelSplitter(); +var BiquadFilter0=Context0.createBiquadFilter(); +var WaveShaper0=Context0.createWaveShaper(); + +ChannelSplitter0.connect(BiquadFilter0,3,0); +ChannelSplitter0.connect(WaveShaper0); +BiquadFilter0.disconnect(); +WaveShaper0.connect(ChannelSplitter0); +</script> diff --git a/dom/media/test/crashtests/875144.html b/dom/media/test/crashtests/875144.html new file mode 100644 index 0000000000..bf5d0d0861 --- /dev/null +++ b/dom/media/test/crashtests/875144.html @@ -0,0 +1,81 @@ +<script> +Logger = {} +Logger.error = function(e) {} +Logger.comment = function(e) {} + +try { o0 = document.createElement('audio'); } catch(e) { Logger.error(Logger.comment(e)); } +try { (document.body || document.documentElement).appendChild(o0); } catch(e) { Logger.error(Logger.comment(e)); } +try { o1 = new AudioContext(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o2 = o1.createGain(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o3 = o1.createBufferSource(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o3.buffer = function() { o4 = o1.createBuffer(1, 3, 52970); +o5 = o4.getChannelData(0); +for(var i=0; i<3; ++i) { +o5[i] = Math.sin(i * 63); +} +return o4; +}(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o3.buffer = function() { o6 = o1.createBuffer(1, 15, 41218); +o7 = o6.getChannelData(0); +for(var i=0; i<15; ++i) { +o7[i] = Math.sin(i * 0); +} +return o6; +}(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o3.buffer = function() { o8 = o1.createBuffer(1, 0, 49074); +o9 = o8.getChannelData(0); +for(var i=0; i<0; ++i) { +o9[i] = Math.sin(i * 0); +} +return o8; +}(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o3.buffer = function() { o10 = o1.createBuffer(1, 31, 86527); +o11 = o10.getChannelData(0); +for(var i=0; i<31; ++i) { +o11[i] = Math.sin(i * 127); +} +return o10; +}(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o3.stop(-1) } catch(e) { Logger.error(Logger.comment(e)); } +/* [Exception... "An attempt was made to use an object that is not, or is no longer, usable" code: "11" nsresult: "0x8053000b (InvalidStateError)" location: "file:///Users/cdiehl/dev/projects/peach/Peach/Utilities/JS/undefined.js Line: 602"] */ +try { o3.channelCountMode = 'explicit'; } catch(e) { Logger.error(Logger.comment(e)); } +try { o12 = o1.createBiquadFilter(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o3.buffer = function() { o13 = o1.createBuffer(1, 63, 28347); +o14 = o13.getChannelData(0); +for(var i=0; i<63; ++i) { +o14[i] = Math.sin(i * 15); +} +return o13; +}(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o12.channelCount = 1; } catch(e) { Logger.error(Logger.comment(e)); } +try { o12.connect(GainNode, 65536, 0) } catch(e) { Logger.error(Logger.comment(e)); } +/* TypeError: Value does not implement interface AudioNode. */ +try { o3.buffer = function() { o15 = o1.createBuffer(1, 1, 72540); +o16 = o15.getChannelData(0); +for(var i=0; i<1; ++i) { +o16[i] = Math.sin(i * 7); +} +return o15; +}(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o12.getFrequencyResponse(new Float32Array(7), new Float32Array(127), new Float32Array(7)) } catch(e) { Logger.error(Logger.comment(e)); } +try { o12.getFrequencyResponse(new Float32Array(15), new Float32Array(127), new Float32Array(7)) } catch(e) { Logger.error(Logger.comment(e)); } +try { o17 = document.createElement('audio'); } catch(e) { Logger.error(Logger.comment(e)); } +try { (document.body || document.documentElement).appendChild(o0); } catch(e) { Logger.error(Logger.comment(e)); } +try { o3.buffer = function() { o18 = o1.createBuffer(1, 7, 91261); +o19 = o18.getChannelData(0); +for(var i=0; i<7; ++i) { +o19[i] = Math.sin(i * 7); +} +return o18; +}(); } catch(e) { Logger.error(Logger.comment(e)); } +try { o12.getFrequencyResponse(new Float32Array(31), new Float32Array(31), new Float32Array(127)) } catch(e) { Logger.error(Logger.comment(e)); } +try { o20 = o1.createChannelSplitter(1, 2, 4, 16, 32); } catch(e) { Logger.error(Logger.comment(e)); } +try { o12.channelCountMode = 'explicit'; } catch(e) { Logger.error(Logger.comment(e)); } +try { o3.buffer = function() { o21 = o1.createBuffer(1, 0, 14451); +o22 = o21.getChannelData(0); +for(var i=0; i<0; ++i) { +o22[i] = Math.sin(i * 63); +} +return o21; +}(); } catch(e) { Logger.error(Logger.comment(e)); } +</script> diff --git a/dom/media/test/crashtests/875596.html b/dom/media/test/crashtests/875596.html new file mode 100644 index 0000000000..7bac09dab7 --- /dev/null +++ b/dom/media/test/crashtests/875596.html @@ -0,0 +1,12 @@ +<script> +try { o1 = new AudioContext(); } catch(e) { } +try { o6 = o1.createGain(); } catch(e) { } +try { o8 = o1.createBufferSource(); } catch(e) { } +try { o6.gain.setValueCurveAtTime(new Float32Array(7), 0, 0) } catch(e) { } +try { o8.connect(o6, 0, 0) } catch(e) { } +try { o8.buffer = function() { + o19 = o1.createBuffer(1, 1, 76309); + for(var i=0; i<1; ++i) { } + return o19; +}(); } catch(e) { } +</script> diff --git a/dom/media/test/crashtests/875911.html b/dom/media/test/crashtests/875911.html new file mode 100644 index 0000000000..fbc52642b4 --- /dev/null +++ b/dom/media/test/crashtests/875911.html @@ -0,0 +1,3 @@ +<script> + new OfflineAudioContext(1, 10, 48000); +</script> diff --git a/dom/media/test/crashtests/876024-1.html b/dom/media/test/crashtests/876024-1.html new file mode 100644 index 0000000000..5502d8e42d --- /dev/null +++ b/dom/media/test/crashtests/876024-1.html @@ -0,0 +1,5 @@ +<script> +o1 = new window.AudioContext(2, 8, 44100); +o4 = o1.createBiquadFilter(); +o4.detune.setValueAtTime(0.0843, 1.7976931348623157e+308); +</script> diff --git a/dom/media/test/crashtests/876024-2.html b/dom/media/test/crashtests/876024-2.html new file mode 100644 index 0000000000..4b9beb7453 --- /dev/null +++ b/dom/media/test/crashtests/876024-2.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + var bufferSource = new AudioContext().createScriptProcessor().context.createBufferSource(); + bufferSource.start(0, 0, 0); + bufferSource.stop(562949953421313); +} + +</script></head> + +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/876118.html b/dom/media/test/crashtests/876118.html new file mode 100644 index 0000000000..bc0630350a --- /dev/null +++ b/dom/media/test/crashtests/876118.html @@ -0,0 +1,16 @@ +<script> +var Context0= new AudioContext() +var BufferSource7=Context0.createBufferSource(); + +BufferSource7.connect(Context0.destination); +BufferSource7.buffer=function(){ + var length=7; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0);for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(-1))}; + return Buffer; +}(); + + +Context0.destination.channelCountMode="explicit"; +Context0.destination.channelCount=519910189000000; +</script> diff --git a/dom/media/test/crashtests/876207.html b/dom/media/test/crashtests/876207.html new file mode 100644 index 0000000000..7bfcb096b2 --- /dev/null +++ b/dom/media/test/crashtests/876207.html @@ -0,0 +1,30 @@ +<script> +try { o1 = new window.OfflineAudioContext(1, 10, 44100); } catch(e) { } +try { o2 = o1.createChannelSplitter(1); } catch(e) { } +try { o3 = o1.createAnalyser(); } catch(e) { } +try { o4 = o1.createWaveShaper(); } catch(e) { } +try { o5 = o1.createChannelSplitter(6); } catch(e) { } +try { o6 = o1.createAnalyser(); } catch(e) { } +try { o7 = o1.createBufferSource(); } catch(e) { } +try { o7.connect(o1.destination); } catch(e) { } +try { o7.buffer = function() { +o8 = o1.createBuffer(1, 3, o1.sampleRate); +o9 = o8.getChannelData(0); +for(var i = 0; i < 3; ++i) { +o9[i] = Math.sin(i * 127); +} +return o8; +}() +; } catch(e) { } +try { o7.playbackRate.cancelScheduledValues(0) } catch(e) { } +try { o7.channelInterpretation = 'speakers'; } catch(e) { } +try { o1.destination.channelInterpretation = 'speakers'; } catch(e) { } +try { o5.connect(o1.destination, 1, 1) } catch(e) { } +try { o1.listener.setOrientation(0, 1073741824, 1073741824, 4194304, 1, 0) } catch(e) { } +try { o4.curve = new Float32Array(127); } catch(e) { } +try { o6.getByteFrequencyData(new Uint8Array(12)) } catch(e) { } +try { o6.disconnect() } catch(e) { } +try { o1.destination.channelCount = 33554432; } catch(e) { } +try { o7.playbackRate.setTargetAtTime(0, 8388608, 1) } catch(e) { } +try { o6.getByteTimeDomainData(new Uint8Array(12)) } catch(e) { } +</script> diff --git a/dom/media/test/crashtests/876215.html b/dom/media/test/crashtests/876215.html new file mode 100644 index 0000000000..07135e3628 --- /dev/null +++ b/dom/media/test/crashtests/876215.html @@ -0,0 +1,14 @@ +<script> +try { o1 = new window.OfflineAudioContext(1, 10, 44100); } catch(e) { } +try { o6 = o1.createScriptProcessor(0, 0, 2); } catch(e) { } +try { o8 = o1.createBufferSource(); } catch(e) { } +try { o8.connect(o1.destination); } catch(e) { } +try { o8.connect(o6) } catch(e) { } +try { o3.disconnect() } catch(e) { } +try { o8.buffer = function() { +o21 = o1.createBuffer(1, 3, o1.sampleRate); +o22 = o21.getChannelData(0); +return o21; +}() +; } catch(e) { } +</script> diff --git a/dom/media/test/crashtests/876249.html b/dom/media/test/crashtests/876249.html new file mode 100644 index 0000000000..6f72b40bc1 --- /dev/null +++ b/dom/media/test/crashtests/876249.html @@ -0,0 +1,27 @@ +<script> +var Context0= new AudioContext() +var BufferSource0=Context0.createBufferSource(); +var BiquadFilter0=Context0.createBiquadFilter(); +BufferSource0.start(0,0.6167310480959713,0.7142638498917222); +BiquadFilter0.connect(Context0.destination); +BufferSource0.buffer=function(){ + var length=86333; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(-1))}; + return Buffer; +}(); + +BufferSource0.connect(BiquadFilter0); + +BufferSource0.buffer=function(){ + var length=21989; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(0))}; + return Buffer; +}(); + +BufferSource0.stop(0.04184641852043569); + +</script> diff --git a/dom/media/test/crashtests/876252.html b/dom/media/test/crashtests/876252.html new file mode 100644 index 0000000000..cb9cb63ed3 --- /dev/null +++ b/dom/media/test/crashtests/876252.html @@ -0,0 +1,23 @@ +<script> +var Context0= new AudioContext() +var BufferSource4=Context0.createBufferSource(); +BufferSource4.start(0.05386466556228697,0.397192713804543,0.48810303467325866); + +BufferSource4.buffer=function(){ + var length=109076; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(370))}; + return Buffer; +}(); + +BufferSource4.buffer=function(){ + var length=19339; + var Buffer=Context0.createBuffer(1,length,53362); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(-0.16235407581552863))}; + return Buffer; +}(); + +BufferSource4.stop(0.46482366253621876); +</script> diff --git a/dom/media/test/crashtests/876834.html b/dom/media/test/crashtests/876834.html new file mode 100644 index 0000000000..f4ca6ee558 --- /dev/null +++ b/dom/media/test/crashtests/876834.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<script> +new OfflineAudioContext(0, 0, 3229622); +</script> diff --git a/dom/media/test/crashtests/877527.html b/dom/media/test/crashtests/877527.html new file mode 100644 index 0000000000..c639d501b7 --- /dev/null +++ b/dom/media/test/crashtests/877527.html @@ -0,0 +1,37 @@ +<script> +try { o1 = new window.AudioContext(2, 5, 44100); } catch(e) { } +try { o2 = o1.createChannelMerger(1); } catch(e) { } +try { o3 = o1.createDelay(10); } catch(e) { } +try { o4 = o1.createBuffer(2, 2048, 8000); } catch(e) { } +try { o5 = o1.createPanner(); } catch(e) { } +try { o6 = o1.createBufferSource(); } catch(e) { } +try { o7 = (function() { +var buf = o1.createBuffer(1, 50000, o1.sampleRate); +for(var j=0; j<1; ++j) { +for(var i=0; i<50000; ++i) { buf.getChannelData(j)[i] = Math.sin(i * (9.8));} +} +return buf; +})(); } catch(e) { } +try { o6.buffer = o7; } catch(e) { } +try { o6.connect(o5); } catch(e) { } +try { o5.connect(o1.destination); } catch(e) { } +try { o1.listener.speedOfSound = 0.0000019073486328125; } catch(e) { } +try { o6.loop = true; } catch(e) { } +try { o8 = (function() { +var buf = o1.createBuffer(2, 1000, o1.sampleRate); +for(var j=0; j<2; ++j) { +for(var i=0; i<1000; ++i) { buf.getChannelData(j)[i] = Math.sin(i * (1));} +} +return buf; +})(); } catch(e) { } +try { o6.buffer = o7; } catch(e) { } +try { o6.connect(o5); } catch(e) { } +try { o5.connect(o1.destination); } catch(e) { } +try { o6.loopEnd = 1.4901161193847656e-8; } catch(e) { } +try { o6.connect(o1.destination); } catch(e) { } +try { o6.buffer = o8; } catch(e) { } +try { o5.setPosition(0.36, o1.destination.context.destination.channelCountMode, o1.destination.context.destination.channelInterpretation) } catch(e) { } +try { o2.channelCountMode = 'explicit'; } catch(e) { } +try { o1.listener.speedOfSound = 4; } catch(e) { } +try { o1.startRendering(); } catch(e) { } +</script> diff --git a/dom/media/test/crashtests/877820.html b/dom/media/test/crashtests/877820.html new file mode 100644 index 0000000000..6d65c1e9d9 --- /dev/null +++ b/dom/media/test/crashtests/877820.html @@ -0,0 +1,4 @@ +<script> +o1 = new window.OfflineAudioContext(2, 5, 0.39); +window.location.reload(); +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/878014.html b/dom/media/test/crashtests/878014.html new file mode 100644 index 0000000000..4a0ca6dce2 --- /dev/null +++ b/dom/media/test/crashtests/878014.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +try { o2 = new window.AudioContext(1, 15, 44100); } catch(e) { } +try { o5 = o2.createDelay(0.1); } catch(e) { } +try { o6 = o2.createPanner(); } catch(e) { } +try { o8 = o2.createBufferSource(); } catch(e) { } +try { o9 = (function() { +var buf = o2.createBuffer(1, 12134, o2.sampleRate); +for(var j=0; j<1; ++j) { +for(var i=0; i<12134; ++i) { buf.getChannelData(j)[i] = Math.sin(i * (-127));} +} +return buf; +})(); } catch(e) { } +try { o8.buffer = o9; } catch(e) { } +try { o8.connect(o6); } catch(e) { } +try { o6.connect(o5, 0, 0) } catch(e) { } +try { o8.buffer = (function() { +var buf = o2.createBuffer(1, 5409, o2.sampleRate); +for(var j=0; j<1; ++j) { +for(var i=0; i<5409; ++i) { buf.getChannelData(j)[i] = Math.sin(i * (-1));} +} +return buf; +})(); } catch(e) { } +setTimeout(function() { try { o5.delayTime.setValueAtTime(0.78, 121560862.56366833); } catch(e) { } setTimeout(done, 0); },128) +try { o5.delayTime.value = 0.4283; } catch(e) { } + +function done() { + document.documentElement.removeAttribute("class"); +} +</script> diff --git a/dom/media/test/crashtests/878328.html b/dom/media/test/crashtests/878328.html new file mode 100644 index 0000000000..ec7b39871b --- /dev/null +++ b/dom/media/test/crashtests/878328.html @@ -0,0 +1,5 @@ +<script> +o1 = new window.AudioContext(2, 7, 44100); +o5 = o1.createDelay(1); +o5.delayTime.setValueCurveAtTime(new Float32Array(3), 1.7976931348623157e+308, 0.64); +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/878407.html b/dom/media/test/crashtests/878407.html new file mode 100644 index 0000000000..ae2918dc85 --- /dev/null +++ b/dom/media/test/crashtests/878407.html @@ -0,0 +1,11 @@ +<script> +o1 = new window.AudioContext(); +o4 = o1.createDelay(0.4468); +o6 = o1.createPanner(); +o7 = (function() {var buf = o1.createBuffer(1, 1000, o1.sampleRate);for(var j=0; j<1; ++j) {for(var i=0; i<1000; ++i) {buf.getChannelData(j)[i] = Math.sin(i * (-15));}}return buf;})(); +o8 = o1.createBufferSource(); +o8.buffer = o7; +o8.connect(o6); +o6.connect(o4) +o4.delayTime.setValueAtTime(0.6019893103749466289898, 0.26) +</script> diff --git a/dom/media/test/crashtests/878478.html b/dom/media/test/crashtests/878478.html new file mode 100644 index 0000000000..89a47ddb55 --- /dev/null +++ b/dom/media/test/crashtests/878478.html @@ -0,0 +1,30 @@ +<script> +var Context0= new AudioContext() +var BufferSource0=Context0.createBufferSource(); + +BufferSource0.loop=true; + +BufferSource0.buffer=function(){ + var channels=3; + var length=97252; + var Buffer=Context0.createBuffer(channels,length,Context0.sampleRate); + for(var y=0;y<channels;y++){ + var bufferData= Buffer.getChannelData(y); + for (var i = 0; i < length; ++i) { bufferData[i] = 1;} + }; + return Buffer; +}(); + +BufferSource0.playbackRate.cancelScheduledValues(0.4); + +BufferSource0.loopEnd=5e-324; + +BufferSource0.buffer=function(){ + var length=26590; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = 1}; + return Buffer; +}(); + +</script> diff --git a/dom/media/test/crashtests/880129.html b/dom/media/test/crashtests/880129.html new file mode 100644 index 0000000000..775e9d80ba --- /dev/null +++ b/dom/media/test/crashtests/880129.html @@ -0,0 +1,9 @@ +<script> +try { o1 = new window.AudioContext(3, 2, 44100); } catch(e) { } +try { o6 = o1.createBufferSource(); } catch(e) { } +try { o15 = o1.createAnalyser(); } catch(e) { } +try { o15.fftSize = 32; } catch(e) { } +try { o6.connect(o15,0,0) } catch(e) { } +try { o27 = o1.createPanner(); } catch(e) { } +try { o6.buffer = function(){var buffer = o1.createBuffer(2, 1148, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<1148; i++) {buffer.getChannelData(c)[i] = 0;}}return buffer;}() } catch(e) { } +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/880202.html b/dom/media/test/crashtests/880202.html new file mode 100644 index 0000000000..dc0fade9db --- /dev/null +++ b/dom/media/test/crashtests/880202.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var Context0= new window.OfflineAudioContext(15,12119,44100) +var BufferSource1=Context0.createBufferSource(); +var Gain0=Context0.createGain(); +var Panner0=Context0.createPanner(); +Context0.listener.setPosition(29,135,158); + +BufferSource1.connect(Gain0); + +BufferSource1.buffer=function(){ + var channels=3; + var length=53325; + var Buffer=Context0.createBuffer(channels,length,Context0.sampleRate); + for(var y=0;y<channels;y++){ + var bufferData= Buffer.getChannelData(y); + for (var i = 0; i < length; ++i) { + bufferData[i] = i*(270); + } + }; + return Buffer; +}(); + +Gain0.connect(Panner0); +Panner0.panningModel="equalpower"; + + +setTimeout(function(){ +document.documentElement.removeAttribute("class"); +},500) + +</script> diff --git a/dom/media/test/crashtests/880342-1.html b/dom/media/test/crashtests/880342-1.html new file mode 100644 index 0000000000..7d1aa0c3e3 --- /dev/null +++ b/dom/media/test/crashtests/880342-1.html @@ -0,0 +1,208 @@ +<script> +try { o1 = new window.AudioContext(2, 10, 1019159); } catch(e) { } +try { o2 = o1.createBufferSource(); } catch(e) { } +try { o3 = o1.createConvolver(); } catch(e) { } +try { o4 = o1.createChannelMerger(2); } catch(e) { } +try { o5 = o1.createAnalyser(); } catch(e) { } +try { o6 = o1.createPanner(); } catch(e) { } +try { o7 = o1.createDynamicsCompressor(); } catch(e) { } +try { o8 = o1.createWaveShaper(); } catch(e) { } +try { o9 = o1.createChannelSplitter(6); } catch(e) { } +try { o10 = o1.createScriptProcessor(8192, 2, 3); } catch(e) { } +try { o1.listener.setPosition(-144115188075855870, 0, -5e-324) } catch(e) { } +try { o3.buffer = function(){var buffer = o1.createBuffer(2, 741, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<741; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}(); } catch(e) { } +try { o10.onaudioprocess = function(e) { /* onEvent */ }; } catch(e) { } +try { o3.connect(o5,0,0) } catch(e) { } +try { o9.channelCountMode = 'max'; } catch(e) { } +try { o10.onaudioprocess = function(e) { /* onEvent */ }; } catch(e) { } +try { o7.channelInterpretation = 'speakers'; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(2, 1887, 63346);for(var c=0; c<2; c++) {for(var i=0; i<1887; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.playbackRate.exponentialRampToValueAtTime(3.819464020334534, 32) } catch(e) { } +try { o5.connect(o9,2,0) } catch(e) { } +try { o9.channelCountMode = 'explicit'; } catch(e) { } +try { o1.listener.speedOfSound = 72057594037927940; } catch(e) { } +try { o1.destination.channelCountMode = 'explicit'; } catch(e) { } +try { o7.threshold.value = 0.0646435404346891590021684237399313133209944; } catch(e) { } +try { o7.connect(o10,0,0) } catch(e) { } +try { o1.destination.channelInterpretation = 'speakers'; } catch(e) { } +try { o3.connect(o4,0,0) } catch(e) { } +try { o7.release.value = 23.030355486273447; } catch(e) { } +try { o9.connect(o9,4,0) } catch(e) { } +try { o6.channelCountMode = 'max'; } catch(e) { } +try { o7.threshold.value = 0.6395867363641939418172910336579661816358566284179687500; } catch(e) { } +try { o2.connect(o9,3,0) } catch(e) { } +try { o10.onaudioprocess = function(e) { /* onEvent */ }; } catch(e) { } +try { o7.connect(o10,0,0) } catch(e) { } +try { o5.connect(o5,0,0) } catch(e) { } +try { o2.playbackRate.value = 5e-324; } catch(e) { } +try { o4.channelInterpretation = 'discrete'; } catch(e) { } +try { o2.playbackRate.value = 1.2211628339508704; } catch(e) { } +try { o2.channelCountMode = 'clamped-max'; } catch(e) { } +try { o1.listener.dopplerFactor = 32; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(22, 1811, 21177);for(var c=0; c<22; c++) {for(var i=0; i<1811; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o5.channelCountMode = 'max'; } catch(e) { } +try { o1.listener.speedOfSound = 1024; } catch(e) { } +try { o2.playbackRate.value = 9.999999999999998e-91; } catch(e) { } +try { o1.listener.speedOfSound = 16; } catch(e) { } +try { o8.curve = new Float32Array(256); } catch(e) { } +try { o1.listener.setVelocity(0, 128, 4) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(23, 483, o1.sampleRate);for(var c=0; c<23; c++) {for(var i=0; i<483; i++) {buffer.getChannelData(c)[i] = 0.026;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 945, 43803);for(var c=0; c<3; c++) {for(var i=0; i<945; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(19, 997, 23781);for(var c=0; c<19; c++) {for(var i=0; i<997; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o1.listener.speedOfSound = -8; } catch(e) { } +try { o3.channelCountMode = 'explicit'; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 1740, o1.sampleRate);for(var c=0; c<3; c++) {for(var i=0; i<1740; i++) {buffer.getChannelData(c)[i] = 8;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(1, 1057, 30602);for(var c=0; c<1; c++) {for(var i=0; i<1057; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 78, o1.sampleRate);for(var c=0; c<3; c++) {for(var i=0; i<78; i++) {buffer.getChannelData(c)[i] = 10;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o1.listener.setPosition(9.999999999999995e-275, 0.0001, 2) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(1, 863, o1.sampleRate);for(var c=0; c<1; c++) {for(var i=0; i<863; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o8.channelCount = 3; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(2, 1821, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<1821; i++) {buffer.getChannelData(c)[i] = 0.3655;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o6.connect(o6,0,0) } catch(e) { } +try { o1.listener.setOrientation(128, -0.479527496, 128, 1, 1, -16) } catch(e) { } +try { o4.connect(o8,0,0) } catch(e) { } +try { o7.reduction.exponentialRampToValueAtTime(1.7976931348623157e+308, 2048) } catch(e) { } +try { o1.listener.dopplerFactor = 0.5754; } catch(e) { } +try { o7.release.value = 0; } catch(e) { } +try { o5.getFloatFrequencyData(new Float32Array(2048)) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(2, 120, 42419);for(var c=0; c<2; c++) {for(var i=0; i<120; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o3.buffer = function(){var buffer = o1.createBuffer(1, 1620, o1.sampleRate);for(var c=0; c<1; c++) {for(var i=0; i<1620; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}(); } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(1, 823, 77239);for(var c=0; c<1; c++) {for(var i=0; i<823; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o1.destination.channelInterpretation = 'speakers'; } catch(e) { } +try { o1.listener.setPosition(2048, 0.000522899209, -4503599627370495) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 84028, 75483);for(var c=0; c<3; c++) {for(var i=0; i<84028; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.playbackRate.setTargetAtTime(5e-324, 9.999999999999998e-104, 0) } catch(e) { } +try { o7.attack.value = 9.999999999999994e-236; } catch(e) { } +try { o1.listener.dopplerFactor = 1024; } catch(e) { } +try { o3.connect(o7,0,0) } catch(e) { } +try { o2.playbackRate.linearRampToValueAtTime(0, 0) } catch(e) { } +try { o4.connect(o10,0,0) } catch(e) { } +try { o1.listener.setVelocity(0.682, 32, 1e-76) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 201, o1.sampleRate);for(var c=0; c<3; c++) {for(var i=0; i<201; i++) {buffer.getChannelData(c)[i] = 4;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.connect(o6,0,0) } catch(e) { } +try { o5.getByteFrequencyData(new Uint8Array(32)) } catch(e) { } +try { o3.connect(o6,0,0) } catch(e) { } +try { o7.channelCount = 1; } catch(e) { } +try { o2.playbackRate.setValueCurveAtTime(new Float32Array(512), 8, 1) } catch(e) { } +try { o3.connect(o4,0,1) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 1996, o1.sampleRate);for(var c=0; c<3; c++) {for(var i=0; i<1996; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o1.listener.dopplerFactor = 2; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(2, 983, 60517);for(var c=0; c<2; c++) {for(var i=0; i<983; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o6.coneInnerAngle = 360; } catch(e) { } +try { o8.curve = new Float32Array(512); } catch(e) { } +try { o1.listener.setPosition(32, 16, 9.999999999999995e-280) } catch(e) { } +try { o6.connect(o6,0,0) } catch(e) { } +try { o1.listener.setPosition(2097151, 512, 5e-324) } catch(e) { } +try { o7.channelCountMode = 'clamped-max'; } catch(e) { } +try { o1.destination.channelCountMode = 'max'; } catch(e) { } +try { o1.listener.setPosition(0, 1000000, 64) } catch(e) { } +try { o4.connect(o5,0,0) } catch(e) { } +try { o9.connect(o4,0,1) } catch(e) { } +try { o7.attack.setValueCurveAtTime(new Float32Array(8), 256, 2048) } catch(e) { } +try { o9.channelCountMode = 'explicit'; } catch(e) { } +try { o1.listener.dopplerFactor = 5e-324; } catch(e) { } +try { o4.connect(o10,0,0) } catch(e) { } +try { o7.ratio.cancelScheduledValues(1) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(1, 1590, 9733);for(var c=0; c<1; c++) {for(var i=0; i<1590; i++) {buffer.getChannelData(c)[i] = 2;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o1.destination.channelCount = 2; } catch(e) { } +try { o1.destination.channelInterpretation = 'speakers'; } catch(e) { } +try { o5.channelCountMode = 'max'; } catch(e) { } +try { o9.channelCountMode = 'clamped-max'; } catch(e) { } +try { o7.attack.setTargetAtTime(0.11499421161482907549622467513472656719386577606201171875000, 1, 1.7976931348623157e+308) } catch(e) { } +try { o2.playbackRate.value = 1; } catch(e) { } +try { o3.normalize = false; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(2, 1866, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<1866; i++) {buffer.getChannelData(c)[i] = 0.174908422905697580329587026426452212035655975341797;}}return buffer;}(); } catch(e) { } +try { o2.playbackRate.value = 1.0; } catch(e) { } +try { o7.threshold.value = 100; } catch(e) { } +try { o1.listener.setVelocity(961.4441892370145, 9.999999999999999e-157, 1) } catch(e) { } +try { o5.getByteFrequencyData(new Uint8Array(2)) } catch(e) { } +try { o6.connect(o10,0,0) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 1176, o1.sampleRate);for(var c=0; c<3; c++) {for(var i=0; i<1176; i++) {buffer.getChannelData(c)[i] = 9.753993292300242;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.playbackRate.linearRampToValueAtTime(0.8687, 32) } catch(e) { } +try { o5.channelCountMode = 'explicit'; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(13, 703, 12723);for(var c=0; c<13; c++) {for(var i=0; i<703; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.loopEnd = 1.7976931348623157e+308; } catch(e) { } +try { o3.connect(o7,0,0) } catch(e) { } +try { o1.destination.channelCountMode = 'clamped-max'; } catch(e) { } +try { o1.destination.channelInterpretation = 'discrete'; } catch(e) { } +try { o2.connect(o10,0,0) } catch(e) { } +try { o3.normalize = false; } catch(e) { } +try { /* switch-case did not return anything. */ } catch(e) { } +try { o10.connect(o8,0,0) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 132, 88507);for(var c=0; c<3; c++) {for(var i=0; i<132; i++) {buffer.getChannelData(c)[i] = 1.7976931348623157e+308;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.loopStart = 1.7976931348623157e+308; } catch(e) { } +try { o1.listener.dopplerFactor = 1024; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(1, 40, o1.sampleRate);for(var c=0; c<1; c++) {for(var i=0; i<40; i++) {buffer.getChannelData(c)[i] = 1.3785770335346594;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o4.connect(o9,5,0) } catch(e) { } +try { o8.curve = new Float32Array(16); } catch(e) { } +try { o10.onaudioprocess = function(e) { /* onEvent */ }; } catch(e) { } +try { o6.channelCountMode = 'explicit'; } catch(e) { } +try { o2.playbackRate.value = 0; } catch(e) { } +try { o4.channelCount = 3; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 220, o1.sampleRate);for(var c=0; c<3; c++) {for(var i=0; i<220; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o1.destination.channelInterpretation = 'discrete'; } catch(e) { } +try { o1.listener.setPosition(70368744177664, 2048, 1.7976931348623157e+308) } catch(e) { } +try { o2.playbackRate.setValueCurveAtTime(new Float32Array(128), 1.7976931348623157e+308, 0.75) } catch(e) { } +try { o5.fftSize = 118; } catch(e) { } +try { o5.minDecibels = 1; } catch(e) { } +try { o7.release.value = 5e-324; } catch(e) { } +try { o2.channelCount = 3; } catch(e) { } +try { o2.channelCountMode = 'clamped-max'; } catch(e) { } +try { o3.normalize = false; } catch(e) { } +try { o1.listener.speedOfSound = 2; } catch(e) { } +try { o2.loopStart = 32; } catch(e) { } +try { o3.channelCountMode = 'max'; } catch(e) { } +try { o1.listener.setPosition(0.37976588317653304, -274877906943, 64) } catch(e) { } +try { o8.curve = new Float32Array(4); } catch(e) { } +try { o1.listener.setVelocity(16, -1024, 0) } catch(e) { } +try { o5.minDecibels = 10000; } catch(e) { } +try { o2.playbackRate.value = 5e-324; } catch(e) { } +try { o3.connect(o9,1,0) } catch(e) { } +try { o10.onaudioprocess = function(e) { /* onEvent */ }; } catch(e) { } +try { o5.connect(o8,0,0) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(3, 554, o1.sampleRate);for(var c=0; c<3; c++) {for(var i=0; i<554; i++) {buffer.getChannelData(c)[i] = 0.000001;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o7.release.value = 0; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(1, 1289, 29583);for(var c=0; c<1; c++) {for(var i=0; i<1289; i++) {buffer.getChannelData(c)[i] = 5e-324;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o1.listener.setOrientation(1024, 64, 16, 1024, 1, 68719476735) } catch(e) { } +try { o1.listener.setOrientation(512, 10000000, 274877906944, 9.999999999999998e-113, -8, 3.6191134923595274) } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(1, 1453, 15258);for(var c=0; c<1; c++) {for(var i=0; i<1453; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o8.channelInterpretation = 'discrete'; } catch(e) { } +try { o5.channelInterpretation = 'discrete'; } catch(e) { } +try { o7.connect(o9,4,0) } catch(e) { } +try { o8.connect(o10,0,0) } catch(e) { } +try { o1.listener.setPosition(18014398509481984, 16, 0.505129302503804056279079759406158700585365295410156250000) } catch(e) { } +try { o10.connect(o9,5,0) } catch(e) { } +try { o2.loop = false; } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(11, 1673, o1.sampleRate);for(var c=0; c<11; c++) {for(var i=0; i<1673; i++) {buffer.getChannelData(c)[i] = 0;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(2, 577, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<577; i++) {buffer.getChannelData(c)[i] = 0.5611;}}return buffer;}() } catch(e) { } +try { o2.connect(o1.destination); } catch(e) { } +try { o1.listener.setOrientation(64, 2049, 5e-324, 0.1777, 2, 7) } catch(e) { } +try { o5.maxDecibels = 128; } catch(e) { } +try { o2.start(0) } catch(e) { } +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/880342-2.html b/dom/media/test/crashtests/880342-2.html new file mode 100644 index 0000000000..a8ef88ae70 --- /dev/null +++ b/dom/media/test/crashtests/880342-2.html @@ -0,0 +1,8 @@ +<script> +try { o1 = new window.AudioContext(2, 10, 1019159); } catch(e) { } +try { o2 = o1.createBufferSource(); } catch(e) { } +try { o3 = o1.createConvolver(); } catch(e) { } +try { o3.buffer = function(){var buffer = o1.createBuffer(2, 741, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<741; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}(); } catch(e) { } +try { o2.buffer = function(){var buffer = o1.createBuffer(2, 120, 42419);for(var c=0; c<2; c++) {for(var i=0; i<120; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}() } catch(e) { } +try { o3.buffer = function(){var buffer = o1.createBuffer(1, 1620, o1.sampleRate);for(var c=0; c<1; c++) {for(var i=0; i<1620; i++) {buffer.getChannelData(c)[i] = -1;}}return buffer;}(); } catch(e) { } +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/880384.html b/dom/media/test/crashtests/880384.html new file mode 100644 index 0000000000..798fbf133d --- /dev/null +++ b/dom/media/test/crashtests/880384.html @@ -0,0 +1,8 @@ +<script> +o1 = new window.AudioContext(3, 256, 44100); +o2 = o1.createBufferSource(); +o3 = o1.createConvolver(); +o3.normalize = false; +o3.buffer = function(){var buffer = o1.createBuffer(2, 1051, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<1051; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}(); +o3.buffer = function(){var buffer = o1.createBuffer(2, 1112, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<1112; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}(); +</script> diff --git a/dom/media/test/crashtests/880404.html b/dom/media/test/crashtests/880404.html new file mode 100644 index 0000000000..bf34932388 --- /dev/null +++ b/dom/media/test/crashtests/880404.html @@ -0,0 +1,6 @@ +<script> +o1 = new window.OfflineAudioContext(2, 32, 44100); +o12 = o1.createConvolver(); +o12.buffer = function(){var buffer = o1.createBuffer(1, 78, o1.sampleRate);for(var c=0; c<1; c++) {for(var i=0; i<78; i++) {buffer.getChannelData(c)[i] = 1;}}return buffer;}(); +o1.startRendering(); +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/880724.html b/dom/media/test/crashtests/880724.html new file mode 100644 index 0000000000..b57b5f9964 --- /dev/null +++ b/dom/media/test/crashtests/880724.html @@ -0,0 +1,13 @@ +<script> +o1 = new window.AudioContext(); +o5 = o1.createConvolver(); +o5.buffer = function() { + var buffer = o1.createBuffer(2, 3, 33120); + for(var c=0; c<2; c++) { + for(var i=0; i<3; i++) { + buffer.getChannelData(c)[i] = -1; + } + } + return buffer; +}(); +</script>
\ No newline at end of file diff --git a/dom/media/test/crashtests/881775.html b/dom/media/test/crashtests/881775.html new file mode 100644 index 0000000000..d55c45d17e --- /dev/null +++ b/dom/media/test/crashtests/881775.html @@ -0,0 +1,25 @@ +<script> +o1 = new window.AudioContext(2, 16, 44100); +o2 = o1.createBufferSource(); +o12 = o1.createBiquadFilter(); +o1.destination.channelCountMode = 'max'; +o2.buffer = function(){ + var buffer = o1.createBuffer(2, 326, 77632); + for(var c=0; c<2; c++) { + for(var i=0; i<326; i++) { + buffer.getChannelData(c)[i] = -1; + } + } + return buffer; +}(); +o2.connect(o1.destination); +o2.buffer = function(){ + var buffer = o1.createBuffer(3, 405, o1.sampleRate); + for(var c=0; c<3; c++) { + for(var i=0; i<405; i++) { + buffer.getChannelData(c)[i] = 1; + } + } + return buffer; +}(); +</script> diff --git a/dom/media/test/crashtests/882956.html b/dom/media/test/crashtests/882956.html new file mode 100644 index 0000000000..ae7b441f99 --- /dev/null +++ b/dom/media/test/crashtests/882956.html @@ -0,0 +1,15 @@ +<script> +o1 = new window.AudioContext(1, 2048, 44100); +o2 = o1.createBufferSource(); +o1.destination.channelCountMode = 'max'; +o2.connect(o1.destination); +o2.buffer = function(){ + var buffer = o1.createBuffer(30, 442, 94933); + for(var c=0; c<30; c++) { + for(var i=0; i<442; i++) { + buffer.getChannelData(c)[i] = 1; + } + } + return buffer; +}(); +</script> diff --git a/dom/media/test/crashtests/884459.html b/dom/media/test/crashtests/884459.html new file mode 100644 index 0000000000..e321d569f2 --- /dev/null +++ b/dom/media/test/crashtests/884459.html @@ -0,0 +1,12 @@ +<script> +var Context0= new window.OfflineAudioContext(14,191531,44100) +var BufferSource1=Context0.createBufferSource(); + +setInterval(function(){ +BufferSource1.playbackRate.setTargetAtTime(0xC8F461D3EE6B2,(Context0.currentTime+0.0677539280615747),0.826130285160616); +BufferSource1.playbackRate.setValueAtTime(35467.63924283907536607336193,0); +},1) + +Context0.startRendering(); + +</script> diff --git a/dom/media/test/crashtests/889042.html b/dom/media/test/crashtests/889042.html new file mode 100644 index 0000000000..9f74979c58 --- /dev/null +++ b/dom/media/test/crashtests/889042.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<script> + (new AudioContext()).createConvolver().buffer = null; +</script> diff --git a/dom/media/test/crashtests/907986-1.html b/dom/media/test/crashtests/907986-1.html new file mode 100644 index 0000000000..4dec6bc480 --- /dev/null +++ b/dom/media/test/crashtests/907986-1.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new window.OfflineAudioContext(1, 100, 48000); +context.oncomplete = function(e) { + document.documentElement.removeAttribute("class"); +}; +// zero front vector +context.listener.setOrientation(0, 0, 0, 6.311749985202524e+307, 0, 0); +var panner = context.createPanner(); +panner.setPosition(3.40282e+38, 4, 3.40282e+38); +panner.connect(context.destination); +var source = context.createOscillator(); +source.connect(panner); +source.start(0); +context.startRendering(); +</script> diff --git a/dom/media/test/crashtests/907986-2.html b/dom/media/test/crashtests/907986-2.html new file mode 100644 index 0000000000..e0626ba2c2 --- /dev/null +++ b/dom/media/test/crashtests/907986-2.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new window.OfflineAudioContext(1, 100, 48000); +context.oncomplete = function(e) { + document.documentElement.removeAttribute("class"); +}; +// zero up vector +context.listener.setOrientation(0, 6.311749985202524e+307, 0, 0, 0, 0); +var panner = context.createPanner(); +panner.setPosition(1, 2, 3); +panner.connect(context.destination); +var source = context.createOscillator(); +source.connect(panner); +source.start(0); +context.startRendering(); +</script> diff --git a/dom/media/test/crashtests/907986-3.html b/dom/media/test/crashtests/907986-3.html new file mode 100644 index 0000000000..75b756c363 --- /dev/null +++ b/dom/media/test/crashtests/907986-3.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new window.OfflineAudioContext(1, 100, 48000); +context.oncomplete = function(e) { + document.documentElement.removeAttribute("class"); +}; +// linearly dependent +context.listener.setOrientation(0, 0, -6.311749985202524e+307, 0, 0, 6.311749985202524e+307); +var panner = context.createPanner(); +panner.setPosition(1, 2, 3); +panner.connect(context.destination); +var source = context.createOscillator(); +source.connect(panner); +source.start(0); +context.startRendering(); +</script> diff --git a/dom/media/test/crashtests/907986-4.html b/dom/media/test/crashtests/907986-4.html new file mode 100644 index 0000000000..a73500efca --- /dev/null +++ b/dom/media/test/crashtests/907986-4.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new window.OfflineAudioContext(1, 100, 48000); +context.oncomplete = function(e) { + document.documentElement.removeAttribute("class"); +}; +var panner = context.createPanner(); +panner.setPosition(0, 3, 0); // directly overhead +panner.connect(context.destination); +var source = context.createOscillator(); +source.connect(panner); +source.start(0); +context.startRendering(); +</script> diff --git a/dom/media/test/crashtests/910171-1.html b/dom/media/test/crashtests/910171-1.html new file mode 100644 index 0000000000..9f3ec831be --- /dev/null +++ b/dom/media/test/crashtests/910171-1.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new window.OfflineAudioContext(1, 4096, 48000); +context.oncomplete = function(e) { + document.documentElement.removeAttribute("class"); +}; +var delay = context.createDelay(); +delay.connect(context.destination); +delay.delayTime.value = 1.0; +var buffer = context.createBuffer(1, 2048, context.sampleRate); +var source = context.createBufferSource(); +source.buffer = buffer; +source.connect(delay); +source.start(); +context.startRendering(); +</script> diff --git a/dom/media/test/crashtests/920987.html b/dom/media/test/crashtests/920987.html new file mode 100644 index 0000000000..6e8b2992a6 --- /dev/null +++ b/dom/media/test/crashtests/920987.html @@ -0,0 +1,6 @@ +<script> +var ctx = new AudioContext(); +var buffer = ctx.createBuffer(1, 1000, ctx.sampleRate); +var array = new Float32Array(900); +buffer.copyToChannel(array, 0, 0xfffffff8); +</script> diff --git a/dom/media/test/crashtests/925619-1.html b/dom/media/test/crashtests/925619-1.html new file mode 100644 index 0000000000..146c531f9b --- /dev/null +++ b/dom/media/test/crashtests/925619-1.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +// 1024 > 89478.5 * 48000 - (1 << 32) +var context = new window.OfflineAudioContext(1, 1024, 48000); +context.oncomplete = function(e) { + document.documentElement.removeAttribute("class"); +}; +var buffer = context.createBuffer(1, 2048, context.sampleRate); +var source = context.createBufferSource(); +source.buffer = buffer; +source.start(89478.5); // 89478.5 is a little greater than 2^32 / 48000. +context.startRendering(); +</script> diff --git a/dom/media/test/crashtests/925619-2.html b/dom/media/test/crashtests/925619-2.html new file mode 100644 index 0000000000..e734b8bcad --- /dev/null +++ b/dom/media/test/crashtests/925619-2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new window.OfflineAudioContext(1, 2048, 48000); +// 1024 > 89478.5 * 48000 - (1 << 32) +var buffer = context.createBuffer(1, 1024, context.sampleRate); +var source = context.createBufferSource(); +source.buffer = buffer; +source.onended = function(e) { + document.documentElement.removeAttribute("class"); +}; +source.start(0); +source.stop(89478.5); // 89478.5 is a little greater than 2^32 / 48000. +context.startRendering(); +</script> diff --git a/dom/media/test/crashtests/926619.html b/dom/media/test/crashtests/926619.html new file mode 100644 index 0000000000..2ead02af4e --- /dev/null +++ b/dom/media/test/crashtests/926619.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + var ac = new window.AudioContext(); + + var _ChannelMergerNode = ac.createChannelMerger(4); + + var _MediaStreamAudioDestinationNode = ac.createMediaStreamDestination(); + var _MediaStream = _MediaStreamAudioDestinationNode.stream; + var _MediaStreamAudioSourceNode = ac.createMediaStreamSource(_MediaStream); + + _ChannelMergerNode.connect(_MediaStreamAudioDestinationNode, 0, 0); + _MediaStreamAudioSourceNode.connect(_ChannelMergerNode, 0, 0); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/933151.html b/dom/media/test/crashtests/933151.html new file mode 100644 index 0000000000..3d45f7af38 --- /dev/null +++ b/dom/media/test/crashtests/933151.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + var ac = new window.AudioContext(); + var buffer = ac.createBuffer(1, 24313, 47250); + buffer.copyFromChannel(buffer.getChannelData(0), ''); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/test/crashtests/933156.html b/dom/media/test/crashtests/933156.html new file mode 100644 index 0000000000..b89445a43d --- /dev/null +++ b/dom/media/test/crashtests/933156.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +function boom() +{ + var ac = new window.AudioContext(); + + var panner = ac.createPanner(); + panner.setPosition(8, 0.7643051305237005, 0.10292575673733972); + + var oscillator = ac.createOscillator(); + oscillator.connect(panner); + oscillator.start(0); + + setTimeout(function() { + panner.panningModel = 'equalpower'; + oscillator.stop(0); + document.documentElement.removeAttribute("class"); + }, 0.5); +} +boom(); +</script> +</html> diff --git a/dom/media/test/crashtests/944851.html b/dom/media/test/crashtests/944851.html new file mode 100644 index 0000000000..4f663accc4 --- /dev/null +++ b/dom/media/test/crashtests/944851.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +var ac = new AudioContext(1, 1354, 44100); +var shaper = ac.createWaveShaper(); +var biquad = ac.createBiquadFilter(); +shaper.connect(biquad.frequency); +biquad.getFrequencyResponse(new Float32Array(55785), + new Float32Array(62876), + new Float32Array(45111)); + +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/952756.html b/dom/media/test/crashtests/952756.html new file mode 100644 index 0000000000..ffced2e400 --- /dev/null +++ b/dom/media/test/crashtests/952756.html @@ -0,0 +1,19 @@ +<script> +var Context0= new AudioContext() +var BufferSource0=Context0.createBufferSource(); +BufferSource0.buffer=function(){ + var length=35887; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(0.39765272522345185))}; + return Buffer; +}(); +BufferSource0.start(0.01932738965842873,0.33345631847623736,0.3893404237460345); +BufferSource0.buffer=function(){ + var length=15952; + var Buffer=Context0.createBuffer(1,length,Context0.sampleRate); + var bufferData= Buffer.getChannelData(0); + for (var i = 0; i < length; ++i) { bufferData[i] = Math.sin(i*(85))}; + return Buffer; +}(); +</script> diff --git a/dom/media/test/crashtests/986901.html b/dom/media/test/crashtests/986901.html new file mode 100644 index 0000000000..343df2c0ed --- /dev/null +++ b/dom/media/test/crashtests/986901.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + var ac = new window.AudioContext(); + var delay1 = ac.createDelay(0.02); + var delay2 = ac.createDelay(0.002); + var source = ac.createOscillator(); + source.start(0); + source.connect(delay1, 0, 0); + delay2.connect(delay1, 0, 0); + delay1.connect(delay2, 0, 0); +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/990794.html b/dom/media/test/crashtests/990794.html new file mode 100644 index 0000000000..8b40088b1a --- /dev/null +++ b/dom/media/test/crashtests/990794.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<script> +var ctx = new AudioContext(); +var source = ctx.createOscillator(); +source.start(0); + +function appendMerger(src) { + const inputCount = 18; + + var merger = ctx.createChannelMerger(32); + + for (var i = 0; i < inputCount; ++i) { + src.connect(merger, 0, i); + } + + return merger; +} + +for (var i = 0; i < 6; ++i) { + source = appendMerger(source); +} +</script> diff --git a/dom/media/test/crashtests/995289.html b/dom/media/test/crashtests/995289.html new file mode 100644 index 0000000000..c988f41fa8 --- /dev/null +++ b/dom/media/test/crashtests/995289.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<script> +var r0=new AudioContext(); +var r5=r0.createOscillator(); +var r6=r0.createPeriodicWave(new Float32Array(1),new Float32Array(1)); +r5.frequency.value = 4294967295; +r5.start(0); +r5.setPeriodicWave(r6); +</script> diff --git a/dom/media/test/crashtests/adts-truncated.aac b/dom/media/test/crashtests/adts-truncated.aac Binary files differnew file mode 100644 index 0000000000..670f696e1d --- /dev/null +++ b/dom/media/test/crashtests/adts-truncated.aac diff --git a/dom/media/test/crashtests/adts.aac b/dom/media/test/crashtests/adts.aac Binary files differnew file mode 100644 index 0000000000..208515464a --- /dev/null +++ b/dom/media/test/crashtests/adts.aac diff --git a/dom/media/test/crashtests/analyser-channels-1.html b/dom/media/test/crashtests/analyser-channels-1.html new file mode 100644 index 0000000000..2f3133cf13 --- /dev/null +++ b/dom/media/test/crashtests/analyser-channels-1.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> + var context = new window.OfflineAudioContext(1, 256, 48000); + var analyser = context.createAnalyser(); + analyser.channelCount = 2; + analyser.channelCountMode = "explicit"; + analyser.fftSize = 32; + var source = context.createOscillator(); + source.connect(analyser); + source.start(0); + context.startRendering(). + then(function() { + document.documentElement.removeAttribute("class"); + }); +</script> diff --git a/dom/media/test/crashtests/audiocontext-after-unload-1.html b/dom/media/test/crashtests/audiocontext-after-unload-1.html new file mode 100644 index 0000000000..9b4f1181d2 --- /dev/null +++ b/dom/media/test/crashtests/audiocontext-after-unload-1.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<title>Test for bug 1646601</title> +<script> +document.addEventListener('DOMContentLoaded', async () => { + const frame = document.createElement('iframe'); + document.body.appendChild(frame); + frame.srcdoc = '<html></html>'; + await new Promise(resolve => frame.onload = resolve); + const subwin = frame.contentWindow; + const subcontext = subwin.AudioContext; + // Construct an AudioContext while the subdocument is fully active to start + // a MediaTrackGraph. + new subcontext(); + // Unload the subdocument and wait for completion. + // This shuts down the MediaTrackGraph. + subwin.location.reload(); + await new Promise(resolve => frame.onload = resolve); + // Test that a new AudioContext on the inactive subdocument does not attempt + // to use the shut-down MediaTrackGraph. + try { new subcontext() } catch {} + document.documentElement.removeAttribute('class'); +}); +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/audiocontext-after-xhr.html b/dom/media/test/crashtests/audiocontext-after-xhr.html new file mode 100644 index 0000000000..a4dd9990ca --- /dev/null +++ b/dom/media/test/crashtests/audiocontext-after-xhr.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> + <script> + document.addEventListener('DOMContentLoaded', () => { + const xhr = new XMLHttpRequest() + xhr.open('G', '', false) + xhr.send() + window.ac = new AudioContext() + }) + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/audiocontext-double-suspend.html b/dom/media/test/crashtests/audiocontext-double-suspend.html new file mode 100644 index 0000000000..98399549bd --- /dev/null +++ b/dom/media/test/crashtests/audiocontext-double-suspend.html @@ -0,0 +1,5 @@ +<script> +var ac = new AudioContext(); +ac.resume(); +ac.resume(); +</script> diff --git a/dom/media/test/crashtests/audioworkletnode-after-unload-1.html b/dom/media/test/crashtests/audioworkletnode-after-unload-1.html new file mode 100644 index 0000000000..7da8d1161a --- /dev/null +++ b/dom/media/test/crashtests/audioworkletnode-after-unload-1.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<title>Test for bug 1634200 and bug 1655544</title> +<script> +document.addEventListener('DOMContentLoaded', async () => { + const frame = document.createElement('iframe'); + document.body.appendChild(frame); + frame.srcdoc = '<html></html>'; + await new Promise(resolve => frame.onload = resolve); + + const subwin = frame.contentWindow; + const ctx = new subwin.AudioContext(); + const url = URL.createObjectURL( + new Blob([`registerProcessor("noop", + class extends AudioWorkletProcessor {})`]), + {type: "application/javascript"}); + await ctx.audioWorklet.addModule(url); + + frame.remove(); + new subwin.AudioWorkletNode(ctx, 'noop') + + document.documentElement.removeAttribute('class'); +}); +</script> +</head> +</html> diff --git a/dom/media/test/crashtests/buffer-source-duration-1.html b/dom/media/test/crashtests/buffer-source-duration-1.html new file mode 100644 index 0000000000..df8d7a37d5 --- /dev/null +++ b/dom/media/test/crashtests/buffer-source-duration-1.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +const rate = 44100; +var context = new window.OfflineAudioContext(1, 512, rate); +var buffer = context.createBuffer(1, 128, rate); +var source = context.createBufferSource(); +source.buffer = buffer; +source.start(0, 0, 86400); +context.startRendering(). + then(function() { + document.documentElement.removeAttribute("class"); + }); +</script> diff --git a/dom/media/test/crashtests/buffer-source-ended-1.html b/dom/media/test/crashtests/buffer-source-ended-1.html new file mode 100644 index 0000000000..de8546316c --- /dev/null +++ b/dom/media/test/crashtests/buffer-source-ended-1.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new AudioContext(); + +var source = context.createBufferSource(); +source.buffer = context.createBuffer(1, 2.0 * context.sampleRate, context.sampleRate); +source.onended = function(e) { + document.documentElement.removeAttribute("class"); +} +source.start(0.0, 1.0); +setTimeout( + function() { + source.buffer = context.createBuffer(1, 1, context.sampleRate); + }, 0); +</script> diff --git a/dom/media/test/crashtests/buffer-source-resampling-start-1.html b/dom/media/test/crashtests/buffer-source-resampling-start-1.html new file mode 100644 index 0000000000..55db8591ed --- /dev/null +++ b/dom/media/test/crashtests/buffer-source-resampling-start-1.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +const rate = 44101; // not divisible by 2 +var context = new window.OfflineAudioContext(1, 512, rate); +var buffer = context.createBuffer(1, 128, rate); +buffer.getChannelData(0)[0] = 1.0; +var source = context.createBufferSource(); +source.buffer = buffer; +source.playbackRate.value = rate / (Math.pow(2, 30) * 1.0000001); +source.start(512 / rate); +context.startRendering(). + then(function() { + document.documentElement.removeAttribute("class"); + }); +</script> diff --git a/dom/media/test/crashtests/buffer-source-slow-resampling-1.html b/dom/media/test/crashtests/buffer-source-slow-resampling-1.html new file mode 100644 index 0000000000..5d8a50442b --- /dev/null +++ b/dom/media/test/crashtests/buffer-source-slow-resampling-1.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +const blockSize = 128; +// The sample rate is a prime number so that the resampler is not expected to +// simplify in/out fractions. +const rate = 44101; +var context = new window.OfflineAudioContext(1, 3 * blockSize, rate); +// Non-zero buffer, so it can't be optimized away. +var buffer = context.createBuffer(1, 128, rate); +buffer.getChannelData(0)[0] = 1.0; +var source = context.createBufferSource(); +source.buffer = buffer; +source.loop = true; +// Initialize the resampler with a slow input rate. +// With the current (Mar 2017) implementation, very slow rates give the +// resampler a very large denominator. +source.playbackRate.setValueAtTime(rate / 0x7fffffff, 0.0); +// Change to a moderate input rate. +// With the current implementation, skip_frac_num increases by den_rate for +// each output sample and so one block before the change in playback rate is +// enough for high skip_frac_num at the time of the change. +const changeBlock = 1; +const changeBlockSeconds = changeBlock * blockSize / rate; +// With the current speex_resampler_set_rate_frac() implementation, the +// moderate resampler denominator is still large enough to trigger overflow of +// 32-bit unsigned integer arithmetic. +source.playbackRate.setValueAtTime(rate / (rate + 1), changeBlockSeconds); +source.start(0); +context.startRendering(). + then(function() { + document.documentElement.removeAttribute("class"); + }); +</script> diff --git a/dom/media/test/crashtests/channel-count-in-metadata-different-than-in-content.mp4 b/dom/media/test/crashtests/channel-count-in-metadata-different-than-in-content.mp4 Binary files differnew file mode 100644 index 0000000000..92bf3722f2 --- /dev/null +++ b/dom/media/test/crashtests/channel-count-in-metadata-different-than-in-content.mp4 diff --git a/dom/media/test/crashtests/convolver-memory-report-1.html b/dom/media/test/crashtests/convolver-memory-report-1.html new file mode 100644 index 0000000000..a49a281d1c --- /dev/null +++ b/dom/media/test/crashtests/convolver-memory-report-1.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title>Bug 1481745: Exercise ConvolverNode memory reporting</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script> +let context = new AudioContext(); +let response = new AudioBuffer({length: 128, + sampleRate: context.sampleRate}); +response.getChannelData(0)[response.length - 1] = 1; +let convolver = new ConvolverNode(context, + {disableNormalization: true, + buffer: response}); +convolver.connect(context.destination); +let osc = new OscillatorNode(context); +osc.connect(convolver); +osc.start(); +osc.stop(128/context.sampleRate); +osc.onended = (e) => { + SpecialPowers.getMemoryReports(); + document.documentElement.removeAttribute("class"); +}; + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/copyFromChannel-2.html b/dom/media/test/crashtests/copyFromChannel-2.html new file mode 100644 index 0000000000..8d3d5a2124 --- /dev/null +++ b/dom/media/test/crashtests/copyFromChannel-2.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> + <title>Crashtest for bug 1548816</title> + <script> +let cx = new OfflineAudioContext({numberOfChannels: 1, + length: 1, sampleRate: 44100}); +let buffer = new AudioBuffer({numberOfChannels: 13, + length: 22050, sampleRate: 44100}); +buffer.getChannelData(12)[0] = 1.0; +let o2248 = new AudioBufferSourceNode(cx, {buffer: buffer}); +let array = new Float32Array(52428); +buffer.copyFromChannel(array, 12); + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/cors.webm b/dom/media/test/crashtests/cors.webm Binary files differnew file mode 100644 index 0000000000..72b0297233 --- /dev/null +++ b/dom/media/test/crashtests/cors.webm diff --git a/dom/media/test/crashtests/cors.webm^headers^ b/dom/media/test/crashtests/cors.webm^headers^ new file mode 100644 index 0000000000..cb762eff80 --- /dev/null +++ b/dom/media/test/crashtests/cors.webm^headers^ @@ -0,0 +1 @@ +Access-Control-Allow-Origin: * diff --git a/dom/media/test/crashtests/crashtests.list b/dom/media/test/crashtests/crashtests.list new file mode 100644 index 0000000000..637b161e7f --- /dev/null +++ b/dom/media/test/crashtests/crashtests.list @@ -0,0 +1,182 @@ +skip-if(OSX) load 1185191.html # this needs to run near the beginning of the test suite +load 0-timescale.html # bug 1229166 +skip-if(Android) pref(media.autoplay.default,0) load 459439-1.html # bug 888557 +load 466607-1.html +load 466945-1.html +load 468763-1.html +load 474744-1.html +HTTP load 481136-1.html # needs to be HTTP to recognize the ogg as an audio file? +load 492286-1.xhtml +load 493915-1.html +pref(media.autoplay.default,0) load 495794-1.html +load 497734-1.xhtml +load 497734-2.html +load 576612-1.html +load 752784-1.html +skip-if(Android) load 789075-1.html # bug 1374405 for android +skip-if(Android&&AndroidVersion=='22') HTTP load 795892-1.html # bug 1358718 +load 844563.html +load 846612.html +load 852838.html +load 865004.html +load 865537-1.html +load 865550.html +load 868504.html +load 874869.html +load 874915.html +load 874934.html +load 874952.html +load 875144.html +load 875596.html +load 875911.html +load 876024-1.html +load 876024-2.html +load 876118.html +load 876207.html +load 876215.html +load 876249.html +load 876252.html +load 876834.html +load 877527.html +load 877820.html +load 878014.html +load 878328.html +load 878407.html +load 878478.html +load 880129.html +load 880202.html +load 880342-1.html +load 880342-2.html +load 880384.html +load 880404.html +load 880724.html +load 881775.html +load 882956.html +load 884459.html +load 889042.html +load 907986-1.html +load 907986-2.html +load 907986-3.html +load 907986-4.html +load 910171-1.html +load 920987.html +load 925619-1.html +load 925619-2.html +load 926619.html +load 933151.html +load 933156.html +load 944851.html +load 952756.html +load 986901.html +load 990794.html +load 995289.html +load 1012609.html +load 1015662.html +skip-if(Android) test-pref(media.navigator.permission.disabled,true) load 1028458.html # bug 1048863 +load 1041466.html +load 1045650.html +load 1080986.html +skip-if(Android&&AndroidVersion=='21') load 1180881.html # bug 1409365 +load 1197935.html +load 1122218.html +load 1127188.html +load 1157994.html +load 1158427.html +load 1185176.html +load 1185192.html +skip-if(Android) load 1257700.html # bug 1575666 +load 1267263.html +load 1270303.html +load 1368490.html +load 1291702.html +load 1378826.html +load 1384248.html +load 1389304.html +load 1393272.webm +load 1411322.html +load 1450845.html +load 1489160.html +load disconnect-wrong-destination.html +load analyser-channels-1.html +load audiocontext-after-unload-1.html +load audiocontext-after-xhr.html +load audiocontext-double-suspend.html +skip-if(Android) load audioworkletnode-after-unload-1.html # Needs secure context +load buffer-source-duration-1.html +load buffer-source-ended-1.html +load buffer-source-resampling-start-1.html +load buffer-source-slow-resampling-1.html +load convolver-memory-report-1.html +load copyFromChannel-2.html +load empty-buffer-source.html +HTTP load media-element-source-seek-1.html +load offline-buffer-source-ended-1.html +load oscillator-ended-1.html +load oscillator-ended-2.html +skip-if(Android&&AndroidVersion=='22') load video-replay-after-audio-end.html # bug 1315125, bug 1358876 +# This needs to run at the end to avoid leaking busted state into other tests. +skip-if(Android||ThreadSanitizer) load 691096-1.html # Bug 1365451 +load 1236639.html +test-pref(media.navigator.permission.disabled,true) test-pref(media.devices.insecure.enabled,true) test-pref(media.getusermedia.insecure.enabled,true) load 1388372.html +load 1414444.mp4 +load 1494073.html +skip-if(Android) load 1526044.html # Bug 1528391 +load 1530897.webm +skip-if(Android&&AndroidVersion<21) load encrypted-track-with-bad-sample-description-index.mp4 # Bug 1533211, unkip after bug 1550912 +load encrypted-track-without-tenc.mp4 # Bug 1533215 +asserts-if(Android,0-1) load encrypted-track-with-sample-missing-cenc-aux.mp4 # Bug 1533625, bug 1588967 +load 1538727.html +load empty-samples.webm # Bug 1540580 +test-pref(media.autoplay.default,0) load 1545133.html +load track-with-zero-dimensions.mp4 # Bug 1542539 +load 1560215.html +skip-if(Android) load 1547784.html # Skip on Android as clearkey is not supported +load 1547899.html +load 1569645.html +load 1575271.html +load 1577184.html +pref(media.autoplay.default,0) load 1587248.html +load 1594466.html +load 1601385.html +load 1601422.html +load 1604941.html +pref(media.autoplay.default,0) load 1673525.html +skip-if(!winWidget) load 1608286.html +load channel-count-in-metadata-different-than-in-content.mp4 # Bug 1584959 +load mp4_box_emptyrange.mp4 # Bug 1667480 +load 1673526-1.html +load 1673526-2.html +load 1693043.html +load 1696511.html +load 1697521.html +load 1708790.html +skip-if(cocoaWidget) load 1709130.html # video failed decoding on MacOS, 1709684 +skip-if(appleSilicon) load 1517199.html +load 1734008.html +load 1741677.html +load 1748272.html +load 1752917.html +load 1762620.html +load 1765842.html +load adts.aac # Bug 1770073 +load 1787281.html +load 1798778.html +load 1830206.html +load 1833896.mp4 +load 1833894.mp4 +load 1835164.html +load 1840002.webm +load 1845350.mp4 +load noextradata-8ch.html +load invalidfmt.html +load 1848660.html +load 1835118.adts +load trimming_needed_and_last_sample_invalid_duration.ogg +load 1839193.html +load 1850453.html +test-pref(media.wmf.hevc.enabled,1) load 1859384.mp4 +test-pref(media.wmf.hevc.enabled,1) load 1859600.mp4 +test-pref(media.wmf.hevc.enabled,1) load 1860840.mp4 +load 1864450.html +load 1872787.html +load small-timebase.html diff --git a/dom/media/test/crashtests/disconnect-wrong-destination.html b/dom/media/test/crashtests/disconnect-wrong-destination.html new file mode 100644 index 0000000000..515ca3c877 --- /dev/null +++ b/dom/media/test/crashtests/disconnect-wrong-destination.html @@ -0,0 +1,13 @@ +<script> + var oc = new OfflineAudioContext(1, 1, 44100); + var splitter = oc.createChannelSplitter(2); + var merger0 = oc.createChannelMerger(2); + var merger1 = oc.createChannelMerger(2); + splitter.connect(merger0, 0); + splitter.connect(merger0, 1); + splitter.connect(merger1, 0); + splitter.connect(merger1, 1); + + splitter.disconnect(merger0, 0); + splitter.disconnect(merger1, 1); +</script> diff --git a/dom/media/test/crashtests/doppler-1.html b/dom/media/test/crashtests/doppler-1.html new file mode 100644 index 0000000000..2af3c8f460 --- /dev/null +++ b/dom/media/test/crashtests/doppler-1.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new window.AudioContext(); +var source = context.createBufferSource(); +source.buffer = context.createBuffer(1, 1, context.sampleRate); +source.onended = + function(e) { + setTimeout( + function() { + var panner = context.createPanner(); + source.connect(panner); + panner.setVelocity(1.0, 0.0, 0.0); + setTimeout( + function() { + document.documentElement.removeAttribute("class"); + }, + 0); + }, + 0); + }; +source.start(0); +</script> diff --git a/dom/media/test/crashtests/empty-buffer-source.html b/dom/media/test/crashtests/empty-buffer-source.html new file mode 100644 index 0000000000..2ce48a9ec1 --- /dev/null +++ b/dom/media/test/crashtests/empty-buffer-source.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title>Bug 1636540: AudioBufferSourceNode with empty buffer</title> + <script> +const offline = new OfflineAudioContext({length: 128, sampleRate: 16384}); +const buffer = new AudioBuffer({length: 1, sampleRate: 21725}); +const node = new AudioBufferSourceNode(offline, {buffer: buffer}); +node.start(5/offline.sampleRate); +offline.startRendering().then( + () => document.documentElement.removeAttribute("class")); + </script> +</head> +</html> diff --git a/dom/media/test/crashtests/empty-samples.webm b/dom/media/test/crashtests/empty-samples.webm new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/dom/media/test/crashtests/empty-samples.webm diff --git a/dom/media/test/crashtests/encrypted-track-with-bad-sample-description-index.mp4 b/dom/media/test/crashtests/encrypted-track-with-bad-sample-description-index.mp4 Binary files differnew file mode 100644 index 0000000000..32303f0357 --- /dev/null +++ b/dom/media/test/crashtests/encrypted-track-with-bad-sample-description-index.mp4 diff --git a/dom/media/test/crashtests/encrypted-track-with-sample-missing-cenc-aux.mp4 b/dom/media/test/crashtests/encrypted-track-with-sample-missing-cenc-aux.mp4 Binary files differnew file mode 100644 index 0000000000..875c5dca76 --- /dev/null +++ b/dom/media/test/crashtests/encrypted-track-with-sample-missing-cenc-aux.mp4 diff --git a/dom/media/test/crashtests/encrypted-track-without-tenc.mp4 b/dom/media/test/crashtests/encrypted-track-without-tenc.mp4 Binary files differnew file mode 100644 index 0000000000..188faebf1b --- /dev/null +++ b/dom/media/test/crashtests/encrypted-track-without-tenc.mp4 diff --git a/dom/media/test/crashtests/invalidfmt.html b/dom/media/test/crashtests/invalidfmt.html new file mode 100644 index 0000000000..10c951dcf8 --- /dev/null +++ b/dom/media/test/crashtests/invalidfmt.html @@ -0,0 +1,8 @@ +<html class="reftest-wait"> + <audio + onerror="document.documentElement.removeAttribute('class')" + autoplay + controls + src="fmttoosmall.wav" + ></audio> +</html> diff --git a/dom/media/test/crashtests/invalidfmt.wav b/dom/media/test/crashtests/invalidfmt.wav Binary files differnew file mode 100644 index 0000000000..2939c836b9 --- /dev/null +++ b/dom/media/test/crashtests/invalidfmt.wav diff --git a/dom/media/test/crashtests/media-element-source-seek-1.html b/dom/media/test/crashtests/media-element-source-seek-1.html new file mode 100644 index 0000000000..5c3aed5ae7 --- /dev/null +++ b/dom/media/test/crashtests/media-element-source-seek-1.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var audioElement = document.createElement("audio"); +audioElement.autoplay = true; +audioElement.src = "sound.ogg"; +audioElement.onplaying = + function() { + audioElement.onplaying = null; + setTimeout( + function() { + audioElement.onseeked = + function() { + // Note we reset 'src' to release decoder resources and cubeb + // streams to prevent OOM or OpenCubeb() failures. + audioElement.src = ""; + document.documentElement.removeAttribute("class"); + }; + audioElement.currentTime = 0; + }, 100); + }; + +var context = new window.AudioContext(); +var source = context.createMediaElementSource(audioElement); +source.connect(context.destination); +</script> +</html> diff --git a/dom/media/test/crashtests/mp4_box_emptyrange.mp4 b/dom/media/test/crashtests/mp4_box_emptyrange.mp4 Binary files differnew file mode 100644 index 0000000000..83057533a0 --- /dev/null +++ b/dom/media/test/crashtests/mp4_box_emptyrange.mp4 diff --git a/dom/media/test/crashtests/noextradata-8ch.wav b/dom/media/test/crashtests/noextradata-8ch.wav Binary files differnew file mode 100644 index 0000000000..40587a7de9 --- /dev/null +++ b/dom/media/test/crashtests/noextradata-8ch.wav diff --git a/dom/media/test/crashtests/offline-buffer-source-ended-1.html b/dom/media/test/crashtests/offline-buffer-source-ended-1.html new file mode 100644 index 0000000000..0631021126 --- /dev/null +++ b/dom/media/test/crashtests/offline-buffer-source-ended-1.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +var context = new window.OfflineAudioContext(1, 12001, 12000); + +var source = context.createBufferSource(); +source.buffer = context.createBuffer(1, 12000, context.sampleRate); +source.onended = function(e) { + document.documentElement.removeAttribute("class"); +} +source.connect(context.destination); +source.start(0); + +context.startRendering(); +</script> diff --git a/dom/media/test/crashtests/oscillator-ended-1.html b/dom/media/test/crashtests/oscillator-ended-1.html new file mode 100644 index 0000000000..831111261c --- /dev/null +++ b/dom/media/test/crashtests/oscillator-ended-1.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +function createContext() { + var context = new window.AudioContext(); + var source = context.createOscillator(); + source.onended = function(e) { + document.documentElement.removeAttribute("class"); + }; + source.connect(context.destination); + source.start(0.49); + source.stop(0.5); +} +createContext(); +</script> diff --git a/dom/media/test/crashtests/oscillator-ended-2.html b/dom/media/test/crashtests/oscillator-ended-2.html new file mode 100644 index 0000000000..ee9b8cf300 --- /dev/null +++ b/dom/media/test/crashtests/oscillator-ended-2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +function createContext() { + var context = new window.AudioContext(); + var source = context.createOscillator(); + source.onended = function(e) { + document.documentElement.removeAttribute("class"); + }; + source.connect(context.destination); + source.start(60); + source.stop(0.5); +} +createContext(); +</script> diff --git a/dom/media/test/crashtests/small-timebase.html b/dom/media/test/crashtests/small-timebase.html new file mode 100644 index 0000000000..fffc518e4a --- /dev/null +++ b/dom/media/test/crashtests/small-timebase.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<video id=a src=small-timebase.mp4 controls autoplay></video> +<script> +a.onplaying = function() { + dump("OK"); + document.documentElement.removeAttribute("class"); +} +</script> +</html> diff --git a/dom/media/test/crashtests/small-timebase.mp4 b/dom/media/test/crashtests/small-timebase.mp4 Binary files differnew file mode 100644 index 0000000000..f2fba95cce --- /dev/null +++ b/dom/media/test/crashtests/small-timebase.mp4 diff --git a/dom/media/test/crashtests/sound.ogg b/dom/media/test/crashtests/sound.ogg Binary files differnew file mode 100644 index 0000000000..edda4e9128 --- /dev/null +++ b/dom/media/test/crashtests/sound.ogg diff --git a/dom/media/test/crashtests/test.mp4 b/dom/media/test/crashtests/test.mp4 Binary files differnew file mode 100644 index 0000000000..44d7ee9cbc --- /dev/null +++ b/dom/media/test/crashtests/test.mp4 diff --git a/dom/media/test/crashtests/track-with-zero-dimensions.mp4 b/dom/media/test/crashtests/track-with-zero-dimensions.mp4 Binary files differnew file mode 100644 index 0000000000..3f4a1317f3 --- /dev/null +++ b/dom/media/test/crashtests/track-with-zero-dimensions.mp4 diff --git a/dom/media/test/crashtests/trimming_needed_and_last_sample_invalid_duration.ogg b/dom/media/test/crashtests/trimming_needed_and_last_sample_invalid_duration.ogg Binary files differnew file mode 100644 index 0000000000..593c489ec1 --- /dev/null +++ b/dom/media/test/crashtests/trimming_needed_and_last_sample_invalid_duration.ogg diff --git a/dom/media/test/crashtests/video-crash.webm b/dom/media/test/crashtests/video-crash.webm Binary files differnew file mode 100644 index 0000000000..9532113d87 --- /dev/null +++ b/dom/media/test/crashtests/video-crash.webm diff --git a/dom/media/test/crashtests/video-replay-after-audio-end.html b/dom/media/test/crashtests/video-replay-after-audio-end.html new file mode 100644 index 0000000000..9ffd6078de --- /dev/null +++ b/dom/media/test/crashtests/video-replay-after-audio-end.html @@ -0,0 +1,43 @@ +<html class="reftest-wait"> +<head> + <title> Bug 1242774 : video crashed if pause and play again after audio track ends </title> +</head> +<body> +<script type="text/javascript"> +function assert(value, msg) { + if (!value) { + dump("### Error : " + msg + "\n"); + } +} + +var AUDIO_END_TIME = 4.5; +var video = document.createElement('video'); +video.src = "video-crash.webm"; +video.play(); + +video.ontimeupdate = function () { + assert(AUDIO_END_TIME < video.duration, + "AUDIO_END_TIME should be smaller than the duration!"); + + if (video.currentTime > AUDIO_END_TIME) { + dump("### Pause video during silent part.\n"); + video.ontimeupdate = null; + video.pause(); + } + + video.onpause = function () { + video.onpause = null; + setTimeout(function() { + dump("### Re-play after pausing during silent part.\n"); + video.play(); + video.onended = function () { + video.onended = null; + dump("### Video is ended.\n"); + document.documentElement.removeAttribute("class"); + } + }, 1000); + } +} +</script> +</body> +</html>
\ No newline at end of file diff --git a/dom/media/test/dash/dash-manifest-garbled-webm.mpd b/dom/media/test/dash/dash-manifest-garbled-webm.mpd new file mode 100644 index 0000000000..aa78ded3ec --- /dev/null +++ b/dom/media/test/dash/dash-manifest-garbled-webm.mpd @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<MPD + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:mpeg:DASH:schema:MPD:2011" + xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011" + type="static" + mediaPresentationDuration="PT3.958S" + minBufferTime="PT1S" + profiles="urn:webm:dash:profile:webm-on-demand:2012"> + <BaseURL>./</BaseURL> + <Period id="0" start="PT0S" duration="PT3.958S" > + <AdaptationSet id="0" mimeType="video/webm" codecs="vp8" lang="eng" subsegmentAlignment="true" subsegmentStartsWithSAP="1" bitstreamSwitching="true"> + <Representation id="0" bandwidth="54207" width="320" height="180"> + <BaseURL>garbled.webm</BaseURL> + <SegmentBase indexRange="35090-35123"> + <Initialization range="0-228" /> + </SegmentBase> + </Representation> + <Representation id="1" bandwidth="78006" width="428" height="240"> + <BaseURL>dash-webm-video-428x240.webm</BaseURL> + <SegmentBase indexRange="50173-50206"> + <Initialization range="0-228" /> + </SegmentBase> + </Representation> + </AdaptationSet> + <AdaptationSet id="1" mimeType="audio/webm" codecs="vorbis" lang="eng" audioSamplingRate="48000" subsegmentStartsWithSAP="1"> + <Representation id="2" bandwidth="57264"> + <BaseURL>dash-webm-audio-128k.webm</BaseURL> + <SegmentBase indexRange="41927-41946"> + <Initialization range="0-4521" /> + </SegmentBase> + </Representation> + </AdaptationSet> + </Period> +</MPD> diff --git a/dom/media/test/dash/dash-manifest-garbled.mpd b/dom/media/test/dash/dash-manifest-garbled.mpd new file mode 100644 index 0000000000..ac8eadbddc --- /dev/null +++ b/dom/media/test/dash/dash-manifest-garbled.mpd @@ -0,0 +1 @@ +PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxNUEQgbWVkaWFQcmVzZW50YXRpb25EdXJhdGlvbj0iUFQxOS41MVMiIG1pbkJ1ZmZlclRpbWU9IlBUMVMiIHByb2ZpbGVzPSJ1cm46d2VibTpkYXNoOnByb2ZpbGU6d2VibS1vbi1kZW1hbmQ6MjAxMiIgdHlwZT0ic3RhdGljIiB4bWxucz0idXJuOm1wZWc6REFTSDpzY2hlbWE6TVBEOjIwMTEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTpzY2hlbWFMb2NhdGlvbj0idXJuOm1wZWc6REFTSDpzY2hlbWE6TVBEOjIwMTEiPjxCYXNlVVJMPmh0dHA6Ly93d3cuZ29vZ2xlLmNvbTwvQmFzZVVSTD48UGVyaW9kIGR1cmF0aW9uPSJQVDE5LjUxUyIgaWQ9IjAiIHN0YXJ0PSJQVDBTIj48QWRhcHRhdGlvblNldCBhdWRpb1NhbXBsaW5nUmF0ZT0iNDgwMDAiIGNvZGVjcz0idm9yYmlzIiBpZD0iMSIgbGFuZz0iZW5nIiBtaW1lVHlwZT0iYXVkaW8vd2VibSIgc3Vic2VnbWVudFN0YXJ0c1dpdGhTQVA9IjEiPjxSZXByZXNlbnRhdGlvbiBiYW5kd2lkdGg9IjIwMTA5IiBpZD0iMiI+PEJhc2VVUkwvPjxTZWdtZW50QmFzZSBpbmRleFJhbmdlPSIzMTk3ODAtMzIwNjEyIj48SW5pdGlhbGl6YXRpb24gcmFuZ2U9IjAtMjA4NzAiLz48L1NlZ21lbnRCYXNlPjwvUmVwcmVzZW50YXRpb24+PC9BZGFwdGF0aW9uU2V0PjwvUGVyaW9kPjwvTVBEPg diff --git a/dom/media/test/dash/dash-manifest-sjs.mpd b/dom/media/test/dash/dash-manifest-sjs.mpd new file mode 100644 index 0000000000..c7ecba3c69 --- /dev/null +++ b/dom/media/test/dash/dash-manifest-sjs.mpd @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<MPD + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:mpeg:DASH:schema:MPD:2011" + xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011" + type="static" + mediaPresentationDuration="PT3.958S" + minBufferTime="PT1S" + profiles="urn:webm:dash:profile:webm-on-demand:2012"> + <BaseURL>./dash_detect_stream_switch.sjs?name=</BaseURL> + <Period id="0" start="PT0S" duration="PT3.958S" > + <AdaptationSet id="0" mimeType="video/webm" codecs="vp8" lang="eng" subsegmentAlignment="true" subsegmentStartsWithSAP="1" bitstreamSwitching="true"> + <Representation id="0" bandwidth="54207" width="320" height="180"> + <BaseURL>dash-webm-video-320x180.webm</BaseURL> + <SegmentBase indexRange="35090-35123"> + <Initialization range="0-228" /> + </SegmentBase> + </Representation> + <Representation id="1" bandwidth="78006" width="428" height="240"> + <BaseURL>dash-webm-video-428x240.webm</BaseURL> + <SegmentBase indexRange="50173-50206"> + <Initialization range="0-228" /> + </SegmentBase> + </Representation> + </AdaptationSet> + <AdaptationSet id="1" mimeType="audio/webm" codecs="vorbis" lang="eng" audioSamplingRate="48000" subsegmentStartsWithSAP="1"> + <Representation id="2" bandwidth="57264"> + <BaseURL>dash-webm-audio-128k.webm</BaseURL> + <SegmentBase indexRange="41927-41946"> + <Initialization range="0-4521" /> + </SegmentBase> + </Representation> + </AdaptationSet> + </Period> +</MPD> diff --git a/dom/media/test/dash/dash-manifest.mpd b/dom/media/test/dash/dash-manifest.mpd new file mode 100644 index 0000000000..98c7a90480 --- /dev/null +++ b/dom/media/test/dash/dash-manifest.mpd @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<MPD + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:mpeg:DASH:schema:MPD:2011" + xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011" + type="static" + mediaPresentationDuration="PT3.958S" + minBufferTime="PT1S" + profiles="urn:webm:dash:profile:webm-on-demand:2012"> + <BaseURL>./</BaseURL> + <Period id="0" start="PT0S" duration="PT3.958S" > + <AdaptationSet id="0" mimeType="video/webm" codecs="vp8" lang="eng" subsegmentAlignment="true" subsegmentStartsWithSAP="1" bitstreamSwitching="true"> + <Representation id="0" bandwidth="54207" width="320" height="180"> + <BaseURL>dash-webm-video-320x180.webm</BaseURL> + <SegmentBase indexRange="35090-35123"> + <Initialization range="0-228" /> + </SegmentBase> + </Representation> + <Representation id="1" bandwidth="78006" width="428" height="240"> + <BaseURL>dash-webm-video-428x240.webm</BaseURL> + <SegmentBase indexRange="50173-50206"> + <Initialization range="0-228" /> + </SegmentBase> + </Representation> + </AdaptationSet> + <AdaptationSet id="1" mimeType="audio/webm" codecs="vorbis" lang="eng" audioSamplingRate="48000" subsegmentStartsWithSAP="1"> + <Representation id="2" bandwidth="57264"> + <BaseURL>dash-webm-audio-128k.webm</BaseURL> + <SegmentBase indexRange="41927-41946"> + <Initialization range="0-4521" /> + </SegmentBase> + </Representation> + </AdaptationSet> + </Period> +</MPD> diff --git a/dom/media/test/dash/dash-webm-audio-128k.webm b/dom/media/test/dash/dash-webm-audio-128k.webm Binary files differnew file mode 100644 index 0000000000..f56c042053 --- /dev/null +++ b/dom/media/test/dash/dash-webm-audio-128k.webm diff --git a/dom/media/test/dash/dash-webm-video-320x180.webm b/dom/media/test/dash/dash-webm-video-320x180.webm Binary files differnew file mode 100644 index 0000000000..282e6a2cc3 --- /dev/null +++ b/dom/media/test/dash/dash-webm-video-320x180.webm diff --git a/dom/media/test/dash/dash-webm-video-428x240.webm b/dom/media/test/dash/dash-webm-video-428x240.webm Binary files differnew file mode 100644 index 0000000000..23f2c89616 --- /dev/null +++ b/dom/media/test/dash/dash-webm-video-428x240.webm diff --git a/dom/media/test/dash/garbled.webm b/dom/media/test/dash/garbled.webm new file mode 100644 index 0000000000..ac8eadbddc --- /dev/null +++ b/dom/media/test/dash/garbled.webm @@ -0,0 +1 @@ +PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxNUEQgbWVkaWFQcmVzZW50YXRpb25EdXJhdGlvbj0iUFQxOS41MVMiIG1pbkJ1ZmZlclRpbWU9IlBUMVMiIHByb2ZpbGVzPSJ1cm46d2VibTpkYXNoOnByb2ZpbGU6d2VibS1vbi1kZW1hbmQ6MjAxMiIgdHlwZT0ic3RhdGljIiB4bWxucz0idXJuOm1wZWc6REFTSDpzY2hlbWE6TVBEOjIwMTEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTpzY2hlbWFMb2NhdGlvbj0idXJuOm1wZWc6REFTSDpzY2hlbWE6TVBEOjIwMTEiPjxCYXNlVVJMPmh0dHA6Ly93d3cuZ29vZ2xlLmNvbTwvQmFzZVVSTD48UGVyaW9kIGR1cmF0aW9uPSJQVDE5LjUxUyIgaWQ9IjAiIHN0YXJ0PSJQVDBTIj48QWRhcHRhdGlvblNldCBhdWRpb1NhbXBsaW5nUmF0ZT0iNDgwMDAiIGNvZGVjcz0idm9yYmlzIiBpZD0iMSIgbGFuZz0iZW5nIiBtaW1lVHlwZT0iYXVkaW8vd2VibSIgc3Vic2VnbWVudFN0YXJ0c1dpdGhTQVA9IjEiPjxSZXByZXNlbnRhdGlvbiBiYW5kd2lkdGg9IjIwMTA5IiBpZD0iMiI+PEJhc2VVUkwvPjxTZWdtZW50QmFzZSBpbmRleFJhbmdlPSIzMTk3ODAtMzIwNjEyIj48SW5pdGlhbGl6YXRpb24gcmFuZ2U9IjAtMjA4NzAiLz48L1NlZ21lbnRCYXNlPjwvUmVwcmVzZW50YXRpb24+PC9BZGFwdGF0aW9uU2V0PjwvUGVyaW9kPjwvTVBEPg diff --git a/dom/media/test/dash_detect_stream_switch.sjs b/dom/media/test/dash_detect_stream_switch.sjs new file mode 100644 index 0000000000..b8480a1274 --- /dev/null +++ b/dom/media/test/dash_detect_stream_switch.sjs @@ -0,0 +1,143 @@ +/* -*- Mode: JavaScript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* dash_detect_stream_switch.sjs + * + * Parses requests for DASH manifests and ensures stream switching takes place + * by verifying the subsegments downloaded and the streams they belong to. + * If unexpected subsegments (byte ranges) are requested, the script will + * will respond with a 404. + */ + +var DEBUG = false; + +function parseQuery(request, key) { + var params = request.queryString.split("&"); + if (DEBUG) { + dump('DASH-SJS: request params = "' + params + '"\n'); + } + for (var j = 0; j < params.length; ++j) { + var p = params[j]; + if (p == key) { + return true; + } + if (p.indexOf(key + "=") === 0) { + return p.substring(key.length + 1); + } + if (!p.includes("=") && key === "") { + return p; + } + } + return false; +} + +function handleRequest(request, response) { + try { + var name = parseQuery(request, "name"); + var range = request.hasHeader("Range") + ? request.getHeader("Range") + : undefined; + + // Should not get request for 1st subsegment from 2nd stream, nor 2nd + // subsegment from 1st stream. + if ( + (name == "dash-webm-video-320x180.webm" && + range == "bytes=25514-32767") || + (name == "dash-webm-video-428x240.webm" && range == "bytes=228-35852") + ) { + throw new Error( + "Should not request " + name + " with byte-range " + range + ); + } else { + var rangeSplit = range.split("="); + if (rangeSplit.length != 2) { + throw new Error( + "DASH-SJS: ERROR: invalid number of tokens (" + + rangeSplit.length + + ") delimited by '=' in 'Range' header." + ); + } + var offsets = rangeSplit[1].split("-"); + if (offsets.length != 2) { + throw new Error( + "DASH-SJS: ERROR: invalid number of tokens (" + + offsets.length + + ") delimited by '-' in 'Range' header." + ); + } + var startOffset = parseInt(offsets[0]); + var endOffset = parseInt(offsets[1]); + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + + var paths = "tests/dom/media/test/" + name; + var split = paths.split("/"); + for (var i = 0; i < split.length; ++i) { + file.append(split[i]); + } + + fis.init(file, -1, -1, false); + // Exception: start offset should be within file bounds. + if (startOffset > file.fileSize) { + throw new Error( + "Starting offset [" + + startOffset + + "] is after end of file [" + + file.fileSize + + "]." + ); + } + // End offset may be too large in the MPD. Real world HTTP servers just + // return what data they can; do the same here - reduce the end offset. + if (endOffset >= file.fileSize) { + if (DEBUG) { + dump( + "DASH-SJS: reducing endOffset [" + + endOffset + + "] to fileSize [" + + (file.fileSize - 1) + + "]\n" + ); + } + endOffset = file.fileSize - 1; + } + fis.seek(Ci.nsISeekableStream.NS_SEEK_SET, startOffset); + bis.setInputStream(fis); + + var byteLengthToRead = endOffset + 1 - startOffset; + var totalBytesExpected = byteLengthToRead + startOffset; + if (DEBUG) { + dump( + "DASH-SJS: byteLengthToRead = " + + byteLengthToRead + + " byteLengthToRead+startOffset = " + + totalBytesExpected + + " fileSize = " + + file.fileSize + + "\n" + ); + } + + var bytes = bis.readBytes(byteLengthToRead); + response.setStatusLine(request.httpVersion, 206, "Partial Content"); + response.setHeader("Content-Length", "" + bytes.length, false); + response.setHeader("Content-Type", "application/dash+xml", false); + var contentRange = + "bytes " + startOffset + "-" + endOffset + "/" + file.fileSize; + response.setHeader("Content-Range", contentRange, false); + response.write(bytes, bytes.length); + bis.close(); + } + } catch (e) { + dump("DASH-SJS-ERROR: " + e + "\n"); + response.setStatusLine(request.httpVersion, 404, "Not found"); + } +} diff --git a/dom/media/test/detodos-recorder-test.opus b/dom/media/test/detodos-recorder-test.opus Binary files differnew file mode 100644 index 0000000000..88b2eab0f8 --- /dev/null +++ b/dom/media/test/detodos-recorder-test.opus diff --git a/dom/media/test/detodos-recorder-test.opus^headers^ b/dom/media/test/detodos-recorder-test.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/detodos-recorder-test.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/detodos-short.opus b/dom/media/test/detodos-short.opus Binary files differnew file mode 100644 index 0000000000..8bda283fc5 --- /dev/null +++ b/dom/media/test/detodos-short.opus diff --git a/dom/media/test/detodos-short.opus^headers^ b/dom/media/test/detodos-short.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/detodos-short.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/detodos-short.webm b/dom/media/test/detodos-short.webm Binary files differnew file mode 100644 index 0000000000..45af2675a6 --- /dev/null +++ b/dom/media/test/detodos-short.webm diff --git a/dom/media/test/detodos-short.webm^headers^ b/dom/media/test/detodos-short.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/detodos-short.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/detodos.opus b/dom/media/test/detodos.opus Binary files differnew file mode 100644 index 0000000000..6c7ba88a66 --- /dev/null +++ b/dom/media/test/detodos.opus diff --git a/dom/media/test/detodos.opus^headers^ b/dom/media/test/detodos.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/detodos.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/detodos.webm b/dom/media/test/detodos.webm Binary files differnew file mode 100644 index 0000000000..39cfa7f537 --- /dev/null +++ b/dom/media/test/detodos.webm diff --git a/dom/media/test/detodos.webm^headers^ b/dom/media/test/detodos.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/detodos.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/dirac.ogg b/dom/media/test/dirac.ogg Binary files differnew file mode 100644 index 0000000000..2986cf1e80 --- /dev/null +++ b/dom/media/test/dirac.ogg diff --git a/dom/media/test/dirac.ogg^headers^ b/dom/media/test/dirac.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/dirac.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/dynamic_resource.sjs b/dom/media/test/dynamic_resource.sjs new file mode 100644 index 0000000000..98c02e552d --- /dev/null +++ b/dom/media/test/dynamic_resource.sjs @@ -0,0 +1,53 @@ +function parseQuery(request, key) { + var params = request.queryString.split("&"); + for (var j = 0; j < params.length; ++j) { + var p = params[j]; + if (p == key) { + return true; + } + if (p.indexOf(key + "=") == 0) { + return p.substring(key.length + 1); + } + if (!p.includes("=") && key == "") { + return p; + } + } + return false; +} + +// Return resource1 file content for the first request with a given key. +// All subsequent requests return resource2. Both must be video/ogg. +function handleRequest(request, response) { + var key = parseQuery(request, "key"); + var resource1 = parseQuery(request, "res1"); + var resource2 = parseQuery(request, "res2"); + + var resource = getState(key) == "2" ? resource2 : resource1; + setState(key, "2"); + + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + var paths = "tests/dom/media/test/" + resource; + var split = paths.split("/"); + for (var i = 0; i < split.length; ++i) { + file.append(split[i]); + } + fis.init(file, -1, -1, false); + dump("file=" + file + "\n"); + bis.setInputStream(fis); + var bytes = bis.readBytes(bis.available()); + response.setStatusLine(request.httpVersion, 206, "Partial Content"); + response.setHeader( + "Content-Range", + "bytes 0-" + (bytes.length - 1) + "/" + bytes.length + ); + response.setHeader("Content-Length", "" + bytes.length, false); + response.setHeader("Content-Type", "video/ogg", false); + response.write(bytes, bytes.length); + bis.close(); +} diff --git a/dom/media/test/eme.js b/dom/media/test/eme.js new file mode 100644 index 0000000000..927c99876a --- /dev/null +++ b/dom/media/test/eme.js @@ -0,0 +1,479 @@ +/* import-globals-from manifest.js */ + +const CLEARKEY_KEYSYSTEM = "org.w3.clearkey"; + +const gCencMediaKeySystemConfig = [ + { + initDataTypes: ["cenc"], + videoCapabilities: [{ contentType: "video/mp4" }], + audioCapabilities: [{ contentType: "audio/mp4" }], + }, +]; + +function bail(message) { + return function (err) { + if (err) { + message += "; " + String(err); + } + ok(false, message); + if (err) { + info(String(err)); + } + SimpleTest.finish(); + }; +} + +function ArrayBufferToString(arr) { + var str = ""; + var view = new Uint8Array(arr); + for (var i = 0; i < view.length; i++) { + str += String.fromCharCode(view[i]); + } + return str; +} + +function StringToArrayBuffer(str) { + var arr = new ArrayBuffer(str.length); + var view = new Uint8Array(arr); + for (var i = 0; i < str.length; i++) { + view[i] = str.charCodeAt(i); + } + return arr; +} + +function StringToHex(str) { + var res = ""; + for (var i = 0; i < str.length; ++i) { + res += ("0" + str.charCodeAt(i).toString(16)).slice(-2); + } + return res; +} + +function Base64ToHex(str) { + var bin = window.atob(str.replace(/-/g, "+").replace(/_/g, "/")); + var res = ""; + for (var i = 0; i < bin.length; i++) { + res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2); + } + return res; +} + +function HexToBase64(hex) { + var bin = ""; + for (var i = 0; i < hex.length; i += 2) { + bin += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + } + return window + .btoa(bin) + .replace(/=/g, "") + .replace(/\+/g, "-") + .replace(/\//g, "_"); +} + +function TimeRangesToString(trs) { + var l = trs.length; + if (l === 0) { + return "-"; + } + var s = ""; + var i = 0; + for (;;) { + s += trs.start(i) + "-" + trs.end(i); + if (++i === l) { + return s; + } + s += ","; + } +} + +function SourceBufferToString(sb) { + return ( + "SourceBuffer{" + + "AppendMode=" + + (sb.AppendMode || "-") + + ", updating=" + + (sb.updating ? "true" : "false") + + ", buffered=" + + TimeRangesToString(sb.buffered) + + ", audioTracks=" + + (sb.audioTracks ? sb.audioTracks.length : "-") + + ", videoTracks=" + + (sb.videoTracks ? sb.videoTracks.length : "-") + + "}" + ); +} + +function SourceBufferListToString(sbl) { + return "SourceBufferList[" + sbl.map(SourceBufferToString).join(", ") + "]"; +} + +function GenerateClearKeyLicense(licenseRequest, keyStore) { + var msgStr = ArrayBufferToString(licenseRequest); + var msg = JSON.parse(msgStr); + + var keys = []; + for (var i = 0; i < msg.kids.length; i++) { + var id64 = msg.kids[i]; + var idHex = Base64ToHex(msg.kids[i]).toLowerCase(); + var key = keyStore[idHex]; + + if (key) { + keys.push({ + kty: "oct", + kid: id64, + k: HexToBase64(key), + }); + } + } + + return new TextEncoder().encode( + JSON.stringify({ + keys, + type: msg.type || "temporary", + }) + ); +} + +function UpdateSessionFunc(test, token, sessionType, resolve, reject) { + return function (ev) { + var license = GenerateClearKeyLicense(ev.message, test.keys); + Log( + token, + "sending update message to CDM: " + new TextDecoder().decode(license) + ); + ev.target + .update(license) + .then(function () { + Log(token, "MediaKeySession update ok!"); + resolve(ev.target); + }) + .catch(function (reason) { + reject(`${token} MediaKeySession update failed: ${reason}`); + }); + }; +} + +function MaybeCrossOriginURI(test, uri) { + if (test.crossOrigin) { + return "https://example.com:443/tests/dom/media/test/allowed.sjs?" + uri; + } + return uri; +} + +function AppendTrack(test, ms, track, token) { + return new Promise(function (resolve, reject) { + var sb; + var curFragment = 0; + var fragments = track.fragments; + var fragmentFile; + + function addNextFragment() { + if (curFragment >= fragments.length) { + Log(token, track.name + ": end of track"); + resolve(); + return; + } + + fragmentFile = MaybeCrossOriginURI(test, fragments[curFragment++]); + + var req = new XMLHttpRequest(); + req.open("GET", fragmentFile); + req.responseType = "arraybuffer"; + + req.addEventListener("load", function () { + Log( + token, + track.name + ": fetch of " + fragmentFile + " complete, appending" + ); + sb.appendBuffer(new Uint8Array(req.response)); + }); + + req.addEventListener("error", function () { + reject(`${token} - ${track.name}: error fetching ${fragmentFile}`); + }); + req.addEventListener("abort", function () { + reject(`${token} - ${track.name}: aborted fetching ${fragmentFile}`); + }); + + Log( + token, + track.name + + ": addNextFragment() fetching next fragment " + + fragmentFile + ); + req.send(null); + } + + Log(token, track.name + ": addSourceBuffer(" + track.type + ")"); + sb = ms.addSourceBuffer(track.type); + sb.addEventListener("updateend", function () { + Log( + token, + track.name + + ": updateend for " + + fragmentFile + + ", " + + SourceBufferToString(sb) + ); + addNextFragment(); + }); + + addNextFragment(); + }); +} + +//Returns a promise that is resolved when the media element is ready to have +//its play() function called; when it's loaded MSE fragments. +function LoadTest(test, elem, token, endOfStream = true) { + if (!test.tracks) { + ok(false, token + " test does not have a tracks list"); + return Promise.reject(); + } + + var ms = new MediaSource(); + elem.src = URL.createObjectURL(ms); + elem.crossOrigin = test.crossOrigin || false; + + return new Promise(function (resolve, reject) { + ms.addEventListener( + "sourceopen", + function () { + Log(token, "sourceopen"); + Promise.all( + test.tracks.map(function (track) { + return AppendTrack(test, ms, track, token); + }) + ) + .then(function () { + Log(token, "Tracks loaded, calling MediaSource.endOfStream()"); + if (endOfStream) { + ms.endOfStream(); + } + resolve(); + }) + .catch(reject); + }, + { once: true } + ); + }); +} + +function EMEPromise() { + var self = this; + self.promise = new Promise(function (resolve, reject) { + self.resolve = resolve; + self.reject = reject; + }); +} + +/* + * Create a new MediaKeys object. + * Return a promise which will be resolved with a new MediaKeys object, + * or will be rejected with a string that describes the failure. + */ +function CreateMediaKeys(v, test, token) { + let p = new EMEPromise(); + + function streamType(type) { + var x = test.tracks.find(o => o.name == type); + return x ? x.type : undefined; + } + + function onencrypted(ev) { + var options = { initDataTypes: [ev.initDataType] }; + if (streamType("video")) { + options.videoCapabilities = [{ contentType: streamType("video") }]; + } + if (streamType("audio")) { + options.audioCapabilities = [{ contentType: streamType("audio") }]; + } + navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, [options]).then( + keySystemAccess => { + keySystemAccess + .createMediaKeys() + .then(p.resolve, () => + p.reject(`${token} Failed to create MediaKeys object.`) + ); + }, + () => p.reject(`${token} Failed to request key system access.`) + ); + } + + v.addEventListener("encrypted", onencrypted, { once: true }); + return p.promise; +} + +/* + * Create a new MediaKeys object and provide it to the media element. + * Return a promise which will be resolved if succeeded, or will be rejected + * with a string that describes the failure. + */ +function CreateAndSetMediaKeys(v, test, token) { + let p = new EMEPromise(); + + CreateMediaKeys(v, test, token).then(mediaKeys => { + v.setMediaKeys(mediaKeys).then(p.resolve, () => + p.reject(`${token} Failed to set MediaKeys on <video> element.`) + ); + }, p.reject); + + return p.promise; +} + +/* + * Collect the init data from 'encrypted' events. + * Return a promise which will be resolved with the init data when collection + * is completed (specified by test.sessionCount). + */ +function LoadInitData(v, test, token) { + let p = new EMEPromise(); + let initDataQueue = []; + + // Call SimpleTest._originalSetTimeout() to bypass the flaky timeout checker. + let timer = SimpleTest._originalSetTimeout.call( + window, + () => { + p.reject(`${token} Timed out in waiting for the init data.`); + }, + 60000 + ); + + function onencrypted(ev) { + initDataQueue.push(ev); + Log( + token, + `got encrypted(${ev.initDataType}, ` + + `${StringToHex(ArrayBufferToString(ev.initData))}) event.` + ); + if (test.sessionCount == initDataQueue.length) { + p.resolve(initDataQueue); + clearTimeout(timer); + } + } + + v.addEventListener("encrypted", onencrypted); + return p.promise; +} + +/* + * Generate a license request and update the session. + * Return a promsise which will be resolved with the updated session + * or rejected with a string that describes the failure. + */ +function MakeRequest(test, token, ev, session, sessionType) { + sessionType = sessionType || "temporary"; + let p = new EMEPromise(); + let str = + `session[${session.sessionId}].generateRequest(` + + `${ev.initDataType}, ${StringToHex(ArrayBufferToString(ev.initData))})`; + + session.addEventListener( + "message", + UpdateSessionFunc(test, token, sessionType, p.resolve, p.reject) + ); + + Log(token, str); + session.generateRequest(ev.initDataType, ev.initData).catch(reason => { + // Reject the promise if generateRequest() failed. + // Otherwise it will be resolved in UpdateSessionFunc(). + p.reject(`${token}: ${str} failed; ${reason}`); + }); + + return p.promise; +} + +/* + * Process the init data by calling MakeRequest(). + * Return a promise which will be resolved with the updated sessions + * when all init data are processed or rejected if any failure. + */ +function ProcessInitData(v, test, token, initData, sessionType) { + return Promise.all( + initData.map(ev => { + let session = v.mediaKeys.createSession(sessionType); + return MakeRequest(test, token, ev, session, sessionType); + }) + ); +} + +/* + * Clean up the |v| element. + */ +function CleanUpMedia(v) { + v.setMediaKeys(null); + v.remove(); + v.removeAttribute("src"); + v.load(); +} + +/* + * Close all sessions and clean up the |v| element. + */ +function CloseSessions(v, sessions) { + return Promise.all(sessions.map(s => s.close())).then(CleanUpMedia(v)); +} + +/* + * Set up media keys and source buffers for the media element. + * Return a promise resolved when all key sessions are updated or rejected + * if any failure. + */ +function SetupEME(v, test, token) { + let p = new EMEPromise(); + + v.onerror = function () { + p.reject(`${token} got an error event.`); + }; + + Promise.all([ + LoadInitData(v, test, token), + CreateAndSetMediaKeys(v, test, token), + LoadTest(test, v, token), + ]) + .then(values => { + let initData = values[0]; + return ProcessInitData(v, test, token, initData); + }) + .then(p.resolve, p.reject); + + return p.promise; +} + +function fetchWithXHR(uri, onLoadFunction) { + var p = new Promise(function (resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", uri, true); + xhr.responseType = "arraybuffer"; + xhr.addEventListener("load", function () { + is( + xhr.status, + 200, + "fetchWithXHR load uri='" + uri + "' status=" + xhr.status + ); + resolve(xhr.response); + }); + xhr.send(); + }); + + if (onLoadFunction) { + p.then(onLoadFunction); + } + + return p; +} + +function once(target, name, cb) { + var p = new Promise(function (resolve, reject) { + target.addEventListener( + name, + function (arg) { + resolve(arg); + }, + { once: true } + ); + }); + if (cb) { + p.then(cb); + } + return p; +} diff --git a/dom/media/test/eme_standalone.js b/dom/media/test/eme_standalone.js new file mode 100644 index 0000000000..202259b7fa --- /dev/null +++ b/dom/media/test/eme_standalone.js @@ -0,0 +1,286 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This file offers standalone (no dependencies on other files) EME test +// helpers. The intention is that this file can be used to provide helpers +// while not coupling tests as tightly to `dom/media/test/manifest.js` or other +// files. This allows these helpers to be used in different tests across the +// codebase without imports becoming a mess. + +// A helper class to assist in setting up EME on media. +// +// Usage +// 1. First configure the EME helper so it can have the information needed +// to setup EME correctly. This is done by setting +// - keySystem via `SetKeySystem`. +// - initDataTypes via `SetInitDataTypes`. +// - audioCapabilities and/or videoCapabilities via `SetAudioCapabilities` +// and/or `SetVideoCapabilities`. +// - keyIds and keys via `AddKeyIdAndKey`. +// - onerror should be set to a function that will handle errors from the +// helper. This function should take one argument, the error. +// 2. Use the helper to configure a media element via `ConfigureEme`. +// 3. One the promise from `ConfigureEme` has resolved the media element should +// be configured and can be played. Errors that happen after this point are +// reported via `onerror`. +var EmeHelper = class EmeHelper { + // Members used to configure EME. + _keySystem; + _initDataTypes; + _audioCapabilities = []; + _videoCapabilities = []; + + // Map of keyIds to keys. + _keyMap = new Map(); + + // Will be called if an error occurs during event handling. Users of the + // class should set a handler to be notified of errors. + onerror; + + /** + * Get the clearkey key system string. + * @return The clearkey key system string. + */ + static GetClearkeyKeySystemString() { + return "org.w3.clearkey"; + } + + // Begin conversion helpers. + + /** + * Helper to convert Uint8Array into base64 using base64url alphabet, without + * padding. + * @param uint8Array An array of bytes to convert to base64. + * @return A base 64 encoded string + */ + static Uint8ArrayToBase64(uint8Array) { + return new TextDecoder() + .decode(uint8Array) + .replace(/\+/g, "-") // Replace chars for base64url. + .replace(/\//g, "_") + .replace(/=*$/, ""); // Remove padding for base64url. + } + + /** + * Helper to convert a hex string into base64 using base64url alphabet, + * without padding. + * @param hexString A string of hex characters. + * @return A base 64 encoded string + */ + static HexToBase64(hexString) { + return btoa( + hexString + .match(/\w{2}/g) // Take chars two by two. + // Map to characters. + .map(hexByte => String.fromCharCode(parseInt(hexByte, 16))) + .join("") + ) + .replace(/\+/g, "-") // Replace chars for base64url. + .replace(/\//g, "_") + .replace(/=*$/, ""); // Remove padding for base64url. + } + + /** + * Helper to convert a base64 string (base64 or base64url) into a hex string. + * @param base64String A base64 encoded string. This can be base64url. + * @return A hex string (lower case); + */ + static Base64ToHex(base64String) { + let binString = atob(base64String.replace(/-/g, "+").replace(/_/g, "/")); + let hexString = ""; + for (let i = 0; i < binString.length; i++) { + // Covert to hex char. The "0" + and substr code are used to ensure we + // always get 2 chars, even for outputs the would normally be only one. + // E.g. for charcode 14 we'd get output 'e', and want to buffer that + // to '0e'. + hexString += ("0" + binString.charCodeAt(i).toString(16)).substr(-2); + } + // EMCA spec says that the num -> string conversion is lower case, so our + // hex string should already be lower case. + // https://tc39.es/ecma262/#sec-number.prototype.tostring + return hexString; + } + + // End conversion helpers. + + // Begin setters that setup the helper. + // These should be used to configure the helper prior to calling + // `ConfigureEme`. + + /** + * Sets the key system that will be used by the EME helper. + * @param keySystem The key system to use. Probably "org.w3.clearkey", which + * can be fetched via `GetClearkeyKeySystemString`. + */ + SetKeySystem(keySystem) { + this._keySystem = keySystem; + } + + /** + * Sets the init data types that will be used by the EME helper. This is used + * when calling `navigator.requestMediaKeySystemAccess`. + * @param initDataTypes A list containing the init data types to be set by + * the helper. This will usually be ["cenc"] or ["webm"], see + * https://www.w3.org/TR/eme-initdata-registry/ for more info on what these + * mean. + */ + SetInitDataTypes(initDataTypes) { + this._initDataTypes = initDataTypes; + } + + /** + * Sets the audio capabilities that will be used by the EME helper. These are + * used when calling `navigator.requestMediaKeySystemAccess`. + * See https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess + * for more info on these. + * @param audioCapabilities A list containing audio capabilities. E.g. + * [{ contentType: 'audio/webm; codecs="opus"' }]. + */ + SetAudioCapabilities(audioCapabilities) { + this._audioCapabilities = audioCapabilities; + } + + /** + * Sets the video capabilities that will be used by the EME helper. These are + * used when calling `navigator.requestMediaKeySystemAccess`. + * See https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess + * for more info on these. + * @param videoCapabilities A list containing video capabilities. E.g. + * [{ contentType: 'video/webm; codecs="vp9"' }] + */ + SetVideoCapabilities(videoCapabilities) { + this._videoCapabilities = videoCapabilities; + } + + /** + * Adds a key id and key pair to the key map. These should both be hex + * strings. E.g. + * emeHelper.AddKeyIdAndKey( + * "2cdb0ed6119853e7850671c3e9906c3c", + * "808b9adac384de1e4f56140f4ad76194" + * ); + * This function will store the keyId and key in lower case to ensure + * consistency internally. + * @param keyId The key id used to lookup the following key. + * @param key The key associated with the earlier key id. + */ + AddKeyIdAndKey(keyId, key) { + this._keyMap.set(keyId.toLowerCase(), key.toLowerCase()); + } + + /** + * Removes a key id and its associate key from the key map. + * @param keyId The key id to remove. + */ + RemoveKeyIdAndKey(keyId) { + this._keyMap.delete(keyId); + } + + // End setters that setup the helper. + + /** + * Internal handler for `session.onmessage`. When calling this either do so + * from inside an arrow function or using `bind` to ensure `this` points to + * an EmeHelper instance (rather than a session). + * @param messageEvent The message event passed to `session.onmessage`. + */ + _SessionMessageHandler(messageEvent) { + // This handles a session message and generates a clearkey license based + // on the information in this._keyMap. This is done by populating the + // appropriate keys on the session based on the keyIds surfaced in the + // session message (a license request). + let request = JSON.parse(new TextDecoder().decode(messageEvent.message)); + + let keys = []; + for (const keyId of request.kids) { + let id64 = keyId; + let idHex = EmeHelper.Base64ToHex(keyId); + let key = this._keyMap.get(idHex); + + if (key) { + keys.push({ + kty: "oct", + kid: id64, + k: EmeHelper.HexToBase64(key), + }); + } + } + + let license = new TextEncoder().encode( + JSON.stringify({ + keys, + type: request.type || "temporary", + }) + ); + + let session = messageEvent.target; + session.update(license).catch(error => { + if (this.onerror) { + this.onerror(error); + } else { + console.log( + `EmeHelper got an error, but no onerror handler was registered! Logging to console, error: ${error}` + ); + } + }); + } + + /** + * Configures EME on a media element using the parameters already set on the + * instance of EmeHelper. + * @param htmlMediaElement - A media element to configure EME on. + * @return A promise that will be resolved once the media element is + * configured. This promise will be rejected with an error if configuration + * fails. + */ + async ConfigureEme(htmlMediaElement) { + if (!this._keySystem) { + throw new Error("EmeHelper needs _keySystem to configure media"); + } + if (!this._initDataTypes) { + throw new Error("EmeHelper needs _initDataTypes to configure media"); + } + if (!this._audioCapabilities.length && !this._videoCapabilities.length) { + throw new Error( + "EmeHelper needs _audioCapabilities or _videoCapabilities to configure media" + ); + } + const options = [ + { + initDataTypes: this._initDataTypes, + audioCapabilities: this._audioCapabilities, + videoCapabilities: this._videoCapabilities, + }, + ]; + let access = await window.navigator.requestMediaKeySystemAccess( + this._keySystem, + options + ); + let mediaKeys = await access.createMediaKeys(); + await htmlMediaElement.setMediaKeys(mediaKeys); + + htmlMediaElement.onencrypted = async encryptedEvent => { + let session = htmlMediaElement.mediaKeys.createSession(); + // Use arrow notation so that `this` is the EmeHelper in the message + // handler. If we do `session.onmessage = this._SessionMessageHandler` + // then `this` will be the session in the callback. + session.onmessage = messageEvent => + this._SessionMessageHandler(messageEvent); + try { + await session.generateRequest( + encryptedEvent.initDataType, + encryptedEvent.initData + ); + } catch (error) { + if (this.onerror) { + this.onerror(error); + } else { + console.log( + `EmeHelper got an error, but no onerror handler was registered! Logging to console, error: ${error}` + ); + } + } + }; + } +}; diff --git a/dom/media/test/empty_size.mp3 b/dom/media/test/empty_size.mp3 Binary files differnew file mode 100644 index 0000000000..0c208a2959 --- /dev/null +++ b/dom/media/test/empty_size.mp3 diff --git a/dom/media/test/file_access_controls.html b/dom/media/test/file_access_controls.html new file mode 100644 index 0000000000..2f7bc360ed --- /dev/null +++ b/dom/media/test/file_access_controls.html @@ -0,0 +1,160 @@ +<html> +<head> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body onload="setTimeout(load, 0);"> +<script> + +// Page URL: http://example.org/tests/dom/media/test/file_access_controls.html + +var gResource = getPlayableVideo(gSmallTests).name; + +var gTests = [ + { + // Test 0 + url: "redirect.sjs?domain=example.com&file="+ gResource, + result: "error", + description: "Won't load when redirected to different domain", + },{ + // Test 1 + url: "redirect.sjs?domain=example.com&allowed&file=" + gResource, + result: "loadeddata", + description: "Can load when redirected to different domain with allow-origin", + },{ + // Test 2 + url: "redirect.sjs?domain=test1.example.org&file=" + gResource, + result: "error", + description: "Won't load when redirected to subdomain", + },{ + // Test 3 + url: "redirect.sjs?domain=test1.example.org&allowed&file=" + gResource, + result: "loadeddata", + description: "Can load when redirected to subdomain with allow-origin", + },{ + // Test 4 + url: "redirect.sjs?domain=example.org&file=" + gResource, + result: "loadeddata", + description: "Can load when redirected to same domain", + },{ + // Test 5 + url: "http://example.org/tests/dom/media/test/" + gResource, + result: "loadeddata", + description: "Can load from same domain" + },{ + // Test 6 + url: "http://example.org:8000/tests/dom/media/test/" + gResource, + result: "error", + description: "Won't load from different port on same domain" + },{ + // Test 7 + url: "http://example.org:8000/tests/dom/media/test/allowed.sjs?" + gResource, + result: "loadeddata", + description: "Can load from different port on same domain with allow-origin", + },{ + // Test 8 + url: "http://example.com/tests/dom/media/test/" + gResource, + result: "error", + description: "Won't load cross domain", + },{ + // Test 9 + url: "http://example.com/tests/dom/media/test/allowed.sjs?" + gResource, + result: "loadeddata", + description: "Can load cross domain with allow-origin", + },{ + // Test 10 + url: "http://test1.example.org/tests/dom/media/test/allowed.sjs?" + gResource, + result: "loadeddata", + description: "Can load from subdomain with allow-origin", + },{ + // Test 11 + url: "http://test1.example.org/tests/dom/media/test/" + gResource, + result: "error", + description: "Won't load from subdomain", + } +]; + +var gTestNum = 0; +var gVideo = null; +var gTestedRemoved = false; + +function eventHandler(event) { + //dump((gTestNum - 1) + ": " + event.type + "\n"); + var video = event.target; + opener.postMessage({"result": (event.type == video.expectedResult), + "message": video.testDescription + (gTestedRemoved ? " (element not in document)" : " (element in document)")}, + "http://mochi.test:8888"); + // Make sure any extra events cause an error + video.expectedResult = "<none>"; + nextTest(); +} + +function createVideo() { + var v = document.createElement('video'); + v.addEventListener('loadeddata', eventHandler); + v.addEventListener('error', eventHandler); + v.crossOrigin = 'anonymous'; + return v; +} + +function load() { + opener.postMessage({"result": (window.location.href == "http://example.org/tests/dom/media/test/file_access_controls.html"), + "message": "We must be on a example.org:80"}, + "http://mochi.test:8888"); + + nextTest(); +} + +function nextTest() { + //dump("nextTest() called, gTestNum="+gTestNum+" gTestedRemoved="+gTestedRemoved+"\n"); + if (gTestNum == gTests.length) { + //dump("gTestNum == gTests.length\n"); + if (!gTestedRemoved) { + // Repeat all tests with element removed from doc, should get same result. + gTestedRemoved = true; + gTestNum = 0; + } else { + //dump("Exiting...\n"); + // We're done, exit the test. + done(); + window.close(); + return; + } + } + + if (gVideo) { + gVideo.remove(); + gVideo.removeAttribute("src"); + gVideo.load(); + } + + gVideo = null; + SpecialPowers.forceGC(); + + gVideo = createVideo(); + gVideo.expectedResult = gTests[gTestNum].result; + gVideo.testDescription = gTests[gTestNum].description; + // Uniquify the resource URL to ensure that the resources loaded by earlier or subsequent tests + // don't overlap with the resources we load here, which are loaded with non-default preferences set. + // We also want to make sure that an HTTP fetch actually happens for each testcase. + var url = gTests[gTestNum].url; + var random = Math.floor(Math.random()*1000000000); + url += (url.search(/\?/) < 0 ? "?" : "&") + "rand=" + random; + gVideo.src = url; + //dump("Starting test " + gTestNum + " at " + gVideo.src + " expecting:" + gVideo.expectedResult + "\n"); + if (!gTestedRemoved) { + document.body.appendChild(gVideo); + // Will cause load() to be invoked. + } else { + gVideo.load(); + } + gTestNum++; +} + +function done() { + opener.postMessage({"done": "true"}, "http://mochi.test:8888"); +} + +</script> +</body> +</html> + diff --git a/dom/media/test/file_eme_createMediaKeys.html b/dom/media/test/file_eme_createMediaKeys.html new file mode 100644 index 0000000000..3ff782b1bf --- /dev/null +++ b/dom/media/test/file_eme_createMediaKeys.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> +<title>Eme createMediaKeys helper page</title> +<script> +// This script waits for a message then attempts to requestMediaKeySystemAccess +// then createMediaKeys. On success posts 'successCreatingMediaKeys' to the +// source of the message, on failure posts 'failureCreatingMediaKeys' and a +// description of the failure to the source of the message. + +async function createMediaKeys() { + const clearKeyOptions = [ + { + initDataTypes: ["webm"], + videoCapabilities: [{ contentType: 'video/webm; codecs="vp9"' }], + }, + ]; + + let access = await navigator.requestMediaKeySystemAccess( + "org.w3.clearkey", + clearKeyOptions + ); + + return access.createMediaKeys(); +} +function setupMessageListener() { + window.onmessage = async event => { + // We don't bother checking the message data since it should always be + // telling us to create media keys. + try { + let keys = await createMediaKeys(); + if (!keys) { + event.source.postMessage("failureCreatingMediaKeys no keys", "*"); + return; + } + event.source.postMessage("successCreatingMediaKeys", "*"); + } catch (e) { + event.source.postMessage(`failureCreatingMediaKeys ${e}`, "*"); + } + }; +} +window.onload = setupMessageListener; +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/file_playback_and_bfcache.html b/dom/media/test/file_playback_and_bfcache.html new file mode 100644 index 0000000000..4798e1487e --- /dev/null +++ b/dom/media/test/file_playback_and_bfcache.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<head> + <script> + function init() { + if (location.search == "") { + let bc1 = new BroadcastChannel("bc1"); + bc1.onmessage = function(e) { + if (e.data == "loadNext") { + location.href = location.href + "?page2"; + } else if (e.data == "forward") { + bc1.close(); + history.forward(); + } + }; + window.onpageshow = function() { + bc1.postMessage("pageshow"); + }; + } else { + document.body.innerHTML = "<video controls src='owl.mp3' autoplay>"; + let bc2 = new BroadcastChannel("bc2"); + bc2.onmessage = function(e) { + if (e.data == "back") { + history.back(); + } else if (e.data == "statistics") { + bc2.postMessage({ currentTime: document.body.firstChild.currentTime, + duration: document.body.firstChild.duration }); + bc2.close(); + window.close(); + } + } + window.onpageshow = function(e) { + bc2.postMessage({ event: "pageshow", persisted: e.persisted}); + if (!e.persisted) { + // The initial statistics is sent once we know the duration and + // have loaded all the data. + let mediaElement = document.body.firstChild; + mediaElement.onpause = function() { + mediaElement.onpause = null; + mediaElement.currentTime = 0; + mediaElement.onplay = function() { + setTimeout(function() { + bc2.postMessage({ currentTime: mediaElement.currentTime, + duration: mediaElement.duration }); + }, 500); + } + mediaElement.play(); + } + } + }; + } + } + </script> +</head> +<body onload="init()"> +</body> +</html> diff --git a/dom/media/test/flac-noheader-s16.flac b/dom/media/test/flac-noheader-s16.flac Binary files differnew file mode 100644 index 0000000000..01152142a9 --- /dev/null +++ b/dom/media/test/flac-noheader-s16.flac diff --git a/dom/media/test/flac-noheader-s16.flac^headers^ b/dom/media/test/flac-noheader-s16.flac^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/flac-noheader-s16.flac^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/flac-s24.flac b/dom/media/test/flac-s24.flac Binary files differnew file mode 100644 index 0000000000..1ba5e27a15 --- /dev/null +++ b/dom/media/test/flac-s24.flac diff --git a/dom/media/test/flac-s24.flac^headers^ b/dom/media/test/flac-s24.flac^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/flac-s24.flac^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/flac-sample-cenc.mp4 b/dom/media/test/flac-sample-cenc.mp4 Binary files differnew file mode 100644 index 0000000000..c89190387a --- /dev/null +++ b/dom/media/test/flac-sample-cenc.mp4 diff --git a/dom/media/test/flac-sample-cenc.mp4^headers^ b/dom/media/test/flac-sample-cenc.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/flac-sample-cenc.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/flac-sample.mp4 b/dom/media/test/flac-sample.mp4 Binary files differnew file mode 100644 index 0000000000..d39c94a7b2 --- /dev/null +++ b/dom/media/test/flac-sample.mp4 diff --git a/dom/media/test/flac-sample.mp4^headers^ b/dom/media/test/flac-sample.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/flac-sample.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/force_octet_stream.mp4 b/dom/media/test/force_octet_stream.mp4 Binary files differnew file mode 100644 index 0000000000..802da047bc --- /dev/null +++ b/dom/media/test/force_octet_stream.mp4 diff --git a/dom/media/test/force_octet_stream.mp4^headers^ b/dom/media/test/force_octet_stream.mp4^headers^ new file mode 100644 index 0000000000..d554cbedb5 --- /dev/null +++ b/dom/media/test/force_octet_stream.mp4^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-store +Content-Type: application/octet-stream diff --git a/dom/media/test/fragment_noplay.js b/dom/media/test/fragment_noplay.js new file mode 100644 index 0000000000..247641763f --- /dev/null +++ b/dom/media/test/fragment_noplay.js @@ -0,0 +1,19 @@ +function test_fragment_noplay(v, start, end, is, ok, finish) { + function onLoadedMetadata() { + var s = start == null ? 0 : start; + var e = end == null ? v.duration : end; + var a = s - 0.15; + var b = s + 0.15; + ok( + v.currentTime >= a && v.currentTime <= b, + "loadedmetadata currentTime is " + a + " < " + v.currentTime + " < " + b + ); + ok( + v.mozFragmentEnd == e, + "mozFragmentEnd (" + v.mozFragmentEnd + ") == end Time (" + e + ")" + ); + finish(); + } + + v.addEventListener("loadedmetadata", onLoadedMetadata); +} diff --git a/dom/media/test/fragment_play.js b/dom/media/test/fragment_play.js new file mode 100644 index 0000000000..ec0fe7952a --- /dev/null +++ b/dom/media/test/fragment_play.js @@ -0,0 +1,92 @@ +function test_fragment_play(v, start, end, is, ok, finish) { + var completed = false; + var loadedMetadataRaised = false; + var seekedRaised = false; + var pausedRaised = false; + + function onLoadedMetadata() { + var s = start == null ? 0 : start; + var e = end == null ? v.duration : end; + ok( + v.currentTime == s, + "loadedmetadata currentTime is " + v.currentTime + " != " + s + ); + ok( + v.mozFragmentEnd == e, + "mozFragmentEnd (" + v.mozFragmentEnd + ") == end Time (" + e + ")" + ); + loadedMetadataRaised = true; + v.play(); + } + + function onSeeked() { + if (completed) { + return; + } + + var s = start == null ? 0 : start; + ok( + v.currentTime - s < 0.1, + "seeked currentTime is " + + v.currentTime + + " != " + + s + + " (fuzzy compare +-0.1)" + ); + + seekedRaised = true; + } + + function onTimeUpdate() { + if (completed) { + return; + } + + v._lastTimeUpdate = v.currentTime; + } + + function onPause() { + if (completed) { + return; + } + + var e = end == null ? v.duration : end; + var a = e - 0.05; + var b = e + 0.05; + ok( + v.currentTime >= a && v.currentTime <= b, + "paused currentTime is " + + a + + " < " + + v.currentTime + + " < " + + b + + " ? " + + v._lastTimeUpdate + ); + pausedRaised = true; + v.play(); + } + + function onEnded() { + if (completed) { + return; + } + + completed = true; + ok(loadedMetadataRaised, "loadedmetadata event"); + if (start) { + ok(seekedRaised, "seeked event"); + } + if (end) { + ok(pausedRaised, "paused event: " + end + " " + v.duration); + } + finish(); + } + + v.addEventListener("ended", onEnded); + v.addEventListener("loadedmetadata", onLoadedMetadata); + v.addEventListener("seeked", onSeeked); + v.addEventListener("pause", onPause); + v.addEventListener("timeupdate", onTimeUpdate); +} diff --git a/dom/media/test/gUM_support.js b/dom/media/test/gUM_support.js new file mode 100644 index 0000000000..80d218cae7 --- /dev/null +++ b/dom/media/test/gUM_support.js @@ -0,0 +1,103 @@ +// Support script for test that use getUserMedia. This allows explicit +// configuration of prefs which affect gUM. See also +// `testing/mochitest/runtests.py` for how the harness configures values. + +// Setup preconditions for tests using getUserMedia. This functions helps +// manage different prefs that affect gUM calls in tests and makes explicit +// the expected state before test runs. +async function pushGetUserMediaTestPrefs({ + fakeAudio = false, + fakeVideo = false, + loopbackAudio = false, + loopbackVideo = false, +}) { + // Make sure we have sensical arguments + if (!fakeAudio && !loopbackAudio) { + throw new Error( + "pushGetUserMediaTestPrefs: Should have fake or loopback audio!" + ); + } else if (fakeAudio && loopbackAudio) { + throw new Error( + "pushGetUserMediaTestPrefs: Should not have both fake and loopback audio!" + ); + } + if (!fakeVideo && !loopbackVideo) { + throw new Error( + "pushGetUserMediaTestPrefs: Should have fake or loopback video!" + ); + } else if (fakeVideo && loopbackVideo) { + throw new Error( + "pushGetUserMediaTestPrefs: Should not have both fake and loopback video!" + ); + } + + let testPrefs = []; + if (fakeAudio) { + // Unset the loopback device so it doesn't take precedence + testPrefs.push(["media.audio_loopback_dev", ""]); + // Setup fake streams pref + testPrefs.push(["media.navigator.streams.fake", true]); + } + if (loopbackAudio) { + // If audio loopback is requested we expect the test harness to have set + // the loopback device pref, make sure it's set + let audioLoopDev = SpecialPowers.getCharPref( + "media.audio_loopback_dev", + "" + ); + if (!audioLoopDev) { + throw new Error( + "pushGetUserMediaTestPrefs: Loopback audio requested but " + + "media.audio_loopback_dev does not appear to be set!" + ); + } + } + if (fakeVideo) { + // Unset the loopback device so it doesn't take precedence + testPrefs.push(["media.video_loopback_dev", ""]); + // Setup fake streams pref + testPrefs.push(["media.navigator.streams.fake", true]); + } + if (loopbackVideo) { + // If video loopback is requested we expect the test harness to have set + // the loopback device pref, make sure it's set + let videoLoopDev = SpecialPowers.getCharPref( + "media.video_loopback_dev", + "" + ); + if (!videoLoopDev) { + throw new Error( + "pushGetUserMediaTestPrefs: Loopback video requested but " + + "media.video_loopback_dev does not appear to be set!" + ); + } + } + // Prevent presentation of the gUM permission prompt. + testPrefs.push(["media.navigator.permission.disabled", true]); + return SpecialPowers.pushPrefEnv({ set: testPrefs }); +} + +// Setup preconditions for tests using getUserMedia. This function will +// configure prefs to select loopback device(s) if it can find loopback device +// names already set in the prefs. If no loopback device name can be found then +// prefs are setup such that a fake device is used. +async function setupGetUserMediaTestPrefs() { + let prefRequests = {}; + let audioLoopDev = SpecialPowers.getCharPref("media.audio_loopback_dev", ""); + if (audioLoopDev) { + prefRequests.fakeAudio = false; + prefRequests.loopbackAudio = true; + } else { + prefRequests.fakeAudio = true; + prefRequests.loopbackAudio = false; + } + let videoLoopDev = SpecialPowers.getCharPref("media.video_loopback_dev", ""); + if (videoLoopDev) { + prefRequests.fakeVideo = false; + prefRequests.loopbackVideo = true; + } else { + prefRequests.fakeVideo = true; + prefRequests.loopbackVideo = false; + } + return pushGetUserMediaTestPrefs(prefRequests); +} diff --git a/dom/media/test/gizmo-frag.mp4 b/dom/media/test/gizmo-frag.mp4 Binary files differnew file mode 100644 index 0000000000..f6980663c2 --- /dev/null +++ b/dom/media/test/gizmo-frag.mp4 diff --git a/dom/media/test/gizmo-noaudio.mp4 b/dom/media/test/gizmo-noaudio.mp4 Binary files differnew file mode 100644 index 0000000000..24732a4064 --- /dev/null +++ b/dom/media/test/gizmo-noaudio.mp4 diff --git a/dom/media/test/gizmo-noaudio.mp4^headers^ b/dom/media/test/gizmo-noaudio.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/gizmo-noaudio.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/gizmo-noaudio.webm b/dom/media/test/gizmo-noaudio.webm Binary files differnew file mode 100644 index 0000000000..9f412cb6e3 --- /dev/null +++ b/dom/media/test/gizmo-noaudio.webm diff --git a/dom/media/test/gizmo-noaudio.webm^headers^ b/dom/media/test/gizmo-noaudio.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/gizmo-noaudio.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/gizmo-short.mp4 b/dom/media/test/gizmo-short.mp4 Binary files differnew file mode 100644 index 0000000000..f8caec741e --- /dev/null +++ b/dom/media/test/gizmo-short.mp4 diff --git a/dom/media/test/gizmo-short.mp4^headers^ b/dom/media/test/gizmo-short.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/gizmo-short.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/gizmo.mp4 b/dom/media/test/gizmo.mp4 Binary files differnew file mode 100644 index 0000000000..87efad5ade --- /dev/null +++ b/dom/media/test/gizmo.mp4 diff --git a/dom/media/test/gizmo.mp4^headers^ b/dom/media/test/gizmo.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/gizmo.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/gizmo.webm b/dom/media/test/gizmo.webm Binary files differnew file mode 100644 index 0000000000..518531a93f --- /dev/null +++ b/dom/media/test/gizmo.webm diff --git a/dom/media/test/gizmo.webm^headers^ b/dom/media/test/gizmo.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/gizmo.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/gzipped_mp4.sjs b/dom/media/test/gzipped_mp4.sjs new file mode 100644 index 0000000000..b08362d75e --- /dev/null +++ b/dom/media/test/gzipped_mp4.sjs @@ -0,0 +1,25 @@ +function getGzippedFileBytes() { + var file; + getObjectState("SERVER_ROOT", function (serverRoot) { + file = serverRoot.getFile("tests/dom/media/test/short.mp4.gz"); + }); + var fileInputStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + var binaryInputStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + fileInputStream.init(file, -1, -1, 0); + binaryInputStream.setInputStream(fileInputStream); + return binaryInputStream.readBytes(binaryInputStream.available()); +} + +function handleRequest(request, response) { + var bytes = getGzippedFileBytes(); + response.setHeader("Content-Length", String(bytes.length), false); + response.setHeader("Content-Type", "video/mp4", false); + response.setHeader("Access-Control-Allow-Origin", "*", false); + response.setHeader("Content-Encoding", "gzip", false); + response.setHeader("Cache-Control", "no-cache", false); + response.write(bytes, bytes.length); +} diff --git a/dom/media/test/hevc_white_frame.mp4 b/dom/media/test/hevc_white_frame.mp4 Binary files differnew file mode 100644 index 0000000000..27d642346e --- /dev/null +++ b/dom/media/test/hevc_white_frame.mp4 diff --git a/dom/media/test/hevc_white_frame.mp4^headers^ b/dom/media/test/hevc_white_frame.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/hevc_white_frame.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/hevc_white_red_frames.mp4 b/dom/media/test/hevc_white_red_frames.mp4 Binary files differnew file mode 100644 index 0000000000..5da0aecd17 --- /dev/null +++ b/dom/media/test/hevc_white_red_frames.mp4 diff --git a/dom/media/test/hevc_white_red_frames.mp4^headers^ b/dom/media/test/hevc_white_red_frames.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/hevc_white_red_frames.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/hls/400x300_prog_index.m3u8 b/dom/media/test/hls/400x300_prog_index.m3u8 new file mode 100644 index 0000000000..3252eb178f --- /dev/null +++ b/dom/media/test/hls/400x300_prog_index.m3u8 @@ -0,0 +1,10 @@ +#EXTM3U +#EXT-X-TARGETDURATION:10 +#EXT-X-VERSION:3 +#EXT-X-MEDIA-SEQUENCE:0 +#EXT-X-PLAYLIST-TYPE:VOD +#EXTINF:9.97667, +400x300_seg0.ts +#EXTINF:9.97667, +400x300_seg1.ts +#EXT-X-ENDLIST diff --git a/dom/media/test/hls/400x300_prog_index_5s.m3u8 b/dom/media/test/hls/400x300_prog_index_5s.m3u8 new file mode 100644 index 0000000000..8e9d19f764 --- /dev/null +++ b/dom/media/test/hls/400x300_prog_index_5s.m3u8 @@ -0,0 +1,8 @@ +#EXTM3U +#EXT-X-TARGETDURATION:4.00 +#EXT-X-VERSION:3 +#EXT-X-MEDIA-SEQUENCE:0 +#EXT-X-PLAYLIST-TYPE:VOD +#EXTINF:4.00, +400x300_seg0_5s.ts +#EXT-X-ENDLIST diff --git a/dom/media/test/hls/400x300_seg0.ts b/dom/media/test/hls/400x300_seg0.ts Binary files differnew file mode 100644 index 0000000000..b17b0a88ff --- /dev/null +++ b/dom/media/test/hls/400x300_seg0.ts diff --git a/dom/media/test/hls/400x300_seg0_5s.ts b/dom/media/test/hls/400x300_seg0_5s.ts Binary files differnew file mode 100644 index 0000000000..9504d5d889 --- /dev/null +++ b/dom/media/test/hls/400x300_seg0_5s.ts diff --git a/dom/media/test/hls/400x300_seg1.ts b/dom/media/test/hls/400x300_seg1.ts Binary files differnew file mode 100644 index 0000000000..d751091e68 --- /dev/null +++ b/dom/media/test/hls/400x300_seg1.ts diff --git a/dom/media/test/hls/416x243_prog_index_5s.m3u8 b/dom/media/test/hls/416x243_prog_index_5s.m3u8 new file mode 100644 index 0000000000..ae518e7890 --- /dev/null +++ b/dom/media/test/hls/416x243_prog_index_5s.m3u8 @@ -0,0 +1,8 @@ +#EXTM3U +#EXT-X-TARGETDURATION:4.04 +#EXT-X-VERSION:4 +#EXT-X-MEDIA-SEQUENCE:0 +#EXT-X-PLAYLIST-TYPE:VOD +#EXTINF:4.04, +416x243_seg0_5s.ts +#EXT-X-ENDLIST diff --git a/dom/media/test/hls/416x243_seg0_5s.ts b/dom/media/test/hls/416x243_seg0_5s.ts Binary files differnew file mode 100644 index 0000000000..48e5473276 --- /dev/null +++ b/dom/media/test/hls/416x243_seg0_5s.ts diff --git a/dom/media/test/hls/640x480_prog_index.m3u8 b/dom/media/test/hls/640x480_prog_index.m3u8 new file mode 100644 index 0000000000..ac1212e2e7 --- /dev/null +++ b/dom/media/test/hls/640x480_prog_index.m3u8 @@ -0,0 +1,10 @@ +#EXTM3U +#EXT-X-TARGETDURATION:10 +#EXT-X-VERSION:3 +#EXT-X-MEDIA-SEQUENCE:0 +#EXT-X-PLAYLIST-TYPE:VOD +#EXTINF:9.97667, +640x480_seg0.ts +#EXTINF:9.97667, +640x480_seg1.ts +#EXT-X-ENDLIST diff --git a/dom/media/test/hls/640x480_seg0.ts b/dom/media/test/hls/640x480_seg0.ts Binary files differnew file mode 100644 index 0000000000..9bf0f0454a --- /dev/null +++ b/dom/media/test/hls/640x480_seg0.ts diff --git a/dom/media/test/hls/640x480_seg1.ts b/dom/media/test/hls/640x480_seg1.ts Binary files differnew file mode 100644 index 0000000000..c1ed938f44 --- /dev/null +++ b/dom/media/test/hls/640x480_seg1.ts diff --git a/dom/media/test/hls/960x720_prog_index.m3u8 b/dom/media/test/hls/960x720_prog_index.m3u8 new file mode 100644 index 0000000000..8ff18b089c --- /dev/null +++ b/dom/media/test/hls/960x720_prog_index.m3u8 @@ -0,0 +1,10 @@ +#EXTM3U +#EXT-X-TARGETDURATION:10 +#EXT-X-VERSION:3 +#EXT-X-MEDIA-SEQUENCE:0 +#EXT-X-PLAYLIST-TYPE:VOD +#EXTINF:9.97667, +960x720_seg0.ts +#EXTINF:9.97667, +960x720_seg1.ts +#EXT-X-ENDLIST diff --git a/dom/media/test/hls/960x720_seg0.ts b/dom/media/test/hls/960x720_seg0.ts Binary files differnew file mode 100644 index 0000000000..031bfe30d6 --- /dev/null +++ b/dom/media/test/hls/960x720_seg0.ts diff --git a/dom/media/test/hls/960x720_seg1.ts b/dom/media/test/hls/960x720_seg1.ts Binary files differnew file mode 100644 index 0000000000..63f15cb0cb --- /dev/null +++ b/dom/media/test/hls/960x720_seg1.ts diff --git a/dom/media/test/hls/bipbop_16x9_single.m3u8 b/dom/media/test/hls/bipbop_16x9_single.m3u8 new file mode 100644 index 0000000000..dce6a76c7b --- /dev/null +++ b/dom/media/test/hls/bipbop_16x9_single.m3u8 @@ -0,0 +1,5 @@ +#EXTM3U + +#EXT-X-STREAM-INF:BANDWIDTH=263851,CODECS="mp4a.40.2, avc1.4d400d" +416x243_prog_index_5s.m3u8 + diff --git a/dom/media/test/hls/bipbop_4x3_single.m3u8 b/dom/media/test/hls/bipbop_4x3_single.m3u8 new file mode 100644 index 0000000000..8f354ff011 --- /dev/null +++ b/dom/media/test/hls/bipbop_4x3_single.m3u8 @@ -0,0 +1,4 @@ +#EXTM3U + +#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=232370,CODECS="mp4a.40.2, avc1.4d4015" +400x300_prog_index_5s.m3u8
\ No newline at end of file diff --git a/dom/media/test/hls/bipbop_4x3_variant.m3u8 b/dom/media/test/hls/bipbop_4x3_variant.m3u8 new file mode 100644 index 0000000000..8a9a100dba --- /dev/null +++ b/dom/media/test/hls/bipbop_4x3_variant.m3u8 @@ -0,0 +1,10 @@ +#EXTM3U + +#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=232370,CODECS="mp4a.40.2, avc1.4d4015" +400x300_prog_index.m3u8 + +#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=649879,CODECS="mp4a.40.2, avc1.4d401e" +640x480_prog_index.m3u8 + +#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=649879,CODECS="mp4a.40.2, avc1.4d401e" +960x720_prog_index.m3u8 diff --git a/dom/media/test/huge-id3.mp3 b/dom/media/test/huge-id3.mp3 Binary files differnew file mode 100644 index 0000000000..41cb93d805 --- /dev/null +++ b/dom/media/test/huge-id3.mp3 diff --git a/dom/media/test/huge-id3.mp3^headers^ b/dom/media/test/huge-id3.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/huge-id3.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/id3tags.mp3 b/dom/media/test/id3tags.mp3 Binary files differnew file mode 100644 index 0000000000..bad506cf18 --- /dev/null +++ b/dom/media/test/id3tags.mp3 diff --git a/dom/media/test/id3tags.mp3^headers^ b/dom/media/test/id3tags.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/id3tags.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/id3v1afterlongid3v2.mp3 b/dom/media/test/id3v1afterlongid3v2.mp3 Binary files differnew file mode 100644 index 0000000000..8de7bde0d3 --- /dev/null +++ b/dom/media/test/id3v1afterlongid3v2.mp3 diff --git a/dom/media/test/invalid-cmap-s0c0.opus b/dom/media/test/invalid-cmap-s0c0.opus Binary files differnew file mode 100644 index 0000000000..0b99587865 --- /dev/null +++ b/dom/media/test/invalid-cmap-s0c0.opus diff --git a/dom/media/test/invalid-cmap-s0c0.opus^headers^ b/dom/media/test/invalid-cmap-s0c0.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-cmap-s0c0.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-cmap-s0c2.opus b/dom/media/test/invalid-cmap-s0c2.opus Binary files differnew file mode 100644 index 0000000000..a921894fee --- /dev/null +++ b/dom/media/test/invalid-cmap-s0c2.opus diff --git a/dom/media/test/invalid-cmap-s0c2.opus^headers^ b/dom/media/test/invalid-cmap-s0c2.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-cmap-s0c2.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-cmap-s1c2.opus b/dom/media/test/invalid-cmap-s1c2.opus Binary files differnew file mode 100644 index 0000000000..95a84f523c --- /dev/null +++ b/dom/media/test/invalid-cmap-s1c2.opus diff --git a/dom/media/test/invalid-cmap-s1c2.opus^headers^ b/dom/media/test/invalid-cmap-s1c2.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-cmap-s1c2.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-cmap-short.opus b/dom/media/test/invalid-cmap-short.opus Binary files differnew file mode 100644 index 0000000000..fcd7eb506a --- /dev/null +++ b/dom/media/test/invalid-cmap-short.opus diff --git a/dom/media/test/invalid-cmap-short.opus^headers^ b/dom/media/test/invalid-cmap-short.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-cmap-short.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-discard_on_multi_blocks.webm b/dom/media/test/invalid-discard_on_multi_blocks.webm Binary files differnew file mode 100644 index 0000000000..f39ab5bcb8 --- /dev/null +++ b/dom/media/test/invalid-discard_on_multi_blocks.webm diff --git a/dom/media/test/invalid-discard_on_multi_blocks.webm^headers^ b/dom/media/test/invalid-discard_on_multi_blocks.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-discard_on_multi_blocks.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-excess_discard.webm b/dom/media/test/invalid-excess_discard.webm Binary files differnew file mode 100644 index 0000000000..5b34aca1a7 --- /dev/null +++ b/dom/media/test/invalid-excess_discard.webm diff --git a/dom/media/test/invalid-excess_discard.webm^headers^ b/dom/media/test/invalid-excess_discard.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-excess_discard.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-excess_neg_discard.webm b/dom/media/test/invalid-excess_neg_discard.webm Binary files differnew file mode 100644 index 0000000000..2bfad6ed21 --- /dev/null +++ b/dom/media/test/invalid-excess_neg_discard.webm diff --git a/dom/media/test/invalid-excess_neg_discard.webm^headers^ b/dom/media/test/invalid-excess_neg_discard.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-excess_neg_discard.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-m0c0.opus b/dom/media/test/invalid-m0c0.opus Binary files differnew file mode 100644 index 0000000000..86555f60eb --- /dev/null +++ b/dom/media/test/invalid-m0c0.opus diff --git a/dom/media/test/invalid-m0c0.opus^headers^ b/dom/media/test/invalid-m0c0.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-m0c0.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-m0c3.opus b/dom/media/test/invalid-m0c3.opus Binary files differnew file mode 100644 index 0000000000..2c681a8c03 --- /dev/null +++ b/dom/media/test/invalid-m0c3.opus diff --git a/dom/media/test/invalid-m0c3.opus^headers^ b/dom/media/test/invalid-m0c3.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-m0c3.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-m1c0.opus b/dom/media/test/invalid-m1c0.opus Binary files differnew file mode 100644 index 0000000000..c7728f79ee --- /dev/null +++ b/dom/media/test/invalid-m1c0.opus diff --git a/dom/media/test/invalid-m1c0.opus^headers^ b/dom/media/test/invalid-m1c0.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-m1c0.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-m1c9.opus b/dom/media/test/invalid-m1c9.opus Binary files differnew file mode 100644 index 0000000000..1ef6e9f9cf --- /dev/null +++ b/dom/media/test/invalid-m1c9.opus diff --git a/dom/media/test/invalid-m1c9.opus^headers^ b/dom/media/test/invalid-m1c9.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-m1c9.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-m2c0.opus b/dom/media/test/invalid-m2c0.opus Binary files differnew file mode 100644 index 0000000000..5c3f97e2ab --- /dev/null +++ b/dom/media/test/invalid-m2c0.opus diff --git a/dom/media/test/invalid-m2c0.opus^headers^ b/dom/media/test/invalid-m2c0.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-m2c0.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-m2c1.opus b/dom/media/test/invalid-m2c1.opus Binary files differnew file mode 100644 index 0000000000..5ecb95ee25 --- /dev/null +++ b/dom/media/test/invalid-m2c1.opus diff --git a/dom/media/test/invalid-m2c1.opus^headers^ b/dom/media/test/invalid-m2c1.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-m2c1.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-neg_discard.webm b/dom/media/test/invalid-neg_discard.webm Binary files differnew file mode 100644 index 0000000000..3f665c0b59 --- /dev/null +++ b/dom/media/test/invalid-neg_discard.webm diff --git a/dom/media/test/invalid-neg_discard.webm^headers^ b/dom/media/test/invalid-neg_discard.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-neg_discard.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/invalid-preskip.webm b/dom/media/test/invalid-preskip.webm Binary files differnew file mode 100644 index 0000000000..99b4f2ca71 --- /dev/null +++ b/dom/media/test/invalid-preskip.webm diff --git a/dom/media/test/invalid-preskip.webm^headers^ b/dom/media/test/invalid-preskip.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/invalid-preskip.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/make-headers.sh b/dom/media/test/make-headers.sh new file mode 100644 index 0000000000..35d9bd90f8 --- /dev/null +++ b/dom/media/test/make-headers.sh @@ -0,0 +1,18 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Script to generate ^header^ files for all media files we use. +# This is to ensure that our media files are not cached by necko, +# so that our detection as to whether the server supports byte range +# requests is not interferred with by Necko's cache. See bug 977398 +# for details. Necko will fix this in bug 977314. + +FILES=(`ls *.ogg *.ogv *.webm *.mp3 *.opus *.mp4 *.m4s *.wav`) + +rm -f *.ogg^headers^ *.ogv^headers^ *.webm^headers^ *.mp3^headers^ *.opus^headers^ *.mp4^headers^ *.m4s^headers^ *.wav^headers^ + +for i in "${FILES[@]}" +do + echo "Cache-Control: no-store" >> $i^headers^ +done diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js new file mode 100644 index 0000000000..bb4557d498 --- /dev/null +++ b/dom/media/test/manifest.js @@ -0,0 +1,2556 @@ +const { AppConstants } = SpecialPowers.ChromeUtils.importESModule( + "resource://gre/modules/AppConstants.sys.mjs" +); + +// In each list of tests below, test file types that are not supported should +// be ignored. To make sure tests respect that, we include a file of type +// "bogus/duh" in each list. + +// Make sure to not touch navigator in here, since we want to push prefs that +// will affect the APIs it exposes, but the set of exposed APIs is determined +// when Navigator.prototype is created. So if we touch navigator before pushing +// the prefs, the APIs it exposes will not take those prefs into account. We +// work around this by using a navigator object from a different global for our +// UA string testing. +var gManifestNavigatorSource = document.documentElement.appendChild( + document.createElement("iframe") +); +gManifestNavigatorSource.style.display = "none"; +function manifestNavigator() { + return gManifestNavigatorSource.contentWindow.navigator; +} + +// Similarly, use a <video> element from a different global for canPlayType or +// other feature testing. If we used one from our global and did so before our +// prefs are pushed, then we'd instantiate HTMLMediaElement.prototype before the +// prefs are pushed and APIs we expect to be on that object would not be there. +function manifestVideo() { + return gManifestNavigatorSource.contentDocument.createElement("video"); +} + +// Need to get the server url composed with ip:port instead of mochi.test. +// Since we will provide the url to Exoplayer which cannot recognize the domain +// name "mochi.test". +let serverUrl = SpecialPowers.Services.prefs.getCharPref( + "media.hls.server.url" +); +var gHLSTests = [ + { + name: serverUrl + "/bipbop_4x3_variant.m3u8", + type: "audio/x-mpegurl", + duration: 20.0, + }, +]; + +// These are small test files, good for just seeing if something loads. We +// really only need one test file per backend here. +var gSmallTests = [ + { name: "small-shot.ogg", type: "audio/ogg", duration: 0.276 }, + { name: "small-shot.m4a", type: "audio/mp4", duration: 0.29 }, + { name: "small-shot.mp3", type: "audio/mpeg", duration: 0.27 }, + { name: "small-shot-mp3.mp4", type: "audio/mp4; codecs=mp3", duration: 0.34 }, + { name: "small-shot.flac", type: "audio/flac", duration: 0.197 }, + { name: "r11025_s16_c1-short.wav", type: "audio/x-wav", duration: 0.37 }, + { + name: "320x240.ogv", + type: "video/ogg", + width: 320, + height: 240, + duration: 0.266, + contentDuration: 0.133, + }, + { + name: "seek-short.webm", + type: "video/webm", + width: 320, + height: 240, + duration: 0.23, + }, + { + name: "vp9-short.webm", + type: "video/webm", + width: 320, + height: 240, + duration: 0.2, + }, + { + name: "detodos-short.opus", + type: "audio/ogg; codecs=opus", + duration: 0.22, + }, + { + name: "gizmo-short.mp4", + type: "video/mp4", + width: 560, + height: 320, + duration: 0.27, + }, + { name: "flac-s24.flac", type: "audio/flac", duration: 4.04 }, + { name: "bogus.duh", type: "bogus/duh" }, +]; + +var gFrameCountTests = [ + { name: "bipbop.mp4", type: "video/mp4", totalFrameCount: 297 }, + { name: "gizmo.mp4", type: "video/mp4", totalFrameCount: 166 }, + { name: "seek-short.webm", type: "video/webm", totalFrameCount: 8 }, + { name: "seek.webm", type: "video/webm", totalFrameCount: 120 }, + { name: "320x240.ogv", type: "video/ogg", totalFrameCount: 8 }, + { name: "av1.mp4", type: "video/mp4", totalFrameCount: 24 }, +]; + +gSmallTests = gSmallTests.concat([ + { name: "sample.3gp", type: "video/3gpp", duration: 4.933 }, + { name: "sample.3g2", type: "video/3gpp2", duration: 4.933 }, +]); + +// Used by test_bug654550.html, for videoStats preference +var gVideoTests = [ + { + name: "320x240.ogv", + type: "video/ogg", + width: 320, + height: 240, + duration: 0.266, + }, + { + name: "seek-short.webm", + type: "video/webm", + width: 320, + height: 240, + duration: 0.23, + }, + { name: "bogus.duh", type: "bogus/duh" }, +]; + +// Temp hack for trackIDs and captureStream() -- bug 1215769 +var gLongerTests = [ + { + name: "seek.webm", + type: "video/webm", + width: 320, + height: 240, + duration: 3.966, + }, + { + name: "gizmo.mp4", + type: "video/mp4", + width: 560, + height: 320, + duration: 5.56, + }, +]; + +// Used by test_progress to ensure we get the correct progress information +// during resource download. +var gProgressTests = [ + { name: "r11025_u8_c1.wav", type: "audio/x-wav", duration: 1.0, size: 11069 }, + { name: "big-short.wav", type: "audio/x-wav", duration: 1.11, size: 12366 }, + { name: "seek-short.ogv", type: "video/ogg", duration: 1.03, size: 79921 }, + { + name: "320x240.ogv", + type: "video/ogg", + width: 320, + height: 240, + duration: 0.266, + size: 28942, + }, + { name: "seek-short.webm", type: "video/webm", duration: 0.23, size: 19267 }, + { name: "gizmo-short.mp4", type: "video/mp4", duration: 0.27, size: 29905 }, + { name: "bogus.duh", type: "bogus/duh" }, +]; + +// Used by test_played.html +var gPlayedTests = [ + { name: "big-short.wav", type: "audio/x-wav", duration: 1.11 }, + { name: "seek-short.ogv", type: "video/ogg", duration: 1.03 }, + { name: "seek-short.webm", type: "video/webm", duration: 0.23 }, + { name: "gizmo-short.mp4", type: "video/mp4", duration: 0.27 }, + { name: "owl-short.mp3", type: "audio/mpeg", duration: 0.52 }, + { name: "very-short.mp3", type: "audio/mpeg", duration: 0.07 }, + // Disable vbr.mp3 to see if it reduces the error of AUDCLNT_E_CPUUSAGE_EXCEEDED. + // See bug 1110922 comment 26. + //{ name:"vbr.mp3", type:"audio/mpeg", duration:10.0 }, + { name: "bug495794.ogg", type: "audio/ogg", duration: 0.3 }, +]; + +if ( + manifestNavigator().userAgent.includes("Windows") && + manifestVideo().canPlayType('video/mp4; codecs="avc1.64000c"') +) { + gPlayedTests = gPlayedTests.concat( + { name: "red-46x48.mp4", type: "video/mp4", duration: 1.0 }, + { name: "red-48x46.mp4", type: "video/mp4", duration: 1.0 } + ); +} + +// Used by test_mozLoadFrom. Need one test file per decoder backend, plus +// anything for testing clone-specific bugs. +var cloneKey = Math.floor(Math.random() * 100000000); +var gCloneTests = [ + // short-video is more like 1s, so if you load this twice you'll get an unexpected duration + { + name: + "dynamic_resource.sjs?key=" + + cloneKey + + "&res1=320x240.ogv&res2=short-video.ogv", + type: "video/ogg", + duration: 0.266, + }, +]; + +// Used by test_play_twice. Need one test file per decoder backend, plus +// anything for testing bugs that occur when replying a played file. +var gReplayTests = gSmallTests.concat([ + { name: "bug533822.ogg", type: "audio/ogg" }, +]); + +// Used by test_paused_after_ended. Need one test file per decoder backend, plus +// anything for testing bugs that occur when replying a played file. +var gPausedAfterEndedTests = gSmallTests.concat([ + { name: "r11025_u8_c1.wav", type: "audio/x-wav", duration: 1.0 }, + { name: "small-shot.ogg", type: "video/ogg", duration: 0.276 }, +]); + +// Test the mozHasAudio property, and APIs that detect different kinds of +// tracks +var gTrackTests = [ + { + name: "big-short.wav", + type: "audio/x-wav", + duration: 1.11, + size: 12366, + hasAudio: true, + hasVideo: false, + }, + { + name: "320x240.ogv", + type: "video/ogg", + width: 320, + height: 240, + duration: 0.266, + size: 28942, + hasAudio: false, + hasVideo: true, + }, + { + name: "short-video.ogv", + type: "video/ogg", + duration: 1.081, + hasAudio: true, + hasVideo: true, + }, + { + name: "seek-short.webm", + type: "video/webm", + duration: 0.23, + size: 19267, + hasAudio: false, + hasVideo: true, + }, + { + name: "flac-s24.flac", + type: "audio/flac", + duration: 4.04, + hasAudio: true, + hasVideo: false, + }, + { name: "bogus.duh", type: "bogus/duh" }, +]; + +var gClosingConnectionsTest = [ + { name: "seek-short.ogv", type: "video/ogg", duration: 1.03 }, +]; + +// Used by any media recorder test. Need one test file per decoder backend +// currently supported by the media encoder. +var gMediaRecorderTests = [ + // Duration should be greater than 500ms because we will record 2 + // time slices (250ms per slice) + { + name: "detodos-recorder-test.opus", + type: "audio/ogg; codecs=opus", + duration: 0.62, + }, +]; + +// Used by video media recorder tests +var gMediaRecorderVideoTests = [ + { + name: "seek-short.webm", + type: "video/webm", + width: 320, + height: 240, + duration: 0.23, + }, +]; + +// These are files that we want to make sure we can play through. We can +// also check metadata. Put files of the same type together in this list so if +// something crashes we have some idea of which backend is responsible. +// Used by test_playback, which expects no error event and one ended event. +var gPlayTests = [ + // Test playback of a WebM file with vp9 video + { name: "vp9cake-short.webm", type: "video/webm", duration: 1.0 }, + // 8-bit samples + { name: "r11025_u8_c1.wav", type: "audio/x-wav", duration: 1.0 }, + // 8-bit samples, file is truncated + { name: "r11025_u8_c1_trunc.wav", type: "audio/x-wav", duration: 1.8 }, + // file has trailing non-PCM data + { name: "r11025_s16_c1_trailing.wav", type: "audio/x-wav", duration: 1.0 }, + // file with list chunk + { name: "r16000_u8_c1_list.wav", type: "audio/x-wav", duration: 4.2 }, + // file with 2 extra bytes of metadata + { + name: "16bit_wave_extrametadata.wav", + type: "audio/x-wav", + duration: 1.108, + }, + // IEEE float wave file + { name: "wavedata_float.wav", type: "audio/x-wav", duration: 1.0 }, + // 24-bit samples + { name: "wavedata_s24.wav", type: "audio/x-wav", duration: 1.0 }, + // aLaw compressed wave file + { name: "wavedata_alaw.wav", type: "audio/x-wav", duration: 1.0 }, + // uLaw compressed wave file + { name: "wavedata_ulaw.wav", type: "audio/x-wav", duration: 1.0 }, + // Data length 0xFFFFFFFF + { name: "bug1301226.wav", type: "audio/x-wav", duration: 0.003673 }, + // Data length 0xFFFFFFFF and odd chunk lengths. + { name: "bug1301226-odd.wav", type: "audio/x-wav", duration: 0.003673 }, + + // Ogg stream without eof marker + { name: "bug461281.ogg", type: "application/ogg", duration: 2.208 }, + + // oggz-chop stream + { name: "bug482461.ogv", type: "video/ogg", duration: 4.34 }, + // Theora only oggz-chop stream + { name: "bug482461-theora.ogv", type: "video/ogg", duration: 4.138 }, + // With first frame a "duplicate" (empty) frame. + { + name: "bug500311.ogv", + type: "video/ogg", + duration: 1.96, + contentDuration: 1.958, + }, + // Small audio file + { name: "small-shot.ogg", type: "audio/ogg", duration: 0.276 }, + // More audio in file than video. + { name: "short-video.ogv", type: "video/ogg", duration: 1.081 }, + // First Theora data packet is zero bytes. + { name: "bug504613.ogv", type: "video/ogg", duration: Number.NaN }, + // Multiple audio streams. + { name: "bug516323.ogv", type: "video/ogg", duration: 4.208 }, + // oggz-chop with non-keyframe as first frame + { + name: "bug556821.ogv", + type: "video/ogg", + duration: 2.936, + contentDuration: 2.903, + }, + + // Encoded with vorbis beta1, includes unusually sized codebooks + { name: "beta-phrasebook.ogg", type: "audio/ogg", duration: 4.01 }, + // Small file, only 1 frame with audio only. + { name: "bug520493.ogg", type: "audio/ogg", duration: 0.458 }, + // Small file with vorbis comments with 0 length values and names. + { name: "bug520500.ogg", type: "audio/ogg", duration: 0.123 }, + + // Various weirdly formed Ogg files + { + name: "bug499519.ogv", + type: "video/ogg", + duration: 0.24, + contentDuration: 0.22, + }, + { name: "bug506094.ogv", type: "video/ogg", duration: 0 }, + { name: "bug498855-1.ogv", type: "video/ogg", duration: 0.24 }, + { name: "bug498855-2.ogv", type: "video/ogg", duration: 0.24 }, + { name: "bug498855-3.ogv", type: "video/ogg", duration: 0.24 }, + { + name: "bug504644.ogv", + type: "video/ogg", + duration: 1.6, + contentDuration: 1.52, + }, + { + name: "chain.ogv", + type: "video/ogg", + duration: Number.NaN, + contentDuration: 0.266, + }, + { + name: "bug523816.ogv", + type: "video/ogg", + duration: 0.766, + contentDuration: 0, + }, + { name: "bug495129.ogv", type: "video/ogg", duration: 2.41 }, + { + name: "bug498380.ogv", + type: "video/ogg", + duration: 0.7663, + contentDuration: 0, + }, + { name: "bug495794.ogg", type: "audio/ogg", duration: 0.3 }, + { name: "bug557094.ogv", type: "video/ogg", duration: 0.24 }, + { name: "multiple-bos.ogg", type: "video/ogg", duration: 0.431 }, + { name: "audio-overhang.ogg", type: "video/ogg", duration: 2.3 }, + { name: "video-overhang.ogg", type: "video/ogg", duration: 3.966 }, + + // bug461281.ogg with the middle second chopped out. + { name: "audio-gaps.ogg", type: "audio/ogg", duration: 2.208 }, + + // Test playback/metadata work after a redirect + { + name: "redirect.sjs?domain=mochi.test:8888&file=320x240.ogv", + type: "video/ogg", + duration: 0.266, + }, + + // Test playback of a webm file + { name: "seek-short.webm", type: "video/webm", duration: 0.23 }, + + // Test playback of a webm file with 'matroska' doctype + { name: "bug1377278.webm", type: "video/webm", duration: 4.0 }, + + // Test playback of a WebM file with non-zero start time. + { name: "split.webm", type: "video/webm", duration: 1.967 }, + + // Test playback of a WebM file with resolution changes. + { name: "resolution-change.webm", type: "video/webm", duration: 6.533 }, + + // The following webm files test cases where the webm metadata dimensions do + // not match those in the stream. See bug 1695033 for more info. + + // Reference file with correct dimensions (webm metadata matches stream + // resolution). + { name: "bipbop_short_vp8.webm", type: "video/webm", duration: 1.011 }, + + // The webm resolution is greater in both dimensions than the in stream + // resolution. + { + name: "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + type: "video/webm", + duration: 1.011, + }, + + // The webm resolution is correct for height, but is narrower than the stream + // resolution. + { + name: "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + type: "video/webm", + duration: 1.011, + }, + + // The webm resolution is smaller in both dimensions than the in stream + // resolution. + { + name: "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + type: "video/webm", + duration: 1.011, + }, + + // End of webm dimension clashing files. + + // A really short, low sample rate, single channel file. This tests whether + // we can handle playing files when only push very little audio data to the + // hardware. + { name: "spacestorm-1000Hz-100ms.ogg", type: "audio/ogg", duration: 0.099 }, + + // Opus data in an ogg container + { + name: "detodos-short.opus", + type: "audio/ogg; codecs=opus", + duration: 0.22, + contentDuration: 0.2135, + }, + // Opus data in a webm container + { + name: "detodos-short.webm", + type: "audio/webm; codecs=opus", + duration: 0.26, + contentDuration: 0.2535, + }, + // Opus in webm channel mapping=2 sample file + { + name: "opus-mapping2.webm", + type: "audio/webm; codecs=opus", + duration: 10.01, + contentDuration: 9.99, + }, + { name: "bug1066943.webm", type: "audio/webm; codecs=opus", duration: 1.383 }, + + // Multichannel Opus in an ogg container + { name: "test-1-mono.opus", type: "audio/ogg; codecs=opus", duration: 1.044 }, + { + name: "test-2-stereo.opus", + type: "audio/ogg; codecs=opus", + duration: 2.925, + }, + { name: "test-3-LCR.opus", type: "audio/ogg; codecs=opus", duration: 4.214 }, + { name: "test-4-quad.opus", type: "audio/ogg; codecs=opus", duration: 6.234 }, + { name: "test-5-5.0.opus", type: "audio/ogg; codecs=opus", duration: 7.558 }, + { name: "test-6-5.1.opus", type: "audio/ogg; codecs=opus", duration: 10.333 }, + { name: "test-7-6.1.opus", type: "audio/ogg; codecs=opus", duration: 11.69 }, + { name: "test-8-7.1.opus", type: "audio/ogg; codecs=opus", duration: 13.478 }, + + { + name: "gizmo-short.mp4", + type: "video/mp4", + duration: 0.27, + contentDuration: 0.267, + }, + // Test playback of a MP4 file with a non-zero start time (and audio starting + // a second later). + { name: "bipbop-lateaudio.mp4", type: "video/mp4" }, + // Opus in MP4 channel mapping=0 sample file (content shorter due to preskip) + { + name: "opus-sample.mp4", + type: "audio/mp4; codecs=opus", + duration: 10.92, + contentDuration: 10.09, + }, + // Opus in MP4 channel mapping=2 sample file + { name: "opus-mapping2.mp4", type: "audio/mp4; codecs=opus", duration: 10.0 }, + + { name: "small-shot.m4a", type: "audio/mp4", duration: 0.29 }, + { name: "small-shot.mp3", type: "audio/mpeg", duration: 0.27 }, + { name: "owl.mp3", type: "audio/mpeg", duration: 3.343 }, + // owl.mp3 as above, but with something funny going on in the ID3v2 tag + // that caused DirectShow to fail. + { name: "owl-funny-id3.mp3", type: "audio/mpeg", duration: 3.343 }, + // owl.mp3 as above, but with something even funnier going on in the ID3v2 tag + // that caused DirectShow to fail. + { name: "owl-funnier-id3.mp3", type: "audio/mpeg", duration: 3.343 }, + // One second of silence with ~140KB of ID3 tags. Usually when the first MP3 + // frame is at such a high offset into the file, MP3FrameParser will give up + // and report that the stream is not MP3. However, it does not count ID3 tags + // in that offset. This test case makes sure that ID3 exclusion holds. + { name: "huge-id3.mp3", type: "audio/mpeg", duration: 1.0 }, + // Half a second file of a sine with a large ID3v2 tag, followed by an ID3v1 + // tag. The ID3v1 tags should be at the end of the file, but software usually + // play it anyway. + { name: "id3v1afterlongid3v2.mp3", type: "audio/mpeg", duration: 0.5 }, + // An VBR file with a padding value that is greater than an mp3 packet, and + // also subsequent packets after the theoretical EOF computed from metadata, + // to test padding trimming edge cases. + { + name: "padding-spanning-multiple-packets.mp3", + type: "audio/mpeg", + }, + // A truncated VBR MP3 with just enough frames to keep most decoders happy. + // The Xing header reports the length of the file to be around 10 seconds, but + // there is really only one second worth of data. We want MP3FrameParser to + // trust the header, so this should be reported as 10 seconds. + { + name: "vbr-head.mp3", + type: "audio/mpeg", + duration: 10.0, + contentDuration: 1.019, + }, + + // A flac file where the STREAMINFO block was removed. + // It is necessary to parse the file to find an audio frame instead. + { name: "flac-noheader-s16.flac", type: "audio/flac", duration: 4.0 }, + { name: "flac-s24.flac", type: "audio/flac", duration: 4.04 }, + { + name: "flac-sample.mp4", + type: "audio/mp4; codecs=flac", + duration: 4.95, + contentDuration: 5.03, + }, + // Ogg with theora video and flac audio. + { + name: "A4.ogv", + type: "video/ogg", + width: 320, + height: 240, + duration: 3.13, + }, + // A file that has no codec delay at the container level, but has a delay at + // the codec level. + { + name: "no-container-codec-delay.webm", + type: "video/webm", + }, + // A file that has a codec delay at a container level of 0, but as a delay at + // the codec level that is non-zero. + { name: "invalid-preskip.webm", type: "audio/webm; codecs=opus" }, + + // Invalid file + { name: "bogus.duh", type: "bogus/duh", duration: Number.NaN }, +]; + +const win32 = + SpecialPowers.Services.appinfo.OS == "WINNT" && + !SpecialPowers.Services.appinfo.is64Bit; +if (!win32) { + gPlayTests.push({ name: "av1.mp4", type: "video/mp4", duration: 1.0 }); +} + +// AAC files with different sample rates. We add these here as some are added +// conditionally. +gPlayTests.push( + { + name: "bipbop_audio_aac_8k.mp4", + type: "audio/mp4", + duration: 1.06, + }, + { + name: "bipbop_audio_aac_22.05k.mp4", + type: "audio/mp4", + duration: 1.06, + }, + { + name: "bipbop_audio_aac_44.1k.mp4", + type: "audio/mp4", + duration: 1.06, + }, + { + name: "bipbop_audio_aac_48k.mp4", + type: "audio/mp4", + duration: 1.06, + } +); +if (AppConstants.platform != "win") { + // Windows WMF decoder doesn't do >48K everywhere. See bug 1698639. + gPlayTests.push( + { + name: "bipbop_audio_aac_88.2k.mp4", + type: "audio/mp4", + duration: 1.06, + }, + { + name: "bipbop_audio_aac_96k.mp4", + type: "audio/mp4", + duration: 1.06, + } + ); +} + +// ambisonics.mp4 causes intermittents, so we conditionally add it until we fix +// the root cause. +const skipAmbisonics = + // Bug 1484451 - skip on mac debug + (AppConstants.platform == "macosx" && AppConstants.DEBUG) || + // Bug 1483259 - skip on linux64 opt + (AppConstants.platform == "linux" && + !AppConstants.DEBUG && + SpecialPowers.Services.appinfo.is64Bit); +if (!skipAmbisonics) { + // Ambisonics AAC, requires AAC extradata to be set when creating decoder (see bug 1431169) + // Also test 4.0 decoding. + gPlayTests.push({ + name: "ambisonics.mp4", + type: "audio/mp4", + duration: 16.48, + }); +} + +var gSeekToNextFrameTests = [ + // Test playback of a WebM file with vp9 video + { name: "vp9-short.webm", type: "video/webm", duration: 0.2 }, + { name: "vp9cake-short.webm", type: "video/webm", duration: 1.0 }, + // oggz-chop stream + { name: "bug482461.ogv", type: "video/ogg", duration: 4.34 }, + // Theora only oggz-chop stream + { name: "bug482461-theora.ogv", type: "video/ogg", duration: 4.138 }, + // With first frame a "duplicate" (empty) frame. + { name: "bug500311.ogv", type: "video/ogg", duration: 1.96 }, + + // More audio in file than video. + { name: "short-video.ogv", type: "video/ogg", duration: 1.081 }, + // First Theora data packet is zero bytes. + { name: "bug504613.ogv", type: "video/ogg", duration: Number.NaN }, + // Multiple audio streams. + { name: "bug516323.ogv", type: "video/ogg", duration: 4.208 }, + // oggz-chop with non-keyframe as first frame + { name: "bug556821.ogv", type: "video/ogg", duration: 2.936 }, + // Various weirdly formed Ogg files + { name: "bug498855-1.ogv", type: "video/ogg", duration: 0.24 }, + { name: "bug498855-2.ogv", type: "video/ogg", duration: 0.24 }, + { name: "bug498855-3.ogv", type: "video/ogg", duration: 0.24 }, + { name: "bug504644.ogv", type: "video/ogg", duration: 1.6 }, + + { name: "bug523816.ogv", type: "video/ogg", duration: 0.766 }, + + { name: "bug498380.ogv", type: "video/ogg", duration: 0.2 }, + { name: "bug557094.ogv", type: "video/ogg", duration: 0.24 }, + { name: "multiple-bos.ogg", type: "video/ogg", duration: 0.431 }, + // Test playback/metadata work after a redirect + { + name: "redirect.sjs?domain=mochi.test:8888&file=320x240.ogv", + type: "video/ogg", + duration: 0.266, + }, + // Test playback of a webm file + { name: "seek-short.webm", type: "video/webm", duration: 0.23 }, + // Test playback of a WebM file with non-zero start time. + { name: "split.webm", type: "video/webm", duration: 1.967 }, + + { name: "gizmo-short.mp4", type: "video/mp4", duration: 0.27 }, + + // Test playback of a MP4 file with a non-zero start time (and audio starting + // a second later). + { name: "bipbop-lateaudio.mp4", type: "video/mp4" }, +]; + +// A file for each type we can support. +var gSnifferTests = [ + { name: "big.wav", type: "audio/x-wav", duration: 9.278982, size: 102444 }, + { + name: "320x240.ogv", + type: "video/ogg", + width: 320, + height: 240, + duration: 0.233, + size: 28942, + }, + { name: "seek.webm", type: "video/webm", duration: 3.966, size: 215529 }, + { name: "gizmo.mp4", type: "video/mp4", duration: 5.56, size: 383631 }, + // A mp3 file with id3 tags. + { name: "id3tags.mp3", type: "audio/mpeg", duration: 0.28, size: 3530 }, + { name: "bogus.duh", type: "bogus/duh" }, +]; + +// Files that contain resolution changes +var gResolutionChangeTests = [ + { name: "resolution-change.webm", type: "video/webm", duration: 6.533 }, +]; + +// Files we must reject as invalid. +var gInvalidTests = [ + { name: "invalid-m0c0.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-m0c3.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-m1c0.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-m1c9.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-m2c0.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-m2c1.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-cmap-short.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-cmap-s0c0.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-cmap-s0c2.opus", type: "audio/ogg; codecs=opus" }, + { name: "invalid-cmap-s1c2.opus", type: "audio/ogg; codecs=opus" }, +]; + +var gInvalidPlayTests = [ + { name: "invalid-excess_discard.webm", type: "audio/webm; codecs=opus" }, + { name: "invalid-excess_neg_discard.webm", type: "audio/webm; codecs=opus" }, + { name: "invalid-neg_discard.webm", type: "audio/webm; codecs=opus" }, + { + name: "invalid-discard_on_multi_blocks.webm", + type: "audio/webm; codecs=opus", + }, +]; + +// Files to check different cases of ogg skeleton information. +// sample-fisbone-skeleton4.ogv +// - Skeleton v4, w/ Content-Type,Role,Name,Language,Title for both theora/vorbis +// sample-fisbone-wrong-header.ogv +// - Skeleton v4, wrong message field sequence for vorbis +// multiple-bos-more-header-fields.ogg +// - Skeleton v3, w/ Content-Type,Role,Name,Language,Title for both theora/vorbis +// seek-short.ogv +// - No skeleton, but theora +// audio-gaps-short.ogg +// - No skeleton, but vorbis +var gMultitrackInfoOggPlayList = [ + { name: "sample-fisbone-skeleton4.ogv", type: "video/ogg", duration: 1.0 }, + { name: "sample-fisbone-wrong-header.ogv", type: "video/ogg", duration: 1.0 }, + { + name: "multiple-bos-more-header-fileds.ogg", + type: "video/ogg", + duration: 0.431, + }, + { name: "seek-short.ogv", type: "video/ogg", duration: 1.03 }, + { name: "audio-gaps-short.ogg", type: "audio/ogg", duration: 0.5 }, +]; +// Pre-parsed results of gMultitrackInfoOggPlayList. +var gOggTrackInfoResults = { + "sample-fisbone-skeleton4.ogv": { + audio_id: " audio_1", + audio_kind: "main", + audio_language: " en-US", + audio_label: " Audio track for test", + video_id: " video_1", + video_kind: "main", + video_language: " fr", + video_label: " Video track for test", + }, + "sample-fisbone-wrong-header.ogv": { + audio_id: "1", + audio_kind: "main", + audio_language: "", + audio_label: "", + video_id: " video_1", + video_kind: "main", + video_language: " fr", + video_label: " Video track for test", + }, + "multiple-bos-more-header-fileds.ogg": { + audio_id: "1", + audio_kind: "main", + audio_language: "", + audio_label: "", + video_id: "2", + video_kind: "main", + video_language: "", + video_label: "", + }, + "seek-short.ogv": { + video_id: "2", + video_kind: "main", + video_language: "", + video_label: "", + }, + "audio-gaps-short.ogg": { + audio_id: "1", + audio_kind: "main", + audio_language: "", + audio_label: "", + }, +}; + +// Returns a promise that resolves to a function that converts +// relative paths to absolute, to test loading files from file: URIs. +// Optionally checks whether the file actually exists on disk at the location +// we've specified. +function makeAbsolutePathConverter() { + const url = SimpleTest.getTestFileURL("chromeHelper.js"); + const script = SpecialPowers.loadChromeScript(url); + return new Promise((resolve, reject) => { + script.addMessageListener("media-test:cwd", cwd => { + if (!cwd) { + ok(false, "Failed to find path to test files"); + } + + resolve((path, mustExist) => { + // android mochitest doesn't support file:// + if (manifestNavigator().appVersion.includes("Android")) { + return path; + } + + const { Ci, Cc } = SpecialPowers; + var f = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); + f.initWithPath(cwd); + var split = path.split("/"); + for (var i = 0; i < split.length; ++i) { + f.append(split[i]); + } + if (mustExist && !f.exists()) { + ok(false, "We expected '" + path + "' to exist, but it doesn't!"); + } + return f.path; + }); + }); + script.sendAsyncMessage("media-test:getcwd"); + }); +} + +// Returns true if two TimeRanges are equal, false otherwise +function range_equals(r1, r2) { + if (r1.length != r2.length) { + return false; + } + for (var i = 0; i < r1.length; i++) { + if (r1.start(i) != r2.start(i) || r1.end(i) != r2.end(i)) { + return false; + } + } + return true; +} + +// These are URIs to files that we use to check that we don't leak any state +// or other information such that script can determine stuff about a user's +// environment. Used by test_info_leak. +function makeInfoLeakTests() { + return makeAbsolutePathConverter().then(fileUriToSrc => [ + { + type: "video/ogg", + src: fileUriToSrc("tests/dom/media/test/320x240.ogv", true), + }, + { + type: "video/ogg", + src: fileUriToSrc("tests/dom/media/test/404.ogv", false), + }, + { + type: "audio/x-wav", + src: fileUriToSrc("tests/dom/media/test/r11025_s16_c1.wav", true), + }, + { + type: "audio/x-wav", + src: fileUriToSrc("tests/dom/media/test/404.wav", false), + }, + { + type: "audio/ogg", + src: fileUriToSrc("tests/dom/media/test/bug461281.ogg", true), + }, + { + type: "audio/ogg", + src: fileUriToSrc("tests/dom/media/test/404.ogg", false), + }, + { + type: "video/webm", + src: fileUriToSrc("tests/dom/media/test/seek.webm", true), + }, + { + type: "video/webm", + src: fileUriToSrc("tests/dom/media/test/404.webm", false), + }, + { + type: "video/ogg", + src: "http://localhost/404.ogv", + }, + { + type: "audio/x-wav", + src: "http://localhost/404.wav", + }, + { + type: "video/webm", + src: "http://localhost/404.webm", + }, + { + type: "video/ogg", + src: "http://example.com/tests/dom/media/test/test_info_leak.html", + }, + { + type: "audio/ogg", + src: "http://example.com/tests/dom/media/test/test_info_leak.html", + }, + ]); +} + +// These are files that must fire an error during load or playback, and do not +// cause a crash. Used by test_playback_errors, which expects one error event +// and no ended event. Put files of the same type together in this list so if +// something crashes we have some idea of which backend is responsible. +var gErrorTests = [ + { name: "bogus.wav", type: "audio/x-wav" }, + { name: "bogus.ogv", type: "video/ogg" }, + { name: "448636.ogv", type: "video/ogg" }, + { name: "bug504843.ogv", type: "video/ogg" }, + { name: "bug501279.ogg", type: "audio/ogg" }, + { name: "bug604067.webm", type: "video/webm" }, + { name: "bug1535980.webm", type: "video/webm" }, + { name: "bug1799787.webm", type: "video/webm" }, + { name: "bogus.duh", type: "bogus/duh" }, +]; + +// Playing this file errors out after receiving "loadedmetadata", we still want +// to check the duration in "onerror" and make sure it is still available. +var gDurationTests = [{ name: "bug604067.webm", duration: 6.076 }]; + +// These are files that have nontrivial duration and are useful for seeking within. +var gSeekTests = [ + { name: "r11025_s16_c1.wav", type: "audio/x-wav", duration: 1.0 }, + { name: "audio.wav", type: "audio/x-wav", duration: 0.031247 }, + { name: "seek.ogv", type: "video/ogg", duration: 3.966 }, + { name: "320x240.ogv", type: "video/ogg", duration: 0.266 }, + { name: "seek.webm", type: "video/webm", duration: 3.966 }, + { name: "sine.webm", type: "audio/webm", duration: 4.001 }, + { name: "bug516323.indexed.ogv", type: "video/ogg", duration: 4.208333 }, + { name: "split.webm", type: "video/webm", duration: 1.967 }, + { name: "detodos.opus", type: "audio/ogg; codecs=opus", duration: 2.9135 }, + { name: "gizmo.mp4", type: "video/mp4", duration: 5.56 }, + { + name: "/tests/dom/media/webaudio/test/half-a-second-1ch-44100-aac-afconvert.mp4", + type: 'audio/mp4; codecs="mp4a.40.2"', + duration: 0.5, + }, + { name: "owl.mp3", type: "audio/mpeg", duration: 3.343 }, + { name: "bogus.duh", type: "bogus/duh", duration: 123 }, + + // Bug 1242338: hit a numerical problem while seeking to the duration. + { name: "bug482461-theora.ogv", type: "video/ogg", duration: 4.138 }, +]; + +var gFastSeekTests = [ + { + name: "gizmo.mp4", + type: "video/mp4", + keyframes: [0, 1.0, 2.0, 3.0, 4.0, 5.0], + }, + // Note: Not all keyframes in the file are actually referenced in the Cues in this file. + { name: "seek.webm", type: "video/webm", keyframes: [0, 0.8, 1.6, 2.4, 3.2] }, + // Note: the sync points are the points on both the audio and video streams + // before the keyframes. You can't just assume that the keyframes are the sync + // points, as the audio required for that sync point may be before the keyframe. + { + name: "bug516323.indexed.ogv", + type: "video/ogg", + keyframes: [0, 0.46, 3.06], + }, +]; + +// These files are WebMs without cues. They're seekable within their buffered +// ranges. If work renders WebMs fully seekable these files should be moved +// into gSeekTests +var gCuelessWebMTests = [ + { name: "no-cues.webm", type: "video/webm", duration: 3.967 }, +]; + +// These are files that are non seekable, due to problems with the media, +// for example broken or missing indexes. +var gUnseekableTests = [{ name: "bogus.duh", type: "bogus/duh" }]; + +var androidVersion = -1; // non-Android platforms +if ( + manifestNavigator().userAgent.includes("Mobile") || + manifestNavigator().userAgent.includes("Tablet") +) { + androidVersion = SpecialPowers.Services.sysinfo.getProperty("version"); +} + +function getAndroidVersion() { + return androidVersion; +} + +// These are files suitable for using with a "new Audio" constructor. +var gAudioTests = [ + { name: "adts.aac", type: "audio/mp4", duration: 1.37 }, + { name: "r11025_s16_c1.wav", type: "audio/x-wav", duration: 1.0 }, + { name: "sound.ogg", type: "audio/ogg" }, + { name: "owl.mp3", type: "audio/mpeg", duration: 3.343 }, + { name: "small-shot.m4a", type: "audio/mp4", duration: 0.29 }, + { name: "bogus.duh", type: "bogus/duh", duration: 123 }, + { name: "empty_size.mp3", type: "audio/mpeg", duration: 2.235 }, +]; + +// These files ensure our handling of 404 errors is consistent across the +// various backends. +var g404Tests = [ + { name: "404.wav", type: "audio/x-wav" }, + { name: "404.ogv", type: "video/ogg" }, + { name: "404.oga", type: "audio/ogg" }, + { name: "404.webm", type: "video/webm" }, + { name: "bogus.duh", type: "bogus/duh" }, +]; + +// These are files suitable for testing various decoder failures that are +// expected to fire MEDIA_ERR_DECODE. Used by test_decode_error, which expects +// an error and emptied event, and no loadedmetadata or ended event. +var gDecodeErrorTests = [ + // Valid files with unsupported codecs + { name: "r11025_msadpcm_c1.wav", type: "audio/x-wav" }, + { name: "dirac.ogg", type: "video/ogg" }, + // Invalid files + { name: "bogus.wav", type: "audio/x-wav" }, + { name: "bogus.ogv", type: "video/ogg" }, + + { name: "bogus.duh", type: "bogus/duh" }, +]; + +// These are files that are used for media fragments tests +var gFragmentTests = [ + { name: "big.wav", type: "audio/x-wav", duration: 9.278982, size: 102444 }, +]; + +// Used by test_chaining.html. The |links| attributes is the number of links in +// this file that we should be able to play. +var gChainingTests = [ + // Vorbis and Opus chained file. They have user comments |index=n| where `n` + // is the index of this segment in the file, 0 indexed. + { name: "chain.ogg", type: "audio/ogg", links: 4 }, + { name: "chain.opus", type: "audio/ogg; codec=opus", links: 4 }, + // Those files are chained files with a different number of channels in each + // part. This is not supported and should stop playing after the first part. + { name: "variable-channel.ogg", type: "audio/ogg", links: 1 }, + { name: "variable-channel.opus", type: "audio/ogg; codec=opus", links: 1 }, + // Those files are chained files with a different sample rate in each + // part. This is not supported and should stop playing after the first part. + { name: "variable-samplerate.ogg", type: "audio/ogg", links: 1 }, + // Opus decoding in Firefox outputs 48 kHz PCM despite having a different + // original sample rate, so we can safely play Opus chained media that have + // different samplerate accross links. + { name: "variable-samplerate.opus", type: "audio/ogg; codec=opus", links: 2 }, + // A chained video file. We don't support those, so only one link should be + // reported. + { name: "chained-video.ogv", type: "video/ogg", links: 1 }, + // A file that consist in 4 links of audio, then another link that has video. + // We should stop right after the 4 audio links. + { name: "chained-audio-video.ogg", type: "video/ogg", links: 4 }, + // An opus file that has two links, with a different preskip value for each + // link. We should be able to play both links. + { name: "variable-preskip.opus", type: "audio/ogg; codec=opus", links: 2 }, + { name: "bogus.duh", type: "bogus/duh" }, +]; + +// Videos with an aspect ratio. Used for testing that displaying frames +// on a canvas works correctly in the case of non-standard aspect ratios. +// See bug 874897 for an example. +var gAspectRatioTests = [ + { name: "VID_0001.ogg", type: "video/ogg", duration: 19.966 }, +]; + +// These are files with non-trivial tag sets. +// Used by test_metadata.html. +var gMetadataTests = [ + // Ogg Vorbis files + { + name: "short-video.ogv", + tags: { + TITLE: "Lepidoptera", + ARTIST: "Epoq", + ALBUM: "Kahvi Collective", + DATE: "2002", + COMMENT: "http://www.kahvi.org", + }, + }, + { + name: "bug516323.ogv", + tags: { + GENRE: "Open Movie", + ENCODER: "Audacity", + TITLE: "Elephants Dream", + ARTIST: "Silvia Pfeiffer", + COMMENTS: "Audio Description", + }, + }, + { + name: "bug516323.indexed.ogv", + tags: { + GENRE: "Open Movie", + ENCODER: "Audacity", + TITLE: "Elephants Dream", + ARTIST: "Silvia Pfeiffer", + COMMENTS: "Audio Description", + }, + }, + { + name: "detodos.opus", + tags: { + title: "De todos. Para todos.", + artist: "Mozilla.org", + }, + }, + { name: "sound.ogg", tags: {} }, + { + name: "small-shot.ogg", + tags: { + title: "Pew SFX", + }, + }, + { + name: "badtags.ogg", + tags: { + // We list only the valid tags here, and verify + // the invalid ones are filtered out. + title: "Invalid comments test file", + empty: "", + "": "empty", + "{- [(`!@\"#$%^&')] -}": "valid tag name, surprisingly", + // The file also includes the following invalid tags. + // "A description with no separator is a common problem.", + // "雨":"Likely, but an invalid key (non-ascii).", + // "not\nval\x1fid":"invalid tag name", + // "not~valid":"this isn't a valid name either", + // "not-utf-8":"invalid sequences: \xff\xfe\xfa\xfb\0eol" + }, + }, + { + name: "wave_metadata.wav", + tags: { + name: "Track Title", + artist: "Artist Name", + comments: "Comments", + }, + }, + { + name: "wave_metadata_utf8.wav", + tags: { + name: "歌曲名稱", + artist: "作曲者", + comments: "註解", + }, + }, + { + name: "wave_metadata_unknown_tag.wav", + tags: { + name: "Track Title", + comments: "Comments", + }, + }, + { + name: "wave_metadata_bad_len.wav", + tags: { + name: "Track Title", + artist: "Artist Name", + comments: "Comments", + }, + }, + { + name: "wave_metadata_bad_no_null.wav", + tags: { + name: "Track Title", + artist: "Artist Name", + comments: "Comments!!", + }, + }, + { + name: "wave_metadata_bad_utf8.wav", + tags: { + name: "歌曲名稱", + comments: "註解", + }, + }, + { name: "wavedata_u8.wav", tags: {} }, +]; + +// Now Fennec doesn't support flac, so only test it on non-android platforms. +if (getAndroidVersion() < 0) { + gMetadataTests = gMetadataTests.concat([ + { + name: "flac-s24.flac", + tags: { + ALBUM: "Seascapes", + TITLE: "(La Mer) - II. Jeux de vagues. Allegro", + COMPOSER: "Debussy, Claude", + TRACKNUMBER: "2/9", + DISCNUMBER: "1/1", + encoder: "Lavf57.41.100", + }, + }, + ]); +} + +// Test files for Encrypted Media Extensions +var gEMETests = [ + { + name: "vp9 in mp4", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="vp9.0"', + fragments: ["short-vp9-encrypted-video.mp4"], + }, + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: ["short-aac-encrypted-audio.mp4"], + }, + ], + keys: { + "2cdb0ed6119853e7850671c3e9906c3c": "808B9ADAC384DE1E4F56140F4AD76194", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 0.47, + }, + { + name: "video-only with 2 keys", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d03": "7e5733337e5733337e5733337e573333", + "7e571d047e571d047e571d047e571d04": "7e5744447e5744447e5744447e574444", + }, + sessionType: "temporary", + sessionCount: 1, + duration: 1.6, + }, + { + name: "video-only with 2 keys, CORS", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d03": "7e5733337e5733337e5733337e573333", + "7e571d047e571d047e571d047e571d04": "7e5744447e5744447e5744447e574444", + }, + sessionType: "temporary", + sessionCount: 1, + crossOrigin: true, + duration: 1.6, + }, + { + name: "audio&video tracks, both with all keys", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio3.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d03": "7e5733337e5733337e5733337e573333", + "7e571d047e571d047e571d047e571d04": "7e5744447e5744447e5744447e574444", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "audio&video tracks, both with all keys, CORS", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio3.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d03": "7e5733337e5733337e5733337e573333", + "7e571d047e571d047e571d047e571d04": "7e5744447e5744447e5744447e574444", + }, + sessionType: "temporary", + sessionCount: 2, + crossOrigin: true, + duration: 1.6, + }, + { + name: "400x300 audio&video tracks, each with its key", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "640x480@624kbps audio&video tracks, each with its key", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d401e"', + fragments: [ + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "640x480@959kbps audio&video tracks, each with its key", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d401e"', + fragments: [ + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "640x480 then 400x300, same key (1st) per track", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d401e,avc1.4d4015"', + fragments: [ + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + name: "640x480 then 400x300, same key (2nd) per track", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d401e,avc1.4d4015"', + fragments: [ + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312", + "7e571d047e571d047e571d047e571d22": "7e5744447e5744447e5744447e574422", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + name: "640x480 with 1st keys then 400x300 with 2nd keys", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d401e,avc1.4d4015"', + fragments: [ + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + name: "400x300 with 1st keys then 640x480 with 2nd keys", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015,avc1.4d401e"', + fragments: [ + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + name: "640x480@959kbps with 1st keys then 640x480@624kbps with 2nd keys", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d401e"', + fragments: [ + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + name: "640x480@624kbps with 1st keys then 640x480@959kbps with 2nd keys", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d401e"', + fragments: [ + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + name: "400x300 with presentation size 533x300", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "400x300 as-is then 400x300 presented as 533x300", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + name: "400x225", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.64000d"', + fragments: [ + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "640x360", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.64001e"', + fragments: [ + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "400x225 then 640x360", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.64000d,avc1.64001e"', + fragments: [ + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + name: "640x360 then 640x480", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + ], + }, + { + name: "video", + type: 'video/mp4; codecs="avc1.64001e,avc1.4d401e"', + fragments: [ + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311", + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312", + }, + sessionType: "temporary", + sessionCount: 3, + duration: 1.6, + }, + { + // File generated with shaka packager: + // packager-osx --enable_raw_key_encryption --keys label=:key_id=7e571d047e571d047e571d047e571d21:key=7e5744447e5744447e5744447e574421 --segment_duration 1 --clear_lead 0 in=test-flac.mp4,stream=audio,output=flac-sample-cenc.mp4 + name: "flac in mp4 clearkey", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="flac"', + fragments: ["flac-sample-cenc.mp4"], + }, + ], + keys: { + // "keyid" : "key" + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 1, + duration: 2.05, + }, + { + // File generated with shaka packager: + // packager-osx --enable_raw_key_encryption --keys label=:key_id=7e571d047e571d047e571d047e571d21:key=7e5744447e5744447e5744447e574421 --segment_duration 1 --clear_lead 0 in=test-opus.mp4,stream=audio,output=opus-sample-cenc.mp4 + name: "opus in mp4 clearkey", + tracks: [ + { + name: "audio", + type: 'audio/mp4; codecs="opus"', + fragments: ["opus-sample-cenc.mp4"], + }, + ], + keys: { + // "keyid" : "key" + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 1, + duration: 1.98, + }, + { + name: "WebM vorbis audio & vp8 video clearkey", + tracks: [ + { + name: "audio", + type: 'audio/webm; codecs="vorbis"', + fragments: ["bipbop_360w_253kbps-clearkey-audio.webm"], + }, + { + name: "video", + type: 'video/webm; codecs="vp8"', + fragments: ["bipbop_360w_253kbps-clearkey-video-vp8.webm"], + }, + ], + keys: { + // "keyid" : "key" + f1f3ee1790527e9de47217d43835f76a: "97b9ddc459c8d5ff23c1f2754c95abe8", + "8b5df745ad84145b5617c33116e35a67": "bddfd35dd9be033ee73bc18bc1885056", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "WebM vorbis audio & vp9 video clearkey", + tracks: [ + { + name: "audio", + type: 'audio/webm; codecs="vorbis"', + fragments: ["bipbop_360w_253kbps-clearkey-audio.webm"], + }, + { + name: "video", + type: 'video/webm; codecs="vp9"', + fragments: ["bipbop_360w_253kbps-clearkey-video-vp9.webm"], + }, + ], + keys: { + // "keyid" : "key" + f1f3ee1790527e9de47217d43835f76a: "97b9ddc459c8d5ff23c1f2754c95abe8", + eedf63a94fa7c398ee094f123a4ee709: "973b679a746c82f3acdb856b30e9378e", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 1.6, + }, + { + name: "WebM vorbis audio & vp9 video clearkey with subsample encryption", + tracks: [ + { + name: "audio", + type: 'audio/webm; codecs="vorbis"', + fragments: ["sintel-short-clearkey-subsample-encrypted-audio.webm"], + }, + { + name: "video", + type: 'video/webm; codecs="vp9"', + fragments: ["sintel-short-clearkey-subsample-encrypted-video.webm"], + }, + ], + keys: { + // "keyid" : "key" + "2cdb0ed6119853e7850671c3e9906c3c": "808B9ADAC384DE1E4F56140F4AD76194", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 2.0, + }, + { + // Files adapted from testcase for bug 1560092. See bug 1630381 for a + // detailed explanation on how they were adapted. + name: "avc3 h264 video in mp4 using clearkey cenc encryption", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="avc3.640015"', + fragments: [ + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "10000000100010001000100000000001": "3A2A1B68DD2BD9B2EEB25E84C4776668", + }, + sessionType: "temporary", + sessionCount: 1, + duration: 2.08, + }, + // The following cbcs files are created using shaka-packager using commands like + // ./packager-win.exe 'in=bipbop_2s.mp4,stream=audio,init_segment=bipbop_cbcs_1_9_audio_init.mp4,segment_template=bipbop_cbcs_1_9_audio_$Number$.m4s' \ + // 'in=bipbop_2s.mp4,stream=video,init_segment=bipbop_cbcs_1_9_video_init.mp4,segment_template=bipbop_cbcs_1_9_video_$Number$.m4s' --protection_scheme cbcs \ + // --enable_raw_key_encryption --keys label=:key_id=7e571d047e571d047e571d047e571d21:key=7e5744447e5744447e5744447e574421 --iv 11223344556677889900112233445566 \ + // --clear_lead 0 --crypt_byte_block 1 --skip_byte_block 9 + // See bug 1726202 for more details on their creation. + { + name: "mp4 h264 + aac clearkey cbcs 1:9 pattern", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_1.m4s", + ], + }, + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 2.04, + }, + { + name: "mp4 h264 + aac clearkey cbcs 5:5 pattern", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_1.m4s", + ], + }, + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 2.04, + }, + { + name: "mp4 h264 + aac clearkey cbcs 10:0 pattern", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_1.m4s", + ], + }, + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 2.04, + }, + { + name: "mp4 h264 + aac clearkey cbcs 7:7 pattern", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_1.m4s", + ], + }, + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 2.04, + }, + { + name: "mp4 h264 + aac clearkey cbcs 9:8 pattern", + tracks: [ + { + name: "video", + type: 'video/mp4; codecs="avc1.4d4015"', + fragments: [ + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_1.m4s", + ], + }, + { + name: "audio", + type: 'audio/mp4; codecs="mp4a.40.2"', + fragments: [ + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_1.m4s", + ], + }, + ], + keys: { + // "keyid" : "key" + "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421", + }, + sessionType: "temporary", + sessionCount: 2, + duration: 2.04, + }, +]; + +var gEMENonMSEFailTests = [ + { + name: "short-cenc.mp4", + audioType: 'audio/mp4; codecs="mp4a.40.2"', + videoType: 'video/mp4; codecs="avc1.64000d"', + duration: 0.47, + }, +]; + +// Test files that are supposed to loop seamlessly when played back. +var gSeamlessLoopingTests = [ + // MP4 files dont't loop seamlessly yet, the seeking logic seeks to 0, not the + // actual first packet, resulting in incorrect decoding. + // See bug 1817989 + // { name: "sin-441-1s-44100-fdk_aac.mp4", type: "audio/mp4" }, + // { name: "sin-441-1s-44100-afconvert.mp4", type: "audio/mp4" }, + // { name: "sin-441-1s-44100.ogg", type: "audio/vorbis" }, + // { name: "sin-441-1s-44100.opus", type: "audio/opus" }, + { name: "sin-441-1s-44100-lame.mp3", type: "audio/mpeg" }, + { name: "sin-441-1s-44100.flac", type: "audio/flac" }, +]; + +// These are files that are used for video decode suspend in +// background tabs tests. +var gDecodeSuspendTests = [ + { name: "gizmo.mp4", type: "video/mp4", duration: 5.56 }, + { name: "gizmo-noaudio.mp4", type: "video/mp4", duration: 5.56 }, + { name: "gizmo.webm", type: 'video/webm; codecs="vp9,opus"', duration: 5.56 }, + { + name: "gizmo-noaudio.webm", + type: 'video/webm; codecs="vp9"', + duration: 5.56, + }, +]; + +// These are video files with hardware-decodable formats and longer +// durations that are looped while we check telemetry for macOS video +// low power mode. +var gVideoLowPowerTests = [ + { name: "seek.ogv", type: "video/ogg", duration: 3.966 }, + { name: "gizmo.mp4", type: "video/mp4", duration: 5.56 }, +]; + +function checkMetadata(msg, e, test) { + if (test.width) { + is(e.videoWidth, test.width, msg + " video width"); + } + if (test.height) { + is(e.videoHeight, test.height, msg + " video height"); + } + if (test.duration) { + ok( + Math.abs(e.duration - test.duration) < 0.1, + msg + " duration (" + e.duration + ") should be around " + test.duration + ); + } + is( + !!test.keys, + SpecialPowers.do_lookupGetter(e, "isEncrypted").apply(e), + msg + " isEncrypted should be true if we have decryption keys" + ); +} + +// Returns the first test from candidates array which we can play with the +// installed video backends. +function getPlayableVideo(candidates) { + var resources = getPlayableVideos(candidates); + if (resources.length) { + return resources[0]; + } + return null; +} + +function getPlayableVideos(candidates) { + var v = manifestVideo(); + return candidates.filter(function (x) { + return /^video/.test(x.type) && v.canPlayType(x.type); + }); +} + +function getPlayableAudio(candidates) { + var v = manifestVideo(); + var resources = candidates.filter(function (x) { + return /^audio/.test(x.type) && v.canPlayType(x.type); + }); + if (resources.length) { + return resources[0]; + } + return null; +} + +// Returns the type of element that should be created for the given mimetype. +function getMajorMimeType(mimetype) { + if (/^video/.test(mimetype)) { + return "video"; + } + return "audio"; +} + +// Force releasing decoder to avoid timeout in waiting for decoding resource. +function removeNodeAndSource(n) { + n.remove(); + // reset |srcObject| first since it takes precedence over |src|. + n.srcObject = null; + n.removeAttribute("src"); + n.load(); + while (n.firstChild) { + n.firstChild.remove(); + } +} + +function once(target, name, cb) { + var p = new Promise(function (resolve, reject) { + target.addEventListener( + name, + function () { + resolve(); + }, + { once: true } + ); + }); + if (cb) { + p.then(cb); + } + return p; +} + +/** + * @param {HTMLMediaElement} video target of interest. + * @param {string} eventName the event to wait on. + * @returns {Promise} A promise that is resolved when event happens. + */ +function nextEvent(video, eventName) { + return new Promise(function (resolve, reject) { + let f = function (event) { + video.removeEventListener(eventName, f); + resolve(event); + }; + video.addEventListener(eventName, f); + }); +} + +function TimeStamp(token) { + function pad(x) { + return x < 10 ? "0" + x : x; + } + var now = new Date(); + var ms = now.getMilliseconds(); + var time = + "[" + + pad(now.getHours()) + + ":" + + pad(now.getMinutes()) + + ":" + + pad(now.getSeconds()) + + "." + + ms + + "]" + + // eslint-disable-next-line no-nested-ternary + (ms < 10 ? " " : ms < 100 ? " " : ""); + return token ? time + " " + token : time; +} + +function Log(token, msg) { + info(TimeStamp(token) + " " + msg); +} + +// Number of tests to run in parallel. +var PARALLEL_TESTS = 2; + +// Disable parallel test for media engine tests, see more info in bug 1840914. +if ( + SpecialPowers.Services.prefs.getIntPref("media.wmf.media-engine.enabled", 0) +) { + PARALLEL_TESTS = 1; +} + +// Prefs to set before running tests. Use this to improve coverage of +// conditions that might not otherwise be encountered on the test data. +var gTestPrefs = [ + ["media.recorder.max_memory", 1024], + ["media.audio-max-decode-error", 0], + ["media.video-max-decode-error", 0], +]; + +// When true, we'll loop forever on whatever test we run. Use this to debug +// intermittent test failures. +const DEBUG_TEST_LOOP_FOREVER = false; + +// Manages a run of media tests. Runs them in chunks in order to limit +// the number of media elements/threads running in parallel. This limits peak +// memory use, particularly on Linux x86 where thread stacks use 10MB of +// virtual address space. +// Usage: +// 1. Create a new MediaTestManager object. +// 2. Create a test startTest function. This takes a test object and a token, +// and performs anything necessary to start the test. The test object is an +// element in one of the g*Tests above. Your startTest function must call +// MediaTestManager.start(token) if it starts a test. The test object is +// guaranteed to be playable by our supported decoders; you don't need to +// check canPlayType. +// 3. When your tests finishes, call MediaTestManager.finished(), passing +// the token back to the manager. The manager may either start the next run +// or end the mochitest if all the tests are done. +function MediaTestManager() { + // Set a very large timeout to prevent Mochitest timeout. + // Instead MediaTestManager will manage timeout of each test. + SimpleTest.requestLongerTimeout(1000); + + // Return how many seconds elapsed since |begin|. + function elapsedTime(begin) { + var end = new Date(); + return (end.getTime() - begin.getTime()) / 1000; + } + // Sets up a MediaTestManager to runs through the 'tests' array, which needs + // to be one of, or have the same fields as, the g*Test arrays of tests. Uses + // the user supplied 'startTest' function to initialize the test. This + // function must accept two arguments, the test entry from the 'tests' array, + // and a token. Call MediaTestManager.started(token) if you start the test, + // and MediaTestManager.finished(token) when the test finishes. You don't have + // to start every test, but if you call started() you *must* call finish() + // else you'll timeout. + this.runTests = function (tests, startTest) { + this.startTime = new Date(); + SimpleTest.info( + "Started " + + this.startTime + + " (" + + this.startTime.getTime() / 1000 + + "s)" + ); + this.testNum = 0; + this.tests = tests; + this.startTest = startTest; + this.tokens = []; + this.isShutdown = false; + this.numTestsRunning = 0; + this.handlers = {}; + this.timers = {}; + + // Always wait for explicit finish. + SimpleTest.waitForExplicitFinish(); + SpecialPowers.pushPrefEnv({ set: gTestPrefs }, () => { + this.nextTest(); + }); + + SimpleTest.registerCleanupFunction(() => { + if (this.tokens.length) { + info("Test timed out. Remaining tests=" + this.tokens); + } + for (var token of this.tokens) { + var handler = this.handlers[token]; + if (handler && handler.ontimeout) { + handler.ontimeout(); + } + } + }); + }; + + // Registers that the test corresponding to 'token' has been started. + // Don't call more than once per token. + this.started = function (token, handler) { + this.tokens.push(token); + this.numTestsRunning++; + this.handlers[token] = handler; + + var onTimeout = async () => { + ok(false, "Test timed out!"); + info(`${token} timed out!`); + await dumpDebugInfoForToken(token); + this.finished(token); + }; + // Default timeout to 180s for each test. + // Call SimpleTest._originalSetTimeout() to bypass the flaky timeout checker. + this.timers[token] = SimpleTest._originalSetTimeout.call( + window, + onTimeout, + 180000 + ); + + is( + this.numTestsRunning, + this.tokens.length, + "[started " + + token + + " t=" + + elapsedTime(this.startTime) + + "] Length of array should match number of running tests" + ); + }; + + // Registers that the test corresponding to 'token' has finished. Call when + // you've finished your test. If all tests are complete this will finish the + // run, otherwise it may start up the next run. It's ok to call multiple times + // per token. + this.finished = function (token) { + var i = this.tokens.indexOf(token); + if (i != -1) { + // Remove the element from the list of running tests. + this.tokens.splice(i, 1); + } + + if (this.timers[token]) { + // Cancel the timer when the test finishes. + clearTimeout(this.timers[token]); + this.timers[token] = null; + } + + info("[finished " + token + "] remaining= " + this.tokens); + this.numTestsRunning--; + is( + this.numTestsRunning, + this.tokens.length, + "[finished " + + token + + " t=" + + elapsedTime(this.startTime) + + "] Length of array should match number of running tests" + ); + if (this.tokens.length < PARALLEL_TESTS) { + this.nextTest(); + } + }; + + // Starts the next batch of tests, or finishes if they're all done. + // Don't call this directly, call finished(token) when you're done. + this.nextTest = function () { + while ( + this.testNum < this.tests.length && + this.tokens.length < PARALLEL_TESTS + ) { + var test = this.tests[this.testNum]; + var token = (test.name ? test.name + "-" : "") + this.testNum; + this.testNum++; + + if (DEBUG_TEST_LOOP_FOREVER && this.testNum == this.tests.length) { + this.testNum = 0; + } + + // Ensure we can play the resource type. + if ( + test.type && + !document.createElement("video").canPlayType(test.type) + ) { + continue; + } + + // Do the init. This should start the test. + this.startTest(test, token); + } + + if ( + this.testNum == this.tests.length && + !DEBUG_TEST_LOOP_FOREVER && + !this.tokens.length && + !this.isShutdown + ) { + this.isShutdown = true; + if (this.onFinished) { + this.onFinished(); + } + var onCleanup = () => { + var end = new Date(); + SimpleTest.info( + "Finished at " + end + " (" + end.getTime() / 1000 + "s)" + ); + SimpleTest.info("Running time: " + elapsedTime(this.startTime) + "s"); + SimpleTest.finish(); + }; + mediaTestCleanup(onCleanup); + } + }; +} + +// Ensures we've got no active video or audio elements in the document, and +// forces a GC to release the address space reserved by the decoders' threads' +// stacks. +function mediaTestCleanup(callback) { + var V = document.getElementsByTagName("video"); + for (let i = 0; i < V.length; i++) { + removeNodeAndSource(V[i]); + V[i] = null; + } + var A = document.getElementsByTagName("audio"); + for (let i = 0; i < A.length; i++) { + removeNodeAndSource(A[i]); + A[i] = null; + } + SpecialPowers.exactGC(callback); +} + +async function dumpDebugInfoForToken(token) { + for (let v of document.getElementsByTagName("video")) { + if (token === v.token) { + info(JSON.stringify(await SpecialPowers.wrap(v).mozRequestDebugInfo())); + return; + } + } + for (let a of document.getElementsByTagName("audio")) { + if (token === a.token) { + info(JSON.stringify(await SpecialPowers.wrap(a).mozRequestDebugInfo())); + return; + } + } +} + +// Could be undefined in a page opened by the parent test page +// like file_access_controls.html. +if ("SimpleTest" in window) { + SimpleTest.requestFlakyTimeout("untriaged"); + + // Register timeout function to dump debugging logs. + SimpleTest.registerTimeoutFunction(async function () { + for (const v of document.getElementsByTagName("video")) { + SimpleTest.info( + JSON.stringify(await SpecialPowers.wrap(v).mozRequestDebugInfo()) + ); + } + for (const a of document.getElementsByTagName("audio")) { + SimpleTest.info( + JSON.stringify(await SpecialPowers.wrap(a).mozRequestDebugInfo()) + ); + } + }); +} diff --git a/dom/media/test/midflight-redirect.sjs b/dom/media/test/midflight-redirect.sjs new file mode 100644 index 0000000000..9a2101251c --- /dev/null +++ b/dom/media/test/midflight-redirect.sjs @@ -0,0 +1,87 @@ +function parseQuery(query, key) { + for (let p of query.split("&")) { + if (p == key) { + return true; + } + if (p.startsWith(key + "=")) { + return p.substring(key.length + 1); + } + } + return false; +} + +// Return the first few bytes in a short byte range response. When Firefox +// requests subsequent bytes in a second range request, respond with a +// redirect. Requests after the first redirected are serviced as expected. +function handleRequest(request, response) { + var query = request.queryString; + var resource = parseQuery(query, "resource"); + var type = parseQuery(query, "type") || "application/octet-stream"; + var redirected = parseQuery(query, "redirected") || false; + var useCors = parseQuery(query, "cors") || false; + + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + var paths = "tests/dom/media/test/" + resource; + var split = paths.split("/"); + for (var i = 0; i < split.length; ++i) { + file.append(split[i]); + } + fis.init(file, -1, -1, false); + + bis.setInputStream(fis); + var bytes = bis.readBytes(bis.available()); + let [from, to] = request + .getHeader("range") + .split("=")[1] + .split("-") + .map(s => parseInt(s)); + + if (!redirected && from > 0) { + var origin = + request.host == "mochi.test" ? "example.org" : "mochi.test:8888"; + response.setStatusLine(request.httpVersion, 303, "See Other"); + let url = + "http://" + + origin + + "/tests/dom/media/test/midflight-redirect.sjs?redirected&" + + query; + response.setHeader("Location", url); + response.setHeader("Content-Type", "text/html"); + return; + } + + if (isNaN(to)) { + to = bytes.length - 1; + } + + if (from == 0 && !redirected) { + to = + parseInt(parseQuery(query, "redirectAt")) || Math.floor(bytes.length / 4); + } + to = Math.min(to, bytes.length - 1); + + // Note: 'to' is the first index *excluded*, so we need (to + 1) + // in the substring end here. + let byterange = bytes.substring(from, to + 1); + + let contentRange = "bytes " + from + "-" + to + "/" + bytes.length; + let contentLength = byterange.length.toString(); + + response.setStatusLine(request.httpVersion, 206, "Partial Content"); + response.setHeader("Content-Range", contentRange); + response.setHeader("Content-Length", contentLength, false); + response.setHeader("Content-Type", type, false); + response.setHeader("Accept-Ranges", "bytes", false); + response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + if (redirected && useCors) { + response.setHeader("Access-Control-Allow-Origin", "*"); + } + response.write(byterange, byterange.length); + bis.close(); +} diff --git a/dom/media/test/mochitest.toml b/dom/media/test/mochitest.toml new file mode 100644 index 0000000000..de8c690255 --- /dev/null +++ b/dom/media/test/mochitest.toml @@ -0,0 +1,951 @@ +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +tags = "media-gpu" +prefs = [ + "gfx.core-animation.low-power-telemetry-frames=60", # only for test_video_low_power_telemetry.html + "media.setsinkid.enabled=true", # for test_setSinkId_after_loop.html +] +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bug1535980.webm", + "bug1535980.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "id3v1afterlongid3v2.mp3", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-cenc.mp4", + "short-video.ogv", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "shorter_audio_than_video_3s.webm", + "shorter_audio_than_video_3s.webm^headers^", + # source file generated with: + # > sox -V -r 44100 -n -b 16 -c 1 sin-441-1s-44100.wav synth 1 sin 441 vol -5dB + # then encoded: + # ffmpeg -i sin-441-1s-44100.wav sin-441-1s-44100-libfdk_aac.mp4 + "sin-441-1s-44100-fdk_aac.mp4", + # afconvert -s 3 -f mp4f -d aac sin-4411-1s-441100.wav + "sin-441-1s-44100-afconvert.mp4", + # ffmpeg -i sin-441-1s-44100.wav sin-441-1s-44100-libfdk_lame.mp3 + "sin-441-1s-44100-lame.mp3", + # ffmpeg -i sin-441-1s-44100.wav sin-441-1s-44100.ogg + "sin-441-1s-44100.ogg", + # ffmpeg -i sin-441-1s-44100.wav sin-441-1s-44100.opus + "sin-441-1s-44100.opus", + # ffmpeg -i sin-441-1s-44100.wav sin-441-1s-44100.flac + "sin-441-1s-44100.flac", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "white-short.webm", + "white-3s-black-1s.webm", + "white-3s-black-1s.webm^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", + "two-xing-header-no-content-length.mp3", + "two-xing-header-no-content-length.mp3^headers^", + "single-xing-header-no-content-length.mp3", + "single-xing-header-no-content-length.mp3^headers^", + "padding-spanning-multiple-packets.mp3", +] + +["test_capture_stream_av_sync.html"] +skip-if = [ + "os == 'android'", # 1712598 (canvas error) + "os == 'mac'", # 1517199 (timeout-on-osx) + "os == 'linux'", # 1713397, 1719881 (high intermittent failure on linux tsan), 1776937 + "apple_silicon", # Disabled due to bleedover with other tests when run in regular suites; passes in "failures" jobs +] + +["test_chaining.html"] + +["test_cloneElementVisually_ended_video.html"] +tags = "cloneelementvisually" + +["test_cloneElementVisually_mediastream.html"] +tags = "cloneelementvisually" + +["test_cloneElementVisually_mediastream_multitrack.html"] +tags = "cloneelementvisually" + +["test_cloneElementVisually_no_suspend.html"] +tags = "cloneelementvisually" + +["test_cloneElementVisually_paused.html"] +tags = "cloneelementvisually" + +["test_cloneElementVisually_poster.html"] +tags = "cloneelementvisually" + +["test_cloneElementVisually_resource_change.html"] +skip-if = ["os == 'linux' && !(debug || asan || tsan)"] # Bug 1559308 - lower frequency intermittent +tags = "cloneelementvisually" + +["test_clone_media_element.html"] +skip-if = ["os == 'android'"] # bug 1108558, android(bug 1232305) + +["test_fastSeek-forwards.html"] + +["test_fastSeek.html"] + +["test_hls_player_independency.html"] +# There's a limit for creating decoder when API lever < 18(Bug 1278574) +# We could skip the test in that case as we cannot play 2 video at a time. +skip-if = ["os != 'android'"] +tags = "hls" + +["test_hw_video_decoding.html"] +skip-if = ["!mda_gpu"] +scheme = "https" + +["test_imagecapture.html"] +scheme = "https" + +["test_invalid_reject_play.html"] + +["test_media_selection.html"] + +["test_media_sniffer.html"] + +["test_mediastream_as_eventarget.html"] + +["test_mediatrack_consuming_mediastream.html"] +scheme = "https" +tags = "mtg" + +["test_mediatrack_replay_from_end.html"] + +["test_midflight_redirect_blocked.html"] + +["test_mixed_principals.html"] +skip-if = [ + "os == 'android'", # bug 1309814, android(bug 1232305) + "apple_silicon", # bug 1707737 +] + +["test_mp3_broadcast.html"] + +["test_multiple_mediastreamtracks.html"] +scheme = "https" + +["test_play_events_2.html"] + +["test_playback.html"] +skip-if = ["os == 'android'"] # bug 1316177 + +["test_playback_and_bfcache.html"] +support-files = ["file_playback_and_bfcache.html"] + +["test_playback_hls.html"] +# HLS is only supported on Fennec with API level >= 16 +# TODO: This test is similar to test_playback.html, will remove the +# redundant code once test_playback.html is enabled on Fennec. +skip-if = ["os != 'android'"] +tags = "hls" + +["test_playback_rate.html"] + +["test_played.html"] +skip-if = [ + "os == 'android' && is_emulator", # Times out on android-em, Bug 1613946 + "os == 'mac'", # Bug 1110922 + "os == 'win'", # Bug 1110922 + "os == 'android' && processor == 'aarch64'", # Bug 1110922 +] + +["test_replay_metadata.html"] + +["test_reset_events_async.html"] + +["test_resolution_change.html"] +tags = "capturestream" + +["test_resume.html"] +skip-if = ["true"] # bug 1021673 + +["test_seamless_looping.html"] +skip-if = [ + "apple_catalina && debug", # Bug 1796318 +] + +["test_seamless_looping_cancel_looping_future_frames.html"] + +["test_seamless_looping_duration.html"] + +["test_seamless_looping_media_element_state.html"] + +["test_seamless_looping_not_keep_painting_old_video_frames.html"] +skip-if = ["os == 'android'"] # Android has black frames issue. + +["test_seamless_looping_resume_video_decoding.html"] + +["test_seamless_looping_seek_current_time.html"] + +["test_seamless_looping_shorter_audio_than_video.html"] +skip-if = ["os == 'android' && verify"] # Crash + +["test_seamless_looping_video.html"] +skip-if = ["os == 'android'"] # Android has black frames issue. + +["test_setSinkId_after_loop.html"] +scheme = "https" + +["test_temporary_file_blob_video_plays.html"] +skip-if = ["os == 'android'"] # bug 1533534 # android(bug 1232305) + +["test_videoPlaybackQuality_totalFrames.html"] +skip-if = ["os == 'win'"] # bug 1374189 + +["test_video_dimensions.html"] + +["test_video_low_power_telemetry.html"] +run-if = ["os == 'mac'"] # This telemetry is macOS-specific. +disabled = "https://bugzilla.mozilla.org/show_bug.cgi?id=1849680" + +["test_video_to_canvas.html"] +skip-if = ["os == 'android'"] # android(bug 1232305), bugs 1320418,1347953,1347954,1348140,1348386 + +["test_vp9_superframes.html"] diff --git a/dom/media/test/mochitest_background_video.toml b/dom/media/test/mochitest_background_video.toml new file mode 100644 index 0000000000..762a9a8648 --- /dev/null +++ b/dom/media/test/mochitest_background_video.toml @@ -0,0 +1,800 @@ +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +tags = "suspend media-gpu" +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-cenc.mp4", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-video.ogv", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", +] + +["test_background_video_cancel_suspend_taint.html"] +skip-if = [ + "os == 'android'", # bug 1346705 + "os == 'mac' && debug", # Bug 1670131 - after splitting manifest perma fail +] + +["test_background_video_cancel_suspend_visible.html"] + +["test_background_video_drawimage_with_suspended_video.html"] +skip-if = ["os == 'android'"] # bug 1346705 + +["test_background_video_ended_event.html"] +skip-if = ["os == 'android'"] # bug 1346705 + +["test_background_video_no_suspend_disabled.html"] + +["test_background_video_no_suspend_not_in_tree.html"] + +["test_background_video_no_suspend_short_vid.html"] + +["test_background_video_resume_after_end_show_last_frame.html"] +skip-if = ["os == 'android'"] # bug 1346705 + +["test_background_video_resume_looping_video_without_audio.html"] + +["test_background_video_suspend.html"] +skip-if = ["os == 'android'"] #Bug 1304480 + +["test_background_video_suspend_ends.html"] + +["test_background_video_suspend_ready_state.html"] + +["test_background_video_tainted_by_capturestream.html"] + +["test_background_video_tainted_by_createimagebitmap.html"] + +["test_background_video_tainted_by_drawimage.html"] +skip-if = ["os == 'android'"] # bug 1346705 diff --git a/dom/media/test/mochitest_bugs.toml b/dom/media/test/mochitest_bugs.toml new file mode 100644 index 0000000000..9d4a0dea2f --- /dev/null +++ b/dom/media/test/mochitest_bugs.toml @@ -0,0 +1,812 @@ +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +tags = "media-gpu" +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bug1799787.webm", + "bug1799787.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-cenc.mp4", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-video.ogv", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", +] + +["test_bug448534.html"] + +["test_bug463162.xhtml"] + +["test_bug465498.html"] + +["test_bug495145.html"] +skip-if = ["os == 'win'"] #Bug 1404373 + +["test_bug495300.html"] + +["test_bug654550.html"] + +["test_bug686942.html"] + +["test_bug726904.html"] + +["test_bug874897.html"] + +["test_bug879717.html"] +skip-if = ["os == 'android'"] # bug 1285441, android(bug 1232305) +tags = "capturestream" + +["test_bug895305.html"] +skip-if = ["android_version == '25' && debug"] # android(bug 1232305) + +["test_bug919265.html"] +skip-if = ["android_version == '25' && debug"] # android(bug 1232305) + +["test_bug1113600.html"] +skip-if = [ + "os == 'win' && os_version == '10.0' && debug", # Bug 1713410 + "os == 'mac'", # Bug 1198168 +] + +["test_bug1120222.html"] +tags = "capturestream" + +["test_bug1242338.html"] + +["test_bug1248229.html"] +tags = "capturestream" + +["test_bug1512958.html"] +tags = "mtg capturestream" + +["test_bug1553262.html"] +tags = "mtg capturestream" diff --git a/dom/media/test/mochitest_compat.toml b/dom/media/test/mochitest_compat.toml new file mode 100644 index 0000000000..c477661a19 --- /dev/null +++ b/dom/media/test/mochitest_compat.toml @@ -0,0 +1,1033 @@ +# This file lists tests which are compatible for testing Windows Media +# Foundation media engine playback. These tests would still be testing on +# different platforms, but we will use these tests to do additional testing on +# Windows to test the media engine playback. + +# -------------------------------------------------------------------------- + +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +tags = "media-engine-compatible media-gpu" +prefs = ["media.wmf.hevc.enabled=1"] # for test_hevc_playback +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "adts.aac", + "adts.aac^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "hevc_white_frame.mp4", + "hevc_white_frame.mp4^headers^", + # This HEVC file is created by following steps. + # 1. generate two videos + # - a white frame video (0-2 seconds) at 1024x768 resolution + # ffmpeg -t 2 -f lavfi -i color=size=1024x768:rate=30:color=white -c:v libx265 -pix_fmt yuv420p -strict experimental -metadata:s:v:0 rotate=0 -metadata:s:v:0 width=1024 -metadata:s:v:0 height=768 -y white_frames.mp4 + # - a red frame video (2-4 seconds) at 3480x2160 resolution with inband SPS + # ffmpeg -t 2 -f lavfi -i color=size=3480x2160:rate=30:color=red -c:v libx265 -x265-params "sps-id=1" -strict experimental -metadata:s:v:0 rotate=0 -metadata:s:v:0 width=3480 -metadata:s:v:0 height=2160 -y red_frames.mp4 + # 2. covert them to annexB + # ffmpeg -i XXX.mp4 -codec copy -bsf:v h264_mp4toannexb XXX.ts + # 3. combine them together + # ffmpeg -i "concat:white_annexb.ts|red_annexb.ts" -c copy -strict -2 -y hevc_white_red_frames.mp4 + "hevc_white_red_frames.mp4", + "hevc_white_red_frames.mp4^headers^", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-cenc.mp4", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-video.ogv", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webaudio/test/half-a-second-1ch-44100-aac-afconvert.mp4", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", +] + +["test_VideoPlaybackQuality.html"] + +["test_VideoPlaybackQuality_disabled.html"] + +["test_access_control.html"] + +["test_arraybuffer.html"] + +["test_aspectratio_mp4.html"] + +["test_audio1.html"] + +["test_audio2.html"] + +["test_audioDocumentTitle.html"] +skip-if = ["true"] # bug 475110 - disabled since we don't play Wave files standalone + +["test_buffered.html"] + +["test_bug1431810_opus_downmix_to_mono.html"] + +["test_can_play_type.html"] +skip-if = ["(android_version == '25' && debug)"] # android(bug 1232305) + +["test_can_play_type_mpeg.html"] + +["test_can_play_type_no_ogg.html"] +skip-if = ["(android_version == '25' && debug)"] # android(bug 1232305) + +["test_can_play_type_ogg.html"] +skip-if = ["(android_version == '25' && debug)"] # android(bug 1232305) + +["test_can_play_type_wave.html"] + +["test_can_play_type_webm.html"] + +["test_closing_connections.html"] + +["test_constants.html"] + +["test_controls.html"] + +["test_cueless_webm_seek-1.html"] + +["test_cueless_webm_seek-2.html"] + +["test_cueless_webm_seek-3.html"] + +["test_currentTime.html"] + +["test_debug_data_helpers.html"] + +["test_decode_error.html"] + +["test_decode_error_crossorigin.html"] + +["test_decoder_disable.html"] + +["test_defaultMuted.html"] + +["test_delay_load.html"] + +["test_duration_after_error.html"] + +["test_empty_resource.html"] + +["test_error_in_video_document.html"] + +["test_error_on_404.html"] + +["test_fragment_noplay.html"] + +["test_fragment_play.html"] + +["test_hevc_playback.html"] +run-if = ["os == 'win'"] +skip-if = ["!mda_gpu"] +scheme = "https" + +["test_hevc_support.html"] +skip-if = ["!mda_gpu"] +scheme = "https" + +["test_info_leak.html"] + +["test_invalid_reject.html"] + +["test_invalid_seek.html"] + +["test_load.html"] + +["test_load_candidates.html"] + +["test_load_same_resource.html"] + +["test_load_source.html"] + +["test_load_source_empty_type.html"] + +["test_loop.html"] +skip-if = ["wmfme"] # Bug 1781539 + +["test_looping_eventsOrder.html"] + +["test_mediatrack_consuming_mediaresource.html"] + +["test_mediatrack_events.html"] +scheme = "https" + +["test_mediatrack_parsing_ogg.html"] + +["test_metadata.html"] + +["test_mozHasAudio.html"] + +["test_mp3_with_multiple_ID3v2.html"] + +["test_networkState.html"] + +["test_new_audio.html"] + +["test_no_load_event.html"] + +["test_not_reset_playbackRate_when_removing_nonloaded_media_from_document.html"] + +["test_paused.html"] + +["test_paused_after_ended.html"] + +["test_periodic_timeupdate.html"] + +["test_play_events.html"] + +["test_play_promise_1.html"] +tags = "promise-play" + +["test_play_promise_10.html"] +tags = "promise-play" + +["test_play_promise_11.html"] +tags = "promise-play" + +["test_play_promise_12.html"] +tags = "promise-play" + +["test_play_promise_13.html"] +tags = "promise-play" + +["test_play_promise_14.html"] +tags = "promise-play" + +["test_play_promise_15.html"] +tags = "promise-play" + +["test_play_promise_16.html"] +tags = "promise-play" + +["test_play_promise_17.html"] +tags = "promise-play" + +["test_play_promise_18.html"] +tags = "promise-play" + +["test_play_promise_2.html"] +tags = "promise-play" + +["test_play_promise_3.html"] +tags = "promise-play" + +["test_play_promise_4.html"] +tags = "promise-play" + +["test_play_promise_5.html"] +tags = "promise-play" + +["test_play_promise_6.html"] +tags = "promise-play" + +["test_play_promise_7.html"] +tags = "promise-play" + +["test_play_promise_8.html"] +tags = "promise-play" + +["test_play_promise_9.html"] +tags = "promise-play" + +["test_play_twice.html"] +skip-if = ["appname == 'seamonkey'"] # Seamonkey: Bug 598252, bug 1307337, bug 1143695 +# If encountering intermittents in test_playback.html please consider disabling +# the individual faulting file via `manifest.js` as disabling the whole test on +# a platform removes a lot of coverage. + +["test_playback_errors.html"] + +["test_playback_rate_playpause.html"] + +["test_playback_reactivate.html"] + +["test_preload_actions.html"] + +["test_preload_attribute.html"] + +["test_preload_suspend.html"] + +["test_preserve_playbackrate_after_ui_play.html"] + +["test_progress.html"] + +["test_reactivate.html"] +skip-if = ["true"] # see bug 1319725 + +["test_readyState.html"] + +["test_referer.html"] +skip-if = ["android_version == '25' && debug"] # android(bug 1232305) + +["test_reset_src.html"] +skip-if = ["verify && debug && os == 'win'"] + +["test_source.html"] + +["test_source_null.html"] + +["test_source_write.html"] + +["test_standalone.html"] + +["test_suspend_media_by_inactive_docshell.html"] + +["test_timeupdate_small_files.html"] + +["test_unseekable.html"] + +["test_videoDocumentTitle.html"] + +["test_video_gzip_encoding.html"] + +["test_video_in_audio_element.html"] + +["test_video_stats_resistfingerprinting.html"] +tags = "resistfingerprinting" + +["test_volume.html"] +# The tests below contain backend-specific tests. Write backend independent +# tests rather than adding to this list. diff --git a/dom/media/test/mochitest_eme.toml b/dom/media/test/mochitest_eme.toml new file mode 100644 index 0000000000..696e0e947e --- /dev/null +++ b/dom/media/test/mochitest_eme.toml @@ -0,0 +1,850 @@ +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +skip-if = ["os == 'linux' && (asan || debug)"] # Bug 1476870: common fatal error (shutdown hang) on asan/debug +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-cenc.mp4", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-video.ogv", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", +] + +["test_eme_autoplay.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_canvas_blocked.html"] +skip-if = [ + "os == 'android'", # bug 1149374 + "apple_silicon", # bug 1707737 +] +scheme = "https" + +["test_eme_detach_reattach_same_mediakeys_during_playback.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_initDataTypes.html"] +skip-if = ["os == 'android'"] +scheme = "https" + +["test_eme_missing_pssh.html"] +skip-if = ["os == 'android'"] +scheme = "https" + +["test_eme_non_mse_fails.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_playback.html"] +skip-if = [ + "os == 'android'", # bug 1149374 + "apple_silicon", # bug 1707737 +] + +["test_eme_protection_query.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_pssh_in_moof.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_sample_groups_playback.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_special_key_system.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_stream_capture_blocked_case1.html"] +tags = "mtg capturestream" +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_stream_capture_blocked_case2.html"] +tags = "mtg capturestream" +skip-if = [ + "os == 'android'", # bug 1149374 + "apple_silicon", # bug 1707737 +] +scheme = "https" + +["test_eme_stream_capture_blocked_case3.html"] +tags = "mtg capturestream" +skip-if = [ + "os == 'android'", # bug 1149374 + "apple_silicon", # bug 1707737 +] +scheme = "https" + +["test_eme_unsetMediaKeys_then_capture.html"] +skip-if = [ + "xorigin", + "os == 'android'", # bug 1149374 + "apple_silicon", # bug 1707737 +] +scheme = "https" + +["test_eme_waitingforkey.html"] +skip-if = [ + "xorigin", + "os == 'android'", # bug 1149374 + "apple_silicon", # bug 1707737 +] +scheme = "https" + +["test_eme_wv_privacy.html"] +scheme = "https" diff --git a/dom/media/test/mochitest_eme_compat.toml b/dom/media/test/mochitest_eme_compat.toml new file mode 100644 index 0000000000..43a5b510fc --- /dev/null +++ b/dom/media/test/mochitest_eme_compat.toml @@ -0,0 +1,793 @@ +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +tags = "media-engine-compatible" +skip-if = ["os == 'linux' && (asan || debug)"] # Bug 1476870: common fatal error (shutdown hang) on asan/debug +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-cenc.mp4", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-video.ogv", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", +] + +["test_eme_createMediaKeys_iframes.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_detach_media_keys.html"] +skip-if = ["os == 'android'"] +scheme = "https" + +["test_eme_getstatusforpolicy.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_requestKeySystemAccess.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_requestMediaKeySystemAccess_with_app_approval.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" + +["test_eme_request_notifications.html"] +skip-if = ["os == 'android'"] +scheme = "https" + +["test_eme_session_callable_value.html"] +scheme = "https" + +["test_eme_setMediaKeys_before_attach_MediaSource.html"] +skip-if = ["os == 'android'"] # bug 1149374 +scheme = "https" diff --git a/dom/media/test/mochitest_media_engine.toml b/dom/media/test/mochitest_media_engine.toml new file mode 100644 index 0000000000..c9ad881aec --- /dev/null +++ b/dom/media/test/mochitest_media_engine.toml @@ -0,0 +1,10 @@ +[DEFAULT] +subsuite = "media" +tags = "media-engine-compatible" +skip-if = ["!wmfme"] + +["test_eme_mfcdm_generate_request.html"] + +["test_eme_wideinve_l1_installation.html"] + +["test_eme_mfcdm_getstatusforpolicy.html"] diff --git a/dom/media/test/mochitest_media_recorder.toml b/dom/media/test/mochitest_media_recorder.toml new file mode 100644 index 0000000000..428f99601d --- /dev/null +++ b/dom/media/test/mochitest_media_recorder.toml @@ -0,0 +1,856 @@ +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +tags = "mtg" +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-cenc.mp4", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-video.ogv", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", +] +prefs = ["media.recorder.video.frame_drops=false"] + +["test_mediacapabilities_resistfingerprinting.html"] + +["test_mediarecorder_avoid_recursion.html"] +skip-if = ["os == 'win' && !debug"] +scheme = "https" + +["test_mediarecorder_bitrate.html"] +skip-if = ["os == 'android'"] # bug 1297432, android(bug 1232305) + +["test_mediarecorder_creation.html"] +tags = "mtg capturestream" + +["test_mediarecorder_creation_fail.html"] + +["test_mediarecorder_fires_start_event_once_when_erroring.html"] + +["test_mediarecorder_multipletracks.html"] + +["test_mediarecorder_onerror_pause.html"] +scheme = "https" + +["test_mediarecorder_pause_resume_video.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_mediarecorder_playback_can_repeat.html"] + +["test_mediarecorder_principals.html"] +skip-if = [ + "os == 'win' && os_version == '10.0'", # Bug 1453375 + "os == 'android'", # Bug 1694645 +] + +["test_mediarecorder_record_4ch_audiocontext.html"] +skip-if = ["os == 'linux' && bits == 64"] #Bug 1598101 + +["test_mediarecorder_record_addtracked_stream.html"] +skip-if = ["os == 'android'"] # Bug 1408241 +tags = "mtg capturestream" + +["test_mediarecorder_record_audiocontext.html"] + +["test_mediarecorder_record_audiocontext_mlk.html"] + +["test_mediarecorder_record_audionode.html"] + +["test_mediarecorder_record_canvas_captureStream.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_mediarecorder_record_changing_video_resolution.html"] +skip-if = [ + "os == 'android'", # android(bug 1232305) + "os == 'linux' && (tsan || asan || debug)", # 1770504 (high intermittent failure on Linux tsan) +] + +["test_mediarecorder_record_downsize_resolution.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_mediarecorder_record_getdata_afterstart.html"] +tags = "mtg capturestream" + +["test_mediarecorder_record_gum_video_timeslice.html"] +scheme = "https" + +["test_mediarecorder_record_gum_video_timeslice_mixed.html"] +scheme = "https" + +["test_mediarecorder_record_immediate_stop.html"] +tags = "mtg capturestream" + +["test_mediarecorder_record_no_timeslice.html"] +tags = "mtg capturestream" + +["test_mediarecorder_record_session.html"] +tags = "mtg capturestream" + +["test_mediarecorder_record_startstopstart.html"] + +["test_mediarecorder_record_timeslice.html"] +tags = "mtg capturestream" + +["test_mediarecorder_record_upsize_resolution.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_mediarecorder_reload_crash.html"] +tags = "mtg capturestream" + +["test_mediarecorder_state_event_order.html"] +tags = "mtg capturestream" + +["test_mediarecorder_state_transition.html"] +tags = "mtg capturestream" + +["test_mediarecorder_webm_support.html"] diff --git a/dom/media/test/mochitest_seek.toml b/dom/media/test/mochitest_seek.toml new file mode 100644 index 0000000000..0c90bd1bfb --- /dev/null +++ b/dom/media/test/mochitest_seek.toml @@ -0,0 +1,824 @@ +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +tags = "media-gpu" +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-cenc.mp4", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-video.ogv", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", +] + +["test_seek-1.html"] +skip-if = ["os == 'android'"] # bug 1322806, android(bug 1232305) + +["test_seek-10.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_seek-11.html"] +skip-if = ["os == 'android'"] # bug 1323133, android(bug 1232305) + +["test_seek-12.html"] +skip-if = ["os == 'android'"] # bug 1321081, android(bug 1232305) + +["test_seek-13.html"] +skip-if = ["os == 'android'"] # bug 1299174, android(bug 1232305) + +["test_seek-14.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_seek-2.html"] +skip-if = ["os == 'android'"] # bug 1309778, android(bug 1232305) + +["test_seek-3.html"] +skip-if = ["os == 'android'"] # bug 1321082, android(bug 1232305) + +["test_seek-4.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_seek-5.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_seek-6.html"] +skip-if = ["os == 'android'"] # bug 1336629, bug 1324482, android(bug 1232305) + +["test_seek-7.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) + +["test_seek-8.html"] +skip-if = ["os == 'android'"] # bug 1310584, android(bug 1232305) + +["test_seek-9.html"] +skip-if = ["os == 'android'"] # bug 1332019, android(bug 1232305) + +["test_seekLies.html"] + +["test_seekToNextFrame.html"] +skip-if = ["os == 'android'"] # bug 1329391, android(bug 1232305) +tags = "seektonextframe" + +["test_seek_duration.html"] + +["test_seek_negative.html"] + +["test_seek_nosrc.html"] + +["test_seek_out_of_range.html"] +skip-if = ["os == 'android'"] # bug 1299382, android(bug 1232305) + +["test_seek_promise_bug1344357.html"] +skip-if = ["os == 'android'"] # bug 1299382, android(bug 1232305) + +["test_seekable1.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) diff --git a/dom/media/test/mochitest_stream.toml b/dom/media/test/mochitest_stream.toml new file mode 100644 index 0000000000..043f8471d4 --- /dev/null +++ b/dom/media/test/mochitest_stream.toml @@ -0,0 +1,792 @@ +# Media tests should be backend independent, i.e., not conditioned on ogg, +# wave etc. (The only exception is the can_play_type tests, which +# necessarily depend on the backend(s) configured.) As far as possible, each +# test should work with any resource type. This makes it easy to add new +# backends and reduces the amount of test duplication. + +# For each supported backend, resources that can be played by that backend +# should be added to the lists in manifest.js. Media tests that aren't +# testing for a bug in handling a specific resource type should pick one of +# the lists in manifest.js and run the test for each resource in the list +# that is supported in the current build (the canPlayType API is useful for +# this). + +# To test whether a valid resource can simply be played through correctly, +# and optionally that its metadata is read correctly, just add it to +# gPlayTests in manifest.js. To test whether an invalid resource correctly +# throws an error (and does not cause a crash or hang), just add it to +# gErrorTests in manifest.js. + +# To test for a specific bug in handling a specific resource type, make the +# test first check canPlayType for the type, and if it's not supported, just +# do ok(true, "Type not supported") and stop the test. + +[DEFAULT] +subsuite = "media" +tags = "mtg capturestream" +support-files = [ + "16bit_wave_extrametadata.wav", + "16bit_wave_extrametadata.wav^headers^", + "320x240.ogv", + "320x240.ogv^headers^", + "448636.ogv", + "448636.ogv^headers^", + "A4.ogv", + "A4.ogv^headers^", + "VID_0001.ogg", + "VID_0001.ogg^headers^", + "allowed.sjs", + "ambisonics.mp4", + "ambisonics.mp4^headers^", + "audio-gaps.ogg", + "audio-gaps.ogg^headers^", + "audio-gaps-short.ogg", + "audio-gaps-short.ogg^headers^", + "audio-overhang.ogg", + "audio-overhang.ogg^headers^", + "audio.wav", + "audio.wav^headers^", + "av1.mp4", + "av1.mp4^headers^", + "background_video.js", + "badtags.ogg", + "badtags.ogg^headers^", + "bear-640x360-v_frag-cenc-key_rotation.mp4", + "bear-640x360-a_frag-cenc-key_rotation.mp4", + "beta-phrasebook.ogg", + "beta-phrasebook.ogg^headers^", + "big.wav", + "big.wav^headers^", + "big-buck-bunny-cenc-avc3-1.m4s", + "big-buck-bunny-cenc-avc3-1.m4s^headers^", + "big-buck-bunny-cenc-avc3-init.mp4", + "big-buck-bunny-cenc-avc3-init.mp4^headers^", + "big-short.wav", + "big-short.wav^headers^", + "bipbop.mp4", + "bipbop-cenc-audio1.m4s", + "bipbop-cenc-audio1.m4s^headers^", + "bipbop-cenc-audio2.m4s", + "bipbop-cenc-audio2.m4s^headers^", + "bipbop-cenc-audio3.m4s", + "bipbop-cenc-audio3.m4s^headers^", + "bipbop-cenc-audioinit.mp4", + "bipbop-cenc-audioinit.mp4^headers^", + "bipbop-cenc-video1.m4s", + "bipbop-cenc-video1.m4s^headers^", + "bipbop-cenc-video2.m4s", + "bipbop-cenc-video2.m4s^headers^", + "bipbop-cenc-videoinit.mp4", + "bipbop-cenc-videoinit.mp4^headers^", + "bipbop-cenc-video-10s.mp4", + "bipbop-cenc-video-10s.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4", + "bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4", + "bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^", + "bipbop_225w_175kbps.mp4", + "bipbop_225w_175kbps.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s", + "bipbop_225w_175kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4", + "bipbop_225w_175kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s", + "bipbop_225w_175kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4", + "bipbop_225w_175kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s", + "bipbop_225w_175kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4", + "bipbop_225w_175kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s", + "bipbop_300_215kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s", + "bipbop_300_215kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s", + "bipbop_300_215kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s", + "bipbop_300_215kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4", + "bipbop_300_215kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s", + "bipbop_300_215kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s", + "bipbop_300_215kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s", + "bipbop_300_215kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s", + "bipbop_300_215kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4", + "bipbop_300_215kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key1-1.m4s", + "bipbop_300_215kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-2.m4s", + "bipbop_300_215kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key1-init.mp4", + "bipbop_300_215kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300_215kbps-cenc-video-key2-1.m4s", + "bipbop_300_215kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-2.m4s", + "bipbop_300_215kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300_215kbps-cenc-video-key2-init.mp4", + "bipbop_300_215kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s", + "bipbop_300wp_227kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s", + "bipbop_300wp_227kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4", + "bipbop_300wp_227kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s", + "bipbop_360w_253kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4", + "bipbop_360w_253kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s", + "bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4", + "bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s", + "bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4", + "bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_360w_253kbps-clearkey-audio.webm", + "bipbop_360w_253kbps-clearkey-audio.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp8.webm", + "bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^", + "bipbop_360w_253kbps-clearkey-video-vp9.webm", + "bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s", + "bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s", + "bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s", + "bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s", + "bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4", + "bipbop_480_624kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s", + "bipbop_480_624kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s", + "bipbop_480_624kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s", + "bipbop_480_624kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s", + "bipbop_480_624kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4", + "bipbop_480_624kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key1-1.m4s", + "bipbop_480_624kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-2.m4s", + "bipbop_480_624kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key1-init.mp4", + "bipbop_480_624kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_624kbps-cenc-video-key2-1.m4s", + "bipbop_480_624kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-2.m4s", + "bipbop_480_624kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_624kbps-cenc-video-key2-init.mp4", + "bipbop_480_624kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s", + "bipbop_480_959kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s", + "bipbop_480_959kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s", + "bipbop_480_959kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s", + "bipbop_480_959kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4", + "bipbop_480_959kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s", + "bipbop_480_959kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s", + "bipbop_480_959kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s", + "bipbop_480_959kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s", + "bipbop_480_959kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4", + "bipbop_480_959kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key1-1.m4s", + "bipbop_480_959kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-2.m4s", + "bipbop_480_959kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key1-init.mp4", + "bipbop_480_959kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480_959kbps-cenc-video-key2-1.m4s", + "bipbop_480_959kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-2.m4s", + "bipbop_480_959kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480_959kbps-cenc-video-key2-init.mp4", + "bipbop_480_959kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_663kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_663kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_663kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key1-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-3.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s", + "bipbop_480wp_1001kbps-cenc-audio-key2-4.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-audio-key2-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key1-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key1-init.mp4^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-1.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s", + "bipbop_480wp_1001kbps-cenc-video-key2-2.m4s^headers^", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4", + "bipbop_480wp_1001kbps-cenc-video-key2-init.mp4^headers^", + "bipbop_audio_aac_8k.mp4", + "bipbop_audio_aac_8k.mp4^headers^", + "bipbop_audio_aac_22.05k.mp4", + "bipbop_audio_aac_22.05k.mp4^headers^", + "bipbop_audio_aac_44.1k.mp4", + "bipbop_audio_aac_44.1k.mp4^headers^", + "bipbop_audio_aac_48k.mp4", + "bipbop_audio_aac_48k.mp4^headers^", + "bipbop_audio_aac_88.2k.mp4", + "bipbop_audio_aac_88.2k.mp4^headers^", + "bipbop_audio_aac_96k.mp4", + "bipbop_audio_aac_96k.mp4^headers^", + "bipbop_cbcs_1_9_audio_1.m4s", + "bipbop_cbcs_1_9_audio_1.m4s^headers^", + "bipbop_cbcs_1_9_audio_init.mp4", + "bipbop_cbcs_1_9_audio_init.mp4^headers^", + "bipbop_cbcs_1_9_video_1.m4s", + "bipbop_cbcs_1_9_video_1.m4s^headers^", + "bipbop_cbcs_1_9_video_init.mp4", + "bipbop_cbcs_1_9_video_init.mp4^headers^", + "bipbop_cbcs_5_5_audio_1.m4s", + "bipbop_cbcs_5_5_audio_1.m4s^headers^", + "bipbop_cbcs_5_5_audio_init.mp4", + "bipbop_cbcs_5_5_audio_init.mp4^headers^", + "bipbop_cbcs_5_5_video_1.m4s", + "bipbop_cbcs_5_5_video_1.m4s^headers^", + "bipbop_cbcs_5_5_video_init.mp4", + "bipbop_cbcs_5_5_video_init.mp4^headers^", + "bipbop_cbcs_7_7_audio_1.m4s", + "bipbop_cbcs_7_7_audio_1.m4s^headers^", + "bipbop_cbcs_7_7_audio_init.mp4", + "bipbop_cbcs_7_7_audio_init.mp4^headers^", + "bipbop_cbcs_7_7_video_1.m4s", + "bipbop_cbcs_7_7_video_1.m4s^headers^", + "bipbop_cbcs_7_7_video_init.mp4", + "bipbop_cbcs_7_7_video_init.mp4^headers^", + "bipbop_cbcs_9_8_audio_1.m4s", + "bipbop_cbcs_9_8_audio_1.m4s^headers^", + "bipbop_cbcs_9_8_audio_init.mp4", + "bipbop_cbcs_9_8_audio_init.mp4^headers^", + "bipbop_cbcs_9_8_video_1.m4s", + "bipbop_cbcs_9_8_video_1.m4s^headers^", + "bipbop_cbcs_9_8_video_init.mp4", + "bipbop_cbcs_9_8_video_init.mp4^headers^", + "bipbop_cbcs_10_0_audio_1.m4s", + "bipbop_cbcs_10_0_audio_1.m4s^headers^", + "bipbop_cbcs_10_0_audio_init.mp4", + "bipbop_cbcs_10_0_audio_init.mp4^headers^", + "bipbop_cbcs_10_0_video_1.m4s", + "bipbop_cbcs_10_0_video_1.m4s^headers^", + "bipbop_cbcs_10_0_video_init.mp4", + "bipbop_cbcs_10_0_video_init.mp4^headers^", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_bigger_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm", + "bipbop_short_pixel_metadata_narrower_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm^headers^", + "bipbop_short_pixel_metadata_smaller_than_in_stream_vp8.webm", + "bipbop_short_vp8.webm", + "bipbop_short_vp8.webm^headers^", + "bipbop-lateaudio.mp4", + "bipbop-lateaudio.mp4^headers^", + "black100x100-aspect3to2.ogv", + "black100x100-aspect3to2.ogv^headers^", + "bogus.duh", + "bogus.ogv", + "bogus.ogv^headers^", + "bogus.wav", + "bogus.wav^headers^", + "bug461281.ogg", + "bug461281.ogg^headers^", + "bug482461-theora.ogv", + "bug482461-theora.ogv^headers^", + "bug482461.ogv", + "bug482461.ogv^headers^", + "bug495129.ogv", + "bug495129.ogv^headers^", + "bug495794.ogg", + "bug495794.ogg^headers^", + "bug498380.ogv", + "bug498380.ogv^headers^", + "bug498855-1.ogv", + "bug498855-1.ogv^headers^", + "bug498855-2.ogv", + "bug498855-2.ogv^headers^", + "bug498855-3.ogv", + "bug498855-3.ogv^headers^", + "bug499519.ogv", + "bug499519.ogv^headers^", + "bug500311.ogv", + "bug500311.ogv^headers^", + "bug501279.ogg", + "bug501279.ogg^headers^", + "bug504613.ogv", + "bug504613.ogv^headers^", + "bug504644.ogv", + "bug504644.ogv^headers^", + "bug504843.ogv", + "bug504843.ogv^headers^", + "bug506094.ogv", + "bug506094.ogv^headers^", + "bug516323.indexed.ogv", + "bug516323.indexed.ogv^headers^", + "bug516323.ogv", + "bug516323.ogv^headers^", + "bug520493.ogg", + "bug520493.ogg^headers^", + "bug520500.ogg", + "bug520500.ogg^headers^", + "bug520908.ogv", + "bug520908.ogv^headers^", + "bug523816.ogv", + "bug523816.ogv^headers^", + "bug533822.ogg", + "bug533822.ogg^headers^", + "bug556821.ogv", + "bug556821.ogv^headers^", + "bug557094.ogv", + "bug557094.ogv^headers^", + "bug604067.webm", + "bug604067.webm^headers^", + "bug1066943.webm", + "bug1066943.webm^headers^", + "bug1301226.wav", + "bug1301226.wav^headers^", + "bug1301226-odd.wav", + "bug1301226-odd.wav^headers^", + "bug1377278.webm", + "bug1377278.webm^headers^", + "bunny.webm", + "can_play_type_dash.js", + "can_play_type_ogg.js", + "can_play_type_wave.js", + "can_play_type_webm.js", + "cancellable_request.sjs", + "chain.ogg", + "chain.ogg^headers^", + "chain.ogv", + "chain.ogv^headers^", + "chain.opus", + "chain.opus^headers^", + "chained-audio-video.ogg", + "chained-audio-video.ogg^headers^", + "chained-video.ogv", + "chained-video.ogv^headers^", + "chromeHelper.js", + "cloneElementVisually_helpers.js", + "contentType.sjs", + "detodos.opus", + "detodos.opus^headers^", + "detodos.webm", + "detodos.webm^headers^", + "detodos-short.webm", + "detodos-short.webm^headers^", + "detodos-recorder-test.opus", + "detodos-recorder-test.opus^headers^", + "detodos-short.opus", + "detodos-short.opus^headers^", + "dirac.ogg", + "dirac.ogg^headers^", + "dynamic_resource.sjs", + "eme_standalone.js", + "eme.js", + "empty_size.mp3", + "file_access_controls.html", + "file_eme_createMediaKeys.html", + "flac-s24.flac", + "flac-s24.flac^headers^", + "flac-noheader-s16.flac", + "flac-noheader-s16.flac^headers^", + "flac-sample.mp4", + "flac-sample.mp4^headers^", + "flac-sample-cenc.mp4", + "flac-sample-cenc.mp4^headers^", + "fragment_noplay.js", + "fragment_play.js", + "gizmo.mp4", + "gizmo.mp4^headers^", + "gizmo-noaudio.mp4", + "gizmo-noaudio.mp4^headers^", + "gizmo-short.mp4", + "gizmo-short.mp4^headers^", + "gizmo.webm", + "gizmo.webm^headers^", + "gizmo-noaudio.webm", + "gizmo-noaudio.webm^headers^", + "gUM_support.js", + "gzipped_mp4.sjs", + "huge-id3.mp3", + "huge-id3.mp3^headers^", + "id3tags.mp3", + "id3tags.mp3^headers^", + "invalid-cmap-s0c0.opus", + "invalid-cmap-s0c0.opus^headers^", + "invalid-cmap-s0c2.opus", + "invalid-cmap-s0c2.opus^headers^", + "invalid-cmap-s1c2.opus", + "invalid-cmap-s1c2.opus^headers^", + "invalid-cmap-short.opus", + "invalid-cmap-short.opus^headers^", + "invalid-discard_on_multi_blocks.webm", + "invalid-discard_on_multi_blocks.webm^headers^", + "invalid-excess_discard.webm", + "invalid-excess_discard.webm^headers^", + "invalid-excess_neg_discard.webm", + "invalid-excess_neg_discard.webm^headers^", + "invalid-m0c0.opus", + "invalid-m0c0.opus^headers^", + "invalid-m0c3.opus", + "invalid-m0c3.opus^headers^", + "invalid-m1c0.opus", + "invalid-m1c0.opus^headers^", + "invalid-m1c9.opus", + "invalid-m1c9.opus^headers^", + "invalid-m2c0.opus", + "invalid-m2c0.opus^headers^", + "invalid-m2c1.opus", + "invalid-m2c1.opus^headers^", + "invalid-neg_discard.webm", + "invalid-neg_discard.webm^headers^", + "invalid-preskip.webm", + "invalid-preskip.webm^headers^", + "manifest.js", + "midflight-redirect.sjs", + "multiple-bos.ogg", + "multiple-bos.ogg^headers^", + "multiple-bos-more-header-fileds.ogg", + "multiple-bos-more-header-fileds.ogg^headers^", + "multi_id3v2.mp3", + "no-container-codec-delay.webm", + "no-cues.webm", + "no-cues.webm^headers^", + "notags.mp3", + "notags.mp3^headers^", + "opus-mapping2.mp4", + "opus-mapping2.mp4^headers^", + "opus-mapping2.webm", + "opus-mapping2.webm^headers^", + "opus-sample.mp4", + "opus-sample.mp4^headers^", + "opus-sample-cenc.mp4", + "opus-sample-cenc.mp4^headers^", + "owl-funnier-id3.mp3", + "owl-funnier-id3.mp3^headers^", + "owl-funny-id3.mp3", + "owl-funny-id3.mp3^headers^", + "owl.mp3", + "owl.mp3^headers^", + "owl-short.mp3", + "owl-short.mp3^headers^", + "pixel_aspect_ratio.mp4", + "play_promise.js", + "poster-test.jpg", + "r11025_msadpcm_c1.wav", + "r11025_msadpcm_c1.wav^headers^", + "r11025_s16_c1.wav", + "r11025_s16_c1.wav^headers^", + "r11025_s16_c1_trailing.wav", + "r11025_s16_c1_trailing.wav^headers^", + "r11025_s16_c1-short.wav", + "r11025_s16_c1-short.wav^headers^", + "r11025_u8_c1.wav", + "r11025_u8_c1.wav^headers^", + "r11025_u8_c1_trunc.wav", + "r11025_u8_c1_trunc.wav^headers^", + "r16000_u8_c1_list.wav", + "r16000_u8_c1_list.wav^headers^", + "reactivate_helper.html", + "red-46x48.mp4", + "red-46x48.mp4^headers^", + "red-48x46.mp4", + "red-48x46.mp4^headers^", + "redirect.sjs", + "referer.sjs", + "resolution-change.webm", + "resolution-change.webm^headers^", + "sample.3gp", + "sample.3g2", + "sample-encrypted-sgpdstbl-sbgptraf.mp4", + "sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^", + "sample-fisbone-skeleton4.ogv", + "sample-fisbone-skeleton4.ogv^headers^", + "sample-fisbone-wrong-header.ogv", + "sample-fisbone-wrong-header.ogv^headers^", + "seek.ogv", + "seek.ogv^headers^", + "seek-short.ogv", + "seek-short.ogv^headers^", + "seek.webm", + "seek.webm^headers^", + "seek-short.webm", + "seek-short.webm^headers^", + "seek_support.js", + "seekLies.sjs", + "seek_with_sound.ogg^headers^", + "short-cenc.mp4", + "sine.webm", + "sine.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-audio.webm", + "sintel-short-clearkey-subsample-encrypted-audio.webm^headers^", + "sintel-short-clearkey-subsample-encrypted-video.webm", + "sintel-short-clearkey-subsample-encrypted-video.webm^headers^", + "short.mp4", + "short.mp4.gz", + "short.mp4^headers^", + "short-aac-encrypted-audio.mp4", + "short-aac-encrypted-audio.mp4^headers^", + "short-audio-fragmented-cenc-without-pssh.mp4", + "short-audio-fragmented-cenc-without-pssh.mp4^headers^", + "short-video.ogv", + "short-video.ogv^headers^", + "short-vp9-encrypted-video.mp4", + "short-vp9-encrypted-video.mp4^headers^", + "small-shot-mp3.mp4", + "small-shot-mp3.mp4^headers^", + "small-shot.m4a", + "small-shot.mp3", + "small-shot.mp3^headers^", + "small-shot.ogg", + "small-shot.ogg^headers^", + "small-shot.flac", + "sound.ogg", + "sound.ogg^headers^", + "spacestorm-1000Hz-100ms.ogg", + "spacestorm-1000Hz-100ms.ogg^headers^", + "split.webm", + "split.webm^headers^", + "street.mp4", + "street.mp4^headers^", + "test-1-mono.opus", + "test-1-mono.opus^headers^", + "test-2-stereo.opus", + "test-2-stereo.opus^headers^", + "test-3-LCR.opus", + "test-3-LCR.opus^headers^", + "test-4-quad.opus", + "test-4-quad.opus^headers^", + "test-5-5.0.opus", + "test-5-5.0.opus^headers^", + "test-6-5.1.opus", + "test-6-5.1.opus^headers^", + "test-7-6.1.opus", + "test-7-6.1.opus^headers^", + "test-8-7.1.opus", + "test-8-7.1.opus^headers^", + "test-stereo-phase-inversion-180.opus", + "test-stereo-phase-inversion-180.opus^headers^", + "variable-channel.ogg", + "variable-channel.ogg^headers^", + "variable-channel.opus", + "variable-channel.opus^headers^", + "variable-preskip.opus", + "variable-preskip.opus^headers^", + "variable-samplerate.ogg", + "variable-samplerate.ogg^headers^", + "variable-samplerate.opus", + "variable-samplerate.opus^headers^", + "vbr-head.mp3", + "vbr-head.mp3^headers^", + "vbr.mp3", + "vbr.mp3^headers^", + "very-short.mp3", + "video-overhang.ogg", + "video-overhang.ogg^headers^", + "vp9-superframes.webm", + "vp9-superframes.webm^headers^", + "vp9.webm", + "vp9.webm^headers^", + "vp9-short.webm", + "vp9-short.webm^headers^", + "vp9cake.webm", + "vp9cake.webm^headers^", + "vp9cake-short.webm", + "vp9cake-short.webm^headers^", + "wave_metadata.wav", + "wave_metadata.wav^headers^", + "wave_metadata_bad_len.wav", + "wave_metadata_bad_len.wav^headers^", + "wave_metadata_bad_no_null.wav", + "wave_metadata_bad_no_null.wav^headers^", + "wave_metadata_bad_utf8.wav", + "wave_metadata_bad_utf8.wav^headers^", + "wave_metadata_unknown_tag.wav", + "wave_metadata_unknown_tag.wav^headers^", + "wave_metadata_utf8.wav", + "wave_metadata_utf8.wav^headers^", + "wavedata_alaw.wav", + "wavedata_alaw.wav^headers^", + "wavedata_float.wav", + "wavedata_float.wav^headers^", + "wavedata_s24.wav", + "wavedata_s24.wav^headers^", + "wavedata_s16.wav", + "wavedata_s16.wav^headers^", + "wavedata_u8.wav", + "wavedata_u8.wav^headers^", + "wavedata_ulaw.wav", + "wavedata_ulaw.wav^headers^", + "!/dom/canvas/test/captureStream_common.js", + "!/dom/html/test/reflect.js", + "!/dom/media/webrtc/tests/mochitests/head.js", + "hls/bipbop_16x9_single.m3u8", + "hls/bipbop_4x3_single.m3u8", + "hls/bipbop_4x3_variant.m3u8", + "hls/400x300_prog_index.m3u8", + "hls/400x300_prog_index_5s.m3u8", + "hls/416x243_prog_index_5s.m3u8", + "hls/640x480_prog_index.m3u8", + "hls/960x720_prog_index.m3u8", + "hls/400x300_seg0.ts", + "hls/400x300_seg0_5s.ts", + "hls/400x300_seg1.ts", + "hls/416x243_seg0_5s.ts", + "hls/640x480_seg0.ts", + "hls/640x480_seg1.ts", + "hls/960x720_seg0.ts", + "hls/960x720_seg1.ts", + "sync.webm", +] + +["test_streams_capture_origin.html"] + +["test_streams_element_capture.html"] +skip-if = ["os == 'android'"] # bug 1372457, bug 1526207 for drawImage + +["test_streams_element_capture_mediatrack.html"] + +["test_streams_element_capture_playback.html"] + +["test_streams_element_capture_reset.html"] + +["test_streams_element_capture_twice.html"] + +["test_streams_firstframe.html"] + +["test_streams_gc.html"] + +["test_streams_individual_pause.html"] +skip-if = ["os == 'mac' && debug"] # Bug 1756880 - temp due to low frequency shutdown hang +scheme = "https" +tags = "mtg" + +["test_streams_srcObject.html"] +skip-if = [ + "os == 'android'", # bug 1300443, android(bug 1232305) + "os == 'mac' && debug", # Bug 1756880 - temp due to high frequency shutdown hang +] + +["test_streams_tracks.html"] +skip-if = ["os == 'android'"] # android(bug 1232305) diff --git a/dom/media/test/multi_id3v2.mp3 b/dom/media/test/multi_id3v2.mp3 Binary files differnew file mode 100644 index 0000000000..253f19a9b6 --- /dev/null +++ b/dom/media/test/multi_id3v2.mp3 diff --git a/dom/media/test/multiple-bos-more-header-fileds.ogg b/dom/media/test/multiple-bos-more-header-fileds.ogg Binary files differnew file mode 100644 index 0000000000..c9721cb98e --- /dev/null +++ b/dom/media/test/multiple-bos-more-header-fileds.ogg diff --git a/dom/media/test/multiple-bos-more-header-fileds.ogg^headers^ b/dom/media/test/multiple-bos-more-header-fileds.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/multiple-bos-more-header-fileds.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/multiple-bos.ogg b/dom/media/test/multiple-bos.ogg Binary files differnew file mode 100644 index 0000000000..193200868e --- /dev/null +++ b/dom/media/test/multiple-bos.ogg diff --git a/dom/media/test/multiple-bos.ogg^headers^ b/dom/media/test/multiple-bos.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/multiple-bos.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/no-container-codec-delay.webm b/dom/media/test/no-container-codec-delay.webm Binary files differnew file mode 100644 index 0000000000..9c1ef8e6d7 --- /dev/null +++ b/dom/media/test/no-container-codec-delay.webm diff --git a/dom/media/test/no-cues.webm b/dom/media/test/no-cues.webm Binary files differnew file mode 100644 index 0000000000..8ed761099e --- /dev/null +++ b/dom/media/test/no-cues.webm diff --git a/dom/media/test/no-cues.webm^headers^ b/dom/media/test/no-cues.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/no-cues.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/notags.mp3 b/dom/media/test/notags.mp3 Binary files differnew file mode 100644 index 0000000000..7f298131aa --- /dev/null +++ b/dom/media/test/notags.mp3 diff --git a/dom/media/test/notags.mp3^headers^ b/dom/media/test/notags.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/notags.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/opus-mapping2.mp4 b/dom/media/test/opus-mapping2.mp4 Binary files differnew file mode 100644 index 0000000000..72401a9c0b --- /dev/null +++ b/dom/media/test/opus-mapping2.mp4 diff --git a/dom/media/test/opus-mapping2.mp4^headers^ b/dom/media/test/opus-mapping2.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/opus-mapping2.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/opus-mapping2.webm b/dom/media/test/opus-mapping2.webm Binary files differnew file mode 100644 index 0000000000..4379f2534a --- /dev/null +++ b/dom/media/test/opus-mapping2.webm diff --git a/dom/media/test/opus-mapping2.webm^headers^ b/dom/media/test/opus-mapping2.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/opus-mapping2.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/opus-sample-cenc.mp4 b/dom/media/test/opus-sample-cenc.mp4 Binary files differnew file mode 100644 index 0000000000..22bb787540 --- /dev/null +++ b/dom/media/test/opus-sample-cenc.mp4 diff --git a/dom/media/test/opus-sample-cenc.mp4^headers^ b/dom/media/test/opus-sample-cenc.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/opus-sample-cenc.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/opus-sample.mp4 b/dom/media/test/opus-sample.mp4 Binary files differnew file mode 100644 index 0000000000..80329ce14b --- /dev/null +++ b/dom/media/test/opus-sample.mp4 diff --git a/dom/media/test/opus-sample.mp4^headers^ b/dom/media/test/opus-sample.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/opus-sample.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/owl-funnier-id3.mp3 b/dom/media/test/owl-funnier-id3.mp3 Binary files differnew file mode 100644 index 0000000000..05ec507530 --- /dev/null +++ b/dom/media/test/owl-funnier-id3.mp3 diff --git a/dom/media/test/owl-funnier-id3.mp3^headers^ b/dom/media/test/owl-funnier-id3.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/owl-funnier-id3.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/owl-funny-id3.mp3 b/dom/media/test/owl-funny-id3.mp3 Binary files differnew file mode 100644 index 0000000000..6533755a32 --- /dev/null +++ b/dom/media/test/owl-funny-id3.mp3 diff --git a/dom/media/test/owl-funny-id3.mp3^headers^ b/dom/media/test/owl-funny-id3.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/owl-funny-id3.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/owl-short.mp3 b/dom/media/test/owl-short.mp3 Binary files differnew file mode 100644 index 0000000000..9b31531f22 --- /dev/null +++ b/dom/media/test/owl-short.mp3 diff --git a/dom/media/test/owl-short.mp3^headers^ b/dom/media/test/owl-short.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/owl-short.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/owl.mp3 b/dom/media/test/owl.mp3 Binary files differnew file mode 100644 index 0000000000..9fafa32f93 --- /dev/null +++ b/dom/media/test/owl.mp3 diff --git a/dom/media/test/owl.mp3^headers^ b/dom/media/test/owl.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/owl.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/padding-spanning-multiple-packets.mp3 b/dom/media/test/padding-spanning-multiple-packets.mp3 Binary files differnew file mode 100644 index 0000000000..d7ab9dc3f5 --- /dev/null +++ b/dom/media/test/padding-spanning-multiple-packets.mp3 diff --git a/dom/media/test/pixel_aspect_ratio.mp4 b/dom/media/test/pixel_aspect_ratio.mp4 Binary files differnew file mode 100644 index 0000000000..fce12cc03e --- /dev/null +++ b/dom/media/test/pixel_aspect_ratio.mp4 diff --git a/dom/media/test/play_promise.js b/dom/media/test/play_promise.js new file mode 100644 index 0000000000..7051fedc19 --- /dev/null +++ b/dom/media/test/play_promise.js @@ -0,0 +1,3 @@ +function getNotSupportedFile(name) { + return name + ".bad"; +} diff --git a/dom/media/test/poster-test.jpg b/dom/media/test/poster-test.jpg Binary files differnew file mode 100644 index 0000000000..595a5315f8 --- /dev/null +++ b/dom/media/test/poster-test.jpg diff --git a/dom/media/test/r11025_msadpcm_c1.wav b/dom/media/test/r11025_msadpcm_c1.wav Binary files differnew file mode 100644 index 0000000000..2e883ba5ed --- /dev/null +++ b/dom/media/test/r11025_msadpcm_c1.wav diff --git a/dom/media/test/r11025_msadpcm_c1.wav^headers^ b/dom/media/test/r11025_msadpcm_c1.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/r11025_msadpcm_c1.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/r11025_s16_c1-short.wav b/dom/media/test/r11025_s16_c1-short.wav Binary files differnew file mode 100644 index 0000000000..e08d5bbdc0 --- /dev/null +++ b/dom/media/test/r11025_s16_c1-short.wav diff --git a/dom/media/test/r11025_s16_c1-short.wav^headers^ b/dom/media/test/r11025_s16_c1-short.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/r11025_s16_c1-short.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/r11025_s16_c1.wav b/dom/media/test/r11025_s16_c1.wav Binary files differnew file mode 100644 index 0000000000..ab2e08befb --- /dev/null +++ b/dom/media/test/r11025_s16_c1.wav diff --git a/dom/media/test/r11025_s16_c1.wav^headers^ b/dom/media/test/r11025_s16_c1.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/r11025_s16_c1.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/r11025_s16_c1_trailing.wav b/dom/media/test/r11025_s16_c1_trailing.wav Binary files differnew file mode 100644 index 0000000000..af53beaf25 --- /dev/null +++ b/dom/media/test/r11025_s16_c1_trailing.wav diff --git a/dom/media/test/r11025_s16_c1_trailing.wav^headers^ b/dom/media/test/r11025_s16_c1_trailing.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/r11025_s16_c1_trailing.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/r11025_u8_c1.wav b/dom/media/test/r11025_u8_c1.wav Binary files differnew file mode 100644 index 0000000000..97dc453b9e --- /dev/null +++ b/dom/media/test/r11025_u8_c1.wav diff --git a/dom/media/test/r11025_u8_c1.wav^headers^ b/dom/media/test/r11025_u8_c1.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/r11025_u8_c1.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/r11025_u8_c1_trunc.wav b/dom/media/test/r11025_u8_c1_trunc.wav Binary files differnew file mode 100644 index 0000000000..4d2db39777 --- /dev/null +++ b/dom/media/test/r11025_u8_c1_trunc.wav diff --git a/dom/media/test/r11025_u8_c1_trunc.wav^headers^ b/dom/media/test/r11025_u8_c1_trunc.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/r11025_u8_c1_trunc.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/r16000_u8_c1_list.wav b/dom/media/test/r16000_u8_c1_list.wav Binary files differnew file mode 100644 index 0000000000..afde32e9a3 --- /dev/null +++ b/dom/media/test/r16000_u8_c1_list.wav diff --git a/dom/media/test/r16000_u8_c1_list.wav^headers^ b/dom/media/test/r16000_u8_c1_list.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/r16000_u8_c1_list.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/rdd_process_xpcom/RddProcessTest.cpp b/dom/media/test/rdd_process_xpcom/RddProcessTest.cpp new file mode 100644 index 0000000000..fad7d6ee2e --- /dev/null +++ b/dom/media/test/rdd_process_xpcom/RddProcessTest.cpp @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if defined(ENABLE_TESTS) +# include "mozilla/RDDProcessManager.h" +# include "mozilla/RDDChild.h" +# include "mozilla/RddProcessTest.h" +# include "mozilla/dom/Promise.h" + +namespace mozilla { + +NS_IMETHODIMP +RddProcessTest::TestTelemetryProbes(JSContext* aCx, + mozilla::dom::Promise** aOutPromise) { + NS_ENSURE_ARG(aOutPromise); + *aOutPromise = nullptr; + nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx); + if (NS_WARN_IF(!global)) { + return NS_ERROR_FAILURE; + } + + ErrorResult erv; + RefPtr<dom::Promise> promise = dom::Promise::Create(global, erv); + if (NS_WARN_IF(erv.Failed())) { + return erv.StealNSResult(); + } + + RDDProcessManager* rddProc = RDDProcessManager::Get(); + MOZ_ASSERT(rddProc, "No RddProcessManager?"); + + rddProc->LaunchRDDProcess()->Then( + GetMainThreadSerialEventTarget(), __func__, + [promise, rddProc]() { + RDDChild* child = rddProc->GetRDDChild(); + if (!rddProc) { + promise->MaybeReject(NS_ERROR_NOT_AVAILABLE); + } + MOZ_ASSERT(rddProc, "No RDD Proc?"); + + if (!child) { + promise->MaybeReject(NS_ERROR_NOT_AVAILABLE); + } + MOZ_ASSERT(child, "No RDD Child?"); + + Unused << child->SendTestTelemetryProbes(); + promise->MaybeResolve((int32_t)rddProc->RDDProcessPid()); + }, + [promise](nsresult aError) { + MOZ_ASSERT_UNREACHABLE("RddProcessTest; failure to get RDD child"); + promise->MaybeReject(aError); + }); + + promise.forget(aOutPromise); + return NS_OK; +} + +NS_IMETHODIMP +RddProcessTest::StopProcess() { + RDDProcessManager::RDDProcessShutdown(); + return NS_OK; +} + +NS_IMPL_ISUPPORTS(RddProcessTest, nsIRddProcessTest) + +} // namespace mozilla +#endif // defined(ENABLE_TESTS) diff --git a/dom/media/test/rdd_process_xpcom/RddProcessTest.h b/dom/media/test/rdd_process_xpcom/RddProcessTest.h new file mode 100644 index 0000000000..b0281df45b --- /dev/null +++ b/dom/media/test/rdd_process_xpcom/RddProcessTest.h @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef _include_dom_media_RddProcessTest_h_ +#define _include_dom_media_RddProcessTest_h_ + +#if defined(ENABLE_TESTS) +# include "nsIRddProcessTest.h" + +namespace mozilla { + +class RddProcessTest final : public nsIRddProcessTest { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIRDDPROCESSTEST + + RddProcessTest() = default; + + private: + ~RddProcessTest() = default; +}; + +} // namespace mozilla +#endif // defined(ENABLE_TESTS) + +#endif // _include_dom_media_RddProcessTest_h_ diff --git a/dom/media/test/rdd_process_xpcom/components.conf b/dom/media/test/rdd_process_xpcom/components.conf new file mode 100644 index 0000000000..507559851b --- /dev/null +++ b/dom/media/test/rdd_process_xpcom/components.conf @@ -0,0 +1,15 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Classes = [ + { + 'cid': '{12f7d302-5368-412d-bdc9-26d151518e6c}', + 'contract_ids': ['@mozilla.org/rdd-process-test;1'], + 'type': 'mozilla::RddProcessTest', + 'headers': ['mozilla/RddProcessTest.h'], + 'processes': ProcessSelector.MAIN_PROCESS_ONLY, + }, +] diff --git a/dom/media/test/rdd_process_xpcom/moz.build b/dom/media/test/rdd_process_xpcom/moz.build new file mode 100644 index 0000000000..87dbb39bc1 --- /dev/null +++ b/dom/media/test/rdd_process_xpcom/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS.mozilla += ["RddProcessTest.h"] + +UNIFIED_SOURCES += ["RddProcessTest.cpp"] + +XPCOM_MANIFESTS += ["components.conf"] + +XPIDL_MODULE = "rdd_process_xpcom_test" + +XPIDL_SOURCES += [ + "nsIRddProcessTest.idl", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul" diff --git a/dom/media/test/rdd_process_xpcom/nsIRddProcessTest.idl b/dom/media/test/rdd_process_xpcom/nsIRddProcessTest.idl new file mode 100644 index 0000000000..a10fdbd249 --- /dev/null +++ b/dom/media/test/rdd_process_xpcom/nsIRddProcessTest.idl @@ -0,0 +1,25 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +[scriptable, uuid(12f7d302-5368-412d-bdc9-26d151518e6c)] +interface nsIRddProcessTest : nsISupports +{ + /** + * ** Test-only Method ** + * + * Sending Telemetry probes + */ + [implicit_jscontext] + Promise testTelemetryProbes(); + + /** + * ** Test-only Method ** + * + * Stop existing RDD process + */ + void stopProcess(); +}; diff --git a/dom/media/test/reactivate_helper.html b/dom/media/test/reactivate_helper.html new file mode 100644 index 0000000000..1834131559 --- /dev/null +++ b/dom/media/test/reactivate_helper.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<body> +<script> +var loadsWaiting = 0; +var elements = []; + +function checkAllLoaded() { + --loadsWaiting; + if (loadsWaiting == 0) { + parent.loadedAll(elements); + } +} + +function loadedData(event) { + var e = event.target; + parent.ok(!elements.includes(e), "Element already loaded: " + e._name); + parent.info("Loaded " + e._name); + elements.push(e); + // Reset "onerror" handler to avoid triggering another error in removeNodeAndSource(). + e.onerror = null; + checkAllLoaded(); + +} + +function error(event) { + var e = event.target; + parent.info("Error " + e._name); + // Don't wait for the element encounting errors. + checkAllLoaded(); +} + +for (var i = 0; i < parent.gSmallTests.length; ++i) { + var test = parent.gSmallTests[i]; + var elemType = /^audio/.test(test.type) ? "audio" : "video"; + // Associate these elements with the subframe's document + var e = document.createElement(elemType); + e.preload = "metadata"; + if (e.canPlayType(test.type)) { + e.src = test.name; + e._name = test.name; + e.onloadeddata = loadedData; + e.onerror = error; + e.load(); + ++loadsWaiting; + parent.info("Loading " + e._name); + } +} + +if (loadsWaiting == 0) { + parent.todo(false, "Can't play anything"); +} else { + parent.SimpleTest.waitForExplicitFinish(); +} +</script> +</body> +</html> diff --git a/dom/media/test/red-46x48.mp4 b/dom/media/test/red-46x48.mp4 Binary files differnew file mode 100644 index 0000000000..0760cc1c16 --- /dev/null +++ b/dom/media/test/red-46x48.mp4 diff --git a/dom/media/test/red-46x48.mp4^headers^ b/dom/media/test/red-46x48.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/red-46x48.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/red-48x46.mp4 b/dom/media/test/red-48x46.mp4 Binary files differnew file mode 100644 index 0000000000..d83de4027d --- /dev/null +++ b/dom/media/test/red-48x46.mp4 diff --git a/dom/media/test/red-48x46.mp4^headers^ b/dom/media/test/red-48x46.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/red-48x46.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/redirect.sjs b/dom/media/test/redirect.sjs new file mode 100644 index 0000000000..6873fd52f3 --- /dev/null +++ b/dom/media/test/redirect.sjs @@ -0,0 +1,35 @@ +function parseQuery(request, key) { + var params = request.queryString.split("&"); + for (var j = 0; j < params.length; ++j) { + var p = params[j]; + if (p == key) { + return true; + } + if (p.indexOf(key + "=") == 0) { + return p.substring(key.length + 1); + } + if (!p.includes("=") && key == "") { + return p; + } + } + return false; +} + +// Return file content for the first request with a given key. +// All subsequent requests return a redirect to a different-origin resource. +function handleRequest(request, response) { + var domain = parseQuery(request, "domain"); + var file = parseQuery(request, "file"); + var allowed = parseQuery(request, "allowed"); + + response.setStatusLine(request.httpVersion, 303, "See Other"); + response.setHeader( + "Location", + "http://" + + domain + + "/tests/dom/media/test/" + + (allowed ? "allowed.sjs?" : "") + + file + ); + response.setHeader("Content-Type", "text/html"); +} diff --git a/dom/media/test/referer.sjs b/dom/media/test/referer.sjs new file mode 100644 index 0000000000..0c699c4ae1 --- /dev/null +++ b/dom/media/test/referer.sjs @@ -0,0 +1,49 @@ +function parseQuery(request, key) { + var params = request.queryString.split("&"); + for (var j = 0; j < params.length; ++j) { + var p = params[j]; + if (p == key) { + return true; + } + if (p.indexOf(key + "=") == 0) { + return p.substring(key.length + 1); + } + if (!p.includes("=") && key == "") { + return p; + } + } + return false; +} + +function handleRequest(request, response) { + var referer = request.hasHeader("Referer") + ? request.getHeader("Referer") + : undefined; + if ( + referer == "http://mochi.test:8888/tests/dom/media/test/test_referer.html" + ) { + var name = parseQuery(request, "name"); + var type = parseQuery(request, "type"); + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + var paths = "tests/dom/media/test/" + name; + var split = paths.split("/"); + for (var i = 0; i < split.length; ++i) { + file.append(split[i]); + } + fis.init(file, -1, -1, false); + bis.setInputStream(fis); + var bytes = bis.readBytes(bis.available()); + response.setHeader("Content-Length", "" + bytes.length, false); + response.setHeader("Content-Type", type, false); + response.write(bytes, bytes.length); + bis.close(); + } else { + response.setStatusLine(request.httpVersion, 404, "Not found"); + } +} diff --git a/dom/media/test/reftest/av1hdr2020.mp4 b/dom/media/test/reftest/av1hdr2020.mp4 Binary files differnew file mode 100644 index 0000000000..295bec8a3c --- /dev/null +++ b/dom/media/test/reftest/av1hdr2020.mp4 diff --git a/dom/media/test/reftest/av1hdr2020.png b/dom/media/test/reftest/av1hdr2020.png Binary files differnew file mode 100644 index 0000000000..c5d3344a80 --- /dev/null +++ b/dom/media/test/reftest/av1hdr2020.png diff --git a/dom/media/test/reftest/bipbop_300_215kbps.mp4.lastframe-ref.html b/dom/media/test/reftest/bipbop_300_215kbps.mp4.lastframe-ref.html new file mode 100644 index 0000000000..575acb107d --- /dev/null +++ b/dom/media/test/reftest/bipbop_300_215kbps.mp4.lastframe-ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE HTML> +<img style="position:absolute; left:0; top:0" +src="data:image/png;base64,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" +> diff --git a/dom/media/test/reftest/bipbop_300_215kbps.mp4.lastframe.html b/dom/media/test/reftest/bipbop_300_215kbps.mp4.lastframe.html new file mode 100644 index 0000000000..600b04a4f0 --- /dev/null +++ b/dom/media/test/reftest/bipbop_300_215kbps.mp4.lastframe.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "../bipbop_300_215kbps.mp4"; + video.play(); + video.addEventListener("ended", function() { + document.documentElement.removeAttribute('class'); + }, {once: true}); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0"></video> +</body> +</html> diff --git a/dom/media/test/reftest/color_quads/720p.png b/dom/media/test/reftest/color_quads/720p.png Binary files differnew file mode 100644 index 0000000000..cf3f2408c1 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.av1.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.av1.mp4 Binary files differnew file mode 100644 index 0000000000..fa1801013a --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.av1.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.av1.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.av1.webm Binary files differnew file mode 100644 index 0000000000..96fd46f848 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.av1.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.h264.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.h264.mp4 Binary files differnew file mode 100644 index 0000000000..c5f08a56f2 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.h264.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.vp9.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.vp9.mp4 Binary files differnew file mode 100644 index 0000000000..c64f7eb8d2 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.vp9.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.vp9.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.vp9.webm Binary files differnew file mode 100644 index 0000000000..d4341d22ed --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.gbrp.vp9.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.mp4 Binary files differnew file mode 100644 index 0000000000..ac89827620 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.webm Binary files differnew file mode 100644 index 0000000000..1544ef996e --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.h264.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.h264.mp4 Binary files differnew file mode 100644 index 0000000000..041d7b4477 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.h264.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.mp4 Binary files differnew file mode 100644 index 0000000000..e9cdbb5f51 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.webm Binary files differnew file mode 100644 index 0000000000..6d0b53f002 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.mp4 Binary files differnew file mode 100644 index 0000000000..f30c731bf6 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm Binary files differnew file mode 100644 index 0000000000..0e733057d8 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.h264.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.h264.mp4 Binary files differnew file mode 100644 index 0000000000..9a4783f2db --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.h264.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.mp4 Binary files differnew file mode 100644 index 0000000000..00565d66d3 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.webm Binary files differnew file mode 100644 index 0000000000..08159b5233 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.av1.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.av1.mp4 Binary files differnew file mode 100644 index 0000000000..3a50d11691 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.av1.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.av1.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.av1.webm Binary files differnew file mode 100644 index 0000000000..c18de4bf4f --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.av1.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.h264.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.h264.mp4 Binary files differnew file mode 100644 index 0000000000..9d735cf9ed --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.h264.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.mp4 Binary files differnew file mode 100644 index 0000000000..79dcb0d72d --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.webm Binary files differnew file mode 100644 index 0000000000..31af47cba1 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.mp4 Binary files differnew file mode 100644 index 0000000000..dfcac969b9 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.webm Binary files differnew file mode 100644 index 0000000000..00f46b0597 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.h264.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.h264.mp4 Binary files differnew file mode 100644 index 0000000000..ca8b8a1572 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.h264.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.vp9.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.vp9.mp4 Binary files differnew file mode 100644 index 0000000000..19ff1b4265 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.vp9.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.vp9.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.vp9.webm Binary files differnew file mode 100644 index 0000000000..6fd0aa6756 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p.vp9.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.mp4 Binary files differnew file mode 100644 index 0000000000..e95fd5c9fb --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm Binary files differnew file mode 100644 index 0000000000..f28e65f034 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.h264.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.h264.mp4 Binary files differnew file mode 100644 index 0000000000..1fe6824cb4 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.h264.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.mp4 b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.mp4 Binary files differnew file mode 100644 index 0000000000..532ae19359 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.mp4 diff --git a/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.webm b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.webm Binary files differnew file mode 100644 index 0000000000..e4aad890f5 --- /dev/null +++ b/dom/media/test/reftest/color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.webm diff --git a/dom/media/test/reftest/color_quads/reftest.list b/dom/media/test/reftest/color_quads/reftest.list new file mode 100644 index 0000000000..6071733f76 --- /dev/null +++ b/dom/media/test/reftest/color_quads/reftest.list @@ -0,0 +1,69 @@ +# Reference image generated via https://jdashg.github.io/misc/colors/color-quads-16-127-235.html +# Test videos encoded via ../gen_combos.py --write color_quads/720p.png + +# We're sort of testing two things here: +# 1. Does a av1.webm video into the actual values we expect? +# 2. Do other similar videos decode the same was as av1.webm? +# We have this split because while each platform/compositor has its own inaccuracies, +# each platform/compositor will have the *same* inaccuracies regardless of video. +# So, we just need to first check if e.g. av1.webm decodes to what we expect, +# and then we have generally trivially compare other codecs/containers to that. + +defaults pref(media.av1.enabled,true) + +# - +# yuv420p + +fuzzy(16-51,5234-5622) fuzzy-if(swgl,32-38,1600-91746) fuzzy-if(useDrawSnapshot,16-16,11600-11600) fuzzy-if(OSX,16-73,5212-5622) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.webm ../reftest_img.html?src=color_quads/720p.png +fuzzy-if(winWidget&&swgl,0-20,0-5620) fuzzy-if(winWidget&&!swgl,0-1,0-78) fuzzy-if(Android,254-255,273680-273807) fuzzy-if(OSX,0-35,0-1947) fuzzy-if(OSX&&swgl,0-67,0-5451) fuzzy-if(appleSilicon,30-48,1760-187409) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.vp9.webm ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.webm +fuzzy-if(winWidget,0-1,0-78) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.webm +skip-if(winWidget&&isCoverageBuild) fuzzy(0-16,75-1941) fuzzy-if(Android,28-255,273680-359920) fuzzy-if(OSX,30-32,187326-187407) fuzzy-if(appleSilicon,30-48,1835-187409) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.h264.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.webm +fuzzy-if(winWidget&&swgl,0-20,0-5620) fuzzy-if(winWidget&&!swgl,0-1,0-78) fuzzy-if(Android,254-255,273680-273807) fuzzy-if(OSX,0-35,0-1947) fuzzy-if(OSX&&swgl,0-67,0-5451) fuzzy-if(appleSilicon,30-48,1760-187409) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.vp9.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p.av1.webm + +skip-if(Android) fuzzy(16-48,8107-8818) fuzzy-if(winWidget&&swgl,31-38,8240-184080) fuzzy-if(appleSilicon,33-38,8819-11705) fuzzy-if(useDrawSnapshot,20-20,187200-187200) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.webm ../reftest_img.html?src=color_quads/720p.png +skip-if(Android) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.webm +# On Windows & sw render, we noticed that the comparison image captured from AV1 is not equal to its displayed video frame, so we would need to compare other codecs directly to PNG file. That should be fixed in bug 1748540. +skip-if(Android) skip-if(winWidget&&swgl) fuzzy-if(Android,255-255,273726-273726) fuzzy-if(OSX,0-16,0-1718) fuzzy-if(OSX&&swgl,0-20,0-2423) fuzzy-if(appleSilicon,0-16,0-1874) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.webm ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.webm +skip-if(Android) skip-if(winWidget&&swgl) fuzzy-if(Android,255-255,273726-273726) fuzzy-if(OSX,2-36,184281-187407) fuzzy-if(winWidget,0-21,0-360000) fuzzy-if(appleSilicon,36-49,187329-187407) fuzzy-if(useDrawSnapshot,0-1,0-10) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.h264.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.webm +skip-if(Android) skip-if(winWidget&&swgl) fuzzy-if(Android,255-255,273726-273726) fuzzy-if(OSX,0-16,0-1718) fuzzy-if(OSX&&swgl,0-20,0-2423) fuzzy-if(appleSilicon,0-16,0-1874) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.av1.webm +skip-if(Android) skip-if(!(winWidget&&swgl)) fuzzy(0-35,0-8506) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.webm ../reftest_img.html?src=color_quads/720p.png +skip-if(Android) skip-if(!(winWidget&&swgl)) fuzzy(0-35,0-8506) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p.vp9.mp4 ../reftest_img.html?src=color_quads/720p.png + +# - +# yuv420p10 + +skip-if(Android) fuzzy(33-49,1870-2579) fuzzy-if(swgl,34-52,180421-270528) fuzzy-if(useDrawSnapshot,16-16,183840-183840) fuzzy-if(OSX,60-74,270329-271024) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm ../reftest_img.html?src=color_quads/720p.png +skip-if(Android) fuzzy-if(OSX,0-12,0-187770) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.webm ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm +skip-if(Android) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm +#[2] skip-if(Android) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.h264.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm +skip-if(Android) fuzzy-if(OSX,0-12,0-187770) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm + +skip-if(Android) fuzzy(33-49,174620-270059) fuzzy-if(swgl&&!winWidget,36-52,11553-11555) fuzzy-if(swgl&&winWidget,36-52,11554-187200) fuzzy-if(swgl&&OSX,34-50,11465-270059) fuzzy-if(useDrawSnapshot,20-20,186800-186800) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm ../reftest_img.html?src=color_quads/720p.png +skip-if(Android) fuzzy-if(OSX,0-12,0-274122) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.webm ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm +skip-if(Android) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm +#[2] skip-if(Android) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.h264.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm +skip-if(Android) fuzzy-if(OSX,0-12,0-274122) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm + +# Android is really broken in a variety of ways for p10. +#[2]: yuv420p10 broken in h264.mp4: https://bugzilla.mozilla.org/show_bug.cgi?id=1711812 + + +# - +# gbrp +# Note: tv-gbrp doesn't really make sense, and we should consider dropping it. +# Specifically, we should probably do (gbrp, ...(tv,pc)x(yuv,yuv10)) instead of (tv,pc)x(gbrp,yuv,yuv10) +# That said, we should probably test a couple combos, at least. (But then again, why not all!) + +skip-if(winWidget&&swgl) fuzzy(0-1,0-3600) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.av1.webm ../reftest_img.html?src=color_quads/720p.png +skip-if(winWidget&&swgl) fuzzy(0-1,0-7200) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.gbrp.av1.webm ../reftest_img.html?src=color_quads/720p.png + +== ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.av1.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.av1.webm +== ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.gbrp.av1.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.gbrp.av1.webm + +# Our h264.mp4 doesn't handle gbrp, but *also* doesn't error properly. +== ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.h264.mp4 ../reftest_video.html?src=timeout +== ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.gbrp.h264.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.h264.mp4 + +fuzzy(0-1,0-3600) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.gbrp.vp9.webm ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.webm +== ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.webm +fuzzy(0-1,0-3600) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.gbrp.vp9.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.gbrp.vp9.webm diff --git a/dom/media/test/reftest/frame_order.mp4 b/dom/media/test/reftest/frame_order.mp4 Binary files differnew file mode 100644 index 0000000000..87b65f4386 --- /dev/null +++ b/dom/media/test/reftest/frame_order.mp4 diff --git a/dom/media/test/reftest/frame_order_mp4-ref.html b/dom/media/test/reftest/frame_order_mp4-ref.html new file mode 100644 index 0000000000..0c59debcfa --- /dev/null +++ b/dom/media/test/reftest/frame_order_mp4-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML> +<head> +</head> +<body> +<!-- + This ref image is generated by capturing video frame on 0.3s from + 'frame_order.mp4' +--> +<image style="position:absolute; left:0; top:0" src="data:image/png;base64,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QQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEAgqAEAIBDUAAAQCGoAAAgENQAABIIaAAACQQ0AAIGgBgCAQFADAEDwLzt4JGSwax6ZAAAAAElFTkSuQmCC"></video> +<script type="text/javascript"> +</script> +</body> +</html> diff --git a/dom/media/test/reftest/frame_order_mp4.html b/dom/media/test/reftest/frame_order_mp4.html new file mode 100644 index 0000000000..e77cf05e9e --- /dev/null +++ b/dom/media/test/reftest/frame_order_mp4.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +</head> +<body> +<video id="v" style="position:absolute; left:0; top:0"></video> +<canvas id="canvas" style="position:absolute; left:0; top:0"></video> +<script type="text/javascript"> +/** + * Do seek multiple times and check the video frame on 0.3s. + */ +async function testFrameOrderAfterSeeking() { + const video = document.getElementById("v"); + video.src = "frame_order.mp4"; + await new Promise(r => video.oncanplay = r); + // The issue won't happen on the first seek, because the decoder hasn't been + // created yet. + video.currentTime = 0.1; + await new Promise(r => video.onseeked = r); + video.currentTime = 0.3; + await new Promise(r => video.onseeked = r); + // Since our media pipeline sends the frame to imageBridge, then fires + // a seeked event, the target frame may not be shown on the screen. + // So using canvas to access the target frame in the imageContainer in + // videoElement. + const canvas = document.getElementById("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + const ctx = canvas.getContext("2d"); + ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); + document.documentElement.removeAttribute('class'); +}; + +window.addEventListener("MozReftestInvalidate", testFrameOrderAfterSeeking); +</script> +</body> +</html> diff --git a/dom/media/test/reftest/gen_combos.py b/dom/media/test/reftest/gen_combos.py new file mode 100644 index 0000000000..f7e7d50fe1 --- /dev/null +++ b/dom/media/test/reftest/gen_combos.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python3 + +# E.g. `./gen_combos.py [--write] color_quads/720p.png` + +import concurrent.futures +import pathlib +import subprocess +import sys + +ARGS = sys.argv +SRC_PATH = pathlib.Path(ARGS.pop()) +assert SRC_PATH.exists(), "gen_combos.py [--flags] <src file path>" +DIR = SRC_PATH.parent + + +# crossCombine([{a:false},{a:5}], [{},{b:5}]) +# [{a:false}, {a:true}, {a:false,b:5}, {a:true,b:5}] +def cross_combine(*args): + args = list(args) + + def cross_combine2(listA, listB): + listC = [] + for a in listA: + for b in listB: + c = dict() + c.update(a) + c.update(b) + listC.append(c) + return listC + + res = [dict()] + while True: + try: + next = args.pop(0) + except IndexError: + break + res = cross_combine2(res, next) + return res + + +def keyed_combiner(key, vals): + res = [] + for v in vals: + d = dict() + d[key] = v + res.append(d) + return res + + +# - + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +# - + +OGG = [] +WEBM_CODECS = ["av1", "vp9"] + +if "--all" in ARGS: + OGG = cross_combine( + [{"ext": "ogg"}], keyed_combiner("vcodec", ["theora", "vp8", "vp9"]) + ) + WEBM_CODECS += ["vp8"] + +MP4 = cross_combine([{"ext": "mp4"}], keyed_combiner("vcodec", ["av1", "h264", "vp9"])) + +WEBM = cross_combine([{"ext": "webm"}], keyed_combiner("vcodec", WEBM_CODECS)) + +# - + +FORMAT_LIST = set( + [ + "yuv420p", + "yuv420p10", + # 'yuv420p12', + # 'yuv420p16be', + # 'yuv420p16le', + "gbrp", + ] +) + +if "--all" in ARGS: + FORMAT_LIST |= set( + [ + "yuv420p", + "yuv420p10", + "yuv420p12", + "yuv420p16be", + "yuv420p16le", + "yuv422p", + "yuv422p10", + "yuv422p12", + "yuv422p16be", + "yuv422p16le", + "yuv444p", + "yuv444p10", + "yuv444p12", + "yuv444p16be", + "yuv444p16le", + "yuv411p", + "yuv410p", + "yuyv422", + "uyvy422", + "rgb24", + "bgr24", + "rgb8", + "bgr8", + "rgb444be", + "rgb444le", + "bgr444be", + "bgr444le", + # 'nv12', # Encoding not different than yuv420p? + # 'nv21', # Encoding not different than yuv420p? + "gbrp", + "gbrp9be", + "gbrp9le", + "gbrp10be", + "gbrp10le", + "gbrp12be", + "gbrp12le", + "gbrp14be", + "gbrp14le", + "gbrp16be", + "gbrp16le", + ] + ) + +FORMATS = keyed_combiner("format", list(FORMAT_LIST)) + +RANGE = keyed_combiner("range", ["tv", "pc"]) + +CSPACE_LIST = set( + [ + "bt709", + # 'bt2020', + ] +) + +if "--all" in ARGS: + CSPACE_LIST |= set( + [ + "bt709", + "bt2020", + "bt601-6-525", # aka smpte170m NTSC + "bt601-6-625", # aka bt470bg PAL + ] + ) +CSPACE_LIST = list(CSPACE_LIST) + +# - + +COMBOS = cross_combine( + WEBM + MP4 + OGG, + FORMATS, + RANGE, + keyed_combiner("src_cspace", CSPACE_LIST), + keyed_combiner("dst_cspace", CSPACE_LIST), +) + +# - + +print(f"{len(COMBOS)} combinations...") + +todo = [] +for c in COMBOS: + dst_name = ".".join( + [ + SRC_PATH.name, + c["src_cspace"], + c["dst_cspace"], + c["range"], + c["format"], + c["vcodec"], + c["ext"], + ] + ) + + src_cspace = c["src_cspace"] + + vf = f"scale=out_range={c['range']}" + vf += f",colorspace=all={c['dst_cspace']}" + vf += f":iall={src_cspace}" + args = [ + "ffmpeg", + "-y", + # For input: + "-color_primaries", + src_cspace, + "-color_trc", + src_cspace, + "-colorspace", + src_cspace, + "-i", + SRC_PATH.as_posix(), + # For output: + "-bitexact", # E.g. don't use true random uuids + "-vf", + vf, + "-pix_fmt", + c["format"], + "-vcodec", + c["vcodec"], + "-crf", + "1", # Not-quite-lossless + (DIR / dst_name).as_posix(), + ] + if "-v" in ARGS or "-vv" in ARGS: + print("$ " + " ".join(args)) + else: + print(" " + args[-1]) + + todo.append(args) + +# - + +with open(DIR / "reftest.list", "r") as f: + reftest_list_text = f.read() + +for args in todo: + vid_name = pathlib.Path(args[-1]).name + if vid_name not in reftest_list_text: + print(f"WARNING: Not in reftest.list: {vid_name}") + +# - + +if "--write" not in ARGS: + print("Use --write to write. Exiting...") + exit(0) + +# - + + +def run_cmd(args): + dest = None + if "-vv" not in ARGS: + dest = subprocess.DEVNULL + try: + subprocess.run(args, stderr=dest) + except FileNotFoundError: + print("FileNotFoundError, is ffmpeg not in your PATH?") + raise + + +with concurrent.futures.ThreadPoolExecutor() as pool: + fs = [] + for cur_args in todo: + f = pool.submit(run_cmd, cur_args) + fs.append(f) + + done = 0 + for f in concurrent.futures.as_completed(fs): + f.result() # Raise if it raised + done += 1 + sys.stdout.write(f"\rEncoded {done}/{len(todo)}") diff --git a/dom/media/test/reftest/generateREF.html b/dom/media/test/reftest/generateREF.html new file mode 100644 index 0000000000..4e26066973 --- /dev/null +++ b/dom/media/test/reftest/generateREF.html @@ -0,0 +1,104 @@ +<!DOCTYPE HTML> +<html> +<head> +<script type="application/javascript"> +</script> +</head> +<body> +<p id="out"></p> +<video id="v1" style="position:absolute; left:0; top:0"></video> +<canvas id="canvas"></canvas> +<script type="application/javascript"> +// READ ME FIRST. +// The script is trying to make a reftest sample for reftest. + +// STEP1. Uncomment the method below that you want to use. If you want to dump +// Nth frame, modify the parameter to the number of frame you want to dump. +//window.onload = function() { setTimeout(dumpFirstFrame, 0); }; +//window.onload = function() { setTimeout(dumpLastFrame, 0); }; +window.onload = function() { setTimeout(function(){dumpNthFrame(15);}, 0); }; + +// STEP2. Set the source of video that you want to capture +const videoSrc = ''; + +// STEP3. Ensure the pref `media.seekToNextFrame.enabled` is on +// STEP4. In a terminal, navigate to the containing folder and start a server with "python -m SimpleHTTPServer 8000" +// STEP5. Open "http://localhost:8000/generateREF.html" in the browser +// STEP6. Copy the base64 image url to your xxx-ref.html + +function drawVideoToInnerHTML(v) { + // This allows to dump content via canvas when the source is cross-origin. + v.crossorigin = "anonymous"; + var canvas = document.getElementById("canvas"); + canvas.width = v.videoWidth; + canvas.height = v.videoHeight; + var ctx = canvas.getContext("2d"); + ctx.drawImage(v, 0, 0, v.videoWidth, v.videoHeight); + var dataURL = canvas.toDataURL(); + document.getElementById("out").innerHTML=dataURL; +} + +function dumpFirstFrame() { + var video = document.getElementById("v1"); + video.src = videoSrc; + video.preload = "metadata"; + + video.addEventListener("loadeddata", function() { + drawVideoToInnerHTML(video); + }); +} + +function dumpNthFrame(n) { + var video = document.getElementById("v1"); + video.src = videoSrc; + video.preload = "metadata"; + const totalFrames = n; + + function checkNthFrame() { + console.log((totalFrames-n+1)+"th Frame time is " + video.currentTime); + n--; + if (n == 0) { + drawVideoToInnerHTML(video); + } else { + video.seekToNextFrame(); + } + } + video.addEventListener("loadeddata", checkNthFrame); + video.addEventListener("seeked", checkNthFrame); +} + +function dumpLastFrame() { + var video = document.getElementById("v1"); + video.src = videoSrc; + video.preload = "metadata"; + video.seenEnded = false; + + // Seek to the end + video.addEventListener("loadeddata", function() { + video.currentTime = video.duration; + video.onseeked = () => { + video.onseeked = null; + callSeekToNextFrame(); + }; + }); + + function callSeekToNextFrame() { + video.seekToNextFrame().then( + () => { + if (!video.seenEnded) + callSeekToNextFrame(); + }, + () => { + // Reach the end, do nothing. + } + ); + } + + video.addEventListener("ended", function() { + video.seenEnded = true; + drawVideoToInnerHTML(video); + }); +} +</script> +</body> +</html> diff --git a/dom/media/test/reftest/gizmo.mp4.55thframe-ref.html b/dom/media/test/reftest/gizmo.mp4.55thframe-ref.html new file mode 100644 index 0000000000..28a93cc268 --- /dev/null +++ b/dom/media/test/reftest/gizmo.mp4.55thframe-ref.html @@ -0,0 +1,7 @@ +<!DOCTYPE HTML> +<img style="position:absolute; left:0; top:0" +src=" + +data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjAAAAFACAYAAACiO0YzAAAgAElEQVR4nOy9V1cb+b73+SdJIkoCFBEKSKCcc86AAsFgnLPbdnfb7ZxT226789ln7/M85zzPM7PWrDU38wLmatbczEv7zkWpFEpVKkkFxr23Lz7LygUGVB/9Iqk553Gc1F0Lgqi6hSH0+ELZci8KQvjXID9mjv9ncNwI+fupuOax6ZAPTdWx0JNNm7wnG3ZhlG1zPSlZZzmQDkVxba6D/JqMldyqtC+yljlhmGWsZFbm+iK1ImMlYabIrHSTNkmRNs0iaZxBol9MU+wY51iJmSgSxjnEDLOIchAzzCKqn+lJZHm663oT3WwX4aXpHkwivDSJoG4aQd00/A2CDNqfE9JOtV2fRXhpFsElKYJLUgS0M/BrpuHXTA6EVyvuwN/Ao5Gw4lN34lVNduBWizlxKUWcOFQUNpVkKKxKUQcOBYVdSeFQSBpMwaGYgnVxgoG4A3sD5u1ckK8C89cWGOEC9FVgjpuvAvNVYI5DYNKmWSSMM0iaZnn5KjBfBearwHyBAnPcEZDjFpgtz7wghArMcX//xy0vXwXmq8B8boGhJIYSmH7kJWmaRXJluoPDFBg+mALTydyxCwwlMZ9XYHzqqQ6+CswxCchxCkzNc8zy8CUgUGAEc9zfv0DBOQwR+iowf12BEcpfVWCamKSsxFcokiZph9B00YfA9I7QzHXRW2j+mgLjVYnhVYmHEpheQvOXF5jjFhDBn149i4I47hPksXPMAiP053/s/3+HIDBChOavLjAbdmlPuOVGhrJNJlhgClY5K1xic9ii81Vgjl5gOmiknkLLswgtzyK4PMsrMJ2wC0xgaYoTPoHxLUkQaODVTrJCi4tfM8kqMFzi86ULjF0hafKXFBihJ47DEJhtr2JohH79Qo59OCwI4rgjMEK//+MWHzb5GVRghMAnMHwct8AMClNomOJSss0PJDGCozAWOStcYsMUHKECkzLP8fIlCAy30AgXmGDjcjv04zujL90CE9TNDi0wviVJk88pMO041eLPKjD07U2+dIE56jd/IfJSP3Z5+BIQJjCCBegLF8DjFhi+v6+qe0GQwNSciz35KjBfpsDQEjOswDQFiEVY0hYZ0hZZh8CkTdMcSDtgkxmuOpl+YQpMzDCLhJ5GivjyXBNeoRlQYPgiMP0IDDsSVrhSTu0CQzHdAZfA8EmMcIHphBYWWkp4BaYN6+IE7A26U03sCBYYoScYwW/+XoUgjl8gjpvjFZjj//6PX3S+CsxfV2CEIkRgsmYZ0pZ5VpINsmZ2/koCwxaVaReYdmIGKavEtGh0MunnENHPIWSY4xWYziiOFBGdFCGdvCkwFN1pKJrjFpheQuNsMKzA2FRTxyswO+5FCEGowOx6FgRxGCfwHd/isXHcAnHCuygIoeIy/M9ecSgclsAIEWg+oaFQsFJ10wxXyL7pVmDDtYiKc3A2HQvYHFJi6BqafmttOLFLB2LDNtdB2TbPSmlNjuKq7Mg5bIFJMuATGP4ozwyFeQoZ8xTSpskG7ALDFJleYtMuN5wpJtNcz66lhGG6g5hhGlH9VA8kiOoliBimEDFMIWSgJIYWGhrudFRLYEI6OULL0oEEJqSlkSCklSCilSC6NNmkdX8nQc0kgppJhLQzCGqmm3i1FHzi09mCLW7ibErM5FA4VJIOXMpO6JRSK7U0zqBTYJiP50OQwOx6+D95fukCc5zy8iUgVGCGP7YSOz6lYIE54VUKovV7oGTlOASGHSUrNY9SsMBsuttFqBs+iTkMgRm2iFiowGzYFzr4VxIY+jV6HT+zMoOsZe7YBYbZlt1LYJgct8CwFwdT3VBRBp9DYNpxaSRHKjBMifniBEZoBECowOz6lYI4boEQ+vUL5fgEpvH9C/z5C/36hf4eCI3Y9J+OYheYLbeSMzrTD73EpR+BqToWeNNQQlJUn0tgyg1KtvnBGLKdu12QChYpChY5ChY5iqvzKK7ON6/nzTJWWhLTEJLVBVZyFnbo129KC8d8m3aByVraIzGHKzB8KSSu+5LGGV6B6WQSMcMkosZpRI3TCBulvALTkYJaliG6LENEP98UGIruNFSzzqYPgaGvcxcCU6miZtdTA98SRa+W7V4CQ6eUhhUYuoaGptfMGZfyCxOYHTeVQuj9Bv9lC8y/OnsCESowQo9/3AIzTLTmMAWm7lL0lBs+WhGc4RAiL4chMFXHYHQJDUNg1h2KwURGgMDQEsMmMEyRYQpNK3KygPzq4pEJTOv6TIfANFNLHEXCdDEx8zoTobUySeNMBwnjzMACEzZKETV0EjNw1NO0CQyF7IsXmF5CQ9fFCBGYdon57AIjvIagt6AcdQrjuAVAKPsB1bGy518cmv2AArv+RUEc7/fO//MZRGCGRUhBcKuQfliB4e/W6zkMUqDA8IkMt7jQjxEmMJsOBTYdCqy38TkFpsUCSmsLXQLDRd4sawpIfm0eWQ5aosIuMC2kPcmbZ5A3t0dgqDbs1kyawQSGvp0rMsMUm27RoWQlaZziYYaRZppEoiExMcMkp7hwCgwdmdHLmvAJDFtxMN0NFdNRMAfsddXRNISl2fXEEJhBWrjZBMalmRoKZ1shsEMlgltJQQuLmwFTYNqjN3bleNfz+RAkMCe8St4oy1ELzF5AJQjBEQyBxz8Iqo8N6kSuGEpcaPYEcuwCJ/j3QH3oDFqHs+VexLZHNRRCBUZI+qruUnyxAtM3Q3ZD0XU2wwpMU2TW5nsKTPNxq4sddL9WZ21Ot8TMomCZbUZijlNgKGab3VF8AtMJdTu9CiFmlPEKDPO2mEGKqEHeITHMFFQ7X5rAdM6jmfysAtMuLEyOTWDYP6nyffLsL4Vw1AJz2CfCQY/LLxpaHg5DYlQdUvJ5+TIEZniJGVZUOp+/52vRbwHyrkcxcOqKLZUlRGC2nYqeDCoyNHUHBX/khhKTmr03TJGp2eWo2qQouBZQcC00O6poodl0KLDRSCkxoeRFQdElJr1XI3C1da+vMZFjvU1w1hl0R3DYKa/KUGYpHua6nVtg6EjMHPLmOeRWKLhqdPqdJNwOLUXs0LU0tLhwkzTOIG2YYoVNYGJGGRIcsMkLhbwBX9s2+2A9WlxoaKHhmgAc0s4gpJ1BeGmWKuRttG8zBYZ+HE1QM91xmS4G/twCQ3c9tSYAjzfoLP51N2ArBmajS2AG7eLgExi+N3A+gTlscfgqMIcjMAdB5SFxfBGog6D6ECJ0hy8wTOi/Nbb7DkNg+OglN0IFpuZcFCQwzXk5PNCPYwpPL4FhRmY6UWHdoeKcazPo/JoNK8VhC0z74wcRGC6RoQWmXVa601H9d1H1LzP9C0zaNIuMabrJcQsMG/HlGVaB4Zog3C4w4aXZpsD4GxIjRGC82km4tdMDQ0mMpENimKLylxCYYbpraEE58Kt4UPREuHwMFzk4vBP4l8LgJ/9TIc1f4OvuLYB9yWkvye4hHj3pQ94HK2Iero2cezwBXWSvYqWjkN+10IKWl8Z1rnk2rWF9DWFxqRpQ97cEaKHjcUxhYd7ejaxB43kMMeLbDcUUGibNpZQOGinKDu7BfCX7HEr2ltDQ4jI889iwts+wYUR4eASHuRuKDTp91A4tMmzy0o/ADBupYQ7do9YidHc99YrOUMW+ww7RYxea/sWFZqZJh8BwiAzdTs0UmMDSVLM4mKsFu1dbNlNkmLClnCio9m2uQXnts2bacasnGtB7mXoLSq/2bJdSAsJ8Qxv0jfioBeZUUNkT4RGIL1tgToVUnwnNkAg/9pcuMD3xa4ZjEEnqS2KOT2A6ZKZNYHbaCo1pEelHYDojMPMDCUy3MMkbUMdnRoZ6TSauOhZQcSq76JQYKnKz7qSRY93JPWG4S3COUWCKq52TiQeRmcMSmEEWV3IJTHstzWELTLfIHL7AxJdneAWmtRW7U2C4tmf3KzFHITDt27OPXGAGTdkMnFrhKQTli7ActcAct1gIP45iSL4cgTla+env53/cNTyHFZEZWH588x3seuTY9cix7aXYc6uw5+YWmBOubnacC83L1MZxeVvdDFcbthI1p7JNJHrTTA91paW41i50RnZomCmrdmp29i4rOjpTa5+J05SgOVRcc9h0SllhCgw9m6ZiZSJDRbDc9N7WzbZaoV+BKZnlPeESmy7RabRrpxukzDMMei+a5FtW2VUb09zCzexm6iZhmG7e32rDpkWGeb2/7dlMceEUGBaRad/F1IJZLzPZAT3xtxtKYujUk29J0rEh288FQ2RoYeGa+Nu9f+kvJjBcJxb6BMAnKP/sAiOc4xGY02EtToe1x/79H7XACH39oxYcoSLEFBianQb7HjX2PWqc8Hay61FQEuNc6Am9dbxdYGoeZZNWRKa3wDD3RH0OgWm/v6M+p61+5zAEZtMuRdXGRI7qsOsVGmxYuXdAcQlMv0JTXp1HySxHeXWelWEFphtZ126mYQWmQ2a6upnYhSfRxVyH+HDtauIioZ9lFZionkNiWCYBtwtM99LJ4QWmncMQmPY27SMTmEFTJd2fPHt/MuV+41/EQXARp3jhkZihIwdfRgSBj9NhdW8iSmHwvf5RHz+iFCBhbCI2mJgJFdXDKiY+7A8O/UsRFREdVGDo2hdOeWmmleax455vK/ylxIWeQ1N1qRpoUHVpUHfJO2pWaDFoiohT1oASmFatjaIx1I9rnxR1/45b2UFH/Q4LfAXI3AIzy4ASmPUGdM1N12qFprgsdFBtULfKWanaOqFfr9ciy34EhlNomsXAneLCNYCPa+4MPTSvH4Fho6uN2yhFztQtO0xRaaWcGMW/RopmuqnxvG6RYQoM1+A8riWUs10C01w02VNkpAwYgrPcLTHtBHU09I4maokkU2ACvSRGK+ZMNTHFhU9g3KrJntAD87juH1hguj95Dnt/fwJzJqTqyXEJjOATf4OvAiNUfoQJjHDJ5BOkL1dg2FK8wwjMtmO+CS0wtAC0CwzV1aRC3atqDdJzqzsEho7Y0CJCt3HTIrLtkjdYaNbZsAkM1yTjwxSYukshWGDoGppmWspOUbUrOqg12LIvsFJjQM/QaRYZD7GpW4jA8NPYBdWY9JtpMKjAtLqZKHIm2aEJTLrxnH4EpjvVxC8w7SLTK+0U1c8MJDCtluzeAkNJjARB3ST8y5NdAtMLvloZ7m3Yoi9FYNiFpAX9CZb9kzP9uDOhhQYKDo5WYI79BH7Mxz8T1Qjin11g+AX0cARmWMERKkO0uJz0UdASs+2n4E4hqbDTtodp20lFN2puNQWdIvIuNNn2LTYFpu7VoO7VoOJRNhdKbroVXQLTiqZQxbgtgZFixy1rClJLeOZRo1+DjcbjWDuoBhCYZh1PI4K06dZg061pCVyb1G075lF3KFF3KFGzaVCzaVC1q1C1q7DpoGF2OKk6qNo1qNo12LKpsGVToWanoAWHfh5TfNpbvJlt28wIzUARGXoNglXOSn5N1hdMgelG3qfAUJEYej4NW7opaZrtui5cYNgZRGAS+t51M50CwwFL1KZXJKZdaGiJoS8PQr+rCzwaEQPJ8QgMdw1CS146Q/u9UwBCBYauxRie4xGIM1EVzkT5T5D8EqESiDCBEX58YfD/jI7458/z+sIjhIcrQt2y01lMvx+gJjPvBBax7Z/HSZ8WJ33aDnFhCgwd2dj1tMSEFpVt32KTnYAS2z41tn3qDoFpp5fAbHnmm8JCyUu3wNCy1K/A8NFrh1TNoxxYYOoOLeoOLWoONWoONSpONafAVJzqJjWH9tAFZsMq47yfN0rT6GQSKjC0xPQSGCZsAsPsbuKrnWnV0HRCCxCz6ynZJjNMessMc3dTi3aB4S8CZh+M17yNowi4H4Fh43MIDMVUT+iBeVz3E+HFqcPWJtACIwyhJ6CzQ3IuosG5iAZnw8qhOBdR4VxExfs4PoE4F1E0UA2JRiDDHvewjs/HUk+OWmD65TAjjcNEdprjDXxa7LUJy06DiteEiteEnM+PnM+PkseGkseGTY8Wmx4ttZjSp0Tdp6PwqxssYiugRN0/j7p/HhWfBhWfBnWvHHWvHBv+Baz75lHxUrREQ40tt5rat+Shamm2XfKmuGx7lrDtWWoO8qOft+3RYNujaQmQR9bJoQkMld6iI0e0yOw7p7HvnMauYwYnnLPYdcxg1zGDHZcU2465ptA0i5YbbdnrDgU2XEoUXToUXTpk3BZkPauIeb2Ieb2IuN0dxNx2xNx2JF2rSLpWkXUZkHUZUHAuoeBcahu0t9Cgc+AeXVvDvH3QVQhcAtMlNDYaaSeMSAwn7YsnWeDa1t1dK8Nkpi9a27dpGK3ZnDIzuMD07mriatHmqaHhERwuiaGLfgeOzLTVy/jUIhboWpkvXGC4Q+/U44YVABqhJ6DjP4H35p9dYM5HlwTxVWCE193s+Vs7zdpbpU941dj1a7Hr16LqW0HVt4K8P4Ccz4+y146y1451twabHi22fcq+BKbq17IKzKZbjop3vpkqogWGFoUd93xjRk2jzduzhB2vrm2qcGN2DY/A0I+nB3cKFRg6ckSnzk66ZnDSRclLOzsuKUUjQkPPvaFny9ATfgvOJRRdOuS8ayj4rEgFAoj7fIh6PAg7nU0iTisiTisSTjMSTnNTYPIODfIODcp2alpw+7wapsAwIzTDCAzXkstBBYYrtXRYAsM9b0a4wKR7RmW4BaZdZPi6lwYRmEFEJrw0icjyNEINmBLDJTjDiAyzm+mLEBj+N/beqZfjF5hhT7yaQ0HwCT6mGo7G8S/EtRQx3cBQX4MwiTlugeF7Pn80TntI9D6O8GLjbg6CSpwIUdGTvMeEvMeEsCeAsCcAp78IT7AMS2Qblsg2dNET0EVPQB8/B338HEzhEzAEd+D1JeH1JRH3O5AIOFH16VHxLqPqV6IWUGPHr8ZuUNOssVkP6FD2L6HmVaHuV6MYkqEQlKLqlqLmkTXbm2nhqHhnUPPNouKXohqQoe6noGt06p4l1D1LTYGpe0yoe0xtC2XlDDpXKbRSUuxwFQW3t4LXPErU3DrU3DqccMtwwi3DtkvKSt3doFGUvOGi5IUWj6TLhKTLhIA3gpA/BlN4H4bgCWj8O9D4d6AIbkER3IImsAWVtwqjex1G9zqsjiSsjiQCjgCCziBSjlWkndaugXvMlQn0UsrulQi9ZYYeoNc9SG+eZVFlu8xIUbC2BKZglSLfa/ZMH/uZ2lccFFcoeq0uoFNNVLpoBrl+JKZtNUGGRWS4U0v8ApMcoBW7W2R4amf6lJgQQ2L6TTkNLTHNYt+/uMAcdYSCj8MSkaPjyxWYCzEdLsS1R/v9CWa5J0edouoXPoERHimiI5+df7974SXUPIvIOJaRcxvhtbngs7th9+ThDpSwEqpjJVSHNrxDETqAOngSGncFi7YSzKterK754LevIOK2ouzSNgWmHtJgN0hx4Fc0BWYzqMdWQIutgBbFkAyl8Dx2AlTdDV1Ls+tfxF5AgZpvtikw9dACtkML2Aq2Hr/t01Ecg8DUvaqeAtNMd7VdbheYLfciKh41NlxK5B0aZK0qRGw6RGw6uOw+uOw+aNw1aD11aPw70AZ3oQptQxXahtpXg9JTgc5RhNaaw8pqGIaVIGwmO9yrHiTtlr4Eho780LeziQwbm7aFngLTJTRNZCjZZCjYGzSEph+B6WfhZKkBM0LDVStDiw89j4YLWnS6hYfa28RdK9O5RTvdRkcUZqB1Bq3al36G5/UjMSEGn0tg6Im+XNB7l7juJ3yha5p+31ibchBZouAQB1pgLkRUPbkY1fRE+AluuBNv88QvEN7j8AqEWiBCvweBxx1WnDqiQMMLjNAI2eHV6vQ+zmEJDJNKxIq8xwDnmgMry0borBks23KQe89gMXAekshNTEZvYTx2G2PR7zEeuw2yegZEXQFZqoFoN0H0W1iwhKBciyDjNqLgN6MWVKIeUmEvsIz9oB6n/SqcCahRjGhQjGiwFVBjK6BGKGpEJLaCXMyPXMyPgs+NlMOKrMeKgs+OeECPRNCARHgFqegqchEz0iFjU4To1BYtKDW3HTW3HdteaYNOgaFreprLZpt74LhWKvAswXSvouayoOJyoeJyIeoLIeoLIRwMIhQIIBoIIhoIIh7wIx7wo+LWo+LWY9OjRcW7hJJXj6JnGTGXCRG7AS6rE841B3TWDHTWDETOM5jyXIAoeBXi8HWMxm9hNH4LY9FvQQLXQTyXQNwXIHHugaxUIV/NQu1ah8/pQMDjptYasKxK2HCqseFUdwlMO70FRt7sZKLatRc66JYYRjEwLTINgeEcnNfHwsl2mWkKDEsKKstIM/UjMK3t21wCQ8HVtj28wPS7VLLf2pnecsMUmP7nyfSGU2YOKwLTr7hwvfFyRjd4BIbuIjlugTksETkyjlhgLiaWBHHcAsOPvidHHiHrOxV2eJHGjg8SbbexsRFaRda1DJt5DSadAWpzEprVFGadJyHznIYoeB2SyE2Mx25jNPwdiP0CSPAmRMHrGPFehth+GnO+S1gNl2GLV7AetqEUXOsSmDMBNc4GNdhI6FCKarEVUKPuVyIQ0sMfXEbUY0Pc70Ap4EM9EcNWKoyNiBcx/zLiAT3iIRMS4RVkwytNgVkP6FDzW1DzW7DrX8SufxFbPldTYHZ8MkpaGjNtjkJgtj1r2PasoeZ2o+JyIe4PI+4PIxIKUfgDFD4von4fKm496j4jqn4dKt4lrPuNqITMSHlXEbIuw7nmgHVlFdq1NHTWDKY8FzDju4SJwBXMZ3/AYvU5FqvPsbDxHNPZ+5hKfIfx0HXM+c5AGjiLJV8FS74KAh43gl4PNlzzPQWGTmGxCUwv6DkzQgWGlhjOuTOHKDB0rQw9TO8oBaYlMdwC0y4yfALDLTKDFAD3EJkGoeVpRPqI3HDVzPTf0URNABYcgem322bY0DrfGzafoFyKaXsi9AR3aWgaxz9mgbmY0AwJJSCX4zTLrFxMcMGUmWGPz37cfvlnERi+yKDgdvfGB4qDmAYHsdbt2ZAPQZsFap0NqiUrJg15zK6UMWE/C4n7Ikb9tyAK38F0/jk0Oz9jYec3GC/8FyyX/ifUe39CVf87FJW/wbL5Ddaqt5AvpBGPh7EeNGIjZEI1uIqtsBWV2BoqsTUU4gbkosvIhrRIepVYCpSh9hWgjl6EpfAd3LWX2Pjmv6Nw8Q9ETvyIldxZKIJbUPvLUPvLMPiy0HszcHvC8AVi2AzYsBmwNbun9rxG7LqXcdIjxYFXhpNuFQ48apz2KHHgUuDAraPwqHHgUWPPrcCeWwHmEstmSooWFRa23IuIeYMIO70w+6tYDdahjF6EOnYJ2sR1aOLXoI5fgDF/A5r0Fcz5T0LuqmBmrYh5SwIKaxpeuwVeuwXGFQsUag3mtA7IdG6M6goQGcsgqweYcF0ACd8ESd4BST3AaP4ppusfsXDyTywe/ImZrY+QbT7FdOkB5pOnII3uY83vx5rfj7RbhYxHjaJbiaK7tZByw0VRcS6yCgotOhUWqMd0DuKjNnO3JgczdzKxFQGX21JKvebN8C2kpAbqtSixpJZokek1EZgNZo0NU3gyKzMcu5waIrMi66Bz3UGbxDSRd9FLZFrXBUZiGPSbfupn1gx7F1NjjYF2pgPf0gyv1HQIjNDQN3/ovvcb9HELzPAnT+rELzyC0VtguAWC5l9bYHj/f+KGnhy1YB6WwJyNLbHCJy7Nx3AITMRpxapWCfGUEpJpNYgiCok+h3HbGUx5LmEydhey7BMoah9gOPgTvjv/F0wX/wdUJ/6Acvd3KCp/w1zhF+hyF6DNnEciGUEiGUElasZmeAX10BrqoTWUw2asRyzIRnRIBtRIepWIuRcoefEVoE9dh7NyH/7ttwjuvoN78ymshfvQJU5C5t7AzFoCElMYE8o1SNQ2aHUrMJnt2AzYUAnaOwTmhEePA6+MoiEqpz1KSmIYArPvVWLfS2/0Xmx2Y9H/cgkM3b7tsdhgN1igteZg8mxgMXwe6tglaOLXsJT6BkupK5gPnobYsQWiL4AogyByDyZUbkwvB7FmXIJRq4BCrcGCQoVJxRqmlFYQbZYSmLVTlMBEbmEk9QNI4h5Gck8wu/0LFKf+HYsHf0K6+wvk1WeYLj3AQupMh8CkXApkPGqUPSqUPapmu3e7wLBB73xiLt9snzy86ZC3SU3nHJquvUxdaSgqUkMLDN+8GT7KDIlhRmiOSmDYdjkdh8D0WzvDJTfDCky/MtMdjeEWmEEk5ggFZvhak8+ZommdwIeD+4R+OFxO6nnQCUPg9385rhGI0OMLgxlRG1iQBQoOM7J3OOmo7r/LUzET9iN6bISsyDiW4bdZYDMsQaYwYEqmAZldA1lwgSyXMGrcALFfgMhzDeLYXcxln0Be+wjdqb9Be/6/QXXmH1g49Q9I9/7E3NZbzNRfQ7bxAHPle9DlzkCVPIm1YBp6ZxgebwZeXxZOfx7uQAGWYBaroRwWVl2Y0q1AYi1izl3BqP86JNHvMJJ4gbH0a5D0I5DEfRDnFRDzGRDTPohxD0RXAVmugqxsgNi3sRF0Yz3gwr5Hj5NeY1NQTnsWGzTEhRYZtxan3VoceJQ48CjbpgsrccKrbA7dq/spNv26Jhu+JZS8RhQ9BkScdngtKzAY3dAbnBBZKph17kIUvIXZxF1MpV9gOvMSJHYPxH0dxH6JwnQSxHIaksAFTAYvYs2yDa26gOlFDyRyJyYWTBArLSCaIEZ0EYysnYTEfR6joVuYTN4FST3BaP4lpmu/Q3vuf0FS+RmSys8QbbzFaOklxtPfgCSuYiGyCWmgBLPPD2s4gpDPiZDPiaLHgKLH0Ewhda1CaFzvWpXARdvz+q2foTucenU7DSowNOsNmaHFhW7LzjZob9POr/XubGLrcmqn/X6m0HTtaOoBW1opbZKzkjTIkDTIeorLIAIjOHLDmAgcayPatSm7m5B2poNuoZmCryE7bEPy+haYXm+W/YkMu3QIVT4AACAASURBVJwMIizDRDC+CkxvriQEktQKQ+DxvwpMb+go0KmYCbuBJSRtSwgY5mHWKqGVz0I0o8TknBpk0Y0RhRdEX4bIUsOI4yIm3Fchjt2FNPcUc5vvIK28h6TygaL2CZLaJ8h23mG69qopMOrUAeThbRjdUahXvVgxB7BmjcBsj2PFGoPGGoRy1Y9JrQkTKj2ILopxSxbEexWiyLcg8eeUwOSfYaT0EqTwFIrTf2B25z3Gy88gyt+FuHAPstwNyHI3sBF0o+x3YM+9jD33Mk66lnDStYQD9wKFS9FTYFpzbxRNgdkJKLHVoBLQoxo0oB42YitiQi1iRT1qQ8rvhX/VArVmDSq1BURfhMhSwYjnOmYTdzGdeQlR/AlI9C6UO5/gvPpf8N3836Ddfg9F5TUs28+h33wIl2Mf5pUalIY45pfCECnMlMBoQxCZkiCr+x0CM5p/ibHCK0yUP0G0/jMmyj9RrL+hyN4ESVyFNFDCtDsHvdMNg9sDv9uKgMeOgkuPosfQnBzcjKwMITDM5w0iMHxyw0w1cXY3DSkwNIPU1/SSm055mRlIYNglhl1gaInpR2AOQ2aECEysY0s2F7MdBHWznALDJjHkMOadCJOIXgWm/KmI4U9enamgoREaAeETjNRyTy4ntYI4doERiPAojMAUFV+KkFdg9B0cdkqKfs6ZxCrqXg185iU49SqoNUYsKJZA5E6QRTeINgOynAMx72LEcRrE8w1GQ99hPHEPU7knmFh/g8nae0zsfIRk/xfM7H3CzN4nzG+9x9zma8g2HmG2eA8TkdMg/hMQOXIglgRmTCGMqZ2YmlvEmHgWZGwWIxNSkCkTxmRWEHkERJfDiOMsZsLfYDb/HIubP4KU3mBi51dIL/4PRD/9fzA++r8hvfp/Qn7xf8fkyf8GeeUNZssv4YwkYA/FkHT7kPL4UfDYUPTZUfQbUPQbUPGsoua3YdtrxLbXiBNuG4VnBXteC7bdJmy7Tdh1G3DCY0TNv4atoA3VEEUp7MFm3I/1eBAbiTCKiSjy8Qj8wTiMKzaI5SsQyUwg+hLG1uognmuYTN7FeO4tRIV3GK98guri/0Ly7f+D1I//L3QX/yeUp/8Dur0PWKy+hC1yCwbXRSzaNjFjzGF0yY/RJT+IMQ2xfR0j5i1Me85gLPwdplL3MZZ9BlHxJSaKP2Gi+BNGix8wUf6E8Y2PGN/4CJK9D5K4AxI6C+LcxYgjjzFXEXpnEKuBBNKeVWR9a80Jyq11DfSep4Vmizd9mdoMvthBU2CaQqPsoN9i4P7nz/QuCm5Gbjjnz1Cw1c8Ik5j2gmAZSwSGnkkzj8wK9S99mWKu2YpNwV7oO0z79WFIDH8UpnPFAVNgIrwS0y0w7QTa5IUNwtc2evTpnv5lpSkt7SdhgScuwRGAYxaYK6klQVxLLQtk6VgRHqU5WoHhe/7luKGDw+zAuphoFTmfSayi5lYj6liBU6+CTm+ByWzHhDYIiS4CYihSrO1j1HUGI4FvMRG5g6ncEyxW30K29yvm93/DzKnfMXPqd8hO/Y7pEx8xu/EK0+svIV1/iMncHYwG90FcdYxa0yArMUwbgyAiDQiZACGkgRhEYqAEZj4KosuB2E5D4r+CydRjzBVegJTfQrT7G0Z2f4fo5N9Aqr+D7P4d47v/DlL9DZP5J5hIP4Q1EIHZE0DE5kTE5kTKvoKscxU5tw55zzI23RZKYtx61Nx67LqsFG4TTnhWsB9Yw35gDQcBC/Z9ZmwFbdgK2lAJWlEJWrEe8SLrtSHusiLussK7ZoFVvwS1xog5mRJkUovxWQOIoQyRfRvEcw3i2B1M5H/E9MYnjG5+xMj6T5je/g2S2ieIN3/CzNavWKy+xFzpCYyey9BYz0C6UsSsKY8pcxxT5jjGV4uYdlW7BGYk8xTi0itI1n/G5MYvkFR+hXjjl5bA5B6CJH8AiZwDce9h3F2CxL8JszcKiz/OKTBbzcWcLYFpl5i6S3GoArNhlw8UrSnb5js6nHo9jm3+DJvADCox7GLTWVPTjMR0DdGb76JdYJgRm35FZhCBGUZkBhGYqH6OVWDaCS9Nd1zmExhqY/YAAnPYNSb8b/ADCgsTgZ/Ah44kHLvAMGQkrRmMpsDQ/DUFpikyw0ZxEvqe8AoIz8+PN0U4oDANKzOn4xZUXSq4TEtYW1JgUWWCWreGUX0aEys5kNUtEEsdxHsBI8ErIJEfMJq4j9H0fUyvv8Tc1jvMbb3DDE39HSY330BefEGlmJL3MR29A0ngDMbdJzHlKEO0mofUFAeZd0A0owUZl4OQSYoxLcblNpDFCMhyDqO2M5j0XsZU/AFmU09Ayj9Csv0rSP1XkMonkO1/Bzn5nxDt/QOjW39iZvMdptbfYjG4A5mvBp2rAI09h6XVCJatMZidIay6I7B5wnAHE4iEE4jH00jG8khEckhGUkjH0k1y0STSwRicniysjiScniwc7jQMjgLm9WEojUHMKOwgRA5CZkDILAiZB5lawei8A8RQhti2DeK6gMnoLUzk32Bq/QNGKz+BbLwHKb8GKb+GePM9VYBbeQ1Z8Rmk4XOY9h1AZF/HuK2McdsGRPZNEMcuxt0nQVZ3QTznMBa5g6n0I4xln0BcegFx+SdMbnxq1sCMbH7EyOZHkPxrkOxLkPh3IJEbmA4fQJo4C0ekBEekhILPiYLPiYpHh4pHxzmob9ujwrZH1XU7M1JDRWfme6aaBmnP7rdupl+B4Uo1DUJviZlHcXW+KTC5VUY9DMdEYOZ04H5hrjCgZYZv0m97xOYoBYa5bLJfgekWl5bA9JIYwQIjvM5jAFlhQWgEZfgTMfU8/giJMK6m9RzocDWt+yowQuWGR2CE1iAdt8C0injNTYGxaBawqDJBqbWAaGMYM2ZArLsgjj2QwGVMRL8Bid3DaOI+xjIPMZ59hLHCE0yUn0G0+RKizZcQr7/CRPkFZjOPMZN+hMnIbUwEboI4dkFs2xgzZzBiTEFqikNqikOlc2BetYopqQGjYhXIrAWiRSeIOgFiyDcFZib5GPLcc4xufoCo9glk6zeMn/w7yMF/gZz8T0yc+DtEe//AbPU9RMWXWAzuQO6vQ+vIQ7GahNLoh9Loh9poh9poh9ZohW7FAfOKFaurdqyZXVhdccJqssJmtsFqslKX9Was6oxQaZ1YVFmh1Dig0joxo/ZiTuPD/JIXIpkZ04trEMtXIFm0YkbthFjpxdiCE8S0gSnHLoj7EiajtzCWfQVx8UeMbH7AWO0j5k7+gYUzf4fsxO+Y2/kVisprLGy8hCZzHQuxi5AGdzDprmLSXYfEVcWoaw+jrj0Q73mIItcgTt7HdPYxJgrPIC69gGT9Y1NgxJufmgIzWv4RpPgGk/kHEGXvQZY8B2niLGzhImzhomCB4YrUDCMww8pNb5HpnkNTWmOJzByaxAwvMBmWlQeDi0xnF9NhR2z4BYd9N1MvielE2pfAcEkMGbRtmQl/EWrvN/SBZIUZdRD0yZsWmGFPjF+GwDTJaAej8bzrTfRDojtWhArMtaShJ0dfRD1YxIdPaNpvp/89H13CQdSEqksFj2kJZqUMcsUyFBojiCaOUVMeI65TGPOexWj4O0zE74Ak74Mk72MkdQ+j6fsYyz3CROEJxIUHEBceYDL7GJPZx5hKP8Fk6jGmo/chCd8FcV8AcZwDWauBrFYwsboNkXUHUusmZLYKZGvrkK6WQZZLGDGsgxjqIOZdEOdVquYm9RhThZeYWH+Dma2PmNn5HfKTf8Pk/n9gcv8/IDvxd8hO/B2zG68wnn0EYjsNYj2F0ZUqyPI6lY5aLoBokyCaBIgqRKH0UyiCIMoQiCZMofKCKFwgC1YQpR1EHQXRxkGWMyC6FIi2ALJcAtFmMGoqY862gVnrOmat65i0FCE2FSA2FSCyblEC47mAyegNjGSeQ1R4DVL5gNH6J8yc/APys3+HdO93zOz+ClntNaTVVxDn72AsdQskfBHEcwrEdQrEeUD9HzrPYyz3CGO5RyCFpxgtPcd4+RUm1t9gfOMDxNWPGKv+jLHqzyC1n0CqHzC+8Q5j6z9iLncPM5kfoEmcgzp+Bp5gEZ5gEWWvG2WvGzW3HnWPoWuuzZZ7kbrOKTBcKNuiM23FvY12a6ECw0w5tebQNLBLKRjt2/TEYK7dTU1JGXIOTWltAaW1habI8G3W5lxXMKDEcEViDruGhldgDFJEDVJE9HOIDCUxUkR0UoSWmcwitDzbNhCPXWK6BIYzxcLBIPLCzgCyMoTAcJ7MDklguAXjcLiWMbKT1TPQDQj1vG8yNMYh0R8rQsTmWmqJV2CupPjgK7IeTGD4hamTXmLTLjD7EWNTYFYUUsgWdVhUGUC0CYjX1jHiOoVx3zmMx25T6wJSDyiJSdzFSOoeSPo+SOoeRlK3MZK6jfHEPYwn7mEy9RiTqceYiT3AdPQ+xoLXMOK7ggn3Hibce5h2nsS08yQWXdtYdG1D4axB7dnGpHUb0w6qYHjcfQ7EdxOi6A9NgRkvv4J480eq02n/3zC5/x+Q7P0Dc9t/w2T1N0iKTzGavg/iOAOydkAJjHETY4YSxo1liIx5TBhymNAnMa5LYEwXwZgugomlGMTLSYyb0hCZs5gwJzBmjGFk2QeicWNMn4bImMXESgFiCyVaRJ0DWcqC6IuYMGQwYchAZMxi1rqORc8O5K4tSOw7kNh3QDwXMB272SEwI7WPmN7/HbIz/46Z3V8xvf0L5iovMVV+hunSPUwV72IycxMTiWsQp25iMv0txLn7mMw/gLj0DOLSM4yXX2BinZIX0cZbiKsfIal9wsTWrxiv/wJS/whS+wkTlfcY33gHaf4+ZrN3mwLjDZXgDZWw7vNg3edhFZiOOTdeNSUxbWLTFaXpuE/ZITH9CAwtMf2mm9olhikw1QaDCgxfUTB/tGZ4gem4TVAU5vgFpgnntuyW1HQKTm+BaU37nWaFXI0voRfXErqeHFY3yaACMfCJiud1rqe1AyI0ctFfBIP/JK4TxM2MXhBfqsD0T++fD1fqjBYU4ZG4TiHiS9l1f4hgCBDjw8eFxDLOxloRGK9xGZZFOeYX9FCoTCA6KnpAnGcx7r2EscQdiFJ3mwJDi8pomkonjWXeYCzzBiT3B0jmd5D8Y6pwNPsYJPMIJPuQIveUIvOQInkHJHkH4sz3kGRvYzz7AGOZ+xjLPMZo6iFI/BlI8gVI+ilI+inGy28wUngFSe0T5k78gZndf0Bc/xPi8ieMFz6ApB+DRO+BeL+hWLsMYrkIsnIGxHwWxLJLYd4AWVmHLHQCxtJVrJQuY3wtDyJ1gCxFQMaWQabMIPIAVY9jqYPYdjHuPoNx9xlMRL+BvPQAC+X7EMe/wUjoAoifKpAljh2QtRpG3Hsg9h0qfeY8B+K7TM1/ST8CWX8LUvkA0fbPmN7/HZLdXzCx9RETtbcY3XyN8c2XGN98idHNDxDXf4Z46x3EW+8wuv0Bo9sfQKrvWlR+BKl+oKj9itHt30G2/wTZ+oOi/jvGqlQ9zGzhPqazd6FLnocmdgb+UAH+UAGbXg82vR7sePXY9ix3TR6mac7FaURiuCI1nMsuG7UxNed8Uy7YGLxehl1cWrCsObDKmhOCW5OC5/tkERvWRZQ5YAoMX9t1u7R0iE3XkslO2ASnXWD6SSHRqabDLfhl39HE13ZNC0wz0sJEP93EvzzJCa/A8HHYYsItGMN90u7/RDacwPBFKL4KzJcuNsIEhn4cVwTtcwsMs76LKTAegw7mBRnk88tYVBpBdAWMmSsgjjMYdV/AaOw2RqLfgyTugSTvQ5x+iMnsY4hyjyEpPoW4+B7i4nuQ/J8tgck/pgQm+xgk/4iCFhj69vRdjGTvQ5K9DXHm+4a8tAlM9GlTYESF1xgpvMJ4+Q3G1t9DXP2IicrvIOVPIKnXFImHIMHbIK5rIKvnQVbOgxjPgRhOghhPgSxXKHQ5EE0aZCULiWsTRB0EmVoFkTookVlwgyi8IPMhirUtEPsJiH3nIfadhyRxC/LSA8hL9zCT+Q6S5HVIktdBPCdBrFsg2hyIOg1irlDXLfsgawcg3hsg4dsg+ZcgpdcYqbzDeP0nTGx9xFjtA8arbyjaBGa88hNGN19jdPM1SPUtReXHFtV3QwnMUuIcAuESAuESKj5fh8Ds+BZZ2fNRw/3aIzFc6xT4aHUyddPZyXR4AtMOJTJHIzDdItO77ZozOtO2q4lPYNiiNGyTftlIrci69jP1gl9wuJdM9lP0G9HP8QpML4khQgeF8dUbHLawdAuMhge+1xdWyyH0RHsju9yTmzljT/iez8etrEEQN46Zo4vM9BbkK6mlRg1Rb4HhF5rBBGZQwbmYWG7UwJhRdWngXjbAvLCIBbkZioVVEH0dxHICxHoeo85LIJ5rGAneBInfxkjqB8ymf4A0cxfSzF3Isvcwl32CuewTSNKvIE69xFj6KcbST6mISPoxRnLPKDKPMZJ5jLEGo6mHGMs8xkj2Pkj6LkjmMUX2OUjqCUjsBUjyFUj6OdVJk3vT4BXG1t9jNP8cJPMUosJbjGReYiz5A0j8NkYj10H8lzDqu4Bx/0WMeC+CWA9AVmsg+hLIchrEkAPRBUEWnSCLVK2LyBLFvK8IonWDqJyN+5wg+gxEq2WIHTuYcu+D+K5Sm59jt0ECN0BSd6k5K97zILaTIKt7INaTIJHrIIEr1M6i+Pcg2acgxVcg5bcg6z+CVN5BtPsLxrY/YKT+rgmp/ghSeUsV4FZaxbhk82eQ6i/Uv5s/g2z+2cFI9U+M1v4NY1t/w2jt30Bqv4NUf8No5TeMbP6K2eITTOUfsQpMxefDjldPwRAXOvKy51M3JWbXo2CN0lDrFjjExjPfpO6S95SY9m4mbhHhjuLwCQwlMZ3ywpZqYmeBJ/XUXRQ8yDwZthUHebMMxRWKLpHpGJY30yUwfCTMMsRXpE0OU2D4djLREZtOiWFfZUAvlgwtT/aEHPYckEFPCEJFgSkszEgJ3/GOu5bjq8B8Pqk5zEgOXQRN//7QtUmD1zkZOxg2IsQmMddSy7icpIbj7YdXUHGq4dItw7KogGJhFcrFNUpgVnZBrOcx7roCcewOxDEq3TOavtslMLOZx5jNPIYk/QqS9CuMZ59RApOh6CUwo6mHlLywCUzyFUXqGUjyKUjmJSUw2ZcguVdNQZqtfMJE/g3EuYcQZR9gOnsHU5nbkKa/w3z2NqTp25iM3oDEewrEug2yWgZZ2wBRukFmzCALayBLHhB9gBKXhTUQ6QqI3E4V9GriIPoMiHkTU+59TMS/h7z8FDP1t5DtfID20t8xf+pX6C78gvm9t5DXX0K19yOUO28wU36E2eorzFZfYaL6AaLaT5jY+hlTe39g8uTvkOz91hQYUv2xA1pgaIlpCgzN5p8glX9r/jtSbUnMSPXPLoGZKz3DVP4RllMXoEue7xKYXZ8Ruz5j3wLDFanpR2C2PPOskZjuYXn8AsN8XHuqqn3gXtfz7e17mhYGEpgO+eHYuj2MwNCTgtl2NPEJDHPi73EJTPeeJr7UU3uaqbfAUBIjUGD431CFRVCERjb4Uj38JzdhAiP8hCtMYG7m9YL4NmcUBO/Xd8QcteDw/44O9vvTLUKdQjNoDRXX322r64+KwJwMmVC1q+DTKmFfkEKzsAzVvA7EsItRywGI/QLGPFcxFv4OouhtjMXvQpS6D1HmCcTZp82uIyZUXczDZu3LSO4JBUNgWtzHaPpux/2jqYeQxB9AEn+A8dRTTKSpaAspvAQpPwUpPcFU8S6mincxXXyBqcJzTGV+gDj1PUTJGxAlb2AqcQszqe8xG/sOk6EbENu2MbqyCZExCzLvB5GugcisIDIzhdwMMmcEmTWAzOipXVByB0ZkXkhUEYwub2DWvgcSvQpR/g7E1beQH/yKhYv/wMLFf8Bw639i9Yf/A9KDnzF/5jfMnfyE2f2PmN79GeItqnV6vP4JY9s/Q7T7G8ZP/AKy9RNF7X0rRVR9D1J5h9HKTx2MV37CRPUjRmofQKrvMV6hGK2+x0jlHUj1J5DqTxipfcRI7SNI7deG7PwGUv0N8uITzOUewJY4CWtsH/FIGvFIGpXgKjYDFuz4tdjxa7HnV3bSEJd2gTnhVXKKDtcWbzaBEZpuokWHLXLTCzYhOiyBYWvZ7mdAHi0wTEpmOSu9VhdkLXNdyyPZUkc0h5lCGrx+phGt0VO0BGaOATMSw45ggeGKsByVsHSfjDprOpgCw/96pgZHEw0QKiC3Cqae/KsLzGFJzbCyw/f7w/d8ZneZ8JoqfUeNDh2BOQivNAXGrVzAksIAzcIyRsz7EFnPYNR9BRO+6xgN3WoKjDj9EOLs06bATOWeNJnMPoYk8+jQBGYy8RBTqceYSD/vFJjiY5DUDxBlb0OUvU19LflnmEzfgSj5HUTJGxCnbmI2fRvTyW8xG/sOE76rGLc0UkjaOMicC2R6BWTKRMmKZAlkssGUDmR6GWTaQknMjAsSVQQTpiolMKHLIMmbIMVnGF1/QaV76u8wVn+Nie23mKi9xmjlJcj6M0q2Cs8pSm+o1NHme4qNNyDrryk23oBU3jRqXN6BVN83xWWs9hFjtY+YqH6EqPYJo1s/YaT2ARPVD02BGa2+70tgpPmHrAJTCa5iN7DEKTDtERiaXgJDb/HujMwwZIa3i2k4geFKRXVLDHtqiZdmxGYwgRl20m95dZ5XYNiWR6YtsgbzSFu6p/7St6ct831Ha/hkZzixkXUIDFc3E1dEhgm5nlxGL75J6XsivDak9xt26wTBTrewdAoN/0lKmMAIPuEKFJhbBYMgvsubjhX+749H4AYQmMOVITpKJuz3Z9C29X4jM1dSBlxNG3EpZaAKeaMm7Pm0yJvnkTbMwbGsgGNZgSn7BmZdVUx5T2LGfwozoYuQRa9gKnEL0swdzOUeYC73ADO5B5jNP2wylX8ASeYexjJ3MZa5C5KjGMk9ouAQGHHme4jS30KU+h7i9B2I0/chSt3FVOohZtKPIMo8w0T6KZVeyj8HKT4DST8Ayd7HSO4BxrIvMJ57CVn8LuYid5qpKXHqKUTJx5AGv4fYeQ2S5XWMqnIgKh/IogtEbqGYt4AsrlL1LgoXyIIdZNEBsuCjmM9CpFmHyLKFacceSOAqJqI3qcLk7EOQ/LNOCo8oySo+Bym/oMSl+Bqk+Aak9Bak/CPF+huKjTY2f2wKzESVkhZxg8nqJ0xWP0FS+4WiMbCuxU8QbXzA9MZ7TG+8x9z6myaz5ddYydyAKf0NYpF1xCLrKAf9KAf92A5qsB3UYC+gouCIwOz7Ndj3a7ru323QlBu/kkNg2FNL7cW/HQLDiNTwiUwLOWuNDVdqiTPF1ENgOtJPjk66BIZrnkyDjmhLY/5McW0O5VUaGcqrMpQsUpQ6pGW2i7x5po+BeVwrDLojM4MKjBC5SRrnkND3aMdumy3TC8InKJ9bYPiEheZmbgU3cyvoSrkwJYD3BHW0AiNcQL4KzGFIzeFHc45HYPoVmnaBuZjU40LcjLNREzYdGhRXFxG2GRG2GSH3bWM+sIO50FnMRy9gPn4NitQNyHI/QJ6/C2n+IavATBcoxIUHEOXvg+TvURJDR2J6CIw4Q8mLJPsDJJkHEKfvYyb9CDPpRxBnn0OUedYpMLnHGMk9YBWY5us2BGbGexMTtsuY0BZAFBlKXhZdIAoriMoBonaAaJwgGj+INgCi8mBE68OoOoJRdQQT6jKmdFVI1nYw6zwJEriKsfANkMx9qoA3/ahRu/O40WV1DyR3HyT3mCL/EqTwCqTQkBia0iuK9ijMxhuQ6nuM1Kipw6LGhm9J7ROmaz9juvYzJuu/QlL7BZNVpsSwC8xs+TVmSq86BCYe28B6KID1UAA7IW1TYPaDauwHVJ34NU2BOQhqsc+QnM8lMP2nmLgFptcyyr4lhkdguiVG1lti2iIz7QP0mAJD0xSetbkm7RLDbMP+UgSGT2joOTS9BKYfiSHfpLXoxc2Mjofe7bRc7betItDhik9pQREqMPxpEn1Pvssb/sU5XgH6Lm/moCFIeTPFkLLDLa60QAtLUfEVSQ/ext4pOHRx8KWUCVeyFlzMGHEhbcDZlAVnUxbsJ+04kbChkvBjM+5FKR5GMRZCKR5FKR5FIFVDIFWDJ7kHZ3wXK5E9GEO70IVOYSl4AJK8TJG40UnyuwY/UKQedJN5REUuSi9Aig9Big8hzj2GOPcYo/mnGM0/xUjxGUjuCUiR5gVF4SVI4WUz5SROPIUo/gRz7lsQrV7GnDINiSwKMm8HWXCAKFYxpraDaH0NQiDLEYwvRyAyxCDRpzBpSGPGtIE5cxXT1m3MOfYw6buI6cBljIVvYSx8CyR2ByT+A0jyMUXqB2rGTeoRVWiceg6SeQGSfkEVIqeeUaQbreWFF5TIbL5ptEX/J0jtv0Dq/w5S+xtGt95jdOs9xupPMVZ/CsX6WyjW30JTegZN6RmMhQcw5O/DlrsJW+4mArmz8GfPIJrZQzSzh0Iij3w8i2rUh0rYi92wCTshI06ElNgNKnAQVHZwiiagbnLgV3WJTVekhiE0TPgEZturwI6v+3G9Jv12wpQapsgoWKVl2EhMq42bW2KYItNTZtolZohUE1NgmO3YNFwik2/AXCLZS2ySJmkPsZntScI406BTYLprZbjastmH5BF+QTl8gel4gx6wZoNXWL4wgfm+YOyJ0OcfPyuCECow3xcsHDRev2hpsILviiuHGM1ZaSAsoiNUYPgiOtcyK7iaNuJyegVXshZcyq7gUnYFFzJruJBZw0HGiYOME9vZMLYyIVQyCVQyCWymk6hkUojmdxHN7yKQO41A7jTc+YtwZs/Dmr0Ka/YqptZvN3jQgXj9CcTrTzC28QJjGy+oEzaT9VeUwKy/ogSm9AiT+ScQ5x5jrPCsJTCFp90Ck6egBUYUfwJRGHmdcAAAIABJREFU/AmmbNdADGcxPZ+AaC4MIrdREsMmMPoYJMY4psxJzJrzmLMUIFurQ27dwrR1GzLXPiTeC5j0XQQJXMdI8BuQ0LcgkdsgsYcU6buUxKQfg2SfgCSfUaSeUwKTfk51UuWfUV936RW12LE51+U/GxLzN6rLqNGVNFp7gtHaEyyW32Ch9Brq4lOoi09hyN+HIX8f1uwNWLM34M+egS99GuHUCYRTJzoEphr1YTdswm7YNJDAnAqoccAWnWERGS6B2fH1Rz+ic5QC0y9sW7fZBKYlMfwCw6yVGah2phGJ4ROYlsSwC0xrJ1NndKbf+pjW5d4C00LaJTCdEsMtMGwcmsDQYtLvG3SzCHTI4lM6BSK0iJX/JCksQnH8gvGlI0yABhUYJp8zHcWaYuxDYgZpY29JkqkjJdsqFF7BtcwKLqctuJy24GLGggspM86lrTiXtuJCys7AysCO80kbTqVcOJVyoZYKopYKYj0TZWWteJaVldJVmApXoM5+D2X6Wyzk7kNReISZ8iNMFe9DVHwMcYlaIDleeorx4muKwjuMF95BnH+F8cwLTCbvQBz/HpPRGxCHr2PcsgOiWwdZCIBIvSBSI4jMBLKwhnGlg9qLpA6DaGIg2jgmliIQ6WIQL8ch0ScwZSxgxlTEpHmDYnUTk6ubGLfVILLXMeLch9h/FuOhy5gIX8Vo4ntMZO5iovQKU5V3mK79ipn675Bt/wnp1h+Qbv2GufqvmKt9wFztAySVd5BU3mGi8iMmKj9CtvkDZJs/YGn9MrTlS7AVdmEr7MKVr8OVryOfziCXTCOXSiKXSmIjEcVGIoqtuBf1mBtbcTfqMSe2YlZsxaw4ETNhN2rEfkSH/YgOp0IqnAqpcDaowmm/AmcCSpwNqnAmRHEqqGxc1uBMSNMtMn5VU2hoOoQmoDpagfGoWOSlm+7U0lEJTEtkuASGLRLTJTRtCya5JKYfoeFbXcC2qqB94i/XUsm0RdbqbDL3aNNu3J9okGLQb0Rm8EF5hywwtJQMGuEYWDiKxg6E1oDwnyCFnaBvl0w9OerX/9L5VxcYvr+PXvLyLUtEp11gqBRXo9g9Z+oQmCuZNVzJrOFipiExGRsuZGy4mHYwsHVAi83ptBun025sZ8PYzoaxmYuzYls/z4pl/TrM5WtYLt2DvnwfqvITqMpPMLdBMbXxHFMbzyHZeAnx+guIyz82+Ani8k+YKv0ISeE1JpN3IIp9h4nAFRDnWZClMogiCzLnAZl2gEzrQOb0IFIzyPwqVai76AdRhkFUERBlACPqIEY1IYxrwxDpMhAvZzGmz2PCUMCoPo9RfR7EUKSw1EHsJ0A85zAWvITRxPcQZe9BXH4D6fanpsBIt/6AbPtPyLZ/x/yJP7F44ldI6x8xu/2pQ2Ck63cgXb8DbfkSNKWLsOZ3YM3vwJmrwZmrIZdMI5tIIpuMI5uMYz0exno8jHrMjWrUhXrMiWrUgXp0DfXoGnajRk6BaYdLYJgSwycw+0F1k2ZhcEDVl7zs+tX8IkOvMmijX4Fh8jkEhm/HEpvADLslmxaYdolhXueKzNAD87hqZ1pdTQ2ZGVJg+CWmv64lToG5lV2GMDrfUPt9g24VcQoTEOECc7QRhuMWhH96iqscmHG7aMb3pdUGZlb4fj94I4BHLDCDt7G3pKX9clNksmZcz5pxJbvSwSUObqe0HXyfVOP7pBq3EhrcSmhwI7mEG8mlru7Fa0kTriVNuJSiuJBa7eBsyo2zKTf200nsJRPYSuWwlcqhlKWI57KI57IIFLPw5zNwFUoU+ZNw5U/CkT+DtfRJ6ON70Ia3MGcvQ2RKg8g8ILMOkGkzyKQJRKwFmdJhZFqLCake47MGiGQmiOQWiOQWjC6sYGzRjFGFFSKNAyK1ByK1ByPqIEbUwbZt1nGKlQpGrNuULHkuYDR2D+L0Y4jLP2Fy4xNEtT8grv+JyfqvmN6mIjDT1U+QbbyDvPIeC8W3WCz/iMXiWywW3yKVKSGVKSGfTiCXimMr4cRWwomTsVWcjK3iVMyAg+hykwsRFS5EVLgUVuFCSIkzURVOR5Q4iGhxENHidFiN02E1zoaVOBtW4nxYibNBBc6H1BSN62dCFKca0ELDJTCt1JIS+wEFDvwqiqbYULfTYrPrV3fRS2B4ozQsItMpNFwFv90i0wm/+LRTdbegVh9wR2F6RWK4JvoOIjLMSAzFHINuyWmHOQGYuxiYitQw5SRtmUPKPINEg0EEhpIYWlRmOOi9j4nw1Xjw0/qk+FVg2AXmh/IKJ0JP4L1e+3PwVxeYYSN6rccL65ii/w4OU2DYOCyBoSXm25QW36a0uJnS4WZK192dmFrB9dQKLqcpLqbXOjiX8eBcxoP9dBL76SS203lsp/Mo5yiShRyShRyCpRwCxSzcpTJF4QDuwgGchbOw507DkNyHLroDdXAXCl8dsrUSJTGTJhCJkRIYsRZkSoMJqR4imQli+QpEcgvE86uYUK5BrLJCrHVietmL6eUgppeDEOliEOli1CbrpRiILkOxuoUJxwkQzwWM+y9jLH4f4vRjTJTedwnMZP1XzNR+bgqMbOMdFopvKYkpvsVC4U1PgdmPmjvkpV+BORPV4FxExSkw5xtyczasxOkIxdmwGmfD6o5IDC0zHddDKqp2pq1Whk9gaFnhQqjAUBJzPALDrIdhkxgKOTbs8g6B4Y7aDBaN6Vdg2ESGOQG4s/CXPzKTtlASk1yl6Ija9BGR+WIEhpYSrjdo7jZaYQLCPAENyu2SgYe/tmD8syNUYL4vmToY/HeIPTXVD/38ffCmmBhprtZ1Lokx40bWjOs5E77Jr+BqzoSrOROu5A2sfJfp5lZa34axgZ719pscNO9PUnzb4EGM4n5Mg/sxDe4k5Lgdl+Hb+CJF1IZvozZci/lwNerFiXgAJ+IB1OJRVKIhFEMZeI0OaFU+KBddmF20YUq+itkFE4XCiFmFEXNKM6Qqy//P3nu+13VdeZqHmSBIgACRMy5yxkXOOecMXOQMggCYxJxzUiApUpSsRFJykl1qhyrbZVfZHqeylSw5ll3d1V3Tz6RnerrmT/jNh5P32fvsc++5EKQafXgfAheBkEjivljrt9aCf0QyAiJTsTc6BXujU+AX5YRflBM+0cXwjS3Fzth67Iytx6aEbmxO7IWQ4cI25xSE/HlsLlrC9vKj2FF5DH715xHYchk72y9iZ/tF+Cich0/7efi1XIJfyyUllBtRcxYRNWfRWtyJ1uJOtJQ1obmkEc1lpRL5aCp1orc4Cb3FSegvjkd/cTxGiyIxWhSJ8aJwjBWEYbQoHK7CMAwXRmC4MAKjReEYLQrHuAZXfqgiMK7CILgKgzBcJKMXGFdhBFyFEQaRYQmM3KKSH5fpc4ZQQ8AkViWmOydMOSypfdlMYNxdkueOyMgtKVqgly4zbIHRwbi5xJMYWU7qUgJQlxLAFJlqCeX9EwNQnxSoExj2JJMqLKTIlEuQC/VMzxrE+ZlMMelHrz9zAqNmFOwJyBcCY4+DTYkbiu3/hoZkOo2JWGtMxEpjskQiFU8FRn1/zwVmud7+lNZSnf5r0ArMUm0CRWQSsViTiPlax+deYGZLcjFQXoCB8gJ0lpeis7wUbeWNaC6tR0lhF5zZzUhIr0J0Ygki43MQHpOJoKgUkcg0BEenY59EQEwqAmJS4R+dB//oPPjGlmJ3fBl84hrgm9CMrSn92J46gC3ZE/ApmMPWkmVsKz0An+oT2FVzEv6NFxDcdk0nML4dl+DTfh6+HRfg33oZfi2XENx0AfsaziGqVpSYtpIukfJmtJQ1oaW8TKSiAM1l+egrTUFfaQoGShIwUJKAseJojBVHY6JYkpjiSIwWhWOkKBIjRZFUgdHJjBsCI7+sRZYVWWgG80OoAmNFXlitJqrQSNJCohUY3ki29gYTX2j4AtORGWwqMLLEiC+rEiNCr9TIG395LSZSamRxUfEnCDAVGFliaAKjlRhvCox+HNsoMFaW4gn7a6Jgjvn48EptPJNVKyHY+hhT+IJhj7V69zjYEOcWh5scphy0Ce/zf+ZpTLTFwaZkHbK4WIeo6LjdwkrQQQoI+Xbe+7sLTWD0IWS6wMiv73cTMlfDDhkbM3J64rFUHY/5KodIZaKOuco4Cfk8ifnV+enyCIkEzNekYqQqG30laejLT0NrehxSExyIDg9DaGQCQiMTEBaVirCoVIRKBEdlIzgqGwHRuQiIzsWe2FL4xZVhp6MRu5JasCWlF1vT+rDZuYBtBcvYXCqePdhSdxLbGk9ja9tZ+PRcxs6eq9jVdx17Bp+D//AL8B+6B9/+5+DXcQ27268gsOUiApovYHfjSexuPIns6nFkV4+jpLoXJdW9aKssRFtlIforUtBblgxXaRST4ZJIjJZGwVUSqTBWHI6x4nBMFIcr7SYto0XBGC0KxkixTChGikOVSg5PYIYLw3QCI79OVmLI0WsziSFvMNFOGahEoDcnTEdPdii6s4LQkx2sozsrSEdX5j7DYzL8Cg4tOByMjsxQdGSGoj0jRIdRZvbpJIZ1a4m8mk3iucD4ozbZD9UpImpLKdAAS2JqEgNQleQvEaDD2FoyP10gj2uXxwdI8BbhkUcjRbwmMKt1Dir8cKteKD5tgfG2kLiLXYE50pxgiy8EhtOiclNg3MX2Hh1Oi0quwqjVGFVglmoT/sMJzFSZA9PlCRiqyERfSRpcZbnozk1GWmICIkOCERQai5AIhyIwwZEpTIHZE1uKHfENOoHZlDuPbQXL2FJ2HNurTmNb42n4tJzHjs4L8O29gr0jzyJw9HmETj1C2PTL2Df2EAGuF7Gv7zb2dt9ASMdVBLVegl/zaexpOoWcmgnk1EygtKbP6wIzQREZrcC4SkJ1AiMitqho8iILzLBGdOTXSZGhTiwRaN+uPV9AQgqMFlVigrmw5GU9BMZYmTEKDO3WEk9iWJUYKwJTl+KP2lQRtdVkFBgzmWEJjJF9OokhqU4IRGW8PyocgRL06gz76rUkMMt10TCFs+eEJS6rdXFYq9cLynqIyVpjnC02WmAONSfYwq7AbDT2//+l6FBlRm5Tka+TLSzzvx92W4w8AbEjOCv1CcaWVIPxseV6h7qRmMDOBJSdTdrq4j17AjNTFYGZqghMV0RiqjwCE6XxmCpzYKosGeMliVirzMWsMxH5saFI8N+BsOAwhIeGIzQ0FWFh6YiMSEJkRBJCIzIQGpGBwMgc7IvKhX9sMfxji+ETXwPfhHpsT+nGjtQebMqdxrbCBWwqfwZbq09iU/NZbGu/gJ1dl+DbewWRC68iev/riF15iri1t+FY/Qpil99C3NzriJx6GaF91xHcfRWB7Wewt+UUcusmkVs3ifKaHpTX9KCzqgCdVQUYqkjGQHkSxssimYyWRmCiLBLjpREKkyUROnkhMavAaAVGC0tmXFLuZpgQmeFC/dg1D16bSV+hiSBQL2aTeCI07ooMS2BUPNz8S1zFplVjWEKjnXpiiYwsMOo0k9hG4kmMUWD8dZBj27wTB1UOEdYVbbUKE0BF4LVweC0grbSs1SdoiDcIjKWKCFFhsCsoPNyumBBCY/sJvCXRFkdtstECYxe7AsOrcPGlxjzzZLdCwxUc6mQVTWbEfTjeFBg7iyjVzcQJEkk6FLGpku+tRVCRBWamMkqUmDKHTmCO1ORjsSgN+bGhcPhtQ3hoOMKCwxAUnIzgkBRERiQhIjzRssBsds5ge9EiNlccw/aaU9jcck4RmN19V+EzcAu7h+7Ab+w+AqdeQtjsawideRXh4y8haOQeQnquIbj7KvZ1nENg+xk466fgrJ9CRW0vKmp7lb06QxXJGKpIxkR5FJPxskhMlUdhoixSYao0EpMlEUzGSkIxVhIKl0I4XCVilkbM01iDJzBDBeFUtOKifZ3bclKqMRHod0ai3xmpCIwdiSGxslhPP74dhs6sMEVktNgRGKPE0KszPIFp0MASGJF9aEjex63EuCswbImRtwIHmQqMmpNhCIzn1Q/pGzYhLCyBWWuM84qc2G25eDtDwnuC5QnERgvMRmNfAJN1HGpOcgtPBEYvM0Z50Vd47OGJwNBkRisyWoHx5HwDXWCi3EQ+DRKvm46SUc8hyPISRqC/Pj9bHYOZyihMlcWJlCRhsjgRR6qzsb8wCUXRQXDsEhASuA/BewMQsDce+wISsDcoCkGhsQgIT0RQVAr8orPgF52FXbF58I3Lx/b4SuxMqMamlDZsTeuAkDeFbcXzECoPY2vtMWxtOYed7Rfh230Zu3uuYGf/dezou4Ydvbewo/cWdvY9i519z8Kv9zb8em8jpOcagrquKAKTXzeF/LopVNX0oqqmFz1VheipKsRwRTKGK5IxVR5lynRZFKZKRXGZLtO/LhKtMFkSpVRq5FaT2nqio1ZmWBUaeutpuDCCKTFmUsPMyzDaS0qLSTpt0JsTZJme7H2eiwxx4sBsUklEvIrdlh4g4VklRis09EoMuW+GskRPQ1NygA7eBmBjdsY43eSOwMgVGFJcSCrjA6h4TWAONjgkEiXE183k49MQFLsCY1dQnmlNMmWjBYb39a03dr9+uwLjbsvO+HfYfLLLrsBwBYc6WWUmM4k6yEknd29UqSsNok1hCYwxXCyiik20KCnVETqsCMxEUQIOV2VhIS8e+ZEBiNoqIHCPH/x9d2P3rijs3hUFnz3B2BsUBf9QBwLCE7EnMhN7IjPhE+OET4xTJzBbUtt1ArOt7ji2tZ5XBMav96oiMDv7bmNn32349D8Hn/7n4N93B/59dxDcfRXB3VcR1Hke+zrOoaB+miowrsoUuCpTLAkMC1JgpkqjDS0nOUPDEhijyLAFRp6QGi2K1FRm9GjFRfs6v9UUoUCVGI3AWJUZuwIjSgwrG2NNYKwemaQJDL0SwxYYGs0pgaYCw16YxxYY7dt5t5mqHGIVhnY1W385O5CKBYGJZiBP8YiVFlVgRA5LyK8faaRjV2D4LYb1zZDYFYQjbfbYKIGQP/5YW7It7EtQio6jLcluYffPnz8qnmwLbsjYgLnMuDvGzRvttiowKsSmY8biPW0YeFErMJKwyK0lrcDMVsdgsiIWkxWxGCt3wFUah/nqbLgKHEgL88e+zQJ8tu/Azm3bsXn7XmzZEYDtu/bAZ08A9gTHYG9YPHZHJmN3ZDJ2RmdjZ3Q2tseWwMdRBiG5GZtSWiDkj2Fb8TSEyoPYVvcMtrVehE/HFezpugr/3uvwGbiBnf3Xsb3/Nrb334bPwB34DNzRCMx1BHdfR2jnJYR0XERBwyQKGiZRVduNqtpu9FTlo6cqX7lNZUVgZiuidehFJkbHRFm0jtHSKIyWRmG8RA9bZKwJjPy4PJ5NtphU2JUalsDQZIZ1Ldt6ZYbegpLbULyWEk9glEV4GoGxdSmbCP8qQqIZ1da+biYwWnhbf1kCY4Q31bQPVQ7jkUkV+WZTIGri9zKxLTCkuBxsECdLjkjI0yIsgXFXWNwVkC8Exhy7AvJ5FRj5/e1ncHgVnhRT+BLD3ptzsCnRksCYVWXsT0HJG4m9KzBqUFicZlqoiRSRKzLStXs5FKxUYKriMFUVh7FyB0bL4rFYmwNXgQOpoX4I3CRg25Yt2Lp5M4RNvhC27MHm7buwZacvtvuFYk9wDHaFJcI3PAnbozKxMzobW6OLsDOuFEJSI7aktkLIH8P2khlsqTmC7fXHmAKzY+AOdgzcwa7BZ7Fr8FmmwBQ2TqOgYRLVdT1UgZmuiNahkxdJVkiB0UuMZwLDlplogsh1Exg9kRgqiMRgfoTuZUVkrASBTaXGnsCwbjRp5UUrMKTYuC0yhMDod8zQsSIwZkvzaAIj75fxRGBqEvd5Q2DIyQlSXKxN/aiSQQ9JejpGbEceaC0GEqtPdCx4gnG0PdmUZ1oTNpSNFhirnCA43pqk/KrlWHOiJcgcjt1pMBV3Mzj2KjirTYlY1YgNKTTkoj4VUWDsj4FbO6mhTi5aa00dqInBgZoY3ToH7Q22uZpYzNXEKpUXOTMzWZ2IiSoHXOWpcJWnYrq+AD0FSYgO8MEOQYCgsBPClt0QtoRA2BQEYXMUhN1JEIJSsCUsA9tCRXyiSxGU2gD/7Db4ZbVia8kCdlWtwKfhJHY1nsaOtmvw6bgB366b8O+7o4iLMCLheh6C63lFZPb23oF/z2349tyAT/d1lDYOobRxCLV1Laita0F/dR76q/OU45riBJYWo6yYCcxUeYwBrcDIkiKLDA/tyLa29SRXZNwRGPHkQSRjqsma2GhDwNamm4LR5wxCnzMIvbmBHlVrtK2nzqwQSwcnjacLrC3Ko8mNLDBtacHG9lKav45mDY2pfgrNKXvRnLLXMOXEyso0pPijPtnPkImRQ8Ha96lL3GOCP2oT/MQL2Yl+ylVsI36oTfBDvWMvauP9mHhFYPTSwRcYdyok3s5IfNYE5lh74sbyGZATTwSGFBnyMR5kC81uFknG/QyOexUclsDI/95WGTArNXYnoZRxcc8EhpW5WamNxUptLJbrog37qLQCI7NQHY/5qjhMVDkwXhmvCMxsUxG68hIQsmszNukEZhMEYQsEYQ8EwReCsA/CpkgI28Mh+ERB8HNA8HNgU7ATvrHl2J5UC7+sVgjOSeyo2A+fhpPwbTqjCMzunlvw77sDn8FnRYFxPSsy+gKE0Rc+dYGRJYYmMFSRkbAqMsbsjL4yQ4Z/R4qNuEqMk02s7IxWakjBcW88O1hBFBnz1hNNaLQCw7vRZJQZeQvwpycwirRoZEYVl726TA2v5URWZUiB0ckOQV3iHlF6Ev3XT2BUMYmRsJpREb+Bkj9dqrIST2WjBcZui+XzLjDHO5JsYVtOLH4dLIExE5uNEBi61KxfxWa12YHVZtoPDlZPNtgMEVvcWKzKDNmGYq1niMFqXQxWaqOxUhutE6D9NXHqccoaEXnB3mR1KkbLEjBUkY3hyhwsNOehKzcCwdsFQmBINmHbZh/4+Phj5w4/+O4OxR7/cGwKSsD28FT4RKcjvqAWvlkNiKjoR0TDIiIblxDYehpBbWewt/sGAntvYdfgbfgM3MKOodvYMXQbO4fvYOfwHewavI1dg7cR2HsLAT03Edx5A0Ed11Hf0In6hk601tWhpbYGI1XZGKnKxlRlMqYqk6UR8ijMVcZgrjJm3QSGFBkSlsSobaZojJfEqBUdywITrqvWsFtN6rI8+uK8EEv05+0jkIWG1X4K1lVtVEKI1pO6FVhEHwrmL8YzP23Aay+R4sKqxBgf57eeyBtOuiV6ZtUaE2qSfFGT5KtUZmRhqU3Y7RYGgVGFJE7CPIPC+0bMEpijLQ4cbXFwv/nbzUgcaU0xxe4TMFdQOlJMsSsQG057ii1Odorwfp+T7SlUPJUYKwLjThbJc8ExF2zelNVaSwLWWvgitFEhY8NGY2I5H6uCI5/ukEVGK0DLtfHKGLh800nOzszUpmO8IgnDlTkYqcrFYks+OnLCEbRNwGZTgRGwSdgGQdgGQdiOLVv9sX1nIDYFJWBraDJ2RKQgs6YTYWU9iK0dRlTTfkQ17UdQ2xmvCUxrXR1c1bluCYz8uBadxFTEGjATGpbAsGRGzcrE6ASGDP+SrSdtC4onOlrk1pP8Mu2UgbnYBCmsh8BoNwObZWhoAmN+o4lTkVHCwXRaJJTXZYmRNgSTm4LtCoyZzNQl7mEKjPq6RYExjoCaC4yV0rn2m62aV3FQsTMmbElgONWRLwTm8y0wZpi1mshJLLsC47ncfDoC42nI2P0Qsnn1h92yVrd1L9dFK+KyXBdNLNRUTyiId6DkvTZJWKxJxEx1CqarkjFZk4PJmhzMtzrR4QxDsI+ALRyB2SKIkiOKzjZs2+oLYdceCL5+2L5vLzJKi1DfWo3qhjJU1Fejor4aJQ0dKG3qQnHLEMraR5DX5YKzcwTZPS5k97iQ2zuK3N5R5HW5kNflQln7CErbhlHZPISKpkEM1xZjuLYYrupcuKpzMV2ViumqVN0iPxEx40MTFjOJoQkMT2TMKjQk8n4ZI+LiPGVkmyI22tetCgxNaHgSoxeZIAJe1SbIULEhW09WpprI8WwzgTG/oq1KjJypkUe0aZACQ4pMc1qAQWJoWAkGW5EYRVCS/VCTtAd1Sb6oS/I1vL0u0V/Jy5jhNYFhZ0xk4fBMYMzGfr0hMHafgO0KjPwE/nnlsywwZpUaWUC9NQ32hcDwNh7T21jMEyFSBUYRGxOBWa5PxHJdMpZqkzBfl4a52lRM1eZiqjYXC215aM8JRdAOAdu4FRjt61sgCNshbN0BYesObPLfjYzSItS1VKGmsQKVDTWobKixJTCVzUOKwIzWOD91gbEiMTyp0S7JmyyJwkRxpCIwE9KyPBHjSLY7lRpXSSRXYlh3mfQEK1gVGL3EqBUb87wMfaKJNr3UlR3KvKBtlBkyI2MuMDIsgWnNCEJrRpBXBMYdmamVqE/eLeFHSIy/JQTym4zSEmqJFyFaRVa/EcstGq3A0KZguBkSE2GxViFJZJCsr4DYfCJmP0Gncdh4CbEH77/PnFNdqTjVlcr9fU51pBmkhPaYVZGxWknzNN9kWXA4LU4S8t/ZwdZEHGx1X4Ssk8rEs3FwVgvK6k2qeIPI0DYNz9dlYL4uAwttBWhM2we/zfwKjBl7dwmoLnFgrDEeI/WxGKuNwWhNFKarHZiudmC+NhFL9cmYak7BZFMyRppFRltSMNqSgqlmkaX6ZCzWJWG+JhnzNcmYqU7TIW4hdmCpMg5LlXFcgeGJzUxlHEdi6OPZvP0zCpqNv5MlUcopg4nicN0JA+3yvDGN2JCnDrQVG9ZCPe3LLIFhy4xeYPhtJ37LyTQETJw56M4VYQmMQWKyA0VMWkztGYG6l2m0ZholpkUjMDyJcVdg2DKzBw0pe1CbvBu1ybtRn7xLYreOxiQ/NCb5fXoCw/qGqwoHfYyX9w2efKJeB4MEAAAgAElEQVT5tAXG/hN0OofUzzm8/z57//3rKTDaP2dWhYxXYbPL51lgSIkxR87isMTG2jkH8gq4cbdNEg40JInyUp+JhbYCNKQGYrehwuIegb4CassSMd7kwGhDHMbrRImZqUnATE2C2wKzWJuC+ZpkzNWkY64mXScwC9UJWK6Kx3JVvHL0Ug4tqycWrDFTyUYrMFYw3wQs7pnRnzGIpAoMeXxSe4DSrGJDQ1uZ4YmMKDPBBLy2k15g1DCwdYHRSowsMN05YXpyQxi7ZvYZBMa8xWSUG1lgqGgExkxmPN0zY5QYUWDqJBpSfNGQ4uu5wBxpToIWY8vHfAMrLyxLCoxhCqY1QceJtkQdbAERId+fxExuPo0KivUn8GSPONOZuqFspDyp/4+NVRyrlbWT7WmmHOcifS6i5bVeY+ryvycyjOytRYCGNQEWhcr7+2+MYiNKjFyxEackySyNVmZWGhMx2+ZEU3Yw/LfYE5jEnQL6i5OwVJ+M+dpE7K9xYH+NA0vV8ViqjsdKTQLW6pOwWpuIlZoErNYmYrU2EWv1Scrj8q+rtYlYrk3AsiaEPFcbpzBTE6vAExh5Y/FiVQwVXttpvkJlrjxa97IZs2VRmGWeL4jEVGk4JkvCMFkShqnScOXYpFZeJsqM1RpScMZ0UkNntCjUsHeGTQhchSEYLgqhyAwbUVqCjWPa8jkDnsxIIqMIjIEgdOcG6cRFD7vFJMpKgARdZNqy9lEFpi1rn0QwU2bMqjPNxK4Zct8MSUOaH+pS9qA21Re1qb4akdHTmLQbjUm7udNMbgsMc5zYA4ERsw16Pm2BsVth+bwLzNnuNFvYlZDT3Wmm8D6WJzfcP78vBOZzIzD6PVNiRo9sQZGbiGfbnGjJCcG+7fZaSMm+osDsb0jBYl0SV2BkZGFxR2C0yFe75Skr9UaUiDcFxgyWxGjFRS8x4Xqkq9mkoJDVGlalhgZNYGiwBIYFXWLkqozxRpNWYJibgCWB6XGKsARGrcTQBYaZkyFaTRspMGZC05AmwhOYpmQRrsAYF7eRLR9ruZMjrSk42p6qQzemzNhDQgoHKTTHOswh35+EV13hPYnynoC5gtCVYYr6e6V4hF0BsQtPQOziify40+LiCQ6/OmeUVnemtDZeYOytIeCfbZB/+NE/bl12yGOaeoExDh3omW91oj0nFKE7BWITrzU2SaTuFgVmpTEVy3XJioAcqHbgQLXDY4GRx8EX6+KxWBeP+fp4ncCol7/1wqQSa4AUGBJPBIYlNdqdM7otwOURCrMVkZgqj9JVXmS0kjNZEqZ7m/sSY44oL0EEIUxGCoI1hEqEY6QgHEN5YRIRGHSqrw86QyXCdcgCY8DCBmBxcd4+6vFJpcVEQoiMVla0AmM1S8Mb09aNZtP2zaT6oTnVT20pSSLDC/2Sm39JvCYwpLzIsARGnS4xx0xejnem4FSHOfxsyv+/BeZcT7otzthk/eXHs2yOFYmxFsJ2T4qsCg8rjOxtWP+uZfg3qNgCY61yQ983RQqMktmTONgUh0Mt8Vhoy0NTxj4EbBaw3UOB2SIIyPAXMFSW5jWBOVAnQhMYLep2YvH3k0VGRb4ZZRSZJSvZGYqYLFbSH6dKDGv/jEZgpssjlMyMTl7KRdHRSoz8uFZ4rEqMNZEJVnAVBpmIjigw6st6gVHIj8RQXoROYGSxkRnUXs02ERirRyfdERiZ9mwRteIiohUdrcBYHc92W2SkrAwpMMzQL+Muk4xAlowNJXGL31gVYelI0yNnTZjjsRsrMHafJPmCkGmK8mTem+oR53szbLHRArPeImM/ZOx+CNmdKS07AnPSg4/zvsCQ6w1YAsN+u3vHMxlDBoTArDbHYa0lHostTtQn+8FP8FxgNgkC8oM3Y7ImyyAwWlHxRGDk6aklDbLMLNYZb0SxBEYLTWC0aAVmsZKNHYGhnUAg8zJkpWa6PEIJDMsVGK3wsKoz/HwMTWDk1+VWE0tg5NaTfK8pzCAypLDQkCsx/aTMeHw9m1WhEenOCkR3FkVssgM1eZkAzWP7TAPBnogMTWjktpKZwGgX5jUk7zNFONaWCi2eCoxBXCRYGQGWwJACcryTzYluKyFT9pPP6e4M7hMg74mX9wR/vjfLlLO9GSJ9aR5hV2DsctZLeEuEjGKUYQr/7wcP/d8Xb4+Zs4RHmcJy8+PcFibGv2vtDyja1pYxR0PP3LAFh3caRFqcaUFgDrY6sNSWh7rEPdgt8PfAsJbbbRUElEX5YKG5AKtN6ViuSxblYwMERhYntRpjFBgtrOyMmqFRMZMZFuwdNHyBMavU0Ko18mO0Co31sC9fYPSEGwRGlBhjJUatxlgTGDI746nM0ARGhlWhIQWGzNZYFRh3qjLyQr3mNH80pouwJ5gsCgw3lGj5Gx2xYbYzTUQpt9MCrhThcFNg7GY0+AJi7wn+Ql+2KXYF5kJf5oZyrt97eEuG9GKUaQpPUJh/twwtQPcyOGc6RTwVGG0AXfycmTjVlYkznTLpOjwWps4MJlqBUSXGusCIv9KHBXjDBEdbHNJZEvVUibgYUx4vT8XB1lQstReiJskfPoL7Id7N0sdsEgQ4QwRMN2RjpTUTS02pWGlMFKedpNMGq3UOrNUnYK0+Aat1DgX5MRJ1j00cgbigT2alVo967FL/ur5KY8zOaFmiCgwjDOyBwJjdbdLKC0t0mNUa6ePkzz1Vys/K8ISGtWvGPAgcpqvM0ESGJTPcsC9DYJhCkxuo0JMdwBQZapspO1AXFDbbN+Ot9pIsM+RRSfmYZEvqPuUydnNKIBpTgkzxisCclGWFgtm0jpUMyYluNid77IVMrVVQvhCY/8gCwxMaTwRGD73SI4uFnWyO/m0bIzDGFlUqAdmWEh9XBSfBY4HRP+7AsfZEpbV1qC0NB1tTsdBWgOpEP+wQ+LeQSLZKH+MnCCiN2YmJukystmVhf3M6VpuSsdqUrIiIVk7cFZgDDfEK5GI+7eda1Vzu9pbAqI/RMzS8yow7W4GpQiOFfGcrIjFXGcUUGG1Q2B2B4Vdn6PtlrE81sQWGJjI8gbG0W0aHXmJY1RlyqokmMF05+5g7ZtwVGDOZ4QmMFq7A8Fbda2/20EOKSRKsEGOSDnfHhD0Nt6ro20BGSUk15XxvGgeewJgLAP/j0zcYnsRszOe3+v/fbsaHj5hlMoazrbWs+KPumaaQvy8pLiyROdWRJgpUR5quFUW+bqwAsTHKiwo7Q0NfcKkdJtCdHGl14HCrQ9lJdbQlFUdbUnGkNQ3HOjKUr+NIWzYOtWZhqrkKeRF7PRqd3iFJzFZBQG6wgIm6dKx1pGOlLRVrrck40JyoW6y31pioLNhTsPh2VWD0FRnyyOVKbSxWtZuIiYoMq2LDazXxwsAk6oZg/aZg1rSTVjy0hyi1BylnK6IxVx6JufJIMKs25bGYLY9lLs4jF+ixUMWGvyyPJzIjBaEYK4jAWEEEXPnhBJEY0YR8Sfrz9fTlhTLpoQpMIHpz96JbIVCHsUKjpztrr0SgIT+jpSszQKEjY68Ca1GesulX85giLZpNwOoivH1UGlKDTLEkMMc1FRRjaFGWDdakjrmQeFtYDEFXbmZlYwXGriBcHMhcX/qzzfHy53dfkOwJon3hoYezreVnTCo8SqUni4N7AkNWgGSJ8YbAmMoNJT9ztD2VuV5BbUuZC8wzrWk4qtkMfLQlGcfb03C0IwdHO3LQkpuMVP/tHgmM7yYBPoKAhMBt6MyLwFxLLo50Z+NQVxYOtqXoBGatMZGBvKdG/7inArMq4S2BsSo4xukmEnpIWCszvJ00sxXRmK+IwnyF8fq2VmCmy2I0IhPFlBgzmVHCwCVROtyRGG0lRhYYI1Fw5UdaFhieyBirNIHocwaiJy+QKzDmMkMPAZMC05GxVy8zmjFtnsDQzxnI+2Q8FBhW60fLCdOV7+tbUfF0OkeLPvTqXXhPoDwB2HBB+ZzwH01gFOngCAxPSJiflwFNYGSx8Uxg5Fay+yKjW7PAnIKi35lS99Sk4WhbuvLrbHEYhrP2YCgvDBOlsYjeJmCfZqLIHYEJ2iYgdpeAgepMHB4swkpvHp4ZzMS5iUKcGszGfF0EVppisNIUIx3CpR+sVA/lGi9zm1/q1iMLzFp9vOYmlF5syJbTap2DITaxWK6NNYgQC2M4mI1RboywKje01pSu7SSJi1ZgWNuAJ0siuHIjH6M02y9DVmq0EjNeFI6xgjAKEbqqzEheGEZoElMQjqGCcMOCPFJm2O0m8Tp2D4M+CZbIqG0mo8jQKjEsgaHtmKGhr774cwWmOS1YgdpCOtGVDit8XgSGlhM515+u8Gm3WNa7gnF5MMsWn/ff336Lzp7wsKbLeFkbVXY8EyR1DF8Pf++QXnRYlRnmkr+ODD2axz2pxHBHvBm3qRTBaUvHsY4MHGlNw9n+PHQ6tiBFEJCyRUCsIMBfEKso2zwQmDAfAcUOf9w4MokbK5040O3EmfF8XFusxMXxQhxojsNqcxxWmmLc2Cxsfp2bJzRr9fGKwNAepwmMLDHal0mB0WJFZswExh2ZYQkM2YZSW01xXIGhnzZwT2CMMkOvyIwzICsxckuJnF4aokAKTL/2dIGHAsOUGCUrE0AIjbnI8ASGJTOsCkxLejBa0oNNBYYmMVSBOdmdYYA9abG+guJpuJU9dpyCC/2pXwjMZxzL/w94/3+5FTC7AiSGsY3j8Xo8Fxj39vDwhIdVqZHzObxwsVZeTnVl8oPAhPCwQsBWpxtliVEFJwPHOjJwtC0T5/qLMJG/D1lbBMQJAkIkcdkjSYx2r4sVgQnZIiA3VEB3UTTaMnZgrCIMa20xODuSiXPD2VioCcXh1jgcbo2zsJBPPWppR2jW6uNxsMEoOIrYEBkbmqCIyNUb1tvNhUY7KUXintQYx7q1AmNsO8Xp4E0tMffOKIIjCozVDcDa8K8oMKEMJJkpjNSLTKEemsCwqjKGKk1eqHQhex/68oJNBWYgV0Qb/u1z6sO+VvbKkMhBX1JetNDaSkaBYR2N1AuNPF4t47HAsDbIeqPlY0dgtNUWGhf6U70qMLwnyMsDOabYFZQrQ9m2sCsan/bv/3kXGPl19X3ttbTIqSs7AqN9nL0jJ1PhdHeW6ZTUpy0wJ7pycaA6Dj3J21EZLsC5R8BOQcBuQVxi5yP9ut1kIkmWG39BQGbEdjjDBbTnReBQTybuH+3Ct1+YxU9eP4Qff+kQ7q/W40hbvCIw5neh+AJjRWgONjgUgaE9bggJM2VGCgVz348uNGYCY1VkRJmh76WhCYz4uoMqMKxxbZ7AyGFg3rI8o8iIlRj5irYMTWC0EkMKzLCE5yITpAgMDblCwxIY1q4Zs90ypMCYbfrltZZIcTEKjV5cSKH53AsMT1hoAnNxwHvZEv4TfK4p6y0IfIHI4LDeX18mrgxlevz7cwVxnQXnYn8uLvbnghyPP0dACo1VgeHhrsAYK0Dq46TA0KeoZIEhl/2xzm7oBUf7fUY7HMBb/Cfn8ZTBAkVyMnCyIwvH2zNwvD0DcyXh6EnejubYTWiIEpC+U0CoIMBXqsT4C2Imxl8QECCNSO8RBOySfo3xERC5XUBdkg8mahJxvDcXL6y04WtXXPju8/P4zZdP4Pf/6RK+98ICbk4XK1NT5IbhwwbEkLGnxy2tCoyVNhQVy+LjXqVGbjmxsjTkbaflKhFyuZ584kD7srwJ2GxM2yAz5OZfuRJDWZ7Hk5kxQl5MRUaC3Ow7TEEUl1Amg/khCv0FQejLtyIwITq4y/I4+2XkqSVvCYyxtWStQuORwOjK1utcMTEIyECmDt7bSS4OpFt7YvQSPIGxKwBXh3NsksXB2uexKzAs7AqMXcHxtsDIr6vva68CRAoMb/OzXYE53Z0lkUHszTHfgyOj/Z4iZ+vcERhZYpRFfh1ZOhYrojCctQe9qb7oSfHBYH4YamK2oCopALHbBcTuFHH4C4jeJRLjKyDaT0DUHgFpQZuQHb4dJ1yVuLLQihdW2nBroQFvne/H39ycxM/fPIyfvrqKd69P4Nn5chxrT1QERrukjyUwVi93s0TmcKOINhgsP04TGJ7IkFNSZiLjDZkxiox+R82BaodOYLQSQ9sYbHXfDGtxHikwPJEhZWayJIIpMSKROoFRA8CRGC2KxIiEUWTCTCVGFpn+giCJEKbA9OcFa45MipD7ZrTL8kiBYWVjxP0ywYrAyLIiywyvpdSaGai5du2hwNC+SdGDh4x17YTAGI4NcgXGfLkZbyrHk0kd/ZOgvQrERldQvCUg6ydA5vAEhi023vnzcbtl5WE2x/P9OXSxUf996F/nCQwJqzLDXvSnFxhysR87PJxFILeoxOwcb58UuYWbbFEdb8/AkaYUHKqPx7HmZCxXxWKyIAg96bvQk74LI3lB6E7zRZNjO5oTdqAlaTu6M/egLExAe/oeHGhJw/7mVBztceLcWDleeaYH37g2g++9sIDv3JnB3z07ie/cGsOP7s/jZ6+s4N1rY7jiymWeUGBXYuRDlqk61BaT2mqiCY0sMCyxYbWfSGExCoyb4lOvDQ7Tp59YAWJtiHh/TYxEFPbXROGAxP6aKCxVR2KpOhKLVRHKy0vV0ViqjtZf3K6IMr2YrUfeM6Pf/EsKDFtmohV0I9icxXmukki4SiIxUhwuIonLULHIiEFmwhTMJGagMFgRGBqD+SFeExiyxdSbE4SunGB05QSjQ0KWF7OKjO4yNiEw9KCvfnJJi9cFxv0KjLnAWGnZ2Au1rm8LxW7l4tOqoGyUwNgXmvXN4FiVYbezOTanrFgCQ1aCrIqMnNPhCcyZnmwJWXjMF/qZCYyIcfEkjZM9Iie6UxWBkTM5ssAcb8/AiTZx+d9KbTwmC4IwmOOHvqzdcOUHixKT6Y/mhB1ocmzFdEU0hgpCcajLiSsztTg/XombC024e7ALrzzTgydnR/DrJyfxvRcW8ItX1/DHb17Ax189jR/dn8eD5VocbYnTTFERi/s0AnOkNQVHWlMYFRkjNIGRkUXFqtjwAsKeTkZpBUaEvomYhSwwCnXRBoHZT4iM+HqMJDHE6QPLF7TlPTNR+tMFBGyhieEKDE1iZIFRJKYoEq6SaK8IjCgxngkMa/OvFYGRKzBmAmPWVtIKjGc7ZCxWYM5qjw6ScFpCvLe7u/eE9gRjrypi7wmS94R8bSTXFJ4g8D7+2kg2h/X9eG8LjPtis74VLo+rN7xWlc0pqwsDIuTrLIFhnbJgVma6s3GuO9tYrZEel4WFVs3RIb+/hFaAzBb5GVtQ5ASklKvpkHfXZOFURxZOtqfhXHc2DtbGYTR7NyadezGavRvjuf5YKAnFZEEgVmpjcaQ5SQwhd6ThzmQZXlpuwDcuuPA3l0bw7WsTePd8H/7xuRl8+Poh/PLhEr59qR9vHqzB81P5uNyfitXqCBxrcSgVGK28aG89HWFAVmVYV7zVW09JBOTj6sXuw00OAwcb4nCwIQ5rjSJ2R73lzM3BBgd1+snqFNRSXSyW6kSBWa6LxkqtCFtgoohKTJREDFGVkYmT0AuMivg4Pz8To0OdXjIXGVdJOANRZoYlZHlRWktSpWa4MEyt2hSL7aeRglBFbmSBGSgMZQrMYH6IYf/MIDGaPZAbooiNPuSrD/vKFZp+ia6cfejODVLOE9COR3ZI49a0I5FtWcFoywrm7o+xLTDsKom5sBhu9xgyKd4dE3Y/N2K3gmFPYOyzsQLD/3hz7IvN+lbArP594wmMAastLDcFRs7ksLI51is0ORJWH+d9HpGzCllKBcdTgTndrd08nI0zndk42Z6GUx0ZWCgJRV2wAFemL/qStqIpQkB7jIC2OAET+QGYKw3FRH4AJp1+mMrzx1jOLriydmAq3xfLlSFYKfPHqZZoPDeeg8u9CTjTFoVTrZE40RKF+SJfrNVG4uqwE/KBTSsnFMxEhiUwKsmKrMhvZwmMqchIyCLiSZCYFBgxe0PZMmyapTEXGPl1uTJDslQdranGRBsPUSqBX2sCw7vfpN/+q0qMtqU0UWbcJzMqwRMYV0k0XCXRGCuO1gkMibwBWBaYwaIQRWBoyFkZdwRG3i8jB4BJgelzhigC052rwrq3pBUYWWLkl0mB4S3DMwgMrUxMTkyQFRgzgeGFaN0RGG/lSNazBcN7gr7ucprCEwTex18fzTFnnT/ersDwxMZ+hci9lpi7QsN8Py8JDDN8PChCvs7K3hjG+/tzcdlEcGThMMqOXmDUthYpRPRFf+RouTIOzjyWSSJKDHk+4VRHhsLJ9jQsloahNUpAX9JWdMYL6HJsQl/SVtQGiS/vrwjDWk00DtVE42JPFm6NFuL5yVI82l+Lx0fa8ORwPb5+qh3vfWkZP7ztwt9e7cfXT7fi8kAyznTG4kxnKs71aEbHyQV/mrFx7eZhWVyMV7v117tpAkMXHKPw0GRG5lBzgiQxiR4HiQ82JVIExrMJKPJkgnoqQcTQatJACoyla9qMSo0qL1EK2haTcQNwnMJUaaxBZNSwbxjGS8MUkVFlJhKjpVGKyLAW5cniQl7BVlpMRSEYLgpxW2AMQkO0mAadwQShhkkmeZqplyMyImLYV245qTITjI7MYMvTSwaBockKOUFxri9bH6wd0JSs3RQWEk8qKPYyI2RbZn0rEFyBsMsGCwz34zlw//9x39+7LTp3BYf9ft6ZPnNXYMj381RgLvTlSvAelz83+b56saFNZ501HSNn7dNJNwiMiNj2OtOZqVRgZGnpTdyCsRw/zBTuw3R+IJYro3C+Nwu3x0vx+EgXfnBrAe+/fhJ/+cZ1/PGrF/DHr17AX985h3999yL+89+cwz9/7SR+cncKXz3RjIu9CTjfHQ/5Ur0cRrYiMDJWBIZkPQTmYFOiIVxsVWjkzI02e2O6gI8hNfL9J5bAaCWGvAslB4C1AkPLxpgJjHGaKYoghiows+XxOomhCYxIOCbKwnUCIxKlCMxoKfsWk5yZIW8wKS0mSWAGi8IwUBiq/KoVmKGCUMMGYGUTsEZg9DKjFxi5QkOKjFyR6ZFgi0wwlc6sEHRmhXCzMqzKjECTlQsDuRqyTWGWvjnIIVlvCAkP86qHPYFxVwBujObr4AkC+f4GxpzmrPPHq/+tWQzsiQz/4/Js4p6gWq/QOU2xLuV0AbokIYuKsleIMy6uvP+AE1cGnFSxudSrCgfZknJ/lw7R0hrI1X+vsRg2ZlVu1NBxNs725uBcdzbOdmVhtmgf2mIETGTvxkj6Dsw6/XGkNgZHG2Jwa7QQrx9swLsXh/CfLvTjx8/P4v1X1/DHr5zEr19dxnuvr+K3Tw/id18+ik/ePoIPH6/iB7dG8ObBKpxuj8X57gRcHsixJDA6mSHOKsjSQms9GYWGValhtZzoHG5JxKHmBN3iPdaklJnIuCMwvKoMKSYkdIFxSOPYMQT8i9rUVpPJJW1yAzBNYKZkymMk9NNL4wrRirBQw8AMkWFdxB4pDlUEhoYcAnZHYIbywjCUH4Kh/BCNwATpXrYiMHqJMRcY7Qg2Oan0mRKYS0PZuDSkDc96V2CstGQ+SwJjmw0WGPV9cxiYf367FZzrrnxTPqsCY72lZS4wqhCZCwz5dllgDO834MRljXBcHnASuLtrR/1YWWBkzhHVGasCo6/cyG8XszVyi2vS6YfmSAGz+XsxmrETCwUBONGYgIs9GXh1pQnvXhzCj+8u4FsXB/CTF+bwm1cO4JMnR/HLR4t47/VVfPzWYfz26UF8+HgVP39pDj+4NYJXV8pxoiXKY4EhJYaVm9FLjLnA0Co33hAYnsxoA8Ws6SdPhcaa3Mi7ZmINAmNFYlSMm38tnTAoj9cxXSETqwiMbgy7PAoT5VEYL4vGuKFaQx/NtnIZe6Q4FCPFoRgqDvdIYLQio5MaSWBoyC0l3Th2XqgiMXSREYWlOzeEWYGxMsFkEBja4ixq2ZkZqjUfP9ZKyyXpJ0r9N3Dr0yfax69LGEOz7gnJjZFsDrk6brqcOuwKzK1R57qy3gJyazTHFjdd5thucXGzRnSxuTEsov49Ebk+lKOD/PtB4o0KohXUf1/03I7lUPJADi6bncJwM6vDqwjZPaapZPKUH8Byca4vFyMZO9EYLmDKuRsnmh24N1WCN9ea8NUT7fi7ay786Pkp/PT+HH7+0gJ++WgRv3plDh89WcEnbx/C775yGB+9fRjvP17Fr15dxj/cm8J3rg7j/nwJznYm4mJvCi72Z0sZmEwq6nI94uhlZ5rhYCX1hALnSrcqOWkSxh00NFQhScDhlkQcaUvCkbYkHJbkhp25ETnSlCJCCAwLo8wkwp3AL3uKKVGCvjTPuPGXLzDyOQPyZfmEAXnGYK4yDnMVDkJmYnWBX7UiozJRFq2bYnJXYGgZGXn8WjuOPVIUqVRotGPZ+hHtSCrcG0zOcBE59Cu/7gxHX26Yjt6cEHTnSuSEKXRlh6IrO1QSmBB05IQqtGeHUJFDvzJeFRjaeOslAncFhiUnsmC4EwylPeHxnkBJYXFXYHgCwROQ22N5trg1XsAhTyKXQZ4pt8dzdbgvMRwBs1gh8jRD5K7AuIvdiqHVjM/lERF3w8k0gbniSfjYCxuQeVuJzfbhKJXj/jxc6M/DQOo2NIQJmC8KwOn2JNyfLsPjgy34+qlOfP/GGH5ybxY/f2kJv3y0iH/60n78+tUFRWA+efsQPnx6UBGYH92dxHevufBgoRRnOhJwoScZF/rEJX4sgTnVmY1TndnK0UvazShvCMyxtnQJWvvJiDr5pMqLFm1lhy4xqRLJymTUZ1FgaBJDysxiVYwiMORNJqPIOAzIAqODvJYtVWSmK2I11RnNOLZmrwxzSZ6JzGj3yngiMMOFURgqiMRwYZTysoj5HSZZVgxCQ0hMb04IenNC0OMMYwpMd06YTl7ckRiB9k1E99OXxyFbtdxtrZTufYGx0oLgC4weuxURrnB4XWB4sAVqv24AACAASURBVMTFosDwvgZCcIzC4x2B4WZ13BQbUlDlP3+yQscTXLuC4u0pKytS494YubEVbGmKyksCc2FAGjAYyMX5QSfODObizGAuupME1EcIWC7fhwvdqXi4UIynRxrwzpkWfP/mIH764hh++fI0/ulLs/jN6wv4zesL+OjJMj75ykF89PYq3nu6ht88WcWvXjuEf3ywiO9cdeHuTAnOdibjYm8aLvRl42yX9uAlQ2SI21GqwKTgeEeSgjyOzUTzvsc7kigL9FS5YQWBtS0nueJifHuChFF+WALDgt5aSjZIjDtSc6DOIf0qCsxyvYNAHc1eqiPbS2qLSb6GbTkvQ4aBDWPaIqTAkBUZ8rgkrTpDn2aSUIRGfxVbXoznKomW5CVahDKGLVduRIERTxdoD0yOmByWZEkNuRiPXJAnt5ZksVEqMhSMOZkgJgLtG4u+b26eSWHnVtjSQs8gWKygEE8o2gCoO9kJtQViT0C8LTAkdybybXGbi5MD5+NtCox9ARMrSZ5miNwVGHcrdFYyWXawKzasnJnViT9+lo1xxNTiLSougzm4MJCN84NOnB904uyQKDGdCQKaogSsVoXicn8mHi4U48nheqbAvPfGIj5+axW///phfPT2Kn7zRJSYX712CD95uB/fvjKC56cKcb4rBZf7xRtY2uvexk3DWdK1bqPAnJSOWKryYrwBZUVgRNIMAsOr3DzTmqJUXIzSwxYYkTSdwJhxhHGV24rE8KUmCSv1STjQkGAQGJmlOuPYtSwwi5LEmFVoyFYTXWIcOmhtJp3QEEvyWC0mcpqJFBh1228kxkuiMFoag9HSGEViXMWxcBXHmgqMKDH2BKY/L5QpMMrOGE0+RhaYHmeYWpWxITOCu+Oexm90+mwKL9x4fcipK8273QKiCIw7wmLMcKyvgHhbSD5rAsP/GpxUvC0wnsJu7Ynw/p5wW4zrjBUZYskNT3h4IXry4zwRGDU8zGldmYyTXxjIxrmBXJwbyMXZISdO92ejwyGgJUbAWnUYLvdn4tFiGd462ox3zrTh+zeH8dMXJ/DLl2fx61fn8N4bi/jN6wv47dMD+P3XD+ODp8t4//EqPnr7MH784gL+9uYYvnl+ALdGnTjbmYzL0skG7RFM2rFL8nG9yDCOWFIyM7LA6Ko2GoERsd5+UrcHU97enijCbEfpMzeeCgwL6yJjFJgDDQnKWLaCJC8rErz2krXcTCyzIqO9ks1bjke7lm3loCStIjNeEoPxEo3AKBjHsHUhYKnVRAoMD1JgeBWZPglZbNSgb4ipyNDkRfuYbYHhLYAzhGaJbMF6CQy39fCFwGyowKiYfzzzz+0zIjC3NO9LY70Fxko1yWoriiYzLDmyXu1hjZGTU1HeEZjT/dk40ZupCMxKZQgu9aXjlf2VeHqkCd88244f3BrBT+6P45cvz+K9Nxbx/ptLeO+NRXz4eD8+eLqMD54u45OvHMUHT9bwj/fm8ffPz+Cds724MZKtCMzF/lzddW/WrSia2JACozuNIIeADRe5yQOXstwYBcadPI3hfQiBMU5G2RcYLWYyYyo2DclYa0iWpCVBJzAHKAvyaAJjNTdjFv5lSgx1FJsvM/xjkoTIEAKjq8JIAkMuyqMJjHzCwEVUY1hCw8vIkDKjFZh+3cRSGBWzKsy6Cgxv/PjGcB5uujTfbD1o+2ifUORRXMvC4m6GgyMgdlok8ud4brJg3bjDwa7APDeZZwlPBYYvYIW4PVG4YQJze6zAFJ7geH2snoL59JW52CjTV9JY+k0N8r9l+YcSLdo2sZnAyBLjucA4cXHQifOD+Tg3kIdTfVk41p2OtnhVYK4MZOGV/ZX48jMt+Nb5Lvzw5gh+/MIofvVoFh+8vl/hozcP4MPHEk8P45OvHMPPHuzH92+N453TPbg1nI3zXSm4MpCFywNO3eg3eQPKTGDkjcJ6iSGzNOkEqUTVhlOxsSA0ZlkbY1jYbNSbDv0aN+3ytnWZIQXGWKVxUMew1QV57NCv1fCvVmBouCsw02VRhqOSVi5jj5dGUG4ykSJD3/SrikykASsSYyUXYyYwfQrh6MsL50oMS2ZsC4y7+1PWQ2DcERZvC4zdCsN6yosVgbkzmcfB/OOtCgwb86/fqsB4CktsFAHh/j3ZWIGxImT0yoy8K8epq7CQ1Ra1FWYUGDN4+3dIkbk6KML/fqQXn0tDeYrAXHIV4fJ4MU73Z6MtXkBztCgwVwez8aXlKnzleCu+faEb/3B7FD+9N45fvjSD919bwodvLOPDN5bx8WNxCunjtw7i/ccH8d6ba/jZg/34+zuT+PqpbtweycHF3jRcH8rBlcE8pQpjOIRp4Yq38eK2XnTkW0/aio0eY8XmeHuKJYExlRhmi4q+t8abAuOOzJgJDG2/jFZgrEgMr81kVWBYe2VmK6LpMuOmxJDj2FqBERE3/rJHstX7S2YCQ2KWkaFmZSRIoZEFRouVqoyMwA/6WZ8MsjIFZBw/Zm1wNW5ytSIw/MyE9IRkuQViLhz2BcauANgTBLsf//xUPhXvfX0WRc3DFpt9gbGZ4bE51UZ+PnJBICkg5A8OV0eduDqqfTsdUlBujxTi9kghbo0WSo+xMkB0mSGrMZ4IjLjQLw+XhvJwfjAfN6crcXumAqf7stAUIaAtRsD+iiBcHszCays1+PqpTvzd1X785LkJjcAs4MM3lvDhG0v4+MmyIjDvvX4AHz5exY/vTuFbl3vxzukuPDuWi4u9abgxIv7e8uQUuZtG3RKcThGZTGmTcKbuFALtqC7tBpR60JJdsTG2n2ikaALEZiFhEquhYbbcmLWczCaa9CRTUe8zxWGtPhZr9fEKq5RKDDmezWovyRUYVWIc2F/jYErMQnUs5iqjqAvy5qviMFceK00tyTIjni6Yrog0MFUeQSGKKjATpbE6gdGOYdNHsqN1aCXGTGjk8K9VkdEKjHYMW63I8CXGI4EhBcSTUWW9eOhL8+wFasZFarTKiVVh0UqLexkO7wqMVQHwHoWmrJfAWGW9K1D8Cg+9MnNnXMTTvyeqIHm3AsgTJGPGS670FEpIVRmbAnPHVYw7rmLcHivCrdFCQ2WJJzCkyFwfEjFrNVGrMMP5uOoqxLXxMqw0xKMiSEDBbgGVAQI640WBuTKUjTcP1uGbZ7rxg+tD+OnzkzqBkSXmozf348PHB/DRkxW8/8YKPnqyhp/cm8a3r/ThqyfacWMoQxGYq8PiVmLaaLd+0Z7xDAJNYIxhYHOBYbWmrIsMmanRIwuLsaKjz9x4U2CsyIxWYI40pVAkRto/0xAn4dBJjCwy7P0yDtMqDSkwNGSBESEX4oksVjqoAjMjQQqMUWZEgTHskymNFSWmLJYpMHqJsScwJCyJIQVmMD8Cg/kRTIGxKjECP+DnobBYzBasp8Dw2w/2BcbTysj6i4s1gbH78S9MF+CFaTsiw/v6rH393m5RkRkcT1uA3IyPTYHRfs2mAmPYn1NI5born/q4NvNya7QQt0fyJZy4PeLEHVe+yKgTd6Rwsygx+YZMjJXFgcaAMD0MLAvMye4sDGTuQqm/gIJdAtqiBHTHC5jM9cGZjiS8tr8K3zjViR9eG8LPX5jCL+6O45f3JvDBK7P4+LVFfPL6An7/eAmfPFnA758u4uM3RX7+YBw/uNWHr55oxtX+RJzpSMD14SxdBcaTbcKyyJztypByM/rbTtoqzrmedJzuTiHQi4z2MjfJqY40A2T2hhUSNo53s0PD9EV71ttOnlRmDNWZJofCwYY4rDUSSBJjRWCsLckjBUY/pq0VGVFc9OPXamtJLzCkxBgRW0xagZkqF9tHssCMl+mvZNNuLsktJ1ViWHeX6DkZeSGe9kr2UAH9KrZ40iBUPEegiEwI+vOCxXxMfpjSWlLGrokTBSRcgfF4RNlEYLSleXcWqbGeYNwRFuXjlQyHe7hfwTAXF1kA1o8iDuv98eZ4S2A8FSR2tkefIVqv1pY3BUb7b0EVfbUVpv0hgCUwMrfGinRSow3r3nTl48aQE9cHc3FtIAvXBrJwtS9TpD8dV/vTNWc37AmMKjLGXVLXXaK8XHUVYqk6GvOVEXhutgr3l+rx8nIDLvZk4Eh9JE61OXBvMh9vrNTgnePNksSM4VcvTuLDL80pAvOHJ/vxx7eX8ce3l/HJ4yV89Po8fv5gHP/4/DC+dakHD+YLcGUgA1eHMhWBsbqQz3gCQazIGIWFLjBnelMVzARGV9WhyIwiNYYsDT1jY5AYIjTMbzW5l5uxKzNHmhN0EsMSGPMtv9YkRiRBB09g1JyMKjAiMZivitEJDIkVgZkojcVUWRwmyuMMAkMXmRgd7oR9R4siqQIzXKjeYqIJzEhBqE5gBvNDlAqNlj5dVsZ4b6nHGQLBbCzzBu0nN6swQoZktsAbAuOOsLCeqDwVGLsVEt4T/N2ZIpuUcLD38esvWNYEaqMERhXZjWqBWRcY/fuI7bNbY0WKrFx35ePKYB4uDzhxdagQVwYLxAOM0rSN9qr0+cFCnO514vxgIW5MVuH+ajtuz9XjxmQFro6V4vpYsYjFY5s8gaFlZ5SPHS3E4YYYzBT64+JAJt4+1YN3Lw6JnO3BOyc68LVn6vC1Z+rw7TON+OHVbvzsuX68/3AMH786gd+9NomPX53AHx/P4E9vzeJPb83i949n8MEro/jFvSH8/O4gfvzsCL57uRNvHm7GC9NFuDaSx5QYa1uEyQmmdFO0AnOmNxVnetJ1aCegznZl4Gx3msKZzlQDsqiomRrydXIKij3mzRIYq0crPa3M0IUmQcfBJgeBMeh7oC6OeUySvIKtLsYzVmRojy1qmK+K0WwAVk8YaAVGRq7IkMxWRGJWIzJq+DdWvbOkvbkkh39LI3VMlkRIL0djsiRKx0RxpIHxonAd7OvY4TqBkSEFRhWZEAl92NeqxHhdYHj7OT4tgeFP31gTGGPLxLsViI0WmHtzxebMlpriyde0HgLjqSA9O1VIRf7zJl9n/X3wtIJkV2CMY/HEvwMpyyP/+7kzWYAbY048O1WMFxercGusCLcnihWJOdWRhuemK/DKShtePtCKO5NluO4qxJXBPOXJ9nhrEo60puF4ZxZmyyKwvyYOz3Rm4XR/Hi4OF+KSqwj3l+pxc6LUtFWllRirAkPjuisfx1sTMJi2FSOZW3GhLx1vHm7GN8714ftXXfjJszP4xd1J/OLuJH51dxS/ujuKXzw/gN88GMXvXpvEb780ht9+aQx/eHMaf3gq8vvHM/jtaxN4/+UJ/OalMfzyxUn89PlRfOeqC6+t1ePaSB712KV1kSEvcHOOVval4WxfmiWBkYVIKzEkxkwNK2NDZmv0oWFmxoa4vG0mNLKo0ETmaEuym9kZvcAcMkiM+ZVs61ex+ZUaUmAWNZUZ4w0mUWysSoxckdEKDIn2KrayKI8QGTkELEPKDEto3BUYbaVGKzBDisSE6bIyytg1Q2JkBPInIuM3G94Yp5tBWmkU2eoiNVJgaD8huyMsrCcqq3hbYHhP9lzBsCkg6/3x9itE3qkgsQTGbgvr3lSRKXcnCyWKqTw3UaSHEBT140XU37tYQnp9QnxfpV0pfb4748W4My6GbW+PFeHOZJH0g4T4+o3xItyUBObWWBG+dnYY3742g7dPDuHaSBEWKyIwkr0bw9l+GC8IQluyLyrCBGTsEZAXJCDZV8ThIyDVX0B+mIAOZxhWm1JxfrgUFwdzcHU0X1fp0bantC0q3XoFw7i3Oed6UjFXshdDqQIWS/xxYyhDnDw61oy/vdCHXzw3ivcfzOCDlybx0cvT+N1r0/jj4zn8+emsjr++NYe/PJ3Fn58uShzAnx7vx8evruKDl/fjh7em8NpKHa6N5Fm+86S9L2dXYBSkS9wyxlFutXpjLjC8kLA57k4/8WRGFhiezGgX6tFlJlERmEM6kRFvMpFTTe5IzYG6OEoLSludUVmqi8dSXTxVZEipoUkMDb3QELtliCOStG2/ssiIv0YzJCZCB1mNMbuOzRMYrcQMEQwUhitYaSutq8BYCUeayYvZHhLWT6A8YfG2wNivkHwhMJ+GwLBbYPYqQHYFRhURQkgk5I+XP5/6e5fo3l8VHLl1Jn4+rcDcGS/G7YlCPD9ThttjRTjWFI+ro/m4OVGsVGG+cWEM112FqA8RECMIiBUEOAQBKdKvcYKAEEHAbkHATkHAHun1FD8BWUECQgUBaX4C0rcKaIgRcKorFTfGxSrP7YliRWBIZKEy7rMxz+qoraUcXOhLxzONUVirDsGZthg8N+7E07UavHuqAz+43IVfvjCGD16axIePpvCnJ/P47+8ewf/53aP4v793HP/j+yfxP75/Ev/P947j//rOUfxv3zqG//Wbh/FfvnoIf317FX9++gzef7SEd88P4MXZUqWdRTuLYO0Sd67SnhMxD/+6KzDkOLehJaUgj3anE/CmoowCY0liKJUZWVZoUsOSGSsCc7QlUScwosTQBUZ7cJIlMTqZIW8zUao0WoEhoQmMMTfDlhmWwMj3l2Yq4zBdEatblEdKjIiUoTGIjL7dRFZltOJCXsd2lURiuCQSQ8XhCrLYuAiJGSoI1V3HdltgyL0NxmVbnNX6nA20/Mke8zFkbih2QuXuVD6Te9MFVO5OORmIH8drRdgVlPscXpwttkmpKffnS2zxYK4ID+aK8OJsIZV7c0buzhYo2P3v47e4zAXmPgfy/cjXX5wqMkUVC5qsFOPuZDmDYtybUgXL8HeXFCXi77j8+W9Ol+PGVBkuTVThwmg5LrpKcHawEGuNcTjckohzPam40JeOs91JONudhFePduFbN+dwYrgUMYKAXYIAf0lWdgoCfAUBewUBwdLbgqS3p+4UMN+YhtP9uZguD0NXioCGKAGDGdtwsjMFV4dzcGu8ADddTqWtdWe8UBEX5iJA5pI+SWLGS3DVpU5PXRjIxLF2B462JOJcXzZeWmnEW6f68LfXx/Hjuwv41YN5/PqlRfz2lQX87tX9+P1ry/jT41X85fFh/PXpEfzl8VH89ckz+OuXz+DfvnkZ/+0bl/CnJyfwD7en8bVj7Xi0UIFnx/KUDcVmo95mG4aNFZl0An3L6Vw/SboOY4tK/Dzne9MUzvWkaiBbTuQmYb3QkBUad0PD7ImoFJzqSMHJ9iQdJ9oScbJd2gosnzdoT8QzrQm6193JzpiFf41Xs9ktJ4PMMNtMtOyMnsU6kfnaGIW5mmgmrFaTKjWizMxUxmBaEhryOjZ5XFIvMpHMdhNNZLQ3mbQCI99gYh2TNIpMuG4cWysyZkIjmG0JFb+JcKYgCHFxfwOtvXFjM2kxExeVPAbi20mBYVUAPK2QPJgrMeXhfKlNyk3xlsCwoAmMls+7wDyY1kMKjFo5KdFUTVTuTVVQBebeVAnuTWl/P1Ju9V/nvekC3dvl3+/GVBmuT5Ti4nglTg8V41hXNtaaU3CgPgYHmxw4252CO5NFuL9QjlvjebjkKsCbJ3rx8PgwunMDEb9TQNwOAX6SqETuENBTnoziOB8ECwJitggIFATsEwS0Z+zFtakKnBnIw4H6KBzrSMLhpjic689Ud+yMFeCF6RKpvWVfYOSwsBJEHsvHjfECHG9PwXCWD4Yyt2O2JBCn2+Nxf64M3zzdhh9cH8Kv70/id6/ux0cvz+PPTw7iv7z9DP7rV47jv331NP7ta2fwX9+5iD88PoZvne3B4wM1uDdZiBfGxDHxW8PZOoExkxjagj5qu2kgUw/ZhhrI9khgSIlRoZ9AYAkMK3PjrsSwBIZEFhlywZ5OXjZIYNzPy7gnMCQ0gdFKjCwwIuJU02xVHGYqY3TXsVkCI7eeRImhVWmiDJkZrcDor2KraGWGdlRSKzDDhRHKXSZbAmP8JsIXGP4yN34lxVsCwxMW8omAJzC8VoQsIp4LwHoLjDl2BebhQjEeLhQzBeb+vBGtwPD++3ncnyszhSc4D2eK8XDGDWGS/rzVKpb6NrNKmtqykhGF+P50Fe5NVWgow72pMtyfFlF/P7mqpa+syV//w9l8PJzNx0vTBXg0U4j70xW4P12B21O1uOoqx6neUqw0ZGKqKBpdybvhyvTFbFEwVsr24XxnMl5eKMFXnmnCa6tVeLRYgjePNOLNI4147XATnp0qxOX+bJzvSsON4Tw8PdqJ52fKcGu8AFeGMnG+NwWXhtNxaTgdN8ay8OJSCV5drcI3znXhOzdG8dbJdjw/W4I7k+oPBM9N5jF+0CGulisnH+hXyK+PFeLGeBGuTxbjymg+Lo8X4/mlOhzuL0Z+iChW4VKbK3KLgLSATSiI3oOaxGC0ZsWgKy8Bw+WZmK7OwVhZOkYKEzCUH4/ZUgc6E/dgODMAV4YrcGO4AFcGnJrxcBHWmDdXYAazcHkwyyguDIExYPL+rAoMTWBYaNtTZgJDYhYcZk1EnelMZYsMbUuwbmOw9XFtd6aZjNkZhy5DwxebWAm90KwSyEcnl+qimSzWRinsr4lRWKo2VmRmJXmZrXJgtsqBeQ2ytMhCM1cZpxMYJT8jVWNIaC0m8io2K/zLOiapSIxcpZEEZrBIhCcygtkdlzvjhR63gLy1Cp8nMO4Ki5ECBpLgcLIg9isYGyswDxbsIQsMC5rAaPmPJDBmEmNXYFQpFP+7aQLzYCYPj2YK8cpcMV5erMUrS/U425uPgw3JmCiKRVeKP6pDBRTuFlAfImAwbSemc31wuCYcl7ri8eJUHr56ohXfv+HCzx7sx4/vzuGDx8fx4dMT+PCNU3jvtRP47ZMz+KeXj+Kjp2fw8dtn8buvnMUfvn4ef/zmBXz05ZP44MkRfPLlE/iXv7mAf/32Ffzm9cP42rluPDcjTnzJuSh1+SB9MSRLYMgbWDcninFzohjXJ4txdawQVydLcWO6HEtt2cjdJwpMkCDAR2qB+UnslfCXcjx+Uq5HfnuE9HFDGXtxd74Vz02U4caw+r1R3TTspAoMuWGYdWNOFhmDzNgQGPntZFvKU4GhwboBZRYctio0pMDoNgRTBMbqnSYrU0wyhyn5GRFatYYmNPLuGUJwiK3A6uXsGB0sidEKzP4adSxbzs/M1cRjriaeKjBacVGJMQgMDaPIiAKj3mUSd8xYERiaxAxLEiO3kGSBYUmMLDJeExhvSYm7UzyeiIv+CecLgVlPgXlA4dMUGB4vzZXgJXd+P+afGzsH9OJsIbOlJVdK7k9XSVQoAvPibLlBYOSv9+XZMpG5TJGFGLw4HY57Ewm4P5mIG/1ZON0Uh744X3REbENt4A44twjIEgQ4twio9RfQF7cDY+m7cKgqBpc7knFvrBCPD9Tg68da8a2zbfjRjUG8/2gOn7y+jH9++yD+9Z1j+D++ex7/84fX8O//cBX/7z9ew7//w2X8zx9dwr///UX8+99fxP/83nn87+8ew798+RD+8MZ+/Oz5cXzzZBMezRfjxak83J8vkQRGGiGfKCHQT2XdmSzDnckyJQRMcnOiFLcmy3BzuhTXxotwcbIINxYqMdOWg9QANbuzWUKQ2EKwXWKXJDRBgoAAQYCrIA6XJ1pxa6ION8drcXusRKJAJzCsy9u0Ewl0gckgyNJD5miIt5sJjjFfk06ZgrIvMOT0Ew13KzOm5w40AuPOuLaVdtPhlkQFUmC0sGRGrtjIIqPeaHLozhvIFRq5EqNlqS7WgLb9RMqMtiKjVmYYt5iUEHCEhPGwJHlcUn9gMgITZeEa9MclWftlzKaXtMih3iFN0JecWBoqCIWgDdSR0MY6WT8xeWttvicCYycEu9ECwxOMR4tlpmy0wDxaLDGFJjA6/gMJjBaWwJC8OFMpUS0hvT5bjgdzFYZW3aP5UjyaL9UJzKPZDDyYicDdiRDcGY7GuVZ/zOXuQmuogIZAAdV7BBTtEJAuCCj2ESnbKaBur4D6QAEjKTtwsi4Ktwey8fpSJd453o53T7fg7y5148e3xa217700jY9fW8TvHy/jz2+t4c9vreCf317FP3/5AP789jL+8tYy/vRkEf/8eBH/8vYB/OnxAXz4aAY/vD6ANw+U4sWpPLw4lQd16aB9gbk1VoQb4yWKwFwZzcfFySLcXKzCVGs2kvxVgdlKCMsuQcBuYZOCtjIToGk7jRUl4NpUO26M1eCqqxK3Rotxa7TY0EIy2zBMu/Ekn0iQRebKUCYBITgcgWG9nS0y2aYYQ8N6aB+jHQfniYyZ0NAW7p3qYsiMtBnYrsAYr2ivn8Cs1ccrLyu5GaUSYy4zZIaGVZHh3WJS8zN6gSGRw8A0gZElRvzVKDA0kSGPSbIERisxNNZVYNZzMy2Jp/KiluI5gsOqnGirEItlHsMTlPXGztf+cLEMLy+V4uUltsg8pKAVGPsCVm4LWQjcFT7D20xyQCJleDBXZpgCe2m2Cg9nKvFwphoPNQLzYK5ChBDFlxfK8PJCGV6ZK8fLs2V4bSYJr0zG4+F4IO4O78GzvYE4UiJgMlZAT4CAyi0CyjYJKNksIEcQULJLQNFOATmbBORvFVCyU0Bz6BaMZ+3FSkUcjtXH4WpfLh7NlOKtg0347vle/C/PTuHDh/P4+NEi/vDKEv706jL+8sYy/uXxKv71yTL+9cky/u3pfvz3Lx/Af35jBr9/MIJ/ut2HH55rxDsHy/HKRBoejGXg5clsvDiVh3uT6pQfOU6u3XcjrkkoEVGOa8rHNsXxcLkCc22qDJdGC3FhqhJX5+sw0ZSDhN3i1NQuqbqyQxCwTfp1p9RWkltLuzTVlz1SKHmvIGCiMhmXZ9tweawSF11luqveN0bzdftqzE8kkAcsrQmMCr0FpYiOieBYakkxcEdgRIkx32fjbmXGeOKAlBl1GzC5HfhYW7LuTtMzrUkaUhhyI779SFuSTmJUkg0SoxUZ9TF9fsYwti3LjJSZOUDgjsBoX2btlmGPZkdJ6KeYtAIzoxMZ1pVseeOvUWB0oV/KQUlZYsaKjZNLZersYQAAIABJREFUw7r2klFkvCIwG7k632qlxeOf8nktFJsCwBOMl5fK15WXbCILDAuawGixL2AVtvCmwJhLjFFgHsyVSfIiCsxLszV4MFclUYGH85V4uFhGFZgvzVfglblyvD6bjIejMbg7vAcvDO3G1dZdOFwkYCpOFJjq7QIqNgso2yYgXxDlpWingNzNYjspVxBQsVtAV+xmjGX4YzpnD+bz92IpbxdWi/1xsj7k/2PvreOqvvs/7g/dCAIGBg2CdEhK2TNnFymhlCJ2x2YnKohKl4oxezrn5qabMadO191xLa9dsWtXPO8/vuccTnJAvH773ff9++P54HCQgeh2nnvXi6fGeVCeGkhVdgQNeVEcKRpIS/FAjs+P52RJLKcXxnNi7gDqsvyoSvNk+1gHSif35daOybzw9JPsnOTG7qm+lKcGsis1RJIYxTp4lGxdXEK+tdV6CTmarWnRShUZCXnFZlNqDJvTYtmYEce6lCg25A6htORJssdE4mYpSYiVkrQoY6GEldKauLVMXmyFICPJj/WzRrFmeiyrp8UoLhcrUr31HNzTJjDyuzVygZEeB6gRpIb2FpQ+gWn3TI2uXKeJ2lGOlXgcAqNLZpRXt7XLTPvu0LQ/6sBbITBy1AVGGW0y01GBKRziriEwuioy+rab2jqQp11mWgVGvsWkS2AkiemlQ2JaBUZ9XkaljaSWxaTeUmprBVubxIjWcq1mKVfbYa2OZgH9ty/TPqq4tPcFS/+LaNstFH1U5ETrIbZN/miB2T9bQp/IKNPZn5lqhadtQdQnoHIh6GjFSrOCpb1dVpYlJ5ayrFj2ZcawLzOG8oxEyjMS2ZYlsTsrlN1ZoZRlRbBvVnhrq2i2K3tm9ebgHFsaS3pybZMFr2yx4o1dBjzYbcg75U7c2W7J80sEJ+YIykeZsiJEMKe3ILWrYLiNINFEEpgBQhBpIIg1FYQLQaCMYCEIMRYkOwkm+BiRFtqFOdG2FMU7UBBnS3GyIyuGd2f92L5sneLJzhn9KMsM4NDsMCrnBFNdEEpNYQjVBcE0FARRM8efyln9Obs0iRc2jKN2Thg7p/mwN7U/palBlKYGKVq/29Kj2KY01FyaFk5pWjh70sIpTQljV2oku1Ij2ZkSroL8v1tb06LZkTmQNdMjWDohkNyh3kwOd2JAHzPczKVKirVSdcVSJiryaowceRXGWoaDXGCGhLAm60lWTotj5bQ4NsyMYWNKLE/PiJA2oKZrux7cSuuF4TCVUEzNtO32C4y8gqNZpdEcDNaYlZnor2g5ParUKB/i0xSZ9idyS0LTr030z8y0f2V78UgfnSx6wptFSmna80d6ywTGQ4ZMaEb4aEiMdplRHf7VmpytdAE4XyYxulaz5chnZ+RbTLoO57VfZPpoCIwymUor2RK6UrJVwyV1bS/pSsbWHSKpGVWgLDKPXWA6KyodvaPSkUqLNjHprMB05IVbG/oE5kDuwDb53yIwuujsz0cf+r4/vS2wxygw2ijPlhNHeXacQmT2ZyaxPzOJHbnJbM9JYk9OGHtywijLipBJTBR7MyLZl92Xg/menFnrw9WdEXxU687H9R583diNb5q681mdCw/32nN1ueCZfMH+0WYsDxbk9RFk95QEJt5YEG0siDKS3kYbSwITZSIY18eaFL+epIY4Mju2L4ue8GbdpFD2zIqiqiiZmnmDOLxkJBefnsjV7TO5tiuFl3fO5MbeNO5Xzua1ijRu70/l9YNpvH4wjdf2TeXa9nE8u2ooR+ZGciDTn/3pfhzICqEsPZDS1CD2pAUrBGZ7RkynBWZzSiQLxvoxpp8RLjLxsBGCviaCnkaCXqYCRxPpeXMlgTETqm0lS6U5mG5CuiqcOiiIlRmjWT0jgbWpSWxKjWNjSiybUqOkCAatN2rC2i0wrQSqEaxXYLTRHqlZPdG/w9eDdV0S1pSYtkMsNSVGc8VbVWL0tJnauD/TEYGRI283zR8px1NDYJTRJTPq8zPqa9rKF4DlApPfjjszyhtMbQlMWxEG6gKTrTL866ZVYFolRldCtjQjo28dWx4yqSwxcmHRJjLK7SVtszJC0QpSFxgtQYbaT+s/3lDC/6lDcIoXpew47Wi0cP47L8CdFZj9sztHWSepmBNHxZw4vSLz35KazgpMRytZra0zzb8XbVWK5KIkPyBYNiuBslkJlOYkU5qTrBCXg9nhHJgVRmV6ABUzfTk9T3BjgwF/PtITLvrCcz3hUg+4YAtnrfl7UwBf7OnF1QUGnMoSlCUL1gcJFvYVzLYXDLcSDDKVKjAxJpK8xJoKRnU3IzvYlXVjItmTOpwDRcM5NG8kB+cNpX7JGI6ufpKTT03imaencHbzdK7syeRWdRGfnl/PL6/u5dfb5fx6u5yfXy3lw3OrudNYyM3aOdyszOJaeSqv7Evj0uYJNMwbyP6sEMqzB1CWFaGYO5P/+16aGc3ujCj2pQ9gX/oAytIk9qcNoDy1datwY3qEjEg2pkeyOT2SLRlS9Wb9lCDWTA5l8WhfZiW6MTnMEV9r6cCeoxA4GwgcDSSpkbeJLNWwEwIHQ0EPQ4GzscDNSIpSyB0SzK6iaWzLGs7GtEFsTYtlW3oc29KjZLlS0nq3zqiV6RFs0hJgKR8Clh/Ek9Oe8EppuylIhnzTKYj1kwIVyD+uTWS0PdaQHb0iE6KBJDEdSeT21ykwrY/1z8nIKzLq7y8Z5aOymq167denTbmRi0wrHUvN7ojAtBVf0JbAqFdjCnS0lVSHfV1VQyaT+moIjDLSSrayxKgKTGZcL1nAZB+dqBzEUxIYbZUY+V0Z6TieNlQrM0IhI6nRqmgNLmx/GvB/K/unPWvIHaqm/MECc2B2bJscnB3fJhVzOkd5XueQC4wuOiI2j4I+wdInOI9TYNoWVenryP9+lWclUp6VyJ7cQZTmJFOePYDy7AEcyomgMjeSyvQAyqf78OJKwXvlDvBcf7geAZed4dnucNoSTpnzeakz31W48eoyM05mCPYmCp4KFix1E+TaCYZaCAabCeItJHGJNRUk2whm+nRn5fBItk1JonzWKBqXTuDk+hSOrZnMM0/P4MzGaZzfOpPLuzO5ui+XaxWzudtQwnsnV/DN81v48vnNfHhuLZ9dfIoPzq7i9aYibtbO4fW62bxSkc6LO6fx4s5pvLxzJpc2TKBuXhJlWRHsny1VDeX/rsvngsoyIinPjKI8PZJ9qeGUy9AlMBtTItg+K5btGTGsGu/H0zMi2TNnCNtmj2Bj1hDSkvwIdhC4mUvVFHulVpKV0JyHsZX9GichVW08TQS+VoKCERGUzpvJjpwn2J49gj25g9g1K1EhMJtTwlQO66mjCM1Uy3DaNF27xHRGYLShrzKjG+2XhVsvCWsKjCQxemZq2og80B5/oHtOpnNr2pqVGnWBWagiMu07licXGfX5GfmxPOXDeeoZTPqSsguHaK5h66vIaIpMxwWm9baMK5kJfRVkKKVjSzlMqqvYcmlRlhl1gdEQGSV5UX88M9pZpSIzI7JX5wXmUSonHbqTom+I9hFbQIoXoJyB2pF9vLVaof0FVN8LuDoH8gaqcEgvCW1yoJPsz+8c8t9HR34G/5MCow+5KLb7682R0FZV0l5hiqQ8N1JDlCpyBlKRM1AayM2JpSo7kqrsSA6leLNtdDd2jTHm0Ax7vqkR8Jw9XOwJl5zhQn842w+OBcJRf77c5cfPB8J5e30fruQbsztSsDVEsLqvYKGDIMlSYpCFINFUkGwqGG4tyO1nQ0FAVxYPcGDDEHeqMoI5v3Q4VzeP59q2yby0YwrXdk/j2r40bh6YxWuVudyvK+BO1Wyul6VztXQaV0un8fLe6dw8kMabtbN5pzGfd+tyebs6i3erUninciYP9k3i3OJIqtM9qJ3lxaE0b+qy+1OVHcGhWWEcSI/nQHo8damJVM+M5/C0OI5MH8jxKVEcnTiAk5MiOD01muOTwmiZEELjtHCOpERRnRZBbUYkZRmRPP2kN6vG+1GaE8/+4qHsLx7K3vlD2VM8mFUzQiga6cbkCBue8DMg1Ek6UmcraxE5y6TFTvY40FKQFuvM6klhrJ0Swe7sBLZnxLE3K5amRaNpXDCSPbNi2J4SzvaUcI3FB3Vx0YXi8vnUEDZPDVE5jKdrKFhlu0mtcqOL1lZU6wCw8gyNrlaUrsvCGkwKfSwCo35wr/VxxweAdclM21eAVasxbQ35KlMywkvlsfIWk7rAaLv8K5+Z0VWhUR/6naeGxmG8DmYxzU7sLUO1QjM70Z1cNZmR2kvqoZLyNWzNcEldd2VaV7F7awhMa+aSdtSrMzoFpn3yEvVIVZP/CYFp70bP/tkJOlBvt3ROXP6/LjAd4VF/dtrobAXp4Jw4Dnbo60m0X8yi2T87WmNmqSJnIAdyE6gqSJLkJj2M0mn+bBhmx9JYY7YMFzRn9+LnwzKBebY7/zllx7+Pu/HNfmu+3u3IL4f68u2eAH6tiuLjrV68UmJD9WDBlmDB8p6CRU6CIbaCQdaCwZaCBBNBkolgiKUgx8eaPD875vQzYWG4PTuedOVIfgznVg7j+afHcnX7ZK6XTufmgVncq83jYeNc3jlSwvvHFvHJqeX8+MJGfr22lT9dXsuX55fz5eklfH5yEZ+3zOPTo3P58sgcPqrL5F7peJ5bOZDjRSE05fpROrk3m0c7sGOSF+WpgRzKTOBQZgLVM+OpnBZLw6RIqsaGUDcqkKZxIRweE0jTSH/qnuhHwyg/qsYHUDspmPLJAVSlhFOeGcWqJ1yYHefIktFe7M5LoHHVeJrWT+Hwhmmc2JrBMzuyaNmSSc2aqexbMoG12YnkjQsg/8lA8p8MZO6kEBZPHUDJpFCeSk+geX0ml3YVcXFnIcfXzqB+8XgubkrjhZ05HFs+nj2zYhTr3vJMJ11r3uqoZz9tmRbGlmmtUS4bpofJZmo0k7e1taCU0SUw2i8F6xIXXTM3OmRmUqgCSWLaMz+jLDSt4qLtXk17tpm0pnerVWjksqKvIqOQGB23ZTRbS95aBUY+BKwuMIoKjawaIx/+1ScwcoplzBvsTrGS2MirMh3OY0ruo1NgZie6kyOjVWJ0r2FLQtM2mjdlVOdiNMMjNQVGWWKEYgBXIS4x7MyI05sBpJ4F9LiEpaMC0941ZHWBaRWTtgWmtd3SPiHRx8GCeBUq8/WR2CYHO8mBgs6h/vtR51EEpyN0VsB0iaPm11IVP22fI4mQamtO/vfkUO5ADuUOpDpHojYnmtqcaJrmxFE21Z9dI/uybqAdKyIE62IFBycKbq734e+nXPnHGQ9oCuRPu3pwM8WGcyMEr0zowYd5wbxZ7MTbJd25XtCNM9OMqB/tQOlAQ5b2MyPfWTDaRvCEpWCUqWCEoWCMgWCcsWC+u2BVoAkrAwVrQgTbBgnqpjlxpsCTK0uCeHV9DHe3JvOwbCLvV87gvdp0PmyYxQeNGXx+bDa/nCvhLxcX8fslib+fLuT7w7P4vmESPzRN4demIXxVEcXHO/vwQ2V/OBHK7839ef9pO87MFFQkCnYMEOwKEpSGChoGOHIkpidnwl04HdqXF/v34jmf7tx3seNNDwe+8XTkR9+efBPQnc/7deV+sD0PQh24ktiL5+OdqYyyoyzEkp2J9hyZ5seFkkReXj2Se3tSeViewetlKdwtT+VBTQ7vNhXwbnMxbzXO5d3mYt5tLuZBbZGMebxRU8Sb1RLv1BbzXn0JDyvncqM0i+NLRrEvXRok3pUawa7UCHbKqjHbZoaxY0YEO2boFphWJOHZOiOcrWrhlVJ0gqwNNWOAArnEyFtQym0oXSKjfim4FfUtqPaKjHo7Sv99Gm3p3HJ0ZkEpREb3MHBbG0/qAqNtTkbXVtOSUdpWsFsFRrO9pIl8CFheiWlPrEHxMC+Kh/pQPNSHEhnFQ7y1UjJYQndFxkUFjQwmJYGZk9xH59xMTlIrrQO/rWiuYaumZKujfhhPvSKjPUBSWyq2hGidW5GLS9wjCczjEpKO3lnpyP0U7YOs/ycw/ycwjyYwlfnxGp8n//uiXqGqnB3PgZxYFYGpy42hKj2czSNdWD7Agnn+gpUDBNuGmHAsx4J7WwL5utaOzw5Z8fU2R67nC6pCBdtdBYd8BS1RgpMjBadGC5rHCA4kCbZHClb4CGZ1Fcy0EkzuJgnMSBPBE0aCCaaCmV0Ea4LNKRval7oJvWhJ8aJumhOHJnShIcWRlqxenC7y4vmlQdzcOoIH+ybwbnUqnx7O5Yvjc/jyRB5fH5vD18fm8N3RHP7UkstPR7P5tiGNLyvH8PnBUXxRHsHHpSH8UhsEr0yE99Pg1hi4Pg7OJ/Hxhn4cHS/Y5COYZycoMREsNhdsNBNstxE0dTXkhLMlr/W05E0PB75ys+cbT0c+79eV910tudJHcLGHoN7LgFNhttTGOVId60DZsB7UjHOjaro3h7NCuLhiGNc2jefVnZO5tz+Ne5Wz+KilmI+OL+bNhiI+ObGEb59dx68v7eCXF7bx0/Pb+P65zXx/fgPfnlnHh82LeVhVyJ2y2VzdmkJT8RB2pwSzY0aYIn18V2qEoqW0c+YAds7UttUpsWVmpOqWZ8oAtstv3ChVcBQZUDJ5kV8f3jBdek4hPGphvOpSI29J6RKYtmjf9pN6dabtWRpFuKVMYLStebcdUtmRDSfdrSfdIiOrxKjflJFd/NV+U0bzaN6CUT4qyAVILjALnuinXWLUBEYnMoGRV2PktM7HuKihOeybl+zapsDMSXJRERhdEiOJjKbAaJMZzcN4qhKjOwVbh8AoLtemx6jS7qu2qifT27pGqi83R3EuvZ03QDoyLKtrpkHngKystaCPA/mxKhwsiFNB/ePq6BeYuP8y7ZEo3egTGL0Spe/z28mBDtIqkNpFUOPX5ydSWZBEVUESlfmJVBUkUFWQQP2cROrnJHJ4drwKzbkDacpu/fM/NSeGM3lxPMxI4NaUcF4a7cuxSAdqo8w5EGJIRbRgT5igcqDg5DhTzs6054XcXtxeNYCrCwLYNNySZTGCEb2kK7puxgIvM4GvvQm+9ib49LQi0LUroe52BLnYkORhyWAfGxJlLaMJFoIZ9oJ5fQQ5DoKnfQVVyaZcSjPgvdVufLG1D++tceD2QsG1IsEL+YLrxYKXigQ3FwpuLzXj7acc+Hi3O98eDOCXxih+O5bAX5sj+PaQL1/t6c6Xpd34ttSc78us+Gm/gMP28FIfuOUFr/SCK13hWQu4ZA2nzKHFkN+qzPhqu+C1fEHLSMFOH8EqJ8Eaa4nSboJaLwNO+pnyjL8Zp73NeMbThNOudjzT14b6HkbU9zCiytuMpsAuHBzYjRPjfDk5awCX5ibx3LLhvLByJM+vG83Lm8bzyrbJ3NmTwoOKWbx5MJt3q3P4sD6fjxsK+KAuT/H4w8YiPmgo5KOmYt6rK+JGaSanV4ziUG40e9KCpVVvWStdeStTvtUpF5ntKVFs1yIy8svDijMWqeFStpzsgKi6yMhDK7emRbMtPUaxPq4yGKxUpZEj34KSr3Orr3XLZWXdNAndIqMdXcPDyltQqoPEwapVGT03a9o3R6NfZNp7PG/ZaD+Wj+nP0rH9FRKj7VieXFbkrabWao1sbmaUhPz9xSN9WfREP8W9mUVPeLNwROtQ74JhEuqtJHVKhkoUK7WTJNwpHuJO0WBXDdRFRmVmZlBf8lSCJDUzmNQlRlVkdF34VcdV62G8jIGupMe5KNAIkoxxJjPGWafU6BUY/fdV2jqfrl9gOnK0rLOy8kcIjD46KzBVBQM7SUKn+D+B0S0wzbkDqZgTQ8WcGI7NiuBIRig3J4dxKr43LQO6Uu4u2BcgaIizpnmYOcdG2nBirAlnJ1lxZoYdZ2fac3iGA/uGG5DvJ0jpLYi1EbjLNmp6CIGbhcDTWuDa1RhPJzOCXGzwcDAgvLsgoodgsIUg2UyQ4iDIcxMs6yco7ivYHiKoHmTGmamCVwts+WJrHzgcAyci4Vg4HBvAP5tD+c/RcH4+5M37m3twb6U1N5Zbc2uFLbdWdeX2Ggc+3t2XH2sC+c/RQDgfA5dD4VoMvB4J96Lgmgucs4NnjOFZG7jqADec4Q1feDcY3kqAe9FwIZLfynvwMN+WE0MElb6Cva6CMmfB3p6CCkfBPjvBfiuJamtBnZ2goacxh/tYUOFmyH5XAzb3N2JPhC07BjlROd6TI7kRnClO4NlVw3nh6bG8un0KDw9k8WF9IZ82F/Np81w+aSrkk6ZChcS8VzObt6tn805NHvcrsnlx4wRaFg7hUE4E+9JDKcsIY29GJHvU5KUjAqM8O6MuMNoqMZvTotksu0q8SW2rSduwb2urSRV1gZFXaNZPl2htOemWGOXnOyIw8oqNykaT2iq3voyn9siMtvZSe7OZpERtf5aO7c8y2Vt1gVF+Tl6ZUX5/4UhfFo7uz8LRrTlNixUS462CvCKzcLgPC4ZpH/TVJjDKPG6B6ZjEtCeuoPVA3mMXmNbqSbQa8oqKvnP7/z2BeZyiomvwVv8Qbdt0VmD0S0JnBeW/KzCVhf87eHSB0Y6iRVY4iIOFg6jKH0ZV/jAa8gbRkDeIurwh1OUNoSEviYa8JCqKEqgoSqC2MJ7awnguZ8fwXFY0704O4t4Yb75N7MmXsY4Q15PvvAz5zFfwdaARVwcK7o405ZWJgtvTDLmTYsLtGcZcnGjGyRGCiiQLnvIXjLUTJBoIvCyk+ybyVGVLIehiaEBXC2O62VrgbGdBDxszXG0ErjaCCAtBbBcjpjsJCrwN2Rgs2BYhqIoT1CcJLk0TvJZvyudrDPjzTjt+LzeBejs4aQ/ne8DZnvC8G7zsA1fc4XxPOO0Ep7rCaQc47wSveMHDELjnD3cD4c1wuOUN5+yhWcAJM7jRG97yg7c94S0PeMsT3nCB+x7wuhu86ALPdOG3PY68VSw4N0ZQHSnY4yco9RVs8RFs8zNge4gJW4KMKHYTpNgIRpoJxlgKRtkLpvQ2Zqq3BVO9LZjiKZjmZUCqrwE5IRaUxHdlxfBebJrowb70YKryIqibG8Oz60ZyZdOTPL9hNJfWjeD86qGcWZ7M0eJYKrMDKUvxpXS6NxWp/hxMD2J/Wij700IpSwtnb0oIu1LD2JUappThJM0Ubk6PYHN6BBvSwmUMYEPaADalhbMpLZwtqeFsTgljS0qYdHMrJZTtKVKW3JaUEElmUsLYnBLB09NCWDM5mFUTAxUvrGsnhrF6QijLnwxixfhgVk+MYMX4UFaND2b1hFDWTQxh0/RIRXr2tpmRbJ0+gM1Tw9g8VZIY6T6N7PDeDAldl4UVwjI9SAWdG1CyCAXl9pL2xG7tq96tYqO8uq17KHjVeH+9UtPRbCb1+Zllo/spDue1HtDzlyG1nhStJiWUBUb9zox86HehDF3bSrorMh6UDNV96Xee2qCvZhq2C3mD+mod/m37now8AdtFLznxfTXQbC+phkcqNpe0CIwyQj2rpRX58x0TmEdtDT2OdtCjbAn9twWmsnBgm3RWYGqK4jtHYWKn+KPFpbMCo+vnriwwh4oGU1MwnJqC4TTmD6YxfzD1BUOpLxhKY0EyjQXJHJibyMF5yTTMTaKuKJGLmZGcSwvj7mgvXozvxqdRdnwaZce/ohz5LcyOnyNt+C3Bifen2PN5mjMPMiy5l2LG66lm3JhqwOnRguYkwbZwwWIXwUgbwUDZqq+DTF4MhJSybCoElgYCW1MDupob4GBhSF8rgbutAcFGgigrwSQ7QZ6XAWWJgiPj7Tky1JTGQUY8N11wO8+EL9cZ8a8KZ6i0hCprqDGEWiOoNYEGc2ixhZMOcMoRznSDZ3tKPNcTzjnAMXM4YQnHreGELZyw5D8Ngp/KBP+sF/CaK3wUKgnM/b5wry/c7A63ektc84ArfeCoP5+vEpwcLigLFGx2EzzVS7C2ryQw+2Js2BVhwTI/Y4rdJIFJEIIYIYg3EsTbCIY6CUY7Cya4ClJ9DcgKMiM72Jg5ERYUxVhQkmDLsqH2rB3dgy0T+7BjqhtlqV6Up3lzKKs/DQVhNBYOoD4/nEOzgihL8WXvtH7sm+5LeWowFelhVGQO4MCsSPZmRFKaFq7IcJLPFG7JGMCWjAFszhzAxvQIrQKzRVat2Z4Wwc60MIXAbEsNZfOMULalhrM1LZJdWXHszE5gX/4QahZP4Ni6VI6vSaOmZDyH5o/jyKoUTjyVzdHV6TQvm8aheWMpyx3C3uxkdqTFsWVmtEJgtkyLkERGcZ+mfQKjQE1gtA0Rb1S6QKwsLe0RGE2ZCdZsO7Vzw6kjMqNtq0mr2KgJzPIxASoCs2SMP0vG+LdbYOSoV2TaGvZVlpvHITASujeY9B3Ga4/EqIuMvgqNfAV7VmwvZsX20noULz2mN6J1lkW9AtO+EMT2zrXoEpjHISydWWPu/AxIx4RFHb2S0FlB+S8LTFVRfCdJfCwcLEzoEHLxqZK1hdSpKUymtmiwoqLSlB9Nc0EMLXkRtORFcCIvimcKYjldEM2Zwhheyo3mhawI3psSylsTA/l5sAffxfeBSDv+HmgG/Y0gyBxCzSDKBpIMIdmIjyYIvp4peD9H8G6W4NYUweURghMJgqZIwc7+BqzpLRhjLb1Qd5PdMJFXYAyFwEh2Dt9I9pyZEDgZCHqaCnyEIMRCMM5OkOUl2BQuqB9jRX2S4MgwQ16cLriXb8xX6w35vbwbVFtLElNtCDVGUGMCjRbQbAlNFtBsAy12cNRK4rAlHLGCoxZwxLz1+aM2cNwO6oz5a6ngnwcFPNtDqtLcD4D7fvBmoNRKuu0Obw6ADwbChQF8ukJwarigJlKwy1uw2UWw0UOwto9gQS/Boj6ChT6CRf0Ek50FU3sJZvqakBPWhayYruTGd6NkWE9WT/RmW5o/5XlRVBUPpHHJYJqWDuPk2rEcXzOGllWjaFk+jJblwzi9fhSXt0u3b16/FaSDAAAgAElEQVTdM5PX9qZzqzSVVzdN5dT8JJrH+7J/UE+aB/bgSEIvLia78sJwb84/4c1zY/tzfkIAl6aE0JwaTnNqOAfTIjmYFkllWjSHUqLYlyqxKy1Klr7d2m6S5mjC2JYaytb0ILakBbIxNYS9+fEcLB7B6U3pvFK9hDeOPsX750p54/gWzmwv5uKeRbx3aj8fn6/kjSO7eKXqKW5UruPlipVc2JhP0+IZ7MsZwqZp0WydPkCSmBnhbJvZuv6tiEKQoS0WQSUiYXoQG2aEsGFGSIcFRts9G3lLqq0tKP1H9fSLjLrQ6M9pUo82UG0xyVk+JkCGaqSBXGS0yYzyNpO+7SXtgZKeSuvZnhS3celXn8xoE5j2SozyYTx1WsXFTYZcYnrLkIuMevaSOxkDXZklR01g1BGtMqJegWlf6OHjnmHpbEuooxtC/28XmNq5iZ3i/wRGVVrUqS2Mp6ZgIA15UdTPjqRhViD1GQE0ZgRxJDucw5mBnMqP4sXsATybEsidJ7y4MdSVr2N78VWMM0TaQYwjRNtDTFeI6QKxdjDCEiY48kOmMb/kWvBFkQmfFRrzMN2A608Kzg6RJGaHr2CBnWCYiSBRdnTNRklgDGQSYyKrxBjIBMZOdkbfWwj6GwlGWQvSXAQrfQVVT5jSOEhwcrQ5L04XPCgy46v1hvyjzEmSlxobqDOGBlOp+iIXmGZLaLKWaDaHwxbQLMdMkhi5wLTYwgl7OOUgiUy9Eb/tF/yzRsBZO7jWB255wF1veNgfHoTD8335ZZsV19MFR5MEddGCiiBBaT/BVm/BUy6CeT0ERU6C/D6CTCfBLB8TnhrmRWlqDJV5Q6laOIqGZeNpWj6KwyvHcHLtWE4/PYGL26Zyff8sru7N5MU96dw8lMfn59fz89Xt/OX6br5/fgOfnVnJpycW8V7zXN6uzuPe/lnc2ZHCS+vGc33eME6nhlMZ3oUNvQUH3A1oDLDmQKAljdFONCb3pmlQH/aOdKN8tCe7J/mzd2ow+6eHcyglivL0WMrSWmcMd2a05j/tyoxWEZjNqQFsTg9jX0ECB4tH0LJ2Gpf3FnFiQzqbMhPJTXZhrK8NuUlebM0cwapJceTGezEz3Jms6L4sGxvO3uzhlM8exfbUgexMT2RvVgK70+MUX39HujRILMUhtF9g5PIiR9sG1CZZhMLGaZrH+NQFRn3ORnPmRv0An26haa/IPEpGky6BWTE2UEVg5CwdG6AiMeoioysle8EoH50So01q5itou+WkOw3blfzBLjrjC/SLjJtOiVE+iNcqNH1kSO9rZi89ssA8WmpzZwXmcQnLo64xd34GRK0l1MEX8Nq5yXronKDoR9/Xb5vOCkz13OROoVus2kdNofxnIMli3byB1BfH0zwvhIbCAI7kdadpthPHckw4U2jN5UJTXpxvyatzbbk624z7kwXXnxB8Fyf4PkFAuD2E2EKQEwR3g1B7CO4CQbYQ0gUGdoXBPfn3FDuY1Zs/zxP8tcSY7xcZ8t0CwaezzXl9suCF4YJnkwSH+huzrqtgiqlglBC4yKowcoGxkg30OsrkpouQZmS6CUFPIfATUhVmuKlgWnfBvJ6CPXGCxljBqWGW3Jgm+GiuDX9aJ/j3Hns4ZAnVtlBjDHUmEvWmUG8m0WAlw0Ki0VL22Eyi3kSiwQwazaHJXBKcY7aS2DQaQY2AShl1ZlJF53BX/r5L8NESwe1swYUnBadHC86NF1xNEby1UPDdJkfemN+dAzGCBU6CAhvBWj8j6kd60ZISytmcWJ5bPIyXVo3hyvpxXN04gSvbpvDCjqm8sHs6L+9N5UZ5Gq9XZvNmQwGfPrOEv728mX/d3MmvL27g67PL+LRlHu81zuG9mizeqcrgg7I0HmyfxJc7p/HuU2M4FWvJU7aCFifBi36Cn/qZ8b2nMT+4GfGnvgZ84GLAu30ENzyMue1tyrMRXbkS24Pzg/pyeYQn58b7c2lKCGfSIjiTFsGJ9EhOZkRTnxbMoam+lE7xomymH/uzQijLDGJvZgiH8qKpKxnCuvGeRNlKf85dZUPcfWR/zk4yuguBhxBEmAnGuQtWjfGloWQMdfNHKP7HtDw3lvI5iezJjtVY394yM0Kxoq0NRfaTDoFpRRoaflSB0X1BWPf7uqox2uZl9KMeayBvK2kKzIqxgUoVmVaBkaNVYjTuzGgKTHskpmSEl4rAdFRkCoe4ytCdwdT2UTz9AiMhr8xoCoyyxGTGu5MZ764QmKy43m0LzP9kGvPjrK60R1ras73y/3aBqZuX1EkGdYrquYmdpHMCo+vn1hEBUhaYmqIYqgqjaSwKpKEwgONze/PiukA+PRjDz0dHwLPj4PnJcHkGnJsI+2L4Kt+OzyME7/QX4GcGUU6SwPg7SALjYcjfugn+4iD4yVvwzzBz/jrWHNJ68muxIX8tMeaHxUb8aaEBXxRY81aq4JWxhlweLKgNsWRHX0GGvQHjDQWeshcsucBYaxEYB6Uz+X5C4CUTmMmOgnQLwdZwQUOM4MIYe25OF3w8z5Yf1hvwr1I7qLTWFJg6E6gzlai3kCEXGgtJQuTiUm8CtcZSBUeZemNoMJEEpsFQetxg0ipCddZQawXVXaHSjv/s78s/9vbk153d+WtpT2gMgduT4WYRH632ZJ2HIEUIlrgK9g3szu5BPagY6UrzrDAulAzmwooRPL9uLFd3Ted2xSxuH8rhtcpc7lXn8qAuj4f1+Tyoy+N+VRavVaRxqzyFN6qzebd+Nu/U5fJBfQ4fN87mm7o8vqjK5ZeD2byzfhRn4qzY1k1wsofghX6C7z2N+d7TmG96C75yFrzlLLjrILjoKHjWQVDVW1DnIqjwNuCQnwkVA+xoSOpF/VgvWqYEcHh6KKezYmnKDKV8vAebxvRm33RfagqiqZsbJ8nLvAQaFgylNDOCGSEWxDkIwq0F/WSy4ioE/Q0EUTaCYBNpS81LSBtrCwb1pW7+aGrmDaM0M5r9swfSuHAELSsnUlsyQrHGvSVVQv2ysDqt2U8y2iEwbV0UbmtgWPkAX1uXgXVVZtp3CbhtgdG8CByggjaBWTHOn2XjAlUkRi4yGltLo1WP5snvxihLjDr/0wLTlsi0LS+aAiMN/moKjCJ7KcGDzHh3suTE9ZYkRsdl33YLjPJFW1Xa3ybSJimdnmPRu/2jKS2VKi2EjqGvhdLRF/DOVlA6LzCdo6aTdFag5N+H7sqS7OdUJNFQmExDYTKNBYk0FiTSXBDH4cJ4jhb4czjPj2M53WnJduJCoSG31jjxXa0xXHaBe+7w0Bse9IS73eC1LnC3K7ztDq/aw14T7swUvOku+CxYQIgZBBpDUB/wtOdXO8E3JoL37QWf9RB8G2sAE535dZ4pvy205IfFRvyw2Igv55jx1nTBq08IriQLmmMF+/wE83sKMswFCQaCCJmc9JC1k6xkLSRjpWDCXkLgYSrwl1VgRhgLct0FJc6CXZGC5jjBpbFWvDpT8OF8U35cZwR7HOCQOVRZScO7tSZQa6ZKnbkaMrGpNW4Vl3qZnNQZQ72hRK2RTGZMlf7ZsvmaRlkbqsUanrGBU7bwjIPE8Z5QZcmfdxnz/RbBJ6sFr+QIqpMF67wEC/tIErMmSLBvsKBuiiPPZLtzviSaV9aP4M6eFO6XpXNv/yzeqprDh/WFfHZ4Pl+1LOaH06v46ex6/n55K395djN/emYt3x1fwddHl/LNkQV8c2QBPxwu4vvmQn6pfJIPNw/k/jwLrqQKXhonOJ0oeG2g4JUowS1fwcvugls9BTe6C+7aCx52E3zmIPjARvCJmeAzS8HnNoKvuwq+6C74upfgjX5mvB9iz+XEPpyJdGR3rA0HB3enbpI3p7MiOF0yiGeXDufk8lEcX/oEzYufoHpuMntz4tiZEcX6KQGsGOfN+ilBbM+IYdP0EJaP9mTlaHd2poVRVZRMzbwhNC4cxpFlozi1fhLXymZzrSyPI8vHKuZw5Mi3o/QhF5g2qzUqLSXth/Y2TgvSyoapgTK0bznpW99WTuZePymQdRMD1FC9CLxmvD9r1MRFNdZA3moKUCNIRWDk6BIY9a0l5fgC5QvAuo7lqctM6yaTfPBXWWpakeZkWpk31J15Q90pUqA9UFK/yLgzJ8lNJ7MT3ZmT5KFUqVFPxVaNKnjsAqN+xVbzwm3bsqL8WFd+zKNWWSQh0XNnRc/2yh8tMH+0gPz/TWAa5w6ice4gmgqTaSpM5khRAk15sTTN7sfhPD+eLfHg9oYB/KkuEp4dDbcC4G6YJDC3+8CNLnDTDm7ZwB07uOUEb/SBu4lw0gXGC+67CP7ZS0gCE9wX+vcAD2P+0U3waXfBx90EH4cImOjMX+ab8c+ltvy8zIRflpvxywIHPs8x4f4kE26NEbQkCg4GC5a7CXJtBEnG0saNmxD0liUo28jmX+RzMNayKk1fQ0GAEPgKwTAjQWE/wQZ/wcEkI44mCM6PNOVmiuD9ucb8sNZQEpgqK2mQt9pIqsLUmEp0RGBUKi8ygVE8Z6oqMXKBaTKXBoKPmsk2muwlgTnjAmdd4bQXnPSA475wsj8cj+HXMg/uLHTkxGTB7kTB0+GCzfGC2skOnCwI5dKiOC6uHsH1rZN4fV8GbxzI4d2q2XxQV8CH9XP5+tgSfjq7nt+e38Zvz+/gl/Mb+fn0Wr4/uYqfnlnOjyeX8cPhIr6pm83Xe4fx7b4RcOoJODcaGsJgfz/Y5A2LnCCzGz+ONuCLUMEbboIHToI7XQQfdRF81UPwZ2dT/t7Xkn94mPO7pwU/uBnxdS/Bi90FVxwFVe6Cag/BphBjdkZZUTrEibpJ3hzNj+HCkmFcfGoyL+1I47VDc7lbXcxrVQu4VVnCjUPzuX5gLtcrirlZuZA71RL3ahbwVtMyHtQv4WZFIXeq5vGwcTEPGhfzsGkJr+wvoGHRSI07No9TYLQJjbrUbJwWxKbpISqoyoz2jKenJwe1KTTqAqMpMpqxBuqXgVVjDeQEqrDyySAZsoqMksDIUZYY5aFfZYlRrGHraC0pt5iUKzStA8DydGwv1UwmPSKjTWC0pWLrrsq460SSGA+FwEgSo19gZiV4kJ3gQVa8u8qwr1aB0dciUj+9r09gOtoWUn++42f59Q3Q6hAXpRmIjqDZqlAVko6/gHeO+uLkP5Q/WmAa5iZpRf5x+depKh5EVXGr8LTMD+NocSgn51lzvMiCF5cK3i215vdTXeG6N9x2hrt94a4L3HOF15yltd9XfOGqB5x1gwue8FIXuGwJ1+3gHQ94KYRPFgk+8RF84S+gvzH4m4K/E/Sz51dXS77rZsB7voL/jHbjH8V2sLQHf1tuyt+Wm/KPRV3481xzvkgz5+3xggvxgqYAwU4PwbruglQbwXghiBSCMFkLoa+sCmOhtFbdRQi6GUry0t9AMMxQUOhjwt4oI5pGONIQK2iME1ybKXiryIrv1hnzzz1OUGkDVbZQZQLVplBtKVFjJVFnKUNNYNTFRfG8HHPVSo5ciurk8zVGEk2mcFg2N9NopiQ2NnDcHp6xl92f6QUXekt/Bid68/v+rny8UvDKHMGlFMG5VMGVXMHL87twe1kP7q3z44MdEXxRMZIvD47im4Oj+aluIn9tmclPjVP48+FJ/Ot0Gr8dH8/PjSP4rjKC7yoj+KHKi6/3u/BtuQX/PNob3giE9yPhgQ/c95KuDF9y4t91Zvy5TPDnXcZ8uV7wTrHgZqbg3lDBrSTBm5GCW/6CT4IFX4YLPuxnzkMXwZUeBpy3E5y1Fpy3FZx2FlzxtqYlqhvnkl1onOLPhbwELq8ex42tM7m9Zxb398/hwaEC3qqZx4dHlvDp8RV8enwFX51ey4+XNvPnK9v5+fkt/OnCU3xzfj1fn1vLF2fX8cXZdbzTspw7NXO5uDWdg4VJGgKzVSYx2tAmMvpmZvRXZkJ0SsyGqYG6M54m675BIxcYbTKzbmJAO6ozAayb2J+1E/yU8GfNeD9FpUbBk4GsHhfA6nH9VVCWGfX5mOVj+reRku2npxLjq7KWrZmWLReZttexW9OwPZgrExnlx0VD3RXtpbaGfPMHeegQFzdFC2lOkgf5SW4yXMhTEhj5lpJcYpQFJjvBQ+e2khyhLTNIf36Q7pTmjgrMow7ftraC9G36JOgd4vwjBeaPFpDOUju/c9QXD+4UjcXJWqkvHkzD/CHUlUgSUz1/MNXzB9MwfxDNC4fQMj+MI/NCeG5Fdx7sDea3U/5wPQHeCJM2Ym47w62ecFPGrR5wtw+c7Mq7qwXvrxf8XtcFnjOHVx3hJRuplfTOMLgZBfn2fBUgoI+AQHMI7A6hvSCwB984Cm52F/wQ24W/FFjBcmf+vsKMv68w47eFtvxSZMZXmVa8PV7wXLKg0V9Q6iPY7S0o6i1IsRbEGwuiZO0hL9nWkaVsI8lYVpVxlFVfAgwFQw0EaT0F5TEmnJ/mRWOcoDJccCNdEphv1hpJAnPQUhKYatNWgZHLi7LA1Ji1Cky92gxMvUnrjIwc9cqNQmZklZgaIVEto0ZWtVHMyphJw8R1RtI8TZ0ZNFvDM33grDucC4JT/aHOj1/29ubL7W58tMGZ+2v6cG91b+6u9eX++v7c3xjFuzsT+bJiJN/XjOeH+on83DSVPx+exI8NT/JtVTKflsXw4e5+fFTqx1flffmx2hvO+cBL4XDNFa67SbEIl2zham+43F06+He+N7wQCq/GwNUkuBQDNaFQ1g+2RkJxXxjbjU+CBXedBdftBOdlXLIXXHaUBOaimxlNYXa0RHXj4BgPTqRHcGbRMF5YO4GXNk/n5q507pTn8GZ1ER8dXcqHR5bwXtNCPj2+gi9PreHLU2v4/OQKPm5ZwofHlvDR8aV8fHIVHx5fzsOmRVwvz+XYqgmU58UrNqGUBUYX2qRGeWZGWVK0PacsMK2PQ9g8I1SBpsi0j/a2mPRXZiTWT/Zn3cT+SiLjL5MYf9ZOCGTthECFwKx5MlAhNMoCo16Vkc/HSPipCIx6FpOywKhnMv03BEadIqX2UpszMoM8VJDLi1xk9AmMeup1VpInWUmeCoGR34/5rwuMckVFF9qEpG05aQ/6hmi1i4u+IdD2oi4k6i/Q+j7eWYFomD/oD+V/m8A0zR9Ec8lgGmU0L4jn8MIETi4Io7mgP01ZZjRlmXFlseDTA478+7Qd3PKBt13gDWe400Xitq3EDXd41Q1e7QEPvfhqpxVbwgTNowXf7EiCZ6Pg7li47y+9mF1zgnd84bIvPy8Q/D1I8K9wAd6W4NcFol35Z28jThgKXnQUfDLDCpb78beV1vx1hRV/W2DCjwWCz6YacX+44FKM4Eg/QZWPoNZPsNHbkCXdBZOtBKMMBTGGksh4yioxDrINFUfZJlI/WQVmiBBM7CKoHOxKw0gfynwFtWEW3E2145N5bvy4rivs9YRKB6h2gipTqDCAKjOoMZdkpsYMaiyg1rIVuZDIh3sVj5WrNZbSkK6cWiUhqjaXYSxRY9hKrVFrZUY+HFxjokq1ufQ91dtI1NnKsIF6W2h0gsPdodkZDveCRhf+VtGV73aa8dMea77aZcY3u835rsyCHyqs+L2pG5xyh4vu8KIvvOoLt/zhhidc6iZlOJ0yhyvWcKM73OkBd53hYTeJN53gPWepGve2OzwIg3vB8HwiHHLljfxuNAwUbPaWjvMttZfY101wsLch1a4WVLtasKW/DbtDHdmc3Ju9o7ypmBlCc14Cp5eO5sWNM7i1O4v7+/N5t7aYT48s5YsTK/jy5Eq+OS3x5akVfHV6JZ+dWs57h0t4o76YO1UFXNg8jfpFQzhUlMy+3FiFwMhpS2C0yYwiy0nP8K8ybQmMpsRoT9zujMzIpaVNqVESGEli/GUEqhGsITBrZK0mjYHfcf6sGivHT8HKMb4KtLWVlOdkFEPAMlRvy/hqTcZuq6U0d5gH84Z7KtaytQmMvMWk3lYqHOKuITDqFZmCJE+JZHeFwEhIQjMnyUOrwOQkeioERtu69WMTGPVKSnvmWTojLJoyov/OyKNsscjR9wLaUWGpKxmkwh8tII1KL/aPgvrvp6M0zB/SKZrmD1Lh8IIhHF4wpPV7LI6jpjCS+lwfmvL9eGmNB5/VJMPVOHhjFLwTIZ3Bf9ALXnOUZltuWsM1M+ntbU94zRtuOsNDL7gYQfVwwXQh2B4m+GpnF7g8EO71l/7P/HlbuN4dbkfByd4wzpS/+AtwNYZ+1hDrDgGOHBWCQ0JwLUHAUl/+ttKavyy35K8lxvxpjuCDCYIbCYIzYYLDPoLqfoKmIBN2BFiw1k2Q1VOSmCQLQZyRoJ+BVInpJRvu7SYb9FUWmNHmgq0hNpRGObLRWbClt6AqQHBnpg0/PeUI+7ygrjvUdlOqtJhLEqNoKZm3SoOywGhg2XGBqTKCKoNWao2gxkBWlVE6rKeChQz5P09GrbUkMM3d4EgPOO4Kpz3hfBBcDIUrkfBSLLwcC1cGSJWTF8PghWC4ESVlOb0ZD29Hw50gOG8PR03hrCW82hfe9YG3vOAtN4m3e8JbPeChI7zRFe71kuajXvWBiz35aVsX7hYILowTNMYLysMFZWGCLR6Cdb0E26wFW62kJO5d9oKlvQSrXQ2Z62NAsa8xBYHGLIq2Zd2IPuyc7Ed5ajBV2ZEcLU7i/KoxXHpqPFe3TuPl7VN5YfNEnt8ykYtPj+PkyuG0LBvMkWXDOZAfzaYZ/dmSEsDenBj2ZEezKzNa5SbNtgzd6BMYRcK2LKSyPTKzeUaoFJmgRWKkx7pmZx5PRUaXwKyb2F9NYqTKjDaBkVCqyugQmJVPBrBqrL+i5aRNYtQP4mmIjGyTSZfA6DqQp01mSka0HshTFxjNaoyu+RjPdguMhKuGwMxJ8iBXhrLA5CR66txWkiP0C0p8m3RkZkWbvHRcWNQrKY++plvT6QFS3RUIeYVE3wt4ZwWicUFy5+jk11cXIt2iov3j+iVF+rym4iE0lwylUQ11gTm6IIljiwZzclEYR+YF0FJkxYn5Xbi9yZDvDrtJ8y1vhMGDAHgYBG/0l7jjDS85wwkrqBdShs85G7jqAje84TV7uNMV7g7mg92mTOsuDdMO6yNYMsaJO8vc+GpvjHQI7lhPuNYL7njC5u58OlJAPwGBJuDvCKPD+T6yD0eFoNxJ8E2OD39b1ZMfFtnzl0ITvs8WvD9K8Eqk4JkAwWEvQZ2PoLm/MWUBpmxzF5S4CIp6CtKcBOPNBQMNpe8nQCYt7rKqTJAQhAuphTTUQDDPSbDcxYqNXQSb7QSHrAXN3QXX+ws+GWrL76ldYK4LrHCGp9xhux+UBkFFgMR+dyh3gwO94GBvqO4ioWgpGcs2juSzL7I1bPVtJjnyykuVkYT8feWKT42Fls+1UhWhGnOoVf51plBl3EqlMVSbSTLV3AWOdYVT3eBcD4mz3WU4wRlZZMIpRzjXTZq7OWwl/T5O94E7UfBhMrwVC/f7wz0/KdfpoRs87CsJzQM/eN4RKj34fqURL0wQHEsUNEQJmqINaYxz4GhSD2qTnNgdasqsvoLxNoJwc4kBVoKBXQVDugtG9BaM7ytI9RXMDjFibpQlS5IcWDuyD5smerBrZn/KZwVyaHYYtfOiqJ0XRV1xNPXzY6iaG0Xt/DiaFg1h/+xIdmQEszsrnD3Z0ezOkg6Y7s6IUqBekdEmNsoiIxcWubRopGxrQbXFFKrIfVLkP6nITNsbTfqERlle2hoGfnpKgArrJ/uroCwwKkO/bQiM5sCv5qyMusi0NRsjCYwMtYpM66Vf7dtLugRG+She2xKjKjCtj2UM9qZwsDf5g7xUkAtMUZK7DFcKE3ULTE6yFznJXuQmeZGT6Kk07OsqC4pUExj9gpKgh/aLS2WhZnpxR4VFvQX0OARGvaqiLim6Pi6vwHTkBft/o8A0LxyioNNCs0A7uj7eWDKUhvlDFG/VUbSCSoZqFZjDC4YoKi9HFg7j8PwEGucOpCG/Hy3zg7i3J5hfz0+Ae0/AW+PgbjDcCYTXfaUXnte8JYF5GACvuEC14PtNgn/sE3DUEC71gFc8JYF5wRhuJcC1aJ5OdiJUtgnUQwhSrQWVIwV/WiugsStccZLO5B+LgTkCYuwg1BzczGF0OKQM4rVuglVCcCVO8MtSJ35Z6sQPOYIvZgreGi54OUJwor+g2VPaUqnxFOzyEez0FizzFizxEBR6CDK6C4ZbC5JMBGHGgiADSWL6CUGIEAwwFDxhIhhrKciykFhtKtjuKDjqLDjeW3C2l+A5d8FVL4mXAgT3YgUfjhL8lCpgiQ3s8oRqX6j3hyZvqPeEOvtWgam3aBUY+WxLnYnqNlO1iepjubioyIux0gyOvOJjqoalhGLI2FyiXkadmSr1ltBoI9FkK0UiHLaVxETOURs4bgvHrKVLwi3yx7KP1Znw7wMmUnvqsiu8riTCb3vBez7wvhd85Cv92Z805avFgpcnCloSBDURgupQwYFAwT5/IyqCTNkTZs6+CEuWhdsyx1OQ4CgY1F3wRF/BRF9B1gArChMdWTmiN1un+FGeEUZlbjSNc5N4ZulIzq0dx8WnpYrLyzunc3N/OncOZXGjPE2iIpPrZem8vDeTC5smc2T5SKrnJ1OeF8/enBiV+Jhdaarp2jvSB7AzI4qdGVE6qzI70qMUV33bQmerSU1elCVmi5YhYd13Z3TLjM7ASWWRURMYDYlRVGeC1TaXQmQEqVRmVk8IZvWEYA2J0SYwyigLjAqKA3nSDRn1ioy+C7+6qjJtXflVlRkvjU0lCW8VgVGXmEIZcoEpTHShMNFFUZHJS/YkL9nz0QXm4Ox42uJQXkKbHMxPbBs9W0L6Qgn1rSd39l6KviHbtuY3dLWA5C/Uj0VQ1FCWDYlBnaJxQXKnPleXEGkIltbvfQgNC4Zqpa5kCHUlQ2hYkEjDgkQaF0bRuDCKhgWJ1M6Pp2XhEFoWDkGazvQAACAASURBVOH4/ACOFPbjZIETp4p6cHWZJbfWO/BFmS2cD4C7A+B+JFzvBVcc4YIRnBVwRsB5Ac8KeNUC3vGW2gLP2fH3nYK/bhFSJeaCg9Qauu0uO3ufBZdHMqGvOb6ydeXusrcx9l1pnurAV2XjpRmKW+Fwz1caTp1uzb+GCPDvCoFOkOjH7/2dKBeCCiG4m9yVHzNC+GSiG3cSbXk5zJSLfoJaD0GVm2Cvp6DUXbDVU7DdW7DBz5T1Psas9BQscBZkOQhmWgmetBCMNZNCDkeaCYZZSzxpK5jsIMjtIih0EpTbCSocBBfsBVd7mfCNpy0/+Hbldx8rfvex4t9uRvzWW/BrDxO+txe8bS/4vLcFn8X04deRgfwtJxaWjoHKyXA4E1oGQUMcNPpBfT+osZVCIatk7R95C6jaRCYuZmrIJUYuLvKZGBm1hhLy9xUiY65JrYXSYzOl43sWrZeE662gViY68mN8DRbQIItLUEQnWMmwkT7/oAHsFfznkICjlvCcM9zwgfsh8DAMHsbC6xFwxouftgoezBacHykJTFO0JDHl/QUbXAVPuwhW9BWsdheUuAqeCrVk2/A+1KWGcbRgMMeKhlI/J57mokG0LBzG+dVP8uKW6VzfkcrtfZk8qMzjnYYSPm5Zxo+XN/Dv22X8+7VSfnlxA5+fXsaHxxbwXksJbzUX8VpVNi/tmc75jWM5tnIwDQuSqciLYmdGDDszYtiVGcvOjBgN8diRLv0auajI2SZDfQhYF+r3ZtqiLanRpG2pkWcyqSNPy269NyPRKjD9eXpKf9ZP9pOhKjLybSZ1kVk7IVh6K0sL13U4T9po0rz0u2ycn1YUQ7860rAVIqPjMJ4yWo/ijfBRYd5wbwVzh3kxd5iPGr4UDe2ndchXZdBX3lrSeQxPajXlJrtJKFdjFEfwlFetPVQQ+gSlMj9RhUcVGPmArUYWkJ6MH13i8jjWkHWtAeubW1FUWRYM1nzBVqs0tC0fj4NWoTi8qHNC05nPl4uK/Ps6vGiY4vtTf771Yx0TmCNL4ji2YjiNi5JonJtAzZxoGuZ40jDHk+eWuvNwdwx/PREPV8bC5TC4EAQv+8LtEElgbrrAvd7wRl+43x1u2MJFAacFXDKXtoxuu8Ixwb92C6gQ0GIGV5zhng/c8eTPJwZyYb4hsWbSCrP84m1vGbndBc/l+8DhrtIQ6F0fuOwEeX1ghICQHuBnDyG9ILwv550F+4Sgqafg9SR73n6iBzfjLHk+UHDWU1DpKjjkItjlKrFZJjHrfYxZ62XIcjfBEhdBQS9BbjdBipNgRlfBJHtpaHekvcT4LoKJdoIsK0F+V8E+W0lgLjoIXu5jylfuVnznY8fvPlbgbwf+tvD/EPee8VXXyf/2pPfeeyGEhPROOpAESADpvUMoCb2E0AQBARWQXkOHAKFJlyKKDQQFBXtd11VX3eru/tS17HU/+HxPPwmgu/f/wfU6h4SEBJFzMfOemXRfSAuHpCC+jHbnTXehUcvurLcV9vkJJ1KFVypt+f0UR35YFgF74uBYBpyJgeNh6tBjk5uSgQO6ttH/WGB0uR2dwBhnc3Qis9dZw1Gh2wi8X5MY/QZirR21x8k0qLzXBnYJv+wSbfzbQbHfFQ568I81wvt1ws0RwpXewuWHhGd7Cc/3E14Z6shLw3040UVY1kaY6iOMDxAey/Fka58E9g3P4tTMrlxZNIDnlg3mmaUDubJ8INfWjOLmhjG8urGa21vH8vbuSby9ZxofHarnm4tL+cfzK/nXS4/z9YWFfHpiNh8dncm7h6dyd/9Ebu0ex82GMby0aRjPrRvImaW92DWlSC8v68YUsXZ0oYWo6ATnfgTGvO3UnMjcS3SMpcVcbHTiYpAa67tmjDcCrxhkeLQkzUJiFMl6iVFoYmORmUnXyDRhcd8sDes3mXQCY7wo7+FeSczXsCYwultM5tew5z9kfK7AbJeMEdZkxlhgZnRNYEbXBAuBUSQwrUuCicAoidFNKlkJ+D6AwNSUxVoIzHgt4Gsc8v0VAtP8IcNdk0rZOakDu6Z01LNzUgdTjKaDdk+1DN0aC4u144TGwmJtVPm37lFprrLSYvB0lrGUWH8h3zezAweMKg+6cOn/QmAOz67Q82vF5dd/vOnXo/s+Dd+v9muYvd0gegZpaazrbPJ4YFYn9s8oYP+MAppmFnGsvj1Pzc2hcUpbGmtsODLZkWtL7fh4eyi/nImAl9PgjXh4LxXuRMAVF3jKTo28vpYId9Pg/Rz4MBc+yYSPM+CtOBW8PSFwwQVuxKrg7kFPflgncLwdnO/AN/v6caUugSHxNqRp+1fSHVVYNlCEQGdPvGycSBehvmM6f37CFp5qA9cD4Y0oWBHLP3oKZPlBug8kBUJ6KN8n+PC2o3DGSbgeJlzN9OJKmjvHklxpjLNjfZSwPkpYGSM8Hi0s1VgQq5gbK9RFChPDhfEhwqhgxfAgYUiA0Mtf0c9b6OOhTgmM9xY2ewgNvsJlP+FahBNfxjrxpwQPfmnrCikekOqubjelealzCPnRkBnCl0FO3BLhaRFOi7BJ7FgnwkoR1tkKm72E5/KC+N3QGP45LQfWFMOeh+BQBRwsh0OZcCANDkTC3jA1sr3TQ4WE9UFho9aR7sfNikwzAqOrxFiMb2vof55ZW0vHTo1djrDDAXY4QYOjetztovI0u50M+Z0Gge2iKjS7HbVlgO6w2ZWf1trz/ZPOfP+kMz9u9oHjCXCtE5xMZ1eJMMtfmBkkrEwX1pfasr7Ulr3943h6UgEvLKzi2tIevLKyP6+vV1uF724Zxd3t1by7ewLv7JnEe/sm887eWt7ePYG391Tz9p5q3ttXw0eHJvPx4cl8dGgiHx6s5YPGGt7ZP5Y7u0ZyaWVfdk7JY93IAtaPLmStxv0KzOpRBaweVaBvMa1pIT9zP2Jzv9Uai8rMvW433bPNZG37r3k1JqWF0O/9CYz+nEG/FBb2Noxl6wRmQR/F/N6JVjHcYmprgnlryfxEQZ0VTCUmUaP5G0yqnWRekWmttZXMp5UMo9e6K9fGQmM+hm3YHaOyMLqWkjE1ZlUZ4+V3Yl5hscRSWkwwkpddUzreswJzvy2ge7V4/ltjyP9tgdGLTF2ZhcA01ZlWH+4HXcWieSp+k4D8lo9XH9OZpvou+q+nqc4U3c+zfLsmMXWdm+XArE7sm55P46wiDk0vYN+kHA5MTuTQtBReXBHN7/YXwZViuNsb3i+Dt0vh1RhVabkdCq+HwY1IuBYGL8eqMdhDdnDQBs46w4tB8HZreD8RboYqgXnaSwnMzUzY5ch7c+25PESYEC10EqFnmPBQsJBipyQmUIQoByHKOxBPcSBehP4xXrwzS2BXIFx2VQvx9pfAUIEUT8jwhdQQSAnmP2nBfB1qzyVP4Vkf4UiYcCxS2B0p7AwX1kUKayKUvDwWqUZvF4YJ9RGKukhhVoQwIVQYFySMCBKGBwpDA5XA9A5UAjPAR0mMTmA2uQvbtd0j1yOd+WMrZ/6S6AnJ7pDho+Qlywey/SEnALLCIDscslrxTagbzzkLl+yEBlsXtog9T4iwQoSVdooNPsLBVsLpbOHZ9sLdQcLf6v356Ql/WB8B2/1hV7C2NM9470wzAqPbDHwvgdnrYkpLArPbyailZcROe01aHKDBXrHdiG120GALO+xhp61ir502NeWkvt7DAXA6Gs60gadi4WhrOBIHu0P5Zasf7I2BvTFcHeHFziJhYSuhLlRYnCYszxJWtvdkZ+9ojtfkcGVuJ15c0Ytbawdzd8so3tkxjvf21PLRgcn8/uhs/nB8Dl+dns/fLy3l75cX8afz8/nm3Hy+PjOPr07X88XJOv5wYoY6VHm4htd3DOfc8p7snJLH+tGFbBhTxDqNtUYyY4yuUqOTHGsCY86vFZj7kRlddcZyqulBZSbDQmB0PzYXGPNFeeYCs6x/Fsv6Z7G0XyZL+mWzpF+25T0mbcOvTmB0m351AmOOucCYo9srM7dHkh5jkZlthHWZMQiMeYvJJBdjpbWkZMb62PXkimiT6aV775FRmZn/usDcc72+mcBYYlpxMd/X8v9SYHQVGHNBsSY0lntXOpgIQHOZFGPRaKrvRFN9JzNpuJeg3J/A/P/dMtKLSX0Xjsyp5MicSprqu3C0vhNNdQZh0X3fhrcrdAJzaFZnDs0ySMu+mRUcqq+iaUYnGqeWcbQugTMPp3Oo1pWjUzx4a6MPfz2RBK8lwO8K4cMkVUW5Fayk5ZY/3PCCl33hZiDczVAh3O1O/G2p8NeHhb8tFP71mMAWgdNecCcNPk6Hl0PgaXc44wx32sOzKewuV5tv00WIF2FQQTrHn3yUmV3LSLITYh2FCFsh0NUWD21xXFmAcKNW+LEhAi57wM1wuJwPcwVSBdIEkkMgIRDa+vJduD3XvIUrTsJud2G/l7DaW1jpKczzFx4OFOaH2fBwpD314TbUhQpTwoTJIUJNmDAhRLWOBvsK/c3oHaAY5KcEZpSbMN5H2OhmEJhXolz4PMaVr+I8+TneA5J8IdUPMoMgxx9yAyAnCHKDITME0gL5Mdadz1yFUyKcs7Njj4uwUYQNTkJThHAuRTjdVjgSIxyMEA5HCEdjhKcShKvtbLndzZGPBvvz3YIkWF0M20pgdzkcKIaD7eFQNuxLh30Riv0BsNfPEN7VCYt5iNek+mJlzPteArPTHnbYGQRmu63ah6MTl622sNlGsVV7X4O9ajc22MJOG9hlq1pXjW4qMHzQU00+NXlDk4da7LdDVMj5UCjs9OYvjzlwZ5Kwt4OwLkNYmy3sLRea+rjxzNhIrtdnc3dJez5Y24vPtg7is53D+WLPaL44UMPXhyfz7en5/HBxCVxdyU/PrOC7pxfy7Zm5/PXkJL45PoGvjg3mD4f68eHurtx8soBnVpSxd1KCXlzW3YfEGPPkGMXa0YZR7Pvl11ZnrMrMvY5P3lNm0jQs7zKZVmSaG8nOMGHpgCwTlvRPtUCdKkhicb8kFvVty6K+bVnYN5mFLYiM4RaTdYGZZyYxOup7JJlITMsyYyox1gTGMh9jfRHevcav9dWYBxQYc4mxEJhdkzqYca9bQA8mMBZtoBYkZq+VlpGxwBiLxW+pwNzfvhKz3Sla+NVSRCqaEZT/jcDoPuevxfjr+nVYCszR+k4cnd2Fo7O7mAiMMfpK1KzOagJpVicO1VdxeE5X9k4v5/D0Cp6a042n5qWwpzaSF5fH89dTveBWFbzbT61zfy8b3mwFd2KUwNwMgGft4ZSWa7nqDm+kwZVw/rlc+GKO8JcFwj8XC/9cIXy/Uiv7n/GBu/FKYu60gQMCx8Phvc78eV05o5yETDtFYbgvZzet5PruzWS62uClBXh97NU6/3QbYUJ+IH983A2ulCp5eS0Sni2CR20hS5OYhEC9wPwr1JaXvYQLtsImG2G7o7DMWVhkK0xzFWa4C9N8VKthepAaha4NVFQHCKP9hQFeQh83oYcRvT2FHn5CH62dNNBXCcwEXyUwW71UC+meApMXqOQlNxhywiE3AnKi+LmVB1fc3TjvYE+DvbDNVjibYMvVHC/OpwoX0oTzqTacSxHOtRXOJwlnk4VLmcLlfOFqifBSlXCtm3C1h3BzoPDhJAf+siiY/2yIgb1pcLgVHIqFxmA4EGS0T8bVUmCMw7sP2kLSyYsO4wrMNk1WjDEWmO22BoHZIYoGW/Vna7utYqeD+vUOuECjKxx0hUNu6sbT+UQ4nwXH2/Lvrcl8+og/l0d4sr+zsKfKluP9vThbHcvliYm8PL+Id1Z35931ffloyyA+2zuOLw9O5KumGXx9ZCZfH6njj4dn8sfDU/nj4al8ebiaLw6N4feNfXivoYpb64p5Y2N7XtnYk31TEv9rAmONXyMw9ys0uiyN+Yj2A8vM0HS9wFi/xdTyTSZ9GFjjfgRGSUySCTqBaU5imhMY3X6ZeZrEmItMvRH3KzI6mTE9HJnQTNDXfFqpeYGxKjJmAmNNYswFxlhixFJYfpvA7J5abkbLq/bvd0qouTbPb13k1lyLqLkxYENLqExhRUSa6ruYtFWMxeagRnMCo/vYe6GThiNzOnN0bpdfzW/5+CNzOht9HQ8mMPr311VyuK6SQ7MqaZzZhUPTOnKivpIL88s5Pj2fUzOEDxrC1bjzB9nwUSTcDYBbfvC6P9wOhjuh8G4rVXE5or2A7BV4ygleSIMz0fyw0JYfH7GHxQLL7GCVwDqBrdoK+3PuavT19znwvD8/HbCH15Lh9xM4P1JVVnLdhAgReqb6sWlIDF19hGwXIctZaKvtXskVYdfgODgZCa8VqAV5bwTDK5mwXqCdVoFpGwqJwZASAFFOvOcp3BAVkj0owkI7oV6EMTaK4S7CKA9hmLdigEZPb6GHl1DpKVS4CmUuQgdn9bzKS7WP+ocKw4OFwf5CtbtQqwnMNm/hkq9wPcqRz2Oc+Treg5/buKgAb5qXyuvkBkJekKrA5ARBVhBkBKi3Z/vzdrRw0V7Y6Sf8YaAnHGkLO8L50wLhg1rh9kjhuV7CmVLhSJ5wIEM4kis83UG43Ek4W2zH4XShobWwNVbY3FpoaCvsyhaOdXTlpepWfPpIKV+uyecvm9vz4848ft6TD3vawN4E2Bup4a/Y46aERtdCMg7eWqvAWGz2dVK5l53OigZHrfriAFvsDWy2gS22sNVOsU0MIrNVC4BvE9jipNjqrD23VWxzhAYX2O4OOzxgtwfs94VTEfBUKBwMgQYPPltsyzuzhdszhNdnCnfmC+8tceDdx9z4cJUXn2wM5ssd0Xy5pzVf7Uvgm4Mp/OlQKn863JavDrThj/vi+GJ3LJ/tjOTThjC+OpDC92eK+Gx/T45ODmFDdbEF1qTGQnKqFevGFLQoMfcWmwITzLM2Jrmbe4xnW+OeMjM0XWH1jIGpwJiPZq8YlGEhMI8OzNbkJYOlAzJY0j+ZJf2TWTogRc/ifkn6t1sTGGuYTzGZX8duTmCaay3dq8VkTWCMQ74GiYlrlpZPE+iIM6G5zb41ZXHUlMVZSIyFwOyZ3NGMlm8BmQvMnmkVZtxjwqeFCaGWbu2YZ1F+LcbCYi4wxs/NJ4kOzyqjqc66iDQnME31nTg0R2Fcwbg/UTHl6NwqjV8vL/8d1Neh+7qOzelsIii671P39mNzOqvns7uoFlNdJU31VRyu60rjzC7sn1TCxaX9ODQxi9U9g3ljvR+81h3ey1QSc8cf3g6Ct0LhzRB4Q+NupKrCnLZTFZQ92hj0xXhoCuSTauH/5gk86Q6POyuBWa+THRtoErjkC7dj4KM0eKkVnA+At4fAyTzKgtXdoRQ3Id5e6B8urOodzKnlpZxcVsLc7oUMSg2nVITHK7ygKQhezlLnCe6EwI0s2OkEpfZKYJLClMBkBENqIH9v7ckn/uqg3yln4REHYYYIw0QYLsIAW2Gwo9DfRdFTo8pN6OIslLsoOjgL7Z2Ezm7CQ75CvxBhaLQwNsqGESHCWA9hop+wyUO1kC75CtciHPgy1oVv2ngaBCbdG3IClajkBpoKTG6IysbkBvJ5mgeXHIQrWQK7+sLV9uq8wnPZ8GwWnM+FQ/GwMYr/W+zOx7WO3BwgPNNZOFUonMoXTrYTGlOFPW2F3SnCzmRhXRvh0VBhbbrw7PAIbs6M4Pq0EN6s9+az5dH8sDGMX7bHwPYg2BYIDZ5KYA75wkEfwySSNYHZ42QQlV32lgKz2wl2uZgKzHZHxRZ72GxnEBGdwOikZasRxgKzxQk2OsAmTXx0IrTVBbY4w2YHxVY72GYPu31V1akxnv/sjOTHXdH8uCuaf+6M4l+7ovnb3jj+uieWb3a34pvdrfjj3ni+PpDIVweS+LoxmW8OJfKnw2355/F0/n0ml18u5MOzJfBqX3ilF5/s6UZTbRCbxpeyaXwpG8eVtIi54BgLjDV+rcDcr9DoRrwfRGisysywDL3ANHePqeWTBqZTTY8OzNbI5NGBmSbiYoxOYHQ80j+VRf1SLDAXGMuxbMX8Xil6jGXmXmJjrSoz+6G2eoExDvsaS4xeZMz2xjQnMNYkRj3G3VNijAXGXGLEUlgeTGCsLYczZu+M9i2yb1op+6aVsn96+xY5MKODCbppnwO/meaXr7UkSLqAraEVY1k9sSYwOlT1wvJjmhMWU2kx5v+9wJhXYJSkVHJsTqX+ez1qJDHqufb+GZ04Ud+Vc/XduTi/F9cWVrJ7QCyLsoQdPQUux8F7HdR4841IFdB9rZWa7Hk9El4Ph9thBl4MhlMOav18g8DpKLjQmrN5wtUygSURsDJeq8DYqJ+zxwEOChx3hGuh8H6q2t9y2g2uxcIn+VweKzwkKndycazwwxE/uFMAd9rCu+nwXEcuTxL6ijCvtfDFaoGLCSqT80YwXO8A+yOgzIvvM7UMTGIApAVCdhhkRUNiAN/E+PKhrx07nIRVIgwSYaAI3UXobStUOirKXQwVlzIXocRFKHYW2rsIJc5CFzehb5AwItqB6jhXauLsGR0h1PkoGtyE3d7CM17CtRAbPo6y4w+tnflXvAs/JnupUeqsIMj1U+S4QTsPaBeshKZdNJS24bNcW14KFr6bLXAyA86FqaOGL4TAS+FwLVAdw7zuBy96whUfNRl2LBLW23O9v3C8UHiqUFVmdqcKO5KFbWnC9nRheZoth3q14tT0zpyeUcmhaeUcmNyRxkkFHJiYz4kZRTzzSBVXH2nPWxv68k3TKL46OALODueXpwbB8VI4UgSNMbArVB2r3OmuQsF7HZS87rVRFbu9ooLBu+2MRMZRhXV32Ku20FYtO2UsKebiYvx2fSVGYLOG8fNNdrDZHrY4qOfrBTbYwCZbJUrbHWCHMzS6w3F/uBAMz0XB9VYqB/ZGvGp73m0Nb7dRvJuoeD9JZcQ+ToYP4lWV8s1suJ7Ip9uzOFlrx6bxxWwaX8zGcUUtsmFsoXXGtGuGgmYoYv3oQgOjihXaMj3jrcDmrB2Ra8Ga4TktsnpYrlVWDc1hlSYwOvTVGA1DPsb6tWz1mKKhBX8Hm6ITGXMMFRpdW8m0ImOOYRNwsgm6Y5LNnS5oTmjuVaExGcXuajytZCoyzS3Cm17VWn9nqeVqTKy22Te+WYl5IIHZO6XcFDNhMd9Say4senGZXs7e6eXsm9mhRe5XWKwJzCFt0ud/ITCNdRWKFhbJmWZeWqq+/L8RmGPzK1vkXnJyfx9vWYGxJjDHLFDvP1HflRP1Xbk4vxenZlayppMPU9sIi7KE91fnwjul6iaNTmDOe8BxO7jgBC8HwK1QJS66x1ej4YUgOOakMgjHQ+GNYu709WC5q3CtQmBhqBKYNdqLyC47aBQlMWdd4FaMkpIrgXDGU+VtTubTUCG8MEXgShf4uBN8WKZE59U4+GgEf90TywhXodpLuDFd+GGPN7zoBq8HqkvXe8OgzIufcmwgLQzaBiqByQiC3FjIjOL71Ci+ivKmyd+ejSKMshVGitDXQdHVRVHhqqosFe6mAlPiLBQ7CRXOQi8/YXiUPdVxrtS2dmBctDAnQLHTQ9jnKzznqwTmo0jblgUm1x3yPSE/VAlMQSwUxfF6rPB6rMC2UDibA6dD4FQQXPaFKwHquOVLAfCyD1zzVSPtN8LhnS5wt5xPp3hxOE84WaTaTAeyDQKzK0tYkW7HnqpwTkwp5/SMSg5Pr6BpRieOzmjPkemlPDWzmGNTCzhS05aTU9NZ3c2emjbCwYG23Fmawi870+BkBziXAecz4WwrOBKqMiiNLkpedoshu7LDRrFLG6He6fDrBMZcYrYYsVlMBWaDrXrcZKekZaOtEpgt9rDVXknMbkdo8oLzgQaBeTUe7ibA20nwTiK821ZJi44PktWE3XsJ8GYU3AqBG0nwfCs+2pJmIjAt0ZLMbKzOt+C3CIw5DyIz1oUmT49VkRmeaSIx1kSmuRaTwlRwHlRglg5IY+mANJNqzIMIjO6UgfnJAmOBaaky01K7yXSfTBJ13ZNMREbJjJWJpWa2+pofizQ9URBvITHGMlNb3lqPsczIvSos99po25y4PKjA3I+wGGM8rvxr0Y05t7TxtqXjh4fqKow+VzkHzaTF2ki0uaj8NwXmXsLRnMDonv/ajzfkYSxFxVhgjs/twvG5qkpzfG4XTsyr5PLD/biyaABHRmQwJ0VYEC+sKxQujxW+3RGuQrCvx6olcy94K8nYIepW0SVtwudOK3gjWnE7Bt5oBc+HaK0kG7iVAtvzWeYlPOYgvNkrEJZ4w6pQlYPZolVs9tioz3/JD96Jh1sRaj/Msz7wZgo/bxP1OZ/1h9shitf84WUPeDMCbgdxcZywtli4PU/gqCs87wOvhcGlctgUDaW+kO0EmRFqF0yGP2QGQH4UFETz95J4PksP5mQrN7Z7CLUewjgXoZ+7oruH0NVd6OQhdPZUjxXuQrmbln9xEdo7Cx2dhS6eKvcyOkIYFy2MjRImhgo1wcIjfsKjQcLJQOF8uC13o2z5oI0r37Zx4btkT0j2UxNHGX6KLG9FToiiIAxaO3IyUPhjd1s4FQrnIuCiHzztq/7bPOMJV9zheS94yV39Pr3oDy/4wY2OcCGTl/sIjVnC2ULhfLFwvEDYnSxsSxb2ZtvxeJoDm4p8OTS2hDPTKjk8tQtHp1fROKsrjbO6sr+uOzumdGLTxEp2zerN0HaRuGvB6tZOQpaX0C8jjCXdE9ld24k3H+vNn/bWwskxcL4GzneC48VwIAL2hcIeb2hwV9LQ4KhCvDscDTQ4qvdtcVZsddLQtZJszGhGcLbYKDbYaoiB9QIbRWtRaVNO+xygyR1Oe8BFf7jqBy8EwI0AeDVIy4QFwt1gA3eC4G4gvBWsHm/7ws0EeD6KD9ancrrWgc0TStk8ofSBJUaPFYExpdCMYjaMKbKCEpzmRKY5mWlJYtTzPAuJMZWZTI1sVg3N0ldmVg3NYeWQbAODKP+BmQAAIABJREFUc014YlCO9pilkcMTg3KMWk3aJJNZRkaH+UFJ85aSOcYbgI3RnS4wzcVYhnx117DN0ctMrwTm9mjD3B6JzO2RyJyHEqjv3saIRKtnCmZ1jVO0cG/J/Ar29M6t9EyriGNaRRxTO7fRS4y1akyzAnOvCktz2RR9RsVMWH6NwDyovBhPAB38DTTWlZnKSEs3fpoLAmuVnH0zy2i0sr/F2k6XB8m8mAvLsXldTbkP0Ti+oMoq9ysuLX28ucgcn9vFpFWkE5gT8yo5Ma9Snx06NqczTXUVHJ1cwfIuUUxtJSzMcmB3pXCknxOvzhZ+2N8KXo2AW9FKYK4HwEkXOGwDRwXOOsFVX7gdDXdjlcDcjITroeoW0RHtBeRCMNys4WyJMFeExljhj+MFVoao8v0G3RSJKJE57qjk5b02cMUbzjqq/M1TLurnHBS4aK+qCq/5w+1AuBMGH8TBM0V8f6AVPOWpcjTXg5TAnCqCpR6Q7w7t3CA7Su2CyQyAnGAoiIbCGH7onMrfiltzOTWA/YHCdH9hkpcw2EdNGvXwUhLT2dNAJw+DyFRoclPpJXTzVePTQ4OEkaFKZGpDFA97Cwu8hINuwukg4U6kDR8muPOvth78kOqtJpEyggwCk+ml0AlMmg9fuAnHfAXmpsLT0XAiEM56qcvNOoF5xhWe9YCrLqoa9YIfvBICr1Xw52XCwWyDwJzKNwjM5kRhd6YNj6c5sD7fk8bRhZyd0ZWj06s4PrM7B2d31wtMw+QKtk99iKOLRzChPBE/EXxF8BHBX3seLUKyCP3chOpQYUWWcLifC+8t8uLvW9oogTkaB6dj4WQMNPmrm0e7nBU7dDLjrNjuCttcrAvMNlsjrLSTtonh/brKyyZ1okAvMbqszFZtymmPPRzxhLPeBoF5ORheC1bVR528vBVqRjC8EwZvBimBeS0RngvnvbVJnJnoyJaa9mypaf/rRaY6n83jCkz4bwiMNaHRSYu5zOjExbrQtGPN8Dz9o2VFxiAwilwTiTGQZyExKwfnWgiO8X4Z1WJq5pSB2Uj2owNTeXRgarNZGWsXs41PGVg7V7DQ7KiktRaTscDM65XAvJ5tTQRmzkMJGm0tzhTUdW1DXbfW1HVrfc/L1+YCY3jemulGpwr+fxcY3cr35umg30prjeaODN7vArZfKy+HZ3fWi8n+6R05OKOMQzPL9UcCdccEzQ85WoSLjWTNeKPswdmVHJxdaZGZud9Jo3tVYO5HYJoTD3OBaU5i7vXx1iTGuMrSVFdhEtw9uaAb+yblc7SujKfmlHJoah4rOzgzM1FYmyPsLhee7iu8OEL4eJHAsWB4PVRxO1zxTACccIIjjnDCFY45w3lfeDYErgSrF9DjzqpC06hlGprc4ZVS/rPKng1+wuMuwrUS4d/Tk2FdAKwPhI12sEnb57HXBl4IhLfbwisB8KwbvBIM5xyUEG0WFfp9zlNNPr0RDm+Ewpvh8F5b+DBZvVi84gHPJKpJqF3l/NRPIM8J2rlAQSC08+efecH8UBjBx1Xx/K57Ii8OyuZSr2TWlYRQ31rtdxnqLwwMULeMevoIPbyFrp6Kh8zo5SX08RX6BwpDQoWxIYpR4cKYSGFkhDAiXBgTKAz3EUa7C+O8hPkhtjzexpuDaRGczI/ntXYx3Cluw8+lKdAhnf+UtuY/pa35vjSZf+TH83ZGEE+5C/tTBba2h3PeqvJywVstA7zoCpfc4BkXuOKqqjBXPeG5ePh9FzjfjfM9hEPZqnV0oVg4XyAcyxX2pQjb2gq70oTHU4WN+c4crs7j6ZmdeGpWZ07WdaGpvoojc7rSWP8QO6d2Ytv07jQ+PJBhhZGEiOAngrcILiK4imAjghjhIIKzqD0+2SFOjEj3pb5LIifHZnB3RR/YXAX7B8CBcthRCPvTYVcSbI+AraGw0RM2eakQ7jZXFbzVhXnv1VoyZrMdbLQxsE5grU5ibFWVZputyuUccoPTPnApBJ4LUDmjV0PhtXC1tPFOuJG4hCve1Hg9DF4Lgptp8EwM765K41ytu15gWsKa2LQkMCaMLbKg+faSJS1VY6xVZawJjA6duJjIzIgsM4HRVWLMURUZy+pMpkY2Twwyutekz9Hc68ik2jPzqBHWQr/WtwAbBKa5kwXWDkpal5lEFvRMMGz4NbuKbZmPUZUZncAYo6vKzKxspX8+o0ssMytbMbOyFdM7xzCjSywzusQyvXNrZljZ8GtxlqAijokVcdSWt6KmLFbP/1xg9KLSTBvnfjfEmqPLkuimeh6UpvouNM5UQrJ3anv2TdEw+/6ttdT2mOy2MVzI3jOtzPL3QPs9Mw3+NpeTsZxkuncbqfkKirlktNRC+jUff3yB5a9/Yl4lx+d24an5VZyYV6mvtByeVcbphd15am4nvcCs6BHIknbCqo4uHO/txpmBPrw4Qnh9kgOfL9cE5o0wJTCvhcKbMWrV/1kPOOqsJOaQnZo4ajDKMezUKil7Rf2lv9sOLqbDa+W83sOHFU7CyTbCx/28+fciO1jto1401tvCJu1zXfaCu22UwFzS8jYv+avPv1HUr3lcVAn/ToQSmNeD4fVoeCMW7gQobubBs0kwPYivOwqkC+S7QoYH/44TPo1z4ItEV95sH84n3RI41zWexqIgHs10Z1aMUB0ujAlT4jEsVOgXKPT2Ex7yUfTwVvT0EXr5Cv38hUHBwrAIYXSMMClamBilWkjjooXqGGF0pDA2WBjhqzbzDrQRRogw1k6Yby886ikc8BaOBArvBDvxQYQ7n8e784c4V75IDuGT1r6c9hQ2iHC6RGB/FZx2h5NucNIZTrkogbnoChcc1e/fZRclglfbwLsl/LI5iROdNHmpEC63Fy6VCsfbGQRmR4qwIllY386JQ2NyuFTXhZMaxgKzb1YVO+p60vjwQAa1CyNAExgfTV7cRbATwd5IYOw1qfEQtb8nTDsPUSjCUF/hQIFwuzqYv9QH8v3iGFgXBbtT4GAC7Gut8ky7Q2CHpxIY3USSubjoci/NCcwmW1OB2WAmMJvFIDAHXeGkF1wMVgLzfBDcCFYCcztUCcybIRphirthSmDuhMOrgUpgLkfzzspUzkxwuy+BsSYxuorNlvGFFtxLYCyrMgYeRGY2jCloMfSrhMY6xgKzZkSWFvjNbkFkcizaS+rRIDArh2S3KDAtnTIwF5hHzaTGcgNwqvZjtQnYeNuvucA0dxnbVGQMRyWtSYxl0DfBpM1kTWTMhUYnNTMrW+kFZkaXeKsCY743Ricw5oj5C3ZzFQfLTbS6For1Y3yGakTLOZTfIi8PJDD1XUxoqq+iqb6KHbXFNNQU6W8/6cbJjc8hbK8tZXttBxomGk4lbJ+k2FrbQc/2SR3ZMaWcnVM7sXNqJ3ZMKWfHlI7smNKRXdMr2DerC/tmdWF/XSX76yrZN6uLITg8s4tCHyJWm2l1e1L0+1Lqq/QcnqOqMMcXdOPYvK6mFRqzzIlxePb43CqOz61SQVqtknN0flea5lXpMf5czedvDD//8LwqmuZ35fC8Kg7OreTwvG4cnGt4gdk5tZz9dZWcmlPOidkdOV4Tx+MVwr4q4ewwF66PEG6Ps+X3M4RPpwvfLBVo8oO7MfB6FNwMUgLzWhs446VeJNYJP68R/r1K4AlRodxNosK7uzSB2ecB+z1VpeZuKpwq5UCSsNVHuJIrfFvnBcuj4XFHWOmsZWJsVRvkdiK86guXbOFqoDpTcCUYGoR/Nwics4PrreFWkqoO3QqDm8FKtl6Jhxei4UguLHTjmxLhzx2Ef3cQfuwofJIjvBwubPRVa/fnxQtrCn1YWBZIfZEXMwtcmZHvwrQcZ2rTbJnURqiJE0ZGCgMDVTWmv5862tjPRx1wHBagTgmMCVOnDybGCZNaK2pbq4+vibNlfIxQHW7DiCDhoUCVn0nQTiOEihCsCYCX9uLupomAq/Y2b60lEyvCrj7Cj0/1VZeZj7rBcT84HQxnwhTnQuFsiBpJvxAELxTCSyV8ONKJg0nCxULhxU42XK1w5GqFI2dKhP1pwqZ4YUuCsCxBWJ9jx5ExOVyZ3ZnTs6o4NbPSaExf/UOkcW4PDs3vxaCsAIJFHdkM1ATFQwQnDd334yyCo4az9nNcNZFJEGGqt/Bkmh/7czw40T6Y0xX+XOgayo3BrfhwUg5/f6QUNvWFA51gXznsSYSGONjmr+GqjUi7KTa7qsetjipztdlea186wXpHWOekWO8Max1gvR1sclRVwa2OatFeozuc8oILgfCcPzwfCDdC1aLE1yPgThTcjVC8Ga24GwVv6f4fCoXrmfB0LG8vbsuFag/D3121pfq/57bXdmBrbZliYilbakvYVlOiF5StE4rZVlPC1gnFepoVmHEFpoIzrliTleZaTPcnNM21mSwpZN3IAgsMMmMW/NVXZMxRraWWqzTWKzBq50yunscG5+gxCEx6ixiyMxlWWdI/nSX90/8rAmPt5pJl4FfXZtLaSd1a67MyxhmZ5iRGV5HRCYxuMV5zEtNcPkZalpeWBUZ3jK+lezb3IzAPIizmPIjAHJzdmYOzO9NYV6EXmM3VeWyuzmPL2AK2jStk+/hito8vtvyXxbhitk4o1f8Pu2l8IZvGF+r3HmwYW8im8cVsqTGXGiU6Ookxx7Ajx3Rvzt7p5eyZVqZvZekxalM11plWbIwzN7qqh251v/ECOZ3E6F4Ajs3rysHZnWmaV6Wfvjoyp5JD2qN5Jci4jXV0fleOLejGkYe7cXThQzTN70rjnC7snVnB7hnleqHbO7Mz++sqOTarlMPTitg/IpTt/bw5M9SZZ8b68Pp4e96e7MIfZgl/mCV8vUTggJcqkb8eBTcClcSc94Htwv89Jvx5kdqu+8/lWlVklxF7Re2B2e+pPs9+US2nt8fAxlg2uAs7A4SPRwmsiIUVdvCoDTypSdBZT1OBueIH1yPgpSh4PgKe81AtkVfiVTBS1+K6Ha5eSK6EwmbhL2OEV4qFb0oEBjlAdRj09+DLEiUwq1yFR0QY7SHMaSUsLAvkyT7xrBuYyJr+8azoFsXcEh9mZ7gwPcWemnhheJhqKQ0KFAb6K0YECaNDhNGhSmDGRQm1sUpeJscLUxJtmZJoy+Q2DtS2tqMm2oExoUKPIKGzl5DqIsRpAhOivfj7aNULR63l4qC1ZNyNKhYnRjvx88l+0OgATS5wJgQuRGryEgFPh8OlKHg2QmWCbpbBs+242UM4lCycayc8XSCcztNaSHnCniRhY2tTgTk6Npdn67voBaaprrO6L6YJzKH5vTi8oDf9030J0SQsWARPDWOBcdee2xtVZXQtpTYi5NiqzccPR9ryZLSwKlJYGSksDxGWBgjLg4Q10cL2tsK5TsIbo+z46zw7WBui5GWLjxKY7e7Q4A3bvWCbp0InMDqJWe8I6xyUtKyxV49rHWCtDWywV63Nrdo17EOeqoV0MRie8YWrAUpgXg03CMybkRrRBt5ppf4fuhUOr2TB6Qheq4/m9HAnGiaX0TC5zOgAbxk7J5XRMLlCQ/s7TC84BrbVlFiIjDXM/x7dPLaoxQrNb6nSWApNoQkWMmPeehqZbajKaOgERpHdLKuGGh+a1Caa9Ft/c5uRGJWVWT44i2WDMiwwFxjLMLCpwOgkxkCGHmOZsaCv7rCkIQhsLjCmEqML+5pXZEwzMubVGWORUTLThplWNvxaiky8RU5mSqd45J4VlhamcHQr9VvKrtxLTu4lLc0JjG7q5X4rL031ndTUktY22jWplB21xWwbV8gmo/0FG6sLWT863yQUpvuDqbu/odZZq6VJy4dms3xoNo+PyOeJUQU8MarA5PnqUUWsrS5h3dhi1o0tNiyAGlvI+nFFrB1fxIaaUrZMLGPrpHK2TmrP1knt2Ta5jC0TO7B5QikbxxXp5WhTbQlbJpayfVIJDZNL9ecZ9kzroF++t3eGpWgagsQV+u27h2dXcHz+Qxyd282iAmPc5jLO5ugqP03zqjg631C5OTi/C02LuukFprG+G6eWDuDUkmGcXDyUA7N7sKG6mCceCmZWni37+jlxZnwIL40VXqkV3pss/G6W8HW98Nf5wj8eE7VM7CVfte/ldjC85AU7hB82CuyzgROe/Pik8NMareqyxw722SoOaBmYYw4qlLtfE5uL0XAnj29n2rDGR3gmX2BBACzzgUXu/LBIYK0jnAyCN/LgtUC4ZK/aH8+5w3M+8HIQvBKpRravRcKNaHgxAV5JgWc6QlMa1AfweTfh7fbCZ92Ff9UKPOoGm0NhiSPvjhROFQirE4TZPsIwL2F+ii0NIzN4ekF3zjzcnaaZHWkY3pbHu4WwvMSDhbkOTG8rTIhRkjIiWEnMkCAlNTpGhAujo1S7qLa1DZPilbhMbevM1ERXJrdxorq1MyNj7KmKsKXQU1VUIkQI0NC1Vuw0zPMjwVoV5s257nC4ABpT4FQ72FcIm9LgsUR4NB5mx8G0SJjSBqa3hZkZMCSU/5Q48kM74T/5jvyS58C/chz5Z7Y9n2cIb8cKFyIV26OF/YnCmdFJXJ9dwrHZHTla18GQgZvbld0zyml8ZBh75g8kJ9wOL6PKi068jCtIXprAOGhtJFuj781bhDYuwoQIB6a19mB6sA1Tg4RZAcJ0P2GKhzDRVahzE6Y7CTNshdURwtkC4UpH4f0+nnw5MoxvJyTA7FxYkAYr8mFlOmzMh+15sCUH1sXD6hhY7adY5apY7QRPOiuBWa8JzDZndVupyRtO+Wqj1L5qCul6INwMURmXuxHwdgS8E6WCu++EwdtRiltRqlLzUgEcjebO+CBeGuzK3omZ7J+Szf5JHdk30SAw2yYrdppVo02r0qU01BTRUFPE9gmFJs8t0P5huG1cYYtsGVvAlrEFbK7OZ3N1vv7Hxm/bNKad4fnoAjaNLmBzdSGbzeTGuEqjQycuBqnJY92oXNaNUvLS7Ei2vtVkOpKtaz0Z7jPpxrJ117LzNCxPGRiHfS3GsM0ERi8yVrCWjdG1lnQZGQMZ+tHrxX3SWdg3VUN3wiCZBX2SmdezrRmWI9dKXJI1dJt9k/Uj18Y0t0dGn5UxC/6aTysZC41xdUbuV1z+1wJzr5s7OmEx50EEpnFWR33mZefEEhpqithcnc/GUeoP8frReQZhGZzB4wPTeGJwBo/2TWJxn7YsG5DC0v7JCu0PyoI+6hDX0sFZrBiWx7IhOSwekMHiARksHZzFY0NyeWJ4O1aOyGPliDyeGJ7LyhF5rBqVy+rR7Vg1uh1Pji1g/bgSNowvZcOEQjbWFLOxplQJjtHmynVjClhb3Y611e3YOK4dm2sK2VZTwPaJhTRMKmLXlBL2TOtg9cq3IcNk2LXTOKsjh+sqOTJHVWAOz63UV2B0IWfzALI+nFxXwYFZ5eydoe5d7ZhRyr45FeybVc7+2RUcWdCT048OorG+N08MzWNax1B6tVIL1gaECnv6OHBlWiyvT3firdlufDZH+OMCO/75iPDdo7b88KSolfDPecLtCPWvyus+SkJOe8KNBHgrC054q+rLdoF9jrDfDg7YwyFNYk66qrHoM25KaLYJPNsaXh3IP2bZcjFX+HSYwHJfWOrN3+sFVtrCuXC4lQM3/ZXAPO8J1/3hWW+45A4vhymJuR6lBOb5eDjhBys8+Xiw8G6p8OVDAlPtYZE/LPeElb6wwhVWe/Pj0kA+GCMcKLHjkVAlMLPihe0j0rnw8EOcml/FyXmVHJ1SyNYhCaztHMSyYnfq0x2YGCeMjVDVliFBimGhBoEZGaEEZlwr1Taa0Eq1jibF2zO5jRNTE12ZmOxFbZInfeLd6OAntLJTVZUgGyHYVvCyVQJjbyYwNtqLf4AIMSJ8siwITpXB2mD+MV34YYDwbU/h+y7C39oL/yoWvisVvmsv/KNI+KFYoLMDdA+AKj/o7A/lvlDmDx19+aHCm3+2d+eD9s68U2TPyVzhZK5wYVwaN+Z04MScMk7MKeP4giqOzOnM4Xnd2DuzgiOPjmLH7D6kB6mpI09NRpy0CpKrJjS6qSTd280FzU+EOEdhgLswOkiY7C9MCTQIzHRvYaav8LCfMNtdWOih9tacyhUOJAqnk4Tz6cLFdOG5XOF6e+FWhfBRd+GbIcJ/JjrD/BBYGgxPxsJKHyUwazwUa91gjYsSmHXajpiN2vXr/a5w3APO+qvpuKt+SmBe1eVfIpW8vBsN70UqgbmjZWBuRcG1YLiaA0ejuTXGj2f72rOnNoPGaXktCow1dCKzo7bYBJ3EWIiMJjAtYSww1sTGutQUmnDv6kyhGXl6lMg0Ewgema0Jjvk00/9WYMyxeo/J4sCkOjJpuJSdbiIwOloSmPm9kvTMM6rAWIpMCnN7pJgIjDEtScysbonNTjGZTzBZXsFWIiMPIi/WBOZBhOXXHgy0Li+GW0Atv9/w8w7VqYmjPVNK2DmxPQ0TSthYnc/60XnojoQ9MTRHGa22YGhxvxQW9Exgfq8kzUyTmd8rhbm905jbO4267inMfiiVub2ymNsri9m9MpndK5O6HhnU9chgTu8s5vXNZU6/bOYPyOXhQe1YNLSQR4YV8MiwAhYPyWfp8EKWjyjQs2JkIStG5rN8RDsWD81h8dAclgzL5tGRuawYmceKkXk8MSqXVaPbsba6gPXjitg0vpCN4wrYPK6dQmuNGchh2/g8tk5QNNS0o6GmHVsnltIwuQM7plewY3oFO6eWa60tw24fFcZWrat9s7qwe0Yndk7ryI4p7dk2pZjtU0vYPbOIg/PKODSnnL0zSlg9LJN5VZGMzvChwl8o8xTauwrdHIVRYcLlak/efaQt79cJH8+14y8PC98uFv5vqfDT48LP67UKzAVPJQrvtIa3YtUY9SlXeL0tvJkC1+PggLZR97ALHHaEg/Zw0gnOuMDzrurUwAthanpJF/S9lgxv5vPzFhvemiJ8WCe8P1P4/UKBfU5wIwZei1MvFM94wY0IeCsBXkmAZ8LgXBQ8HQuns2BPLMzz5tMhwjudhA+6Cj9P9oTlbdSU02PufPeI8P1i7dc+HQTnEvhloxNX+tiwIVGo9RNmRQobe8VzdkZnTsyr4Pjccs7VVXBofB5b+0azotyb+TnOTEsUamOEsWHCiBB152hEiGJkqPr9HR2h9r6M0RipMSpaqE10ZkauP3XtAhmV6UdVmJDgLISLEGorhNkJPrZKAswFRleBCRDVcvp2YSZ/W5DOt5XCNx0FSlyh1A0KvSDXDdJ8IN1XLezLCoXCMCiNguIoyAuB7GBI8YF4G2glkGoDhZ7QyQe6BkJXL34uc4KeIdAnnB+HtuY/IxL586Rs/jo5ly+nlPDF5CJu1HRkX4cwuohQIkKGjRqb1rXE/DU587NV6HI9ugqN7nvzESE32IFHiuKYmxPB8lhfFoW5sdBPmO8jLPQSHvYQ6pyFR/yFy/2F3y/w4c3pwvPDhUt9hGMVwuEcYVeycDpOONtGeDVauBEpvBsjfJ4q/F+W8FO+QJ9AqI6HaW1gdgosSYdlWfBEW3gyBZ6MVGz2hB3+0OgFxwLhnB9cDISXgtWfzdvRav+RcevobhS80VoLo6crXuwFB7P5uqcHH3YUrgxN4NrYTBonlXBgYrHRWZkyjdIW2TmxhJ0TS5qVGHOaq8xYk5l7VWkURSY8eOtJVd4NLacc1o3KNmHtyEyeHJnNkzqJGZnN+hEK3Y9Nt/8at5XyWDU0Ty80xicLdFkZ40V4y4doDM6y2layds6gJZGxlBhTgTG0kcxPFJjfXDI9IrmwR1sW9rAUG8vjkaYiYyE2xnkZ4/0y9zmOLQ96/PBBBea3Xkv+bwpMU30nGmeWs3equrq9o7aUjdX5rB2Zrf/D9djgLJb1T2NR32QW90thUd9k5hst+Knr2oYZXeL0J8F1q47Hl8YwoX2s/shUdUk049rHUlvemokV8dR0iqO2czwTu7RhSlUiU7slMK17IjO7JzG7VyoL+qbzcL8MFvRN10jl4f5pzO2bzLx+qczvn8KiweksGZzBksEZLBuSwfKhmTw+LIuVI3JYNTyT1SOyWDMig7UjM1k7PMOMNDaMymT9mAzWj8lg05hMNldnsa66HZsnFOtbV1snlrJ9Unt2Ti7VT1cZn4jQCc6u6WU0TC5l25Ri1o3LYdWIBJ4c1ZalfaOZUurGgDZCoZuQIUKeo9DRXegaKAwPEaojhbPDnHh/STKfzLPnd/Md+Hax8P1ye358TPhlpZZD2eEIp5xUteOd1vBhIlyLghOOcD0WbiXA3XT1F/kugb22qrW031Zt7H0pDG4Fqn+B3og1CMx2UReIX0yEt4rhcmvY6wM7PeF0IDzfWlVWLvmqUv3NCHgjTvFMGDQ5q/s464V/zBPeGibcrBDe7ikwzQfWpMETSVAXyHczhf/MF1gpsM8fLkaqdtOVdNjty53xAezJFaYEC5MChEdKfDlaU8yJeRUcm1PG2VnlHJ9czK7B8Swv82JupiNTE4QJkWqfyfBgtedleLCSFx2jwtSjriozJFQL/wYoiZmR68+ishhmlMUxLNWbLD8hVpOXUFvB20YJjIOYTu/oBMZfhLaOwtez23KzvxufFwk/93WHbsHQPQQ6h0NH7Yp1mg+09YbUAHUYsigc2oVCViCk+UG8Kz+GC/8KEn5pI5DvAZ39lMD09IcqT+gWwE+Vvnw/KJbvB8Xy6YgEPh+TzAejMrjeI5LNuV7MCRI6i1BpI2TZqQOcIZrE+OuqL5rEeGoVGWetGqNrI3mL0DUllJMT+9JU3Z3NGTEsDndnvo/wsK+wLFBY4C5Mtxee6ugFJyvglWFwPh1OtoU9YXz7hAPfzHHi91OErwbb8UE34bN2wvupSl4+TxW+jhc+jxE+aiV8HCd8nCp8XSh8+5DwyxAXmOIJ80LhsWBYFwv7w+BgJBwNgBMhcN4fLgXDyyFKYG5FqYWP5tmX91LUaYy3iuCK+dkFAAAgAElEQVRuAVyuhDXhfNLJjg87CpcHxfPi6FQOTm7PoSkd2De1gn1TK9gzufyBBOZBRUbPhBI996rOWKeYbeOK9QJzrwxNcwJj+HEu60fn6NFJzJpRuazRWk3rRuW2KDCmEtPORGAsJEYf9rUuMOY8qMBYVmIyTGhOYKyJjLHALOqZZCEw83omM6eXQicw9T1SqO+R0mxlxtpyvAeRGbnXsUPzbbKW/HaBaV5ClHS0fAW5uWvK5pM0nbUcjBptNhaYNSNUUlz3B2Jpv1Sj8FJb6roZ1iFP6hTH+I5RVJdEM6Y4klHF0YwsimJQTiiDckIZVhjL8KJW9MsKpU9GCEMKYxlWEsfQ4hiGFEUzuCCKIUXRDCuJZWT71owua0N1RSI1VcnUVCUzuVsyU7qnMLmbej6mPI6xneKZWJXAlO5JTOuVxrReaczqmcKsninU9Uqlvm86c/smM79/GgsHpLJoYBqLB6axZFA6SwalsmRQKksHp7F8aCZPDM/mieHZSnpG5fLoyFyeGFvE2gmlPDletbE2TujAptr2bKwpZcPYfDaOK2DLuGK21bRnW01Hdk3uxI7aQlYPSWZVP38WVznzeCdhU29bNnQS5iYLYwKEnrbCQ7aqHD/QQ5gcK6zNF04NDuWdmb58uiCMPz9iw18W2/L9ck1cnlTTRWwT2OOogqHPRcF7SfBhigoivuyvlsO91QreTFTh2kZ71UraqAV4L3vDrVgtBxAKr8fAZQ/YJvxns/DzLlGXq2/6wYdx8FaUKsPfDlTL6V6NUFzPhGsZcDYDGmNheSDfzXbkq/HC59XC1RLhpY7CVzUusDoFVoXww8OufDlD+KZOYIsdnImCS4Fqgul5b7gWoG4snfPl78sCuNBdWBYjzPEX5qW6cXREEWfnVnCqvozTs7pwYno5+8aks7JbCA/nuzM1SajRRqx1AmMsMSNChMEhwqAgoX+Q0NdfnRXo4atGr/sGCRNS3Xm4LIaFVUlML46ka6wL2W6qlRSpvdj7aVUKZzOBcRIV8s10Ef41rwMvVnrzVaYLfy/wgdwwRV445IRCur86S9DGG5IDIC8YCsKhnR9keUKqA9/FCV+ECL/zE74JEL6LFUhxhlxf6BACXaKhU5SiYxgU+EG2B2S6QrY7pDnzc7o7P6S48FEr4Za/8LSbcEyElSIsEmG0qFHxDhpJYrggHquJi6f2fSc5CrVxXkxPCmSevzBHq7ws8haWewuLXIQ1McLfl6TBq7nwfJIau78aAFdj4IVYuFIIzxTAgc6wLAH6B0BnR6gMgofCobI1lEVBki8/+QvfuAhfOQnvOwif+wifxNrw+3h7vqzw4qfBcfywLA+2dYUDXeFYHzjZDc71hqe7wDPd4IVKeLk7XOuqeLk7vFgF1wbA1V5wshfs7QizU/iphwPkOEGuM59UtuKPvVN4amIJJyeVGjaqT+6o0Z69ZtvajbEmMuZtpZbaTMYC8+tkptiELRr3Hw42Pn/Q7n8iMKuHtdO3mIxFRhf2NT4m+dhQHdk8NjTbQmDMF+UZX83W7ZTRsczq/hjTiszifimKZsawm6vELOqpMD9ToBMYncSYVmPaMquHKebL8ZoTmuZaTL9ZYB5EWFoSFWu0eJ9HN/7b3C4T/fsN+1JUG0kJzJ7JHfUtpDUjDLP5ywems6Rvin6BT1231kzvHENNxwjGl4YxtjSC0UUhjCwIZ0R+GCMKIxmSF0bvVD96p/oxMDeCQXlR9Ejxp2uiD32yQumXG06frGD65oTQLzeUfrmh9M8LY0C7CAa0i2BQ/v9H3XtGR12n7/83pPfMTJKZTCaT3nvvvRBSSCE06U1AikoTkCYINuxdVkQFAaVXAcVeaIKi2Hct23fd1bXsrqu+fg/enymZJIDu/r/n/B9cJzOTSYwePHlx3dd9X1ZGlyuNLbMwvtLKhKpoJlbHMK4qmrGVViZUWZlcE82kuhgm1cUwvUFpRmMsM5sSuLI5jrltCSwYksDC9kQWtyexpDOZRUPiWdyRwLVdSawYltbrQNLK0TlcP6GQW6aUcfPkUm6dWMqdUyu463IVNLb9DeHWsSrgduvYQtYOz2JVRwyLB5m4rtmb20aEsuMKM4fmxfHSwlSeGm9gSbowLli4LFAYHaR0eYRwZ6nw1rWlsL6Mv9yYxJer3fnXOn+4zU1tX9w9QLXyPuIBT/jDDn84ZFRldR9mKGh5M1qtV5+NUvDyogk2ufEvGwA9KnDMoOzzdyPh7XB1m+V0FGwfqByYbQKH3OBkiHJo3jCrwsE3wtQ9l3MJSvuj+foO4aM5wokx6oLvH6YJ54cLb3UKf50ZxA9LrHyzIIT3RgkfTxL+NEfgzgB4MhGeSYYXMuAlKzxjhOeD4EUdvBIDL0bBg8kcHyvcmiIs1AtXxQ9gQ1cWe66pswPM3vlN7JhdxgMjE7mp3siSAm9mJw7sBTBjjMI4ozBGc1q6Deo2jO3wXVuw0BqkPo6NExaWm1nRks6i+gRGZIZQbRKSvVSYV6f9Urc5FH0BTI638OXCSvaXDuBsuPBejPB1tDv/iHKDaA+I8YQYD4jzgsQgBTB5oVAcDuUmKAmBwgDI9OCLGOGTEOHTAOH3OuHbcOHfVoFEgTw/KAuBEj0UBEKeP+T4QLq7+lx5CDTFQ3sajMiD4bn8pz2Lb5qSOVlq5XByAPdF+3CTQRgbIAz3FEo9hGxRW0dx2r9rkAYwZhEaRRjqL1zlI8wPVACz2qAAZqWfsLdeYFOHgpddZgUwr0bAKwlK+3Lg0ShYnQSzdTDUAC1+0BYB3bHQmQGtyVARDwUWyAyDhAC+jnbn62h3zpuF1/2FTW7CRhFuMQkbM4TTg4RPRg3gP7O8YYEebjbDgymwMQk2p8NT2bAtAx5LhQ0JcEsELPKBSW78fajwZZ3w5wqBQm8o8OKDhmh+15HKzivK2TenhsfmNfwigOnPlbkYzNjOV/zqiqp+YebCQFPFQ9OqegHMpUOMa49TYQ/ZQOaOyUXcMdmRl7l7QiF3T3AATX91Bv8twPTSBQCmL4hxdWWcAWb1sOw+AeZSYGZlV3oPgLFpcZdDfcHM/PZUFnSksaAj7WcBTH9uzP/nAPNzoeXnAswld/csaeHJReoyrjPA3DelhLvGq1CVzYZb1Z3B0o5UFrUmsWBwAlfVRzOjKoLLy01MKDMzKt/AsJxQhueFMTzfyNDcUFrS9DQmBtCUrKM51UBtfBDlVh+qY/1pSg2lNj6AyhgfBqXoaEgOpik1lJYMEy2ZYbRmGWnPMdOZZ6GrIEJTJF0FkXTmWejMs9Ceb6aryMLQ4kiGFkcyrCiC4SWRjCgOZ1SpmTFl4YyriGBihYXJ1VFMq4vlikGJTKqycHltFDMbYpkzOJGr2lLso6t5bWlMH5zGgmHFLBldwZLRFSwdkc91o0tYdVkBy4fnsrIzkxUdGSxvT2VlVzqrhuVyXXcOd3W688hYHXsmC+fWhPL1gyF8eb+OH9ZH8MkKYUutsCpSWBYmrDAJy0zC8nDh7hThYIvw1SoLP92ezHfXC9zu2bOpd/1AFcjd6g87gmCvAV4Oh3PJ8E6cumvxtuaWvBIOL4XBtoF8f7vmwDwmcNhL3WV5L0G9/x0zfBAFb4TAi17woi+c0MNJg+a4hCg35myUOg52LEGtAi8P4Z0u4VSzcL5bODnEg9OdXrw9JowPJll4e5wnLzQLT9cIx4cK39wg8GSYupJ6IlaNrl6PUYWGL+pVI/MrOnXZ9w0r7Ijm/XnChmLh2lBhllG4tyqGp2aVc2BBAzsXNLNrYQu7F9Tz2LRC7h6awIpqHVdleDLBqqBldJgwOlTpshBhpE7oChTa/VRousnPUTHQGKjuvnSECdMzA1lWF8eyujgmZwfSZRXKApUzYREV6rX9YvfRwMVXg5tIEYo9hb8urGN74UBeChVOWIQvrN58GeOroCXBB+I9lBI8INET0gZCpicU6zR3JRKGxEFbIjREqmxMmQUydRDrAVEDIdEHMv0gLwhKTFAaDkURUBIJ5VaojILqWKhPgMHZ0JwDg/NgUA5UpkNxIuTFQ7KJb6P1/NXky1thfrziI9zvJdwgwmUidIlQK0KTCFNFmDtAWOEurPUTbtcJ95uFu8OE+8KFzy/3gMMj4XAR7M2Go7VwsFI5LmtTYaIVOgOhXqdUY4a6SKhOgNpEqEyB8kQoTYayFCjLgNJ0KEmH4jTIsUCCjj/rhfMi3Cvq59wpwpsG4atI4R9W4csI4bsY4d8Jwk8pAukCmdrHdKfnOT4K9vIDlTJ1kB7M38sj+Wd9IgemlvLMLAfAbJhTy4Y5tTw6u1Kp10FPpYu5Mf2pL4D5ZTBT1UP3u0DMxWGmpGf9wdSi/ynA3D6uhNvHldgzlo6wb9+h3/9rgHG0Yfe9ht3fSGmlpqVdmT8LYGzwYpPzhd/+2rD77WFqTvy/BZiLtR//rFZkJ4C52MVY2/ufWqzWgzfNreOxKxt4eGY1904u5q7x+dw8pqCHA+MMMFfWRTGtwszUMiOjC0LoSPWlOdGHliRfmlP8aE7xozExgEqrB+UWDyqtXhQYB5IZLOSHDaAs0psi80AKTEKReSBlkZ6UW30ot/pQEe1NZYwPNXH+NKUaGJyuZ3C6nobkYOoSA6mND1AfkwJoTNMxODOEtlwT7blhtGYZGJIVRHt2MF05wQzN1TEy38CYEhNjS8MZX2ZmfJmJ8WUmJpSZmFxhZlKVhUlVFqZWRTKtNorR5VamD05jZmsms9qymNuawoKODBa0aU2jddHMb4xjXkM08xtjuH5kPjePK2XbdAun11Xz2/sT+dvGbH7aHAVPJahG4m0pvHOlDxuKhVsTldYlCXemCY/kC48WCS8NE75ZGwV3+SiAechN653Rmnef8IVtAQ6AOWZQYd5z0RrEWJRTctIKb8TCcya1Kn23qAun20Rdf33TqrIA5yOUG/OuRelcBJw1wRtGrc/ICMf1cCwQDnurldUNnrDKyJ+nCW91CK/UCUcrlQ5WCgfKhS3ZwsEq4eNpwk83hMLuCHgpE16zwquR8LIVXomCV8PgJYMDYI6HKz2dyle3CLuaPLkuQpiuF27OD2PjhGwOLGhg18IW9i5uY++iRrbMKuXBUWmsaTBydaYX4yMVwIwK0cBFLwwLEoYGKHhp8xEaNdX5aoWPvqrwcXCQMCZmAFcWhDK/1MzEDH+6Y4R6o1Do4zhsZ9JcCds9FZ2oI3GxIjQYFMBsyRGeDRJeNyuA+Wey+uVIejCk+Cole0OSFyQJJAgkD1AOSo4n5Psoh6XeAg1JUJ8IRWZIDVAQk+gDWf5QFAKVkVATDRUxSlWaKqOUKuKhLBZK46E4FooSIC8GcuMgJxYKk6Egia8KUvlLdjwv5UdzKCmEW+K8WGkUpvkJU32EhZ7CIi/hPrPwYKTwaJywOVl4OFrYW+AOt6bBsTFwtAR2Z8L9VlgyAMYN4Kd2gSqBGoGaQKgNUqOvukgFL7WJUJUKFUkKYPJjISsWMmOUsuNU2WdupAo+54ZzPteHY2bhbaPw2yQNSjIF8gSKB0DFAKj3hkY/GOSvoKkuCOp0UBsM1SalqnAoMUCWHtKC+KI0gm9qYtk9oYBD08o1eKm+ZIDpD2IulJPpqWq7+oOZCwGNK8CoW10/A2Rcju7dPbmQe6YW2UHGGWDunGIL/CqAsW2v/i8B5ia7CrhpbEEvgHFsMTlyNBeGGddsjOP43f8aYJZ2ZXLtUIcWdabbYcYVYBZ2prOwU61f97zwe2lAY4OYXgBzoTJC59cdB9Qu3XH5X4CLM6w4Q8uFunpsj59arN0yWdDA5nmNPHplLfdPLeXuCeoP3C1aiHftyGxWdqWypDWBa1oSuLoh2gEweTq6Ur1pS/KmJcGL5kQfmhN9qI/zptrqRkWkOxWR7hSGCdnBQlqAQxlBQmawkG0QckPU4wy9kBvmRp7JnfxwD0oiPCi1eFEU4UGeaSDZxgFkGweQH+FJYaQPRdFKxTGBFMcEUhQXQGlCMFXJOhoyjQzOs9BaYKU5L4rmvCgG51qV8iw050fSVhjFkKJohhTFMqQolqEFsXTlx9Cdl0Z3Xhqjc8MZXxjJ3JIAZuZ6srZU2D7Rn3dW+PLFfTHwuAV2Jatcx4FYeFqvjr7tF7Vu/KJO3aV43J+XxwubioSNecLWHOHJfGFnkbC/XHi1W/hyWZDaNLpX1Pn/J7xgm5/SU36wI1A1Ou/VqX6dZ0LU6f63o9RV3jOR8EaEOuV/JhKeD+SH9cLXdws/bRY47Akndaob5p0oOB8D78YrvaWdWT9rgVf1KrvwQpwKYm4wwo1m/rrAmw+mDuTN0cKhQd5syhcez3PjkWxhY6awrVB4pkX4YMYAflrnrtqM9wTDc1btvLsVTsYq8HrdpOoIXgmC1/TKlXk1Gp4Lho3CycnCvRnC7ABhVazwwLA8Ds3rZO+1Hexe3Mbepc3sW9bC49OLuHN4PEvL9UxPVlmXkUZ12G6YTugMEIb4Ci0+Sk3ewiAvoc5bydZW3egjDA0TJiZ5MDMnkCtSPJkQJYwyq1qCOh+h0kPIH6CC2LbMSLoImSIUiDAlzo8/LajjqSJPjoULz0cIv4vy44skA6QGQboO0gKVbECT6gfp/pDuC2k+kOYPtvbrNL3aSMrQqefJgcrFSfCBzADICYZiC1TGQGWCUnWiUk2i5m4kQV2ygoPiOCiyKgjIMUNuBOSEQ6oe4gMg1heSAlW4uNQM9XFQa1Sq0EFZEL9PF34dL5xLEt5OFo7ECH/uDIENXbBpJCwuhAkWaAyEGl8o10NlKNTEQ12Cw3GpTYW6NBiUDy3F0FIIDdlQmgR50ZBjhQwzZIQrZYVDhlGFn9P1apMrxwBlYVAfBW3RMDQJJuTApHyYWAjj82B4BrQnwqA4aIiB6kil2iiotECJGQqMkBMGWaH8kG+C8mheHp3FyUmFbLqqjMeuLGXTnHI2zSnvdY6ht/qHmf708xyaS8vQXOyoXl+HSW1A0wNstC1OG8TYR0tTNWlhX9v9Gectpr5XsEu5Y3wpt00otENMT5jJVQsYtq0l26hpTEGfcl3F7rmS3VdVQV6fh+/WalozLLuHejk0LndkbO3XNtku/C7V5Aww/bkxznK9LdO7sqB/kFnQkoRcDFAu1tXjCi7/M4flIqWCu5a1smtZa6/nrq+7ujO2y7JbFwxm87xGHp5ZzYOXq+N1t45Vf3BuvCyPVd0ZrOhUPRALm+OZo42RJpWaGF8UyogcA13pgQzN0tOWEkBdjCd1MZ7Ux/tRHeNFucWDwjAhS6/Axab0QAfQpAcKKQFCaqBSsr+Q4q8AJ8sgpOuE5CCllGAhTSck64QUvZAWMoCMMHcyTG5kWzzJjXAn3+pFSawfZQmBlMYFUhYfTElsAEXRfpTE+lGRGERNqoGGTCONWWYaMsNpSjXSkBRCQ5yFhjgLQxL9qY8YyOQU4fqWaN5dV8TXW4fCkwWwvwoO58KRfHg2Vem5cKUX/JSeD1IjmKdj+ONq4egQ4ckKYXeJsLNYuRXvjg+EW63wZJmqC3jYGzYOUGvQ2wOVdgTCziDYGaig4ECAgpgXA1Ve5VwMvBWt9RBpl0jPRKom6uf0qsPorSjV0HvW6DjoZVsvPWGA14LhhQClo5GwW8dP6zx573Lh9U7hzEjhkyu8ONEtbMwWHkhWNz8eyVYtyofqPXh7ivDF0hC4xx82W9TJ/OesCuJOR8KpODgRrYDmRDi8qtMUrSDmNRPsHsAni/RsrVY3RhabhNtbUzgwt6MHwBxY3srOeTU8MiWXGwZFcnWOF+OtCmBGhAjdwUKHf2+AafIW6n0cAFPjI9R5KojpNArjE9yYlujGxGhhrHUAw43C4GDl2JR5q1FRnpdSgaYSEaYnBvL7eTVsK3CzA8xvrb78OS6Y/yT6KojJCFZKD1YgkxEImUGQFaCUEaSUblCyAUxqsFKKv3JiMgMgOwhyw5Q7UxrtAJiaJAe4NGVAazbUZ2oOR4wGMRbINKqsSUqwAhirF/+yDORbk/CPKIFiE7TGQHs8tEZDoxmajPyrIoA/VfjxeZEHZ4uEry+zwvJcuMIK9cKP1QJ1/lAfACXBSqXaOKwqDuqSoD5dyRlgGnOhIgXKkqEk0QEymWZIDYEoH/4d6cZXocIfQ4W/RQjkB6nszNhsmFwIl6VDZywMjoTGCOVi1ZigKkKp1ARl4Qpeys0qf2QDmJwwfio0Q0UMr4zJ4fSUEp6YW8ETcyvYfGXFLwKYizk0/bk0F3Nq+oUZF4C5ZIjpz6GxnaGwgYwLwNiyM30BTF/N2XdOKLcDjE09QSZPyQVg1o0tZN3Ywn5Bpj+o6Q0xeb0gZu2IXG4ckWuHGGc5uzOXAjP2moJupaVO6g9meui/BZhLBZb+mpQv5rJcckblZ4KLM6j09bgv2VwYmxOzdeEgHr26ng1zqnlwhtNNmLG5qtdiZBarujNY2aWKreY1xjCr1srMmkgmlZoZX2RkXLGZUXmhtKcH0ZYSQEtqEIOT/KmP96Pc4kZBqJAXIuTolCOTEaTgJdm/txJ8hWgvId5XiA9QSghUH60+QrSfEOkrmDwFq7cQ4y9E+QvRAUJMsBuxOncS9G4k6N1I0g8gST+ARJ0QFygk6QeQHuZJutmT7EgfciwB5FgCyNNUZVYaahUuSxAe7hbevS2Tfz8az3cbovnp8XB+fNQEG4PgKbO6Q/GMGV4wwGvhcDIITgXDCX84GaAyHxuFczOEvU3C4WrhaJ3wQqPwh1lBsKMAzo6EF2KU8/KEwC5v2B0Mu4JgVzDs1qnyuj3BqsBxf4A6IveCQW0jvRWtoOTtSDgfCe9a4f1YTfFwPhbOJan15zPhcNqkjn6dCIcXkuBABOysgMdz+PuSUF5qE54ZJBxtFF4bLvzxGuHvNwifLhYeqxSujxZuSVR5lb31wqsjQ/h8sfDdumB4YABsskFWuHJcTkeq1dY3YhTAnDTD6wYFMK+Fw/EIOG2EZzz45qZgnukUVoYLSwzCjRXR7Jveyu7FLexZ0sruZc3sW9HKnkWNbLmygruGpbK4TMeUeFXeOEynAKZTGx+1+AjN3sIgX22E5CNUewmV3kpVno5RUpdJGG9V69WTowYwxqRarVt8hEZvocFLqd5TuTmDvFROZEGiJ7+bU822PHcOm4VnrMJHVj8+jQ/mu6RAvk8zQHqQUprmJNicmDS9UmqIUorT49QQ7XMaxKTplZuTaYDsUMgPV5tOxVYoj1JuR20s1MVBQwI0JkJdPNTEQlWkyszk6SHDXzk+qb7q+8b78UOY8C+DgFGUG1Nuhcpo9Yu/0ACFOigIhgI/KA6ESn+o1XItZd5Q6gs1OqiJhHIj5Oi0f4a/ckwKw1Rup8IK1TEqp9OQqFQbD7UpUJUE5THa9lYE5BrVf6M4L5UfihS+Dxd+jBQVYB4cC51p0JECDVFQbYbKCKiyQJUVKjR4qoiCMqtSeaRymYo1ByYvTKk4HMqtPQBm89XlbL2qkq1XVbL56lo2u1xr76n6i5Tf/rxx08+HGTVicq43sHU1OT+2AYwDaFxGTa49Ti6B37unKt0zpYJ7plRw76Ry7p3kaNZ2HMTrDTB3Tijvvy3bpbrAdcTUO/TbWxceJ/Vetba1YDtvKV0MYPpzYlzBZbmTljo7M31kZBZ3ZfRaw+77WF7fYHNNW8rFAcYVWHrCS/9rzP8NuFwqwOxe3tbrubP6c2VUE7MqKXxi4WAem9fAhjm1PHSF6jq6e7L6w3b7uAL7evXqETks61R76/MGJzC7IZ4ZNTHMqItnSmU0owpMdGXqaE0LpjUtmOZUHZVWDwpChcIwBTF5IWp0lKVX7kpasFJqkMOFSQwQkgIVuCQGOQAmylfJ4iNEeAsWLwUxEV7qNWuAYNY+F6m9N9pPKcZffYwLFGKDhKgAISFoAEl6N1L17qTo3MgLHEDSAGFShrBhRjq/31DB93s6+d2twXy3IRp2JsAWKzyuVxCzeSDsCoBnA9Vp/VPBcMYAZ3RKb8bA8zq+uiGQY93CkRrhhSbh+BDh40nu8EgSnBkBb+fD/lDYogHMwTDYZ1An0/foFbw4A8xBHwUxzwfB60a1QfROlIKXd63qlPo72uXet6PgzQS1Tv26Xul0JLxsgB0GfrxP+Pgq4XCLsC1fOFQrnB0t/G2xH9wWDPca4SkrHMuBR8p5qkm4PkpYXyg83ezJibHhDoB5yA0e81NO0XNGhwPTH8C8YoTXzQpgXtPBr+J4Y4pwS4LaerkmI5it42o4uKKTfcva2bu8hb3LW9i3pIk9ixp5bEoJNwyOYmaaJ2MjlQNjGyG5AswgX6HGWwFMhaYqT6WmQOXCjI1Uh+6mxroxyaq2mDoChWZ/oSVAqTVQaAsQhgQK7SIsTvXls1kVdoB5Nkr4INKXT+KCHABjc2AuBDBpob1lc2TszozeoawQyDEq5RuVI1PipHILVFo1WaAiAopCIVcH2cHKAcoIcfwM6QYojFQqsSj3pCRMZW7ygpQK/NR4qF4P1UFQ5Q91wdBkUqqOgAoT5IVAeoDK/aQHQGagGn3la7BQalGqsCpVJkB5nGPtvMAMeSbIM0JOqPq6/DAo00ZczfHQFKPlaSIUvNRo8FITpUCuOqpvgCkJV8cDC03qv1sfALP56vL/CmD606WMmX4J0LgCjHNH04VdmSoXVdgBxrmzyRlg7rm8nPumVtoB5r7JFfbP/68Apv+szIWBpteBPDvM5PVzM0Zbtf4vAWbFsBxWDMthmaYVTrpUgHFew75UoLFBjPQNJf2rdyPxpYNLfzmV/sY9/TkqzoCye3kbe1YMYc+KIT0e25471MKuZc3sWtbMjqVNdqDZvqSFbdc08di8Oh65Uh1ue+iKCvsM1NaLdNPofFYPy2RlVzrLhqSwYHACVzfEclVDPDNrophQHMaonCCGZQXSleFPW0oADTHu1EQNpMIilLh5MZwAACAASURBVJiFIqNQbFIf80IVzOSGqJFRhgY16QYFMFHealSUrFMQE+cvxPgqJybCUwh3Vx8tPoLVTwGMxV9BjNlHiA4agDVAvR6rc8die0+AEOqpuTj+bkS7Ccl+QvoAoSxY2Dha+PjBeL7aZOTvj4Xxn81NsLOTfzzSxBfr6/hhax48VQBbdbBND08GqHP+zwWqtts3Q+CtUHg3At6PhO1W3rlaONYivDBEeKNLeGeU8PUyH9hTAZ+UwZvpcMAHdgyAPf7wtAH26VwUoLTfDw4FwOEAeCZYwcjrJjgTrdaeP8iBd7PgTCa8ngSvpCq9mg0vpsP2DHjQzGdzfTg1Rni+S3hxmPDWDOG312p9SXv18JJRdR0dD4OzkfB+MewK5OBI4d5i4UCLcHpKAB/PF769xUddAn7CT/2MzxrhNaMCmNNxSraix5OhCqReNioX5nQIvB4EW8P5zUJhfbawJEhYEOPFpo4C9l/bwcFlXfY/23uXt7B/ZRs7rm7knlGZzM8LZFKs6kQabhC6goTOQKHNT2j1dYyQGryEOg+h2l2pxlONlFoC1V2YCWZ1ufeK6AFMt6pyyMv0Qpub0DpQmBAkTAsTZhuFWWHCNE/hrhzh02lZ7MgTDkUIz8YI71t9+Tg2kK8TA/hnmt7JgdFDeogDQtI1pYWo9er+lBniUJr2NRnaqClT77j0m2NQH3NDlcNQaFK/rMvCoDJcqdrsJItyTWoi1ail0gLFYZCvHdvLN6rvlWvQFAT5esjXQXGI+r5VETAoERrioTpeuUHFZig0qhs2BToo8FUqclcq8YBSTyjxgzJ/KA1WKjYolYYpJ6fC5PiZ66NgcDy0p0BrCtRFK8elMgJq4pSqYxyPK6MdKonUtrWcHBgbwOQboSQCKqN4eVwupy4vZcv8SrbMr/xZAOOq/1uYqe4FMK4Q4+rOXGjE1GvcpDk0905Tum9qJfdNreR+TT1XsIudRko2oLFVFvTMyNhhxum6rzPAXAxk+oOa3hDTVy7GEfZ1LYu8fqTS6hE5PeQc8nUO+jqAJauXHDUFmfaKAmeocd1gctalgMz/CcBcKrT0NyLqD15cYeXiENNih5jdy1vsn9+1bAjbl7Sw5ZomrQyxwT5WWj+r0l7/vm5soZbmzmFlVzrXtKgNpfnNycxtSmRGTRSTy8IZV2xidEEIQ7P0tKcH0ZmtZ1CCN/XxPtTFeVMT602l1YNSiwclEW4UmQeSF6oyLzlhQlaYgpgUvZBqENJChPRQ9TjO3+GqRGkwExskxOuE+BD3HorTe9gVq3MnJtiNqEAFMCZfB+jEeQox7kKyCPOaDLx1azi/3ZjGb+/35U/rg/j9HXnsGCEsThSmhwn7xgvfPpoOO8P48YlA2BeqdMBD/dI+FwbvRcB5M7xngZcL+fd9XpybILw6VHh7hPDuaOHz2QL3RMP7+fD7GngrEQ75wXYv2B+ksiT7DQ4dCFLa56N00Bee9ocjvvCMHxz1hyN+8LxJXdA9EAp7dLDZTzUiH4yGh9w5N1WDlk7h1eHCezOFL1cFw8NG2J8Jp9LhTJZybt5OViHh10LgbDZ8UAKbczk4UthSIbw+3ofPFgvf3Oytbsts9oW9/nAkRI3QTkfCmXgFMGciHQBzXBu7vW5WAHNCB/sT+PZWYV+TO6tNwiyTcFdlPHsXt/H08qHsXdnO3pXtHLhuCAeuG8KhpZ08Nq2c6+usXJHqzlizIwfTHaxGQEP8hWZfYbA2Cqr3FGo11XkLDX7qJky3UZhoESZb1YXfaZGqLHJcmDDcTx0ivNIqLM/w4tZCpVXRwqPV/nw8OZUnc4SD5p4A848Ef75L1Sl4ydAcl1Sn7aRLBRhXJ8bVybFnaIIgM7insvUqM1JiUEBQbYbaSKi3qoCrTdUWBTCVFqiOhpoYqIpVzkWOXn3/7AAVPM7whQK9ApgKE9TFKmekKk4FjAvCIFsHuQEKYkoDocoA1f5Q4QtlXgpgin0VxJQEaRCjfb+aSKiz9lR9lPq566wKXmqjlONSHanApS9VRisH5hcAzBNzK3jy6iqevLqKJ+bW8YTLNfaLAczFoObnjJf6AhobvKjHaoOpr6LJC0HNxVyaSwUY28ip9z0ZG8yU2wGmlzszsbhnkeSE/H5yMhcHmv5dmb5yMQ6AcVQUqKyMDWAuFWIuBDB9gczFRkyXCjQ2iLkEgGnpoacWt2pSAOOAlUE9tGNpk6b/Dlpcx0Ku8NIfyPT1+f6+l70YbqEjzGy7F7NhlmpcvW9qub2e/VY7zDj265d2pLJgcBxzm2KZ02BlWlUkUyrMTKuKYlSOjhE5BkbkGBierac7M4j29CCGpAbSkhZMU0oAg5IDaUwMsN+LcaxX+1Kb4EdljBeF4UK+USgwCdmhQq5RyNE2lbJMSimhQpLm3CTrhIRgpbggITbQMU6y+CgXpshXyBooDI8Unl4RzZ8eGMBf13vw90dj+f0DJq7OcKdOhEIRckVoNgi7FpXxzf5u/rB1EH94tBQOd8GRNNgXr47BfZAAH5jhPROcy4JDBn6/VHhtnHD+MuGjCcJvJgrfLPSFY8nwmyb4tBzezIDDRtgTpADkQCjs18NBAxzUKbDZ46u0O0htJ+3Ww5P+8GgQPOjFf2705F9r3eG2ULgpmG+WR/LFNWG8Nlx4LEfYWaNGRq9NED6cL3z/sKjvc0wPx63wZhq8m6N6lk4nwxkznAiF17zgTT28lcSPm4UjI4Q9Q1R/0tfr3NT9msd9YKcPHNKrmy8nzPBmvDZGsjkwRrVJ9apJAcypMJXNORYBG4Q3p/vwYLYwN1S4KT2YnXNbOLpiJPuu61ZaNYR9q4ZwcFkHO+YP4vbuNK4pM9izMN0GoUsndAWrEVBbgNDiLzT7KTV5K6Bp81Of7zaoi72TI9Rl38s1TY8QLjcLU0KEqWHCmkzh4UGeHB3tw7NjfNlZL7ww0ptPJ1jYkSYcDheeixI+iPTmN7H+TgCjKSVYAUxa0CUCjCu4aOMeO8CEaNLe7zqCygiDLKMCkFwD5IdAsVH9Ei81q5FMmRkqwpWqjSr8Wh8LdTHqF32OQX19VrAaBWX4q/sp+UYoiVLjn7pElcEpi1UjqOxwSNZBoq/698wLUnBSbdCkg6pgqNJBtV7BTZUBKo1QHQ61FiWbO2R3iTRgqYlSqrSqTimbql3UlwNTEq5GRoUm5VIVGPmxNAKqo3l5fB4nLy9l27xKts2rZMfcanbMrWbLvHq2OG2p9q6XaehTvxRmfr4jU9MLYGyyFU/a4KVvqKnWVNlnfsYZYO6bXsUD02q4//IqO8A4Z2cuBDD2NmwNXBxA41jFvnNiob241zn0238AuPc2k1rJdsjhxriGfLXySBeAWaPJGWQuCDPDclk1LJeVw7N7qW+IsQGM9lxby3Z1aFwBZpkmV4j5nwOMA1x6A8zF3JX+RkT9wcsvle1vs85Qo3Ixjv8OWxY02P8Hffzqeh6eVcf6mbU8MqeJB6bVcNuEYm6bUMztE0u5dXwR14/MZcXQTK4bkcPy7kx7++bCIZnMqIlhWk2cvSdpcoWV8WVWxhRbGF0ezagSK0PzzHTkmGjNMtKaZaQhOZj2HDNdBRF05ptpyQyhPimA6lhvyqM8KI70oMTqSWmML2WxasuoMMqbbIsnGSY3sjRlhruTZfYgw+RGkl6IDVBAExukRk+l/kKVXljbJpy8O4+/bfDiX1uC+XpzAk/PEAa7C0UijEv2Y2F1HBWewmVxwvZZ/hy8xsiaKmHvbA9+3BPLj3ti4dBAlT/5OBLOG+HdXDibBveH8uY04f2xwscThQ/GCL+eIHz3kDu8mAbHE+BMGpzJgGctKsy7PwQOhcDeIDWaORCs4GWnN+wMUODxVCBsGAD3usEdwn9u9ITbA/jP2gA+nCocrBY2pgoPJQtPlij35bP5ngo6tljhxRg1ajoZBaei4XicgphzGfBGCrxhUjrpryDmuBXOJvDDg2aeHyucmCJ8cYN2gG+jF2z3VD/n8zq1YfRGjAIYmwNz2qwg5hWjgpjTml6IhCfc+HCegU3lwrww4YbUALbOauTwshHsu66b/auGsX91O/tWDeHpFZ08t3YkG6eUsWZwDHNzA5gYrTaSug0KYDqDVF7FWW0BSkN1KucyyqhWsSeGq3brSSaly83CzChhRrgwxyrcWig8NSyEs1dZefeaBN6abuKjubF8OsHC1kQFMMesFwCYVJ0DYC5phPQLASY9TCnLqJSt0xwRHeQZoCCkp4oMUBKq8i3lepWXyQuGFD9NWpYlw1+DmGAFNgURUB4LtQlQHQcl0ZAfAVkmVZsQ6wlJfpDpo4LAlXqoCYFaA9SFQn0YNBihzqTWtqvDVZbFpuoIF4jRwKU2um+AqbI64KXKeoERUrgdXigyq9drYnllQj6nZ5Tz5Pwqnpxfxc55NeycV8PW+Q1sne/4S11vNfYLMf0BzcXGSs4gczF3xlY+6dqS7QwwF3ZlLgwwtqBvXwDz4OVVve7IOAOMelyhqXcPkw1gnNuwbQDTH8j078zk9pLtvowzwLi2YDsqCgq48bICO8BcMsRcAGD6hhkXx0a7L/NLAGZJR/p/M0JyHRn9MoDZvay5h2xhRYfaemjfiiF27V/Zzr4Vrexf2dZLe69T2u2kXStb7a/b3rdvVQf7V3eyb1UHe1e228HJnsfRMjJbFwxmy/xBbJ7XyGNX1bFhlrrm+9AVNWoFW/uDtHZkNuvGFnLT2AJWDc/UGqxTuaY9jaubE5hRE8XshljmNMYzoyaKOY2xzKiNZEJxGJdXWpheHc306mgmFJuZXh3L5Ko4JlfFMboonGl18YyvjGZkUTjD840MzzcyqjyaoYVmOgoi6CiIoDXHxKD0EOqTg6lPDqYuVUd9moHapCCqEwIoj/OnPM6f0jh/iqJ9GBojjMsQDk4X/v5oAd8/HAA7rPBMM0dnCkXeqhsnIzSQYRUFZJoC8RD1Wrbeg2QR8jyEpy734W9PtqkMy4uR8OsE+DBGbQN9nAR7TXywRDg/UfjocuHjseoc/19mCdwYBrf4wR1BsDcFXiqFg/GwKxL2R8DOUFWguCcYdupgexBsN8NOC2xI4cebQvhyiZm/LTLym+khnBnhzrFBwoFKYXeF8HSDcGK08OFs4ft73OFQEhxPhDPp8E4GnE1WV3vfsMApE5yxqA2mt6PgLTOcDoVTRjgZBq9HKFflVApf3ye8OUv45FrtAvAGN9jmDvuC4FgQvGrU7sFEqkZsGwydDoMTYfCqQQV7T0eqo3cHAvjDdR7sGiwstwprEoR7h2Vx6JpOO8DsXTWEvauGcHBFJ8duGMXexW3cPy6XZVVGpqcOZJRJGKp3VAi0B6u7LkM1derV8xEGYYxJGB2uNMakNMkkTAgTppiEWdHCbLMwP0a4p1w4MC6QD1cIf7k9mH/fo+O3K4RTLV7szRaORAjPRgrvRwq/ifPky3gvvk3xU8CRqcGG8wjJNubJCFF3WDJsMjgyLhna5pGrMvR9vKbJlpfJClEbS5khkBUK2QaVackJ0RSsQY1OA5lQpcIQyA1Wh94ydU7wpFPglKVXq9zFFiiNUgHckhgotKo7M5khkOAPVje1RZTqo9yf8lDtmFyIUo0RasMVqNRZHYBSE9NTlZpsB/tqohWk2N5vf93mzEQqVUQrlUdDWZTK55RZoTRCBZ2LLFBk4ZuaWP7dkMTBKYU8N7uSrfPr2Dq/ju3zGtg+r/8Dphc7gNpfGbBrhuaxq2p6qL917Y1zKvvWRfMy1b3kfCDvoSsqNF0s/Nsz9GtzZmwVBhfuWyrrlZFx5GRsvUs2iOkjJ+Ok/gCmvxHTxYK+tvJIG8DYZHNk+lvDtod97UCT1UOOA3mZjroCZ/VzKM92V8ZVy5wgxlnSf7ZFc1hsF29d1Suk2xe8NF3caekHYPataGXfitYLwosrwNjyAQeuG2K32ve6yglg1Ps6esjVmdm1bAg7lray49oh7FrawZOLWti6YDBbF7SwdUELG68axPqZtTw0q5b1s+u4f0Yt62c38NCcRu69opbbplRy25RKbp5UyfVjilk5qpDVo0tYOaqQpd25rByVz9LubK5pz2BxVxaLOrJZ0JbB7PpEFrRmMb8jjytbMplen8D8jhzmtGUxrTGZCVWxTK6JZ0ZrNhPrkxlTk8TY2mRGVyczrDSW9nwLXYVWOouj6CqJoavQypC8CJpzzLTkWhicZ6Eh08joFGFWmQ+vLQ7gbxvz+ekxPeyOhoP1HJ4h1BqERO0aa5yfG1ZvdY1Vr11mzR4oNJo8uLZIeP/eYgUwR8PU8bjPktXxuI8S4Y182ODOb64Q3pssfDpR+OAy4b2RwmeThD/MFj6fIXyzSmBfKrxeCIeTFMAcjYXDJgUwu/QKYp40wQZ//rk6iE9mCW+NUaf8n2lQN2f2lQvPNgqvDxPeu1z47gY/eDITXsiFU+Xwdg6cz4P3shXEvBkNZ6xwOhxOGOFMBLwTozaa3jIrl+SUEY5b4NVwBUAvx/DvexTA/HOdE8DstW1nhSmAOWVxwIszwBwPdQDM8Wh4Lgw2xPLOVcJ9hcKKaGFdSyJ757axf9UwDq4ewf41nexb3c6hlV08u3Ykh1d2s/XKem7vTGFegXJhRpmE7lChy+DQME3dIUrD9cLIEOXAjDKqEPAIgzBWL4zWCeMNwoxIBTALYlWH1c4RXrx7rfCP+4zwiIXfLBGOFAtPxAvPWIRjUcIH1oGXBjDpgQ6AyQhxclRs7oxLViZDe80WAu4PYOwgY1AQYwOabIMCFzvEOAFMng4KDEq25zkhClZsgJUdqrae8oxQYFKr3AVmzXUJUyMrW+g43QDJ/kppvmp0VRGmZBsZ1RiVqsw9HZaLAYzNZbG9vzruwgBTEaMAxr6NZOkBMF9Xx/DP+kQ7wGxb0MDW+XXsmD+IHfN7bqT2BS6XAjT9wYwz0DgDzMY5lX3Cy4ZZFWyYVdELYC48aqqxj5n6kivA9AUyypWp7gUwD0y/9A6m/jMytsqCnltMfYV+77xER+Zi+ZgeIV9bdYELwFwqyPQHMH2BTA+g6bd3KbtPiLkgwPQHLz8HYC412+I6Dtq7vKVPcOlPfbktfQGMK8j0pwPXDeHgqnYOrlIBSRvA2CBm5wql3cvb2bOig93L2xXQLG3V6gla2XZNM9sWtrJtYSubFwxi84JBbJrfqPWKNPDo1Y38ak49D82qteveK6q5c2qZ/ePdUyq45/JKbp1Yzk1ji1gzKo/bJlVw0/gy1o4pZvWoAm6fWsOasWWsuqyIlaMKWXVZEasuK2DVZQUsG1nA0hH5zG3P5IpBicxsSmL24GSubEnl6iEZzB6czJSaaCbXxDKlNo4JNTEMLzJyeaqwrMaL99YG88X6BH56xB+2hPDtxlIOTxba433IGCj4iTBQBDcRPEQwePgS6uVPsAhXdHZxfsNU7h4Tx9cbQuG5QnhJB+8nwUfpcC4OPsiHEwn8+zbhrenCJxOFTycJn4wWPh4p/H6C8MfJyplhdSjsr4ADlfArE2xNgKP58HQOPF0OO7LhvjT+tDiQ46M8OdwkHKgXdlcKRxqEV9qVjg8VPp0ncE+QKoV8OQ7eSVHN1h+kwbsp8EEKvJ8M56PUZd7TBnW995ReHcGztVm/ZVI9SqfDVG/SK6HwRhQ8G8Z39wtf3aI1aG8doMZcR/zgRQOcNMEpc2+AOW5QOhUGb4TDSYsCnv0WeGggJ6cJj5QJtw4W9s5J4PDqNp67qYtDa5SOrBnBsZvHcHj1MHYvbuFXEwtZXmtieronY2OE4WZhqK2NOtQBLs4AM1wvDAvVFKJGTyP1wrBgYXywcLlRuMosLIobyLoc4fHBwslZwl9uCYP1Jn67TF1Wvtsi7DILT8cJ5+KE80nCnxK9+FuaHz+m69Uv9VS9Ju0mjG0UlBbSU64AYx8dad/D/j5tdOQKLr1AxgliskLtF2iVKxOmZHvuLBsYZYeouyz5RigMVyvWZVblvpRGQVFkT5VGq5suZVHK/Si1KoiwbwZpox/X0K1tg8i+VaRd8a2O6ykb2NRGaWHeOAU49uxLjOa2xCnZAMbmwJSYVSN4UQQUW/iqOo7vGpJ5emoJz8+p4alrGpUWNvHUwp7uvOtl9otVzVwK0DgDjCvIXAhmbEDT34ipv/Cv43G5pp7bTK71BQ6gqbbLGWQcFQa9r/32N17qCTG23qW+D+K5gkz/+Zh8x1E8J10cZFwu+vbRgG3Lydhk21zqqd4jpv7CvyoAnKNJwYttPftCTdg9sjJD07m2M+2/B5hfCi7Oa6HOuhSA6QtUnOUMJPtXt/eQM7zsX91uf69NvZyY69rZfV07e1d22rVnRYcdZnYv72THtUPYcW0HO67t4Klr2+zauqiFrYva2HJNK48vaOmhDXObeGhOvf3jw1c2seGqwdw/s4E7plSybkIpD84exN0zGrh1chXrJlXy0FWt3DljEDdPquaGCRWsHVfObdNquWliOWsnVLB6XBnXjihkfkcW8zuyWNCZzdKRRSwbVczCrhzmNKcwpy2DK4dkMaM5lYm1sSypdOeObjN/uDeKv/0qkX/cI/BYIDxZz4kFQXQm+pExUAgeIASI4OvmxgARdAO9iQjQEyJCocXKumEWZuULH90ocKxA9RCdiYTP8+DdZJUp+agIns3kHzcIn09RAPP5OOGzscJvxyuIOT9c+GSC8P1Kb7g/mi+vFT6fI3yxTPh2rcCdIXy71pePZg3g5W5hT7WwrVjYXibsrxOebxFODffiw6ke/GmegR9u84EtMWqr6VmLyrmcS1Lw4gww78aog3inDQpeTuoUsLxjVhBzLhzOhCn4OBsOr4erjMupBDgaAr8S/nOPwEaB3T4KYF7QqzVsV4B5wwQnQhTAnAxVAHPaqkK/xxJhv4UfH0zg/FzhoeH+bJ8exaHrmjl2YyeHb+zm0Joujt4wkmM3j+HI9cM5uKKTJ6+s5/buFK4uCGJSojDKInSbhBEmYVhYT3jpMmjwolPjpE69GjsN1eBlhE6YoBemhQtXW4QlCe7cki2srxFenCR8tjoQ7g/l7zd6crJbOV6H44U9FuE1k3A2RvhjgidfpPryfUqQgpj0EAfA2CAmw9BH9sWWc3G9F+MCO78UYJzVF8DY3tcDXsKV62IDmMoYVV1QmwQ1yVCfCg1pMDgLWrKhNQeaM6ExFeqTVZVAXYJSbax2q+VnAkxNvKY+AKYqzgEw9tFRvKZoNe4qNqufv8ikVGyBYgtfVsXyz8YUjkwv58Wr6i8IMDaIsYFMX3fD/luYcR0puY6VXIHGGWAutNHUG2gqegGMM8S4rmfb4OWhK2p6gIwzwFyousAVZuxA41pZ4JKTcWRllFwzMg6gyberJ8RcxJFxuebr2r3UF8zYoKUnzFw4L9Nf+Nf+3HZf5iIt2L0AxlZy2B+o9HejpS+A+SWbRGpM1BNgnF0V1+eXAi7OcgUYVx28vlOpF8jYQKfDnpOxyTU3s9c+znKMuBwh5Hb7qraCQhWC3rakma2LB7N18WC2XNPElvmD2DJ/EI9e3ciGObVsvKqBTfOa2HiVOrL36NVNbJrXzCNXNvLQFTWsn1nLw7PqeHhWA+tn1qux1cx67rq8mnUTSrllfAnrJpRy59Qq7p5Ww22TKrh5XDE3jivlxnGlXD+mmOXDc7lzWDiPT0vj49tC+ewuM//a4MV/HvPju8eqeWqkUBvhTqqboPcQLEFexERFoA/2x9/NDb+BA9Bpo6QkEcq9hDMLB8K+Kjig9SL9pkrpXBa8lw+/LoaXIuF24bO5wqdThE8mC5+OEz4fL/xmtPDry4SPxgp/nunO72cN5M2RwosdwpEmYVO+sK1E2FYpbK0QNlUMZFPFQLZUCfuaPXhpmHB2kjd/WDSQ728OgfWe8IRO3Y85qldH5N4IV/mW9+LggyR4P1Fldd6NUVtHJzWH5DUdnA3TXJgwOBcCb4bCW2FqxPSaAU5EqjLJoyGqBXuDwPaBCmCe08HxEPXPO2tWOhOuXQUOg1OhDoA5FaX0qgVeNMKRUHhiAM8vdmP/HOHoqlJeuKmGg6s6ObJ2GE+vHcHhG0ZyZM0Ijt4wkkNLO3l8egVrBscxM8uHsTHCsHDlwAwLc4ySOvXqoy0TM0STLSszTKfgZlyIMDVCmGMRFiZ4cEue8EC1O8cmunF+UQRf3RbHX2+28vEcf85P8+D9cR6cHSacbhKeLRGOZgqHUoTn4oRXU4VfZwi/zRW+yRO+zRd+yvGEPB9VD5AdpI7LZQY5si/29ehApTQ9pAT1Bpn/BmD6dF5cACYntG+AqdXqC2zw4gwwLdkwOAMaUxTA1CdDfZLaWKpNULIBiQ1U+gOYulil2mhNGgDZgSZJqTJFqTZbqSYNyhIhL1JVKGTo1PisMFzBTHEEFITzVXUM3zencnRGGS9eVcv2RYM0DWZ7PznIvoDm58CMM9D0l49xBZj+czIXry648CZThQYzfZdMOrIyNT3kGv7t72Berw6mXjBjqy2wQU1Zn4Ffm+6YVMIdfYJMoV09YeYi46Vf0LHk/Nh2GK9vV0ap77FST5CxHcu7WJGkM8AsHZquAKYnsLS6qH+A+aWuS4+NIBfX5UIjIleAsbks/cGLK8DYYaUPHdJ0cFU7h67vdPqaoRy8fiiH1nT3ku1z+1d3cuC6jh6yw851Xexd2am5Ne3sWtrB7uWd7Fzezs7l7exYNoQdy4awfUkbTy5q4YmFDm25ppUt17Rqz9vYuqidJxa2sWleM5vnq9c2z1d6fIHShrmtPDCrkQdnD+LB2YNYf2Uzj8xr41dXtfDArEbum9XE/bMHc+eMBtZNqea+y6xsmp7Or28P4/N7ImB7KOwO5/gCAwtihExvIXmgYPAUIgI9ycpIISUpnmAvLwLc3YkJ8iHUXYgUIUuEZ6YIP23OgX0D4WkveCsPftcAH5fAW5nwPOpSuwAAIABJREFUfh58UgovZ8JD7vztauGjccLHoxS82ADm/dFKH04SPpkmfHalG29PFHZWCevThF/lqKNvD+UKj5UKOxuFI53+nBgzkA/nhPD3lb78cKsRfuWtAGavNxwOghcD1DXcN7Wg7gdJSh8mwkdJ6qrvGbNySF7XnJizYQpg3gmDd0xwzqi+/pQRXotQrs6pRAUxW7Um7ANe8KxW3PhGuLoYfM4Cb0Yo2SDmeIiCGBvAvB4JL4XD8xFwSM+vH4jhpWWedoA5esNwnrlxBEduHMXRmy7jmRtHcWTNCJ69bgS7FzTzwJgCFlcYmZzkwcgIBTDO8GIL9nYGKYBp1yt16pU7M1LThDBhSrgCmAVx7qzJFG4rEnZ2Ci9O9eLT5QY+XxnK+WkenJ/mwRdzw/nhumS4OQ9WpcG8SL6druOrYZ58Pkj4a6nwlxIFMN/kCeT7quu2udqGkG1bKNvQE2BsEGOrFnB1Yf6XAOP8nkyDgpecUHUZt8CktnbKrMoRsXUv1af21KB0pYZk1YFkV2JPcLErsX+AqU10AExdjFJfAFObDDUZUJsJNVlQFA8pIfwY7ccPkZ4Q7aM6pXJDNXgxQ0E4FITzj5pYvm9O5Zkrynnp6jp2LG7qE2D6W/Do60L7zwGaTXPrejgyriOliwHNpfYv9Q8yFZpc78z0zMqsn1nbC2KU+r4xc0mFktPK+gUYZ/UFMM66EMD0XyJ5aZ1Ll1oa2f9oqTfAKIhxcWK6s7R27Ox+sjEaxLgcx/vZAPNz1qAvCi9aCLc/gLHBifPz/kDFpkNOMHLoAsBiBxctU+AKMDY9vXZon7J/nSbH9+sJNwevH2bXvuu6HHIJDztGV2pMZQMfx/Nu9qzosmv38s5e2rW0g62L2hT8zB/MlvmD2bqojaeWtNtft4HPI3MbWT+7hvsn53LfpBzO3RrO7zemwfYweCaRo5PcmOwnxGlNxEYPJUuonpgIE9awIAI9BaMW6G3wFa4bZOC3NwXx4+PJsNNX3W15IRY+qoA/1MK7efBOHHycBp/kwJuxsNXMJ0uFtycKZ8cIb10mnBstnBktnL5MeGWU8MYk4bPlwj/v9uNPNxjZ1SbcUSA8WCXcXh3EXbU6NnWGsW14BIdHDeT4DAN/WOrFP240wL0+sNGgCiL3h8HRQHjeoI7TnTar7Mv7cfBhMnyUAh/Eq9fOhCuIOaWH48FwNgTOhzvGSW+a1SjplEWNk07GquLGo8Gw0x12Cxz1hZeD1B2Zs2YFLmctSm/EwkkrvGJSOp4IJ1PgZBy8FqU2mF4O5V87EnlvnSfPrMrmpZuKOHbLSJ5fN4pj60bz3K1jOHbzZQpqVg/n4LIONs2o5Ma2WGZn+zM6ShgZLnQalLvSoROGBKk1apvjYgOY7hAFOyPDVKh3fLg6bHdFpAdXxviyNEm4PsudByuFLa3unLoihF9fm8Drk4QXRgtnZwq/WxnKP++LhCcy4FABHC2FvanwhBXu0vGPZcIfpwmfThD+Pkr48zDhyybhi0bhu1rh2xrhhzI3/lM6EIo8lfK8IMcDsnw0BWmFkDpNthCvtsWUGea00RTax+dtwV8XoMm0SYMdW3g3Kwxyw5ULU2xx6l7SAMbmvtg0KB0aUhXA9ICYBNV95Aow/TkwNXHq/XYHxjZ6StDKITOhIQsai6Emj8/qC3mnKIV7CiJYHuXBKp1wi1n4TdgA/hoXqALUueHKgck3KoApNPNNTSw/Nqfx7OxKXp7fwM4lgzW19FB/Tv1Ti5svWDdzKQ7NxfIxFwaaC1/5vbgrU6HlaS589bevOzOXeizvwjBTokkDmn42mf7/ADD9qW+g6Rn+XTM8i9XDMnsdynMFmZ5H8TL/9wDzc+62qNHLpY2HLua09AUvrgDjCh3OOuykI2uHOp7f2G2HFtvjwzd293i9J9AogHl67TAOrenm8A0j7Tq0ZjiH1gzXgGZoDzmcHfWep9eO4Om1I5yej+LptaM4tGYkB1ePsMu2nXJw9Qj2rhzKzuVD2b60g+1L2tlxbQe7VnSza0U3O5f/P9rOOyzqO3vbR3rvvXcEBaSLWCh2wIqIiKhYYkxiujGWJPbe04tGoyb23kXBrrHF3tNM3/yy2Wzaruv9/vH5DjMMM4DZff94LmCGYkxyzc05z3mevmyc1If143uzYUIfVr9QyLtj8lj7fCeWjc7i4jw/fljVCtZ6wQYfNhYLj3sK8aJqBnQA42htgaO1BT4utvi62uEvgqcIL7S159KbI2B7Fg9WxekTdff4w9lE+DZfhdVdiVS6HgeftoJr3WBHDMzz5JtnhTvDhRtDhesjhDuPCp89L/wy0wbe84HD2XBhCN/P8uOdXGF5R2F+eycmJQhzMoV3u7mwva+wr8yKK6OFryfY8M/ZwoOlNvC+Bax3Umm/+12g2hmOuCoT7dVQBTC3msPtaAU0l4MVxJzTIOZjVzjvoQDmWrAeYM6Fan4YrXn6ZLCqOtgisNsGjrioKYsusO5cgKYIOBuuCh1PBiiAOdcCzkTB6Qg45Q9ngmFXEl+84UbVtGQOz8qget4AqucNoGpuGVVzyzgwq38twOx9pQ/rn+rEqwMSGdfWj6HRzRgQqEy8Pd20LBhXJR3A9HAXemvemH7e+mwYQ4B5IsyecVHCpObC/FThzXZC1UBrrj4bzImhwuFy4fQI4fYLTvwwx537b4fDuuawMw32JsPhNnA0H/a1hlWJsDgQxnrwxzDh38WW/NmnGRTZK3VxhTwHaOsIWfaQZgcpNnUBJklL903SepGSvBS46GQIM/WeN7paqu1a8qrbj9RCu0BK8tGuj/z0AKObwHSKqw8wneIfDmDytAlMXlR95UerlN/8CL3HpWNz7ecmQU48/0mO5NsgF7Z4WPGeCEOaCcUiPC7CbD/hqyBbforVggSTDRJ40/0hM5Bf8yJ5UJDAoSdzGwQYczYDXadcY1MZc0BjbAY2BpiGTrCb0sXU6ISmiddMpnJm/hcwYwww5i6ZdCCzeFibelpUmcWiYZm1MoSZxrNkMpk/OLMOtOigZt6gjDrwMqc8vQ686HoC/1cAM70k6eEBxhhYNk/qYaSHC59rKrgYR6M/LLCYm5g8LMDoAGSfCe2fWVwLK+ZkaiKzd1Yx+2b3Y9/sfuyfU1JH+2b3MzvV0cGR7mv3ze5X+/GBWf1rtX9mSa32zeinvV/M3ul99B6dV3qza4oekPTGZGU+3jC+iLUvdGfdxD5smVLK6dlxfL68Aw8+DOb3933YP1R4IUjIdxBybIQoKyHCQpVIBlgLTiJ0y4zkzbGDyPIVnkwRbr5XDJvTuL8qTqXj7vCFPRZwyB5uZsNXneF2a7iWBtcT4FYSfJqgdC4Sdthzf7nw65vCL+8If64Q2CFw2hPOeSj/yZdtoSaQV3sKgwOF3ABLEu2ERGuhf6Iby/v6sKYsmCOlwvUn3Plhsh3/mOXKgyUC7znCRkcVjrfPRemoi1rxXA9XLda3I5VuhsL1YDjvpYoqT7rBMWc45wOXA+FykIKYT0LhQgicDlT6OET1HO21h122cMhVFTuei1D5MReawydxcCYFTifDkWQ42AL2JcPuRNiTCHuT4EAmHG4HBwv57cN0js5sw6Gp6VTP68fBucVUzS1l/5wS9s4sYff0Yg5MLWb/lL7sfLGQFSOzmNU9gieSbBkQJPTxFnp6KlgpclMqdFUfF3oIPTzV5/TRLpL6+wmD/NXf7yPBwugwYWyUMD5WmJEozE+3YEWesKu/K0cGKYC5OFr4+iV7/njNShV+bvODfWFwNFSFFJ6LUzqVCPvDYJkr30/Rn89/P0z4ZqjwzSClb0st+LpE+L6X8E0P4afuwt86C//IFf7eXvittRIZttDaHlq5QJKzfhWV6KHU0l07vfYyIw+DsD03iHOB5s6akdgdkjQvTJqP6lZqH6amI7pW6fx4JR3A6FZJ+XFKeTrFqnVRnelLpIGJN6KuOkWpdu3ceMiJgy6ZUNSO33vl8V1eGtsz41ke6cvAYEe62AsBloKPdiFoLUKllTAl2pV/hDjzZ7SXSgdu5a+qDlI9a/NvfswP4beiWPY91Y6aFzrW2gQMJy/mwMVY5rLDGoKZtc8r6QLz1jyTX5v++6GJiUx9mGl6F5NJkNEAxnBiYwpm3jMIy3vPTHDew8CMDmDeHpWt9Eg73n6kHW+NzK6jN0a0qSPzHhlTPUxNyZXJrCdDgDFUY9MZcyDTFICZ2k8VS5q7WtJXF9SV1AeWhwOYpq6LjMFl2yvq4qep4NIQpOi012iSstcMrJjSXwUYY5DRAYcOWKrmlta+2BhCjPHXGwOP8dcdnFNG1exSqmaX1oEZvfqxf6bB5GdaCXunlbBnRr9aqdWWWmXpJjdbpw5g8+T+HJ8WzfcfdeO35V6wNYa/v57M/FShi7NqLI6yEsJF8BYh1F5lwQzsmsa9w2t5umcGA0OEy2/0qAswO/1gv7WCmFPx8EVH+Dof7mbDnWS4kQjXY+BOPNxJgZuJ6sX9bIzWHxSlfCM3IuB2GFzxh4st4U4mxye708dZiBYlb81IPDld+Kg8jJoS4egA4c6zwo9T7Pl1liiIWSmw2Un1KO11hmpH5Ym5HKQg5laE0o0QBTGXfBU8nfaAE65KZzzhUqCa3FwKh4thcDZUAcypQM3L4qd6mqqcVEfUxWh1wn0tSeXOnGql8m02BvLgHTt+mCbcfl74epLw95nCLwsd+M+bnvxjZSv+9m48p+fncGpeBw7OLVYQM2+A9t9HKXtnllA1vR+HZpRwcGoJm5/rwhsDkhnf1oshkc0o9lNw0ttLDzGFrtpbD6XeXuYB5tFQ4ZlQ4bkI4ZXmwvQEYWmasK7AipqBwpFBCmC+mmjLn69bw4e++vyewyFwIlLVMnzSAj7JhHOpqnrifXfuT7Hiuyf1APPdYOHbCuHHQTb8OMiGXwbY8ssAW+6X2HO/xB6K3aCfB/Tyhe7ukOsJ7VxUyWKKq6oNSPZQ4JFo0GDdVIDRQYwpgMkK+O8AJi/WxArJAGDyIvXqFKUVRSZAXgvITYbMWD6JD2KnizBOhNFavUeiCG7a/wM2IjhZC486ClNj3Pg52Kk+wKR5Q5onpHnyt7xgfiuKZf/THTg8rjObJxX+ZYBpCszUA5rnu9TRR891qgcwplZMeph5+OqCukDTNDPwsjF5dfRXYcYYZN55tC3vPNq2FmAaAxnz66XW9dRYrsyiwRm1ifKGaghmzK2adEBj7nqp/km2LvFX+7gkSTMDN9zBZJzu+z8HmKaAiymAeZi10MMATEPQUgc6zACMTjrQMHxMQUOfWu2b0Zv9M4upml3Cwbk6ldZR1eySOjowq1+tjB83/pyq2SVUzSmuI+PPM/zzmfpz66ZFOqjZNmcMW2c/wYGX2nBmYXd+fjeE+2viYHMLrr0gPBMu9BahnQhZIrR3FLLtFSyk2QpPZ6cwMjmWAgth7dBWsC6R+2tawHobFei2JxR2BcMBPxUe901P+KwrfJ6gdCdCm3b4w80guK3pZjBc84drHnDVHa65wQ1PZaL9LBKOZTM2W/lvgkT99mkvQhs74bm8GNaWe7GqvxsHBgsXx7rz41Rr/jnHCV5rBiudFcTs8tR7Yk77qtbpa2EKZG6GKoi5Ggif+MJZDzjtppqjT7rCBV+4FgLXIlR1wvlgdS59ykfpXLDKitnvCTucYFsC7EiCDXnwQRb356fyzbgQPhnixcFCYXsHYV2GsDVb2J0j7OlmyYFCG9YVO7Kn0p8DE/I5M7cPRxcN49ji4RxeNJTqBYM5NL+cqrll1MwqoWZWCUdnl3Fgcm8+HN2B+T2jGJPiyIBgVdjY10dNYnRTmCI3oburUKB5YXSrpBJfPcCMCFYaEyw8HyVMaS68HCPMbSGs6WxLTZk1RwfZcXm0cG+8C/9a6gSrQ9T0bX8IHAmCk+EqJPByBFxtqXShFRyOgNUe/GOu8PXTwqejhS9HqKu0u4OFOxXCZ+XK2P31QOHbQc34Zagtfz7izL9HuvKvES78OdiVn0ps+KnIjh8LbPgp357v2lvyS7YTv7Z1Vp4Pne8j2VtBSQs3iPNQau6l1MJTXTi1dNObiBPd9G3XqT6QFQTtI6FDNOTGQV485LU0rdwWdZUTp5QbCzkxqr06J0r1G+WFqoLJ/GDoHKGVTEZDbjg3c+M4mxbMzMRAnvG3IctN/b9nqeUyWYlgK2oi6txMXQR62QiPWgszItz4OdiFP6K8Ic4TWgUogEn3qa1S+DY/mH/2jGP3szkcHN+l9npy63gl4wm9Mbz8t0BTe65tBDCNVxh0rAMwOoh5WKDRm4IbXjnpgSavnlRYXkON2e15d3S7elLw0kZTXZAxBhidzGXKvDoi0yBTRheOl16vqsBQi4ak1ZvILBqcwcKK9FrNH5RWR/PKU+vI3ETG2CtTv0xSF46nPp5dmsys/q1Mpv3Wpv72MzD9avqvAOZh10WG4KLTw5pyzYGKsYdF52Mx9Kw0JOMXfh3A6OBBv8qpK2Og0MGEOYAxBzJNlpmfZw5idJMd3eP6aZEeYLbNGcPByW05NKUdP77hzz+XhcHaaNidyievJDMrU3g6RZjQ1pZR6c509hRSbZSSRGiplT0+10L4ZrEP//mwJWx2gB0usNIeVjmqeP3jkQpe7hXCpy3U5OWzKLgbCbeC4UYgXPNVuuqnAOa6p9I1N7juDtcClJn2qzI+ed2RFnbKg+MjgqsIYSLkugqL8oWPBnqyvUQ4WCl8MU74+wx7HiwUeNMKVlsqiNF5Yo64qRqBS4EKYnQrpKuBShd8NIhxVwBzxkOlDV+LUJdLF0JUFcFpXw1i/FTK7uEA7i8Xbo0Vzj8mHB0o7CoSNrQVliUKS8KFVyOFd+OED1oJa1OEdWnCh5nCR62Fl+OEuenChyMTOTatgGOLh3Ns8XBqFg6hesFgDs4byMF5A6mZVcLhOaWcnF/B8bnl7Bnfi+VDM3mlYwjDYpupYDsfBSmGEFPgrmTshRmoQUxlgCp5HBMsPBMhvBQtvBgmzIhRAHN4oA3HKuzrA8w277oAcy4ILobrAeaTZNX6XZ0Aqz34c5o13z4jfD1KuDdS+HyYFnZYoQDmywEKYn4aZMHPg635pcKWXyps+W2QM78NcuaP/u78X6Et33ew4rv2lvzWzpXf2rlCijf/SdRasRMNpy2emrwVwMR7KIhJcNe3XCe56wEmzVcBTLuIxgHGGF4MASYnRg8wHSIVvHSOgE6hqsQxJwjaB0BuOL/E2/ORq7BUhP6ifpGIFSFKBCdLwdXaQJaCu5XgZiG4WyqAmR3loQeYWA8FMBm+mtQU5ruOIfzaK57dz+ZwaGJXtr7co1GAaSx6ozGoaQhgjFdKxh4ZcwCz+tnO9XqZmgI0OjNwUzuaVozpWKu6IGPGO1PvPNsYZrJ5d3R2LcC8M6q9CtAzmsjoZD5XprU+U0aTYUCe8WpJDzT103518LJocEYdeFlYkV4PYAynMg9ziv0/Axjdea95mV4RGUJLY5BiKktFp6ZAS2PAYgwuhqqFlJkldWUGXIwnLHr11dQwwOjApXpe/yZJDzp1gUdBUKmJj01/vjkwql1JGUGO7p9/65yn2DrnKQ5MH8iZ1x7j66Xx/GN5Jqx1hgNhcDSHB8sCuDfXl9+XxXNpZjjvFwujIoXeTkKpo1DmIox2FJ5wES6McIIV3WBPe9iUzlfPOXCxUvhjsR0cSIWrWXCvC9xLhVst4E6U6k26G6p0xw9u+8IdX7jrB7f94aYv3PRWuu0HV9xVnszVVozNU71MniIEahDjJEIHP2FcnyhWDfJi+QA3Dg8Xboz34B8zrPnXAmd4ywo+0CYxu72gyk15V874wSchCmKuhqrV0rVQuBqs70X62FPz5fioc+pLIXAxWL1/NkB9jxP+ypx7Ngk2unFusLAyVXgvVundSOGtMOGNYOGdCOHdKGFFnPB+gvBBkvBeujXvZ9oyM0OYnia8URbLgZcLOTx/GDXzKjk4bzDVC4ZyaH4ZB+cN4MhcpZMLyjm9cBA10/qx8alcFvdryTOZLpSHaRMY7eqoFmA0Fblp10iaSr0UxAz2UxDzeIjwZLgwLlx4NkiYEiWs6mxP9UA7jg525OKjxgDjDvsD4KifMjafD4DLIXAjTOlatFofXk6AY8Gw0on/my5886TwxWPCt6OEr0eooMPPyoR75cLXFSrw8MsK4YshVtwbZsuXQ524XWbNhRIXzvS2Z3eRL9u7efJ+ni+vZjryeks33kr0YH1LT7am+PFxeiCfZIfxXUYIP2SG8ntqML+lBEGSpkQ/rRbAA1r5qoukZF9I9VcN1O3ClTpEaNdC0Ur5MXrpHsuN1ue05GjSrY46hUPHMOgeDN2CeNDZmz9yXPk8x4VvOnvx9y5hnIkUHrURSjQwjxHVIO9vK0RbC7E2QrSNEGGlfGn+WvFqOxthrYVwyM+FPwIdIEIr0kwNhNZ+kOED6d6Q7s2P+WH82SuB6mfyOTauG9smFrJ1Qne2TezBtokN/3Jr6ujjYYFGd66tkymAaTBTRsvP0kkHMsYyVzCpX0k17J8xXkE1drbd0EVTXZDJ1mQ4lamrWp/MqIYyZVrXqi7EmFormffINOSXMZzM6NSUhN+mAszsUn2ujHFlgQ5opvZPraOHBpim+FqaCi86gHnYtZCpayFT8NIUgNGBSGMAY7iyMV7pGAKFDkxq5peaVEMAox4bYHZqYwww6utLay9TTH6t5pUwflwHNtvmPsO2uc9wZG4lu17ux4VJXvzwZiv40JF/vSdqErMpHj5MhU1tYG9fqOrPveVdWTvchVdShediVfHgy2HCB5kCqwvh4gBY7Mu5CmFdG2X0ZFUgnG0Fn+fDD23gixQFMHei4E6IJgOAueOrAOa2v3rsti/c8YfrXirZ99s8ji/pQoaFApdAUWfdjiIEiNAtQlhaZMWKgR7s6i8cHSHcGyf8fZoFfy4UBTGrLWGLM+x1UhBz3FNByJVgPcBcCa4PMac91dvzAXAhUMHLxWB1In02QHlhjvvBuVZwIo4fJvqwLltYES+sShQ+iBdWxhkoXljVUliZKKxOFt7PtGVllgPT0/QAs/+lAo4uGsHRRSOoWVhJ9YKhVC8cSPXCgRyfr3RyQbnS3HL2TihixYh2TO0Swsg4e0oC9F6YIjehwEVbIRmslHQBdyUeqhupwkcYFig8FqQg5rlg4ZlAPcAcKrPlyCAHLo8Wvproyp9LHGFloOqt2uunB5hzfnApWA8w12NU1cTVJLjUAvZFw7s2/PayBd89owDmy2EarJQrgLlXrt7/fKBwp1yDmEpnPi235Xw/Z44XWLKmrQ1LmgsTgoUn3YVxLkqzHYRF7sJaT2FrUDPOBlhwPcqJe+EO/NDcnX819+ZBgj8kB0BqkAKWJB91jZTiDxmBCmDahtUFGLPg0gDA5EWrqUvHMOjoC21d+SnThu+ShWsZVnzV0YP/6xTMpXgLxvsKw0SItxJa2gjBjkKIkxBvLzS3VfASbimE2AtBdkKOvdDD15KdzlYcCfTQA0xLL0gLqgswGT78mB/GHz1bcvDpPI6M7czWCd3ZPqmI7ZN6sn1S3deCugnkPevUqphTYzCz0UAbDCYyuqmM8dWS8SXT2he61xbtqo46/fs6oGkIbvQm4YamNPkm4aap+TMNg0zdSoOGQOadR9s2kCmTVQdiakHGZP+SHmYeFmCMQWZeRVrtabYhwBiulkxfLpmewNRfMdXtX5pWmlarqf1TkW2TetOgGmiD3m4EMA8FLrrz4YeAF3OQYuhZqTKSoUdFJ/00pa/ZyYoOYHQTC3MTD1NTFXPw0hDI1P8eZdTML6sFE/37xp87oJ4Mv874cd1zB+YNompBBXsXPsLu+SPYN28E6yYWs/3xKM7PyuE/K/z44z1Pfn/Hkvvv28GH9rDGFnb6w+0c+KkSvijm/tvh7CpWzc9b2wjr44Qvh4Tyy3PJfFxgz85M4aMWwuoM4d7znnDAH66nw1c58GV7+KwF3GkOn4Yr3Q2C2wFwy0cBzC0/A4gxAJnzXnAvDs73YVqO4Kf9luqhGRqttWlM32hhct941g3y4MMyF04MF26MdeKHKRb8sdAV3rKDle6wxRV2eusnMef81Cn1pTC4HK5Se29EKZC5GKhC7M5on3c+QA8wFwPVddIZPzjpDUcjYJcX9150ZH2OsCZT2NlZ2N1F2JorrM9W66SN7YXNucKaPGF1rvBatvB6W2FaG2FhZzs+HJ3J8dklHF00mGOLh3B0STk1i8pqdWxhOccXDeL0kiGcWlTByYWDqZ7Zn83PFrCkJIFnM70pD9Mukjy0CyQXoaubkg5k+mgQ089V6O+mAGZ4kCp2HKUl8472FSZGCCu7ulA90I4jgxy48pjwzUseagKzIgC2esLeQDjsD8dDFNRdDFVpx1dD4VoUXI/WVzqcbwH7fOBNR75+Rbj3lHB3tFolfTpUeWI+HSLcHGrL9SE2XB7py60nQjjxeCK7yoKZ1zGIZ1pY0tdf6OostHNUSnMUUuyFdFshw05oby/kuQjFzsIQfyse8xGeC3NgQaQTS5u7synejeq2EXzZK4XPi1rxc5cW/NSpuVaYGKUKEztHqZVP5zClTqHQUVOnMCXD5zqFQtcQpYJA6BbA/QIv/tXNgwt9XThVaMvOTsKWXGFlR0vWFzlxqaMPh1OsOeUpVNkIc62Fl0ToJ2oiUyBCZxHymwndbIVhVkrvNBPWuVvwlYsVP3g6gJ8DhGlVDqmBCl4yfCDdF9J9+WeHUOgex8kncrnwfDf2Tyhi/4Qidk7syc6JhvBS9xfX2mBOE5OZh4EZQ4DZZPSxqSTg2uulWiNw93rSgYyxTAGNbi1luIpqzENTd1pTN1zPbIt2I0nAxnBjyjPz7uh2DWTLGGbKZBkATWNdTKarCxYPbW3W+GsKbIzzZYynMvWLJI1WTaVho0rqAAAgAElEQVSpzBlgukDSEGQMAWZaaRqy/aU+NCgjYNG1QOv0l9ZGhvkn/yW0/P8CGENzrG7yYQoYmgIrTdHhBQOMNJDDCwbWQof+/bpfo3vO8HONZer5/XPL2TenjN3zR7BjbiX75o1g8ysDODA2gYPjkvj5dScefODPg5UO8JEbrHOEjxxgoztURcCNAvhjNNwYwjfTnTjVR6jpJlRlC+tihZURwoYEYVmYsDJaeDdBOFEq/LGqmco7+TQb7nWALxLh0/i6AHM3SAHMLR8FMDqIueWnHrvtC5f8VE/RF8M5N9eZZFFpwG6iOpvsNHNjmo0wONmOlf3sWT/Yk32lwonhwmdjhR+nWvJgSTN4xwHW2CiI2euoIOaEuwqfMwaY6+FwNUSBy8c+Whmjnx5gPtF6j077KoA5EADLheuPC7sLhQNFwrVRdnzzgh2fPilcHGbL5eF2XB/tw8Xhbuzv78am7la83lZ4o73wandn1ldGsf+lAi4sHaLgZdHgBgHm9JIhnF5cyYkFFex/uURNYTpHMTLOlmLfugDTxUUPMN1dVUJvb1eh2EUY4KmmLyNDFcCMDBAe9xdGegrjQoTlnZw4VGbLsSHOXH3cAGA+CIYtHgpgqv3UiuiMvzJJX9Ug5no03IxRpZo3WyiD98ko2BDKPxcI3z4vfPqY8sN8VqkA5rOhwhePuvL1GC9ujwnlVJkjy/OtmRKjVl3FzkK+nVJbBwUw6U4KYjLsFMRkayqwEgqthf6WwgBr4Slr4RlbYaalsMhZ2B5myfVOzaFfFpS0gYIE7WooRAFMxxAlHagYAkyX8PrqFKTapzt6QY4b/8x34rfOLlwqcedCXxeqezuyt7sVa7rZsrqrDccy7NgbL1wIsOZCgDUrAm1Y6iyM8bXgST9LRgVb83SMC6PjXBgeac+EQEteCrVlm78D+yM8+dHHiR99nBTARGq5OCn++ulLihek+/Jz20D+1SmaI6Pacv65rhyY2KMOwOimLvX9jXWnMQ2tmhoCms0TCutlzhjnzxhKlwjcEMA0BjF1VOutMb9uWv1s50Y9NI11OJmfztRPAjae0hgCjPmT7Oxa1QWZhkslG+teaupkxjgkTwcsxjBjDmDmlmXUAkxDbdjTB6QzfUC6IcD0okE10ga99eVCtk0uqtfyXBvF38SrIvOelt51pIOQKk2mAKVhUKkv3XrI1NfqV0d9a98enFtS+9bU5KWpU5iGAaZhmfuao03Qkfml7J1XwfYZpeycV8m22RVsmjGED18ewEfP5bNsdBYfT4nj/1YXwJpAWBcCay2Vdlmr0+Bz0fB1O7hdDNtb8H9POfBxkfBJD+FAlrApUVgbJ6yKEVZEKaPq9lzh3gxRrdI3OsDnXeDTZLiTpMy8t8NVueLNOLjlDzf94EYQXA+E66Fq9XAzSOlqkCpevNkOziYxIVeF7vlofhgrbQrjIEK0i/BYG0+WDmvLtqF+bCr34uRIW66P9eOfM91haTAsc1Hnv5ucYKenqgE44q1WQpdD4Wq4Muxej1Avwp/4wzlv1Ux9xhsuBqkVyScB6rGTLnDCGfbZ859Vwo/zha+mq3/+X15rBhtDYF0grEiG5Un88U57vp7dgm2Vgazo48jibi68PyCYLU9kcfil7hyeU8rpJUOoWVhJzcJKDi2q4NCiCmoWlVG9cABHFpZzdNEgTiyp5MSSSo4tVjo0q5y1z3Rmfkkrnsz0oH9oM4q8hUJPoZu7tkZy0kLuXITezkIvJwUw5b5CZbDSkAChwk941E8Y5ik8FyQszmrGvv6WnBzhzo2nrPj+FS/uL3WC5f7q73G3t+qDOuqtWrnPB6s13PVQ9e/6TgTcCVW6FQE3w+F4GPdXCD+NFb4cLdwd5sDdYQ5cfKIVl8Yks+2RLN7tHcnY1h5UhAmdnIRce/3EpY2T0Fp728ZJaO0kZDoKaXZCqq1SmgYzqVZCmqZUSyHdWsFNe3shz1bIFuHd4nRuLX2WL14ppaYig9MdnbhY6MX3ha780MMNCl01uSsVeUBPT+jtBb29+LPYj9/7+HCv0I5becL5jsK1Iisu9bfncqkDZwfa8XGpDTUD7NnXx4K1BXYsyxXWpFnxfqKwJbwZO2Nt2BNvzfZoYVOOH4d6x7H18a4cfXkgW8d04t0BrVjfMYgVbTy5HGvPpRg7/vBtxm/eoqoEYt1U7UKyv4KYRG99sF+qH7QN52/9k/l1SDYnnu/IybGd2TaxO9smdmfzKz3Y/Ir+F1jdxzpt1XrfzKthwNHlzpjr2tswoRvrX+xaT+vGdWGdQeWBbu1k7KUxJZ2/Rnls8jWZv3ZqKCG4sfyZRs+zG0kArg8xHWqNvobvG+rtR/T5Mm+NzKqj2nPsRrqXGmrErnuGrYLx5g3NUDLqWpo/OF2Bi5FmlacwqzzFAGzSaldMat2kAGaGgfSn13o1CjCNdROZghdzANNUf0vdyUpdcPlfA4yx+dbYy6J7zpRv5WFWR4bgYfjYkYVlTdbRxQM5unhgnY8NnzcFMMcWltXK8HEdwOyYO4QNU0v5YGI/lr/Qmw3juvDWiDS2POLC5292gO2xsDZYwcs6K9gqcMARzkbBtUS41Qf2pfDLc66c7CbsTlMAsy5eeC9YAczalsLbccKaNOHqOIFNsXAuDT7tBJ+nwU3tnPpuJNyK1yDGT+l6oNLV4LoAcytcXQGdTYKvu3HlnW4UuKu1kZ8GLjbaWxcR2rsIz+YFsnWIL9sr/akqF049Ysc34634dZYHLLWE5a7wobV68d3jAAfd4KSXgpgrGsRcDdWk+WHOaBBzPkBBzMVA1XF02g1OucIJHzjiAYfCYX8QbA2GdT6wIxr2t4SqIlifzd8WJnPhWW/W9Hfjg75ObBwRz9FJuRyf2pML80o5Pn8gR+eVcXDeYA7NH0LVgnIOLhxE9cIBJgHmxJLhnFw6gmMLKtk2oRdvDW3LS53DGd7ShZ6+aurSWYOX7k5CgZNWMeAo9HBQrdSVQcLIMAUuA32URvkKle7CU37C3FRhR2/hyBBnrj9pyY/T/OAdL1gboSBwjw9UucBhzVd0KQyuBCldDYRrQera7EaggpfbkXAxAfZ7w6uu/P6S8O0TXnw2wokD/QN4r7XwWJhQ7i50c1R/7i6uCmI6OAvtnYRsZwUumfYKZFprEJNurweYVFsFMGnWenjRAUyWBjE51soQOyHVi91P9qRqYArzW1iytaVwPNeOz/Ot+bKTHX92tOX3fBv+nWfD/Xxb6OQAXZ140N0ZCl35Z09Pfi5047MuVtzMFa50t+BusSM3BrlydYAjp/tbc6rEiqoS61qAeS9HWJVqyfIEYUeMNbub21GT6sL2aGFrfiA3H+/ImZnDODNzGMenlrFvXA9ODs1iZ49Y7iQriPnNW/jdRwOYaFfVHdXKT8FLS0+1Uopz59+Jntxv5cWtLuF81y+Jw0/lcHJsZ3a+VMjOlwrZMrknWyb3rJ2+b5ncsx7A6NdK5gHGHMgYJrybghfd8zpwqfe8CSOwoY/G1IWToQwBpqH2bEOAqQszTTnVbtz0awpoTENMhzr6XwHMXwUZXZmkDmBMVRfMH5zOnIq0OtKBjGErdt2pTAazB2Ywa2BGHYgxlhivhIzVWFKuOXAxBJi/Bi66tZBpMDmo6WEgxdTZsaE5tmFPyv+faYohmJiSMbw09nnHFpZzdMHAWhkCzDHt+WMLyzkwfyA7pvVl87T+fDSpF68/35e5o7vx2nN9mDu6G/PLY/hobC5sagsbs2G9iwqnW6aFwW2yh61O/HuOG2fLhSPthepsoTpL2JUkbMsQThUJnz0m/DHNj99n2PC3icLP8wQ+dIJ97nA+Br7uAHcz4WYY3I2Cu1po3Y0IbdUQrClUUzDc1ELmboaqfqFLwXCtjNWDVdie7irJTYMYWxG8REj2EcbnevNuZSbbBgWwtdyfy4878MV4P36d4QBLvFX542p32OqkPBmHPVQone7nXA5S0oHM+Ug4Fawg5qwPnI2Ai83hTC6cag8nUpVOtoPj2XAglx9Wx3NtYQznZ4ZwakoSmx/x4tWebszMs2JJv+asHJ7J9vGFVE3rz77pA9g/o4zd00vZPb2UndNL2T2zjKq55SoHRpvEHF48iKNLKji6ZAjHllZy/NURnHhtJCeWDGf/zFI+eraAhWUpPNnGj5IwocBDvfh3dRS6OAiFmnraCv2chKH+yvtSGSAM8hZKvYUBPsIwX2GQuzAmQJiTIazpImzqacnBYgsuj/bjt9nxsCIfduVATSF8nAPn8uFqa7iWBbdS4HYq3E2GT1P0beV3u8Gn3eFuKVzpBZu68e/pYVwaGMLGDOFJP6GPdq7fToS29kI7B5VL1N5RaO8sdHDVq72LkO0otHVSauMgtLYTMm3V21RNKTZCsrXQylavFHul1q5CrxALOnsLhZZCqYuwNE5Yn+NIVY5QlSMczxOO5QqnOwhnc9WE5ZPOFlwssuRKT2su9LbjbA9rjvW04ngva06U2HGyvz3Hy+w4MdCe42UWHOor7Okr7OtnwcY+jizvKLyeLixNFZa2Et5vK1x7wp5rT9izZ6hQ82gz9k2Op2ZWMsem9uXQpCJ2je/Fxqc7U1PSgvUdvPk80oJPw4TfQ+14EOMKLXwgwU/BS7wbNHdVinWGGCdIcoMMX/7RswWUZ/LJC525Mr4bu6cVsWNyNzZOKWDTtELWTy1i/dQiNk7pycYpeqAxF6NhbPqtDzONp7wbTmmaAjAbxnWrZwpe+3yXBoHG+NLJ+HTbPMDkmXysHtA82amOVozpzIoxnR/K8GsuS6apF0wKaLRgPF1lQYP+GPPXS7ozbHOVBYbwYvix4WTGcN00e1B6rXRheIYyF4z3PwMYY3DRtT//dXDRXQOZnqg0FWCacqZsaI41ZbZ9WFgxnoo8zHTlYXVsSTnHlpTXQszxRYNqIeX4okEcXzSwVkcXDKB6TikHZ/Vj54xiNkzszprxPVj+bBfmPdadGcPzmTmyI68MbsfLPfwY382TrxcEwrYOKtejKhSWCT/PFn6eJfx7qfD188LerkJVlrA3TTjcRvhioD3MiYF1XWB7V9jXE6pzYHcmbPGGda6wwRIO+cCX2QpiboUr3QmHW5pPwhhgrgbrAeaGTpFwzhdulPPLxlZ0DlKXSLpVkrUGMZ4i+IvQ1VWYmO/HtkEBbCrz4XiFcPlxB74ZJ/wyzQ6WCixzgI32sNMdqt3guI9qjL4QUBdgroXDpRg4HQIn3bXVUQicCoWtMXz/uiOfLRI+XSBcn2/B+WnCkUkWbHlMeL2HMCtHmJ0nTMkWZuRasLSHK2+VJ7H6kWxWP96eD8fk8uGzndnwQgHrXyxkw/gi1k8oYuOkXuya1k81Us8to2pBOTWLlHQAc2zpcI6/OoJTr43kyMIhbH+phPdG5TC5IJ7KBCd6+CiA6WyvVKCpr4PeuDvUX8FLuVddgCl3E54MFBa2tWZtd2Ftd+Gj9sL7GcKHbYS9hcL5kcK3rzhy/1132BChJlBnElUK8dVEuNFS6XpruJEFF9vBqTTYn8GDlcF895wrJ/sIO9oJH7QUHvdWBtY2GsCkNRMyLIVsOwUwHVyFHDf9W510QKODmCx7pUzHukp3EjJdlDKclVq7Cpk2QisR8kQYHiCszrbmo/Z27MgQdmQIBzKVajKEI62FE22Fj3OFs12ETwosONW9GWeKrDjR24aTfWw5VmzN4d6WVBdbaBBjSVUfYXcfBTCb+jqzvKPwVmvhzUwFMBu6CryVAVVlPPiwA98sbM7xeRlUTUtg/4vdOTSpiOrpZdTMGMjV0Tns7xXN9y0d+SLKkt9CbLkf6awAJtFfDzDxbhDrouAl2pH/RNvwINaWO218+LEghhOPZ3P+uY7snNKdnVO6s3l6EZunF7FhWo+HBhhT10uGV65NrasxBzANyXga0xjAmGvPNkwE1oHKw0xmjAFm5ZNdWPlkl4daL5nLlGk8LM8AZnR5MkYA0xjILKnMNAky+u6l1iZ7l0z3L5kw/VZk/CWIkZ2Te9GwGo74Nwcutf1DDfpbGk6/1QGMKTA5NLuYQ7OL60xYjKct9eGlvpo6YWlogvIwoNIYvOiAxFDmoEX3nOHHJxaXc3zRwNqV0ZF5ZRyZp10ezerH7ql92f5yD9aP78nKZ7rw6ujOzChvzdiSdjzTN4uKrvH06xBOv+wg8prbs7rSi5/WD4LdcXCyjbqu2Smww1KtR6rSuDdRONJdOFog/PSCwPJo2BoL68LgLQ941wtWB6vV0UZ/2BwAG11gmwd80lJdJH2WpqL2b4cpXYtUMp7AXAvU5K10wx+ueMOVlnAzmWUjLUjS1kjh2grJTntrr0FMa+9mzOocwPsVqewuc2PfIE8ujhY+fcGZX2bawRt+sMZD/Vn3eEB1gIKY0/7wSbDyxFwJ0SDLHy57q2nSmUio6cOXb7fg/UFhTGgtPJ9uz7jWTjyW5kxlC0v6xdjTM8yKrkEudA1yobJNCCPbRTAqP4GnizJ5vncGY/tk8mLfRF4pS2fG0HTmPpLN0lFZvPlEe5Y9nc+KZzux5sVurH+pBxteLmDzlCK2Te/J9pm92DW7F7vn9Gb/vFKqFpRxaH45h+aXc2DmYDa80JNFZVmMae1Lv2CLWoDpZCcU2gi9HYUhPqo+YGSAgpUBPkJ/MwCzpL0dW/tacmS4F5+Nc+Prl3y4+ZRwpFTYWiis7yx82E3YVSpUPyqcfFo4PV74ZLJwebpwZYZwbYZwdbpwbopwcqJw9gXhxNPCx0PU9znS34Gq3lY8Hyv0sRJa2yhoSbdRK6BWNkKyrZDmoAeQ1q5CtpuS4VSmrZOayrRxUNCS5aw+p5O/JV1CrekYaEFbb6G1uwKaFAehg5ZAPdhahfhtyGrGukxhS6rS1nSlnWnC7kxhb5ZQ1U7YkyfszRcOFgrH+tpS3deO6r521PSy4nBvaw71FQ6XWHCiv1DdS9hfKBzsJWztacOaTsKy9sLb2cK7ycLFUbawNQ4OpMORBDjcArY357flXtyaFcHFl/04MLM1NXPbcuilXDY+0YqPO/ixLVb40s+Sn2PcIc4XEgKhpS/E+0BzT03OEO0IMQ4Q6wgxbpDox/28CChK5NqT7bg7tiNHXunCkVe6sG9KEXtfKWTL5CK2TenBtsnKRqA75DCO2DAEGNMw03SAMQSZ2tXThMJ6RmDjqyZzqyXDyYypsknjDBpDgGncL2OcOdO5jnQA09RzbHM+mcZSf+tNZIwAxtjkaw5gjKcyeoBJ11QXZBovkTQGmLR6Phljv4wp/U8BxhBcdOWJfx1cdJkrptdBOoCpl0zbAMAYelgaAxdjz0pjAPPfTldMgUtD8GLu++jg5djCMmrm9ufQ7BIOTO/Lrik92TKpOxtf7KqMumPyeHV4FjPKWzOuRzzDO7VgWH48xe3D6JriRWGyB23CmjE8XDg+JR32tYSP26mLoUuhKlX1bgJ8MQBW+nNnuPDnK26wIhZWNofFtvxnpvCvqcJ/ZgoPZinxqqgo/20eSkdC4G4WfJMNNxIUrNwJhxvRjQPMVS+47guXveBiHNzL5ue9/RiZqHphIkR1NjkbyF+rHigPEBYWhbO33IPdZW6cGKL6fL6bJPw+xxHetoZVbrDZHvZ6Kh/LMW/VKH1ZWx9dCYGrvnDFR/38Gj8uzw1ido7Q3VboYi10sRU6WgmtmwnJIiRbCK3tlScj27UZnUMs6BHjQI94L0pSgijLCGRgZjBDsn14JC+YMd1DeL53NJP6RDKlpDmzBiYwZ1ASC4a2YumIdF4blcqbj2ey4rl2fDShI2sn5rP+5c5sfqWQ7VN7ao3oJeyfUcG2Sf14szKXsbmhlIXb0s1dDzC97IUyL2FUiDBCg5ehGrjo4KXcTw8wT4cIr+Y6sKVPM6oGu/DpC648eD0RtmTCjmzY3BI+ioZVkfz5dgA/vu7BD6+68fXrTnz7pgvfv+PIj8uc+WWlC39+5MkfGzz4zzY/5Q2qSoR9+bAslm8mJHJyoAvPxwq9LesCTCsLZdxuYSEkWColauugFBu1Isqy10OLboWUaSuk2SuAae8hdA22oVuYDe28hBRHoaW10EL7Xu1E6GwjjAsVZifZsypZWJ0ibGqltDlVaVuKHmL2tBa2tVW1EAcKhFOlTpwoc+VQH1sOFgrVPS3Z31Oo6iMc7iMcKBT2dBcO9BC29bZlbRdhRZ6wqqNwoI/w69x42J8Gu5NgX6QCmJoM2N+KB+s78vOy1pxcks+eKanUTM5n77hsLnUNY0dz4asAG36KcoUIN4jxUtAS56UHGG0CQ3MniHOG5h7Q3IO/pXryR/tQzgxP4dqT7aiZ1KkOwGyb0oNt2vTdHMBsn9KL7ZP7sH1yH5PwYvq6qUejUNMYwBiDjLk1U50Vk2HBpFHhpLm1UsM1B00HGHNemYeBmKak/hom/b45qgNvjurQQDBe01ZLi4dnmAUYUzBjvFKqzZAx4Y9pCsQ0CjCNXRGZA5faZmYz4PKwCbjGcHJodjHVc0rqwYq5YLmmeFua4ld5WFD5bwHGGFaMHzP0txyZX0r1HKVDs0vZN62YnZN7sWViIevGFbFiTEeWjMxhQWU7Zpa3Y0LvZJ7omkhl+yj6tomhKC2M/NQQMmI8SAyyISHQmnhL4YnOAfzfhnQ43lNldtxsCVei4Go0XIyEfU7cf11ggw1ssoPXhPszBeYJTLXhj/HCT6OFe0OEL4cI34wQfp/qCqtbwaF4OJ+l6gU+6wLXm8O1WGXq1HlermvXK1eD9QBzxUerHfCGK54qs+VaKHzZl6PT1dlsvOaHCdAyYVw0X4ybFsle3NyDt4tDWD04nh1lduwqd+TS4834YoIbf8yxh9e9YbW9Wnsd8IAaXzjqAx8Hw9UWcDEWbgTD9UD+dagzJ+Z5UpHkSpy2wgowWGV5aD4cb7EkyMIBP0s7fC1s8bOyINTRnnA3a2J9HEgMdiQ53JXMaAfat3QnP8mT7hkBFLXxp1fbIIZ0imFEQUseL0rgqd7JvNgniZf7pzNrYGvmD23PkpFteeOxXJY/mcfKZzux6rnOrBnbjU0v9uajZwt4Y2gOk7rGUBnnqi6RHJQGeiq/y6hAPbwYAky5rzDYX3jERxjqJrwQKryV68iOYqFmqCM3nxV+nOEJbzjC2iCo8oXjYXAhGq7Ew+2WKrjw+zSlH1rB35Lhb0lKPyQqfZUIX7SAq6mwy5MfZoVSUyGMjlK5JwkWyrOSbKXUykg6kEmwVGCTqJOlUkvteyRYKp9LGxch38+aHF8LMpzVcy2bqdVRGzuhVIQxPsJ7ccIHiVZ81EKZ0jcnCFsShb0JSvtbClVJQlWm8oHtyBa2Z6mz+VMDhOpiYXsXYX9X4VCRUN1DvT1SJBwuFA4VCDU9hF29hM3dhI3dhX39m3FjtAP/ntcSNrWCvdlQFat0MBaqYuBoHByKgvURfLPUgSszwjnxoienyv3Zmt+MOzHC3VjhjzA7/hXhAJGuEOupLpNi3ZTB11AxHhDtDlHOEOfO7+2CoCCeuyMzufdYO46N78rJlwrYOq0nW6bW90Dq4jN0rx97Jvdlz+S+7Hildx3pjkRMpbg3BjKmAMZYpiDGHMwYAoxx2aRxeJ4pmDFt/DV3lt1FQcxTXfngqa7/NcA0vmLSGX51AJPDO6Ny9ABjMIn5bwFm0bBMFlVmNQgw5iYyhvDSEMgYw0yjANOYAdccuOj018HFTNeQ7ipojlJT1kMNgUtTVkMNwUtjxtrGQOXE0oq/JB3E6LwtR+aXqpXa9L7sm9aH3ZN7sWV8N9Y8k8vyx9rw1shslgxOY0pJKyb2iue57vE82j6UsoxAeid4kBvrSdtIF9IiXYn1tSDUWYh0EyJFaGUvVE20gpruKmH2UrRqYP7YH1YJrBHY4QoHfGGnqwKZlW7wngP/mih8/Yhws59wtqtwJEdlxezpqILKWOUChxPgdkf4ukhNda5GGyS2GnlgaicwvnqAueql8lnO+8JnveBYOsMzVPR6oAYxbhrEuGkwESHqhWpcirCsNJIdZXZsKrbkaLlwZYwl308Ufptly/23BNY4wg4HBTEH3eCQh9aU3VwVS14L4NRCH8akqZ8ZpE16fLUJkLsBwHhKM7zEohaodFDlLoK3lRDgIAQ5CWGuQoyX0NJPSA21JDPKkjYxNnRJcKEw2YPidG/6t/ZnaJYvj3QI5qmOYbxQEMtLfZsztX8CcwcmMr+iFQsHJ7OkMp33RuWwfHQerw1uz0vdYhmV5E2/YAuKnIXeHsrvUhkgDPdT4FLhIQz2VOujAT7qEqnCTwHMME9hXJjwdp4T2/sKBytsufqU8O1kFx4stYEPfGGbI+z3Ukm8H4fClWi4GQ+ft4B7iSqE8Mvm8EUM3A1X5Z1X/dVa7nY0XEyCw6HcfyuJI0PUNVSeCHEitBAhoZmasrRx0V8atXYSMpzUOinFXkjWTqdTbPRKttZgx0Z9XpazkO0qZLkp6b5PrqvQwUUY6SJMjnNmTYotq1pZsy5RWJdYF2D2JQoHEoVDycKh1sLhtsK+HOFYgXB2kCVXRjixv5fwfrqwI1c4WKBWSwcLFcAcKVLwcrinsLOnsL1Q2Fwk7O4nHCkWzlYIn70o8HYQ7AiG/VEKXg7GQnW0ymWqzoTqTB5s7s63b6Vxe0xLNrQXrocrgPktxJpfg60gxBEiXCDcASIcFbTUARl3TS4Q6ci3ic78I8uXC6Vx3B6WTvXz+Rwb35Wt03qydZopC4EuYV1JBzC7pvRl5+Q+tdKBjLmiX+NpjtlLp4k96sgczDTqlTHqaTIGGuO1kqmP68KMuSqDLpq6seqZbo02Zzcl5bdhz0yOJm0a82gu7z6ay1uPGkGMCYB545HsOvBi+FztWmlEJouHZ7B4eGsWD2/NosqsOmoqyMw1krmrJWOJ7j80Q+2e2pe904vZPbVvg/Cye1pvdsUdZvoAACAASURBVE3rye7pveppz8ze7JnZmwMzlKoMTp+VijlYp835fw8wB+eWmE3BNQUwpgDF1OMPM0VpbD10cklFXS0t5+TS+mCj97iUcXzRAI4vGsCxhaUcXzSQmrn9qZpZzN6pvdk2qScbX+zOmrFFLHuiI4sqs5k9MI2XSjIY16sVT3RNZGRuLP2zoihM8qdDpBtp/tbEetkS6WaJj5Pg2Ez5Rpy0F1gRYViqcHvDI3CyNXycDWfjoSqAn14T/v66wD4HOOGrslOO+8IWX5gn/PyE8EWFcKtIuNRJONNWOJkl7EkRtrYQjvUTeCMezrWHz3vDZ1lwPRluRsCtSHUybVjyeN1b6aq/9oKnrXCu+cMVrSH60xiqpvpT4C6EihAtaqXkJYKjWOEgljhrBt8ER2FI+xheHxDDmwObs77Unp2Vnpx5yp6rL3ryj9n28E4QrPGFzWGwNxZ2x0BNDpwpgJvDuPtBSyrSA/EWfTOwnejD9Gw1I7GNwfu655uJaha2FH12je55BxHc7AQvp2Z4OwrejkKwpw3RgS60CPcgIdKLxGhPkmK8yI73I6dVCEUZoRS3i6GiYyzDurbk0aJ4xvRJ4oXilkwckMyU0gzG90rk0dYBFAWp5N0yf+V5GeGvpi+VPgpeKjyEcm+hQnus0kd4xFvplRjhvXxH9hZbcmyIK3efsuTvU7zgdVf4IEiFAu72USWZp3zgsr+6GrsbDnfC4FaI0u1ApRvBSrciFLheDIRTHrA2iovPCaOihU4W+glJoqUCkZai3k+21jJe7IV0BwUhWc5KuiyYTIOz6lqjrpOCoPZuQq6nUOiuEokH2QnDXIQ5gcKyJGFrKwUtW1sq7Wwh7Gop1CQqVScLNSnCoTbCqU7C+f7Cl4/Z8stcd7552YY9RcKKTJWFdKC7cLCncKxEODZAOF4mnB4qnBshXH5KlX6eqBSODRaq+gp7ewpHSoTrjwl/THeCt8Nhcws43E41eu/xU23vh4PhWCIcaQErQ7g6VqhKFT4KEc4GC9dihH9G2vJrlB1E2in/S6yT9tYNmrtDlAdEukOkmyYFNb8ne0DbYL4pS+HXUTmcnNCF05O6sW9KAfumFLB9WhHbpxXVi8/YM6U3e6b0ZtcUcxDT8BGJTsaBqobaMrHQpDZPML9iagxgjNN/jacyjQFMQ5OZVc90Ys3Teq1+6n9zht3wVCbH5An2W4/maKqf8NuU9VJjANMUkGnM4NtQsm89gNHBS1MAZu/0PmbBRaf64NJHuyDqx8GGShJNtC/Xma4YAcxfOX1uCFyaesbcGKg0th5qKsCcfHUwJ18dzPFFA6ieU8yh2X04NFv9Xe6d2lNlNozvwqonc3lvlLrvX1iRzvjCaJ7pGMSjueEMae1HcSsf+iZ50TXemzZBtiR4CM2dhBBHwU9rtnUweKF1115UY0R4e3Q0HEuH023gVAzs8tSmL7YKXs4Gwwk/BTEbPflzpvDdCOFOmXC7h3C5s3Cug3C2vXAyTziUJaxI1iBmazjcKlAAcysNbkcpgLkVrDVVB9QHmCt+Cl6u+Kg8kSu+cMEXPouFa08ws4eahIRoqxxvEZzEGgexrAUIXxGSnIUX29rzTkU8m8td2DDAgUPDhNNjbPlmkvDnIjdY5gqrfWBHpIKYqrawPYU7K1vwXJaa9ASJ4CzNcDSCFlPSPd/MQIYgowMfQ6CxF8HFSvC0F3ydBX9XIcijGSFelsR4WxIfYEdaiC1tIp3Ia+5I1wR3eqd7UJLly5B23gzL8efxvDAebR/MkCR3eoUIpT5CeaDetFvpo5/AmAKYUT6qSmB6vLCsozN7+lpwtMKZu09Z8vNUn7oAs8dXdUud8VO5L7fD1cTqbrgeZHQAc0uDm0+jVR7MlVCVaLyjFXdeFsa0EAp0p8+2Cl4SLbV1kIWayOhWRa2stDWTdd3pi2EOTIq9msCk2Stl2KnsmDwtA2agtfBsiPBeorAiRdjUUg8wW+IVwOxOEA7p1Eo4liFc7in8/LgnzIyA11NgWxZ/LPJhXy9hezfhWLFwulQ4N1i49bjw2fNaN9diO/7zqiOsDuHP15z5+xwXflvkxb3xwqVHhdODhFPlwvXhqmbhwQJ7+CgK9gZAVTBUB0JNEFTHqcnM0Rw43B4Wt+L/hllyo7lQ4yZ87ib8I9wKQqx4EGwBEbYKYnQrJWOAiXaHKDd+bunML4mufNIxiC+KE6h+tgMnJ3Rh35QC9k7uzraphf/fAMYwAd4UwBjX3dQFmR4mV0uGIGOc+NsYxBj6ZMxdLT0MwKx5um7B5F+FmP81wDQFZJaOyNSUxdIRWSwe1qZWDzuNaQxiTMGMmIMXvRpugDYHLntn9WHvLFPgopfuishsZksD10Q1c/tTM7fp/hZjY645eHlYD4vhKsgUoDS2CtIBSy3AvDrY5ORFd1VUPaeEqpl9tDVRDzaML2L1s51Z/nR33n6sI3MHZzO1fyov9k3jmcIEKtqG0y/Vj6LkEDrFeZMR4kJKoAPNfR0IdRG8bQS3Zvqpi4Um3YuqLgyumQipIdZcfzcZjpZCVXPYFQ67beGUP1zwgfPecNobTnnBRhf+OVP429D/x9x7x0dVZ///Z9J7nckkM0kmvSd0CCWkASH03gkggg2xwVqwIR1BRQQ7igUsFCkCoYdO6L2Jva2uu191d91V1+fvj/e9MzfDpKC7j8/vj9cjM5NJCDM3uc97zuu8jvDRIOGTSuFymXCmSDjZXjjRSbhU4c+6dsILDqF2gsCeofB5V/igyDVOfTlRfbxih4txLoBxtpA0nbMpnY9W+nIwny4PpzRcwVeyqGpMmFYh0QEhRAODthHCbV0zeGVsLsuqcnh3VAQbJ9g4eU84n8xK4u/PJPOfZbnwThGsKuHjFyvYeIediZ1jcWivmQ57PlrVqj7pr219j5u07+FjgBpfN/lo70uIjxDmJ0QHe2EJ9cEaIdiivLHFmEiI9cZh8yHNEUBBSjgtM810yoygU2YEFamBVKQGckOiDzck+nBzjHBjtDA+SklvIY0yK4C5KUbpDotwV6zweI7wZpcQqvub2Dc6hI/v9ObHx2KurcDsj3QBzJVk+EjL+dHH5i/Fa7IrUP0wE65mqJbhGRvsac9fnvDl7jyhT4BQHKXUIVgLowtUoNLMJBSI0EzU2LOuZh4eay7ac02uik5LEVqJ0F2EXiI8ahZeah7A6jZ+vNXMxNo8YX2BUJ0nbM4RtucIO3KF/QXC0TbCsUoF6789LbDaBtUW2GmH48359SXh2K3ClfuEP08Xvp0h/HW+8PNSUes5tifCHjvsjoPaFNgYAusiYXs8rI+DN4L5fp5w5R7hxI3CodHCuZuET6cIvy70U9u/N6bBznw4kAs7U2FXOuzNgf3NYHcOLI1g9yBhZ5awPl74NFb4fxkCyaHK95IZppSlKd0CaWbIiIT0CMiOhMxwfsgK4bfWsXzfP4/fqtpz5k/dOHdfd7ZP78326b2dwx4ukNHPLwpgtkwfyOZHXQCz6ZG+bG7AwuCK8+jXYBXGE8isf7g36x/qW69Ppi7UVLLmgUpW39+9jlbdV8Gq+yp4995uztvG+w2NZxsTf+uk/97TxakVd5ezwjC1VD/ANLBnSdu11HAYXkm9EKNAxjO8eF4c6YKYZzQtntDRqT8CMbqMeTEN7VmqAzDXwkvDALN19sB6wcUIMJ7AxdMYdFPAxQkn9QDM9QbKNXVSqKEqSn2g0lSAqX1mdB2AOfTMGA4vGcvBxVVO4No9f4iz2rL+we6890AFq/7UhVdvL+GZG9TWzznDW3Bvz0xuL0ngxs5JjG4XR6/cCLqmBVKUHEpbmx9ZEUJKkBDrr064wZr8DSde92pAkPYcHxGeHCj8dUMFVKfBRgfsioBTyapFcMKi9gMdj4MNZn6cLXxTJXwyWPi0hwKYs50VxBztIJwpNVFTISxLE+anC3+b74BPSuGzLi5wuZyo5b7YFMBcsio5wUU382reGB1wLlbA+a7MHBBKrqhFjw5Rk0j6/9dfg44QrXrSwSzM6BLO8hvyWTPGzOqqaPbd7M35+y18NcfC355K4KvFGZyfbuG5gSpiP0PUDqYw7XXSAaMhgGmK3CHHCJX6+2NsRwWZlIK9hVBfISxQCA8SIkOE6HDBHi4kRAnZFiHPKnSIEUoTvLkxyY+x8d6MjxLGhauU3RsiFbzoADPaouDlZqtwp1W4O05YmCes7BbmBJiP7vDi++lmWBKmtlGvDfMMMB9qYOoOMJfj4YNE+Chb6aIDztmhtpSfXojkngI16l0UIXSOFIrCldqHqtZQ2wC196qNb931AC296qqFSamZJr1iU+it1FOEqkjh+QJf3mwfydvNvXgjV1ibJ2xsLmzTIKamQKgtFC6VCn8b5gsPB8ArObC7AA60hgOpSsebw+u+fP+EwEoLvG1VWhMOm6ywPxNOtYKj6XAwCQ4lweYI1Rba5VDtoJ3pajrrzRh+mCNcvVs4O1E4WiVcuEn4dprw65MCK2JgvVV5Ynalw/ZU2JmlAGZHO3i/GTyYyFf9hH/kCt8mCb/a/BTEJAdAWrBSdjhkWRXE6ACTpfTP3Aj+VRDFh53j+GvvLGpvL+LitJ7smtWfHdqQR7Xmf9w0U10UKw2meuYQqmcMpnrGYDbPGKyAxlmhaVg6zLgDTmNQ4+6RMVZkjLd1gHGHmFX3VVwDM3WBpv7x7IZgxggxKw2m37qTS8a2Ulmju5YazpIpZdmkUoMnRskIMC/cWswLtxbz3M1FdXYt6dBiBJr/FsA0BWY8tZh0ibHysnX2YA9qeIFifeBSPXcAW+fVDy4NjUE3xZCrA8wfyW5pism2MYBxgoh7K6g+eWgRKWgZx6FnxnF4yQ0cemYce54ax66FVWyboyByw2N9WPtQD96eWsFrk0t4+eYSnhvfkfmjOzF9UCum9GnJ7RW5jOiQTL8WsXQvsFGeY6FNUjg5Fh/s4UJMkGoRhXi52hMmDydLd3lrJ0kRlbHx3pxBUN2an9/LU3tuLmSruP+T0XDMDGfioMbOTwuFr0cJHw0UvugpfNhFuFCsdKpIONFR2N9F2NFJmG0RtvUU2N8SvhgA5zLhdDp8kAFX0tVJ72KCC2DOxyidtWqtpHgt6C5O6bwd/lzAF6vaMChetXgyxDVWrZ/49ZZOiCgzbYlNuKMynyVjmvPM6Ga8WRXP2psz2HZnFptuS2PJ8ASmFAplZiFLXMZg/bXUKydeYtIk10iHQ6/fATXG7+Pj4b0zGT7nI67WU6QoD1CSpgE+wvgYYUGI8Hiw8FqQsCJMWBOqtCJEeC1AmBcizA0W7osS7jcL98QKU23CgnzhjW7BVPcX9o0OqluBec0Oa0JdAFNrVWsfLie5KjA6mF62a4rXKjDpShfi1cLOE+X8siyKO/KEbt5CoQYsHcKFErOCmDKz8q+URrvC6zqHqdHpjsGuMWpjkF1HXdpyx+4+Qjcv4Y5Q4ZmWfuwsjmBDKx/WFwirs4UNzYX3W6mwxq1tVPru+QHC3x4QeNEHtkXB0TSVBVSbBAcdahP3jhhYGwDrfdReqJpo2B0Fe+3qOScy1F6xg/FwNElVM7cEwpYQ2BUNe6ywNw4O2GFPjDLLvyH8bYGq6Fy6Tbhwi/DFXcIPDwksDoI342F1LLyfBO/HwEYLVMfBTgfs6g1buvHFnJGs6ZfO3OY5PNmuBUdzM7nQtgVkxkJWnMsTk6kpI0IpTVNGBOTF8Jc+Ofw2togrUyv56L7e7H1sAPvdKvmbZwxk68whbJ81tA7AbJ4x2AkwLtAZ2CSY8VSlcW8zbXy0r5p0ekh99AQzOsSseaCStdN6OAHGE9Do8FIXcJq6wqCrU29NKb8GZOo3/eowU1ZH1y6PbKzFVOaEGE8w8+JtJU6A8bQw0lihMcKMgpf2PDOxk1P1wUxjQPO7AMbYNrpegNk2Z1C94KKrPnDRPSyNhc7V1xraq6kxgPmjIXJNrbj8EYBRGsvBxWPZ/3QVNQtHsHXucDbOGMiGR3qx5oEKVk4t5bU7i3jppvYsGduSJ4a3YM6AHP7UI4vbSxzc2DmF0e3s9MiJpDQlgHaJQTS3epMSKtj9hHBvpWCTghdvDye+hk6cenXGIsLkblH8c3UWv24oUH+QL2SrE9AZC5yywoUEdTX5nPCXscKHA4TPe7gA5nxn4Uyx0p4S4XCFiVeaCcvyhR9fDIAr3eHztnAhR4OXdFc15pLV1UI6H6PBiweAOROrTKOf3cbbd7kqMGYNYHzFBXG+oioooaKmropjhcntAnmwq5WnKv15qtKfJ8qFB1sIQ2xCJxHSNOlfp4OE3t75bwOM/v09AYyXXAs4OsD4av9WiAZbySLk+gljooQ7UwN5Lk54wWZis8ObmuxQjuWFcCQnkJ1pfmxN8uKFROHpGGFajPCARZgSJ9xrVwDzeteghgFmi1UBzOEYBbWXkwwVGIdbZc1eF2AuJsBpK5zsym/LY5iUJZSLahm11CaLCkNU1aVDiDLhdo6om8JbGqlUFlVXpZFCuaZuUUKlRRgaraatnswX3iizsLkwkPUtvdnQTFiTI6zOETa2ELYXCuf6CT9MFphlhhXhynNyLB2OZyh4OZQIO2OgOlJNYu20wh4zHIyDA7EK+vcnqGrLhQI4kqJWUBxNUgb43ZFQY4G9VgUwe6wKXvbEKK9LtRlWx8Brwfz6hD9f3S9cvVm4PEH49k7hHw8IPCHwerha/6GHRm6ywuaufLDAxkvF0fwpVhjlI4wL9Galnxfb7VZ+sQYoiMkIV6PUdUasNVNvqutzlzvF8UVFKofGteHiXd3Y+9gA9jyqqvnb5gxh25whbJ09mO2zhjoBZsv0gU6AqZ4xkK0zr638NwQy10Z99K8fZPRx7Yf6XiMjwOimXyPIGAGm/gqN52wZ9zUGb0/tyrv3djNAjFtFRtuOXT/EuC+RdIeYxkaxyxqEGHeAcZcnkHnu5iKW3lxUB2CM8OIJYDwBzZPjCq+BmifG1k331fNj3CXGg6YxgPE0+lwfuGydN5Bt8+sHl8amiBrztLgDTP2VllGaPIPL720D6UDiemyUR3nyuOg6uLiK/YvGsvfJKnY/MY4d86vYMnsk6x4ZxKppg1gxtS/L7qzkhdu68NTEMuaN6ciDQ1tzV88sxnfJYHTnJAa3S6Z7joWS7FiK0i00Twgm0+JNfLBqE4V7q5OXfmLVT54NAUt9VRh/8cFbBIe/sGd2Mr/sGgH7kuFcK7iaqq6yz9kVwNTGwzvC3ycJHw4RPqsUPuwqXC4RLhYpeDlbIhzvIpzoKuwuF95rLVy9X6CmED7rBp9XwAf5cDlX7Ua6lAKXbSp9V6/A6Dpn09pICUrnrXAqCr7sBYfyGZurzLxmDcKCtZO6fqLXW0rh2nOyQoSWMb50S/Bxhpzl+7iyXUK1r9crOEavio8HaNHl7mX5vQDjqfJiEtXGCtV+xlgR8kWNHvcTlWkyV4SXI4X9McKReBPfJgh/zwiEgghoGwvtbNDKCgXRkB3Gd1nBfBovbI8T3o8SlliVnssT1pT5sbW/cGC0Hx/faeLHGWZYGgqvxcHqYNhicU0h6QBzNVW1ji4nKenbxi/FKZ/Th6lKF+0KiE/25l/LE7gxXaXi6mPQetZLlijleymo0aeQnCsCdKNugAoPLAxS/hl9R1KXYKWRfsLkOGF1B+H98gA2thLea6ZaR2tyhU1thdpK4fJE4T/zBN4ywZZIOBCvqiinU5RqY6AmVC093ewN+9I0Ras05wMW2B+t2kvHcuBqLnxUAMcTVfXlWBIctMEBTfujYW8k7A2D3SGwM0xtg99pUdpqgXd8+XmR8M104cNJwtVbhR8fFVgk8LoJ1oXD5u78uKw5j4/MozTSVZ3Tj6FAUWP8D4UKrxQ4+DXHyk8ZUcrUmxYF6boiIC1cfUyP4NdcC//Ji+Gr4nR+HtCODyb34PM/DaR2+lBqpw9l96xh7Jo5lB0zh7Nj5nC2am2krTMH1ZHzHGR8bMZAp5pSofFcmambO2NUHaB5uDdrp/Vwmn+NwOIONjq8qNvaJNN9vZxadW/POnr3Tz14995udeRqLZXz1pTyJgBMV2cr6X8BMC9PKnXqegFGtZGuD2D0ZZE6tPze6ow0DC+DG81pcQeW6wGYmsfr3+zcmBlX36rceOCc2tLbFG/L/wpgPHlcDi6uYu+TI9g5X2nH/Co2zRjK6mn9eGtqT5bf1YPnbylj0fhOzB/VhocHNeeeynRu7ZLM+CIbA1vH0KdZJBXZ0bS3+5Jn8SEjXJsm8hOivVRrQ/d7XC+wuMtLhEDxI1L7Xre3EL5Z3R1qM+FMc3XVfD5BeWEuJMDpNNgZDtP9+GyU8GVv4aNuCmAuFbsqMCe6CkfKhL0VSh/cJ2oNwZl28EV3+Kw1XMpxAcyluPoB5pzNBTAX4xTEnO8I3/Tl/Uc7k6cBilVcXhgdOPy1P+h6bou+TylVVOhdqqgKToyoyaZIUdUXT2bb/wXAuFdYdKg0AqbuVwrQ/p8xotJ/2/kI472FyWHCaxZhY2YIp1MDuJgdBi0t0DkFSjV1SoKODmifAG3t/FZo56cWZk7mh3Io3ZdXUoRnbQpgVpX6Ut1POFjlzyd3efH3mRYFMMut1wcwl+JdAHM1RX3+nFW1JE/25qdX4xmfpgCmVYCCmHxvIcek4CVTVHswUxTctPJ3jVXro9Z5oiaV8kR5X1por017EQpFGBcizGruz7rO3qzr7M2mNsLGVsL7LYUdHYRLw4Sf7g2GF8PhvTRVVdkbD0dT4GQmnEmFE0mwLxKqfeE9gW0BcDgL9qa6kpwPWOCQVf3enG0BH+TAlWwFL+cz1O/Nfivsj4PaBDhocQFMTSjURMKucAUvNVY1On0gGXYnw3tR8JQWIPmcP7wSBhujYW8Kv77Vntd6qyToFFHQbTz+grRjukqEOVZ//pkeyS/ZMZAcDplmyIhWytQgRvPG/Jpr4bd8Kx+1i+ezjkkcGNaaj+/qw8k5ozkzfyz75492AsyuWSOclZjtswbXkX6+cd6vB3Cc07ENAE1dkHFlzjQIM/VOMbmARo1lu0s3AfduEGJ034xTzuqMVpGZWslbUyudIOMJaBTUeF4o2WiWzOQuLJ/cxQkyujwBjHs15sXbSuptJy29uYglN3VkyU1FTtXXTjJK33zdWIupMe+M1IWVIR7UMMAYp4euZ4qosYTcxiaJXLAyyqP2PTW6jvY/XVVHBxdpagRA6ldTv073uSiPy6HFE9j75Fi2zVPVlvcfHcKa+/uyYmpfXr2zkhcm9+LZWytZMK6MGcPbM7VvK26vyGVs5wyGtomnbzMb3bOi6ZgcSbvEMHJjA0kJF+JCBHOAMnL6yfW1JzyZRutrI+knyBgRFt/eDvaXw5n+cDVfhZWd1TJZrqTCKRu85cWlPwlfDRA+7S18USZ8ViycKRNOlwrHOyvt7yyc7il894jAikTlETiXD1+3gY/yVS7M5RT1vc/HusDlglnpXByct6lW0kWHuoK/YIMzZvg0FWpbcHtbZdbNkrpeGL36EiAuU3OQ4bFAw+N6tovevqlvSsgIfkbp/15TppWaIt3Lo9+3iIKv8SJMFuENEdYFCFfDha9sfvyWEgB5UdAiDlrZoY0VCm1QGO9S+wQotKtqTGEStE1Qz82O4EKScDBCeDNd2NZR2NFXODLal8/u8uIfMzSAeVUDmM0W2GuGwzY4a1cZLx+mq2PDCaRJ6v1yB5izqXAyCU4P4OMnQhmdKnQyCQX+Qr6fkOujlGVSOT+ZIuR4qTUABf5CQaCQH+B6brb2nExRCc2tRejgJVSKMDBQmOkQ1vaIZGOx8E4btR6gukg4OVT4xzSBl0PhbRtsjlVekgMO1QI6lawqLyfj4YhVQcb7JljvrQC+1gb7Y2BXGOyJgP3hcCASTsXDxVS4kAYnE+BUIpx2wEEz7ItQk3yHzXAwSj1/f7jS3hDYEwy7g6EmRD12xKK2oh9PUX6ZPVbYG60iDS52he3ZPD/STrmvOv7TRIgQb+eFjZd2TIaKqjC2MXvxao6VNYXpfJPj4IeWWVCQAflpkJ0EmYmQkgDJdkhPgYxUrjTP42RGMqs75LOjZ2f23TacD2bcyf6Fk9m34HZ2PjaMXTPVZvWts4azZfZQTYPZMnswm+Yo6fed5yU3kKmvQlM9w2UINmrzowOc2vRI/2vU+Bi2e66MZ9VnAHbXNZUYp/Qx7R5OmKkDNPpSySld6soJMo1MMd3R1QkxnmBm2eSyOhDjDjRGuVdnFMyoUDx9LPvZia7Hlk7opBZHTujEMzcqeHl2QieWahBj1NM3tPeoBgHGM7goeYYWz0FzTVmm2FRQaRha6lZYGoOW/2uA2bdoJPueGs2eJ0ayY94INs8YzLpHBvHu/X1490+9ePPObiy7vRuLx3di/uhOzBrejvv7NuOubplMKE5ldDs7A1vE0SMrnM6JgRTGepMX5UVGiGAPEGI0f0uYl6udcb0nwsYARj8BB4qqPMSKUGIXPns1ET4YDldy4XymApizMXAhSZ2oaux8N0/48yDh837CtxUKYs6WK4g5UawA5kCxcLxCA5i3kpR/oDYFvusIX7ZWSbsXkxWYeAKY8zYFMU4vjAYw52LUssVvBlC7WF2Bx4srBdeYt+JruK/Di74EMlj7Ax+oPW6suvxfAoyP279nEyEtQLjfT5hvDWav3Z9T2WZ+yonh12Y2KLBAa7sCk46pGrzYXODSIVGpYwJ0SoSiNKVOaVDo4OuWwZx3CGsLhJ1FXuzsJxyt8ufzu735aWYMPBsGy+NgTQhUxyi/x2ENLD9IbTrAnE5RcHCqP1fnBzEyqS7A5Plq8lHgkmVSoJLvJzQLUABTEKien+frqtbkiDoG2onQVoS+PsLtKT680dmX1d3D2NBZWF8kHO0nfDpR+G2mH6zMhm25UJ0NOxKhJlUdm0fTXQBzKkEBE3VhSAAAIABJREFUzO4Q2CgKYLaHKIg4YIWacAUxNSEKSs45FMCcS1a7xU7Eq8ycfRFw2AKHotXz9I8HIjWFw75Q2BMK+zQYOmKBk2kKYA4nKh9OrQ3OpsO5Mk5OF4bEqb1Omd6qlRqsHcv6775+rFtFSPcVHg0UFsZ4c9YcyEeJZv6Zauc/OSmQk6yUqSktGRzx7ImNZo2PcI8IDwULcwrsvNGzkDcm9WHzI2PZP28Mu2YOZ+us4f+/A5j6gvHqg5qGAMbTKLYnmGkIYNwh5q2pla5MGU3/a4BZNvnax4wAcy3IlDrlypapm/a7dEInp4wAo0ONO8wYgaa+SswfBpj68lua6mn54wDT8DTRwUW6RnBw0QiXiVa7fXDxCI86tGSkdrt+MDG2gw4sGePUwaVjqV06jv1Pj2LvglHUPD6S3Y+PYeus4ax5eDBv3deX1+7pw4uTKnhmQgnzR7XjkcGtuK9PHrdX5DKxJI2hhcn0a2GjW04cRcnhtIgLJjfal6wIH9JChDg/lyE10HDi1E+of/TEaGxVuF/x+4krnv/FsQJHb4UPOsD5Nq6AufNxaiz2YjasFb69Rbg4WPiqr8qEuVIuXCgRzher0epjZcLZSm2qY2WimraojoZP2sE3JXAlR+1fcnpcdIDRdD5G20qt+2AcmjSw+TQXrqRxf4m6ArVqChHXiLi7fA3/3wADdLirPoAxVmh0+WvvV6DUHbv+oy0+3bszToSpocKpUOEzhxYVn2uG3DCllv7QOhDaBUKHEGgXA+1joUMSdExW6pwKnbM1pWpKhk4OaB8JeT6cby1caS8c7i9cucGPb+7z5pf5ZnghCF43w3thsC1OAUytXZ2wr6TD1Uz1UQeYCw64mKS8TR/EK4C5rFU2TiXD0SEcfziAwQ4FHVn+QnaAkBkgZAUK6ZoyAoSsICEvTCiIEHJD1f3MQCHdX8j2EbK8VfuolY9QIuqEPi5EmNda2NpP2NRLOD1G+OJu4ae5Ai+GwKpwqI6HXValfRZlxD2ZqHQ6XumUpr1hsEFgjRdsClJG3H2xqoW0NwoOhKqVF5ccalLuTBycjoXaSDgUDrURcDQSjoQpHY2E2nA4HK10MEZpn1WZgvfHKEg6mghH4hXMHLHAsQy42pYf1nZheme1ubtjiJDsH060mAjSjj9jXIKP9vdEb6Em+gh2HyHRX+Ukldp8mZxt5/7W6Sxv35K3Stozu7gVNydZyPJSx1+4qLUZFi8hPlDonOjL3Fv6sv/RUex/dBR7Zwxm74zBVM8ZRvWcYWyZPZjqOUPYPFepes6QOgCzfdZAp7bOHOBU9Yz+2u2mA83m6f2c2vJIX7Y80nDK7/VUZYwAcz0g845BdUHGc1Be/QDjqa1k9Mt4DsUzemTqazMta6Aa454r454vo2+/fn5iR56f2JFnJ3Soo6U3tmfpje15fmIRzxoqNDrouHtl3EFGts8dqoHKUI9yJuLWpwYyXK6n2mIElKaOQTdlSaI7wLhDjBFYPOqZ0fVojEeA2b+4SunpUdQsHMb2Wcppv+mxwayd1ofX7q7kxdvKnOAyfWAB91WmMaksiQkd4xjZOpZB+ZF0TQ+jc6I/LWN8yQ4VHAFCvI9g9xZiTS4PRqC4PC5/9CTYEMAYg+0CREjR/mANSxDOvdgePimBjzoreDlr1WL9bcqEeyoFngjmo1HC5z2vhZgLJcLJLsKVfsKPjwi8EQ+bImFDKJzMUADzWUu1I+l8vOZxsSp5Apjz8dqJMdlViTmbAF8359xL5ZT4qwWLOsAYg+10cDFWSYz33YHECDvG5xvzWoxgEyyu/UdmHxPh/l4Ee7l8M7/3PYwSIcFbuMNfmJPow6eJQfw1x+Lac5MZpJRngnwvaCbQ0gdaREBbCxQmKngpSoHidCjJUSrLVCpNVyq3Q8doPiv14dMSb44MEK7eGMh3D/pfH8DoFbXzGmzqFZgryerkfipZtZCOD2XfVKEyWoXNpfsKqV5Cio+Q7iek+gspfkKyt4KV7GCXdIDJCBBy/YUcXwUvbQOEcpMwKEqYnies6B/DiQkmLk4O5td5wfB8PKy0auFwSUq7rGos+kCsAoVTDgUwJ2xKZxJVReWQGTaZ4G2Bdb6wO1r5WQ5aoTZOwctZu4KXU1py9HGzApgjUer2sSg4FgHHtfvHzSqV+FgMHLHB0Xi1k+yQTU0s7Y5UvplDcartdMQCZ3LhQnN2PRTFkGiVfVMaJTj8wrCIN2FicrZQ9ePbR1w7w6JE/Y7oy08TRXnAWomawrtRhFtMQk9vBYJ60nWA9rVx/kJCkJDmK3Swm1g+qpDDM8ZwYM4w9s4YzNa5w9k6dzjVc4awdd5QqjVtnTdUbU/XtGPOoHohxh1grgdiqh9VcgcY4xSTDi96Vaa+aox7VaYpMOMJYJQaXl+wQpMOMtduwa4PZDyn+xorNLp0cNFhZplWkfEEMO65MnpY3os3uxZJNgYwz07owPMTixTEaDJWa5ZO6FSvV0bqA5ffCzANZrf8wSqLp+mhRhNyF42qM76sq/aZ0cpcWw+4HF46ql6AObh4FPsXV7Hv6VHsWTyKvc9UUbNEacdTw9k8fyDvzx7ExpkD2TB9EO/e34vld3Xn+VtKWDC2E48Nbsn9fVpwd0UOEzraGdUiikH5FvpmRVKWFknHhCByo31JDRbs/qpFFCbX+jOMk0X/LXCpD2CMJ/JgETKC1aROW5OwuMoGl3rBX8aqLdKn4+BUtKuV9GEm7Enm2zmqCnNugPCXPsKXlcKFbsLZLsKpnsInIwXmCLxphzURsDZSbdq9VAx/KYWrLdXV+qVkuBCrKQbOW5QuxCh4cUKOQ7UuzsXDmTD4LBE+HMLLw1QLLEkUhEVJ3daRUUZAcW8buVdrjDIm6upVlyAdXkxCmEkI9xLCfVQuj5/b929KPo+Ia6fSIBFuDxZORwmfpUVAajCkBEJ6KGSE8X1L4cc2wtWuwrcDhS/HClcGCd8WK1EUBmXR0NkBJclQkgnl2VCeqSkdumRAtxTomgyVEVARxsVBwhfjfPjufoEF0fBiELweBes0gNlvVdWBcw64lAZXsuBSBlxIVXIHmMtJcDERTjjUZM7xMWy4SWjlpVpAZlHwHqHdtphcGTexvur3JT5QKSFISA5U0is3hf5CUbBQFSMs7uHF4bv8+WxBCv95PlyZxzfZYJsDdsQq7TLDbovLhHvQrIL5TsZpilU6a1M/9xELbPGGdwVWCWyJgH3xcCRJwfi5DGX4PWmDU1p20pEwOBQEx8LgVCSciICTEer2yTA4FQ7HbKpNdTQLThfA8WawPwO222GbTY1p749VVZpaM3zUB7bnMqdPKBVhQsswf3L9hViTDxYxEW4Swk3q2I/Ujs0gDVqixXXREq19vqFjUL+oCfcXYkP9sUUEYovyxxblT0KUClD8U1Y4q8Z05eOpPfjs3t4cmj6YwzPUhfM2DWKMclVi1ASsC2B0WFEAU6/ptxGQ0QFGTw6uL1PGCDhGgGlqe6kxkHnXTY2tMGgMYJoGMw1PMRmrNK/erkLylk0u4eXbi50fX769mBcnXbv9Wl8a6Vweqcm9ImOszKjbxdcAjBFk6ptq+sMA80c8Lu7A0tR4/+sJmnPPX6kDL4tH/VcAZteiEex4ajhbHh/Ehjn9WD29B2/dX8Hyu9UW0OcntufJqjbMGpzHvT0zuaPcwcROiYxpY2Vofij9M/3pnhxESZyJlmZVBncEuCotEeLyXugmUmM7438FMMbvq49dhotgDRDyIoTi1CgGJgp3dBA+fzUaPh8GX+QqgDgWrv4Qn7arK+3TLWCThX9NVQDzZaXwdU/hcg+l8/2FP98osMgf3k6C13xhmahk0SMtFMB82UntSLqYpODlYpyhAuMGMDrEnItXV7znIuB0CHwynF82FdA5SvlFYrVKktH3YlzCqAOJp9ddv3r11EJyBxj9BKF7b0JElet1gHH/3sb31iT1A41uPB4jwiPxIXyWFsH3LROV1yXfDHlmKIjh3x18oEsY3OILC7NheQHMNsMNUfy9u/CfVj7QLgDa2xTElGZ5BpiKVKhMg/6x0DeGD4YJX433468PmBTAvBQMK8ywPrxhgDmfrKR7lowAc0mDlxMOODGWtTeq+P8Ut9cvRFweJT3nRt/6bfESrD5Cop/6XUr3cQFMeaTwZIVweVElv60sgs29obo57GgFO1OUdtlgZ5yClz0xagy6Nk7ByzEbnIh1Acxpm2oFnbXB0RjY4a8AZrUXbDcrQ/phh5pYqrUpndSqgiejoTYUaoMVwBzXIOZ0lNKpcAUxx2xwLgXONoc1QfC8wOs+8E4gbLJo4XgWZeo9GgOf9OObF4O5raVQHih0TbHT3hKGzduPOC9fzL6C2VcBoNnweupLT00ieJkUwIQ38HfC+XfBX7CGByh4iQgkJswba7gPyRYvUmK8GR0hLCzJoHZMay5MKmXvQ/2cALN97tB6AWbbnEEKYgwVFwUtOtQMvnaiqQkws3W6kieAcR/FNgJMU9tLjflkdK2aVukGMZ73MekQs1KTDjIN711qHGKMFZr6IEYHGF06wLx8e7FHgHGHGSVXW8kIM0aAeeGmYifAuFdi6hvP/p8BTFOXKDYELU1Ny20osr/2mTGaRtfRkSVVHFlSxcGlo9xUxcGlVRx6dozz9sGlVex/ZhT7nxnFnkUj2bNoJDWLRrPjiRFsXTiSjXMGs2bGAFY+2JNXp3bjpbvKeW5SGQtvKGTWkBY83DeHKT2yuK3Uwai2cQxuFkXP3Bi6ZURSEB9EpsWbuHAvogOFCF9X2Jw7pFzvZNH1yFNQmrfhcwEihJiEuAAhOzaYjsmhdC+wcWPHICZ0CmbVZOG33QPhk45wta3q6x+JVFeEx2PV1eOpBHgvmr88KHw+QPhioPBZlfDRcOHscOH/TfWC5fGwLg8WBfLLFIFFIbAuV+1H+qoCPm4Jl3Jd24svWeGiwQvj3IkUq22otmmj3RGaMuHLtrw63kauKIhJ1q5EI8S1gds4cWQEEHe5A4zumTHG/QdpJ4FwcY1ph4kQ6SWEeSuA0VOBda+NsQLk3rYy5vjYRY14PyfCtpRoyI6FVinQxgKtzcqzUhjBt12Enwd6wZN+sKkADiTB+2HwioV/PCh8UyF83Emgsw+UB2pVljToUQDdc6FLjgY0GUo94qCnja+HCD+M9eOHBwQej4SXAuHNKFgfDNssKvvkaLyClYupcDkTLqSr6su5JDgbD+e0sfdLNgW7F5IU9BxPgmM38PYYVX1JFJd/qDGzum6WjtCgJkOEXFGj2Pc0E75+LgwOF8O+TDiQDfsdsDMWdllgdwzURCntjVA6GA3HbS6dsMFJu6qinI53gfKpBPXcd7zhNYF10bA7FQ63goMt4WA2HGumqjEH4hVw1JpVe+hkHJw0w+kYl06Z4UQUHMuG2gxYHsY3DwsfThG+mCb8+pyokLrtUbAtErZGqZC8I0PYdKdQYRda+Qldc7IoTLBj9/ciMciPpGAVcJnsJSSZVOxClEkNAuip1BGiIDvI8Loa93AFaa9zsJcQF+SLPdiPhEBf7P5eRPoIsUG+OBIjiYsNpn+AMCU3jsvtEvhrzxZ8Pr6IH+7qyckZAzkxfQA1cwZTM0f5YarnDGHTnIFsnuuagN0xe0gd7ZwztM5t/X5TQWbbYwPZOr2/c+lkfWPYOtB4qsY01S/TEMismqbpgZ5O1bdY8n8NMA2NYb/iBjHOikyDCySNEHMtwBgrMi/eXMKLN5fUgRd9gskIMMbx7EXjOyA75g2jIe18vDFdW3m5nmj/pgBLQ1ufPW1sNqr2mTEcerqqyQBjBJdDz47h0LNjOLBkNPsWj1B6WkHM9oXD2TRnIBtmD2LVI71584FKXrqrlCW3dmLRxHbMr2rNI4NyuLd7KneWxjO+vZXhzcLokxVM9xQ/Otn9aWNWpe5YP1fEv+5pcb/yrs9U+99uGblLtJ8lWIQof28yYwLomBPPgPbpjOnWgvv6JvJA/ySWjxc+WNYCTubAxx3ggxTV3z8QDgcjlTfgiBUO5MD6GJhphrtM/OuecL4aJ5wfKTDfCptbwuoseEz4cozw/V0CL1uhNgc+LYOv2sPVZnAlSSXtXtb2I3kCmIt2146kCxFwKVoBzAe5/Gf3vQyMUX+kE0RddeoAo1/Z6626hgBGhwz3bdN6i0kfww7XgMXiI5i9VRspSoOXIKlrFjZWgtwh1ui1MYmaqMrxFd4IFo60SIF2GdAxR1VSOtqhLA46RvFNucDIIHghSgHMrjjYaoYN2bA8FiaF8l2lQDuBUj8FMD0zFcBU5kHXXKUumVCWDt1joUcc3wwTfhznz4/TTLAwGl4OghXRsC5IAYy+pfx8sqrA6ACjV2DOan6lSzZt43iSAhodYA5X8fIgNSqdaHg9m1J5NBneu0RNVTbh0MxecKIrHCyCmjTYn6WWKdbYFLwYAeZANByyqGPXCDBHrQpidIA5rY2Kn05UYXYrhO/naGFyKwJhfQJsz4BDOVCbrzJctoRBTTAci1WRA6dsLnA5o63IOG1RHq7TBbDCxBf3CTznqxZGPu8HLwi8FQjv+UN1OGyLVuPd2ypY1FPl4HSKENrF20jy9cLqLTiC/XEECYmByqOS5itYfdVxGemjJhqjNPALdwMYY9aRvwYv5hBfHBHBSsH+xGgQZAv1JzEhglhrEH39hNvTojiSFcbldgmc7JfDpzd04vij/Tk5YyC7Zw2iZs5gZ/Wlet5gqudpk67zhrBr3rB6ZQQYoxqqzGx7TEHM5pn9PQKMpz1MDW3G9rRIsilVmdUP6upVB2Lqg5m37lfSQcZo8vW0EbsxoDFOMdXdvaS0/A5lANYB5hqQaQBg9NuqpeTavWQ0+ip46ewEGH1qyTi99OzEutkyRoi5boDZvWC4m64fWpqyk6jxiP8R7H96RAPjzHWB5vCSsXVUu3QctUvHOSHl8PNVHHlhDEdeGFdHh56/gf1Lx7JvyXhqFo1h54LRVM8ZxsaZw3n3gb68MrkHz91UzsLxpcwe1YF7B7bmzl75jOuSxdAOiVQ0j6M4K5LmSWFkx/njiPIjLkSI8lVXO/oW6P/2FNF/syrjLerntAQJ+fEhFDdzMKI4jUn92/Hg6FxmT2zDstsSqZ7dnh9Xp8KxLvBhtjpBHU+EQ1p8+p5odYVbY4UtKfBWFD88LJwdI/z4gMDm5rCxIzxl5bfxvvxlgPD5IIHpccpQeagQvh8AVzoZlgFqW6rdg+2c4KItfTzvgAvJKqL+igOuDmTbvUJzk7o6jxV9qstEqJicLR7ddxThJr2VoT/Hvb1n9NEEigIWa4AXsX4m4vy9sAZ4EeNncnqa9HydEC+lMJM6CeiVGf3n0MFIf49aiNA7XLjsCObfnXOUAbcoBUrioGsidImEQl++KxWYEgbVdtiWqCZkNgfDdm/Y4QPvZnHxHuGL5sKPnb2hRwb0yobuBUpd8zVpbaWuNuhm51/DTDAukJ+mecETZng5AFZEwPpA7WRqUSPCFxzKu3QlXVVirmkh1QMw+6p4sb9qH8VJ3TH2poyh6+9TmgjdI4TqSQJb8+GQHfYYvC17opT0iouz8qJ7XuLrwstRMxyPgbNae+ysXfNaJcIJO2wO5qcXhb8/LHx0i3BijHB+ovDZY8IPiwRWmaAmBg6lwrEsOJGt4P9Moiaz0ulcuNwK1mZx+hbhg5sEFobAGovaVL3KpCo9q/0VML7XAY4M5qfqh5jSRsgI9iLJT4j1Eez+XtgCBXuQicQAId5fKTFAcASq23Y/waZBtlmLZgg2HIfGtqmIEBfiQ4ollOTwQPLtZrKt0c7k72g/wc9fCAgUWgYL3RzBXHYE8nW+ld/yLdA+ma9vLOIfd1Zy8bEBXHzMtfh383ylXfOGsGveEGrmKunQUjNXSYeX3wMxqirTny0GgKkvHM/YWvK4c+l3wowLYJQaAhhPraWG9i81tkByhRvAeF4iqSoyr2pyB5i6+5bqqi7U1DX5GiHmpVuLeemWUl66pdQJMrr01pIRZoytpT9Ugdm9YLizAuPJ09KU/UMNSX/u9QKMcUrIHVzc5WoXuSowehVm3+IR7Fo0gu0Lh7J57hA2zOjP2of6sHJqV165owvP3Nie+cPbMGNAAff2yuXOrmmMK0pkeJsYeuRHUpoWQOtEf/KtgiNMRftH+bri/Y0tgv9LSGkKwASJEOEn5NiCKG7mYHjnVG7u3ZL7h2cx9+Z2vDrJwZoH8vn4+XDY2VpdlV5KhUvZKpSs1q4ApjocNgbDW1GwLIAv7xb+OV1gXQ5sbQXzIvhhkvDTKOGfIxXA/HyrFywLg605alP1t72UYfJqqssL01SAuZyoHv9oMBwsoqp5KFnayTFGhHDxJly8VYtHA49IzU8R6+uS1U/J7K1K7+6VG73VocNplLeQEBpAfLAf8cF+pESFEhfk67FNFWxyrSrQP68DjH7i1t+btiIMtHjzaWY0v5U3g5IMBTFldujmgK5R0M6Hv5YJPGCGXcmwO0XBy+ZgBS9HzXC4G588KFxKEz4tEChLhJ5ZUKFXX/KhS57LE9PNDt3s/HuEF4wP4eeHfBTAvBIIKyNdAHM4xgUwF5NUFeZCsmofnUvyDDDnHXAkQQHMzmE831cZrmMNr21joK+/PlHa17QUYdHwVNiQAYc6qjHkvTEKYPZF1w8wtTGqqnIqQcHLsVgFMMe1ls85h4IYI8CcToDDCbA9gt/mCmdGCweHCmfHCx9M0wBmUzCcSINzzZUutICLLeFKhlapssOVeDiTD0fS+OphYccg4eKNwp+nCDwnatv05hBYLrAuBLbHsG2SsGaMMLNrEC1FtUjtJiHGS/ldor3UMRvnrWDF7qfAxRGolBigHovVFO7tOvZCxQXs3iK0zUtnWM9ysuzRxAf7kGEOJT7YzwnjYSbt/dDye8rjA7mSFMTX+Vb+nRnOLzlRnOyZxiej23Li/kouTO/PjjkDrgtgjBWY3wcy2li2W8qvEWjcW0uefDKeqjJNCclb+5CSsRLjXo1pCGI8bcK+nm3YrupMfasLlF51gxhdTQUYT5uw64xeXyfA6BDzhysw7hWX3wMu9T234WWKSgpijOAymsNLqhoFFyPAHFxaxYFnx7F/6Vj2LK5i11Oj2PHECKrnDWbjjIG893BfVj3Qlzfv6a5GoG/syPyqQh4ekMftFZncVJbM6I5JDGkdR0WemZL0UFrFB5JrNpESZsLur0qxeqy/0RzqPsXiyevS1ImU31tdachjoXthAkX5NVKifWmWHE1Z83j6dsrmhl453DmikNlj2rLo1lKqH07h05U9YHs67M1Tm3bP5qrJi6PxalJiRwSsiYbX/OG5QHgvBTYVwexQvhsjfD1C+H/DhR9GCp9rHpl/PyzwVgIczoOve8AXLVUM+0W7Jn1DtVlTgjbhYtUWPGrP03fvXC2AP3dg24xkSvxVeyHL5FohECsqByPFT+WMFIQKLSKFVtFKBRal7CghPUyV4+3+GtT4aJNGGoSYRHCECIXpsaSEmUiN8CbFEk6Y6dpRbPcQPf14cD9u9BZfZxHGxHrzTVYklOVCaSZ0ToeyBOiaBF1ioZU/f+kgcKcZttpgVxJsD4IdwSqj5HwunBjOjinCCoewIU+gYxx0z4CuOUrluUplGRrAxEP3BBjuAzeEwoM+sMAAMBsCYXu0Gus9YfMMMGcdDQPMiWTYPozFPZXXx2IAmMZ+H/SprwRR1ZtphcLXb2SqhYv7E1T1Y28c1EQo7dEVrsDlQLQKlDtuc8FLbYyrlXQyThnUz2g6G6d0RtuEfi4VjsfDei9+eUdgS5AyNB/PgVP5cLwL1LSD9T355Z1yfl7fl/+8PxCO9YOzQ+FMIZxqC2eK4W0LF24SLt8qfHOH8LepAk8LbAqDnWZY6wsb0mFzNve2UHk5GaJ8Q3oFyjjBGCCqihittTQtGpzH+alWklERGkzrQG8L8CJUOy4nDOnDgPJOpEaHYPZ3LUkNFuXli/B1vR/pfkLnRH++cPjzfW40OELAEcI/c6OgXQLfDWkFN3fl4sO9ufJoX7bO68+2+QOomTeI3XNcILNj3jB2zh/Bbg/y1FZqDGjcx7Jd+TKu+1vcWkyefDL1TS41VpXRAaYuxPRweWOm6UZfzxDTtE3YjVdjVt7TjRV3db1Gb97ZhTfvrGc9gRFgJnf2qGWTijQ15I8puiY/Rq/M6B4Z9y3Yz97UkaUTOyD6Lp76dC2wjKijxsafG2sNNXVHkXvuig4sRnhR4FL1uwBGtYnGsOupUQpcZvVnzSM9efve7rxxdznLJpWyZHwhj49sycxBuTzQO4vJZfGMbmdlaItI+uRFUpEeRLt4b5pFqxNbWqjyuFi8XMZDT1uJjd6G/wuAcd/nYwQY/Tn6CcHsK8QGCWmRQvOEQLq3jKBfxzgmdo7hju4OFg4Q9szO4ddVFlhnVyexAwkqjbXWrkr3+2NhezJsjoctObA0gG8nCeeHCp8MFD4eIHzVT/iij/DFGAUw390tsDwGdqXApY7wUxf40GDmdQcYfXxar8BccIOYK3lqSeTRW7m7vQKYTFEnylgRbCYhyV+NijeL9qZ9nB/FjhC6pIXTPSua8hyl4qxICpODKIjzITNKVdriAgSLnxDlo65Cg0QoLUhmcFkbUsJM5MWFkBQd6ny/6wMYf8OxoBuEjS0kkwYw4xMC+LGlDSpbQlmWqsKUJyqAKbdCcx++aCUwKdIVhb89CHaFwPFUOJkO27py8JFAdrQVNuYLP7cIg1KH+n5dsl0AU54JXbNcADPCF8aHwUO+LoB5K0pV2XaYGwYY9wrMxTgFMGe1nJOTKfy8vjfzy1wVMv11aezY1itiCSL0dQRx5skoONIbDjpgn9215dkdYPZGqH1GeuvohF3pWKyCl2OxGtTonhVNZzXD+Hkt4+VssoKYc+lwIQMu5qrt6ude04/EAAAgAElEQVRbwrkWsDmfr54N5cr8VD5+MosPFrfg0qICLi2J5ZuV2XC0BXzSDY534K9PC3++X/jXXBM/PyIwV5T35f1QZQTeGg7vZ8LO5swuUWsSskXtwDK2OY3tSj2LSJfuedErNLp0ENefoxvQw0XIsEaQFBmEIyKQSB+XhyvKV4gOFCL9BR9/9Z6kegvFjgAXwCSFQlIof8+J5Ke8aM4Xx/N1v3xOTOnClUf7sm3+ALbNH8Ce+UPYM1/By+75w5znpZrHRzrBpebxkdQ8PrJeb0zDEDPwGnkCGve2kiefTH1A02BAnkH1wUxDrSV9maSnjdhNAZqV93TRblc4oWXlPd2uAZr6TL71AczyO0qcAPPq5M4eKjLFdUauPVZlDEDjvkRSh5hrAGb3gpF15A4sTQWY6/G0NF5t8WTQrS9g7toKjO53URqvaQK1SydwcOkN7Fk0mu0LR7JpzmDWPzaA1Q/14bV7SnnhtvYsnVjIk2Na8NiQAu7rnc4t5UlUtY9haKGdfi3MFGdE0DbBn7wYP9LDBVugunKJ9FH9Y92Uaww58xSIZtR/E2DcR3CNagheTIbbxtwT/eQaKuoEnRxhIssaQBt7KIWOSAbneDG1Mpm/vdGGf6/uDGu1Xv26QFjlCyt8VMn7GR94ysT/u1U420etEfhwmPDhcOGrG4T/TBOY5wNPmGChwFIfWGWDaiscyoBvOildzoBL6S44ca4WiNXkULoYrckKl2Phimb+/bI/V5/3oSxIhXTlipBnUjCT5+tKIB2QFsbIglgmFNq5pVMSt5U6uK3UwU3FCYxqHUWvrFDKHT60s/nQyiJkhKvQQf2Pf3nzVArTY2npiKIwPdZ5teq+wsB9lNrTe+pl+Hx3Ee5M9oGiJOiRr9pHpRnQNQ26pUOXVCiM4afWAmNiYE0KbMhSEHM4G84Ngw1tObakK0cWl3Hmsd5U39SSb/OD+U9xvDLt1lGq+t6VduiZCMN94cZweCQAnrDCK0GwMgo2aABTa1YjwxcSVNvvcoqWz5NUdwrJHWAOxcOpdH7eOJApBQpeYsTlw6jveNc9RwmiqmmjEoTtD+fCATscSlS5LnussNsBuxJdZl0dYHTTrg4qx20ucDlhV16YE3YXwJyKcwHMebvyWF3UoPpyIlxJVMflqRSVAXOyF6zL58NnSvnq5R58+do4PltWxZUXxnD5+SpOPFXB/llFfL6sGK4+DPsq+WJhFD/MF3552leZgp8TeEtgR5Qar94ZDJvS4UAbnhsUqQL/RI2e60nT7q1NY1tIf9yYU6S3i3QQ1KElWPt8hEndTogMxB7mR5iX+nsXG2wiLsSLmGBvLEFehAZ64yOqGtQtIYCvk/z4R340JIVDYiikBENKMP/OCoXmMXzfJxfGl/D1/T357uF+HJsziKOzBzgXAO94fBg7Hh/GtgXD2L5weB2Q8VSJabTF5BaUpwOM+333tpInoPG8Dbt+kNnwSB/WPdKnDsTUDzO9PLaXVhsg5veAjAtmKpzSAcYIMfWuKHCqtI6W31HilA4w9UGMp8qMe46Mp03Yz91cVBdg3OHFE8DseWKkm36/IVff9twUYDm8ZKzb/apGdG21RQeYw0tu4ODTN7DvqTFsmz+E6rmDWP9YP96dVskbU7rw4qROPD2+BXOHZfBIvxTuq7QzuczG+MIIBhUE0yfLl26ZgXSwC/lmIStc9Y2tXq4rFPcpFU+Vlv8lwHgKWzMCiv459ykX9+cYJ6CMP3+QuMytkaL67A5foZm3UBgirL1R+GVtKWyKh+okVe5+Wfh5pvCvx4Rf7hO+u1U4308BzJVBwlfjBOaHwatpsDYHdnWAHc1hXZqCl3fj1HbdbTb4oAD+Vgof5iiAcVZiLE0DmMuxCmAudYGL5czpa6Y8WP3shSFqn06zAKEwUuiSGMCwHDMTC1OYUpHDw/1b89iwtkwf2ob7+hVwe9cURhUmMrCZmcrcGEpTw2hm9Sc5UJveMgnpUb5kRPvRKTueVknRzlK+O8C4vw8NAUyIlzDIV5jROkaNNnfPVbH/xRq4dEuHyizoZOfvzQX6+cNKO1QXwJE8ONcGNrTl46fNHFlcxpXXB/L31ydz6tGefNcshH93jINuWdA9R33slqXgpXuGgpdeDhjhBxMiXADzajC8Y4H3Q9TG5KYCjLNSpj12wA4nUvn3hgHcka3aRzHaa9QQwOgn4jgRCryFpcN8+G7tKDiSrMzju8yqfbQrUWlPtNLeSCWjafeEXcFLbYwCmJPxqp10Mt5zBea85rs6Z1OTQxft6pg8F6ttVM+Bdfn8+QUr373ej3+uHsHf3rmFT18exeXnFcScWdyTQ/NKOP9UC9g2Clbm8fVTZn5bGggvR8BLJnjFG9Z4w95Y9bNV+ymAOdSOJf3CaCNqtD7VACm6H8sTwOiAo6dE6y0n3dOlf50ON/rz4kN9ybRFkREXSZR20aYDTFy4H7FhvpgjgvDzUruoKhID+UtaED81s0ByRB2A+SkjhJ8yQrjQOorPSx2cuqE1n0/pxvG5gzk+dzC75w+h5vGh7FwwnJ0LhrN94XAnwOhyrm0xVGaMQKPfrgMybgCzY84gj1CzecZAjz6ZpsBMQy2mdQbVBzAKYnp5hJg1mtxB5vphpvL/BGCaNoJdxAu3FnvciC27Hx+NUTULqupozxOjG5ECmd8LMJ7kCV6uX55BZt/TVex+ciQ7Hh9B9ZwhrH+0L+/e3503pnTjxUmdefqG9jw+siXT+uQzuTSJsR0SGdU2jj65FsqSAmlrC6CFxYeMcJMKm/NVSbl6qdW4qdgIHMaWjLGq0dQqyvWAi5/2hylMM6BGmNRJNMrkuorSpQfl6X6NILfPGysDnipJeoKsng1h18KvukcKexdUQk0bOFoMZ9JhexjfvCj89VWBt8P5dZk3n08ULo8UfpgqsNwOGxNgUxKsToJVDng7Ed5xwPpseD8XNtphgw32ZMLH3eCrjnAp37Ds0eq2pVpvJVlcumjV4MUKF/Ph8/b8uL41DxcJIxzCqBShR5xQFimUxwi9HD6MyIlgQtt4/lSRwYzBrVlYVcyiG7owa1h7HuhdwK1lGYxpa2dA83h6ZltoGxdCso8y/1pMgi3AhwxzOM0TbdgCfOqAi3twXkMAo8OLvwj2EGGyRXhvaB4MaKZC5orToTxLtXm6ZkHvNlCarVYHtBJ40gzbSuFkd9jTgQ+XFHHhibZceH0SH62awjdv303tvIH8pVU43xeaoVuqmkiq1NQjA3pnQV+HUlUg3BQNj/rDExZ4LRjeNcPmMAUwh6MVwFxMUGPvV9wBRpNz/N2hPCUHEuBYGn9fM4BbUlT7IsbwGrm/LnruS6yoyktbER4qFv66XOBQmmob7bTAzhi1FmB3ktJei9K+aJVZczgGjttdU0dHrUp6BeZEglohcMqhdNqmeWDsWivM4SY7XI6HK11hVzZ/faEt/3y9M39//3a+XTWeT1fcxKVlYzjzwnBqn+rLgdllnFrUh4+fK+erV3rw9XMd+PalIljRGt5qC2+mwcoMeD8LaovgSCxU+0NNPhxqzXNVUYzNEIblCx3ChGTNf6dHIejHmf56GYHGaEL3FNxo3NYebRIcoX60SImlZWocFj/tcT8h2RxEiiUYR1QAMWH+BHsJbX2EoenB/JAfws9tzJAeAqlBkB4MqQGQGqiUHAgpQfzSygoVuXwzpYLvp/Xh7KxBnJ8zhH0LhrFvwTB2PTGMnQuGsvfx4exbMIK9C9Teub3zR7J3vgtq9swbUUc1c4c5P9bMHcbOuYPryAgwxttbZw+ketYAJ8C4w0x900uNtZfWP9qf9Y/291iFUSDTp46cEDOtD6un9WHNA71ZO62PR5D5vQDz9tRK3p5aycp7ujkfe/Oebk55NvrWTfh9/a4ylt9RUifpV0/1vXYPk0v1BeLpyyP/P97OM67KK/3aG6WD9I70DgIiKoIdRQVFpRcBsXfBbowmsRsVROy9Ye/dGDuINYqoIIgtzUySSc+kTDLX+2GfxhE0M/+Z98P6cUBRlMN5rufe615LCS/KFux/G2BKl+VoSdEE/W+sQDcGLv89eGkYYMqWD+DC0gw+XJzKibkJElwmdmXj6EiKcluxKD2Qd/r6MCWmOSOiHMkJsyCxhQW9fYzo6KxHaytBoJls+22uK5NylVH0yjsZzRXD1x3p/LdzXZShaaa6MhXT0VQXNytjfO1N8bU3xd/eFD87Y9yt9GneTAcHY+nTcDaUvSW2evL8WzlSNhbqLRjlC5pmLon25ED5IugkJMB4CcGc3gb883QgfNQFXoTD42BFwqq7rAeo6QwLTOA9fdjhAiWusEEPigQs14VlTeR5//uCP9aYwW4XONlc6qwbVLaDrzvDizaKO3uP+i3VVdZqgKmyaRhgHgZCbSg8G8TVefrM7NqMSZF6DG1lRbqfAX09DEjwNiLN34xBYfbkdXHj7T4tmJ8awfuZHZiT0pZpcUGM6+7PkPZupLRypU+gHe2am+OhK+HQrqnA0aAJnhameFqYqi4Mmv+vjR0hacOrchLWTAjCPO3YEG3PswUDIL0N9PJR+FW0AKZHCHRoyr9CBD/MbAJnO8OdHvyy242aonZ8tS2Oz47O4JPD03m5K5/bi5P5vp2NGmB6+0v1CVDASyD0d4cEDxhoAiNtYI4RFNlLgDlgK7fNNAGmxlVm9ygBRrVG7VEfYB66SINsuQvc8+PHg/0Z6iovwg5CDczaz39lWrKzkNOXLDdB+fvd4ZoXlHvIbJcrDnBJocseUmX2Uldt5br/HWe5NaXcOLrjVN8H85GThBhtgKlykc3ayiThWneo85Dw8twDboTz605zfinpDIfi+OrAEF7uyeXZjmE83pLL/fUZXCuMp3pNEo/WpvB0TVeerO7C56sj+Hx1BN+u9uL7tb78ucERdnioAea+uwKqOvDb0eacfDuUi/MiOb4wg21TezJzcCIdvWwwF/ImRbMNXelZUf6Ma+cfaU4Dmyg+R3kkZSUErqZ6BDhZ4GVjLD1fTeUExtfRHG8HM5pb6GGmLzDTl/UNAwIt+LmlOX9E2EGABfibgZ8peCvgxdNQVmD4NOP7wGb8I8SKBzlhfDm5Jw8XpPBwQQqlS9JeCzBlCohRTWUW14cY5fvqLabUVwBGG2bOK8L0ZK2BLJnUBpi/CjTa05njsxM5Pjux3iSm/lSmXz2pYGZmf6m3+yrUh8Nv91GBTENTmYaARgkw+6fGqaQEGE2oeR3AyMfqoDzNwDwlzDRWU/D6zSW1NJuwlVo3qhPiPzfpSoApK8qmrCj7NR6WzHpqKK/l/wIxmv4W5ceurxxI2YpMrq7MonzVQC4WpnNuUQYfzEvl0DsplEyKY82YGJbmRjEnsw1vJQYzsU8oo6J9yYzyon+YE9H+dkS5m9G6uSUtbAxpbm6AraFMo1W2P2uCSkMek/8WnGiDirJUUXP91lLIaVALS0Eru6Z0cdWjl28zkkKtSA23I7OVFektLUgLMSMx0Jg4b326uQii7AVtrQStLATBJgL3JvICYCPk2F7ZjaI5WtY8T9e8YzMW6vROSyFoYyl4uMgTrmTDw7bwpJM0zr5oBc87wsNwOGYNewzhsLl8u0pAocL/Mlfw83h9Ph8oeJ4t+HqUAf+cYwlbQuBMK7jSAZ52gk+ioS5IhtQ9clRIcZSkvDCqjigUAPPIWRp7q6yhzhFqOvPTUXuOjHNidZIO8/o0Z3pnc4a3NSA7WJAW0IT0wKZkh9gwOsqdCd1bMrVXayb1CGBke1cywm1JCbUgzt+SaHcjwmz18VBEtdvqCOyMBbZGsv/IUPF9VN7RGor6gKi5oab9/VeWPvoZCGJ8jKmbYAPrO0K0DfR2kevOPUKgWwj0aAmxIdC7JSS5Q1czfk00hcKesHsgLI3h4doEvjw4nC9PTuPlscl8tT2PioUpfBXrzrOONtIM3Mcf+nkr5AUJ3pDgColuMMgQRlvCPAMotoUSYzhsA2fN4JIN3LCUcfuPlADjI9frqxR64Cn10Fmh5vL3l7vA/UD+caQfg5zlc9FV4yKrDf9miotqCyHzXi5PFnA7Cm55ym2jUkuFz8VMrVJzKLWWGUXXbOU0o8IJ7jrKQsU7NjIO4L4LVHpAhZvcjKrwhLuecM9LHilVukrTbrW3omFbEdpX4y0Th58Hw7GWfLPVlW9KEvjtcBbfHMrjs53DeFIyjNqtg7m3PoPyZfHcX51A9boUnm/oybP1PXiwsAN1y7rzaVEEnxZF8HyuDy/m+fJlcRi/bOnEL3u6wvHefL0rhcqC9pxf3JeqHSOo3DeP8i3TOb91EZNSOqliAAyEXNNXTvGUKdBKgNGewmiGMyo9Ms2E3FxqbiJwM2uCm1kTmhvKLabmJgJ386Z42RjjYqaLrb68UcrQF0zx1OFvwYLvWgto2QTCmkKwDgQJWTTqbSABxtcM/Iz4w0uXP0Msobsfvw7vCBNiqV2QSO2CRMqWJlO2NJnLBalcLkhVXZ/Kl6ZTrpjSlC1Vb81qb9BeWJKuCMirrwuLUuo9VoGMwjNzVqMp+6xGV5PmhKaxleyGISaRk7MTG/fKvNOfY7P61dORmX05MrO/Qn05MrOvRjhen/8QZhoGGCXE7JzUg92KtyUTYzRgprFgPCXQNH70tE0jHG9LA2m/mpUFG8Z1Zf3YLvW0dkxnNcA07nX5/w8wbwqha9icq4aYsuUDuFiYyvmlyXywKJFjs3tzYHosuyZ2Y/3oriwf1I556a2YEe/PuBh3hndyIjvCmeRgS3r4mtPZzZCW9noEWAi8TOS0RTNYTNl189+Gk78CP5rHNaZCGues9QWuJoIAO306eZrRK9iR7PaejOwRwsS+rXgrJZJ30yJ4J7Ut76W3Y2Zyayb2CWZ0dx+yo1xIb21Pv2A7evmaE+lkRKilXB320he46MmNHFud+pMm7a0G5Yug8nzcQ8g75iWdBb8f7CU9F9XtJLw8CoArbnDKGo5awgdO8KEznLCBQ44yDO1dwRejBM8zBPfiBGVdBVc6Cy73EjwfoUjnPdMKqtrCZzHwoiU88v9rAFNt+6rpt7YLfBRO3bqefDDVm22jIlmdHczsBA8mRFsxtK05mUG6pPiYkOZvRkaQPQOCnchoYU6ijyE93HXo5iLo4mJAlIMOQeayKdlBTx4jmStCwZT1A9oj+b8KMMoVag8dQXyIFf8sCoeNnaGLJfR0kPDSKwx6toJe4ZDQFlKjICcIBofCxCAY4813U4JhURc+2TWQb46O5pND+Xx8MI/PN4/hxnt9eRnTXAJMdzfoGwgJvtDfRwEvCoBJ9mgcYM5Z1AeYWreGAabSQ0oTYO7awQ0PqPDny5JuZNlJiHbUuMgqJzHKnxVluWNHPcHyDA846Q032ingpQGAKTWHq1Zw1Q7K7SW8fOSsgBcHCS/37CS8PHBVg9Y9Lwkx97zggZ8Elwce6n9PtYdatT4SXqq9+HabOz+UePLz/nT+ODaQbw7l8XL3SJ7tHE7t1sHcXZvKtaK+1GxI4/HmDD7eFMvj1dHUFnTlaXEPXhZH8vnydnyxJJhnc7y595YD99924tw4fa5ONed+YQeeru1J7e4x1O0dx83tMzmzfDTntizkvcFxOBvUb55WTmxNdNQf006ZVgKM5oRVeSNjrydwNpYA427eFDdTHdxMdWhuIiHGxUwXFzNdrJoK7AwE6XqCad5N+aGt4NcOehJeQoUEmBYC/E0kxPiaqQAGH31+9DHk9xbm1MV58ENuBA/nxL8CMFcK01TXp2sFGQ0CjPZNuioWZLGUcstJKe2jJaVn5tyitEYB5nUTmsYg5tScJE7NSWrc9PtOf5Xqg0xCPYBRh+P9ZwBzYFpvlbRhZs/knuyZEqsCmN31JjLdG03+/asBea8DGOXj1wLM64y6ja5Fq8AlR6GGj4caghbtYsTGfu3V1ej6Jt2GAObaihyuFGZw9v0kjs/pw/63erE9vzPrh3WkOLsNc5PbMqN3MKN7tGBglDt9w53pFWxLRx9rwpwM8LMxwNtSF2djRbS24gfWUONF838VPNcYwGgaapVmOic9GUAVbCWIcDYgxtuIhFAbhndyZUJsAAszwlgxtCNrR0aybWI0e6bGsP+tXhyZFcfht3uxb3pPtud3ZvXQNhTlhLIovQXv9PUiP9qJUe2tGdTGkmR/PWKcBB2sBG2bCVoaCAJ0BX5NJKC4CnlkZC/UXhpTIUHHQ0+O/bvqCE5OaS1j2+/1gBdRcN1TroEWCzihL9eqrzpIL8JpV1gv+G2S4PNBgo/7CR71ENzuLCiPFHwQLjgZKriRIqAwHMo7wbNU+KQjPAqXZtFqhZn3kQJWqmzU661KkFGtVFtL1QZCTQD/PNuJ2nUuXJ3fnnOzwtk1JoIV6T7MifdhShcHBrW2J6OFOX19bIh1M6OTox5Rdk1oZa1LqGUTQq2b0sJCBx8z2YLc3ERmw5hqwYum/0BTmn1KDXk9lP4FPyEY1dkWdkRCgRd00YdOejJ0rncY9GoHPdpCbDj0i4LMKBjXB/K6QzcHvoyygEFtYcdEOPoe3+2Zxnd7pvGv93O4l92KH0Kt+LWNgyxw7BMCCYEKeUKSFyS5SA3Rg3FmML8JrLCA3Xpw1BwuWMqk21tWcN8J6tzhiYcGwPjJFeNKP6kHXlKVvnDfD+50hivhfLMtiZ0ZJszqZMCUtoJUb0GkgaxQcFY8B92E3B5rJwTLOgt+3tlGHu1cbaaGlSsWaqNuqaX0u1x3kJ6XWw5w20nqjo2cvlRYyDJFJQArv767/lJ3gqDcSxY1XnOVwHXHV/37HvpAXQt4GQcfuvJifTjf7ukK52fw++nJfHkon68OT6Bu9zCqtudyZ00K15f3o3pdAvdXx3NvRTT3VkRTuSKLe8UDqC7qT01xIs8L+vNwbgwXJwZzbUYb9g925eLUVtxbk84Xh/J5fnIBH22fzJlVEzm/firX9ixlx7yRZMa0IszFqN7riYHG80w5eWkm1KWYzbQ+Zq2ARHsh8DQSBFnq0MJWl0CrJngay6275rqyPNPdWOBj3hQ3Ix18zA3I1hMUR+nyrxGCP4cL/pUk+DlW8GMXwbftBT+HSRGoAwECfAzAWw88dcBd8IufLrSz5cdBbWByT6oW9aX6/X6UL03lWkEaZYUZXF2WSXlBBuUFGZQtTae8QF7btG/S5eMsKZUJOIPLSzIoXZLBlcXpKl1elMqlhSkqqQ3AGZyb/6oJuKGNpg/mJqikri54cwdTPZjRABlNmHk14bdhgGkUYhTQ0lh55J6pPdmr6F7aOSVG9bZkcnd2aoCLssZACTQNAYzmkZM2wGiH5L3SuzS2az0pj5REw6vR/z7ANO5raRxO3qQ3bRndXD2IW2sHq6ScvpxfnMzR9+LYPaUzm8ZEsWJQS5akhjC7jzcTor0YHuFIcks74nxNiHTVp7WjDoHWAi9TmdtirysvyMppg/LCohkg9v8bYJQXNStdgYORwM+qKS2dTekV7EhyOx+GRvsxoV9r5g5oT+HwHmzOj2XntP4cmNmHUwvTuLB0AJcK5ffrxqrBXF8zjLLiXC4W5HB2UQbHZqey962+rB/TnRVDO7I4J4rZyWHkx/gzsI09yUE29PEypbOTAe2sBaFmAn8DgaeewL2pTPq0UYCMtY7ARUexCSIE40MEfxz2htvRUNUSrnnABgEbhWzRveUKN5vDdSe5dl0g+GGs4LNcwSf9BY97Ce50FXzURXA9WnC2taCkpaAiSwf2esC9WPi8K9S1VbdQvw5gNIPtam2lagLkBeejRH4+0Y66TYk8XN2b0kXJHJ3WjY0jOlOYEcaM+JaM7exJZkt3+vrYSHgxE7RoJggwkZMrb0OZAeRrLnBtJr1Fyi0Q5bGfiZBN1JqrrZoAo21WVT4vlHlCAUIwNzMUjsfx5yJX6KLPPyOFzG2JDYWeEdA9HLqHQJ+2kNIG0tpCrCu0MuBRgODT1sZ8Mr0nfxTn8rdt+fzj0Cy+mdGPsz2c+cLHkN/aOkKMnwSYxCCpJK/6ADNY980AU+ko6xseu70eYKp84IG/1NUI/jzqCSdH8NvBgfz6wRx+/WAOdfveZe/UPmSGNSdAATDuQoa3DfHT4ZMVXnA7S05+rjZTTFms4Kq1VKmlfHvNHm44Smj5yFlKCTD37BTwovG8eegjv8b7wVARAGds+dc2IRvT9wg4YyFhpsJdATHe8DQUPonh77uMeLE+nN+OxsGVd/nl5ES+PJTPx7tG8HjXUB5syebWyiTKCvpQURzHw7X9qF7Xk6o1PXiwKofKFVnUFCdSuyKJlyvTeDS/F5cmhfDBWD8uT29N7fJ4arbk8vmBcbw4tZCydaM5WjiGY8vGcqhwEpe2zefg2vlMHthHdQOmmT2kNP4bCoGbviDCVZ9OPuZEuBriY6ZubLcU6qJHNz2Br6nA01gCi/IGprmuwNtUEGxvQmtXKwJtTAm2N2eoqeBYpg8s9oT5LvCWJUwzh+EmkCGgqw6/ttYAGH8jCDAGfwPw1eP3QAN+DzTgSW9XfhrSlvvz4qhZ3J9rBWlcK0jj6rJMri7L5FqhGmIaAxipxgFGU9ogowkw5xekN+iXeV2uzOl5CSppA8zrt5gSVKoHMq8k/PbVOFZqHGZUQDO9Dwen93klJE8JMMrHu6b2VPUvKUFml1YPk3YXkzLhtyHvTMnEGHmM9JqU3/ogE83m8dGvgIzQBpfSZVmqt1KNA8zV4oaPkBoCmP8uvEiA0YSXW2sHc3P1IMqWD+DcoiQOz+zBtvHtKM4J4/1kf97u5U1eBweyWjvQ38+EDq5GhNsKnBV3yCY66ohy7ayUJhpv/xfg0hDAKFeWlT4Tu6bymKi1owEdPczpH2hBbpQ7k7u5M7t/MIVZYawb3p5dE7tyaEYsx2fFcmZOPOcW9KOsMI2bxZncXZPD/XUDebR5CI82DaNmy3CqNpf80kgAACAASURBVA+javMwHm4cScXaIdxePpibywZSviidU2/1Yt+4Dmwd0opVmUEsTfDk3RgnJre3YEhLQ1I8BX3cBd3sBS2bCXybyAuKi+Ki4q640AY1Eewb1ZSfjsfDpWCpIyZSdx3hgYv0HnzkAIet+HmR4MuhgrpUwYtYweNugoqOOnzUXnAn2oi73Yw5Ei74sKPg4/mW8EEPeN4LPo6DGn945Ce3P6odJLw8sIYqR6lXknkVeR1KE/CDtnDZm7/t6sLHWyJ5vD6be8uTOT8niUOTurFqSDsWpgQyuac3QyJs6OtpRmdrQUsTQYihwNdA4G8sgwwDreWY3VLUL2hUrqUqIcZER10hoJ3SrHl0qCfURsywpoJtE6NgZ2v+mGsFnZvyaxsh82Bi/KF7a+gSBh2DoEsIRLeA7sEyy6WTB4RZ85uLoMqrCZ+HW/H3gZ1gRga/dA/kvrs+uBlBmLMMrusdCokBUv8uwHzkJI9YnvrDswBZ5vjIR8LKQy+Z0HzfCx4ES7h90BuudeLXY/348WAc3x4czY9HxvHTqan8cHIKfz80gX+cmcHN4ixmRJswpbVgbrQpm5IFFQsd4JKz7Ba6ZqeQvUK29QHmuj3cctIw7TrAbVu4awMVtornjK26kuKeHzwMgruRcNSZP1YK2GgI2/TkWvN+XThtCTccpFfmgR88bQXXOvByoyW162P49cwQvj35Ft+cmMYn+8fzaNtQakpyub85kztrErizJoEH62Kl1kbzYG00d9YncWt1fypXZ1GxMpNn64bz0cJkPpzagePjW3NjcQK3C5Kp3TWFFwdnUn1sGbvnDGREz5Z0cTci2t+OcUldWTl7InPzB7Fw6hgi/V1k75bitcZYyClWpINg/oA2rM+PY8OkBNZN6Mf87Pbk9/Ilp50DicGmdHAQBBrImxefpgLvJgIvHfmz7irkTUtLC0FskANdPM1oZa1PhKMpuZaCo4OcYIMFbLGGjSaw1QK2WcJaQ5ijx+9DBX90FfwcJSBEQLCAFvpSvgbgow8tTCHKia8GR/D7hJ7cW5pMxZIkrhW+Ci9KgNG+xmkCTOnSzPpqAGI0QeaVfBnto6ZGYEY7HE8FMo0Yft+YKaOEGO1wPJVH5s0Q0xjANJT4q1kgqdmGrQQX5bTm3wGYHRO6s00hTYh5M8yoj5iE9tRFDS71AebVraIcLTV8hPQmOPmrAHNzzcD6Ukxfbq8bUk83VuVypTCDk7P7sHtyJ1YPasPi1ADe6uHJ6AhrEgPMiHYUhFoJ/IzUdxXK6Yo2TGi68P+XANNQyJzSI2HZROBl0ZQwV0tiQ5qT0TGIvNhQ3kpsR0FWFOtH9aRkYk8OzOjHB/OTubA4k9KCdMoKMygvyuD26oFUrh9M9ZbhPN42gsfbRlC3fTRPdozhyc6xUiX51O3Io27bRGq35FOzcQwP146gYsVgbiwdwMV5KZyeGc+hKXHsHt+N1UPbMz8xUJVInNnWll4+unRw0yPSWYdWFoIWxoJwY1mkN9JPULehDZwLhFNecNIczjvILpkqd9nqe88ZTjny62I1wDzpIajpKrjXqQkftRdc79CUO9FGnGonON5GcH9KE9jZCu5EwOd9pRemNkBufzxy1JjAaABMvSMkZX6Mh6JwsD3cbcV3B3tSuyaMqlXpVK/J4HpBDhfnpXBgRj+2je/OkoHtmREfyMDWbsR7NKODnRFtzJvgbywBxt9CyslIDTBKb4FmAq+JjjxeMtFRF3tqVwboaACNmeJzO5oJjsyJhZ2t+eltY+igw28RAtq7QmdP6BQq1TlYQkxHX+gcIPNiuvlCB1doYUaFi+CKuWC3o2Cvk6DMUlDlaQhBdhDhAV19JMAk+DcMMG86QvrISXpDnvjB8yCZ21Ot8L7cc4dKT6n7LSTEXO8Mp1rww4FYfjrch+8Pj+Xv+0fw2e4RPN8+mI9LhvNixzCqNo/g9socHq7MpmpVDl9tD4fzfWUh4k1vKLeVuqqQElxKLaHcRg0wd5vLr/G6ldQtC7hjpQaYRy5Q5QQVvlAdDCfcqH1b8MlMAXts4ExzOGABuwQcMpR/1x0XeBgAdaH8cdSXx0V6PN3Ui1/PDOHvx6fyt8OTeLZnDJUbcni0YyCVmzK4uzaR+5vSeLS5L5Vre3FnRQfur+nK3Q0pfLQukbsrMrhZmMzDZVncnJfAB5OjOD0hgnvFGTxal8vL43P45uz7XN7wFmN7eONvKH1SnkaKVOlmcuOwd1QoQU7m2OjIiYmREHiZC9La2lA8oT+nC0ZwcF42B+cP4dCCoRxaMJSD84ewd+5gdszKYtnYeKYmhjM02o/h3QMY3j2I0b1CmZrciXG9W9PB2YjuXpZ097Um2FzQ0kqPCEdTspsJ9mVaS4DZbg87bWCPA+x1hH1OsCsAiu1goCH0EBAmpEcmSE/K10CqhSm0tKAuyZ8fRnXi3tJk7i1NbhRgtK9n6tMFxVbtXwQYJcS8GpaX+somU0Mr2dog88F8OY3562ZfbYhRTGMaAJj6Zt9XQaY+0MRzaEb8X27B1gaZvVp6ZRozuadKmjCjBJrtk2JUENMQyLwJYsSrR0avAkzDa9H1AaZxI+6/M1V5DbAodGttrkJKeBlUT3fWD+HGqhwuL0nj9Ow+7MzrzLrBrViU4M/UzrbktDShr7sgylreMVsIeb5rIOofEWnqf7VR9DqA0VeAlb2OwN24CR3drekT6smo6EDeTulI0aCurB0dy578WI7PTOHs7CTOz5NnwdeLc7i9Kou7a3K4sy6bB1uG8HBbDlXbc6naMYSqHUOoLhnOo50jeLxrNI93jebBnrE82DOW6l35VO/Kp25XHnW78ni2ewJ1JeOo2jyCyvVDubN2CLdXD6JseQan58Vz7J1Ydk/uxPoxERTkBDI7wYtJ3WwZ3NqQzBaCVF9BnLMgwURQkmMFh4LhZGt5t3pFedzjCpU28NAeSp35fbXgy1GC2kzB456CR90E9zoL7nYU3OwguN1Jh4tRgqMtBDcH6cKaSDgTClXx8FkU1ISqV1kfaUCLplQAo8jrqHWSqvaBx/5wsQOPVphTPieC24s6ULZoMKULczk1N40DM+LZNLYrS7PCyO/qTnaIGfGeBnS1E7QyE4Q1E4RaCkIs5ATGSqf+yqrmqrRmDozm1oc2OCs/17qJ/Px+9oJz8+NgSyg/T9Hjj0hdfmurAxFOEmKifKFjgOxG6uIL7b0h0hPaukq1sYcwawg0B3c9PnMQPLMSfO2swz8DLSDYCtq7Q7Q7xPlDoo9UkodCzlJDm8L4ZjBPB4rNJcAcs1QDzB1XeVxUFwTPgmVZ4QM3OaWocJN5K5WuUNkZrrfh9yN9+GFPd749OJafjubz5dGxfHF4NH/bN42Pd+TzeO1gPlqczJMV0Xy9PYFfd0fx29728KEl3HCDG1ZwzQJKfaSUAFNuLVVmqzg+8oK7gVARAbfD4VobuN0eqjtJQ/fjUKgNgeoAqPSGynAo9+O7+YLr2YIXEwWs0YOT9nDOFY4YwiF9KLWRTdr3g+BBMN9u9qJ6vgmPNyTwzeFhfHYon08P5FG3fSSl7/flyZ4x1O0eRdX2MVRuGUHVpiwebx/E/fVJ3F7Rh2uroihfGcmN4kRuFCfyUWEaZfP7cmJ6Fy7Pi+fRphHUbR/LtxdX8/J0IYVjk+jsoouboSDIpik2Qv0apy+kt8XNSPqHDIX0EiW1smbPjL6UrR7NhcWZ8g5/djLHZydzYk4KZxcN4OziHC4UDuHUoiwOz05h76xUzhYO5+T7wzi+YAgXVkzkw+V5rBzVi/QQU9o1E7RrJog0E0SZC5LMBCfyg+FASzgUDseC4WQonAiQOu4iq0dWWPDLKMFv0YKfOgpoaQgh+hBkJBXYDFpYQJQr9G9N3bwEni9K5vqybG4U5XBzWTY3l2VzvWgA14te7dpTL6TI611ZYQalBenqG76CAXItuxGIUSf+ZnFxUSYX309WSdmkLfX6oyW5sVRfmsdLr3pl+nFydl8NvdqKffzdvo1sLDUMMa8DGG2IeR3AaPtm6oHMlFiVAVgbZt4EMNsmdK9fHJnfrR68bMmL/u8AzLUVua9Zg379ROWvAowaXF4FmDvrXwWZW6tyubosk3PzUzgyI5btY7pSlNGSt3r7MCrKlv4BVnS0l3cl9rpqw5peAxeP//XRUWMA00zI1lgfcwOifR1JjQpmct+2LBoUx4axvSmZksKxt5M5OzeL0sXZ3CgazN11w6jcOIKHm4ZSvWU4D7cOpWbHSGpKBvNoxyCqS4ZSXTKURztHULNrZD2Aebh3HLV7JlGze0I9gHm2ewLP90zkxd5JvNg/lU8OTufpvkk82jmOh9vGcmvtYC4WZXF2cSrH5iSzc0pP1ozuRMHAcOanejIjzo7JIYJ3IwWfLTGG42HwoS2UuUp/Qa073LeVa813fGG34Ns8QU2G4GmsBJjKLhJgbrSXEHO5QxOOhwiO9BT87T0vOOAFl9vB03B40gqqmysyOTQ2kFQbSo7qTqRqFzXAPHaGh54SYu7347OtzTk23osDo1w4PCmeY1P7s3daHDsn9WDz+GiKB0cwtacvw9rakdbCkj4e+nSw16GdjaC1XVNa2ag9MEpvi3ZQnWbmixJstCd+OkK95WXTVP6+dHdBeWESrA/k2zzBP9s15Z/tmkJbR6lwNwkxnbyklAAT4QatnSW8BJtDS1sIsuAHH1N+8DHlJy8j/giyhJY2EmC6e0LvADXAJLor5CQBZphufYDZqSsnMJespTFbCTDPgqVqvGVb80fNFXKUAHOrHZzy4uvtnfh+dzd+PJLHj0fy+NuRMSqAqV4zjBvz+3GvII3PNsTxclMfft4ZAce6y02jchcoayZ1xathgCm3g5tOcNtPHjVVRsJlf5lke74F3IuAJ91lttCTMHgUCA984V4Y7DGiaozg3nDBl28LflogYK8JlPvDFUeZNn3FWnZ+VfhDhT9frGnO/TkGVK+N58v9uXx6II8X+8ZxsyiFI1M7cH5RHJeW9FVtad5ekUjl2jQ+WhnPreI47m7qxrVVUdxZncad1WlcmtObg+MjODG9C9UbhvD5/il8dfRtfryyjnvbpjM0OoDWVgJXA2m2FUKdlq0EZSddCTDWQpaUvpvdiRsb87lQNFSVUH6laAhXioZwedlgzi/O4dSCARx5L4WSqb05PDuFMwXDOFMwjNNLRnLy/WEcnDuIkhnpbJmSxPIRMcxOi2BK7yBGdPAmI8SOoe6C0xNDJbyciJQA80FrONMCTgbCCVf4wAtOhcMaW8g15Y8YAWFGEG4CwaYQ0gyCLaGFBT8HW0I3Px7MjOXZgiQJL8W53F6ey62iHG4sz+LG8lfzydQQowYYTZUXDKgnbZhRemYuLc6SEKMBMPVh5g1HSgvUEKP5+K/DzL9n9tWGGSXQvAlglG/3vBXL3hlx7J0Rx+5pvVQw05j5VwUxCoBpCGJKJsZQMrkH2yfFqKQJM39lIiOU69DKkLqyooGUFQ1UPdbuK1KDSq6WGstw+evTldcDS30pj4zurB9RT7fXDeP2umEaj4dwtTiLCwvTODazD9vyoike2IoZ8W6M7mBGWqgx3ZvLHBR/fbX5VJlMq7y4KH0w/+40pqGJTkPSrhNQBnNZKC5agVa6dPF3IrujL+P7RjAvqxMrxsSzZ3oCJ+flcK0wl1vFw6hcP5LqzWN5uGU0j7aPo3b3OB7tHCMhZsdIeWy0YwzPFKorGUVdySj1UdLO0TzZOZrnu8YoNIrnu0bxdLeU8v3nu0bxbOdIHu8cS23JGB5tH0PVttE82DyGyg2juLl6CJeWZnD83Tj2T4tm//BANqU353J+M37Y1gnOe0NZkCz4q/PWWG/2gwtm/PiuoCJLUBcnqOoueNBFcLe94Fak4HaUoDxKcLmNYG8rwc1EHX5f4wDHW8PdEHjWSXotqrykv6Va0VZd4yi9MTXOCt+LqzrQThVs5wQVNlDTBso9OZHfhEXdBHN7eFKcGkZRTjhLM0JZmN6GuSmtyO/mS06YDWkhFsT7GNCleRMibQXhtoLWdjo4msjnkub3uCGzthJgGnt+KbdGbJpKEBrqL3iwdgAUh/FymB6/txP8ESUkvLRxgCBXCHaHcA+I8Ib2PtDRTwJMuBO0dIQWNuBnJlNRfSzB2xwCrCDIBsJsIcoNunnICYwyBybBQyrJEZKdYbiAPCNYIKDYCEqaygnMJWu46gg3XGXb9csoeNZKNjTfUkTg37SD6wESDsqT+XVPW15uTuSHfdn8eGwa3x2ezOeHx/PySB7PS0ZSurA3l2d2oro4mW+3xPD9tp5w2heutoZrzvLvKzOXKrWWuuIiVabQdSvFmnQilMfxYlMK+0e4szTZlyWJPmwY1ooP5ibw3YFceLJcdhc96A9lwXxTKHgyQvDjLMFvcwUsFrDfDK4Fwg0XuTp+zVrRWO0Lt72oWuDAnXcseLCmP18eHM4nh/J5uHUw5+bH8cHsHtxemcOtFdmUFqVzuSCVq0V9ubkqievFsZQWxHBtTQeurori7tp0KtZlcH5ub/blt+PkrBhKlyTxxbF3+ePqCj47vZIrKycwtEcrgs3la4dtE1m+ai7UR+XGQhpy3YXAT08wsZc7J5YM5nJBOlcKM1QX/tJlWQoD7AAuLM7k1LwkjrwTz6l5KZSvHMadjXmULR/Kh0tyOfxuMjunxLJram92T+vLwVnJ7JuZSMnUePZMSWDzmJ6sz3Ll6sJY/lbSn+/2p/Hrnv78tjcBDnWD032gtJNUmR+cc4PVxvyYJ6CrPUSaS4Dx14cgY3mMFGINIdY8G9eZH2YncWFlDpdXD+Le8oFUFKlvrsuLBmgpg7JCten36rLM1wKMJsiULc2sV10gQSady0syVF1NaohRHy29DmDOzktWtGIn19MHc5Pq6cychHo6/V6i1Oz+nNYCmYY6lxpqwtY0/Won/h6Y0VtVWbD/rTj2v91bBTB7Z6iBRgku2ubfvwIwOyf1oGRyw1LCjCbYKKcyysf1AEYJLkpdXZ4r1Wh6bn2AebVsUZnf8u+BS2MAoz1hkfAyTAUudzeMbFAVG0dI2Fk1jGvLczm/OIej7yayZWJ3VgyL4J3UVoyKdiGxpQPdPAwJs9XHx0iaZi1F/VTKhlaoXxdep+mheZN0taTcRFHmXjg1EQRYNqWzmyGJrZwZ38Of99KjWD2sE3umJ3BxQTrlBQO5s2oIVZvGULNjPLUleVSXjKZm11hqd46iducoCS8lY3mukBJYtAHmmQpiJKw82TmSupIRPNs5sp4e7xzLkz15PNmjnNpM4umeqdTtmUL1jnyqto+jYuMIHq/OoGp5Ck+WBvDNpijZj1QeLM2zSoB5YC1NuPfcYZUJj4ZKgHnUQ/Cwq6CigwSYW5GCskjB9Q6CgwqIqZkq4FAoXPeTAPNxqJykVCsL9hoBmFoH9cbSI4Xn4aET3G0Bde348XAX3o4QjGxhSF64OePaWzCqrSkjI+0YFWVPbrgdaYHN6O2lR4yLoKOjDAYMNpeyN5STtP/rMWQTxfNBeRw1xE9woyABFvnzyeAmaoBp5wytbMHNChxNwcUE/GygpTNEKCYwbZpDGxcIc4JgGwi0gBYOEOwIIfYQ6qAGmBhPmcCrDTDJzpDmAiObwHhDCTCrTGC3vuIIyQpK7SXAVPjINuZ73hqTEEt5sS/3g5uBcDqGv28K4outSfx+bBi/nZmlApjne0dyfWl/Dk+K4Ma8HrzYmM3323ry58EkuBAsAabcqWGAuewsVeYC5W4yGfieM3zQkTtvCaaFCxKayS2mcCEIFYJ2TQTDPAUHR7vClU7wxTA47szn8wX/eE/AUgHLBKwRcMwWrgfBLXe4ZKv+d93yhHIXrk835uYMU6rXJfHF/qF8engid9dnc3h6R7aOCuH8/H5cfj+R0qJ0rhSmUbYsnvLl/bhW1Iuywh7c2tCFK8URXFvWn/LCfuzLb8eGQQGcercHj7aO5LPDs/i9rJgnh5ayOT+eDq4meOvL1y97XXUruq2unATaCrne791EEGIq2DAhlgsrx3JuUVI9gLlSOEAGvik68o7P6c+Rd+K5VDiQ6p1TubMxj/OLczi7OIfTC7M4OT+T43PTODY7nWOz0zk8O43Ds9PYPz2ZY+8O4Nw7XfhwZmcuz/Tn/HRvbs7wpHSSMzemmvDFqkD4sC1U9IaKcLgTBmeCYaMlpLaA9pYSYEKbQag5hJhBC0vwNeHB4DZ8M7MvF1fl/mWAubosvR7AaOpaYdZrIUZVWaCQcnvp8pI0FcRIqfNlGprGKJN9ZSN2ff0lmJmdJKUAmsa8Mq+DGE3Tb6OVBUqIeVstTZBpzPSrhpk4lTRhRpUrM6VnowDzVyYzDQKMCl4UANPwerQSXAYp1Fjw3OuPhP5TgJHwMoy7G4Y3IiXEDKdi4wjubRrJvU3y/ZurB1G6LJMPFyZycFYf1o+JZE5GC/J7OpEVYU7fAB3aOQqCTOVaoYOQdzHNhNqLoAkamn1AmiCj0wCYvE6aMKP8c5Xrt80Ud06O+gIfq6ZEeloSF+5FbpcApqR0Ytmo3myalsGReQM5VzSa2+vHcX/bZCp3jKN6zwRqd4+jZpcmoCghZHQjkr+unLQ82zlcS/LXn+4ax9Nd43iyZ4JKT/dO1FA+z/dN4Iu9E/li70S+3Z3J1yVp/OtYiLzjqvWDJ4HqCUyNN9T5wgknPp8leNpP8EixiVTVSfBRpNSNKMFHHeUm0v5gwc0cAdv84Jy7fBH8PFIWPj50keZcTYCpba4hO6ixlb9W6ySPnGqc4I6jjLp/1JW9QwVxloK+NoI+rmbE2BvQzdGA7s6GdHfWp4eLIV0c9Whvo0Mba0GYmSCgmcDfVPZQGf8XAEbpibJSPB8ynQWnp8fw51vePMvU54+2uvwrUh/aOUKEA3iZ8w8rwXcmgn9Y6vKv5sbgawPBDhJmWrpCqAu0VModwjzk4zBXaOUsj5y6+0LvYIj3g37+0M9TKtkW0p1gXFOYpJjArDGG3cZw2EpOIy5aw1V7KHdQwIQFXDSDy+ZwxUau0F+PhPIIft7Tm8/Wtufl3lH869J7fHd2Ni+PTue7D9+lcuMgDo4P59jkSB4V9+aL7QNgXySc7A4XPeGyt7rTSJn3UmYJpRYSoq46wnU7uOkA9zvCOV8OToggy00Q2ETgK2SekaNiMuEo5FZOmBCUTnOFmxNglz+/rHOGNc1grRls0oXtxnDWFO64y226MjNZU3DVBW71guvdOTfJhcvTPHm4cSCfH8jjk4NTqdkxlnWDAhgRKljUz425cc4UZLalZEI8eyYlcHBaKmfnZ3CteDjXiwdTVpDN5SXZnJufxrJUb/ZN6My59xO4t3k4Lw6/w1cfLOLiyimM7uyOh4HA21jgaalPcxMZuWCrL3DQlxBjK6QHxlcIevuYcHp+KpeX5XL5/UTKlqZybVky15YlU16QIU2xRdlcXpLB+fczubQkm4c7plK3bxa3147h3KIBXFicw6UlA7mwOIvz72eqA9/mZ3BmdgrHZ/Xj+Kx+XFyQyqWFaVxZ0Jfzs2O58HY3Tk6M5Mjo1uwf1pIL08N4srof/9gfC6eS4dIQuDgYZsXyeZoXH7e35WUXZ/7ezZWXnRz4o7UTv4Ta8kW/FjC+DxVFudxbPohbKwZya8VArq6QvXfXlVJ4Yq4XDVAZfq8VvgowyjwZ7cmMWgPqmX4vL0lrRBn1IEY77VcFNMpW7AWp/z7EzEngzJx+nKnnj3nzNKbhrSXtPJk4lQ7NiG3UG6NUQ8Zfqd7sm967HsgoYaYhgNk5RX5MCS7KjyvBRflxFcBoT17+LwDTYFruf3A81DCwDNFSfXip2DiCio0j6gFMxcZRKnC5v3U0VdvHcX/raCq3jOL+1tHc2zSS8jXDOF+Yxb7ZyWyc1INFQzowIyWEId296d/KivaeRoTYClyM5UhW2SliJNSZHtoTGu3G5/9EmgBjpLh4KSvuzRQTGR8zQVs7QU8/CwZGOjOxTzCLc9qxIS+Oo+8mcn5xDuVrBlGxbTRVO0bxaOcYnuwczdNdY/4ywKj1ZoB5vm8SL/ZP5sX+yTzfN4mneyfyfN8Enu+bwMs9Ut/tGcAP+7L582gwXGwvAeZpkNwUqnWQAPPEDz4Kh41N+DxNUBMneBIjqO4s4eVOlASYG1GCshjBpWhBxVABmzzhlBNc8YFP2sBn7RT9SK6vB5haOzXAKD0yD9zgrhN83Js/TrmR4CDobiLoatWUDmYy2K+NiaCNqVS4QqHN5J2tryITRhmC+H/1SDUVEoSUANPfQrAxO5Avh1nwKEmoAaaTG3TxgEA7frIQfKkn+NpQ8I2p4EdLAY664G4CHuZSXhbgac7Pbmb86mEJAXYQ0lwNMN18IK6FAl4aAJhJRvC2JbwvoFgfdhjAQQs4YwrnLeGiJVywgHOmUueVspC6EQUXQvlsbXs+W9ue3z6cCdcW8tWpWXx/bg6/XFnAuQW92TbEjwvvdefZ2kT+tiMLDneCMz0lwFzykkB0xUbC0WVzuGIuAeaKnZzO3LCXOS8VUVQuEqQ5C1oLufrrKeRNioPifQ8FvLRpKpjZUlC5IBi2e8PeINhiC3tc4aAtHLKTEHbXQwLMVXMJLzc94XJH/jgUyKFh5pyf7EbVply+ODSRz468xRfH3mZZmisd9QSpLoJYC0GMlSDVS5Df3okZ3b14P9mf9cMj2Tspmv1TYigZ34VNIyIZG67DiZlxXF+Zzd0NQ6nb9xafHH2PjRMSiXYQODeRMOZsLHAwkCm4Nnoym8lSSN+LrRC00BfkxYZSVjyYC0uzKV2SQtnSVMoLk6QUYXA3VwxSTAzSub5iGC9PLKSqZBpXlw/lwuIcSpcNpnTZYK4UDuTy0hxVC/TFRVmcnZfOhYUZXFqcxe2VQ7m9cih3lmdyfUkyZbNjOT8jmmNjIzg+wSjiYQAAIABJREFUrh1HRnuxa6AjR0focW6COS9me/PtslYwpSvf5rbgh94+/BTvx2/9g/h7N1eIdOPXlnY8i/GCUT1fAZjylYNeAZgby7NeAZhry7NU05mryzJVjxuCFwk1A+pBzOsARhNitGFGO+H3wsK0RmHm9UAjA/I0g/He1IRdD2w01rGV8HLsnXgVvByZ2UcFMMqJjBJY3mT81QSYhiBm9+Se7Joaq4IWTf3ViYxQ5rgoc12urcjVMObKo6GGvC1KcLmxarAMRtMCGFU6biPgojLb/ocAc3fDUIXU8KIpJbjc2zycyi0jqNwyjIfbRlK5ZRj3tw6nattIhUbzcMtI7q4bwfXiXC4szuT4u33ZnhdD8cDWzO4fRF4nJ9KCzYlxEoRbyvVgl6ayHVcZra2M0ddcldU0ZmoCjjasaMbHazY/axb9GWn9+cqobwshc2x8zQVtXU2JDbIjq5M/05LasmREHFunJ3NowWDOFQ2nfMMEKraOp2rXZGp2T6B2zyRqd+dRuzuPut3jtDRGJWn0HdmgnuzJ4+nefAWsTFLpxf6JvNg/kef7x/F8/zg+2TuBT/ZO4Ou9o/l672h+PhTNn6d6Q3UYfNxeEevvBLUesvCvLgSu2PBTvuB+f8GTXoLaHoK7kYIKhZH3dkdBZV9BTYrgswkCNnnD8eZwyhUeBMHnHeFFCNT4qo+SVACjcYRU6yA/Vu0oQafaVk5tHjjDQ0d46sHWoYIeRoK2+rq0NzEi1EAQoi8IMZAKVijIUMrHSMpENFwJ8J8AjKGQq9ZNhKBtU8GkLk48SbXnYV9zaGUOba0g0gk6KSYojk343kTwrZHgO1PBD2aCP60F/7IR/GIt+IeV4HsLwd9NBJ8YCD41EvzqoA+B9hDeHKK81AAT7wf9Ncy8yZaQaQ/vGMNie1ilL7VNF/abw4lmcNoczpjAaWM4bQAfGMGHFlJn7eG8M5TGwKGW3C/swIuNcVBWAOWFfH9mHtzbxMsDM1g/MISDoyK5uSCVF2ti+W5XOpwOhA9D4KIDXHaCK1YKWahVaikNvVfN4boz3PHg5ZY+zO8oCBQyzdhe6GAl5I2JuZDGVw99XcItmtDFxZzBQTos6OfD6YnhXJ7ZiU9X9ubPQ8PgRDp8OFB+/fdT5fFHWWe4msV3+7tycmY7FsQbM6mjOe/2cmLr5D5cKB5N9e63+fjYQkqXZNDfXhClI4+uAhUKF4IuRoIklyYMCrJgdFt7JnR0ZUaMG9OimzOxozUHp/flWvFQ7m/Jp273NOp2T2NKQmu8deTWoqWQkz8bXYGlQhY68nXKUnFz1cFKsOvtXC4XZHH+/XQuL02itCCZ8sIUygtTZDjckhRuLM/k4oL+lBVk87fjc/js6HvcWTeKa8tzKF0qJzRXl6mPXUqXpFG6JI0ri9P5cG4C5xekUrN9Ik/3vcXttSNUk41L81O5OC+FC3NTOTOrP8fe6s3R6XHszYtgx6gwdg0OZO/wEA7Oiub0gj5Uv5fC3enx3J+bStnknlzICedwPy8u9fDg2fCuPFyWw6NiCTC3V+Zye+Vgri/LVm0nKY/GbhTlqD5+fVk215bnaCmr3pGT9iTm6rIsri7LUoOMYnuptCBdBS+lBekagPMqyNSbxmgATEMg82aYaSwg79XNpRPvxdfT8Xf7vNEvo5rINHCspClNv4zyrRJg9r/Vpx7AKB/vmRLLrqn1pQQY5WPNyYwmyCgfi1cTdV/vbVFDymAtNdJR1MjE5c0TlsaApb5eCy8aAHN/63AVvNzfOpyHSm2REPNoWx412/N5uDWfuxtGU7Z8OB++n8OhWRlsHteL+ZkdmdAjgMx2nvQJtKGNswkBFvJIR7MjSLvTRjmd0XuNDBqQdkuxdveQ8n1VuZoQuOgLAkwFLa0FMR66pITZMr6HJ/OzI9mQ34O97yRzdnE6ZauGcHfzSB7sGEfNrvHU7BrfKMA82TNOoTENSsLL6wHmxYHxfLpvIp/um8jXe0fz931j+PlQNL8d7SFj2T9uD888JSw8bC7biqsDpNa68vFACTAf9xXUdBdUdRFU9RLU9RXUpgqeZjTl84kC1ntIgDneHC47QF04vGwt16L/CsDUOEONg1S1mzQY37aA5158fSSOcWEyWbitvi4h+oIWumoF6kn5K+SlLxN5DcV/Zw1f1Z2kI2GmpRAMaWlMRawJd3sZqQGmnYMEmPbe0pDr2kzK3Ry8rcHbQiFL8GjGH06G/Gytw0tTCTA/WAl51NQQwPRTrFMn+UKKNWTYwbsmUOQCG5tJlRjCXlO5VnzcBE4YwHE9OKnQ6WYK2cI5J/iwAz9scaeyoD1f70qB0qX84+wcfr24BCo3U74kk8X9XDg6rhN3Fg/gq62J/HFsiISXcy3VAKMy7SrBxVrqkjGUmsq05/MWHBxuTZqFhJdADYAx0wAY16aCEBNBlL0Ric6CRGfBUDfBGF/B7FaCVTGCI7m6fDTLg+9KfOFqLwkwV7tSXezPkhhBbytBV0NBOx1BBz1BjKNgYLgJW/K6c6V4ONWbx3J0eg/GtzEmzVXQVk/gI+Q0yF0IgoWglRBEGQg6Ggmimwm6GAvGRjSjtHAopctyubNuDHW7p3F/y3hSwmxxFvKY2Vrj36Oc2poroEbp6xsa6crRBWM4tyhNBTBlCngpL0yhfGkqV5ekUF6QRumSFO6tH823ZxbxcGs+11cO4XpxLqVLM1UXc/XGjmyLvrwolbOz+3Fn7QheHnmP2l1TuL12BOVF8qJ/dfEAhbIpXZjJpYUZnJ+Xxvm5vTk9K4bLs2K4OieOY7N7cmx2Tyre6su9Gf249XZfbs6I58HkWG6P7crNhBY8HdaZe0syebJmuApgbq0YxPVl2dwszuVmca5q+qLcVrpRlMONIm14kQCjKc2pjASarHpSgo1yFVslrXwZtVdGG2a0gvH+bYh5FWDeBDL1gebNfhklwGj6Y7ThpSGokZOYPhyYEa+CGG2g2T0t7hWI0YaZ101lRHlRfQq9XpyrkBy93Vw5sJ5urcpVaDC3tACmoW6iN5tx/3OAqdg4rGFoUahyyygqt4zg3ubhKnCp3DKMyi3D1BOY7WN4tHMctSV51JbkUbNtHLXbx1OzPZ+qreOp2DiOa8VDObVgAPtn9GNTXi8WZ7VhQmwAgyId6eluSFsLgZ++HD/bCzmZUb54KI+ANHNANIPK3gQwmiWJJlovSJr9JMr2aHsh47xddQU+JoK2jk2JDbJjUEdPJvZtzYLczqzO78/+2QP4YNkoytaN5samPO5vy6d612Qe75tM3f4p1O2fUE9P9+fV0/N9eTzdO74BcJmseDyBF/sn8uxAPs8PTuDT/dP4dP80Xu6fwud7J/P3Axl8dyQbLreHR4nwaVuobSGL/yqdZfx8rQeUhcBywctBgucDBH8bIPg8XfCsv6AuXvAgSfA4U/D1ZAGr7WG/Ixx2geO2cNUPXkRAXZgEklpPDXDxUEiR/6IEm8fOUlXO8MARHphCpTHUdOH8VEF3A0GUELTTF0ToClroSakAxkA+F9x0Be768nv531izN1J8vx2FnLqFCEGijeBKS13udrSAUCuZ7dLGTk5hIhzkqnSoHYTYSmNvGwepCCeIcJeA0qo5eJvxp70u35sIfrIWskyvtQO0d5MAExskASbeTxp5+/tAgi2kOcO7zWCFB2wxga3NYLch7DGC/fpw0AgOG8MhIzhkrHi/GRwzh+P2cNoZDrbnZZErFQVd+XLXAH44NZOvDk/hnxcK+P7EXLZlB7I83pErk2OpLRjMP0oS4HiuLAA96wwXbOCKvVxfvqIJMLYK301TuG4M97vyzRZTRrY0IUzIn1VvXV1sFP+vyp8xWQqpg4uOwMfYgDBzY0JMDWhlKGhlKIgwFLQzFnQ0kRoRYcG85GCKB4ezZEALkgN1CVR8n7x0ZJicV1O5tuyuK4i0Fwzp6svy3A5sy+/D+YWJ7Mxrz5x4L6Z0sSOhuSCyqfz+hgpB6yYy2dpeyKOtcR2t+HBJLifmpXB6UToPdk7iYlEOXT0NVT1pFuLVSbC+4t9nLuSK9YLMSE4uGsEH8xP5cGEyF99P5P9R955RVZjpH+1L77333hVQsGBHRQVERBDBiiiKCoIgNuy9995iiR0BG3YFsSUmGuMkajR2o+nJJJM2Sfb98J7GEYzJ/Ne6937Y6xyIRhHlbJ7ye2oW96Z2STq1S9K5uDidmgW9OD9H3hu6/dZInh+cwPvrslUv6rVLMurcHrq4OIPaRX1kAu78dGrmp/O8opQXhyZza8sw3l+XxaVlGVxc2kfjxT6d6oVpnJufwqk5PTgxM5Gq6fFcXd6PmxtyqJyXxv4ZPThf2oOzE7tztFRyYWoPLk5PoXxCJ/YWteVIaRdOzUzi/OxULi3M5NryLK4uGcg7y7N4Z3kWV1YMRL7WZXF1ZTZXVmQpnmfVef1T/ngll5cPqsOlpQMl9VRiapeoj0iqUW4v1S8wavo2KDP1C03D5wo0E39fbTHVlZo3Fxg1BycnaDx/fXXmQGkSB0qT2DepO/smdefAxO7/3xSYV8VFGfH/1/LyTwRGysubCYyyAqNZhVEKzEfbR3J7Z56Ul52jubMtjzvb8ri3q4h7u4q4u2scH28v5sZbxby3eQyX1hZwctFQdk8dyKpRiYzt0ZxBMT50C3agpbMBIVa6+BjVvd5c35XX+qRFU1y0f45mxUX5RcpaQ2AcFDgqvtg5Kx49hSDASBBlJYj10KNXY3Oy27gxoUcwS4e2Y8/kJCrn9KF66QDe2ziCj94erZCYMdzbX6ji0/2jeXCggE/3j5bP90m05UVTYJ6UFfPo4Jg6AvN52TheHCjhm4N9+ba8P78ej4QrsfAgEp5Ewy13eN8RbjrLFs4HreB8CCyy56thUmC+6C943EvOxnyYIvi0v+C3mfqwww+2mMmAsb2mMmTsTjg8bSnl5Z6f+qjgfV/41A8+9ZDcU6IQGOVRyPv2cE0P7rSHE17kR9gTJWQLRykwjQ0FYQo0BcZTr/6DjP+rwNgLQYwQJFsLKj0F77QwkwIT7QjRDpIoe0mEo9w0irCFJvYQ7SQlprmXrNK0DpDPg+z5w0mf/7rqQLCVFJi2PnKINz4MugcqJMZPITH2kOYC0y1hpTdsNpESs9tIsldfst9AcsBQgTEcNINDDnDMhT92R/NogRM3l3bkyz39+apyHN8cnsCvZxbxwaps5nW2ZlOGP9empnJ3URbfb03k933pcMxBSsxZOzjvADW2kgvWihkYW7XAXLeGD9pybbKgs7msbISYmhJkZIy9qNsCtlL8u3IWcpbEV0GoEITpSKkIF7ICpnweIQSROvJshpuQ1Z0APbmmHGAgCDGRA92NbOT7OvkYkhmsz4gYe3bmt2TPmDbsHtOVitKe7CpMYFnfaEq7eDOlmy9Dm5jR1V7QSAhaGAnmpodRPjWVvRPjObt0IDd3FHJ2aX8Sw2yxEupbRcqvMZptayPFxxflbsG6kfEcmZvDsRk9OD47hXPz1Zxf0IsLC9M4M7sHZ2Ykcn5OMh9vHcHDPcVcWdGfmkV91G0VxdFE5Qv2hYXpXFiYzsnpPXhn+UC+qprJk7LxvLd2ENUL0xQrzBkaw7JqiTkzN5mz83pyfkEvPtqcy51teZxcPoBjS/pybZ6kel4fzs7pzaUZvbg8M5Wq6YmUT+hE2dj27C1sw9GJXTk7M4VLC/txdclALi8ZwJWlA3l31WAFQ7i2eijvrhrC1ZXZGq93WW8kMCqJ0RIY9Rp2XZQCo12FUYqM+rGfSmK0ZaZeodFYzW7ooGRDN5g0KzTyIrY6+beh4d/KqUmvICXmr7aXkupIjGYlZv+ERPZOSGSPQmS0eROhEXXD6TQHdpU3jF7fQqq/6pL9CtqR/8otor/TLnpVXnL4cPMQFbe2DH0FZcVFKS6abaRb24ZxZ1sud7blcnf7KD7ZkcedHaMUbaVc7u4cyd2deSo+3j5Stpt2jOKDzcM5tyidE9OSOTIpge25bVmcGsz49u7khJuR5C5obymIMhY00pFbDR4KwVBWaKzqkRll4Jm2yGhXYDQHei2FlCVbIUvENkKu29rqKMrGijwIN3OBn4MgxM2QZv4mxEU5MzQuiAmZrVlV2J09s7M4sSSHy5uKub1jHA/3T+XpwQk8PjBO1RJSU6ji0f4CHpeNlije9+TgGJ4cHMOzsgKelRXwWVkBLw4W8rx8NM8O5vP1wZF8UzGKnyt7wen+8FF7eJQoj/1dd4YbjrIK854HvO8JR5xhoeDL4YIHfQWPswUvcgWPsgSfjxCw2Q2ONYPZgv8WKDI6dtjCO4HwohPcD1JsOHnBp95SZB74wENPeOwDjzwlD9zgvovcRLrjAnfc4SNn+FcIvGzD3TmODLEUdBCC7kLQRgja6wma60vC9eXtJ09dKRv/6+VyZSsgWghaC8EYIZgsBOV6gjM2gqdu+vwU7giNneTtomgXBY7QxFauR4c68mukEb9GGvG8pS4v2xjyINaeR52cZDWmrTdEuUGorazWRLlAjAd08IduATLIrrufJNFXkuAIqd4wzRGWBckNpA0WsN1EskNHslPA20Im9O4zgv1mcMAcyt3gsBffbYjg7kxnbi7ryhf7Bqv+njzbUcSuIVFMb2XAzgHBXJ/egXtLuvPvLZH8ua8NHHKHY95w0laGIp6zllRbSJRXp2sc4W5jOD2Exe2lCLSxFDT3cCbQ0gR7XV0shPqbB+W/N+U3CcpHWyEHYZ11Zbikq46UHEchcNYRuOnIbxjshMBFX276eBpLvEwEvlYCP2sdfEwEYfY69AyxJauVL6NaOZHX2pnidvYUt7NnXs9AlvZpzOrBMWweEcuc3uEUtHcmxVvQzUlQEufKlrxYthfHcWHNcG7vn0D1qiy6hljgqCEwyq8lyoUCZRvbQgjiGnuwa3wvDs0cwImZyYr13l51OD+3F6dmJnFqZiLvruzPl4en8mD3GDm/sjD9lYqDcvaldlEfahakcWpGMtdWDea7U3O4u3M0V1f1l5WdpX00VpkzqF3Wl5olGVQvTJe/7oI0rqzoz71dRfxr6yjVfbv3lvTn2qJ+XF3an8uL+nJ5XhoX5/SiZnYqNbMV6bazUjg5K5Xaxf05s3gw55YOoWbZME4vyKJmcTZXV43gndW5vLM6V7bBFFxZmV2nKnN5+SDVo3bl5fLyAXWERS0ufbTIrFOJ0ZaX+ioyr5uVUQ7+Kq9in5+bpiCd83PTOTs3gzNz+qg4NTv9FU7O6q3iuAZVM1NVHJvRq87hSOXxyEPT1FROTVajFY6nkpfJPerIi2YVZq+GwGgH4TUUiqd9pkB5qkAohUVTXuqeAKhvNbp+gVEeVPynAvN3xEVJfdLyTwTmzraR3Nk2UiUpmkO+Smm5s2MUd3fmybyTvcV8vCOf21tH8/GWfK6tHM7Z2ZmUj0tlY3Z7piY1YURLd1ICbYh11CHCVBCsKCU7CXUFRbNV9HcFRrMSY6OF8n3WOgJbPZkFYW8gcDQWOJsKfK0FQY6CFs6CWF99MqJtyI8PZNGgFmwtSuD4rD68u3YEd3eOlum75WPrFZhH+wvkc4XAKMXlTQTm64Mj+bG8J78eSYOrUXAvDp42lreR3rGWl4EvO8nvpM/5wWEnWGUOcwQ/T9Dh20LBw0GCP6ZYwZGmUmAmC74YJPiuQMAKHajxhHst4cvm8EnAqwLzyAue+sJTH8kTL4XEKNpJd9zl/MwH/nDDD84kcW+uEys7WjE+WBBnIuigLzdWIoX8LjxURwqM/f8oLzpCVgF89ATx+oLe1jost9Vhq7cVH/jb8UmEB98GWfFLpDNEukJTDykvTZwg0gYaWUKYE4Q58WukET+E6vAwSvB5WyO+7unHNykB0NpDyk6EkyTKRebE1Ccwib4Q7y3pZg89XKHYDOZ6wGpjyUZd2GoAbwnJNgHbBezUkSF3u4wk+52g3I2XK4L41xQ7bq1I4It9g3lxsJAne/N4b2FflnZ3Z3ILHfYNacyNmbF8PL8b32xsrBaYKh84YaOQGEvJWTO1wFyyg4vO8FEoz9a2ZaS7/Px0djSktZ8nIdZmuJmYYCvU7VzlvzvNrT8LjbeVg7CacmOv+DftIqTguBsJvE2lvHibCgKsDAi008fPWgd/C3mpvKObPukRzgyNsmZUKyfyW1qS18KC0S0sKIyxoqCNPcWxzpR09mRwE1PS/AV9AgXFnZxYPTSGtSNac2HNcN7fls/FtUPpGeWEvVBXaTVTnfU03jYVgp4xIeyekMr+0nSOTEmkanoSJ2YmcXJWMidnJXNqdk/OzknhxLRETs5IoHp+Cs8OjOfmhhzVsKqqBaSYeVE+Xl6SyYWF8nLzg13FfHlsBp+8XcDl5ZlUL0xTicvl5fJOm6bAVC9M59Kyvnz01kju7SrivbXytp2mwFxZ3I9LCzN5d2GGZEl/rq/I4sNNI/h422ju7iji/u4Srq7P4/SiLGqWDePcoiFULxpM7dKhXFohubIyW4pLPQKjibbEKIeWtVet/0pg6qvAvK6l1NDqdX0Cc3ZO7zry8k8ERvn82IxedVBKzJsKjCoIb7Ka+kTmTQTmTSRGKIVFc9PonTVZGicAXl2Nrm9gV/Mi9N+TmH8mLn9XYG5tG8ZH23PrHeZVy0rD3Nkxog73duVxf49Muv1kTz739xZz5+0Cbm4cyeXlgzg5uy/7ShJZldWKad0DyWnpQEqADu2dBc2sBEFGcljPXvHdnVJQlJUY5eyMmRbalZf65EVZfbHVka0sJU76cujYxVDgYSDwMpb4Wwgi7AXN3QQJgUb0a+HChB6hLB/WkbLSXpxZPIRr63L5eHsx9/eO4cH+Yh6WFfGwrEij2lLAk4MFPC0v4ml50SsC87x8dB1eVuTxsiKPbypG8P2hUXCqFbybAJ82ltz0kEmt75jDRSOoNoMLFnBIwRpzHo8RfFUkYHconGwLS21ghOCbPoKXGQLGGcIhZ3i3KXzRRm42feoLD/3l0PBDX3jiA8/84LkSfyk0nyrSe285S5G6ZAdHdGCXE2yz5duFkTwq9eHssBBWtxUUB+mS6y43ldoKQZiQrQflXaM3aRGZCNmqaCIE6UIwWAi2CcEBE8FVW8EtDwO+8DXmhzAbCLOGcFt5syjCXs64RDlCtB1E2UJTUwg3glY20N6RZ3F23IkxZFdTwYGWupwfFMm7o1pzLymYyy3t+KKxFf9u7iTbT82d5QxNOy/o4gvxgdDNH7r6QpwPdPaGzs4Q5wKZZpDvCTNtYZYdLNaFFUawVgfW6Uqh2agLm/RhswFsNYVt5rDbE3Z78nR+MP+a6MLHK5P4et9QXhws4uGukZwv7c6s9lbMaq7L4Zwm/Gt6S+7MbsOPq/1gZ5RcYT7iBkdt4JgtnLCQnDSCM6Zw3hZq7OFSGFxpzOH8xnTTk1XQZpamNHZ0opGDI0FOLtjo6Knym7RTsbW3CLWjEpQYC1kp8zCVh1c9LPVlBouJwMPGCH9nc7ztjPCxNsDbSo8oB13aeVuQFGhNZpQHWeF2DGpsy5AwcwaHmNI/xIh+wYZkR1gwuLE5gyMtyYqwoLCtC4syolieFc2phQO5vmUE72/KZXxqNOGm8uuBg8bvWynCyrfNhCClTRDbxiawY3wSZeM6UzmpK4cnJ3BsaneOz+jBiZnJHJ/RnUOlXTgxLZ7zc3tyc0MO1fNSqV6YLgVGtW2UrnpUvlifmpnE5SWZfHV0Gp/uKebamiyurOirkpdLyzJUQ7LKaH9lVefWlpE8PjCBu7uKuLEpl6srs+TsikZuy2XFSvS7KwdybdVgPliXw0c7i7i3bwLvb5/EiSU5bB6bxuq87pTPHcbZNSVc2VLK5c2TqF1XTM3qMVxYM4KaVblcWJPDhTU5XFyTQ+2qoVxalc3FlVmqpRblkstlDaTAZNSpJF2ph8tL+qgFRmNLqb5167/aVqqZn66SF23Oz01TzcacnpfBqTl9VJycnc7JBiRGyYkZqSqR0RYY7bbSIQUNnSpQtZKm9KBMUYkpm9yDg6VqlEO9kteH4f2VyAiltPwdgXldu6i+K9HKt9VVF80Qun8mLh9szuHm1mH8a2vOa9GUFyWaAvNXwqL9tmwrSe7tyuPubskne8Zwd3eh6juA+3um8OGWYi6vyuf84mHsm9KXJYPbURDfmP7NXYgLsKSprcDdWJacbfTkF0ATLTTFxVIDZQtKW16UAmOnq0je1BE46kp50cRdX0qMp5FCYkwkoUaCSHNBR2dBWqgho9s5MCs1lM3DYzg8JZlLK/vy4VvDZabMPo1WUUWRgrF1+KyiSIGsvnxWUchnFYW8rMjj88p8vqkYwTcVI/jjUBOFxLjB7WD4JBBuecH71nDVDM6bwkl9qDSHtwQ/zhF8N13AW35Q1QrWuvLFcMFPgwT/7id4ni74MUfARh2oDpJJsM9bSnl54AeP/OBJgJSV5/7wMhBeBMjnT3ykvHxgCe9awSVTOGEIbwu+Wyz4ZJzg+khr3htuSUWGGzsSLVnU3pU5MfYMCTSht7MgxkLQWFd9RO+vBMZKIbOthSDRTDDRVp8Fvg7UeFlyNdCBJ43sedlUhnf9HOEg5SXMWspLtIuUlyhHhbzYQHMraGUL3bygowv32pjyUXN9djUVrPMXbG1vxdHeAbzf3pVTjYx4GmjM101sZdspyr6uwHTzhy4+ks7eUmK6uUNXN+htCFm2UGIAUy1hkY6UmOUCVgpYrWCNIrl2gwFsMobtLrDNmQez/fhgnAMfr0ziq71D+KxsDPd35HJibBxTYkyZE2PAkWFN6wrMjiZQZg8VToqBYGs4ZiY5biAl5qQ5nLKAK42hyo01Pa1po6iSBAqBm74B3iam+NnZY6YlI/XJimbIpHb6to7i8+duoUOQvREBtgZ4WOrjYqqDjb7A0VTgYWOAu7UeXpa6+NoYEm4taGovaO/T/cBhAAAgAElEQVSsS7yvBSle+qT6GtLf34CBgcb0DzFiYJgJA8NMyGpkSnYTKwZHWjK0iQXTk0JYMqAp5VNTeWf9UO7tG8dbpf1p6SArRc468muHUmCUKc76Qv731HYhbC3qxqbCLuwqaMu+4g4cKOlE+fg4Kid1VRBHxcTOHJvSlQsL07ixLptTiirN2Xm9qJ6XSs2CtDpcWdqXs3NSODYlnvdWZ/HD6blcXz+Es/PkgLAc3k1XRflfUdwqql0m81QuL+/Hk7KJvKicyv29JXyweYR6LlMZRKeYzby+ZjA31mVzfc0Qbm0awe3dY7m1vZD90/owLa0RaY3MSQkxoSSpMQuyOrBnSn9OLsvn4vqxvLt1EjffnsB7W4u4umkUVzaO4PK64VxaO4wra4ZyefUQ1RauajtXMSOqFplMrqzoq+KdFX25ujyTq8sz6wiMshLzypbSEqXUvFlFRjkUXR/V89R5MmfmZ3J6XobqUSkxrxMY7YqMtsBoSsxhBZrtJU2RqZyarBIYSc96BUbNq3eXlKcJ6pMZTYHZN77bawRmTT/eWdv/bwtMfZWWhuWlfoF5E3FR8lcCo9ku0haZj/5GxaU+gfnk7VHc2TWCu7tHcntPLrf3qI8jKoPelMm3d3fm8f66LE7M7c2usR1ZmhXNhARPMiKM6eAoCDcVBOsLvPXk4K2j4jsppZRoV140BUaz4qKUF0c9ibOeFCQ3PTXu+gJPQykuPkZyW8bbUOBlIPA1FPgZCRqZyEC2ppaCVo669Aq2YEQ7P+ZktmBzYTLH5w3knQ0FfLRzLJ8emMzTg+N4VjGBZxXjeF45nueVxTyvLOZFZbFKYDR5Wa5kLC/Lx/JbWS/+ezAVjgVBdRR84Ae3Q+E9d3k9uNYVqh1hv6Vc1d3lBVVNYG80LHLiq8GCJ+mCb/sLvsoUPEwTPO0jeDpRwAFHGSX/tI08MfBJkKy+PA2CJ/7wNACeBcrHTzzlzMt7VnDZBKrN4ZypXAHeJfhzpeCLqYIrAwQVXQQbm0qWNxYsCBTMChXMaaRDnq8O/WwE7UwEzXVkRSZEqB9jhKClosoyTAhWCsF2PcH7xoJ7jhbgZQfB7hBsA0HWEGoO4dZSTppYQxMbaGwhDzK2cIZWHgpcoLUrdHCFjh7Q0YVfmhqzPcSSzf4mTGzpSVETJ0ZFOjI2xpvSGC/GRDrwlr8V5VGe/BLpCi185ExMK1/oFARxIdA1QN5E6hkAqSGQ5iePOiY7Q4oL9LOFIa4w1hom2MNMQ5hnBksNJCuEZKWAtbqw2R42WPNoug+3iu25u7w73+0Zwou9BTx4axjlOc0obarL4tb6nBgWwd2p0Tyc3YoflnrBlnDY4yA3zg5aSCpMJUdM4KgpHLWCU/ZwtSW/7XZkfEs9IoU6rM5ayNaqla6O6sVdeWzTUNS9Cq5dddFu8xkIgZ+9Ma3CvIgJdMLfRhd3Cx3cLXSwNxLYGQrMdaVU2OsJfKyNaGIjiLLTJdZO0NFeEG8jSbEXZLgJ+vnpMzDQmAGhpmQ1Mie7iQM5UU7kxbgwNtaHFf2bsquwC1fXjuLu7lIeHF5McRcf7IWsMik3kZQr+EqZMRGCnu1C2Ti6C+vzOrMjrzVvj27H3qL27B8bqxKZfcUdFNWZOE7MTOLIlHiOTInn+IzunJyVzBlFm+nsnBTOz5UzM2dm9+T0rGROz0rm/s4Cfjg9VzUzo7nhJCUmU7GaLGdKahdl8sG6HF5WTud52WRubhzJu6uGqEcVVg9SLZVcW5PF9fVDuLUll5tb8vhkdwmfVMzm3KpcJvaOoaW9bOn5G8pHNyHvkqU292ZMSkvm5HTnrdKBlC/M5+TaEs5tmsjFzROo3TSemvUF1G4cw+VNBdSuG0XN6mHUrB7GhZVDqVkxhIsrs2SFZkUWV1ZmqwJf1QswyiyZzDoVmotL+9ShIaFpqNV0YWFGHZTyomovqQRGzel56SrOzs14ozmZ46/ITEOBeHUFRomytVQ+NZmDU149UaA56Fs2KZGy0vg6HJjYrV72T+jK/gld2Te+Sx3+TwXmTcTldQLzd8Tl/y8C83BPPo/3F/BofzH3dxfw8dvFfLhtNBfWjODw7Ew2FiYwo08ThnTwISnEjOYugkaWUi5c9dTDucoEYE15+TsC466Bp6G8h+JrKvA1VmAi8TeWhBpJwhREGQva2QkSPQX9IiwZE+vMgowI9o3vxvklA7m1ZRiP9hfz4tAEXh6eyMsjJbw8UsIXh0t4UVlcp/qiFJgXB0fzsnwsn1eU8N+DqVJgDvnLkLILDvCOu+J6sAtcdJMSc9YbTnpAeQhsdODLEYIH/QXP+0pped5L8CJNPr+XLLhfJGCHOZy2h9uR8HlzKTEPfOBxADz2g0+94BMPeZ36pgNcU8jLRSOosZASc8YcjurBfkfYbs4PC3y4nW/A3g6C9ZGCRUGC+QGCKf6CyX6CfD9dsp0F8Q6COGtBK1NBMwNBjL6UmjRTQR9LwRxzwQIrwUk3C66GuvNNiBc/RgRAmDeE+8rbRI0coJGVWmCa2kiBaWQu51xaukA7H0kHL+joA918obMnf7a05IW3YLa5YKwQ9LAQ9LIWJNsLersKsr0NyQ00Z42rPtsDrfku2JbfozyhqSu09Ib2ftA5GLoFQlIY9I2EQdHQLxQyAuVF6h5O0NMY+ljBMF3IN4FJAqbpwXwBC3VhqeJ+kFJi1lnBWkvuT/HgeoEV/1rUla93DebprlHc3TiYA9lNmNJMn5WxplTlhHN7chPuz2zB1wtc+H19MOy0gV12sMdIsk9fclAPKg2g0kwKzOUWfLHOiCH+MlvFReMFXnkaRCkryvatpsBoV2IaqqDFhHqSk55AqyBn/Kx18LTSw9NKDzdLfWz01fJjLQReFvo0tdWhuYMBHe2lwCQ5SFIdBemugjR3QU9nQbyjINFJ0N1NkOKlz4BQU3KjHZjVw5+lmRHULBvK9c1juFexkENzsgizkB+jjUJWlL8/5dFYGyFIbhPC6txY1o3qxI681uzMb8PeovYcKOlE2bjOVExUV2b2j23P4cndODIlnrJxHamaniglZnp3xZBvEieny7erpiZQNTWB07OSubMtj+cHJ3B2Xi/OzU+lemEaNYt7U7O4t3y+qI8q2bZmkTyi+PGWUTwvm8zd7WO4vHwQ764aokp7v7YmSyUw76/L5saGHG5tyeX2ziIeHpjEB29PonxmBkNj/Qk1FHjrqkVVORfkqJAZfwNBjIMgI9qJ3M5+zBrUjh2l6RxdnMvlzWO5tKmY2nWjuLQxn0vrRnBhzXBqVw1TCcylVdl1Zmiurh6i3nJSiNbVVf25sqKvSmL+rwVGiere0j8QGE2RUT5qC4x2sq+ahod9/0pg6m4rJdShIaFRCowm+8Z3QTQ437K2v0pg3mTLqD6JaVhahqmk5J+Ky/+VwPyVqPy1wIxStJFGcne3bCvd25XHJ3tGqbi/L1+9jryvkAcHxvDoYAmf7ivi4y2jeHdlFsdmpLF5eGum9Aghp4UtCT76tLCSK9A++lJG7HUUa566apStIlsdgZ2exF5f4KaBh5F6I8LPSBBgKggxk4SZCUJNJWFmahqbyQpMpJmkqYImpnKGJ9ZR0MPPkNwYR2akRrJjVCdOzuzHtdVD+eit0dzbX8jTwxP48sg4Xh4ay8tDRSpeVI7h88oxvCwv5JuKUXxTMYqvK/L59lABvx2O57fD8VBlBycdZdbHUQfYbQNvmcLbzrDOjF+LdLmdIrgZL7mfKnjeT/BriT7MtIE5FjDdmD+WC9hhI1duLwbKNtLnbeDTALjtLfNebjrKVdv3LOFdC9myumgMtUbyQF+1A5w3hzPGijh8CzjmCm+b8M0cJ67nCPbGCtY0FizwFczzEsxwFZTaC8ZbCUosBDONBdMNBFt0BXstBTftBXfdjfnT05rf3S3Bzw4auUG4qzyq2NhJsVlkJ4m0hcZW/NzYhp/CrPkhzIZvgywg3B5ivKRodAyEDn7QKRDiG0E7H34Ks+axo2C4mSBeqOerlMOndqYCT3sDEm0E6R6mXPI0535zP3kTqbkftPaFdgHQJRSSmkD/5jC4NQxrBkOjoV8UJAdBN09I8IZkJ+jtAUNMYbgljNeBKUYwR0eyUCjmZCxgiSn3S5y5McKMW7Pb8/32/ny2M5fbqzPZMzCcaS0MWdvJlGPZIfxrfBj3pjbly5l2/LrcB7ZYww4HeY9ohyns1JPsErBXF8qt4ZQ7XIjl/hw9ejjJoDhlzIAyAFI7xkDZujUWrw7YGyokQLMKoxSDAEdLYpuGEuRshb+DGb6OJvjYG+NhZ4itsfz5eopf081cl2gbHVo5GRHvIOjupEOGiyDTVU26q6CXg6CzqaCdvqCDkaCTqSDOXJDsJBgT48js7iHsG9eTK6tH88HO8dw7OIMZ/drSI9iElFah9IwJIczdFkuhnudx0BV0jQ5iUU5X1helsWN0B7bnt2NPYUcOlHSlbFwXysZ1YUdeDHsK27GvuAOHJydQPqETe8a04ciURI5N7U7V9CQ5LzMtUSUux6bEc3RyN6qmJnBxcQYfbhxG9cJ0zsyVq9nVC2XezPkFUmpql8gX4JOzUri6bAD3d47h0z3jublxJLWL+/LuqsEy5Xf5AFVl4+rKgby3djDX1w/h5qZh3Nk7kSdHZlH71mS2Tcmka5iraknCSdE+d9BRV7GNND5/BooqlZMQhNmZEBviRU58K0oH9WTp6Ezenl3A6Y2TOb9lOtUbJ1K9UVZqZLWmRLKxgNqNBVzckCelZ90IydphqrmaCyuzubh8ALXL5MxPreZJgldaSn1eEZraxX2pXZRZl4X9qF2ovIjdVyUyZ+b3VlBXYpQC86rEaIXjze3NyTlpHJ+VqkK5Zq2UGeXz+k4UHJ6eTOXUJA5O6c7BKXXzY+rSo16B0ZaY11Vj9k/o+r8LTEMVF83n2ocWZXbL66Xlr8RFmbCrStRtCO2Ky84RdXiTSkt9fPL2qNcKjPJtJZ/sK6gjMA/2F/NgfzHPDkzkedkkHpVN46NtYzm3bCT7S9NZNCSOgq4hJDdxpa23MQG2ejL1VzEvo8ReX2Kn8dzBQKbyehiq5cXLROBjKm/0hFjIKk9jK0GktSDCUhJpraaplSDKWtDMWtDCVtDKThBjK2ntIAWmo7Ogq7Ogh5cgO0yPce2cWJYZwp7CDpxakMyNrUN5emC0qoX0onIMLyrH8PJQEV8o+P5QPt8fyuebytEqgfm5siscspQCc8YTtuvx80zBt5MEj8cKPhgiuJsquJ0iuNZJ8ChDyHXeLdFwoBUc6QhV7eBIazjsC/tdocpZ5sLcDoWnzeWNpA9c4IY9vG+jlpd3zOsXmHNmcNYUTpnIWPxyO9huyH8We/KgxJCqZMHmaMHacMGqMMF8HykxM1wEs9wEq10Ea910OOamwzl/U16EOvJ9lDdE+kK4N4S61i8w4dbQ2Io/wyz4LciEb/1N+MrXkBdeBrzwMoAgCykwnYIkHfygc5AUmBh3vvU34Z6NYISFDt21Kg4mQj0fESlkS6vcSPBhmAtEuEO0DzT3kBLT3k9KTO8I6BsNWREwJEoKTEoI9PCXW0o9HKXEZAjopwOjBBQImChgqoBZAuYImG/AH3P1uFNkz7UcI65PjeGrzRk8eSuH9xf2ZFufIGa0NGZ1rDGVA/y5URzI7dJwPptixY+L3GG9GWyyhM36sEVj62mHYm17nxkcd4Fzbbg5SdDFSnk6QEpMQ5lMf1dglOvJtnoCL2sT/B3MCHA0J8jVkiBXS7wcjHG11sPKSB0m52QsiLbRoa2rGUkuuvRw1SPTVdDPTahEJt1VtpMSrATdLKS8xJpI2uoLMn0EJW1dWZTRhFPzBnNhzQiubMhn36yhFCSEMaBLM9LaNKJ9ZCBu5roqgbEWgjYh7swe2IG1hb3YNaYj2/PbsasgViUwB0ri2JrbnJ35rThU2o1Ts3tRNq4jb49uxeHJCXUHfqclqsTl6ORuHCntonpeqxhUPTc/VSUuSs7MTeHU7J6cnJXCsandqZmfzs0Nw7mxYQRXV2ZTu7ju3SF1y6kf19Zk8f66bO7uHM2D8qk8OTKLyiUjWTisE42shSrQz91QvaWpzPexVTyai1dnDJW3xtyEINhY0NbDmKz2vkwb0IHVo5PYOaU/hxbmcGZ1IbWbSriwsZhLm8ZwadMYrm4u5PKmAq5sGMWVDaO4uj6Xq+tzubxuOBfX5KhmaS6tlHM/6jTfho5GZr6xwEgyFUc30zk9L02VsKwUGU2BqYvWEcm5vVUSo8nxWal1xKYhiTk8PZlD03pQMV1yaFpdXs2PqRuQ11AlpiGZ+R8ERjucbhDvbRjE9Y2Dub5xMDc2Z7+WD7YMkfxDcVGiLSzabaD/C4FRysonb49SCcqnCpQtI+X7td9Wtpju78tXIUPhxvDgwBieHhhbL/ffzufaqgEcLe3OxuymTInzZHCILl1sZbx4E31BpJ4MyvLTU7eHvHUEPrqyauOjrx7S9TWRybzB5oJQKykv4QpZaWIjaGYnibITNLMXtHTQoaWDDs0Vz2McBK0cX6Wdg6SDsyDOQ4cefsZkRtgzNi6E5YPjKCvNoGZ5Pnd2lvLZoQV8fmweL4/O4cuqaXx1fDrfHB/Ll0cL+fpQCd8cHscvh/rw7wMpcNAbTjWG68FwwoY/1wj+s0TAVl3+XCf4ZpTgkwzBd+MErLOHAwFQFiSHejd5wfoA2BAI2/1gTzCU+8LhILgYBO9FwDtecNUTrpnBOyZwxUFy1UVeUL5oIblgJuPoVQJjDidMYb85bBGwzY//LrPlv6V+fDnKjk86mXIpXHDRU3DBTfCRi+BTH12+8DXm2yALfg+0gBBrCHOUV6GjXKGpi3qNOdJBEmEPjaz5JdSMn4KM+TLAjM/9jHnqY8kTbwseuBpw31kfgm2hpS90CpHEhkJcY4gPhfZe4GfL5+aC+UaCPI0XaO0WiHJ1P1sIloa5yYTeFgqBifGGtn7QIQhi/RXnBYIgKRTigyDODzr7Sjr5yMdunnLdOsUWUu1hkAUMtuKXUSb8t8CCHyY68O/xdtwcbselfkbUFIbwbFV3Hm/Npqq4BdNamzIiQDC7mQ670v24lBfA+2Mb82KiLT/O9YJV1rDGFtYbwwZT2GQg2aIDb+nCTis45AFnu3C1UNDOVA7v2ilepDSDI5WPmvKiFBzN9pKhqDu4q5yPMVBIia+dCX72xgQ4mhLgZomfszm+jiZ42xlhZ6b+NRwMBS1sdengZk6iiz6JLvqkOQl6O+uQ7iRIdxL0dpYVmO62UmLiLSWdzQRdLAQ9nAWZfvoUtHblwIR03t0ymZtvz+LU6kkUxEfQPy6a+Ka++NoYY671efYyM2Bw+zCWj85ke1ESm/K6si2/M7uK5YG9XcVd2Dw8hi25rdhdFMuZ+X04PjuFsglxlE/qSkVpNw5PTuDIlETVbIxSXg5PjONgSSz7itup5mdOze7JqTk9ODM3WUXV9ESqpidybn5vjs/oQc2ifny4aRTvrcnh2uqhXFkxULaXlmRQvbiP6ubQpWV9eXf1IN7bkMOn+8bx4PBs7lXOZN/CPCb1a0sLLzschHorTPPzqykrmkF/mi1C5edTM8bCyUAQYm9A6wAnejb3Jze5LYvzUtk5eyRnN0zi/OYpXNhYwoWNsiJzadMYLm0cRe36EVxcO5QLa4ZQszqb6lVZXFipYMWgOmjeJKytE5DXr845goZOFFQvligF5uyCdM4uSNcQGGWKr0Jc5qVxbn7vOm0mWanRPluQWm+67/FZqXXmY5TDvZUzJNrioknFlO4NBuP9VUVGW2b+PyUwf0dc/kpgVFtEClFpSGD+qsLyvwqMqgKjaCVpC8zjfcU8Kyvh+cFxdfisfAKflU/g6f5JfLwln/Pzs9hbGM+iPi0Y09aTXgHmtLORrZ8AA8VQrpEgwFD2eP2MJF7Gct4lwEwQaFFXYBpbycpLU1tBtIKmtlJimturUQpMfSgFpq29pL29rM7EuwrS/I0Z3tyeqUlhbB0RS9WMTK6ty+WT3eN5XjmRr45P5/tT4/jm+Fi+OzKe746M59fDGXy/vyfs95D3bh61ggct4UogXA2G263ho5aw3o6fxgrY6ga7/WGFOUwTMMcE5pjw61Qzfio15qtSwa/zTeEtO6jwg9OecM5HDgTXusBlI7hqDJcVq9KXnaXAXLaCqzbyEGCtuTog7byNvEB81hvOeMHJNnCqLWzrxn9KPLjb0YRL4YIPG+nzcYQRn4Wa8VWkDb9EOvJbU2do4gyRTooqiwtEOkuBiXSGcEe5XRRqxe/BFvwaaMr3fvp856PLZz6GPPXQ44G7KQ/cTbnvrC8FJsimrsB0CIHOjaTAxAVAuAc/uRiz2s6MIqFOb65PYAyFoJ8QzPKx5tdQe4j2lL/XZu5SYmK85aBwWy+I9YDOPlJeOvnUpaM3dHKFji4QbypJ1YFUHT7vL/hyoOBhjg6fZgtqMw04kSw42M+eD6e34s6aDHZlB5AXLOjnJJjcSLA5yZXTQ9y5nB/Ik2Jzvp7mDIuMYZk5rNKH1QawQVeyWUi2mcFBZzjVmdpRgg4WckXdQfHxa76waVdgNAVG+8iqnlC3jZQvfkZC4GyiFhg/e2O8HU3wVraRbAxUAmOsEJgYewNi3S1IcNajm4Mg2VbSy06SYi9Ispbykqjx2NVK0s1W0N1JMLSJFcv6t6J2bQm/vV/G2XVTKEluRmrrMKI9LFTRDMaKF24nPfl3IMZRl2n9u7GlIIG1uZ3YOLw9W/M6sb2gIzvHdGbz8Bg25DSnbEJX3lkzlEsrB3JkWncOTuxCuWJT6VBpN9V8jLIKc3hiHEdKu3BsWoIKOfibVIdj0xI4MiWequlJHCrtxrl5fXhvTQ5XVmRxaak8FFm9MIOzC9M4tyhd1VpRbitd3zic+3tLeHRsLhfW5TIjuzP92njiYSA/xyaibq6WdoVN+WeifcqlPqE10vj7YCFkBS/MXNDBx4hR3UKYNagDG4t6sG/mAE6vHC7bSutHULNmODWrs1XyUr0qi9rV2dSuzlYNAzckMMqUX21h0ZQWzbc1BebM/N6vCIw6xTdTJTBnFZWauq0m7ftLr6b7npmjrsaoKjGzJEdmpXB4Zs/XCkx98qKuzNRfkWlIZkR9g7nyCOMAST1r0RLtcwBSYLQl5U0E5p+Iy+sERrOSoi0st98eWYe/EhhNaVFmv9zfk8+D3RLNq80NoTyIqI7fL1AFwD09UMTTA0U8KytW8fRAEU/KilUbPU/Lx/Lo4HgeHhjHRzvHUr10EG8VdGFmSjC5UVb0dBW0Nhc0MxSEG0hUV5EVbaMgS0mIhSDUUraQGlmq20dNrdREWauFprmNbCE1RCs7QWt7SRtHNW3tBe0UbaYuboKUAB0GN7Nhas9AthR04cSivry3dTSfHCjh2bGpfHt8Ft+fmM0vJ4r4rnIk/ylrDqfj4E4LeNYZnkbD563gWRu4FwVVTvLmzh5j2CL4fa7gu1LBDxMM+K5El/tDTLneW3C+q6A2UfBhjjH/nhMCFZFwvCUcd4WT7nDGGmqd5N2kS0FwIQiqA6DaBWrcoNZZ3tqp9oQaL6huCeeaQ1UslLWADa1hbghkOPMsTPBjkOCHQAFBJrL9E6oYtG2syGwJt5PVlXAHSaST4l6RPX+G2vB7sBW/BJjxs58pvwSY8VOAGT/6mfC5jwnP3Q342M2I2x7G3HY15LarIb8H20GMP3QOg7hGsgLTuREkhEH3xtDOAUIEF10FO4RMEG4p5DaOs1AMgQv1kHiqEEx0tuXrYGd+bRYATZ0VeEILX/UNpbZesl3V0fv1dHaVdLWDrnb8mWzBfxNNuJ9iwp0eBpyMN6W8nWBdRyOOZQVQPSmeNcmeZHgKEm0EOV6C2e1d2ZfuwfGhYXw4wpJ7RU58P82Yn+dYwnw9WGQEy3RhhR6s1oc1BnJIeKcbHInncq6gg40UGHvFx2ys8cL0uhMehg2geaPMUgjczQSBDlJgvG0N8bbVx9NKBw9LgYelFBzlMVZXE0F7J0M6e5jTw0mHRHtBDxtJkrVaXLqZCzpbSGItBB3M5UB4R0tBCwNBewtBrJ0gzlmQ3SqEKelx5CXF0is6CD8LI9XKt6kQOJqZ4GJpjo2eLkLx59Al3Jd5w9NYU5LNqlHJrBzRg1Uj4lg1Io41w9uyKqc1e8Z3592NBdx4q4Dj8zNU660HJ3bj4MRulE+K58i0HlRNT6JqehLlEzpxbFoC5+ancmxaAmfn9eTkrCROzelRR2CqpsvqzaHSLpSN68ip2WlcXDKA8wvS60Tkn57XizPzUxWDwOmcX5DGxaWZfLB5BHd3FXHv0Dy2liTQp10ATVzUw9nKjTKlbOppPSoraJoVNV1RfxbQ646xWgmBp5mgqZsxsaFOZLYNYGxmLIsLU1g7sR9vzxpMxdJ8Tq4ezcnVozm7Np+za/M5tzqXM6uGcW7VUM6tGkr1qmzOrxxMzYrBnF+exbllAzi3bADVSwdwfkn/Opxb3I/qxf2oWdJfJS6aAnNuUQbnFmWoZOaMxpaS5m0lOfTbu86P07651NDtpZNzenFyTi/VSYKjsyRHFBydlcKRmT05NK17AzQsNfXNzNQnMwcnJ/zvAqNO0q1beVEJSgPc3DpUwT8TF3nfKPcVgdFuBf2/ITDqC851xUVTXrQFRpvHB4p4sK+QT/cW8KSsmM8OT+HF0am8rJrHlycX8uTwAm7tnMSp2YNZm9WWwlhf+gSb0t5J0Mz8zQUm3EIKTBMN6siMlZyDaYiWNurZmBhbKTJtnWRLqY2doJWVoI2toJ2tINZe0MVZkOwjGBylx9Se3mwtaMm5ZZk82D2Gl5WT+fVkMT8fH8MvFa3481h7uBwAHzeHe43gTgjcCoMaFyi3ggprGUu/x1ieDVilx8t8wYd9BKc7Cax/9LwAACAASURBVCqaC3Y1FmwLFmyOEBzrKng8WcD+RnDCTUrMMRM4YgRHHeXQ5ykvOOkpE16PW8MZGzhvr5AXT6gMlivA0834bZTgWZzgRqTgYaDgeSPBHxEGEKWQlyh7+RhhI8WlsS2EWUmCLCFQtpT+CLbityALfg0057cgCxV/hFjzZ2M7/mhkyzeBlnzmachtD2MpMa6G3HEz4tcAa2jmBZ1CoUtjtcDEh0JiI0jwgWgzbgYZ869Qc2a3cKHAV5/W9gaEG6mToW0UX4zTNATmj5gQWX1p4gThLlJiYnwlbTyhXQPSolmJiXOTJDhCvAN/9DDjp676fJSgy4fdBEc76bO3pWBhM8H6TsZs6RPIjNam9HIWxJkJ+tgICsOM2NTNin3pHtT2FdzMteDz8YJvpxjy32mCP2Yq5mrmCligOCOxxAA2WENlHO+M0qGjXcMCo5QREyFnI8zFq8GS2gJjovg55kKeGPCy1H1FYNwtZOq1m7msulgIOWzvY61HB2cjunhakOphSIqrPsm2UmBS7GQlJtFaCkwHE0l7M0FbYykxbY3lkcc2plJgEtz1ibGVWzfKj89cCDyNdPG1tcLF1AhnCzNsDPURQj1M7CAEhT3bsqYkm81jM1g3uhdrRnVlXX48Wwq6sDa3Petz23J2STbvbx1N5YwUVQ5H2YSuHJwoH8snxatWr3fmt+T4jO7ULslQJPsmcWJmokpcTsxM5PiMBFUF5lBpF8ondOJQaQLHZ/RUidDxGT04NbsXx2Z05/jsZNWZgfML0qhdksEHm0dwe2chN3aXMjUtlGg3XdUpBXOhrpzpNoByBb6hBGzNlpKm6CgFSHvVXlnJsRACD11BUwdBO189ekfbkpcYwrzBbdg8LoXyeQOpWjaMUyuGcm51LudXD+P86mFcWJND9arsOgJzdml/qpfWLzHVCompXpypEhaltGg+V6J9U6khgWnogOQrlZi5qX8pMJJkjszsoeLwjKR6Baah6sxficxfCkzDK9JqgbmxaWj91ZXXiotEW0q0xeXWttw6aL9Pe/1ZW0S0heXOLs3B27w6cvKm3N+Tz8M9BTzcU/CKrNTH6wVmNE8PjOZZWUGd5zLVtpDHFYU8rSzi4aGxPDw0lqcV43hWOZ7PjkzksyMTeXFoAg/2FXJjQw6nZvdk85BmjGtrTR9fQVdbQStzQUsTQVNTSWONDSMlERZqmmjLjKWUmKgGZKa5BtoyE2MriLERtLaVxNgIWlgJmlvKtzu5ChJ9zejbxJWpyeHsKO7FtXVDeX5oKr+cyuaHYwPgZATciodnreDDIDmguVlAlTFcdJQtnVpHOB0EqwQPBwhqYwXHmwkqwwU7gwVb/QQrPCSLvAUf5wXA3pZwuCNU2sJmwe+TBb9NElBqCYu9YE0QbAiDDcGSNRGwwA9y3fgjWYdfWgm+ihD8HCL4PVxAIyMF1lJUmihj+T3kSnKkKzR25NdAS37yNeMrTz2+8tTjay99/u1nws9BpvwabMYfyryXCGsIt5Tr0hGWfBdqwXNvPW656XPLTZ8PXPW45WHAv72NIcIZYgMgPhw6hkm6BUuJSYqAdt782ERALy/Y3RH2xfHHZne+W2bNlQLB3mTBnOaCAm/BAiPBOgfBf3yMoYUnNHOVwuVjBQF2su3V3BdaeUMbX7m2HesDsV51BaazF8R5Q5wHdPWCRHdJNyeI0uWRj+CRj+BomBEVgbrMDDJmWoAhIyNsGBxkQhcXHdpYCmJNBT1dBWOjrJnT2Ye3uxhxNN2Je0NteJbnwjdjzPm+xIr/jDfh50nm/D7ZGKab88cMO1jkzi8bYjjdX12BUQ5xarcNlNUR7TMdZqJusKTmrSTlj3EyEHhb6eBna4CvnQneNsZ4WeriZipwMxV4WgjcTWQCto+JIMLJiHg3PQY1cWFCG3fGt3KjKMKc/FBjhvoIelnJROc4Y0Enc0FHM0G0gSBKT9DcRK5d9wp2JC3Mmfae1oRbqAdTLRQS42FhSoCDLc4WZljp675yVFQZ2OdlokPbIC/6d4hgVHI7Jg/qytLCDNaVZLB+fCYbx/fm6PICrr41jrJZfXmrqAs7xnZje0EHthd0UCWiHhjfhV1jOrC3qD1n5qRydeVAzs7rRdWsRI7NTOD4DEnV9HiOTO2qmp0pnxRH2YRO7B8by6HSbpydl0bFxC5UTOysyp+pmp4ozxvM68WZucnULklXCUz1hkLy49xx1qvbGlSKh/JjfV0V5U1Oemj+PzQFR7PFqKziad6fMlb8HQmzM6K1nzNpLUPIT+nI7KFJbJw0hD3zRlKxvIiqlWM4vrqIk6tHc2JlPidXjuDkyhGcXZnD2ZU5nFuezdllgzm3bBBnlw7k/BJJjUJmGpKYcwv7cm5hX8WmUt0jkdUL+2q0mhqu1DTUUqrvSGTV7FQNealfYKTENNxiehORUcqMaGgt+k0Eps4ZgAbkRSkq2vKivlHUsKxo89H2ka/wV9tD2gKjKTJ3d0sZ+XRvwd/m0d5CHu0trCMnDaEpLZryohm1L+P2C1U8VfC4QvKgoohHh0t4fniCihdHJ/HV8amSqpl8cXQaj/eWcmNtLhWTerGifzT57d1J8ZPyEGksCDORAhNhIYiyUbeKoqylsGhLjLbAaKMpMM2s6j5vZiVoYSlpaV0/LSwF0WaCdlaCJE9Bfowhy/uHcGZaEPe3doFDQVAbA3fD4bq/vKvzloBqO3jfW86rXHGBEwH8PFdwK0VQ3V5QFS0FZleIYFuAYL2/FJjJNoLZLoKHxXpwKBZqA2CvKV+MFLyfJPgoXnAnSfBVfwElRjDRGEYL/ttP8F2y4PPWgsdRgu+jBD+2ENBUQBMBTcwlEXaScAd5BbqRPQRb80eAJb/6mPGDtzHfexjytZc+33ob8EOAKT8HW/BHI2v+DLeRwXSRttDUVt4zirRWCcxnPgp5cdbhurMON1x0+cpVj58DLaGNDyREQJdw6BoJSeHQs4kUmG6h0NEautjBPD/Y2wlOtISzbeFyEpyL48+Kbny5pRk/l0TzYU9L2dZq4wst3CHInP+6GPGHmwn4W0mJaeYGMZ7Q2g3aekiBifVSV1+UAtPVCxJ8obsH9PCC3v7QyZbPggTXLQVb7ASrTAUjrSUpToKeDrKy0NpC0M5Y0NlS0N9dkN/IhBXRgq0ddLiYJLjRR5/7WYLHOYIXIwVf5Am+GyP4d7Hg+3FG/GeiGY9n+HKgu2yxhjQgMEZCPdypzFeyFTJ0zlpHfQtJs2VkqxAFez2Bi7FaYLysjXAz18XTXAdPcx0CHYzo1NSftNimRPvYEmglaOJiQg8fE0q6RrAmM4Ytg2PZ0rcFSxODmRzjQmEjc7L8jEi2lQLTyVzQzlIQ76pLRqgtg6PdSAlyINpU4K8vc21chCDAVAdvC0O8LQxxMzPGwUAXo9e8KCurMQZCVmP8jQVRDoK4YGuGxPozKaM1y/IS2Tl9EJc2FXNudR7bi7uyvbgrByfLGHhlIuq+kjj2ju3E3qL2HJvanYtLMzk3P5Xjs5M4Mq0bR6Z25fCULhye0oVDpZ1VSb8HJ3ambEInKid15dTsXtQsyqRiYhcqJ8VxbFoClZPiODy5G8emJXBiZhLHZyRQvTCNG5ty+XhHAVXLhtE3yhQ7IdelzYR6tkU7Nfl/uUv2ukqNcvBXe4ZGOUejOVNjLQTuQi5PtPM0ok9LN8b0imbe0E5smZRJ2bxsyhcMpWrZMM6syePcqmGcWT6U00uzOLdcVmhqVgzmwnLJxeWDqFnS/5WqS30Co33h+vyCulWahio1dVC09pQDvX8lMFWzJa9IjMbgr3JzSfO5tshoDv5qSoxoONNlINfWD3xlPfp1Cbr1Zbq8SVvodZKi/b6Pd4yqw+taP5ooKy+a1Ze7u/P+trg82FfIg32FrxWY+mRF+0rzk4NjeFpeVEda6hWY8iJJ5QQeV8qkWyXPK8fz+ZFJfFk1he9PTueH0zP596lZfH9iJt9UTefR3iKurcyhYlw881MbkxNpSryrlIVmZoJoE0GUuUSzClOnIqNI423agMw006BONUZBK6v6aW0taW6tR3NrPdpYClqYCqKNBK0sBL3dxP/D3HuGR1luYdv39JZMMjWZSSa99w6EkNAhEDqComDdqPQWUunVzrY3rEgRQhIIhIAUBQuWrWLHhrpVVIoF2VjP98c9k0xCQNjb93u/H9cxkylJJjNHnvNZ61rXYl7fSF6d44CNQ2BfGrTEw3adzGL5Vyi87oJXrFItYZxeIjhUKjhQJNiRK2hMEzyRLHg4VnB3rJI7YxTMtwtmaAW3xAhO3zYcDhbDyyVwXwo/XCf4vqeOz3MEJ7JV/FIUBEXB/Fpg5FSy4FSy4LdULX9mGCA7EPKCId8mleudIMqwQ3IQPycH8lOCiZ/jAvgxSs/JCC0/Run5OdrIT1F6forR85+EAEizyue0yuuNybBJZdkg08pPqRaORml5x63ldbvgVafgtRAFnzoVfBNtkt6UwXkwtAuU5cGQLBiaDSMz4bICGJ8t4/9LVXB9NNwTBauTYGsgbAuCFjvsDoW1faDcCgUh0CMCCiMgwcQPLg2nwnT8FhUIiXZId8jqUle319jrgZ7R0DsG+sRKeOkfLeFlaDyMiIFR8TA8DgZHQa8wSNXwZoigRQgqhaBCCPoZBQNMgq5mJfmmtsphYZCgn0vDVbEKbkw3sTJfyT29gmgebuHZcWG8dLmdl8eH8MaVNt68ys571zp55xo7+66zcV932W5JE/Is3SLa7zjybw/4+2ACFAKzQhCklCDjW+RoV0kzbKha4FALwowKooNVxFjUhAeqCDUIwowqwk1qMj0hTB43iuXTrmFgVhzpVkGeS8eIOA1Lx3Zl/YzBbJ47go1T+7FmYjFrb+zHo9cUM7dnIkNDZPhhcaCgNMbCZTnRDM+KomuornUTdqRBQUKwnphgMxEBBqwGLSZlW5vkXPIdeH2+D40X0nxBmC61IMokyA3XUZYfxc1TR9BwVwVPLryS++eM4vHyITxePoQ1sweyZvZAnp49gPUz+7FxZgkt84fw/C2X8OyKEeyY35+mql5sqZZqrOzNluo+NFT3Y9Pc3jw9p4T6qr48s3wEe1aOYveKkTTW9Kexpj9bagfSUN2Hxpq+bK2Raw22zx/IvpUjeO2hG3j7iek0rriaYfESwMI18j3yQYxetJ8y+r8JMaoOP6vj/qyO6yl8bUmDF7ySLRq6RNoYnB3DNaXdqL6iH6tmXc6TC69k/dJrabz5WnbdNYWXHp7hTQj2+mZWXcPu265i9y3j2H3LOJ5ZOZZti4azZf4Qti4YyrZFw9m5/BL2rLiMvSvHtckHKl7AaQOdK9h38xVtkON9/J4Vl3kNwG3VmBa/rJgWr9ryY3xheO3HrrcuHs7WxcPPApiOMNMGMMM6lW8MW5y7wnKlV9d2muXydwFMZ1UWf0DpCDT+97335JSzoMXnUemotqWL09vpyNMzW+WDkwvR/x8A5uvGylYdbazku63VHN+2gB92SJA59cxyfn32Lk7vXsXH6xfzzIqruWdiPyoGJjImNZieDgkveYGyApPrzX/xVWJy/FpGuUFeQ6/NK6v3vv8SYHwQ09WmpdChp7ddnnUXe/0yfY2CnlpBTYzg6Kps2JsKWyJgl0luqH7DLfWqXWqXh99ukgDzXDdBc7Zgc5Lg0UTBg9GCVZGC2z2CxaGCqiBBhVmwZWAANMbDl+PgxXFQY+bHXnq+76njdDcT36YLvk8T/JCu4HSqijPpGsgyQq5ZwkteMGQGQroREgMgWssvkWp+iVRzPErDsUh1G7jEBfCfBDO/JgbxS4KZX5OD+CPNCum29gCTbj8bYLJsnEqz8k20jrddGl63Cw7aBK/YBYetgi/DdTKxt08aDMmXEDM4Q+bBjMyE8YVwZQ6URfF5vODbdAEzBdwbDXW6Nm3UwrIY/j1KQKIeSqKge1QrwHwfquaUS8uvkQEQHyirS7lOCTHdw6A4Qo5u9445G2BGxcOYRLg8C67IhpHp0CuMY7lBvO4UrAwUVAtBb62EmC6BCvKMgmyDIEMnyFILcrTSFzLMJpjmFlTFCx7pItjYV8OWfoJtA5W0DBS0DBTsHiTYWyZ4qlRwc4agh0mQIWTlxAcwHTNdOjsgab0w46vM2BRSvoC0EI1M1o0KUhAVpGgHMBEBGqKDDPTMTKIsL4m8cAu5IVpyQ7SMTjJw18QB7Fl+NS/ccSOv3TGRN++azJ7FE7h9ZAZjInX0Mgq6GQS9LIL+EYH09QSQaRbEKARxRkGqRUWKPYCEYD0OleKsNtH55JvM8YXxWRWy3WVTCkJ1bQtmfT6hLm7B9JEF3DltCHfPHM79U/pyz6TePDiphIcm92TDrP6sn9mPulk92b9yDIfuu5qXbr+UbdW9qS/vwea5xdSV96CuvIS68hI2ze3NhtnFrJlWyNZ5pbyw6nKev2MczywfwbYFg7zw0o+G6j40VPdha01fmmr701Tbn73Lh7cCzI7bb2B8bqAM7NRKr5FVJTArFQQoBEZFW/aRP7T6e2T+bojxBxjfz/UBi+/2jhUanwcrSEhzfYJeUOBSUJasY3yhi8oRKdw5qS8b5o+kaeUV7L3zavbddQ0H7r6evauuYdfNl9K0ZAQNtWU8NbMnj04u5LEp3XliWjHr5/Rhc0UpW2qHsmPRKFqWyBFpWYG59CyA8QFOu6klv9wYn3YuHd0OYHYu9cuOaU31HXXWtJIPYjqqM5BpmD+s3QZs30bsVoA524zb3pTbeYru9bzx8PWdgsyFAszbj0j91VLFdx+fxLuPT+L9Jya36oNOwKVtqaIXVLzyVU78YaYdiHTS3jmX/CHls6en81mH2z7ZMI0jfvf59MXGGa3696aZrfqyzh9g2m9r9m11/mKzXJDou/5lndTXDeUcbZzbTvK2Oe307ZZyTu6o4ced81p1tHEOr947nien5TG1RwAjogVdAgS5OkHXAK/h1iYotkiVWM9Wdy+ctLaMgttPJ3W3eOX1v/gqLq23e7/u5lWxV0UWL8BYBb2DBQMCBXddFsmfjYXQ3BNarHAwBt4OhUNOuSn6X3Y44OTPBwTvDRM8202wLV1QFy94NFbwcLTgzkjBHeEyVG5JmKBaK1huFfBwP3izBv45iFMDhQSULGNrgFzr9FBKMCSZ5W6iNIf0t+SFybC5SANn7IIfAgXHAgU/OwVnwrT8Hmnk9zgTJAbxe6qlVWQ5Jaik22UFJs0qYSDNDqk+2aS8FZkzcUGcDNPytl3Fmxa5nfoVu4JXbILXnYKfEgJl4NzADBiWD/2zoThZrgEoTYf+cbLFkx3E7xGCb5MF9HdBRSbcXQYPDoJbusPocH7MEZAbACXyNf4eqeV4iJIToWqOhmn4LkLHDzFGfk21yeyaXDd0jYYeCdAjWobe9fJWY0alSw2Ng9JIGJYMI9Pafp+eLsjU816E4Fm9YJ4Q1AjBQL2gr0aQYJSKMUr/SLJBRgfkB0iT+DiPkqtidUyKVzE1UUNVup4FuWYWFFipzQmiuns4V0YpyA2QOTC+dtDFnpH7Wi0+c2+wQsqhlUscY8wqYswqIgNUhOsFYTrpeQnRy+Td9BAT+ZE2Ctx6CTBpwdwzdQQHHlrIwceWsuvOSm6fWMbghGASlTIaoUuImtwQLelWCSzxJkGixUCa00xiqIPI4EDMqrY9Rxd6sFWLNr+PXSdwBagJD9IRbQ8gzGYkSCdaYcj3NzIJmWw7MDmQsV09XJFj5sp8C9NLnJT3C2fJIA93jEni7rHRPDkxm4ZZOTy/YgDPLe1Nw6wsNs/OobE8n/rybmye04W6WYXUl/dg3dQ8GitKePnOK3j9vqvYt3IE2+cPpKm2P1uq+1Bf1ZuG6j5sqe5DU21/ttb0ZfeyYbz64PW89fg0mm+7lgn5RqL1ggiNhK9QnXxf7GqBVSOwqAVmldxHZVQITN5Lo6INKi5kY/zFeGX+avWE/+N9icB60WZC9hnKLUJWlxJMgm6eAC7Jj2DKkHyWXNaNVRP7s6G6jO3LL2Pnysuoqy3jiWk9WTO9F6tvKGT1DYU8eEM3HryhGw9f352Hr+/Omum9WD+nH5sqS2moHUrTwmGtqwFalo5pDbJr3Wa9bHTbbX63ty2GbKu+/L0AM+IsaOl4vR3AnA0xbQDTEVx8enP1DecFmPNNFvkDzPl2EnUGL4fXTD2rRdQZwHTa+vGruEh1XinpTO0e6wWTc93emc6Cl04AxrcrqONWZx/AfLV5Tqv84eXbLRVelZ+lY00VnGiu5uSOGn5oqeWnXfP5cfdSTrYs5NCTM2laOoqbxudyVZ6R/m5BiU3QI0jCixzTVFAapmGAW02/UEEfh3xMsXeMutAm6Gr3ZsPYVXS1KSmyyumjIpvXyPsXANMjSKp7sPy+/WyC/g4JMCNDBW+vCIamHtBsgRejJMC86ZDw8qYTXouEzYIjlwn2dxfsyBQ0JgkeT2gPMEs9gsVuwaJAQa1B8PaVBr6YFsr7aYK3EiTA/JlhkKPPGcHtASbVKuEizSGnc7rHQEZoK8CcsghOOQS/e7QQa4ZEq3xOWluV5U9fxSXN1h5gUq2QYoEUq1RysJTXS/NLfDA/ePS8G6JtBZiDNsHLVsErNsE3HjV/5rigZzyUZkLfDAkwxTFSPnNtzwjIt/FdiuDreME7XQUnRuj5/apgToxUcipXcCJdQH6QBJgMB794VBxzKjgeouRomIZvwrUcj9TyY6yJP+ID5GvJCZNtrK7hUBQFJRHS4DskUab3TsiDK3IkzPR0eyeUYmFIAvSP5HRRGEcS1NzlFCzVCUoNgj5qQYpZQZJJEOtVilFCTEGgoGuQYLBZjh2PtQguswmuDRHcEC643iN1Q4qRMSFyBUaikC2GANHWOrrYg5TvbNoHL06dnDKKMauIDdIQGaAiTCerM74E2FCDIM1pJNMdSNdwE7khWoYnmrhn6gg2LPoHNSML6BkqiBXSz5JlknlMqb7gSbMgyawgzaqW8GIx4NAoOw0k/Cv5/D5BKoFDL4i2B5Acbic1IoTMGDcxbgsB6vabrFWizbCcGSToG2dgeIKSS1J1jE9TcU2OgSm5GuZ0N3P7iHAeuy6Dhlk5tNQU0VJbyMZpaaybksraySmsnZLJuqlZrJmUw5pJOa0A88JtY3nzgWt59qaR7FhQKuGlohebK6UaK3uztaYvW6r7sGvJEF6671oOPTaFvfdMZtGl6SSa5aLaEI2UUyfh0a6TsmilgnRKgvUqgvUqAtUSZvw9M38XxPiPYJ9v2skHML6KjG8Czteu9JmzrV6QiRCCGKW0AIxMMlBbFsmDk3qwqXqwrEzUlFFfU8bm6sHUebc5ryvvx1Mz+vLYlBIenVzEo5OLeGxKD56a2ZtNldKAvamylE2VpW1j8YtHtQJIu1TepWOkvFusdywe0QovHQFGQkyHBF+vR+Z8VRep4WdVXvwvWysw/tDSOYhcf069ufoG3lp9HYcevpa3Vl/HW6uvO+9eoncem9h6ea703PMtVZRVl6mdAsxhvzbR4XVTW6eFPlkrJ4bOBTAdc1n+CmA6awf533YuePGpFVw6kT+c+PR1Q3mnaoOXtkrLX+n49ipONFdzormaH3fO4/Texfy8bzE/PDOfb7fV8M5jE9m+cAh3jU9hRjcTY6MFw12C0R7BqDC5g8WnMqfUAO86gT6us9U7RNDTIZdAnlPWs1ViF/SxC/o5BKVWQaFKsLKX4Pi6YfBcKryQBW/HwKFoeD0U3nTD25HwfBA/zhEc6CfYni1oSBOsSxQ8HiO4L1Jwt0dwa4RgeajgYYvgUZvgVbfgg0TBt3GCX3P1suqSZpZJuWkhHM+L4nhelEzNzQ6X3o9UG+RGQEkKdE+Q48XJToi1QJQZIgIg0Sa/R7pXmc52mS+y2mKTm6Z9ig+SJll/Jdmk4hz8GR7AJw4t7wdJeHnJKthvExxwCN51qfh3osU7Up0u20m9UuSaga4R0D1a7jQqiZVA0yMK8kI4lWrim0jBp07BuwGCH8KENBB3i4GCKEhycDpcz1GX4KhLcMSj5IhHyacROj6PMvBtjJHvk4L5PdUG2S7Ic0E3D3SPaFsuOSgFJnSHiX2gLFVWZ/rGQr84GBgFg2KhdyzkOzmRYOS9IMF9esHtQlBqFAzQC3roBEVaQZ5WUKD3juf7VQh7WQQlQYJeZlm5621V0MempK8ngK7Bcp1GiKIt9+V/bRcEK+QB0qUXhJuUxAZpiLNoiTGr8BilT8bnl4k0C+KcKuJD1GQ5DWQ5DXSPtlCWG0uW00CI9ww8RC0zYsKM3qqOTUeiK5CEkABinWbCg3RYDcoL8rh0lF7IioNdLQgP1OCxBhAdEkxKZBjpMRHER7iIDnPisAR2+r1NQgJbgV1Qlmrl0hQDEzKDuC7DwNxeYdw2LIL7L0/hmfJcds7OpmlKDAdqstk1O5Hm6TFsn5XAnuoMnl3Qhd01eWyblc2G6xPYODmVp/4RT8u8Et64ewwv3DyUZxb2pamyJ41zelBf3oOGucVsnVvCtqpeNFaU0LJgAPvvGCdPoB+dzuqpPejpkctnIzSCMKVsJ0UbpCL1gnCdwK0RhGhlhcbpVccKjQ9ofK2fjl6pv/ps+FfsLvQ98s+q8ffK+IL4/MP2fCnCEUKGEU7IUHLL5Vlsqilly8Jh7cyu/pWM+nlDebqylMen9+SJGb14YkYvnpzZmydn9uTx6cU8Nq2Ix6cX88SMEtbM6kVd1SAaaoeyqXIADbVlNC0c1ulupOZFw70AI7dZn3sFgXc55FLfZJIPYEa0kw9c/CXBZWSrGuaPoL52OPW1w9sA5tyVlL8GmAuFl84A5uLgZfJ/BTAyr2XqWdWYji2k81ZcOgCMv5fFX/5Vlo46H7icC2LODS4XDjC+CsyJ5up2EHN8exXf75rHj7sXcmb/Tfz50h1wrgkiTgAAIABJREFU8F5O77uNw0+WU185iCWD47g6Wclwl2CoU8LL8FDBMK9K3VL9wwQDwgUDwhWt6ucW9HNLkOnlvDj1sQv6h8gNvaVWwaVWQcssNzyfCS9lS4B5O0buM3rDJQHmUDjc7+HNkYLGdAkwG1IEa+IED3gh5vYowUq34MlQwbZkwaEowedZOv7oYuK3PENb6yjJzqkIAx/FmvkkPphfEy2Q6ZYAk2KVMNMrDQblQ99M6JcDRcmQHgZxVkh2yGmdzFDpT8nqoIyQDi0jh1SKnxKtEl6S7RDvhIggPncZOWxRctAmIeaAQ+oNm+CDcK1cLdAtFooTZUunOBZ6xEiQ6RYJhV71iIKuYdDNxalUE/92C74ME3LDdaEbCuMkDCXaOeMx8I1byVGX4NMwwUcuwYcuJR+6lHzuVvJluIbvI3VyGio1yAsx4RJienhkNaZPFAyIleAyKBkGJEgNjJLqGy/BpiSG/2TaaErQ8VCAbCP1VkmA6aGTRu+uJgkvPb2bnHvbBb1tEmJ6maVKzIKewYIih5ock8ClklNDvimR/+Us21eRcOokwEQEqFoBJt6qIypQjlCHmyS8RAeriLQIYmwKUi0qMuxaMh1aonWi1Ywbopaj1hGBglirhkRXIJnRDuKdRsIDFdh10lDsv5PpQn9fg0ZgM6pxBGqJcwSSGm4nKSKEtOgwkjwuop1WbIF6jOpzH6TNQgbyDU62MKEolslF4VQMTOS+a4p45MY+PDkxnyeuy2Xz9fG8tKiEb58YC/uroGUK7J8LL9bAG8tgfy3sreBU4wyOPHIF/7p9KLtqithRW8wLN5fxws1DaZnXi/rZ3dk0vSvrpxWwYXoX6md3Z+vcEurLe7Bjfn923zxadgUem0Hzyku5olsomSYJMFE6uULFo21bpeIDGIdaQsxZFRqvAjVeqQUBqrZ2k69K47+lXHUO+YfiXQwY+wfo+ft0/KflArzvRYpOMCwtlHlDYnhkWm/q55WxdfFwGuYPaZ3o2bp4OFsXjWTLwhGtU2MbKgbydGUpm6oHU1dbxrryPjwxo4THphXxyNTurJ5cyOrJhTw6uci7J6uItbN6sbGiP/U1g9i6YChb5g+RhtwFQ9k2f6i3hXRJpwDTBjISYFrzYv5OgDm/Gbc9sPjr0KM3nhNe/IHlvwGYzuHl3ADjP1nkG4/2B5hzTRRdjAfmXGbcC5G/p8XnZfFBiv/1c1VcOoeXue1A5butc1t1rKminY5vr2qvbTUc31bDyW3zpJoW8P32hfy4YzG/7bsZXrqbP/ev4rvGCg7dP57Ns0u4ZXg41yTK5XK99YKBZgk1o8IEozxqRoarKHOoKLXKDJoB3lZQP5s8wPSxX7gGeuWLWO+vEszNFfyyOQ8ODIa306XeioM3YuRW6Q8iYHccn5ULmooEG3MF9RmCDUmC1XGCh2IE90UI7g4T7AsXHErX8UeKUR60fd6XlCDIcvB+Uig79IIxgVK3OATrskM5kxXKb7lhMva/KA56ZUDfLBhcIFWYBGluCR3JdtkaygyRKwSyQ+XKgGwXZLkg2y1bL7nhkB8hWzAFXuVHQo5HboVOd0FCKERaOB0WzHGLjrctKt62qHjeoeGAXc3zIWpeCtPzcYSBb1MdkBcpq0MliVJdo+XUUH64zKXJcHjbWDbp7YkNkP6ebDvku6BrlHx8mhPizHwfpeJ4uOCLMDWfu5Ucduv4wKXlnXAN73q0HI7U8VGMgZNxgZxJd8qf0SUKCmPk36nI543x7lLyqV+sVO9IqZIwKAyBIhN/ZksQfcq74Xt+iGBSmGBiiOByp2CsVXBVhOASW1uC7YBgOXbcLVDQPUiQb9WSbhSEatoC7P7XVsHZAKMgNlhBnEVJgk1NvFXV+nWcRU1ssKp1zDrBYSDOpifGosVtENg1UqEmQaRVS7QrmBi3hXBHMA6zAbNO2brJ2n99QUd/hcLvfp/x2KwSOIxKwi0GPF7F2szEO4OJcgQRG2rFGWTEqP7r1xwsBHmeIKb1SWHZZb14+LperJ7Yh9tGJLOov4d7L4mipbIPXz5+FTy7CN5ZAR/cCh8sh89ul/r4Jvj4Nvjkdvjgdji0Al5fAQcXc7ppOkfXXs0bq8porsilcUY2dVMz2Dg1h7ppuTRML2Dz1Hw2Ty+gqbyIlgWlvHbXeN5cfQOv3H8Nt11TwNBYQZpWkBMgyDDKIM8ktSBOIYhVCBK8++FiNIIorVSETuDRCEK1svVk1wmcRiU2g8BmEFj1Cqx6BWatlA9sOpqD/fV3+mn8TcG+VGWbQlDgUnFd/yweurGIpysH0zB/CE1LRrS2YrYuHu4dY76kFWJ8MLBl4QialoyiackoGhcMZVNNKU9XDmBDRX/WlffhyZk9eWxaMasnF/HwpO6snlzE6slFPDKlB0/M6MWm6sGtLapNlQPYumBoayWmo2fGvxLTvGRUJ76X88OLP7j4A4zvuvjLTdAdoKUjwHQGLecClPPd31mWy4VUYNp2Dk1p54P5K4Bpq8JcWH5LZy2liwGWjrqYdtG54aWiU3j5bwHGpx+aF3GqZRk/71zOH/tvglf+CS/exYmtC3jx1qt5+OoCphdYGOUWDAyWm3IHBMuW0mC7ksF2JUNC1ZSFqBjolABzMfDSxy7ob5XyHZhGWwQjzYJn5wp4dgAczoUPcuBfUfBaBLzvgY+i4PUCWBvI21cIGrsJGjIFG1MFj8S3AcyDUYJXEgTvZHvhJdMsM1yyjJBshnwXb8XaeFIIugtBvhD8Qwhutgt+SLZIgPGNERcmwoA8GNYdyrrISkyXOEi0ctql5oRTcDpCwx/JwbJ15AOYbDfkeqAgQsJCYSx0j5OVj8I4uR6gMB4KE+T3y4iC+BB+i3TwozOA9xy6swDm+RA1bzsEH4ZrIc4sFzIWxUmA6R4rIabAG6yX6TUSZ9glxKTaJVTlu2RlJt8DeeEShNKc/JJk4sdoNV9H6vgyXMOH4Xo+cGlbg/XeDVfxQYSWbyJ0fB9vllWqLJf8Hl2900zFMXL9gA9iesdB72ipnh6pkjCpfnYYHQsLuvBndQ4fzYnhxSsDeXS4iluKBNNTBFe6BWPsghFeL8ygQBn61tskKDR7FWIix2uuDdW0jdj+LyO1nQFMnEVJvFXVqr8CmOhgDWFGWQUINQjcgQrCgpQ4AtVYDQKTpv3upc7yTPz9FjohCNAqsBrUWA1qnCYNriA9riAtIQFqnEYldp3cVB+iVxIaqMNp0vzl5JLvb5Vq0zB5VD8enDaGZZf1YlqBjSviFEzPNbF+Sl++emomPHc7vLEK3vwnvLkUXl8E7yyCQwvgzfnwxjx4YxG8vRTeWikh5vBd8OHd8Pbt8Mpyfmicypv/HMre+SVsKy/ghZVlPL9iMHvm9aWlsoSGWV3ZODWP+jklHLhpNK8+cC0frZ/NnrsmsmxcOhO6Obk0N5jLu7iYUZbO1T0iGJSgo2eEihS9hJc4rSBaJwHGoxG4le39JkEq0QowNoMSq15BkE7ZKn+Q6Vil8d+ZdSFG3gsFGd/7bhAStEpTnZSP7c26OQOoq/GruHh9Jb7rzcvGsHXRSDZVD6Zh/jCaloyiZcWltKy4lOZlY9i+dJQ38r9t0aIEGumdWTOrD2tm9eHJmb15bFoxD0/qzvq5A1g7qw+PTy1mzYwS1swo4ek5fdhcMYD6mkGtxuDWCSUvxPibeP3NuueHmLMBxl//nwJMa7x/B2DpCC7nynKRwDLNq/bpuOeaQvJ5YM4FMB2TcjsDmHN5Yv5fA8zRxrlngcsFA0wnQHNyxzxO7qhp1fHtVXzXNIdj28r56ZlazuxbxK/7l/DbgWX8e1M5u5cN48Gr85iap2OkU9BXLxNEB5tlFHqZVTDYq1Jb5/JVWgY62su3F2ZooGC4WXBpiKCfWjAnU3B8/Wh4fwB8XCa3Sr8cBe/HwYcJ8EEKHIrl9EoVzaWCxhzBxjSZxvtQtOBxj2BdrODDRMGX2VpIM0JGgBwHznXyXX4MJ7vGc1dqBFf6/TPKEIKBJsG7cVa+zI2GtFBZISmIgNIcuHIAjC2GwV2gdwbEWzgWKHhHK/jYLPjZo4RE7+hxpneBY443qbcg0muAjfarWMRBcQKUpEp1TYRUN8TYIMTAtzYVXwUJXrFreMWu4Tmnhr12Ffscap5zanjPreWLeCt/ZnugmxeEipLkZdc4yI+FnGjIiYJMj2yPZXtfT0GEDKrLD5PtoCw7pNj5PTaQE9FmvvOY+NRj4uMwPW+FqTnkVvFamNR7bi2fRAfyU5yV39LcEtgKImToXVF02w6lnvHQO0H6ZIqjodgDPcKhOFLmzxSHSdPxeDtUZ8PqHHiyC6yPgHuMfD5f8MpEwcbBgif6CO7pIbgpSzA3WjDdLbjGLhhrFIwwCYboBIUaQYFCECcEkaJtdcL/CjBuQ1sFxgcvCTY1cXYtCQ4dcQ4DEUEq3IEqwoM1hFsMhFsMhJo1OIxKgvUKgnQSWPSKswHFd93fJ+GTVgiMakGAVhAcqMFhMeC0mrAF6XCaVNgM8mAcIGT7LEQtCNcriTHriLIYCTOpW6s7nb1GX0UhLURN1SU9WHldGZMLQxgSLvhHlppHJxVzeN1Mvt+9kjN7FsPzN8GLy2D/IjgwD15YAK/Uwmvz4F+18Po8eLVW6pV5cLBW6sUqODgfXlsE+2v5rXkGP9TdwLdrr+bM1tmcapjOd2sn8eVj1/HOXWN4ecUgDiwr4+VbRvLKPy/l3Yev41/3X8u2BYO47x9duXVcOmtmD+S11bN468lqdt92HU9VjeDWq7oypXcEl2cHMihaTX6AINMkSDcI4nUSbMLVEmhCNVJ2jRzLtqjl3zJI3WYItuoVWHQCq95rEFZ7J51E+83m/kBzsZ813/vu+ywYhSAyQMW4rjGsnOgHAIuGsHXx0LOmfLYvvYQtC0ewsWoQ9fOG8uwdV/HcqqvZd/t4dt18Kc3LRrer3LSHmAGtqyN8ics+rSvv11qRWe01BT8xrSdPTOvJutl9WT+nHxvnDvQDmpFsWzTyrApM05JR3tcwisYFI9mycFTr9fYa3an+NoC50LbQ+eDl/ODig5WLA5i2yP/Oqi8zzhn57wMYf1i5GIi5GIC5GHBpmzaS+rsA5kRzrVftfTInd1RxckcVP+6q4dTu+fy8ZwGn9y7kj+fvgIN38su+O/lsfQ3PLLycW4encV1iAEOC5R6bUrOg1CI10E8dAabUISh1ttcIm2CkXXCJXTAyWDDKKhjjEIwyC7bP9MDBrvD5cDiUJAHmUAS8FwtvxcN7SbAlnQ+nCZq7CuozBevSBWvTBGuiBJuSBJ+kCI7m6SHdxB9JOn5KMPBzsokjyU7e9hipCFJyqRAY1AJLgKCLEAwKELwREcAX2ZGyrZMbKaspxQkwvi9M6AdlXaFfNmSH85Nd8J5B8Emw4HSESrZqfOPRaTZItbbmwvyeZJFVkBw3dImUFZNeydAzDXqnQ1Eq5MVCqgeirPzgNnLUquQ1p47XnDr2h2rZ51Cz165ij03JK2bpi/kmXM9PCRZIskNmmISUnAjIjoKsSMj2Kst3XxjkedoApsAN2Q5pRE6x83OSg+9jLXweFcjHYXre9Wg55FZxMFTwskvBOyFq3nNrOeYx8WOsBZKCJcTkuyXE+LZZF8dIiOkIMD0ioMgjAaa7CwYKGBMINcFwZyLUx0NjAjRnQlM6rM2Hx7M4fncuhxdH8+KsKLZdFchjI4O4tVhQmSO4IVow2CnoaRSkaAQxom2B5X8DMErh3eys9/lclN5qi2whpYToSXEFkBxqItauJyxA4DR6ZVLhNKkICVBjM8izdx9E+AfLdRzz9rWI/DcrB6gEDrMOly2AEHsATquJ4EANerXApGibbAkUcqQ7MkBFXLCR2CADTp2EMJ+fw/+1afxujw4QFESbKUsKYnCCmRklHtZXXMLH62s51nwLPz97K8dblvLzrvmcfmYhZ3ZV8tvuGthTIf0uL1bAwWp4uQperYaXq+GlSnipur1eqIbnq+C5Gvm8g0ulXlgGzy2GPYth1wJ+ba7mh/pZfLNxJp88OpHX7xnPv+6+grcfuZEDt1/G1kWj2b5kLG8+Ppdjz6zi5N57Ob77br7YsYrPtt3G608tYsftk3i86nIWX9adSf1TuDQvhC5uNZlWQbbLRLxZEBukIcIk32OHVmDTyvaSr6VkMyhxGNU4jEocRmVbpcYLMT6ZFG1LQTsul+xsSqnjbR29NGYhyAizMrk0hztnjKNxgdfn4o3o7zjd4wOEjVWD2LpoJC/eM5GX7r2+FWB2LL+E5mWj2z3PBzF1tYPYVD2YTdWD2bJwBFsXjWTropE0zB/GhoqBrJnVh/VzB7BmVh+emNaTRycXtY5vr76hkEcmdefRyYU8NbMnG8oHUFc1iI1VA1sljcYj2lVa/P0tDfNH+LWL2qClYd6oVom/XqR44zn11mOT/hJcOoOVC4GWc+8i6hxg/Bct+ssfXDpbG3ChLaO/G2C+2DyLLy+kyrKl4ry6EHg5H8h8t72KY83VHNtRyXfbKzi2o/Ks6ydaqji5s7qdfmip5sddNZx+Zj6/PbuYP/Yv45d9i/hs3Y1sqSqkpo+eYSFygqhELxhoFZSFSA1zCUaEyUvfVNNQZ5uGhQhGOKVG2wUjrIIxTsHlYUpGBwqmJwlOrsmFjybD5/nwcgQcdMG7CfBeotQrybBaLnbcWSLY2k3Q0EVQnyzYki44kiY4mqeGLAt/xGvZ5laxMVgw0ipHeEM1ArtCYNYKgg2CML0g2anlwWgLO0oyoSAWuiZAdphs1fTNhmFFUNYdBnaBomT+iArkeLDgtwitHJVOt0mPTbyJ/ySY+SnayOtuHa+GanjRo+GVKD2HEwP4d5ZTTvL0TYJeXvVIlp6Wgig53RRpAoeCb50ajtpU/CvExKsOPc84dOyyadkTLNgTLPjQLAHqRJDglEMJbr2ckoowQWQAxARBnHd8O8Mpp6vyIqEgHLp4pDcn2y2rRlkuyAzjj0Qbx2LNfOXR8064hkNuFa+61bzsUnHQpeNlt553Io0cjjXzdaKG7zMDpbemwAVdwuRrK4qCkhhpMi6Olf6YklgZhFccAT3CoDi87bLUDhOSYWEI3JUC69ywPgy2BEFjIDQZoFEH9WbYHAibrLA2kKMrBB9VC3ZOEDzcU7AyVzDDLRgTIChTCjKFIFXIqkykkIstQ0TbCHRnZ84qITArBa5AabqNCpIVGP8qTHSwikizHLH2HQR9chkVuAK0WDVtY7M+KPH3PHSMqTcIeVAM1siz/lCzhnB7IK5gA06TDqtOhUG0VWe03gOeXQgiVIJItcCtkK/LP9hN6/c6fT/H6j3bjxKCshQ7N13Zi/0P1PBNy52cfuFRfnnpbk7uvpnjOxdzbMciTu6slcMAe+dzZu982FcJ+2vgQLXU8xVSL1W16QUvyLxYJeFlfyU8VwHPlsOecv7cOYM/d8yWaq7gj+1z+WNHFX/sqOI/26s4sXkm32yczpdrJ3Nk/QwOPzmJT9fJNS+fbZzD55vK+WjtTI48Xc6RzZV83ljDNzuXc7RlGf9uvolPtyzljTXVbF0xnvumDmDlhK5MGRDFZXmBDEpU0M0pSNQK4tWCWLUgTiM9NHFaaRSO1AoiDFJhegmJDrWcPLOr5HWrWmBRtuUP+Vdl/P1MHYPwfPIHHuF9X4qTIigf1ZV751xGw/zBXngZzJZFg/0i+72tJC907Fg+lgN3XsNbj8/g4P0T2XvbFey8aSw7lo/yTga1VW58ACMnmuTo8o7lY9l724R2QOSDmw0VA1lX3k+2mab0aAWYB/5RwH3X5vDo5EKemFbMUzN78tSc3q3TTk9XDmBjzWA2VA9iU+1wti4ZS8PCS9hYPYwNNcPYOG8km+aP8uoS6haMoX7R2Ha6KIB567FJZ+liAeZCYv/9AcYHIv+vAeZ8sOJ/X8cAOp++bCg/S197w+fO1yK6WIA5H7x0BJgTzdUSXrwA4y9/gDm2o7IdvJxoqeKHlmp+eqaW08/M59TOGn7YUcWZvQvh5Vvhtds5vXcp7z5yLWum9mV2kY2hoXKKpNggGGARDHbIJX2jwqSGu9qPaY9wyvyXMSGCS5yCsSESYMbZBMONgrWXC3jnOviiAA6nwxtREmLeiPIqAw7EwN1d+fz6APYPMtLUXbA9S7AjR/BFphdg8h2QbGSTRfBPIT0vRd4z1jC9wGYSWI1t/6CWGAQbsqI4k+qS7ZfsMKluCRJiyrpDryzI8vB7ZIAXXuwy+C4nRIJMnIGTEVq+cgieDRTsMQp2BUs9bxW85hacTDRJL0qPWOiZCD1T5dRTj0Rp8E22g8fASbeRb50aDrnNvOY0sNupZ5dNy36nihdCNXwSLDhiU/CDRfCjVfC7RfCHVYBNgEMJbq0EmQSz9/fsBGBywqRfJ9cDWeGQ6uRkooVvYwJ41yONvP8K1/JamIaDLh0HXTrecGt4K1zHkSjB14kaSA6QqcLZDlnV6RomIaZ79PkBpsQj1dcMA6xwrYAFTnggAB6zQZ1Bql4DdUp42gB1AVDvhMZQ2J4CO1JhUwa/PhLF8fszeLPWysarg7mll2B8vKDMIehmEmQqZBZLrBdigjocPPwBJkgtAcY3ZeQDmJgggccoR3VDtG0mXatKXvqC7UKNGizqtmA8/83G/u0bX8XFpJA/02ZQEhKgJdSswRWkJUjX3nvhH1Vv9IKYQyEIU8gtyWFKQaROrj+wiM49QWohyAhWMK4onfvKJ3Bw3SqOPbeGH17YwPFn7uXfW2/lyOZqvt62iGM7FvFd80JO7qzl+13zOLWzitO7a/lzz1x4rkrCy/4qODBX6vkKCS4+oHmhUmp/pbcCUwH75sCecnhmNr9unc5vTTP4rWkOv26dzZmt5fxny2x+bJzDqaYKfmyq4vstc/lq81y+rq/g2y1VfF1fwWcb5/DJhll8UVfJZxvn8uHTczi8fjbvrZ/N+xvKObxpPp80LuFI08181LiC9+pW8M7GZbz0ZC3bVt3Io7VjWHJVIeWjc7iyOJz+iQa6hAoyLNJHEyq8Usm1Cy6tPOkJ0UpflNsgL53eUD1fC8rkN8rf2abzjoZg/+RglZBRAP2zE1h0ZV8eqBxP/bxBrQDTuHBQ276h1paQNMq2rLiUl+69nnfXzObg/RPZc+vltKwY08lYsy8BV45i++Bnz63j2X3LFa2emvp5Q9vlsdTVllE/byibKktZP6cf62b35fGpxTw2pTtrZ/Vi/Zw+rJst4eWB6/N54Pp8HpnanUemFfP4rN48MWsAa2YPZO3cwTxVXsqauYNZWzWkFWTqFoyhbsEYGhZfSsPiS/8+gHnv0Rta9f5jky4KYC4UZi6khXSuFQLng5dzAcy5Ki7nqqR0VnHpGETXKbxcgC4GYP4KXjoDmBPNlRekH1qq2+nUzhpO7azh55Y2nXlmPr/uWcjv+xbDS7fAq6v444WbONo4h703jebOKxK5MUfLYLugWCvoGyAYZpfL+0aGttdoP13iEowLFVzuElzpkr6GiWGCw3cMhHe6wZG+8GEavBIuoeW5SNiaLP0SN2fx3lVamnsKNuYLduUK9nYRfJUl+C5fJT0eyWYedihZJATJgTI8zGaUCjV4z6ANMjOii1IwPNzA/bF21mbH8GG3JI4Up/F7USr0zYUhvfg+L5m3QvW86dDIUejcCMgPlT6brBCINfKpU8VbRsEak9RDVsGDFsFDNsEjTkGTR3AgLRDyQqB3PPROhH7J0CcDeiRBVgzEh0CklTNOA1+F6PjCpuZ9q+ADm4KvXFpORJv5MzoYkkIg1SWVEiKV5oJ0N2R4lRkmJ54yPZAVIdtjuZFt01A5YV65IcPJ76kO/pMQzOdRgXwSbuSdcAOHvNWXgy4dL4XqeNlt5C2PhveijXwRZ+TbVAtnMuze9lQEdItu8/r0TJTyAUxxuLcCEyVbTCVe9XXAyFiY4YFF6fCYA9aGwaYAqXotbNbAZhPUB0BDEDQGwxYzNFlgux1anFBn58d7BW9WCfbeIFh/qeDe/oIl3QQzEqUxuFhI71OSaNtS7QMYh1IQZRYkBEklBwuSzILEQEGMoc0kGuHzVajlKG+oQWa8OIxySqjjgct/O3aAkKPTNq18nsuoIMwoD4x2tQQs3wHQP4o+2Htw9QhBjFoQrxUkaQQJKkGiXpDvNJIXbiPdEUCKM4BEu4F4ZwB58eGU5sQxfWwp2+6q5Yt9T/PboW2c/lcDJ557mK933cOxZ1bx5bab+HrbMr5pXsmxHUv4ZvsivttRy7GWeXzfXClPZnbN5fc91RJifJWY/VWwvwIOVJ6t/RUSYA5UwnPl8GwF7JvLny1zpJorvFWYSn5rmsvprRX8vKWcEw0z+G7zNL5pmMk3DTP5atN0vq6bwRcbp/HZ01PbnWTKNPUZ3hPiaRxeM5X3n5rKB2un8fG62XxRV8nXWxdytGkRR5uW8GXjQt5dU8GL99xAw8KxPDipF5WlcUzIMtHPLejpFPR0yyTyJJ2sVsVopKI1ghitHOX2aL1TTmpvOrBCVvCCVG1qTQr2vpcmRVu1xijaKnXxJsGlxVncfkMpT86bQP28gTQuHNQquem5LQvGF3C366ZxHLzvBv718GSev+uaVv+L/5JF36JF+fzBNC4oo3nZaJ5dNYEX77mOZ1dNaJ1o8gXMbZ4/jDo/iNlYNYiNVYOoqy3zjmoPonGBTPytrxnknXAqah3XfmhqCQ9NLeGf/+jOyityWDwmgyVjM1kxvgs3X13Ibdf24O5JfVlTPYa6JVfSsPwa6pZcybr541g3f9zfAzDvPzapVX/VOjoXwPwVyFwswHQElc6rLzP+FoDpTH8XwHzTVHle+QOM/zTS/wIwPt9LZ/IBzI9endrRJh/E/LJ7AaefWcjPu+ZzZt8SfjuwAg7eDS/fy7dbV7BnxeWsHJGFXW7DAAAgAElEQVTB+AQVpWbBoCDBUFvnAHOJSzDGLbgsRELMlS7B5Q7BaKPg1t4CtrkkxBxOhY/SYU84bNDx80rBJzMEr4wW7OwjaOgmqOsi4eW5QhVfZ3sBJt8NyWYetCtYIgQFbiMpZgkvDm8P3AcwTqMgTwi6qQVzFYIFRsF2u5J9EYF84NLzcUQgH0ba2acWNAvB63Y1ZLnlRFEXt2yh5LggUsd7ZsGrasETBqn7g6QesEitCRBstAmORShkpkqfJCjLkrkz/bKgKB0yoyHJDREWjoUH8o3LyOdhRr6JCeY/KaH8kRUhfS4F8XKSqTBJVooKE6E4FXqmQy+veiTL+3KjvabeMK9nxie3Vy4JMTnh/J7q4JtEO0ciAnjXY+StMD0vu6V8APO6S8kbbhWHwxR8FqPnZJyJXzId3omniDa/T3EclMR3DjA9oqA4SgJMbyuUBMFwATc44B4TPO6U8LLZDI16aNBBQyA0miXA1Jsl0GzSw0Y9bA6ApjDY5oEGD2wM5cz6WE4+6uLwP6PZX2Xk4cs01BYKxsUKuqnae2aUQuBUCWKCBEnBgmSLglSLguTgNpBJMitIDBTEBcgE4ZhAJTGBSjxmJRFBKkIClZhV7cPKNF4IMXrBxaoR2HUKQo0aXEYFTp1sTdiUsi1hFm3+Ct/z7F54iVYKEnQSWBL1cqQ4QSWIVgmilIJovSAuQEmCTU+2x0a3lChG9O7GzbP/wca7lvHS2jt4Z8vDvFN3B4e33M0XzXfyRfOdEl6ab+WHvas4uft2jrcs5ei2BRzdVsXRbVWcaCrnRFM5p7bP4syuubKV9Jy3suIDGH/5A4zv6/0VEmD2lMMzFe0A5s/mKn7fVsHprRWcapzDiYYZHK+fztHNMzi6eQZf183gq03T+fem6RJizqqkz+KzjbM48vRsPtkwi483zOKj9TP5eN1sPlo7k/fXSH3w1Bw+WlfBkbqFfNdyK9+0rOJIwwoOPjSXfXdOYW3tOO6+cSA1l3ThuuIoylKD6e6S27xTAwVxBgkxviyaML1UiFbK5pVVI7DrZUvQqpftQYtOXgap2wDH6l0mmmpRMb5PPjdf158nasdTP28gDQtKaVhQKiHGCx8+D8uGioE0zB/GrpvGceDOa3h21QT23T6+1bzbbkO0Vz54aVoyjL23XcHB+ye2tp22LhrZbkposxdi6ucNZVP14NbWUtu49gjps1kyii3zh7CxamDruPZTc3rzZPkAHpnZh9uu6crKK3KYOyiGq/ICmJBn5rpCOxN7OJnU003tyAxWzx5G3ZIraVxxbavOApizFy36tYsen3KWOgJMZ0bd8wHLxYDN/wIwnS5k/ItVAv+tt+V/AZiOFZaLAZjvts49j0m3+hw6P7D4Q4u/OgOYdjCzS+qn3XP4eW8FP++r5ae9NZzZvwJeuxNe+idHG6qpm13ArG6CMS45vTQ0WDDWJRjnElzuFkxwKxnvUnCFU8HldsGVYUqujdQw3iqrMHXjBX/WD4VXB8H+XvBIHF/OU/HqBB0tZYKGXlKb+qjZ2EtFc7GKHSVq/p2v5WhXo6wqZIWyJVjB3UIwzKxioE4Qq5WKNCiINChwG7xlYZNUok4QpxbkCjndkuk9W08XghQh9/lsTfPIFNwecdL30TVcVjM8eg6ZBc8rBHebpG4JFNwaJFhhkVpiltpuF7yVEyINr8Pz5bLGwbnQuwCy4iE5FOJs0scSHSjTe9NCZRUlO1K2fXLCpTG3SxR0i5KVjj7p0D9TwlC/LOifI9UjGXK9ycMZoZARJuUPMNkuCTWZLv5MkXuavosy8VW4jo9DVHzkVPKRXcWHVgXvW5V8YFPxllPFOyFqPnBpORIVyPdJVn7N9o5pd4uTaxlK4uUCyZKoNnBpVYxUUQQUhkORDXq74BoHzM+GR8JhbTxsM0NTIGw3w7ZA2GKEBj1s1kKdGjYrpeoU8nKbEXYFw3Mh8LwLDkTDPg9sj+bEo0aerxHc0U9WZLoJgcurKKUgLVBBWrAgy64ky64k06ZoVbZDS7ZDS4ZdTbpNRapNQ6pNQ5xdTZxdjccs/REmH7AIme5r98bhu7Ryn1Korq0lERWkIMmmJdmuIy5ABuAFe6ElTEgPT4JXiQpBslruVIpTC6JUAo9Cwk2IkFNYZq8sSnkg9QSbSA8JIj8yhNL0CC4rSmfG8B4snziKh2qu4+mbZ7P55unsfmA+HzbcwXfPPsqXzXfyxbY7+KZ5JUe3r+D4tgV8u6WG7+pmcGpbJb/unMuf/pWYCwGY58phb6XUrir+bJnLH9vn8vu2cn7dVsUZL7ycapzD8S0zOdYwg28apvN13RSO1k/jq02T+XfdVL7YOIXPNk2T6hBQ6jtp/XTdVD71DzxdM7lVMn5jJh+vn8mRp2dz5OnZfL6pis83VXFk0zyObJrHB2trePGeSTQsHsf9k/owd1AC13axUxqrortDUBgil+LGaQQxKtnGC1cIQr1yawRh2rb32bdDK9TvM+AxtiVJZ1oE/xiQx91TB7J2/jjqavtTP29gG8jMH0z9vEHSgFtTyoaK/tTPK2PnTWN5dtUEdiy/pP0os7fi4i/5/IHUzxvEc/8cz6sPXs+L91zH7lvG0bBoGPULh7J5wRA2LxhC/cLhrVWYjTWDebqylLraMrYsHMaO5Zew86ax7L5lHM3LRrNl4TA21ZRKiKkexIbqQaytGszjs/tx27U9WDIul/LhmVyWZ6NXhILCEEF3lyA9QFDiUTJ1cBb3lY9j3fLJbL55KhuW3fi/A0w7eHls0lkVl3cfv+Ev4eTvbiGdK7TubHj5+wDm/1bL6P8FwHQGLBcDMD+31LQCzKk9c/l5bwU/7a3h5321/Oe55fxy4CY5xfTqvfDGXfyybwnvP3QD6yZ1obIwmDGhgiEBcvJorE1wRajgWo+ea8J0XBmmZIJb8A+3YIJNcFWwYO0YwbH77Hx9ZzDvTBXsHSuoKxE8kSdYky94Mk/wcI7gkXxBXa409H6eq+arLno5IZPn4RmXkdVCMDxITalekGBUEKeTABNtUhFuUuI2CMLNgiirINsi9/LkCUGakJMtUd4DSYwQLBaCPV2SJbz0TISiSKm8SIgwcMgs2C8EdxqkbjIJbg4QLDVLLTELFpkEG/SCvRFqyHTAgDQoy4OB2dArvz3AJNkhxSnhJS0UUkIh0QEJFn6LNnEmxsSvcYGQbJFVoIIoKPKOaffOgAG5UJong/kKE2XbKyMUMsOlsnzhe15luaUyQvkzxcGPiVa+jTTyqUvDh3YF7wcJ3jYJ3gqQejVI8LpV8LZDwQcuLV959JxMtMj2VX60NyU4Crp7vKPUXnApijwbYLp7JMAUWqBMwFU2WKmFh9xQr5faYpTaaoJGQ5ua9LDNADsCoCUQmgPbAOYlDxxMgNdS4O0SeL0QDvTjy4c83DfawlURcgzbI2RbJiNIRbpVkO1QU+DWk+fSkefSUeDW0zU8kK7hgRSEB5LrMpDtMpHtMpEcaiDRqSXSosKuEQQq5Bm2zx8T6vVQRBiVxAbpSHAYSA8PpijVQ7+8RIqTw0lx6FuNxiFCtqhivCbTJKVUokIqRiGI9n4u3V7Y8XlfTKK9qVQj2pYJhgnZSs0IlHuZisI19E8IYkS6lSu6RlA+OJlVE/vy7F3TeGfdIo5sns+3O27ip11LOb5tAae2VXJ6RzW/7pwL+2q98HIBAONTJwDzW9Mczmyt4D9byvl5Szk/NczmWMMMvquf3g5gvq6bckEA8/H6qXyydrJXU/n4qSkcfnJSqz7yi+1oBZkNFRzZUMGnG2v5dGMtn2xaxCebFvFh3TLe27CYlx+pZvc/p7Jm/gTuuLGUyksKuL5PHKNyQ+mfaKIwUkemTRBjkgnBbo300diUbTDqg5dwg4QXH8C41BJgri8t4J5ppTxZO5ZNNf2oq+3vBzKD2FQzgI3/h7u3jqvCbv+4vzSH7u7ulgYJwa65ntvc5pyCYiKlqCiYGLMbEQPFnoUixqypm5s6O9Ydtk7d+/nje84hhrHtvu/f8zx/vF+cAyJuxnlzXZ/rugraqZfT1RS154Ox3dk5/kU2j+6qPjMgd780lZeNxR3l5xdmsm5EO/ZOe41Ds95i3/Q32DXpZTaO6cr6UZ1ZN7KTki5q1hY1TCzVTX6V+vKe1E1+lbrJr7JtXA82j+7KuhFSrtYWdWRtUUdWF3ZieW5bpr3bmtEvhpHT3o/nQ4yJsZTj7b668gaUp4bghUg7xr/bgcVFvagu7ceqsX3+8wLzpJ0v/1mBkTyt8vLk6ktTVOVFFV/WDP0LX60fpuQ/LzB/V17+jsCoaLznRfJXYbmxq+iptJSBacyd3cUy4KscvVZxb+8Y7u8v4U79aK7vLOTe7nw4XAInyuHYZO7uHMVnM1+l4s1QcoLlorJ2uoJMXTmR9J674C0nwVs2kjfNBK8aCkYHC6pfdGbjC+as7KhLRWsFc6IE5SGCSUGCSSGCyaGCxZGClYnanAnX5UK0oXKfiws3vGw4ZyCYayiYLARtdQVpGgJ3XU28FNr4KWRJPkxPEKVclpaiL2inJWgtBE7Kf/TdhJxqqRSCS/G+DYvbVC/IsV7gYcw5Y8FRIZihL5iqIygzEJQqBCMNBaOMJSMMBRN1BHMsBD/6mkBGELQNlW/TwiHcHQJtwdNUbtFVTQoFWoOXFbia8pOzMV/b6HLcTovjdlqccNPltK8xXweY86vqinRaIGSGQbtI5SHIAJmziXaHECdJmAOEKk8jNEZ1kNLfhD+8FDxw0eeeoy73rbW5YSL4Rlfwtbbgir7gmoHggongiqUO5+z0uOpqwg0vC9nqinaGWFdZpUpwkxWZRE9IcJUkusvR69ZuUnASnSWpNtDGAV62gyHhMM0N5vlDtRWstYEtprDZGLYZSVmpNYDdRrDXWkrLPjs44ABHHSXHrOFjOzjlAp+7w4UA+MyDWzUubO4neMNBkC7kTaZEE0GopSDCRosYRwVxzkbEuegT76og1s2MaBcTYlxNiXYxIcrZmAhHA4LsDfC30cXHXOBqIL/7dtSVL1BuyoOVfmaaRDkYkexlS2aIC+3C3UjxtyPC0QAXTVl58dCQxx7DjQShBoIwXUGItiBQSxCgKfDWVMqWhvyzaS1kG0y/GaogaeOV9apr2zaqi9raAjtNiYMSJw15IblLqDVDesQxqXcmy0e+wYezczhVNZKv14/gzt5yODSePz8sg4Oj4MNiKSf7cxvJSm5TVDJTXwh7CqTAbM/lj6153P9gOLc353F7cx43N+dxfWNuI4EZzPfrB/Hthhy+Wd+fL9cN4IuaRgLTSGSetQJzqSqbyyv6c3lFf/XHr64azNVVg7m2egjXVg/hSrXki7XD+bImj2s1RXyxbgTX1o3mSs0oTiweRl15b1YVvcDsfm0Y+UIkWWluPB9mQSc/BdHWglATgZ9hwy4a1bZgL12Jh7KK5qklSLQTZGUGMDsrjVVFPViTn0FNUVtqijKoKcpgbWEma/IzqM7LZPXwDFYPz2BNfltqitqr7yQ1TBh1VldsVKwb0a7Rz9GGfdN7Ul/+KjsnPM+2cd3ZXNKN9aM6UzOiQxPWFnWkZoT8eXeUvcDh2b358P1e7Jr0MjvHv6ieblKJz9rCrlQXdGFFQVcqhnVgwrttyO0extsZwWT4meFnKnDWkn9uVZfTg+30eCEljFFZr7Bw3GCWjM/971RgnrWF9PfGp5WVlpUDm/IfkpdnFRg1T5g4+m8KzI9bC5rQON/yrAJzfeeIRvxVWm7uHvFUbu+S3GnEvd3Fah4nMHfqR3OnfrT6+f09BfxRX8i92kLu7xoBR6fDZ/Ph+CJubhrDyalvU/V2NLlRpnRQCDrrC543ldWXfq7aDHLX5VVDwcvaglx3wdI2gsq2WlSmGrI4QZe5cYI5sYKZMZJlMYIVCVp8GqTJuUiFFIBge4jw4qa3LZt9HFhioUcXY021wLjraqoFJlhbEKrbsPG1raYgrVEFJkQIYoVgo4ngmzZhcuOsSmCS3eUyOX8rLlto8ZEQTNMVTNESjNYWjNERFOoLRhhIeSnUF0zQFpQrBOesBA9iXCDNH9oEQutQCHCQ8uJrKfMk0a6yXRRqJ4O7jgZ8aa3DeSPBfhPBAVPBXkvBfhvBJ9aCC656EGApNwCnBUPbCGgXImkTKiUmwk3edwq1l4Q1k5gQa0mYkhB7eX4gwA58rPnDUZ/r5oJvTAVfGQnOGUs+NRecs9PjOwd9fvc0lyPmUQ4yVB3jKIUm3v3ZBCbRAtI0obs55CukxKwwgzXWsMlISsx2Y6g1hToT2GsGB+zgoCMccoajym3OJ1ykvJx0lLe1TrvCaS+4FATnO/JgizfLetrS200QbyQJtRRE2mkT62RIvIsx8a4K4l0VRLuYqFHJS7i9gkA7BQG2+vhbaeFpIqXFzVDgbapBkI0+sW4WpAU60z7UnY7hXsR5mBNgoYmHgby27Kkn8FbI6l+YqRSYMENBhEJKTLCOlBgfLVl5cRANY+EmjSouzSdgmgeIVde2VS0NJz2Bq0LmOdwVAm8DSYCBIMxMEGshSHcW9EuwpLCTNwt6h7NnwgtcqHib37bmKeVlZIO47B3WVGBUU0kqgdlbJAWmNr9FgbmxafhjBebbDTn/WGBUlZjHcWXlwCZcXj2YSysHcn55Dp9X9OdMxSDOLh/C51V5nF2Rz9mVIzm3ehRnqsfx2crR7J0/nK3l2VSMeJ2ZA7sxuGsEb6V48kKMKxl+ZiQ46xJhJQgxa5AYbz15gdpLW9DGTYsB7YOYnZXGioLuVOe1oTqvDauHpypJV5LBqtx0VuWmq6swqmCvqgoiadcElbysLcxk85jO7Jr0IttLn2toTY3spBSW9qwtat9EYNYWdWTTqC7UTnyJD9/vxf4Zb6qzNqrJpnUjOykFqBtrC7uyPL8Liwa3ZcwbSfROdaNruAPxTjq4aDeM8qtul1kIQaiDglczohjd70VKB7yGeFpIV0pMX84sy2qRxvJyflk255f1U9O4HKcqyTXnmcXlKVNGTxKWJ8vL00emn9Q2al6R+Sci87gJo2cRmCe1iZpXW5qKS1OBeZzE/L6riOvKx7fqitXc2f1k7taNasK9+tEt8kf9CB7sHcmDvSO5t7uQmztyuV9XBPtHwUcT4Oxs+Ggiv2wYyO7iZGZ2tmRwoOBtR8E7zoJ+boK37ARvWQkGe2kzwFUw0F2Q5y0o8hdMTjCiPMmEicmSWQlGzE4y4aMwEz6LtZEvziFOcsttiDMPwlz40dWIcmNBnhB462vira9JorYgTkO2hqbpC/boSfZrS+p0BduEYL0QVAvBFUMht+ym+0GqjzygmOgOrYMg3IU7jkZc0RLM1RLMEoJiTcEoLUGBjqBIVzBcISnRk+w0ElwMsZJtn8xQGeL1tQMHbQi2hQRvecQxylneVgqy4badFvvNBXWGgtWmgmozwXILQaW5ZJWN4ISjFldDrGX1IzMYnouFlxKhcwKkh0OUmxQ81VXtkGaEWkC4pXIfTqNFeDEuknBn2d5yMwI7bW6aavKbgeCaoQZfGmtxyVzwlZ0eX7kb8HOgJX9GOsjx7WgXuZU43l2Okicpg75JXrIyk+guiXeRxLpJ2tjBqyGQ7w8T42ClCay3gV2GUG8KB8zhoCUctYVj9nDMDk44wCdOkk/t4bQjnHGQnHaEC+5wNRTOB/DrSm8qXhb0dBB0NhC0shQkOmgR42JEjIuRWmCinA2JdFIQ6mBIsK2CYBt9gm30CVISaikIsxLE2WuT7mFClwArng9z4OVQB7r7WdLFRZ/29to856xLOytBso4gXlOZuRIyWBwhBOFCvg3Tkocuw/VlJcZbUwq1KrNjIwSWoiFz03wHiUpgDJQ/xlTIiRk7XYG9XsNYsL2h8vSBQuBoKNsbjvoN1YJgPUGIviDNXPC8pwZ9wwRTnndjZ0EMZ+e+wO81b/Nn7SA4ViT5cIjk0DAlygzM3iLYnQ+1hTzaNpx7mwu4uymPG5vyubEpn1825fHLpjy+Xz+E79cP4dsNkq9rBvNVo7CuDOw2/gZ1mDrPcm3NUK6tHsS11YPUC08bWkrZXF6RxdWq/lxens3l5dny8WPFRvU5sg11rjKbc5XZnFnWn88rB3B2+SAurBzK5ep8rqwp4MKaUZxdVcSBBUPZOqUPNSVvsHBwZ4pejCSrjTuvx9vT1kuLJHtBsoMgzEiO96c5CHon2VH+ZiTLhrZlVW4qK4alsCo3Vc2KYXLfStWQVFYMS6M6L5PqvHbKkedO6hzK2gIpLCppUVGd14aaorZsG9ed2onygrQqK/MXgVH+XDXKx5tLulE76WUOzHqbPdNeZ3PJc+qczPpGU0trRvVgbnZrZg3IZPQrEfTO8KdLqCV+ZjIbpMpnNb9bZqwh8LE3pkvrSHp2Tn02gXmcvKgERopL9l8EpiWJaS4z/ymBeZysPElevlg75C/TRk/KvDSXE8lwvt4w/B/Jy9NGpP+XAvO4Csx1JY3l5XEC01xanlVg/qgfwf26IjX3dhdyf3chj+pHcm/HcKgfCSdnwNFJcGwGx8s6UZpsrBaYHG9BPyfBO7aCtywFvSwE71oKsmwFWQ6C/s6CLFfJCE/BaD9BrZvgYJBCHl4McZIVg2AnaOXBLX9bFjgoKBYCfyMdgs0NSFUI0gwEK13N2B7mwdfB7nwf7sX3Aa78EurFNyFuXPSy5riTBbsMNPjCWMgX8zRfSWOBifECP3u+NxYs0BHMVArMCA1BnqYgX1uQq98gMGN0BdsNBGcDzOWdpDYh0MoHnE3BVSFHnZP9pcQkeMkXcj9LfjGT8rJDV7DCWLDSRLDMTFBhIqgwlY/3GAmOO2hCgLnM6ryUCD1ToVsyZEZBtIfMqQTbyE3BTeTFVspLhJVSXpTypLrvlOCpnG7yliIUZAcu5twy0+ILI02uGAjOGgkumgnO2giuOOvym5chdwItGk4QRDvJ4LFKYhI9WxaYBE/l1zOHFCt4xQCGeUGFPmy0g0M2cNgWjtpJcfnYCU66wElnyacukjNOShzgrCOcdZECc85fSsyl1/h9tS+T2xnSw0wQbSVo7aRLrKsxsa7GxLnoE+usR6STgghHfSkvtgpCVRJjqyDE3oBoB10S3Ixo62tB52A7eoTY0TXQms5eprR3NaCDow6ZNnJvUoKeoLWe4HknwczXYtkx+nVqhr/AhOfCec5FEK8n8BcST2U10EmJSmAslRKjWqjWuHXUvH1kpKzAWGkrA8XNBMbeUMqLk5HAxVCOkwcaSyKNpMBE6wgSDAQpeoLu9oL8WMGM7mZs7O/BkXEJ/LT6ZdiTAyeK4KN8ODpcvj2s3BmjEpgd+Tz4YBh3N+WpBeb6xjx+2pDLTxty1QLzzfpBfLN+UIsC01Rkhj5WYOTbAX8RmMY8vjqTxeUV8nWtscB8XjlALTCfVw7k88rBnKkYxKnl+Xy+spBPV4/h9JpxfLpqLMcri6mfP5z1E/tQOeoNZg/pzqieSRS8GEOfNE+6BhnzcpgR/dKcmdgzjCWDM6ga2prlg5ObSExjgVk+OEUtMDWFHdXCsSa/rZIMZQUnnVW5qeq3NUVt2TymMx+M7crG4o6sG9FOZmOK2lNd2I7VBW2pLmyn/rlUErO5pBs7J75E7aSX2Tb+BbaM7cHGMd2bCEzNiE6sLOzCzL4JjO8VR373AN5O9yXVQxdXffln1Vg8/maZhpDBc1t9IQWmxQV16jZRy+LyeWW2ZFnDb5bk2aaPnkVaniQuTxMYlaQ8rW3UWGCeFtptSVBUAvO/kJf/tMDcqB35WHFRicr/SmAaV2Ie7B3Jw32jebR/DI/2j5LVmV353NuVz5+78/h9fT82DAjgXQ+ZkXnZRl4l7uWiPDdgIXjeRNDDWNDNSNDFQNDeQNDBUNBZIYPBZTa6zPKy4rcwB263coMQM7loLdQOAi05YqNNtRB01RR01xFkawqKrTX51d+RO+Feyhdr5Qr+SGeI9ZBTPmHufG8s+FYhZD4kzRMyvCHJXdI6QC6jC3UFKx226MiKzVghqzsjhKBYQ1ZhinQFI3QFI/UENYaCj/xMIMZTjj2HuYOjEfiay6pMaiC09ofUAHkY0tuUnw0Em/UFG3UEi40l80wF880Esy0kC4wFFZaCM86C32JtoHsYvBILXZOgfbQM9Ia7yLZQoLU8YtmkCqM6CGknCbOTY9bR9nJaKMVLClyKpwzkhjmCqyF3LXT43VBwyUiDi4aCT801OWOtxwVnA656mPCbjyV3Q5V7Z6KVAd/HCYwqIJ3kJk8RxDtCsjV084PhzjA7CXa6wx4f+NgePnGAz6zhtC2ccZF87io5p+S8K5x1hvPOcNEFLropiYDP/Dk5zobB3nIXSLq9IN7FmAQ3E2KddYh11iHM0YAQe30C7YwJdjAl3N6QMDsDIu0NaeVoTLq7Ce19rOgRYEmPAEte9DXkBR8Fr7hp8ryToLO5IEVbkK4n6BOgxZrB6Xy/oQROLIQTC7m1exI3aydwbtlAasc9x+K+iUx60Z8BiTY87yVobSZopSuI0hN4K9ubnkLgosRBKTa2SrGxUGIplHeThMBeSx47dNUTeCg0JQYyp6PC3UjgYSzwNpHZnRAzKTLRxoJES0GqqaCLo6AgVlCWYUB5W8GsLnps7OPA8ZJo/tj4FuzMgsOFcHIcHB0FBwth70jYUwi7ini4NZc7Wwq4s6VAvbjux42SHzYMVUvM9+uH8G3NAL5e25+v1+ZI1gxSMoSvqgfzVfVQvqoeyheNuLZ6CF+uHqT8+GC+WDWQaysHcG3lgBYFpqVOgkpkVM/PL+vHuYq+atTfzFf250Jlf85VDuBc5QDZbqoczNnlwzhXlcv5lQVcWF3EqRUFfFwxjINzB7BvZhabynqyZEg7ZvSOpfzNSOb0jqQiJ5GqQQlUDUpgxeBkVg9LZfWwVFYNTdpN5b0AACAASURBVGHlkFRWDE5h5ZB0NhR1Um/NXZPfnrUFHdQBX9VIs2qsuWpIKlVDUqkpaq9uMzXITtsmn1edl8mqvHasymvH6oL2rMprx8Yx3dk2/iU+GCflRXXXaF1RF2oKO7MmvyPVeR2YkZXK9L6tGfVKNFlt3OkR406ErQZmypbmMx9b/W8JzLPkXv4b4tJcVp4U2FVlWZpv0/23AvN35eWHD/L/Xy0wN5rJy39SYBpLS3OB4cBYODCGh/uKebhnBPd3F0J9ARwew63NOdQVxTIh04bX7AXdTQQvWAiet5S3k54zkkf82utI0rUFqZoygJkhBNlCMNZCi6uuBvwe7qiUF+UF5UhHTnuYsUVD0FlD0F5IgZnsYcqNEDeuBytvIalHje2kwCT7QoQn3xgIrmkJ8DKAFHdo5y+3zSa5y426KYEQ6w+eVtSb61KjFJixjQRG1UoaqSdZoxAc8jaU4pQcIAXGxVS2j1ICIC3oLwLzi6EUmA3agoWGgkVGgjkmkpmmkgXGgvlGgoMmgiu+2vIydPcw6JIAHWNlBSXKHUJswd9CCkyYrZSXICvwNeahl4I/vEy5527M7+763PA05KGvAoJN5Z6dRHcpGCme8rZTlBu4W3HfSp8vLfS4ZKTBxyZSYk7ZyIOQ3zgp+NHDBHxMlTtjHJVTSh4NApPg1lCBUYmM6hhkgiUkWcGLQkrMGgspMJ84wEknOGUDZ+wa5OWsu0QlMBfcJJdcJZfd4YoHnAuFixHcq0liRqaUlxQbQYKbCQluJsS56BLjpEWYowGhDgqC7E0IcTQj0smYaBczYpzNiHezIN3dhHbelnTxNqGLtwndPXTp4qpJJytBpomgh61geJwd2wqf59aOGXBiKRyez+26yfy2vZSbtRO4V18OHy+Ejxfy4NACbtXP5KfamXy5eTJHF4ygZuSbrCx4g7wOoXTxNSfKWOClIaeobJWiopIWi2biosJFV8qLl5E2XkbajxUYH1MNfEw1CDIR+BvKoHusmRSYrs6CEYkaTOloxvweRrzfSYdZHQTzu2qyvrc1BwoCODc1lV+rXuLBln6wMwd25UF9EewbA/WjeLizmNub8/h983B+25TLDxtylRIzrInE/BOB+aJ6qFpevqoezJerB6kFprHEXGsW8n1cNaYlgWlAOexS0V8tMJJhnF0+jNOVuZyuzOXTqnw+rcrn9MoRnF45gpNVhZyozKd+xrtsm9CT6rxMlgxIYFlOLJUD45sIzOphUl5WDU2jOrctm0fKpXOqPS1r8turBWT18AxWDEtrUrGpyElUt4TWFrRTh4Gb01hgVuW1Y0VuBmuLOrK55Dl1q6imsDNrCzqxJr8jq3Pbs2JoJlVDMng/O41J78Qz4qUo+qS6kOZrToCprAA2bxs9s8A0fvwkgVHLS2X239r58qyB3WeVlyePR7cczG0ezlVt0v0nAiNlJU/J02XlcZWXZ5k2aiwtP20rUvO/qsA8LQPTkqzc3zvmqbQsL8U82DeaB/tG8/DAKB7sK+Ze/Qju7ini0d4CGQY8PAoOFfPTuiHsKExmZJQuL5kI3jIR9DaXb981F7xhInhJT9BFR9BJS04XtVcIumkLXjIUzLMVbGtlx0+x1vwUaw0RlhArt9Ret9GkSlswRwhWCcFhZz3ZcgpygDAbiLCDCAuIspajvXEO3HTW5XMhJ4y+d9aEJG+ZWWntJV9w0/xkSDYlBMJd+d7BmE80BAuFYK6yCjNWCEZoCop1BGN1BCXagvX6gsPu+lJg0kKkwLiaytBuaqAUl2RfKTHxXhBowx0zwW49wVYhmG8omW4imGEqeN9cMMtSMMdUMNtEsN5MsN9TW/63tPWDTq2gi7zpRLCDzLEE2zds5g2yBX9L7vpY8LODHp/Z6/GJjRb7HTQ44KjFXmfBATdNvvMx5lakgwwZxyurMW38oZUbeBpz11bBjwaCkwrBKUPBMQtdPrFWcMFBwVVXE+67K+Thyyh7pai4QaJHAwkukkR7ieo0QYIvxHpLkclwgv5W8H487PWFwyFSUi55wQUvOO8J59zhgkeDuFx0UcqLs+SKkkvecM0fjrVi9xBBe3tBmoUg1VWfNDcFia5aJLhoEmmvQ5SjLlF2xsQ4mNLa1YRUdzPS3U1IczWmk5sBXb2MeclTnxfcdeluISX7OXPB5A7eHJ3yOnd2ToKPFsKReTzYO4kbO0q4vn0k17eP5NbOsdyuHceNnaXc3FXGzbpy7u2fwcMDc3j04Vw4NI8H+2dzr34aP28Zy7XqPPZNfoXxz3mQE6+go50gUkMQoS2n5lQtJ9UknaeQ49iB2oJgXUGEoSTUWBCkUE7FaAp8DJQTNMYa+JhqEWAix68jDAWtTAXJJoKuLoJRyVqUdzJnbld9ZnfSZUamYEqqYGqGYHo7DWZ2MmFBD2vWvhvC5v6t2JWXwbHxL/LVssH8vr6Y65vGc2fbFO7uLufu7nJ+rx3PT1vH8u3mUXyxrpAva/LUk0CNUS2su1Itl9c1F5fHCcwXqwY2qcSoeLrA5HB5RQ6XqgZwobJ/kzhFS0LT8PFsdWXm84r+nFmWw5llOZxalsPJpdkcX5zNJ0sHcHJpNicW9mXPhBdYMyyVyv4xLB8QS1VOIlU5iVQOTKSifxxLsuJYNiBRLTBbiruxrqCD+m5RA00rLyqBqRqSqg4ANw4Eq378imFp6uerh2ewcnhbVuTKt6qR6tUF7VmT31FddVkxNJOqYZksyEpiwjuJDOvqR1Y7X15sZUmslxkOOv/gYvdnS/upZeWfCMy/ORPwb8SlJYH5u/LSWGAeF9h92j2jxgLzd+Xl74hLY2n5efsINY/f7/L3BaYlibmhlJj/pcA82DuS+3tHcX+vlJf7e0eqBebhnnwe7lFu9/xwBByaBB9N497GMRwo7MScdFeGuQv6WgkGOmowyF2fbEdNXrcSvGgs98t0NBQ8pyvooSeYbCBY4aXHNxGm/BxnA6HmEGmlvDTtzLFAJ7bb6lNvJfjM11yZmXFuEJhwc4i0lN/1x9jxq50mp4TgkBB8Za8M8maGyjBvorsUmM6RkBEJcb48CHblqrkWKxSC+Up5GaMUmJHagjFaUmI2Ggg+8jKU1YvUYAh2BmfjlgUmyUdKhpMu+40F2zQFs3QFcxSCcqXETDeREjPXXApMjbFgl5Pgrp9CTvq0i4AOkRDtBd4W4GMhv3aSL8S4y9BusB13fSz4xlJw0FiwXyHYaS6otRB8YC45bSG45qoLvmay1ZbmCx1C5ZRTpAt4WvO7mSanDAWfGgiOmGhyzEJXvdn4Dw8D2YqLsIFoZRWmscSoBCbBTqLaFxPvIyUm2RriLeS+mP5WsN4KDvg3qrQoJeaCx5MF5qoLXHOFyz7wRSCcS+PqbMFrQVJg0twUpLkpSHLTJtFVi2hnBWG2WoRbGRDnbEEbT0syfaxp42EmKy+eRrR30SPDXJBsIHjbU4uFPRO5tGg4D3fNgYNzYP8s7u+Zxq0dE7m+fQw3dpRwY0exkhJu7RzLjZ2lXN8xjl+3j5dsncD1HZO4tWsqd+qmc3/vdDgyD04uho8X8vvuKXy7eQyfLB7CjrLXmNk7iam9YhnSzocXgwzo5KVLrJkUF9VOmWBdQbhC0MpEEGutQ7ytHtHWekRaahNqoUOQmRY+plr4mWkTaCrPcUSZyBX7ySaC7m6CMSk6lHcyZ2YHbWZ20Ob9thq831aD8jaCCa0F45IEY+IExbGC3DBBToBgUJCgIEaP8o6OLH2zFRsHZXJock8uLB3EV+sK+W1nGb8o+W3nOH7aOoYfthTz3aYRfLdpBF+vL+TLmlx13uWLtcP4SskX1UPVj79aO4yv1wxpVKX5axVGReMppZanlh4vME+WGZklVbWWZF5mIKcrB/JZRX9OLJF8vLgfJ5dmc2z22+wo6cqy7GglsVT0i2Fxv2gW9W3F/HejWNwvlsqcFDaO6MIHo7uzvrAjq4e3ZcXQNlQNSVcipUXFsoHJLBmQ0KRN1FhgGldrVCHhVbnpaoGpGtZGfaBxVV47Vue2pzqvA6uGtWXZwDSW5KQwp08sY3q2on9bN3qnu9MxQEGwnQ5Wf6d19J8WmH8jL/9EXJoLzD+Tl4bpocdNGz2tNfT1huEtCszTMi7NW0GPo7G4NJeX/z8IzMN9o3m4bzQP9o5qwv1mqK7c/rGnhD/2lPCofhR/7h0N+8dIPpsJn8+FnSWcGN+Nxc+7MiJKMNBDkO0iGOAgyLYT9LUV9LYU9DQVvGQgGGApKHIXfBCow+EkW+5H2nIvwka2SiLsZfvEzxq8TeVdoyAb2U4JtYFwOwizkqR6QooHD7yNuKwnOCnk6DDhDtAhCrpEQ2aIvP2T4i+zMPHeEOkBriacNBHsFYJ5GoL3hWC8EEwQgnIhmKYh2KMvuOBlJHM2qf5yhNrRQIZm0xoJTLK/JNYLfC04Y6HPAQ3BAi1Jub5gmoFgpoFgtpHMxMw2Fsw3FSyzFXztqilbMW1C5Wh1iKPc8htkL08NJPnIaadoD4h05aarCVcMBNsVgg/0BCssJfMtBfMs5OTTBhtNzroY8HOki5SvbonwQgK0DYYIRx456XDFVHBKS3BEX3DCWHDVRovvXY3408dQZmwibJTj1Y4Qozw0GefSaF+MuyTJC5K95bh6oh8kO0KSg5SYNAfIdYLF6XDMB06HyOrLBS+45Cm57CpRtY4uekquOsA1R7jsBl94wvlw7m7Qo6iNNl3tBBluBmS4GZDsriNxMSTaWotocw1SnYzp5mNONx9zunvo87yXAS+6yFDuwBAFi3pGc2bOezyqmwafLoajs3lUV86DXZO5t2sCd2rLuLVzrJIx3NgxuoHaMdyoHcNvO0v4bWcJv+4Yy8/bSvh122glxfy2YxS368Zzr34iDw5Mg8Mz+fPIbDg6h0eH3+fuvinc2DOR77eO4vMVg9k54XmWDUyhpJs7r/kJkgwaJp6itASttAXxhpIohaCVgcy8xJkJEi0EcSZyCindQtDWTJ5jGJuuz/SuVszsYsiMzgbM6GzAzC6GTMxUMDZFi5HJhhQlKBgSY0Jvf0EPe0F7U0G6saCNiSDNRNDWUvBqgBn9kzwp7hHLvAHPsXl8FocWFvPpqlIubJjKNztn8kPdPH7cPZ1vd5bz7bbxfLO1lG82jear9cXqTbqqis3XNbl8XZPLt2sfX4VpTGNRUY9SK6WlMSqBaTy4cn5ZP85XvteEcxV91DR5v3qPWhZnlvZtWGuyuA+nl7zHqcV9+WjWm2wqakf10BRWDEySFZj+cVJk3pNU5aSwqbATO8b0YGNBR1YOSadqYKqa5YNTqBzUmoqcRJYMSGBxdjxLBiTIZXPKgG7TNpMUnxWD01gxOI3lg5XvG9aGqmFtWDa4DdWFnVg5vD0rctuyYmgmq4a1pXJQOouykljYL5HZ70RT8moMfVNc6BnvTKqrJl7mmpj9XXl5ksCo0tNN2kWV2WqBObu8P2eX9/9X8vJvxOVJ1Zdnl5d/LzDfbMzju035z7TPpfHzJ0nKk/hvC0xLY9S/N3rf/5XAqHi4dxyP9pXC/rFwsBQOKzkwTnJ8Fny2AI7M5LulWWzPiuP9DEsKfaXEDHKV9LEXvG0tyLEWDHcWVDkItgbpcivUgvuRtjLfEWwNEa4yxKrab9JYYMJsIdRSkuQGmX4Q68pNZ22uKpQCE2IH7SOhe6yUmCRvWZWJ9ZTh23gpI9dcTPjYSLBUX7aSJjQSmPe1BYfMBF8GWckpo2Rf8LQEWz056dQmCNKDpBilBspMTIIPhNhzxdGCIzqChdqCeUIuxpusK7f/qs4YzDIUzDMRLLUWXHUQPIxxkEcjk/3A1wo8zOT/hyT/hgpPgi9EunLd2YgLuoItulJglpnKKac5ZoLZpoJl+vLW02ETwQUPY1nFeb41vJkJ3WJkRcfPgq+ttTitLTikKzhmKPjCTodfvS0g0ExuIY60lVesWymJcpC5mBilxKgqL8ne0NpXbhhuHQipzkqJsWrIxIzyhnp7KTCXfJR4wmWvpgJz2U22mS55SYG56iDfd80DzofDIRemvWxHDydBpocRGW4GpHrpk+atIMXNmDh7XeKsdMh0t+CFIFteCrbj1QAzXg+xYmiCMwvfacM3VaPgyHI4thg+nMP9HWO5t62ER3XlsP99HuyZzP3dE7ldO06yq4Tbu0q4tXOMlBmlwFzfNY7ru8ZxY/cEbuyewO268dyuG8/NXSX8tmMUv2yV/LqthF+3lfDbzjJ+rx3P9V1l3KybyM36STw8MhM+W8qfx+dz79Bcfqubypnl+awt6ELpc0FkxZjzZogJ3d0ErU0FCUZSXiL15X6kYG1BuK4gQk+QZCRINROkGwqedxaMbq3NlI5mTG2vR3k7Hcrb6TClrTYlrTUZGS8YHqPN4AhBnwANenkJXnGVN9HamUuJSVYIkvQFUTqCSOXXiTUWdPdV8G68MwVdg5nUK5kVBT2oLe/L8SVDuLhuDF9uGcs3W0v5aXsZP20v48cPxvDdxmK+Xl8oqcnlq7XD/iIwjXmawLSEWmKaTd82F5iWJOZcRR91NEMlMKp1JqeXvMeZpX05vaQfpxb3Zd/kV9gysiPr8zJYMyyVVYOSWT4gnmVZ8SwfkMiqQWmsz2vP1uJubCzoyIrBaSwbkMzS7ER5LTonUV11WdgvlvnvtaIiJ1FddWmcjakc1JrKQamSnBSJ6vnQdCqHprMkJ4UVuW1ZNrgNFYPSqRiQwrKBaSzOTmZ+nzhmvxNN+Wsh5HcL4Y1oS16MsiXOVuBppvHvBaZx9eVxAtNYXh4nMM+2UffJAvPM8rJ2cBOu1gxpwpPlZZhyl8s/ExgpMflNBObxbaLhfL8llx8+GN6M/L8nLDtGNuG3RlzfWdyEG7WjnoGRz8zNXcVqbtWN5lbdaG7vGaPmTn2Jmnt7xz6W+/vGqXm4v1TJ2L/wYF8JD/eW8KBe2W7aV8LDfcU82j9Kbvb8aJzkeBkcHy05UQrHx8FH4+HEJDg5HfaN4crsF/ggO4jZbXQZ7iMYaCvIshC8ZyTINhOMNBWU2gpq/TQ5HmfJr3E2/J5gB1E2kiALCDADf1MINJfPg60g2EISbikrF6095QVpL2Nw0QcfM9lySQtUSkaAzIJEK0d/U/xlVcXfhls22hzUF+wSghol64Rgu7bgS1tN7ofYy2pDrAv3HXS4aSXkwcU2yntGKUHyRTslSB5qjPMBTyu+0hWsUeZ4JmsIpmgKpujKfTbTFYIZhjLkW2EuuGYneNTKUVZ0ErzkfSU/K0jwkyPgyf5SvOK8INyJ350MuagnWK9knrFgrpFsUU0zFkw2EUwxEyw0ESy3EXzrbwmdY+DlZOgcAanuEGHOXUcNvtITnNcWfGkiuO+kB36WEG4hW3oRSiIdZGUswkXKUCsXiPOQ+ZfWjjLEm+IBKX5y6V+av7yxlOAtf91tHOGlEKiIgD3d4GwonAuTraHLPkppcYVL7nDZAy76SVQtpKse8secD4aTXix604eeroJMDwMyPQxI8zYk3ceIdBcjWjsoyHTW5zl/K94MtqJXiDW9g4wY096fwxPfhP3z4OQSODQT9pTyZ904NQ/rJvCwbgJ/1E3ij7pJ3N09kTu7JnBnVxl3dpWpReamkuu7RyspkSiF5vou2V65vqOE6ztKuLlrHDd3yee/bhvNL1tH8fMHI/l5+2h+2yk/70ZdGXf2TubR4ffh2Fw4Oos7e8v58YMxnJjbh4NT32BTYRdm9gxjbFcP+scY8oqPoK2VIFZfVmnidQRtTAWZhoJe3oLSNgrGZxpSmq5Jabomo5IFBXGCwaGC3CjBwHAF2cE6vOVryMvOmnS106aDpdx2HKOQLawIA0GIobys7S7kNmIXIQ9UBinkzaEYC0Gqsx5vJ7hT9EICM/p2pnrMu9TPLeDjlRO4tuV9fqhbxK975vLzrln8smM6322exFfrivly7Uh1hUa1oK5xhkZ1TkB+TB6AVB2BVC1WVW2Iv1A1gAtVA7ikJruZzPTlwvK+LQqNqgKj2mqv4kxFH6W8vMfpJf34vKK/uhKzb/Ir7C7twbbRndlU1I61uRlUD01j1aA01gzNYFNhJzYWdKQqJ4XF78Wx6L04FveNZ2l2IhX9k6jon8Ci92LUArNuRAe2lHRTV2BWD2/LqtwMqoakUzkolWUD09QtoaUD06gclM6KoZlUDEhhxdBMlg1MY1FWEouykpjfJ44FfROY/U40U14Npux5X4Z18KN3vB190rzp6GuAj9k/rMA03qrbIC0DHiswjeXl7PL+f3uj7n+y6tJcYJrLy9WaJ8tLY4F5lkV0LW/QbRCYJ2VcWpKXH7fmNanANJeVFoVlZ3ETVLLynxCYxoLSEippeZq8PElg/thfqubhwQn8+aGKMrlyXLl6XP38wzI4UMqjA6XK5yVwaCwcLYGPx8MnEyUflygpkxLz0Xg4WgZHJsCJKXB6Fnw8DWpH8P28V9nTJ4J5rY0Y4S4YYCEYqisYoiOYpSFYaSW44K3JdxGmEGYhR6zDbWXmJdJeEm6nrMBYQYilFJgoW2hlL4l0lu2jMAd5dyjJR9nqUZLgKV944z2lKLTyAC9zPrfT45iJYJehoFYh2KUQHLTQ4Wd3Ixl8jXOFIAt+NRX8aCCkXKhuGaWHSMFID5GHGdNCIdiV61Y6fKAvJWayhmCSEEzWFkzVa5CY+QaCpWaCKzaCPyLspFjFeYCbIQTaSHlpLDDx3hDpwg0XYy7oSnlZoyWYbSCYYygoN5KoBGaeoZx4Oueow/1EH8gMlCcLUlwh1pZHbnp8byjl5YaLMQRYQ6iDMo9kBZHW8vchwJz7ngbc8DTlfoCyGtbKBeJtZatIJTBtAhtI9ZO/7pQAGejNcIKJDlDbsUFgrvk3CMxlNykvzQXmqkvDx88Hw2c+bMlL4nV3QVtPQzp4G9PG15h0HyPaeVrQztOCbj7mvBRsR68Qa/pEOZLX2oW1Q3twZ+dUOLgQ9k3jYd0kqC+DveMle0r/IjBSXv4qMDdqxzxRYH6vLeX32lJu1I7lRu1YtcA05/fasY2kp0F8buyewL395Tw6PAs+mgfHF8HJpfDJcjhewc/bJ3N1TTGnKvKpn9KbhdltmPhyOMPTbHkzQPCyk+BtX0FxkibFSZqMTBCMSxMUJQiGRQmyAwRvuwledhC8YCvoZi3oZCErL+3MBa3NNUk2E0SbahJlJIgy1yLSTJNAQ4GfnsBHX96AchfymKWHEl8NQZCuoJWRoI2j4PkgE95r7c6oHhHMy+7A1nFvcGzhMK6tHct3myfx87YJ/Lp9Ir9uL+WnrWP5blMhX60b3iRDc6V6SKMt8FJgrlQPkyKzenCTDfEqiWksMOrdZ88oMM0lRiUwkixOL+nHmaVZysfZfLawHyfm9ubI+704MKUnu0tfYGtxN7YWd2PbqO5sKuxERb8EFrzTirnvRDH/3WgWvRfHkqwElmTFsbhfLAv7xVKRk8jagnZsGtWF6rxMZT4mjcpBqVTkJFORk8yS/q1Z0r81iwe0ZmH/ZBZnJ7NqWFvWFXVhdW57KgakqAVmQd8E5r4by8y3opj4UgAl3TzJ7ejP2zE29E71ooOP4t8LTMvyMuCJ8nJuxQDOrcjm3Ip/Ly9/W1yaCUxL8nJt3dPkZfgzTBk9eRy6cQvpiQHdLYVN+HFrkZqftxe3KC9/R2BaEpabu0Y/A48XlCcJS3OeRWDu7xvHgw/H8+DD8Tw8OEEpMJPg4GS1yHB4UjMmy6DuoQlweCIcKZVicrwMPp0MpyYqGQ+flcHJifDJeDg2QXJwnMzIHC6TIvPpdLnd98IiOFDGhflvsGdkGhUvuDMyQpBnLcgxEpQoBOWWghWmgk1Ogo98FZwMNuWncDt+jXTgjygHHkQ7ytZGhA2EmDcQaiHbHuE2kghbuZ02wUu2YFIClFUMT1lFiHSFKBe5Z8XXEtyMuOGgyw/mgmumgu9tNcDPTLafEnzBw1iOausI/nA1klWXLq2gUyS0C4XOUdA1RhnCdQM3A740EXwmBCuEoEIIZmjKbM0kLcFUXcECfdn6uWoreBBpLV/wo93Bw1ieW0gOVEqMn/x1JHlDjBuPvMz42kiwVUewUQhmawvm6MrzB1MNlEcqjWU1ZrqJYL+14HKYcqIow1+OVkfbg4cBt0wEN2yEHJ0OtZKoQtKtnCHQko+9Lamz1mKxtSErXaz4wd+BuzF+UhrjXaC1sxwF7+APHQOgnQ9kKg9qpvpBeqBsM71mAdMy4UQrOJUAV/zhsp8clb7iARe9lCgF5rKPnEC65AcXfeFsEJzyZUteHG/7CDr5mdLJz5QuASZ0DzbjpRAbXg6147UQC3pF2tCnlSXDMzyZ2TOCi1WFPNg7hXt7JnG/bix/7BnHoz2lPNpTysO6cTysG8cfdWVNuLdnAvf2TOBu3Xju1o3nzu5x3Nk9Tv33+PruYq7vLuZGXQk36qTE3KiT1ZSWuLX78TS0n6Tc3Kgdy/UdJWoBurW7jHv1E/lj/2TuH5jGn0dmwicL4JMF/LG/nJu7yvh1y0guVfbnw0nPsX1kBnWj0tlZlMKOwkTqx6SzuziFXSNas7MohQU93Ridaka/AMHzdoJOZoIUY0GSQhCrEMQpMzbRxoJIU0moiSDISI5s+xsK/Aw18TPUxNtAAw99gZuuwEWrYbJKNWXlqiHwVQiSXQx5KcabwV3iKXunK4vy32BT+VAOLSnm0+qJXNwwia+2v8+3O6bx9bZyvv6gjC82jePK+mIu1ozgwtoCLqwt4NIayeXq4VxYOVTN+RVDOL9iCBeqBnJxxaAm9/suNBKaxy16Pb886y8S01hgTi/pp24jycfZnF6SzecVOXxekcOpxVmSRf05MbcPH5a/zs6xPagemkZl/wQW9WnFoj6tmP9uNAv6xDQRmcqcZFYPz1Aee+zG8sFpLMpKIncSawAAIABJREFUYFFWAouzpazM75fIvL4JLMpKYu67sSx6L4FVQzOpKexMdV4HtcAs6Jugbh1Nez2M8c/5UNLZneEd/HgnxoZ3W3vSwUsfPzNNLEXDVui/JTCPl5e/CoyUlsY0CMzf3evyNGl5ltMAjxOYa+uGNhGY5vLSWGBa3rD7bPtcvtuUz/ebC54oLzLrUtSivPxbgWksI7d2lzTh9p6xz8DjpeRpkqLinwjMgw/H8+jQRDg4WdJcXI5MlhxWMVFu4v1oAhybCJ9MgM+m/FVgPhkvOTFJCsyhUikxH02UAnNsEhydAMenwuk5cHo+nJoH+6dys3oYv055kxPZrdnb1pXVIXosM5LbclfrCGoUgn16gmNmgks2gq+ctSDYXL54hiv3yKhQLXgLsZJ3fiIc5XbaeK+Gdkacp5SXEOWtoRA7CHOSm2/9rLjtpM8vjrrc8jCWF6BTleFfHwu+NRRc1RbcsteVEzddWsFzcZIe8VJg2kfIHEuIHdedjbioJ1ijI6hSCsxUIZioIasxC/QFSwylwDyMspECE+UK7kZSYJL8ZQC3tZ8yLOwrq0iBtvxgLgVmgxDM0pJM0ZcSM8FAMkVZlak1FnzqZSzFTyUwkTbgosddc8EDF10ItJR3lcJt5Jh6pCXEuEKgJQccFFQJQYFyYuu8vQG/BLvIIHW0AyQ5QhsP6BIE3UKho7+UmAxlxScjSNJNDwb7wW4vKTGXfOV00VXPlgXmkvdfBea0Hx/kx9PbT9Aj1Ibnw+zoEWrBy1G2vNHKmV4xbvSJc2JAiidFHXyZ914Gx2Zlcad+Nnd3T+Tu7on/WGDu1pVyt65U/Xf9Rt1oJSXc3DOWm3tKlYxvEZWkPCuNqzU3asfy2/YxXN9Rwu+1pdyun8Tt+kncrJvInT2TuFc/mT8/nApH3ocj0+HwtKbfiBwcD/tL4UAZHJnCvdpivl05nJPTe7Gt8DkWvx1HYVtv3g41ppOzINlUEKIjMzYBuhI/PXmHyUdP4q0QBBjrqOXFSyHfumvLj/kZysfuWg3L/JyVVRtvTUGEiaCtp4J3Ehwp6hHBrL7pbBj7Oh/O6c+RBYM5tXw4F2uKubphNF9uGcvXH5TwxebRXFs/givririyJo8ra/L+IjLNW0yq6kxLY9gtndhpHM2QQpOtzMVkNZGYU4uzOLO0v1pgPq/I4XzlIM5XDuF85RA+W5jNRzPfoX7iy9SOe56txV3YVNSB9YUdqclvz6qhbagamMqyAYlUDWrN8sEpykOQ7Vmcncjcd6OZ/14MC/omyIrKe3HMfCeaBX0TmPV2K+a+HU1lThqrc9uzfHAbddVlTu8YdfWl/LUQJvTwZWxXD7XA9E72aCIwqhMXGs3QbIbq/c8sMC3Ly4D/m6pLo9Du4yovKp7lqvSzSkvLE0UFaoF5YhvpMfLSXGCeJizNaS4sd+rHtUhL8iI/1rKU/B3+TQtJLTAHJz5dYA5PlAJzYpKstJwqbyowp8bL939cBscnwtHxsvJySBn0PTpBfv5HE+DjSZJPpykrMgvh/Hw4tww+XwLH58GBaVxfOZzjY7pT2zuKqs4uzA/UYLKzYJaNYKa1YLmhoMpYsNdO8JGHLhd8jfgixJJfQ625HmHX0HpSjV1Hu8hJJFUmJi1ISk2EgwwOB5iAvzH4KMBTRz4OVe5BSfGS23Ej3fjDUpsftQX3rbUhzEWOPfdIhOcSoGOUfLFuEyCrDokeEGDDn1aCk7pyxHulkCIzVwgWKCszW80Fv7gKuQsmKQDCnMHFUEpVephsSaUFKqeofCXhdtyzFXyoJ9gpBHM1JdN1BDN0BVMVksmGkrUGgnpnfZkbSvGR+ZRQG2456vCDueBHLxNuh9rzqJUzDyIdZWg63IGbcR58F2TNCFdDXhNyu2ywEKw2FhwNdlUuu1PuiUn1hc7h0CMGuvhBR29oGyQlJiNEXvTu4AQv+cNiR9gdB+f85KmAq75wxaeRuKhCvv6SC/5w3g/ORsAnAWzITaJPoOC1MEtJqAlvhJvRu5U9WQku9E+wo6iDL3PfjaduUi9+2VnGjT2TuVFXxs0947m3V3KnvuwfIWVlLDfqm7Gn9IncbMTt+rJnRlZ1JDf3lKofqyo+N/eM5bby3xXVNy0cngQfTYFj5ZKPpsi/i0fGw6EyODYZjk2DI1Pg4GRu1Y7ii+qhfDznTbaP6UJVTiJTXg1kWJolrwZokGEtiDUShGjI8wmBQgpOiI4gSEcQoCXw0xUE6Al8dSVeOgJvXYGLtrI6oyuPY9pqyAV+1kIu8XPRFngbymOKCc5GdAy04dV4b4Z2j2XOsNdYPymb3fMKOLZyDGc3l3Np61QubJnClc1lXN0ynquby5pwZdNYLm8s4WJNIefX5HNhdZ6SXMmqwVxYNZjzK3OUr6cq/hrLOK88UdBcYFQ0tJNkRebM0v4tcmpxFp8uyOKT+f04MvNdDs54m33lPdlW0p0NRR1YX9iemvy21OTL3MvCfvG8/2YEs95uxcy3opj5VhTv9wrj/V5hTO8Vxoy3Ipj9TjQVA1LUy+qWZiWzuG8is96KYdZbMUx/I5Ipr4RS+pwfY7p6qQXmvWRPOnsrCDbXxFYpL3rN3qrOXeiKv56+eCaBadoy+qvA/NsDjP/mIOOT5KV5C+lxId7/hMA8dc9LC/Ly07aR/LRt5L8SmOaVl78KytMo+dsVl5Y+559nYCYp20gTG2jeQmpcgTk2EU6WK6svzQTm09KGDExLAnOkTLafjpbJ6szHk+DkVDg1Q45hfzYTTs6HzxbCqaVwpgLOrpIcXwx7psHKEfw5vQ+/D+nImZfCOZXgQK2nJluNBZsNBFs1BbsVguPGglNWgh/sBL+76vCnhz74GEOko6wmxHlAojJcmuAtqzMRDrKiE2wOwWaSUEsIV07hJLhBRoQM1PrZ86edAhwVci9NepBcPtepldw7k+orae0t2ycxHuBjwRd2hpwyEKzXkdIyVwgWacrKzC5bXW5660Kcg/wagXY8tNeBABspMG3CmwpMipy6wtOAj800qBOCedoNAjNdOfFUri+YYiSp1hPUOerIMHSSpzzWGGjBb7aCLw0EV+w0+dbNgF99TPjN1xQ8DMHLmC99zTllp8kgC8HLQhAg5OXvSj3BwQDHBoGJdpLj1O0C4bloKTCdfOTywLZBUl7ahUmB6eYBE3RhUwic9X28wFz0hssBcCUQLgY0CMxH3izo5UdWmKBXtD1vtrLlrVaWvB1tTZ8YR4a28SO/nTczeiWzfdyrnFmez6+14/lp+zh1WPZ2XSm360r/PyMwN5t9bmOJuVE3jtv1Spr926De+7SvhAf7StSrEe7XjeR+3Uge1I+VE4YHlFXZQ9Ph0HTuH5jBnb3l/Fw7mctrR3BgZhbVBd2Y1bctgzO8eC3MmvYuWsSYCHyFlJdAbYGvjpQYPz1BgPKSvJeOFBRXHYGTtsRBW24cdtCUQqM6seCsbD05CnkJOsJMEGsjSHEWvBhpRXamG2W9ElhX+ia7Z+Vwsiqfk1X5fFwxjJPL8/h89Ug+rcrn44ohnFs7kos1hVysKeTKuiKurR/BFxtGcGltHlfXDudy9TAurBrIhVUN2ZmWIhnnl2fx+bIstcA0z8E8SWA+r8jh3LKB6urMmaU5nF4ygE8X5/Dp4hxOLsrm2Nw+HJ3dm4MzenFg2hvsnvASaws6sKR/ErPfiZbi8mYE778ZwbTXQ5jaM5jJrwUx6dVAZr4VxZL+rakakkHloHQW901k3jsxTHs9gimvhDK1ZzgTXwqi9Dk/Srp5NxGY7n7GhFpqNREY1ZFRbaW46ImmF9TVAtNcWM4uz2lGS7kXyfmVOf9n4tKSwDSXly/WD3umEG/LC+qe9YZRwV9aSC23kfKa8NO2AiVFf6tl1BxV3qV5++i/0UJ6cnupqRjd21vajL8pMIcmNa28HFV+F3diEpyeAWemNhWYz8rg5NiGKaRjE6SoHC5rkJhDpXBonBLVc5UwTZAcnCi/9tFyybGpcGI6nJoD5xbB/9PeWcdVdf9//KDYrZiIiZ0oKnZu5ly5OZ1zpXN2JyIg3SXYNWt2znZOFGkBE7tnTtdubu75++Nzzj3nnluAuu/2/X3/eD64xVUR7n3y+rzjwlJB9jJx/JQ5Hw768HjxSLI8+rJvcEOWdylNbH2JsBoS0aUFa0pKbCovccJJ4nTtfNxtUIwfWjqIRYUdnNXBbG41xe6flvJmZ5eK0LS8qKlxrSyOi9xqq1uiG1cQ9TOd6ovi3R7NxMfO9UTNTdvaIuFpV0+0QtepwJPyBblQROKkncSBghKHikgkFpc4XbmAmHnTtg60qgM1SvNz6fxQoxy0bwg95ELhLrLE9GgsjrVcKvFDlYKczy+xJr/EKjuJIHuBf0GJwMKiWDiisMS6whIHnQqJ9uiOtYS8NXTgUqWCpBSUWFFEsKR8PlZVLcJyp0KsqFaY6VULMbKkRNvCEi3sRCdKo8IS00pIzGtUhbstKvG4bXVZ9KpD1zrQpyn0awS96kOvxoKeLQS9naFfPZiaD1Y0gVP14GIzuNwELjVWudhQppF8WzM41wjO9IKDzQh4vRJjW0mMal+J0R2qMLZ9WaZ0q8z0nrUIGdya5eO7sdt/ECdXjOHK5pnc3j6LO7tm83jfXCEwshjkVWBsCsc35smNtORGbtTrqsz8+o0fvx/xN0JJhZ8c8pbx4ZcDXvy4d448adibXw7M5ckhP54dDYHj4ZAYwbOECJ7Gh/B4nz83Ns3k6sZZJMcOY7N7f8KHNGNCx/K8X1+iWykxt6aVvZg43ESSaCxJ1JVxlqktU1MSE4iVWplKdgJlR5SDpC7CdJDE/qiqBSQalZHoXLcsgzvWYdirTRnzWitG93Vl6jsdmPFeZ4Z3r4/HkK5EjOvHSq8P2RownEOxk0ld7UHml96c3eTL2U2+nN/izfkt3lzcNIcLGzy48OVMzq+bzvl1kzm3dhLZq8dzbtU4teHGICJjjI6O9Ne10iIujxGTfuXHKbUz2vqZ7JXjObN8DCcWDGef3wC2ze7HmindWDq6Havk2S8rx3dh6WhRBxP9SSvihrVhyaiOfDGhOyvHd2PhZ22JHOpC6BAX/N9tRMj7zfF/txFz36yP9xv1mNWvHmM6VWZ01+q827goLR2ELCrLRItoKCGJ7egKJTUYBEZd+21eYMylL3qBed5hdLkRF73A6OXFnMCYq4H5OwRG1MDoxeXFCoytYl1zHUhKEW9einZfhMD8cSzAIDB/HQs0lpiEICEwycEqqWGQEQonI2V50QnMiblCXpLnqklLsqYOJsFXFZgEXzjmA8cCIF7udjrmD/q/x3GZhEDNYwMgPRqy5kPWAji5EE4uFyTEwr4gWDONp2Ef8v24blwa3JTsblWIb2TPkTKiwyipqEhpvnOQ+MXJHuoWE+3ZzSqJ7qUWjkJk2jiJoydXeR+Qaw218Le5o/pYt1pCYro2NhaY1jUEbnXEFmyXmlCnAo+rleNuxeJkORUjo0oRTlWy51qd0qIep319aF6DJxUL8bCwxJ+VioFbfVOBeaUJvNoE2tXiWb1y3Cwu8WVBITAhBQX+MuGFBGsLaQSmkzwLp1EFzpfPz1FJDPELketbAiQJ33xivcIQO5G8tLCTcLWXaFJUtM6OtZfwdSzK2RqFuNW0vCioblcNOtSA7vXkQl5ZYHo3EUMFFYHpXx/GS7CwLmQ6i84ig7g0ElyQj40M15vA2QaQ1YMf1lZmdo+STOtUmIndqjO9Vx1m9apO+PstWTG+L9u83id54WjOrZvJjW0e3Nwxh5tbZ3Bn12x+OOAralEO+/PkSCC/Hwk0HCflhn+SwBhjKjDKa4EiML8e9jUSmCeHfPj14Fx+3u9pGNRnmHez14tfDszl168DeRofwq/fhPH70SieHo/lr5RF/J64iCcJC7i8cS4ZS6ewx/cTlozsiWf/5oxu68hbziVpVUisOGhcQBUWZW1CLTtBjfwCR5mykkQZSRw1VconqGgnjpsqSuouKUdJFAg720s0KCJoWFQkQfUKSLiUkujgKNGnlsTAZsUZ36smfkPbEDemB+s9B7I7ZCiHooeTvmwCZ9fO4Py66VzZ5MH1rbO5snmmIanJXj2es1+M5fwXEwyioa170UpI9srxhscpKAKjlR39cyhic3LxSFLihnMs8kP2Bw1kt+/bHIn4iK9DP2CXz9ts9ejPlzP6irkvclv1irFdWDq6k6FoN3hwM/zeaYjP2/XxfN2ZOf3rCF5vyJRXazK5dz0+al2eDlULUDu/+vUsJkmUliQqFs6Hg71E+QL5DJTNL+4rLUlIxosYR3N+1Rgdlme7XFwzhvNrjbmwbqxFLn053oS8iou+cNfc0ZF5YVGYwe1tMw2rAG6Z4faOGUZ8u3OmBne+3eluc7dRbqbqmhcYrxwihOb7A55GqO2Vxij3G46gci0w5hMdE5H52pffD/vxxxF/E/6MD4CjAUIaDOIQIDjmLwr+koIFif5yIW4AZIZAVjCc0nQhnQyEE75WBMbflGN+cFRDvC8cCYT4IIgPgGNBcCxEXP8mUHAkAOIDxeOOBMLRIEF8CBwLhdQYOLUYTi8VnFoMabFwyA82TOKH6CFccH+FpI8as713edY2lVhWV+JLJ4nVlSUOlJdIqCGRXceeK42K8n2LcvzoWoFnLSryl2slcQTV0lHMQmlWUbQRt6giinxbVxPFtcogO7faKu1qiU4eF0cxlK9pRWhYjmc1SvBLpQL87FhIdEC1ri32HzWuwqNSEvcKSfxWoZBoB3+lmTii6tkMurtAT1fo2RS6NRQTgZ0KcqqoxFFJ7HZaLIkC4RB7iaBCgi0FJY5VtRczdTrUEgLTsBzJxSR2ShK+srxMlCTGSRJ9ZRoXEdLiXFzs3aldSiwSbFdUolelQoTWKMmyljW42NyRux3rQYdq0L0O9GwEvZsKeenbDPo0F7xWH/o3gBESRNSH9Npw0QUuNRecbwHZLnDBBc43h7MtBSe7QGYnODiEg1PKMa1TQeb2KYPvgHrMH9GWXT5vkxAzjPPrJnNjmweXN7sLtkznytYZXNs+k9u7PXiwx4vvD/nz85Egfj0awpMjwfz6TZAZAqxi+ouCMTY//3BQnvhdxiBTuvtNkiIzrw3Ka4a5tFiRGUPCLIvMz/u8+WGPJ492z+HR7jl895UHj/d68uMhX347GsTThFB+Pya6o34/GsHdHZ5cWjuZQ8FDWTelJz5vN2R0uzK8VVeiYxkxX6ZpQYn6+dVkprYkll46y0LibK92M1WWJBztJCrJKUyVfKJ+pqT8hlpGUjd6K/JT1k59w3WQ768oiSOshmXtaVO9DK80rsrrreowuEMDJrzVGf9PXyNm4vts8h/DNws9SV3lzamNQVzdGcGlbWGc/dKb02vncG7DHDJWTuPk8klc+NKdk8sncWrlFM6smMTZlZPJXjmR819MMpEZQxIj71xSAgztQueTy9X6mqylo8haOoqTy0aTuWQkqQsFCTHD2B84iD1+77Fr7juGDqS4YW2J/tCV0CEu+LwtUhfP1+uqvFkP77cb4v5mI2a+3oBPOlele3Xx9S0rfz2LSBJNK+fDxakAjasUpGFFe+o65KNWKYlqxSSqFsmhwFgbTJcTeTEnLpe+HM/lPIiLueTFnMBY6jp6GQJja2O0tX1GtqVmzksVGMOR03MKjKUam98P++VcYI4FGgtMQoB8fBQq5CUtRMx8yQoVApMVrMpLhh+k+0CKjyowSb5q8qIXFwWtvGgF5oi/ID5I3HY4QJYYfyExyswORWSOBKscCxUkhIsujLRYSI8Vx01ZiyEtDr4Jhb0+sHIyBA3myZhuXHunERdbO5BWrwApFSUSykpkyVyvIJZD/lijML/WKQGNykLzSqI9u3llcbmVkxiK176OEJgO9cTHdnWEwLR0FEsYG1WARg5QvwzUKsWf1YvzV50y0LiSKjAu1filgj33C0v8UEqChg4iuXi3k5go3KMFvNpSdPR0byTaqptX4k61YpwoKLHUThQHB+dXBSakiMT2whKJ1QuKtKlDLTGJt04pkotJ7JbTlzA7iZn5JCZLEv3sJF7LJ9GsuCTmf5QrRKNyhahbRghMqwISbQpKTLCX8HSwI6FKAc43rQRtKov1Dt3rC4Hp2wxeaw79WghebwhvNFIF5oQzXGiuCky2C5xrLuTlfHPIdhUCc6IDpLhxfWFbvhgsET24FlumdWJPwGCOzRvB+XXTubTBnWtbZnFtyyyubp3D9R1e3PpqDre+msONXe48OhzAn8lR/JEUydPjEfyeEM5v8UJiTAnkyZHAf53AmBYmW6/FM3k9OTiXXzQJsnb68M/7vPlhn5dBYh7tnmNSW/hor4+Yf3MwmCdHwvk5Ppafjszj8eE4buwIImnxNDZ5DcZ/aAem9GvAULcq9K5dADcHiaZFhcQo9TBVZKrK8uKUT4hLJUmlnEZcFHlxkOWljEZkymseW04jNOVkIXKSJGrZSzQtLuFWXqJvnWJ81qUuXoNas2jSG+wPG0X6yjlc3OxH9gYfrmz34+ZXQdzc7suVTZ5c2+zFlU2eXNngzpUN7lxeN52La6Zwcc0kLq6ZJHcmTeD8qnGcXzXOsHNJexKjDLM9tUKtqVEE5tSKMZxaMYbMZePJXDaekysmkBj7GceihnEk4hN2+wxk48x+LB0tJCbq49aEfdCCoPea4f9uE/zeaYzvgEZ4vlkPj9frMKN/fSb3rs2nXZzoW9+eJmVFB1md0hINykt0a1KBvm2q08fNmd5tatOpUWVaVC9J48qFaVDBHkkvLGoVtEARGEuFui9SYGxJi3Y1gCVxMScwxuJiXmD0qAPqVNTjIhVbm6NfhMA82uvJo72ePN7nZXT5eQRGGXj180FfiygFhloML0hfBwpsnNH/fjiA3w8H8Mc3gQJzAnM0QHOEIycvCokB8vGR3H2UFWosMCeDIUtuq07TFOkqKwaUox/loyUMIhOkJjDxAaqUKLcfCYL4YJHCKBhSGPn6EVlsjgULjgYJ2TkaDEkRkBYDGbFwcoHoeDqzFNLnQ0IE7JzDk8WfcXfuG5yd0JFj79Rhe9cybHDJz+pGEttqSWyuIXGkpkRS/fx837AYPzUtJbcRVxZHTW2riVknXepBp7ry/BhncSTlIic3jcsLiWkg07i8EKGWVUWBsVsNqFeKpxXseFrBDhqVhFcbiMLYN1zVVQPKfJVuDcQeosYVeOQgcaSgxB5JYrkk5s4sziex1F7ieDGJSzWLiQ3TbWuIdKhWCc4Xk8jKL/FNQYmjhSUOFRSJjL+cygwqKDGkiES7sva0LZOP+uXsqVVCokYxiepFJNpIEu3yScwvJrGrvqO6I6pbPZHC9GsC/ZvBmy3gDRcY0BjeaQJjikKsK2Q0g+w2cKG1ILsVnGkJZ9vCmTaQ1QMyu0PaUH7e1o2DHm3YMMqZr0PeImvZMM6vm8iljVO5sX0mN3fMMnB9xyxu7/bg4SFffjwazJ/psXBuGZxZBhnzeZYSLURGlhgTjgbx29Egg8jo0deW6LH0eernB+eJP74R/C4ffym3mxMZ611W5gVGPf4Wk4YNKxP2eRl4LL8WPtrrKTdCzOHBbg+DyCidn0qjxPf7veUpw0Fi/9PBQO7v8uba+umkzv+c3XPfZvWknoQOasbETpUY0iA/r5SXaF9UraFpai/RRE5r6mhqaJTW7IqypCjSotRtlNCh1HLo71eSGm2tR1lJomYRifbODrzfuTGj+rcn8LPXWTDtQzYHjmNPzAyOL/Pi3JZIrmyP5sr2aC5vCSV7QwAXN/pycaMv59fPEaybztnVU8lePVlmvFGpiLIuSHv51Aqxi0nsYxLJTObysZxcMY6TK8ZxauUE0pdNIGXRWBJiP+dw5CccCPmIPQFD2OU7iC1z3mb15D6smdKXVVP7smxCT+aP7ELEx254v9OI2W/UZWKfmgxtXYIBTYvQ21mib317BrUuy8Q3GuM/vCvRk3oRNfFV3N9vzJh+TnzcrRyD2hazLTAX14yxKTC5FRdFXi7nQVy0AmOu5kXBksCokjLzuQTGMJQujwKT09UB/ymBMScvL1Jg/owPEB0HhgTGjMAYal9CVYHJDDEVmMwAMZU31U+kLknaWhcb4pIQKD9GmfobLFAEJj7EWGDig8WxkiItiqRoOR4KCTqOhYrPPxokrieGCY6FQEq0EJjTy+DkMrHQ78RiSFsIhyNguzfEfc6TOW/w3UetOdOzGidbFCexXj6uVhH7i+5Vlvixpj3P6hSFhqXElOA21dShcx3qCDFpU12kNi0cRWrTtLKYeNvCUdCyqpCX9rXF/c6lxDqE5uWgU01RGNtXXvTYvq5YbdC5jjq2v01NqFOK05ULkVBUYm1BidX2EkvyC1JLS1yvW1q0lXeoBS5V+aNaYS6Xys/VMgU4VSkfZ6rYc6JSfhLLSCwqIxFdWOLjkhIflZDoWKEQbqXtqF1SMhEYVznB2VzTgT+aVhRDA7vVE/Uv/ZrA6y4wwBXeaQWDmouVAuOKw/xWQmDOtobzrQTnXAVn2kCWK6R2gmNt4GB/LsbVJ96nI2fj3jAksje2u3N9q5CWu3s8ub/Pm0cHfXl0OIBfEyN4diIOspfDlTVwYSVkLYS0WP5KncefyVH8eTyC34+F5Vpg/jgaZJV/o8BoGxH0AmNYXrnX0yAw2tdIRWQUmVGE5uGeOdzbKabr3t42k/u7PHm8z1feBxXI4wOhfH8wnMcHo3mwL5zLG3xJXTCR3X4fM29YZya+4sxQl9K8UbcwPatKNCsiFwTbicm/ylwZvcCUthOUtDMWmJJynYf2upbSGhThKS0fY9UsINGshETnqgXp37A0H7StzoReDZn9dmvCP+nOeo+hHAgbRfy8iZxfP5dr24K4ts2PK1vmcmWTB5c2uHN5/QyZKVxYN5HsNWMNEnPCJ4xHAAAgAElEQVRm5ShDnavpIuexnFg0nOPzPiVz+VjSF4/ixJLRZK6YROaKSaQvm0DakvGkLZlI+tJJpC2ZyLF5I/k6fDiHwoaxL+QTdvl/wFbvgWz0GEDksHb4v+/CnIFNmdS3FiO6OTG8iyOTXm+M1wftiJrQj60Rozm4ZCL7F41njd+7zJ/ei4ARbswa3ChnAmONvKQuWnIrLpYERisvzyMw5sTFXPqSF4GxJTLmh9nZEpi5MuL69/u9jTCMFreAOoHTsrS8VIExHB8pAuMrZkMkBonal9RQSAsTbdHpwXAiUBwjZcpkBUGGvyowyb5wfK4qMMcCxMAsBYsJjEKIjCwbhusKYnIwx2xgkJdgY/SyozwuMcJUepIiICNOFAlnLTS86XEkGLa583TFaL6d+SpZw1xIeqM6ezqVZF9DiQONJFIb5Se9SUHuNCnGgxaleeJanj/bVha1IR2ri+WTHWuINmjXKqJQuJUjuMoLErW0dhKj/FtXFBLzSn1RyNtWLhJu5ywG0nWpLVKVJg48cy7ND5ULcNHBjjOlJJKKSSQXF1OF/2jgIATLrQY0q8Kvle25UVLiUeUiooW8mYNoIa9bhN+ql+Q7h3wcLVeA/UUkhhW3Z3A+ierFJRwLSTgXlqhdSKKbJNFFkoiSJHZVLcOzemVE6tSttiji7d8ABjSDwc1hSAv4uDF80gRmO8Cq9pDRGs50gNPt4VRb8fF0ezj5GmT0gYQBcKA3Dze+x40vXuf6htF8t3s6t3a6G4Tl7h5PHuyfy+Ov/fkpPpinyVEiXbu6Fm5uhOtfCnk5sxQy5vNX6jxDAvMsMdK8xMgCY4k/E4KtYqgJ0aD9/KfxIbniZQmMZYnxNUiMXmR+0PwC98hMGmMObSpzb+csbm8TjRj3dntwb7cHj/Z6G1YpPNw9l0d7Avh+fxD3dwZwdvkUDgZ8zNqJfQkc6MpnrcrxXsMidCgplks2kiQaFZKol09twa4goxwtKWJTUhaTYjKFLVBU87GoJDp0Smiep4z8vMoMm0alJLo4l2eAa01G9m5N8Kg3WeE1gr2x0zixMZT0NT6c3BDImY1+nN3kz/nNPmRvmsu5DbM5s24mWV9M4NTqSZxdO4nTayZyds14zqweZ+iAylo6iqR5H7M/aCDHoj/i+PwRHAofSvLCsaQtmUjKovEkxI4iPvpzDkd8xoGwYRyKGM430Z/zdeRnpCydTNqyKaQsm0LSkknsixjBFr8PWDX7HZZM7U/shF6EfNaZ4OGdiJ3Qi7iJfVjjNYhdEZ+zM3wEO8I+Y73PENZ6D2bJ9NdfvMDkJHWxJTDWxEUZTPd3CozZoyOdwNiSlrzJy/8fgXkW7yPjLSQmKRhSwowFJjUQUv1FIe8Jf0FmgBCYNH9VYJJ1CYyef6LAHA83vpwUoZISJY6d0mIgPQ4yFsCJhYLEeXA4VKQ0y8eBz3sw8VV+H9SC+31q833r8tx3KcW9uoX4tnZ+fqhXhCdNSvFX0zJivoxLJXVisKtmz5OroxAXhZblBe2coKuz6HbqWE+0abeppYpRaye59VtME/6uXjluVSvKuSoFyXYsxC/OJUWLeKuq4rGNK/CDg9iB9INTcWjtKNqg2zmBW1Vo7QyNq3CpcTVSqhTn89KFGWQn4VRUFPHVLiToKkm8aic2bu+qWgYalBWJU9ea0Fuud3nPFT5sBUNdYVgzGN0agmvC5h5w0k0IzKm24vKpdgJFYBLfhcP9eXZwFM8OjuLHA+482jODe3u9eLB/Lt8fDuDnoyFCWjIXQPYKuLJWSMu1dUJiLqwUx0enFkN6nEWBMSbEKs+OW+fP42E8TQg1Qvv5fxwNM8s/SWD0EqOIjC2BURIYddaWerty+e4OMSX97lfu3N4xgzvbZ3F3hzv3d3kaBObx3kCefDOPHw9E8v2BOB7ti+HWzkiOx03m64hxLBjVm8m9mvFOwzJ0rGRPs6IijXGS1G6l8nYCpaBXSVqKaiRFTyHN5SKy6CjpTDkzlJFE+lNaliZne4nWFST6NirLiO7OeAxqR8zo3qzz/ICvQj/jcOx4MlbN5MwGLy5u9iR7owfnN8wge/10zn05mdNrJnJm9ThOyjUxaQs/JT78feLD32eP3wD2+A1gd8BAdvm+w27/99kX+AF7AoawJ2AIu/0/YLf/B+zy/4A9QR+yJ+hD9gZ/xN7gj9gX8gm7gz9iV+BQNvu+z3rPgSyZ2p+FE/sSN7EPsRN6ET32VZbNfIuoMa8QPrIri6f2Z+GU11gwuR8Lp7zGsplvsXTGm0imwjLOCFvLF/OSuhiOjzbmXlwUciowpuKSO4GxKi+5FJjcy8tsww+a9gf0RQqMuh/F12TKpnUC+OXwyzhCkhMYrcAoR0ipgaLLKN0P0v0FJwKF0KQFQoqmBua4jCWBMRwB6WVGkZAgwdEwgeH2UEgI00wQtoROYMwdNWkF5qiGY+EqCTKK4BwNka9HCJLCIT1GzKQ5sxjOLoHMOHH7fi+erh7D/XlDuOrdh+TRrhwdUIuvXnVgj1sxvmpVhORmxUhxKc7pZiXIblmG601L8W1LB35t48hv7ZygVU2Bq5Pc1l1TJC8dm0E3V+hQXwhMm6oiyXGpKNYANJU3ddcvzdNaRfm5djF+rFEYGpSRpxHXEmlNo1L8UF7i2xISPzsWENumW8vJT9sa8p9VD9o34w+n0gQVzcd0uRbBpZBEL0miXz4Jd0nC117MtDldo4SYaOxWFbpWE+sEBjaED1vA8GYwogVMaAoz28AiZ9jTFU52grPd4FRfONkbTr8OZ96EkyMgazhkzoTUqZA+F5Jm8/SoJ7/Hz+GXeH9+PRrA0+QIOLUQLn0BN76Eu5vhziZx/dxS8X9zapEgMw7SYniWEslfSVH8lRTFs0RRB2NKqFWeHQ+ygCowerSf/+excCNeVgKjx1Jxr+k8K1+zEmOog9FhS2TUyefGQqMtAr63cxYPds7i/o6Z3N02iztbZ/Ltlhl8u2UG1zZM5t7O2YbVCU+Px/Bwrx+nVk5h25w38R3QiI+aF6JzOYnm9qJOppYkioCrSZo5M5Lahl1GIyfFJONURis4RTVSU9TMfUUl4zkqyu3FJYkqBcSRayvHIrhVL0H/lo581KMxkwa2x2/UayxxH8Q6/+FsjRjNN8vdydjgR+pab9JXTydx2USOxX3O3uAhbPJ8k/Xur7F8Ug+WT+rB6ml9WTW1N4vHdmf+yC5EjehOxPCuBA3rSsDHnQj8pBvBw3sQ/NkrhIx4lZARvQgZ0YuA4a/i80k3pg/uwrRBnZn8Xhcmv9eFSYO6MGFgZ8a904GxA9oz+q22jHzDjRH9W/HZa64M79fSiBciMLkVF0VeFIHJjbgo6IXl+pYp3Nw6zYD51EUrKLNkZuRYYBRpyUsCk3tx+XcLjPJCpYjLn0eCBPEBBnn561iwafv0cXmDdHKoscCkBBgLTJpMeoAgNUBOX/4LBEaLIjDaWhotCcHi73lcrqtJCoeUSPEmeWqhPKNmIaTGin/HFneYP4xnc97k4Zgu/Dy4NXdfb8j1DlU461KKC/UKc7F+Ue42KMHj5g4iSWlaRcynaV5ZtFO3cALXutChKXSRN1S3rS6nN/KG7uYVRKt043JCYuqX4Y+GZUUBcfta0MlZTOJt7sDPFSXulJT4tVohOfmpBq5VBW61oXsT6N4G6jkSWaYIUyWJZgUkWhWT6G8vMaRsfuY5SCx2LEiWUxGuN6ksiprbOAqBeb0xDGkGw91gdCsY1xZmtAafbrCmORzqCac6C4E585og+204+xacGSk45SEkJsMHkj0g2U9wIhrOLhKicm0N3FwvuLYGLq5UxSVrvvg/yYwTBdwvSGBMl58G51lgrCUv/0aBsSQxevSLdhWBebBzlkFgFG5tncHdHe7c2T6buzs8uLPTi3u7fXiwL5Q7uwLI/tKTg6GfEvZxFz5uVY7etQvRzkFsza5upx4tKd1NSheSUtCr1MUU11HMSlJTWCMvisgoQ+AUGVKeR6mlKSf/+fVLSDRzkGhXWeLN5iX5oEMlRvWuQ+CnnQj/vDs7gz9gZ/AHbJs7gI1z3mDV1J7MH9UB//ca4jewAUFDmjPnDWfcX3Nmeu/qTH+tAaO6VOWTDpUZ2rYCQ90q8VH7KnzcsSqfdqnOsK61GNHdmeE9nPm0ay0GdajF4I61GdjBmXfb12ZAh9q81bYmb7Spxuutnejbogp9XCrxSmMHujUoTed6JelQuyjtahbGrUYhpAurx6NFbM5U0S6hMkseUhctuRUXSwKjlZfcCow1LCUvBlvPY/qiFxTLePFwj5eVAXfGP8C5FRhlpLleYHIiMdYGWf36TYBhQNfT+CADBnFRkpcEP8HxuYLkueIoKDVAJCqpcrqS6g8pfpDsY0xaoJq+JPloupACBMogOi3HAlRBMQiGfP1YmE4gwgTxIfJtYSoJ4RqZUDqOlCMm5flCMHuUZFTgGwLHZRJDBcdDITFc5bgmhTkebio2CaFwPEw9dlJkJj1GvHme1HB6oXhTTY2G+GB++8qDH9dM5ErUB2RP60nSZ204/FYdtveoyNdtSnKwVXFSXIpzsq0Dd1tV4G6rCjxxrchf7atB25qCDrWgW31oV11OYCqKKcGNHATNKoqi4JayoLhVFUdFjUtD/RJQpwQ0LAtNS4JrOWhVXnxs4yRWA7jVhXoOfFPCnpWSxEhJzIqJsJdY65ify84luNXIgacNSsn1PA7QthK8Wk10HH3uChM6wOx24NURwtrD4t5w7G3I+ABOD4NzI+DceJmZcGY6nPaDLB8hLpm+YvbQuQi4OB+uLIJrX8CNNXD9C7i6UnBpGZxbDKcXQFaszHwhLifmCdJiICWSv5LDeJYYKmRDU7vy7HgYz46H8eexUGMM94eo3yfmkEVaeR4txs+pyktOj5G0MmOop1Hmv8jza6y1YBuOn42OoC20VR/yMysx+iMkczza68nDfZ480LyePtrtZeC7rzx5sFvl/i4PHsp8t2O2gfvbZhm4u20W93e4Gx53b+ds7u2cbbj+aI8fj/b4cfnLWSTFDGev//usHNcD99cb8HGrUgxoXBy30mrxr5OczFS3E5eV1m2ldqacnNIoBb2KiOiPnpQ9QQUl8zuDtMXCxSXTrqjS8p/jlF/CuahEk1JiH9TQDnUY29eVKW+1Zerb7Zj6thvT3mnH+N5NGN65Np92rs27LSvwXpuKDHKrzJvNS9Ojtj2dahemXfUCtKok0cJBonl5CZcKEg1KStQuLFG/lKBmEUHd0vlo4FCAeg5FDNQtV5g6ZQsZPjqXKUitkvmpUSIf1YqJY+QXLjA5SV1sCYw1cVEG1P1TBCY3HUb/XwRGmTFhVWCU4l0lKUnyEQlKmlLPEqDKiV5gkuaqpAaospOiaZ+2JjDHg4yl5b9VYBLDIDkCUqPUN06FrAVCYs4sEZxaDmdWQvIi2B8C62ZB3CiY8w5PJvTkydC2PHyrKT93rcWj9lV54lqRX1o4iM3RjcqJjduuVaBpOUHjCqrANC5vLDBtqguBcasq6m6alhOLLJtWBJfS0LKsKjCtHMWCxjbO0KACKZVKsctOYqokMTu/xNKyErsbl+NR6+r81K62SIDaOIFbRejkBP2cRcfR+PYwrRv4doPgXkJetgyBzA/hzKdCXi6MhPMTIXsCZM8SEnM2ALKD4GIkXI2BG4vg9lK4vVJmnRCYqyvh8nK4uBTOLYQzC1WByZxnSF0MpETaFBij/38D8vdHUph5NPJiTmBMhMiKwNiSGa3AKAmMMr/GWgeT+RqZ3AmMIYmRX8f0r3vf7/fm8T4vvtvvxcN9mlQmDwLzYLs7D7a7GwnMg52zeSDLy72dsw233d/lzf1d3tz7KoAHuwO5tzuUm9v9yVrjSXzcBLYFfs7CiW/i/m4HhrhV47UmFWhTUSQ01SRN95JkXPSrJCdK/Yy++FcvMIq4KJJjKYkprbuszKapKMtUw0ISrmUlWpWT6FDFjh61C9O7XnH61ilCj2r5eMelPH3qFqFHbXu61pBoXV4sz6xdWMxzqW4nz9Cxk6hhrxY2K0XN2m6rMrrLyvFaGc3fU7tOoJQkIZkKy0QjLn9pnbykLgpXN+VeXAzohOXm1mnGQ+hsdhb92wRG+SFUJMbzhRwhaQXmeRIXc/LyRCcvJgKTEKQKTLKvLC06gUnVkBwAyUHiiCnJX5ASJBMoMAiMjIm8hBjz0hIYcwW9Zjgerv4ZCWHGwpIYqSIvtxP1L7rr5lBqZBIijJ8nKUqQHC0zD1JixfbtdLkwOHORGLiXtRhOLhKP3+vDb+un8OOiEdwMeY/Ls3qSObYd5z5qQdq79Uh5tRIJXR0430Fwo60DN9uV54Gb4Kc2FfjZraLYVdRKXo3QxlHIRhsncVurSuL+lhXlAuPyck1MVXCtDk0q8ax2KR6WkfimsMTXhSROVZT4tmEpaFFRPM6lrOiW6lgRelSDQXVgREvw7Aj+PSCuJ6x8C3YOgvjP4dw0yJ4O52fCBXe45Cu4GASXguFaLNxaBPdWCe6vg3tr4Ns1cGu1SF6uLBPbzLMXwLn58lLQaMiKgYxosUsrPRrSoiA5XCUpzCAk+uJbEjWF3MmRms8L1RGsQz5Wkr+fniVEGKGvefk3CIw1idG/nulf/77bLyTGcPS+x9uAVmQUFDFR0MrK/R3uOUIrOfd3eXJ3hwf3dnpxf5c3d3f5cWurN5c2eBIfOZydfkOJGdaR6X3rMahJEbpXlnArIVHPTkwFdpREvYyyYFIZqldeRtnVVMwMylGUufssPV47e6asJC+4zCdko5Kd2OLtVEDCsaCgWmExULJ+aQnnEhKV7cXzFJXUj8qRlpL2FNPcpnxUljTaS+oix3wydpKEJGMno9z3QgQmt+KiXQOQa3GxIDAmU3QtCIwqJO4yM/+1AiPw/scIjHbC55MjgXKbZhB/HA0xYFjeqBWYpEA1STkhY0heXrLAKBLzbxEYPZYERuGYFY6GwrFIlYQoSIyG5BhImSdImye6Zk4thZNLxL6n9EWQEA0HAmHzHFgwEua8wc8TuvHXx235/u1GPHqlOve6OPKofSUeuJXnh1YOPG5ZFpqVFfUpzR3E3qKWlUVHUqtK4FoRXDUS41pJFZiW1WSq82fNkpyrbs8pR4mbdYvzqEVFcKkgpMi1PLhVhs6VoVdN+LgJTJTlJbwfrH4Htn8Cx0ZD2mQhLxdmwWUPwRV/uBYINyLhVjTcWQJ3l8L91YJ7a+DOari5Cq6vMJWXM7GQFQUZMmkRMlEiddHKi4IsMIZ0JTFU14UWbUhsSA03JiXUmORQSAoxfF/lRF5yIjDmJObfIDCPDgiUROaHvXMNKCKjFRhzPNQkM1qhMSc7Wom5u20Wt7e6c3eHB7e2zObWltnc+yqA29vn8mBfOA/2hfP4m4Vc3xFC5iov9oaOJG5MPzwHtOKzLrX4qF1V+jcsSZeqEu0qiSSkXhGJGvmETFTUJBn6OTJKQlFSnkGjJC/KZUUizB0laVGeXz9BWJEj5TkqSGpRcmlJrcnR1uXo63T0R2CKwJhDORLT3/7cApOX1EVLrsXlBQqMiP9MC7j00qKtUDclbwLzYLe7TkQs4S1j+f7v9/vkomhXf1Tkz09fB+SgaNdUYLTCok9ffv0mwLrAHA0QApMUCKkhZgRGSWI0ApMSIGQlOVCWmEBTgUkJ1OxBkuXI7FGSJYkJM5KYv44JiA+Rh9qFCHlREo6jIbYFRi8yRrfJ4mIoytXIjHJsdDw87wJjC3PPmRil6XKKlYkRpMwTBcEK2mORxHDY6wUbJ/Prok+5EzyAi9O6kjmqFSnvN+CbN6uR0deJ1J6VOdmtIlldK/CoTXkeu1XgadvKPG1bWRUXV0chNm6O0KaKuO4mF/c2rSDSmeYO0EieQtzCQUhQ2wrQuSr0qQbvNoBJbuDXF+a/CSuHwO4RcHQKZMyC03PgvDdc8IHLIXAtHG7Gwp0F8HAlPFoFj9bBd2vhuzVwfxV8uxpurICry+HSUri4BLIXwtn5cCYOTsdCZhSciILUCFVgFAHRSowuhTEhKUw8Pl1OcdIi5JECYZAeDici4EQYpCvyEqw+r0ZgFEnRiswfR8NyJS/mJOZFCox2/YHRVF6NwGjHOVgSGD2WBEabwnz3lfHRkv6YyVI6Yw1FZB7snC0Sme0eAjmRubtDXL6/y5t7O734doc3d3f5cHeXD1c2zCR5/ud8E/4hX4d/zJY5bxI7oiPebzdket96fNrGgTfqFaFbZVFLU1VOZbQJTUU5MamSz1h0lGRFOZbRzqUxl8ro588oCYrS5q2gPaYqrBEORTq0j9WKiJK22MkfpdySW4G5sn6SEXlJXWwJjFVxUdqjLewvUnYY2W6Htiww5pMWd7MV7DkVGMtLGy11FymFaP8OgdEfHZlLYP48FirkJSEEw7ZpRWDSgwS5FZhkGUVeUoOMSQ6WHxssSA4VH20JjCwxBoExpDJ5SGD+zQKTOE+gFRgtqVGQPk8M3MuIgxNxYudTxgIxs+brINjpCasnwcLPwG8gf87ow5MRHXg4xIU/X6nN712r87tbJX5pVR6alhVdTE3LC1yUFQnykD2lO6mtPCemRQWBa0VoVxU6OUK36jCgPoxoD/79YN5gWPMhbBsN8ZMgxV10FZ31hou+cNkfrsuJy73F8Gg5/LgOflgr5OX+Kri7Ar5dJuTlyhIhLhcWw7kFQlzOxMHJeUJezAlMWpSKJZHRkxwuHq8IzIkoWVq0mBGY4+r3kSIs+iQmN9LyTxMYbRqjfz3LqcDoRUZ7pGRNYmwlNHp5MRxD7ZjDgx1zuL/Lk3s753Bn+2yub5zGnW1zuL3Vg1vbPLm7y4cHe/x5uDeA+3uDuL83iDt7grm7N4SbX4Vweas/GV94ciB8NMunDWLuoPZ82K4G/eqXoJWD2IBdp6iYi1RNxqmAOAZSNmkb5tHoZEZbW6JFkRetwOi7oorqruslRZug6JOU/DrscomkFxaDuKybLLAgLuYEJjfiouwxyo24mCvM/TsExloLXk5bovVFuDkVmMf7fGX0t8818DIFJifSkjOBEVND/zK0TcsCk+wP6SGquJgITLBASVqUs36DkNgQGENCEyITZiwySeE6iQkzwkRg4kN1RzQvUWC0xbuWjpIsionyeTJJOgxFoWaeNzFKTAZOjIDjMUJgkmMESTGibiZZlprESFl0ItW6mrRYITAnFwlOLRY7n04vFsstv/aDne78sn4C34UP4Zbf21yf3pPssZ24/H4zTr9Vl/O9a3DmVSeudnXkevdq/NrZiV87awbrKROD28kpTaeq0L0WvF4PBreA6a9A8HvwxQjYMB52TYYDsyDVC04GQHYIXAyHG7FwMw6+XQQPlsN3X8isgIfL4e4SuL0IbsTBtRi4HAcXYuDcPDgbI5KX07Gi3iUrRpaXCCEvRgJjRWT0MqOQphOWjEhTTkRBmuY5kiLl9EXUPymFu/pCXjUV/XcIjPY1yVzDgSWJeXTAh0cHfPh+v4/Ra6ZWYiyJS25lRisyWqF5sHO2QWC0XUtKqnN/h7thgJ4YoufBD3u8+XHvXO5um82drWKw3oOvvLm3x5+7u/24/VUQ2V96cCR2NOvc3yT443ZM6evMiI5V+Kh1Od5pUoyeNSS6O0m4lpRoWliicUGR2NSWJGpIEjXljzUkdT6NvsZGW+irFRytrOg/5kZgzCUx/xGBya28aAUmN+JiS2CUzdG2htFZEhjtMCPb8vI/gbEmL78d1aQvhtZPeV7F8WBIChWSYUtgDPISmHuBSQ0Wz69E72kRQmIUrAmMnMAIwVBuCzMulDXIx3+pwCgJTGK0QEliFBRpSYpShS5Bft60WHFfaoyczMidT+eWw8UvBMfnwdehsH0ubHCHBWNg7rswsRe/fd6FX99ryfdvN4E+9fijRy1oV1OsP2jtJD62d1IFpk8D+KQdTOoD0R/DivGwfRrsdofDHnDEC074wqlAuBAG1+fB3cWCB8sF92S+XQi35sPNBYIbcXA1Gs5HwblIOBMNp6NUecmIVEUjPVxIRVqkdYGxJjEpkXL6Em5eXAxEGwuMoabqxQvM0/gQE5HRryT4pwnM44O+PD7oyw8HfOXXScGP+33ylMbkRGjMiczDXZ483CU6ne6bq6fZ7cnDPV6Gbii1bVsIzK0ts7i5eQZXNrtzbctsbuwI4MH+CO4ejObKjkAy1niSuHQ6u4I/Y6P3B6yY8S7Ro3oRMbIvU/o358O21RnQpBw9a5eiXYV8NC4uUb+QhHN+idr5jAXG0U6kNdqaFu30YK3AaCcFK8W4eoEpoLnNEspj8+WS5xaY3B4Z6TdImxtIZ6k12lzNy43tU424uWMaN3dM47aGb3dON+HOrhkys3SI2+9+NdMC7kbohcZWUa7lGhdvIynRdxepbdMq+sWN5pc3zpHx4sdDczV4yVgu3rVVpPvEMMRKRRlU92d8gOmguuOatulkfyEYGcEygQJtEW9qgJyiaMRFS0qIXD8TYkZcgiAtGE6EGpMeIkgJEc+RGCrkJVFpfTYWGH0iYxAEQ+2LGbRHP+bE4pj8BnM80lhYEsLguAatwJgTGaOkRIN2cq+h+0hHog7D81ngeJQqMQpKKpMcAykxkBQtHpsUrZISY0zqPEH6fMhapA7aU8hYKJ7jaDDs9eLZlml8v3IkD2KGctGnP+emduPUpE5cHteR7JFtufG5G9c/a8ONkW15OKU7T8MHwdqJsNsLDvjB4QDxtTgxT2z/vrAMrnwBN1bDzTXiSOjGCri+FK4uUbm2QHA1TuXSPLi8ALJj4PQ8OBkNJyIhTSMsqRE6oiwQI9AKjBHh4vMNyUs4ZEYYkxGuHiGlhsupYgQkhvMsUawn0Hch2epK0kuLsjvJ0ioDSzuaLL0+mAy0+ybIhF8OBxoQv1wZow7f9Od7HYqwaMVF4fv9Ph2llZQAABPBSURBVEaJjILyWqt9DX6010dGWRYpXqOVpgpzaFuybaGIjJLI6GtolDRG6ZZVioK1v5jf3jadm1tncGubWCaqLBS9tVMM2Huwx5fb273IXj2Z9MVj2BfwHotHd8H/3UaM61qDQY2L0c5BomUJicZFRct0nQKCGvklnOxEB1QFncQo3UVGE4DtVIEpLJkKjC3+qwQmJ+JiTmAUeblpQ15ehMAoy79sdxFZnqSrFRjjNEWLXFFvRlZytnl6jiwqc4346WtvmbzVvJh7gXoaH2SYsmvaLh2oCkxSoJq86AVG2WlkmO0SqBbj5kZg0uTkxZrAJAVqiiZDRCqUEG4qLUZSo699sSIvlgRGW9OinfGRE4FROCY/x98pMHqJ0QqMIiy2BEYRHUVmtEXAWQvg5GI4vVQsPDyzVCywTI8Tn3MoELbNhrWTYelYiPkEoj+BiA8hYijMGybkZY83HA4Sx33JkZAeK1YsXFgB19fArXWyvKyGq8tETcuVRXB5oeDSArgSK7g0T+VCtBhgpwhMZhSkR0BqmCoctgTGICjRxt1FKZG6x0YIITIkLf8/BEYrL9YkxiAyXwdYlZicCIwe8VqsT75VyTHH84qM9shJOyDPcKwkoz1VuLN9Bt/udOfbne4GgTFIzDYPbm3z4PZ2L+7snMvd3aKu5vJmb9KWTGR38Oesnfkeo1+py0CXcvSoVZzOVQviVik/LmUk6hcXi1Id84skRrsZ21z9S8n84rI2bdEfIVnqMHrhR0gGeVk3mUtfTuTy+klmubJh8nPJi9kdRrmQF+2RkR5lzb15aZlhIjBqqmJJXGZyb48qLrkRGHPFtzkWmByIi2V5MRUXVWB8ZHLeLq09ItK/QClzXlSBCRD1LnqBSQwQ8mEQGFlcMvyNlzIqyUuK9pgo2JhUCwKTFqwpCg6WCVRJ1yQ8yeHiKCtJkZgw80c9Ju3QZtqec0UOBcbS8ysCYxhcp0E/9E57lGTt72upbVsvM1pBMSDPl9HOmjGaN6MhJUY9dtLeZpCaWEHmQrEO4fQiOLtUcGaxSFJOxMn/Xnl4m5bEMEiOEo85vRiyl4tR/1fXwLVVcPULuLJCcGGh4OIiwYX5cD4OLsYKLkSrnI+CC3HGApMWLSQpJco8JgITrcOWwISr/AMFxpbQPI0PMpEYLU80dTNPjgSbJjBm+PHrAAOW5Eaf1Px4yN9IZrRSYx4/GaUl28dsQm5JYvKS0giZ8TQU+mpRx34Yo65DmG10++1tYu2Bwp3ts0TS85UPD3f7cneXH3d2+nI48hO2er7Fsgm9ifq0A15vNmV8FycGupSjZ8181C8oUTe/XAhspxb8aluvtQP1CukuWxKX/PJHffu0vqjXFnkWmCsbJlsUmJzKi15gciMu1gRGlZcXJzD39rjnWmBstUibr2XJncBYEpecyYuPVWmxVuOiFRj9oDqRvgQaF+we1yUoSkLyogVGeV5FYDJCZIKMUe5PiTCWmKRwVSBMZrZo5CLBhmDkRWAMz/UvE5hEjbzYEhhtsa/+fuW6Nq1J1vwbT8QKmTm5ADLmyzuG4ozJiBXrE5Sam/MrRK3NhRWQvQzOL4HsxWJa7rmFcGYenIuF7PkysXAuRkhKdoxYG5AdJctLtBCY87GqwKREyYPmLKCvccmNwJyIEoKiiMpLEBi9xJgTmLygFRgtOREYLT8fCTIrMYrIPK/AWJYaU4GxJjF6UTGX0OQskTFGlZjZFpiFdq6ZuqTYWGBubJoqbt/qwe2tHny7w4c7O325/VUAt3b5c31HCBc3+3EofDTbvIeyeOq7eL/fkfaVCuJSUqJ2MYnqhSUq2ou6GGUrtvZISV8XoxWY/NI/SGAM8qITGFsFu5YEJrepizWBMZaXmWbFRSsmOREYg7zkQmByJi/WBeaHA75WBeV55eWXw745HkxnTmC0L1BKUaBydGQkLwlBkBgkWj3TZJSjHJMjJKX2Ra5Rya3AKM+rCEpmmCArRHAyVAjMCSWlkYt6DRITrnI8zDJ5FRjD460IjKHwNgdHPpYEJjEck3UE1tALjKWjJb28GMQjyvSYKkknM+awdGRlkJoYy6TEmh5PKd1PmYsha4kYwKeQtVgcSWXJyc6phWoL9Jl5sszEyETJRAjOR6kJTJ4EJlp8PZQOLgVbCUx6qJAURWT02BAYi+33GqwNubO1TPI/KTA/5aJW5mUKjKU0xlYyk5OjJaVORnvdHPo5ZspRk7l1Ore3Tef2Vndub1WXUn67w5Pb2+dw9ouJpC0YwZGo4ezyHcTn7asysGEx2leWaFJM7U4qL4naGKXIV7/aoJBGTrQo4qHUvijXrR0vWSPXAmMkLxqByau8vLzkJWcCoy/KtSovOoF58Fzi8vIEJufykjuBUYbT6SNircQYBtVp5UUvMOlhxqKhCIxR8W4eBMaQvmjFSJfAZCmXQ2SJiRBFmEoSo38D0kpLkg0B+J/A/L0CkzzPNOE5MV8ISsYimYWiYDhDLhA+MV+QOd+8wJyNVgXmbKQqMNky52NVgcmI+K8QGK3EmKQzZrZZW9psbU5otEMs/zgaYiI0v8WH8Jume0kvMT8fMcaSwOSkdkYvNNaPlcwLjDWJsVQfY05ilK6j3IiMVTTds1qRsbxOZzZ3ts/mttzhdH3zLK5tmkn26smcWj6O5IVjSVowhrCPuzG1VwOGtKtJn/qlaFBCopa8TqBKPnWOjHbwnVZitGiTlgKS9cm71upkjBIYI1nRycvzCowlcfn75GWm2WMjcwKjfANor5trl9bKywOduNiSGP3SReM2aV/ND43ghwP+OWiLFlgTF9NjI8sCYyotfjyJ9zfw29EAA78fC+KPoypizoteYAIESbKUpIe9HIHRyosiMJkhagKjcDJcvZyh+fukhIk3AP0sDm0SY05gcvgGYRFLz5MYqTumkTmuISkGo5HzCuYExmIbtQ2BUY6ELAlMig2BSY6yji3Bya3AKF1OqXGQNl/Ii5YTsYKsOLGZ25zAnI2W5UWTwGRHyUdJ8wWnF0CGcsxlps7HUNujwazAaO5XOpNSY4TEpEVr2rEj5SMlPS9GYBSJsXhfYrhZ/jweYcTThHAjbK0jMCcwtlIZS+S6ANiK0Ohff60V/eZFanJb9JtXgdGj3wWoPXK6s12sPri5eQbZqydyasUYDocNZc3kHoR+1I4Z/eox0KUcHSpI1C8oUa+ARM38Yl+TsmJAmRWjDL7TJjPWhOaFCIw58iowOZEXs1ukX5C4CHmZZUVcrAuMuXkvD/fMNoiLgu1VAOZSF+3eIp2waPjxYKDNmQcvQmCsznWxIC8KT+MFisCQECK/cSrzXgLl9CVYPT7SHiFZExgFvbjoJSYt1LTrKDPEtsBkhsGJcCEwaeFCYlIijNGmMC9DYAxv9tGmGHX5WOJ/AmO+SDhWkBZnTPo8wYkYITFn4sQwunOxAq3AGCUwNgTGbPqkIyXaVGCMpEUnMEoSo6Qx5nhegbH59Y96LoGxXSQs+C2PMqPcnpskJmepjL/xL5A5KPzN6fFSbo+Y7u/ysC02ORQYVWRmmUjMne2zuL/Lk4e753Jz62wur5/GyRUTSIgZxiavwcSM6MqMt1ryWZda9HQuTbuK+WlZ3p5a9qLAV1kuaW43k7n6GHNFvpZqXSweIT2vwOTlyMicwOS21sV28jLLqsDoheXebk8ZD7M82DtboMiLfN3cPBfbs120R0Z5ExjDKO2DgeKxmh9A/Q+o9rr2B9vabzM/Hwnil/hgq+mLuQTGIC6JgZAUpCYnhqQkVBWONE3tS4Zck5IWqjsaCjEjK2ZQ5MUgLjInI2XCdURCVoQ4BlBSGKM/UzPozjArJhdHMjaPbCxIiwnW5MUKhsFztt5YLYiTtS4iI1nQTOnVtlTru4sMRbn6x+YQ/ecpCydTo43RJxrm2rhTYkS6cSJWU/tiRmCyo9RiXq3AZMfCqflwIhpSY4WIWPr/03+tjNYwxFoRGB2KeBmIljdcyyJj+HcLqfsrKYa/kjT/jzn9/zSHFblRROnvFBhLt+dVYszJjF5gDEf6eRSYvNTI5CylUX7B9jQrMpYlxnjOjCIyhg4meXDetU0zubx+GskLR7PbfxCrZrxB7KhuTO5dj/ebl2Joq4q8Wb8YbSuKRKaypO5dqigJqXGQ1J1L2oLfomYSGVtLHV+owFzdNOW55EURmLyIiyWBsTTX5XkERissORUYW9/Mpu16eReYnw4Fmf2BtPYDbTOOjQ82ERhFWrQYy0uoqcDoZUQvMMrgOqXoVv94awJjOI4KE/KSEaaKS1aYwJrAnIwUhZgZEZokRnn+cLU2RpGYRLkT6XnlxZI4vEiBUSTmv1lgkmOM05y8CMzpGMsCczbSVGDOzROcjIP0KFOB0Scs/3SB0f+dzGHl/9/Q7aQTGQVbbduKwGjRyowea3Jj7fXOltyYJDEHA8Uvh2YSGNst2LYFJ7ft15bFRhWYB7s9jXb3WU9j3I0kxugYSSMwSm3MxU1zSF08jvg4wepZ7xE+rBthw3syoVdD3mvtRM86xXEpnw/nImIPU1V7dQeTsjxS6VoqYUZgLC18tFnEa1VidPIipEXLf05e9AJjKi/6DiPjIXT3dntw9yuBJYHRC4v2+sN9HmYFJqfyYhRVHlB/aIywcYT006EgfjoUZDQb4cccyIvROO/DQSa/2fwSH8yvR0PMpi6/HwviaUIwTxOC+VOD0aqApCBIDTMWDqVWRcvzCIwiMSfChbxkhKniYiIwVsiKEJ+rH3p3Qo7mDfUxssQkyRKSJ3GxIg4vWmCSYvImMMpclxSNhPzdAmNRWF6CwGjbqJUuJEVY9AKTHSsLzALRrm1LYEyERc8LFpjUWPn/ZN7fIjB/JUUZoRcaWy3cSlJjTmQsycyTI8E5kpuc1snoExqtwGhXruRtnoxlgcnJ8VJOioGtdS9p262NhcZ0pow2jVGKfG9tm8nNrTO4vmUa2WvGkrl8BOfWjiNj2RgSYj7hcOQnrJ7yKiEftmFan1p81L4KfZztaVpcrpMpKOFsL6b6VpFTmHKSuhCymHxZ34Ztrl7GnOi8MIHJi7zkdjidtWOjnMqLXmBUcTEVGKN6F53APNznYSIwOU9djAXGrLjkQGB++trPrMBYqs7X/iAr4qJfwvZCBCYpBFJChcDoj2fyKjAmCY5WXmQByYrIm8BoJSYrwpj0SFVilCOllAhVAEzEJKdE5+wN+j8lMMob4v8ERhWY8zHiCOncPNHBlBn7/AKjFxO9uGj/LS9DYMxKlYaUeabPoXkevcDoMVcobE5gtFiSmdymM7kp9jU5ZlJeV80IzPNIjK00xhY5OVoyLzH6RcXGk35NjpPkNuvrW6ZxbfNUrm6awuX1k7i4YRKXNk7m0oaZXPhyOmlLxnMo7CM2eb1H9GedmD2wNRP7NuSdllXo7GRP6/IFcCkjNmQ72YnW6wqyyGjTGHNt2OaOlvRYFZgr66eYHB3pBSanxbqWCndfhLxYEhhz8pJTgdEX6yqJy8N9njJCYMy1Q+dEXl6GwFhqLzT3Q6xfsJYTgfntaIBBXPQCI5KJMFlewoW8pIaZysg/VWAUiTFcjxZkxqgSkyrLS0oEltuGrWBUwJrDN+jnFRhbRbQm4hEjv+FqBEbfTWOELDBGkmJFYF44USr6WpiXITDZsWIL9ckFkDHv+QRGW1RsSWBym8AYvvbyn68XF7PHWDYEJhcJjC2B0WOpdia3qUxuBMac0JgcwedBYPIqNLkt/s1prYx1kZltVWIMw/C2zeT6lmnye/1Urm9R3vOF1FzdOI1rm6eTtXIShyM/Yr3Huyyf3Be/99swrF0FBjQuSf+6hXm1VmFalpKoZS86l5zkFQVlJHUwXkmNzOQkfbGZwNgSmGubp+ZKXKx1Hb1IcclZ8vL3CIylb1r1G/35BeaXw8EW5yNY+qG1JDDKi8GvR0MMAmOSuhwPMfBMRsiLvBMmLRLSFYn5FwmMEWYEJiUMUiMF/20CYyQv/xMYqwJzOgqy5r8cgbEkMf8pgVEkJg/HS7YKgEV3k2kRsLWuJr3YvAiBMbtAUhYYdcWKpWJfU7mxJDm5TWhyk8TYEhh9t5JebCwlMdojpJtbZ3Bz6zT5vXyanM5M5/qWGVzd6sXpNVOJjxtHwsKJ7AwazvyxvfH7oDNT+jbhk07OvN6oDK0rFaBxSYmahSQc84ki33JmkhhLwqKXGUkvLCboinaFtGjJu7y8LIHJWfLy8gXG2jfo8wqM4QfrBQjMUzO/zeRUYAzFrUlhkBKpmVcR8V8iMHKRb1qEscCkRssCEJlztG+2/wSBSdVLi5niUuUNX3uc8f9VYLKjRPqSFSHk5WULjPY2ZX7NP01gciI2uehiMicxtkTmRQiM6dFSsHhdNSMwtmbJvKhjJltHTS9CYPS1MnqJuSWnMArqe7ciNbNkZnBlw2Qyl4/gzOoxnFk9geQFwzgY+iErJ/Zg/sgu+A1swsiuNRnkUoZ2jnbUkMQMGSdJbL2uKKnzZJRZMsV0FNXxQgUmN+LysgQm5+Ly8gTG1jel8s1sVCz2HxIY/UCp5xKYtCjNgK3/IoHJjNIcI/3LBcak7djSm9l/ocCkzlMvp8fkTWDORIvvs8zY/wnMSxQYQxv2f5nA5EVictPB9HcJjJLAXN8yg2ubp3N1k3CFC+snihqZjdO5uH4ap1ZN40DIUHb5f8BGjwHMHdyWzzpV4+2WVehcvSBNSkk0Ki5RzV6WGDtBWTv1SEl/vKTl/wAGtuKSZMoHFwAAAABJRU5ErkJggg== +" +> diff --git a/dom/media/test/reftest/gizmo.mp4.seek.html b/dom/media/test/reftest/gizmo.mp4.seek.html new file mode 100644 index 0000000000..e4c1fe9515 --- /dev/null +++ b/dom/media/test/reftest/gizmo.mp4.seek.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<!--This testing should match the 55th frame of gizmo.mp4. The +55th frame's time is 1.8s, so seek to a time which is a little +greater than 1.8s, the display frame should be the 55th frame. +--> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "../gizmo.mp4"; + video.preload = "metadata"; + + video.currentTime = 1.801; + + video.addEventListener("seeked", function() { + // Since the our media pipeline send the frame to imageBridge, then fire + // seeked event, the target frame may not be shown on the screen. + // So using canvas to access the target frame in the imageContainer in + // videoElement. + var canvas = document.getElementById("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + var ctx = canvas.getContext("2d"); + ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); + document.documentElement.removeAttribute('class'); + }); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0"></video> +<canvas id="canvas" style="position:absolute; left:0; top:0"></video> +</body> +</html> diff --git a/dom/media/test/reftest/image-10bits-rendering-720-90-ref.html b/dom/media/test/reftest/image-10bits-rendering-720-90-ref.html new file mode 100644 index 0000000000..5e9a8e9b4c --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-720-90-ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE HTML> +<img style="position:absolute; left:0; top:0; filter:hue-rotate(90deg);" + src="vp9hdr2020.png" +> diff --git a/dom/media/test/reftest/image-10bits-rendering-720-90-video.html b/dom/media/test/reftest/image-10bits-rendering-720-90-video.html new file mode 100644 index 0000000000..a9ba8a9f2e --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-720-90-video.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "vp9hdr2020.webm"; + video.preload = "metadata"; + video.addEventListener("loadeddata", function() { + document.documentElement.removeAttribute('class'); + }); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0; filter:hue-rotate(90deg);"></video> +<script> +//doTest(); +</script> +</body> +</html> diff --git a/dom/media/test/reftest/image-10bits-rendering-720-ref.html b/dom/media/test/reftest/image-10bits-rendering-720-ref.html new file mode 100644 index 0000000000..1ae393031a --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-720-ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE HTML> +<img style="position:absolute; left:0; top:0" + src="vp9hdr2020.png" +> diff --git a/dom/media/test/reftest/image-10bits-rendering-720-video.html b/dom/media/test/reftest/image-10bits-rendering-720-video.html new file mode 100644 index 0000000000..93d2651ffc --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-720-video.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "vp9hdr2020.webm"; + video.preload = "metadata"; + video.addEventListener("loadeddata", function() { + document.documentElement.removeAttribute('class'); + }); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0"></video> +</body> +</html> diff --git a/dom/media/test/reftest/image-10bits-rendering-720.video.html b/dom/media/test/reftest/image-10bits-rendering-720.video.html new file mode 100644 index 0000000000..93d2651ffc --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-720.video.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "vp9hdr2020.webm"; + video.preload = "metadata"; + video.addEventListener("loadeddata", function() { + document.documentElement.removeAttribute('class'); + }); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0"></video> +</body> +</html> diff --git a/dom/media/test/reftest/image-10bits-rendering-90-ref.html b/dom/media/test/reftest/image-10bits-rendering-90-ref.html new file mode 100644 index 0000000000..38f032f0fd --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-90-ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE HTML> +<img style="position:absolute; left:0; top:0; filter:hue-rotate(90deg);" + src="av1hdr2020.png" +> diff --git a/dom/media/test/reftest/image-10bits-rendering-90-video.html b/dom/media/test/reftest/image-10bits-rendering-90-video.html new file mode 100644 index 0000000000..94edcaefd8 --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-90-video.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "av1hdr2020.mp4"; + video.preload = "metadata"; + video.addEventListener("loadeddata", function() { + document.documentElement.removeAttribute('class'); + }); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0; filter:hue-rotate(90deg);"></video> +<script> +//doTest(); +</script> +</body> +</html> diff --git a/dom/media/test/reftest/image-10bits-rendering-ref.html b/dom/media/test/reftest/image-10bits-rendering-ref.html new file mode 100644 index 0000000000..de7fbbfc95 --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE HTML> +<img style="position:absolute; left:0; top:0" + src="av1hdr2020.png" +> diff --git a/dom/media/test/reftest/image-10bits-rendering-video.html b/dom/media/test/reftest/image-10bits-rendering-video.html new file mode 100644 index 0000000000..faaf9c29ef --- /dev/null +++ b/dom/media/test/reftest/image-10bits-rendering-video.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "av1hdr2020.mp4"; + video.preload = "metadata"; + video.addEventListener("loadeddata", function() { + document.documentElement.removeAttribute('class'); + }); +} +//window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0"></video> +<script> +doTest(); +</script> +</body> +</html> diff --git a/dom/media/test/reftest/incorrect_display_in_bytestream_vp8-ref.html b/dom/media/test/reftest/incorrect_display_in_bytestream_vp8-ref.html new file mode 100644 index 0000000000..b08a8d365b --- /dev/null +++ b/dom/media/test/reftest/incorrect_display_in_bytestream_vp8-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML> +<head> +</head> +<body> +<!-- + This ref image is generated by the first frame of the testing video in webm_aspect_ratio_vp8.html +--> +<image style="position:absolute; left:0; top:0" src="data:image/png;base64,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 +"></video> +<script type="text/javascript"> +</script> +</body> +</html> diff --git a/dom/media/test/reftest/incorrect_display_in_bytestream_vp8.html b/dom/media/test/reftest/incorrect_display_in_bytestream_vp8.html new file mode 100644 index 0000000000..271343cfe2 --- /dev/null +++ b/dom/media/test/reftest/incorrect_display_in_bytestream_vp8.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +</head> +<body> +<video id="v" style="position:absolute; left:0; top:0"></video> +<canvas id="canvas" style="position:absolute; left:0; top:0"></video> +<script type="text/javascript"> +/** + * The display information in the VP8 byte stream is different from the display + * information in the container, and it's the incorrect one, which doesn't honer + * the original DAR. This test is used to check whether we will display the + * video frame in correct DAR. + */ +async function testDisplayRatioForVP8() { + const video = document.getElementById("v"); + video.src = "incorrect_display_in_bytestream_vp8.webm"; + await new Promise(r => video.oncanplay = r); + // Since our media pipeline sends the frame to imageBridge, the target frame + // may not be shown on the screen yet. So using canvas to access the target + // frame in the imageContainer in videoElement. + const canvas = document.getElementById("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + const ctx = canvas.getContext("2d"); + ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); + document.documentElement.removeAttribute('class'); +}; + +window.addEventListener("MozReftestInvalidate", testDisplayRatioForVP8); +</script> +</body> +</html> diff --git a/dom/media/test/reftest/incorrect_display_in_bytestream_vp8.webm b/dom/media/test/reftest/incorrect_display_in_bytestream_vp8.webm Binary files differnew file mode 100644 index 0000000000..e4143b7f38 --- /dev/null +++ b/dom/media/test/reftest/incorrect_display_in_bytestream_vp8.webm diff --git a/dom/media/test/reftest/incorrect_display_in_bytestream_vp9-ref.html b/dom/media/test/reftest/incorrect_display_in_bytestream_vp9-ref.html new file mode 100644 index 0000000000..6517c77f63 --- /dev/null +++ b/dom/media/test/reftest/incorrect_display_in_bytestream_vp9-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE HTML> +<head> +</head> +<body> +<!-- + This ref image is generated by the first frame of the testing video in webm_aspect_ratio_vp8.html +--> +<image style="position:absolute; left:0; top:0" src="data:image/png;base64,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"></video> +<script type="text/javascript"> +</script> +</body> +</html> diff --git a/dom/media/test/reftest/incorrect_display_in_bytestream_vp9.html b/dom/media/test/reftest/incorrect_display_in_bytestream_vp9.html new file mode 100644 index 0000000000..7d0e9404d5 --- /dev/null +++ b/dom/media/test/reftest/incorrect_display_in_bytestream_vp9.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +</head> +<body> +<video id="v" style="position:absolute; left:0; top:0"></video> +<canvas id="canvas" style="position:absolute; left:0; top:0"></video> +<script type="text/javascript"> +/** + * The display information in the VP9 byte stream is different from the display + * information in the container, and it's the incorrect one, which doesn't honer + * the original DAR. This test is used to check whether we will display the + * video frame in correct DAR. + */ +async function testDisplayRatioForVP9() { + const video = document.getElementById("v"); + video.src = "incorrect_display_in_bytestream_vp9.webm"; + await new Promise(r => video.oncanplay = r); + // Since our media pipeline sends the frame to imageBridge, the target frame + // may not be shown on the screen yet. So using canvas to access the target + // frame in the imageContainer in videoElement. + const canvas = document.getElementById("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + const ctx = canvas.getContext("2d"); + ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); + document.documentElement.removeAttribute('class'); +}; + +window.addEventListener("MozReftestInvalidate", testDisplayRatioForVP9); +</script> +</body> +</html> diff --git a/dom/media/test/reftest/incorrect_display_in_bytestream_vp9.webm b/dom/media/test/reftest/incorrect_display_in_bytestream_vp9.webm Binary files differnew file mode 100644 index 0000000000..499e3acd94 --- /dev/null +++ b/dom/media/test/reftest/incorrect_display_in_bytestream_vp9.webm diff --git a/dom/media/test/reftest/reftest.list b/dom/media/test/reftest/reftest.list new file mode 100644 index 0000000000..6bbd7b9a53 --- /dev/null +++ b/dom/media/test/reftest/reftest.list @@ -0,0 +1,15 @@ +skip-if(Android) fuzzy-if(OSX,0-80,0-76800) fuzzy-if(appleSilicon,0-80,0-76800) fuzzy-if(winWidget,0-63,0-76799) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-70,0-2032) HTTP(..) == short.mp4.firstframe.html short.mp4.firstframe-ref.html +skip-if(Android) fuzzy-if(OSX,0-87,0-76797) fuzzy-if(appleSilicon,0-87,0-76797) fuzzy-if(winWidget,0-60,0-76797) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-60,0-6070) HTTP(..) == short.mp4.lastframe.html short.mp4.lastframe-ref.html +skip-if(Android) skip-if(cocoaWidget) skip-if(winWidget) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-57,0-4282) fuzzy-if(OSX,55-80,4173-4417) HTTP(..) == bipbop_300_215kbps.mp4.lastframe.html bipbop_300_215kbps.mp4.lastframe-ref.html +skip-if(Android) fuzzy-if(OSX,0-25,0-175921) fuzzy-if(appleSilicon,34-34,40100-40100) fuzzy-if(winWidget,0-71,0-179198) HTTP(..) == gizmo.mp4.seek.html gizmo.mp4.55thframe-ref.html +# Bug 1758718 +skip-if(Android) skip-if(MinGW) skip-if(OSX) fuzzy(0-10,0-778236) == image-10bits-rendering-video.html image-10bits-rendering-ref.html +skip-if(Android) skip-if(MinGW) fuzzy(0-10,0-778536) fuzzy-if(appleSilicon,0-37,0-699614) == image-10bits-rendering-90-video.html image-10bits-rendering-90-ref.html +# Bug 1758718 +skip-if(Android) fuzzy(0-27,0-573106) skip-if(OSX) == image-10bits-rendering-720-video.html image-10bits-rendering-720-ref.html +skip-if(Android) fuzzy(0-31,0-573249) fuzzy-if(appleSilicon,0-37,0-543189) == image-10bits-rendering-720-90-video.html image-10bits-rendering-720-90-ref.html +skip-if(Android) fuzzy(0-84,0-771156) fails-if(useDrawSnapshot) == uneven_frame_duration_video.html uneven_frame_duration_video-ref.html # Skip on Windows 7 as the resolution of the video is too high for test machines and will fail in the decoder. +# Set media.dormant-on-pause-timeout-ms to avoid decoders becoming dormant and busting test, skip on android as test is too noisy and unstable +skip-if(Android) pref(media.dormant-on-pause-timeout-ms,-1) fuzzy(0-20,0-500) == frame_order_mp4.html frame_order_mp4-ref.html +skip-if(Android) fuzzy(0-30,0-270000) == incorrect_display_in_bytestream_vp8.html incorrect_display_in_bytestream_vp8-ref.html +skip-if(Android) fuzzy(0-22,0-377335) == incorrect_display_in_bytestream_vp9.html incorrect_display_in_bytestream_vp9-ref.html diff --git a/dom/media/test/reftest/reftest_img.html b/dom/media/test/reftest/reftest_img.html new file mode 100644 index 0000000000..3e55c264ec --- /dev/null +++ b/dom/media/test/reftest/reftest_img.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<meta charset='utf-8'> +</head> +<body> +<img id="e_img" style="position:absolute; left:0; top:0; max-width:100%"> +<script> +(async () => { + const params = new URLSearchParams(window.location.search); + const src = params.get('src'); + src.defined; + + e_img.src = src; + await e_img.decode() + document.documentElement.removeAttribute('class'); +})(); +</script> +</body> +</html> diff --git a/dom/media/test/reftest/reftest_video.html b/dom/media/test/reftest/reftest_video.html new file mode 100644 index 0000000000..cf9223e7ae --- /dev/null +++ b/dom/media/test/reftest/reftest_video.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<meta charset='utf-8'> +</head> +<body> +<video id="e_video" style="position:absolute; left:0; top:0; max-width:100%"> +<script> + +const TIMEOUT_MS = 2000; + +// - + +function sleepPromise(ms) { + return new Promise(go => { + setTimeout(go, ms); + }); +} + +(async () => { + await sleepPromise(TIMEOUT_MS); + if (!document.documentElement.hasAttribute('class')) return; + + const div = document.body.appendChild(document.createElement('div')); + div.textContent = `Timed out after ${TIMEOUT_MS}ms`; + console.log(div.textContent); + + document.documentElement.removeAttribute('class'); +})(); + +// - +// Test + +(async () => { + const params = new URLSearchParams(window.location.search); + const src = params.get('src'); + src.defined; + if (src == 'none') { + console.log('Show blank.'); + document.documentElement.removeAttribute('class'); + return; + } + if (src == 'timeout') { + console.log('Deliberate timeout.'); + return; + } + + e_video.src = src; + e_video.muted = true; + const p = e_video.play(); + p.defined; + try { + await p; + console.log('e_video.play() accepted'); + } catch (e) { + const div = document.body.appendChild(document.createElement('div')); + div.textContent = `Error: ${JSON.stringify(e)}`; + console.log(div.textContent); + } + document.documentElement.removeAttribute('class'); +})(); +</script> +</body> +</html> diff --git a/dom/media/test/reftest/short.mp4.firstframe-ref.html b/dom/media/test/reftest/short.mp4.firstframe-ref.html new file mode 100644 index 0000000000..d80f2f985f --- /dev/null +++ b/dom/media/test/reftest/short.mp4.firstframe-ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE HTML> +<img style="position:absolute; left:0; top:0" + src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAADwCAYAAABxLb1rAAAHv0lEQVR4nO3dQWyfdR3H8R8d7XBjMDYcYzqCQY0SkWhQAomJJ2/GgyeNiTExHk3URE9e1INGEz3NA5CYETwQFi8YEvAgGg6LogFDIojbEBTGpsyNrWNt9/HQso0Btus2vu2+r1/yypN/+/x/+fbyzpP/0z4dGSMAHY3qAQCqCCDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSCl/jNGsmFi/vUVk5mZHDk2Rl4ZI5kaOTo25MC4/NT5h8b894+PTTk+NpXPz+omgJSaGyOZGDm48PrfY2R6YmRmzMvk9cm67afOPzpGpsfIsbExx8bG8vlZ3QSQFeFPYyQ3fyzJwSRHkiQ5+lqS55P9u5P163P0De+ZWlA/O6uXALICrEk+cEvy9W8nOZTk1Zxe/5yP4JVX5vgb3jOVjCtWwOysZgJIqSNjazJ5c+75zleTnMib12tJppOJLTnziu/IGHl1BczP6iaAlNoz1iSbbl+48nvlLQJ4/IwATp56nwByIQggpXbc+enk4d+edcV3IslskrnTX558YwDhQhBAaj3yaPLyoTMCOLsQwDkB5KITQEo8dP2G5N4dycwZkft/a921mRlryufm0iKA1Lh3R7L/2aXFTwC5SASQd9TOmzYnD9y99PC9vq7aeNbvAcL5E0DeWQ/cnTz3hACyIgggF8XJhePcmMihMfLzz9yW/PHhcw+fAHIRCSAX3sTEqeOJMZKP3568/Nfk8D4BZEURQC6eDRvy+599N8nR5YfvVACvyrHqn4dLjgBycWzfnnz/B8nJg0mOCSArkgByQcyNtTk6Ru6/447krrvy+hNdTi5atpnMPwFmkbXh7IchwPkTQM7fmg2ZHVPJ+29LnnoqOXDgHC7tZhYIIO88AWRZXr/L++jnPpvHv/TF5F9/yann+C2y5k4eTQ6eTHb/Lfd97fPJkX1LCOC6+RsqcAEJIMv30VuTx36XHNif0w8xWOJ6+kD+8OVv5Cs3XZ0c3iOAlBBAluWRa65Knt+7pNYdS5LZhU8D9+1JfrUrGZuSqffmnmu3Jc/sE0BKCCDLci4BPHPNfuub+cV1W5KxKRkb5wP47D8EkBICyLLs2rIteekcbnbs+HVy5xfetM9Da7cmTzwngJQQQJZlyQGcnsnuH/4key+/KU+PG07vMTF/fGjt1uRJV4DUEECW5b5t25KDbxHAuePzHns8+d6PkhuvSybffp+dm69N/u4mCDUEkGV52wBOH85/d96TJ2+9PQ9es3XRfQSQSgLIsjy45erkxb2Z/yuOY8lju5Mf/zT54KeSsXn+H54vwc7Nm5I9S3gwqgByEQggy3IqgIefyZO7duTPn7wzj37oI5kdIxlXJxNrl7SPAFJJAFmWE2Mkt3w42bg+WbP8fQSQSgLIssyMkVxx+XnvI4BUEkBKLTmA69ct+XNFWCoBpNQvr3t3sm/v4gGcmhJALjgBpNT929+TvPjC4gFcAbNy6RFASu163w3J/hcFkBICSCkBpJIAUkoAqSSAlBJAKgkgpQSQSgJIKQGkkgBSSgCpJICUEkAqCSClBJBKAkgpAaSSAFJKAKkkgJQSQCoJIKUEkEoCSCkBpJIAUkoAqSSAlBJAKgkgpQSQSgJIKQGkkgBSSgCpJICUEkAqCSClBJBKAkgpAaSSAFJKAKkkgJQSQCoJIKUEkEoCSCkBpJIAUkoAqSSAlBJAKgkgpQSQSgJIKQGkkgBSSgCpJICUEkAqCSClBJBKAkgpAaSSAFJKAKkkgJQSQCoJIKUEkEoCSKkHbtyevPySAFJCACklgFQSQEr9ZvMnkj2L92924rLMXFY/L5cWAaTUI5tuS/YtUr+T0zk4RrJ2snxeLi0CyIpy8qzX02MqM2NdXn3TuVML6mdm9RJAVrQT412ZfsvQrV1QPyOrlwCyqswuqJ6DS4MAsqoIIBeSAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0JYAAm0JINCWAAJtCSDQlgACbQkg0Nb/AJRYBp4E6qsBAAAAAElFTkSuQmCC" +> diff --git a/dom/media/test/reftest/short.mp4.firstframe.html b/dom/media/test/reftest/short.mp4.firstframe.html new file mode 100644 index 0000000000..759bdc5ede --- /dev/null +++ b/dom/media/test/reftest/short.mp4.firstframe.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "../short.mp4"; + video.preload = "metadata"; + video.addEventListener("loadeddata", function() { + document.documentElement.removeAttribute('class'); + }); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0"></video> +</body> +</html> diff --git a/dom/media/test/reftest/short.mp4.lastframe-ref.html b/dom/media/test/reftest/short.mp4.lastframe-ref.html new file mode 100644 index 0000000000..7474b9039e --- /dev/null +++ b/dom/media/test/reftest/short.mp4.lastframe-ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE HTML> +<img style="position:absolute; left:0; top:0" +src="data:image/png;base64,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" +> diff --git a/dom/media/test/reftest/short.mp4.lastframe.html b/dom/media/test/reftest/short.mp4.lastframe.html new file mode 100644 index 0000000000..abd27c5c8e --- /dev/null +++ b/dom/media/test/reftest/short.mp4.lastframe.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + video.src = "../short.mp4"; + video.preload = "metadata"; + video.seenEnded = false; + // Seek to the end + video.addEventListener("loadeddata", function() { + video.currentTime = video.duration; + video.onseeked = () => { + video.onseeked = null; + callSeekToNextFrame(); + }; + }); + + function callSeekToNextFrame() { + video.seekToNextFrame().then( + () => { + if (!video.seenEnded) + callSeekToNextFrame(); + }, + () => { + // Reach the end, do nothing. + } + ); + } + + video.addEventListener("ended", function() { + video.seenEnded = true; + document.documentElement.removeAttribute('class'); + }); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0"></video> +</body> +</html> diff --git a/dom/media/test/reftest/uneven_frame_duration_video-ref.html b/dom/media/test/reftest/uneven_frame_duration_video-ref.html new file mode 100644 index 0000000000..6f1d73cc71 --- /dev/null +++ b/dom/media/test/reftest/uneven_frame_duration_video-ref.html @@ -0,0 +1,7 @@ +<!DOCTYPE HTML>
+<img style="position:absolute; left:0; top:0"
+src="uneven_frame_durations_3.8s_frame.png"
+>
+<!-- Test frame created via
+`ffmpeg.exe -i uneven_frame_durations.mp4 -ss 3.8 -frames 1 uneven_frame_durations_3.8s_frame.png`
+-->
diff --git a/dom/media/test/reftest/uneven_frame_duration_video.html b/dom/media/test/reftest/uneven_frame_duration_video.html new file mode 100644 index 0000000000..73ca34b8bd --- /dev/null +++ b/dom/media/test/reftest/uneven_frame_duration_video.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<!--Tests the fix for bug 1576990. We want to make sure the frames do not + become stuck due to decoders (in particular the Windows decoder) estimating + frame durations incorrectly. +--> +<head> +<script type="text/javascript"> +function doTest() { + var video = document.getElementById("v1"); + // Video from bug 1576990. + video.src = "uneven_frame_durations.mp4"; + video.preload = "metadata"; + + // This frame differs depending on if the Windows' decoder is estimating + // frame duration or if we use Gecko durations. + video.currentTime = 3.8; + + video.addEventListener("seeked", function() { + // Since our media pipeline sends the frame to imageBridge, then fires + // a seeked event, the target frame may not be shown on the screen. + // So using canvas to access the target frame in the imageContainer in + // videoElement. + var canvas = document.getElementById("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + var ctx = canvas.getContext("2d"); + ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); + document.documentElement.removeAttribute("class"); + }); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> +</head> +<body> +<video id="v1" style="position:absolute; left:0; top:0"></video> +<canvas id="canvas" style="position:absolute; left:0; top:0"></video> +</body> +</html> diff --git a/dom/media/test/reftest/uneven_frame_durations.mp4 b/dom/media/test/reftest/uneven_frame_durations.mp4 Binary files differnew file mode 100644 index 0000000000..a5a0c16a0f --- /dev/null +++ b/dom/media/test/reftest/uneven_frame_durations.mp4 diff --git a/dom/media/test/reftest/uneven_frame_durations_3.8s_frame.png b/dom/media/test/reftest/uneven_frame_durations_3.8s_frame.png Binary files differnew file mode 100644 index 0000000000..889174e115 --- /dev/null +++ b/dom/media/test/reftest/uneven_frame_durations_3.8s_frame.png diff --git a/dom/media/test/reftest/vp9hdr2020.png b/dom/media/test/reftest/vp9hdr2020.png Binary files differnew file mode 100644 index 0000000000..afb68d9e0a --- /dev/null +++ b/dom/media/test/reftest/vp9hdr2020.png diff --git a/dom/media/test/reftest/vp9hdr2020.webm b/dom/media/test/reftest/vp9hdr2020.webm Binary files differnew file mode 100644 index 0000000000..516f62093a --- /dev/null +++ b/dom/media/test/reftest/vp9hdr2020.webm diff --git a/dom/media/test/resolution-change.webm b/dom/media/test/resolution-change.webm Binary files differnew file mode 100644 index 0000000000..29aad93b96 --- /dev/null +++ b/dom/media/test/resolution-change.webm diff --git a/dom/media/test/resolution-change.webm^headers^ b/dom/media/test/resolution-change.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/resolution-change.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/sample-encrypted-sgpdstbl-sbgptraf.mp4 b/dom/media/test/sample-encrypted-sgpdstbl-sbgptraf.mp4 Binary files differnew file mode 100644 index 0000000000..720339bdc2 --- /dev/null +++ b/dom/media/test/sample-encrypted-sgpdstbl-sbgptraf.mp4 diff --git a/dom/media/test/sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^ b/dom/media/test/sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/sample-encrypted-sgpdstbl-sbgptraf.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/sample-fisbone-skeleton4.ogv b/dom/media/test/sample-fisbone-skeleton4.ogv Binary files differnew file mode 100644 index 0000000000..8afe0be7a4 --- /dev/null +++ b/dom/media/test/sample-fisbone-skeleton4.ogv diff --git a/dom/media/test/sample-fisbone-skeleton4.ogv^headers^ b/dom/media/test/sample-fisbone-skeleton4.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/sample-fisbone-skeleton4.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/sample-fisbone-wrong-header.ogv b/dom/media/test/sample-fisbone-wrong-header.ogv Binary files differnew file mode 100644 index 0000000000..46c3933da5 --- /dev/null +++ b/dom/media/test/sample-fisbone-wrong-header.ogv diff --git a/dom/media/test/sample-fisbone-wrong-header.ogv^headers^ b/dom/media/test/sample-fisbone-wrong-header.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/sample-fisbone-wrong-header.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/sample.3g2 b/dom/media/test/sample.3g2 Binary files differnew file mode 100644 index 0000000000..769cb01dbd --- /dev/null +++ b/dom/media/test/sample.3g2 diff --git a/dom/media/test/sample.3gp b/dom/media/test/sample.3gp Binary files differnew file mode 100644 index 0000000000..4a3d8ea66f --- /dev/null +++ b/dom/media/test/sample.3gp diff --git a/dom/media/test/seek-short.ogv b/dom/media/test/seek-short.ogv Binary files differnew file mode 100644 index 0000000000..a5ca6951d0 --- /dev/null +++ b/dom/media/test/seek-short.ogv diff --git a/dom/media/test/seek-short.ogv^headers^ b/dom/media/test/seek-short.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/seek-short.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/seek-short.webm b/dom/media/test/seek-short.webm Binary files differnew file mode 100644 index 0000000000..36abd1570e --- /dev/null +++ b/dom/media/test/seek-short.webm diff --git a/dom/media/test/seek-short.webm^headers^ b/dom/media/test/seek-short.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/seek-short.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/seek.ogv b/dom/media/test/seek.ogv Binary files differnew file mode 100644 index 0000000000..ac7ece3519 --- /dev/null +++ b/dom/media/test/seek.ogv diff --git a/dom/media/test/seek.ogv^headers^ b/dom/media/test/seek.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/seek.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/seek.webm b/dom/media/test/seek.webm Binary files differnew file mode 100644 index 0000000000..72b0297233 --- /dev/null +++ b/dom/media/test/seek.webm diff --git a/dom/media/test/seek.webm^headers^ b/dom/media/test/seek.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/seek.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/seekLies.sjs b/dom/media/test/seekLies.sjs new file mode 100644 index 0000000000..4fc528a0a5 --- /dev/null +++ b/dom/media/test/seekLies.sjs @@ -0,0 +1,22 @@ +function handleRequest(request, response) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + var paths = "tests/dom/media/test/seek.ogv"; + var split = paths.split("/"); + for (var i = 0; i < split.length; ++i) { + file.append(split[i]); + } + fis.init(file, -1, -1, false); + bis.setInputStream(fis); + var bytes = bis.readBytes(bis.available()); + response.setHeader("Content-Length", "" + bytes.length, false); + response.setHeader("Content-Type", "video/ogg", false); + response.setHeader("Accept-Ranges", "bytes", false); + response.write(bytes, bytes.length); + bis.close(); +} diff --git a/dom/media/test/seek_support.js b/dom/media/test/seek_support.js new file mode 100644 index 0000000000..ca6d563f1a --- /dev/null +++ b/dom/media/test/seek_support.js @@ -0,0 +1,61 @@ +// This file expects manifest.js to be included in the same scope. +/* import-globals-from manifest.js */ +// This file expects SEEK_TEST_NUMBER to be defined by the test. +/* global SEEK_TEST_NUMBER */ +var manager = new MediaTestManager(); + +function createTestArray() { + var tests = []; + var tmpVid = document.createElement("video"); + + for (var testNum = 0; testNum < gSeekTests.length; testNum++) { + var test = gSeekTests[testNum]; + if (!tmpVid.canPlayType(test.type)) { + continue; + } + + var t = {}; + t.name = test.name; + t.type = test.type; + t.duration = test.duration; + t.number = SEEK_TEST_NUMBER; + tests.push(t); + } + return tests; +} + +function startTest(test, token) { + var video = document.createElement("video"); + video.token = token += "-seek" + test.number + ".js"; + manager.started(video.token); + video.src = test.name; + video.preload = "metadata"; + document.body.appendChild(video); + var name = test.name + " seek test " + test.number; + var localIs = (function (n) { + return function (a, b, msg) { + is(a, b, n + ": " + msg); + }; + })(name); + var localOk = (function (n) { + return function (a, msg) { + ok(a, n + ": " + msg); + }; + })(name); + var localFinish = (function (v, m) { + return function () { + v.onerror = null; + removeNodeAndSource(v); + dump("SEEK-TEST: Finished " + name + " token: " + v.token + "\n"); + m.finished(v.token); + }; + })(video, manager); + dump("SEEK-TEST: Started " + name + "\n"); + window["test_seek" + test.number]( + video, + test.duration / 2, + localIs, + localOk, + localFinish + ); +} diff --git a/dom/media/test/seek_with_sound.ogg b/dom/media/test/seek_with_sound.ogg Binary files differnew file mode 100644 index 0000000000..c86d9946bd --- /dev/null +++ b/dom/media/test/seek_with_sound.ogg diff --git a/dom/media/test/seek_with_sound.ogg^headers^ b/dom/media/test/seek_with_sound.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/seek_with_sound.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/short-aac-encrypted-audio.mp4 b/dom/media/test/short-aac-encrypted-audio.mp4 Binary files differnew file mode 100644 index 0000000000..c1ba8d37e4 --- /dev/null +++ b/dom/media/test/short-aac-encrypted-audio.mp4 diff --git a/dom/media/test/short-aac-encrypted-audio.mp4^headers^ b/dom/media/test/short-aac-encrypted-audio.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/short-aac-encrypted-audio.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/short-audio-fragmented-cenc-without-pssh.mp4 b/dom/media/test/short-audio-fragmented-cenc-without-pssh.mp4 Binary files differnew file mode 100644 index 0000000000..bc58623999 --- /dev/null +++ b/dom/media/test/short-audio-fragmented-cenc-without-pssh.mp4 diff --git a/dom/media/test/short-audio-fragmented-cenc-without-pssh.mp4^headers^ b/dom/media/test/short-audio-fragmented-cenc-without-pssh.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/short-audio-fragmented-cenc-without-pssh.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/short-cenc-pssh-in-moof.mp4 b/dom/media/test/short-cenc-pssh-in-moof.mp4 Binary files differnew file mode 100644 index 0000000000..aa44c3b9a1 --- /dev/null +++ b/dom/media/test/short-cenc-pssh-in-moof.mp4 diff --git a/dom/media/test/short-cenc.mp4 b/dom/media/test/short-cenc.mp4 Binary files differnew file mode 100644 index 0000000000..aa44c3b9a1 --- /dev/null +++ b/dom/media/test/short-cenc.mp4 diff --git a/dom/media/test/short-cenc.xml b/dom/media/test/short-cenc.xml new file mode 100644 index 0000000000..9658c3e32f --- /dev/null +++ b/dom/media/test/short-cenc.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + This XML file describes the encryption applied to short-cenc.mp4. To generate + short-cenc, run the following command: + + MP4Box -crypt short-cenc.xml -out short-cenc.mp4 short.mp4 +--> + +<GPACDRM type="CENC AES-CTR"> + + <DRMInfo type="pssh" version="1"> + <!-- + SystemID specified in + https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/cenc-format.html + --> + <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b" /> + <!-- Number of KeyIDs = 2 --> + <BS bits="32" value="2" /> + <!-- KeyID --> + <BS ID128="0x7e571d017e571d017e571d017e571d01" /> + <BS ID128="0x7e571d027e571d027e571d027e571d02" /> + </DRMInfo> + + <CrypTrack trackID="1" isEncrypted="1" IV_size="16" saiSavedBox="senc" + first_IV="0x00000000000000000000000000000000"> + <key KID="0x7e571d017e571d017e571d017e571d01" + value="0x7e5711117e5711117e5711117e571111" /> + </CrypTrack> + + <CrypTrack trackID="2" isEncrypted="1" IV_size="16" saiSavedBox="senc" + first_IV="0x00000000000000000000000000000000"> + <key KID="0x7e571d027e571d027e571d027e571d02" + value="0x7e5722227e5722227e5722227e572222" /> + </CrypTrack> + +</GPACDRM> diff --git a/dom/media/test/short-video.ogv b/dom/media/test/short-video.ogv Binary files differnew file mode 100644 index 0000000000..68dee3cf2b --- /dev/null +++ b/dom/media/test/short-video.ogv diff --git a/dom/media/test/short-video.ogv^headers^ b/dom/media/test/short-video.ogv^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/short-video.ogv^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/short-vp9-encrypted-video.mp4 b/dom/media/test/short-vp9-encrypted-video.mp4 Binary files differnew file mode 100644 index 0000000000..23d1083d18 --- /dev/null +++ b/dom/media/test/short-vp9-encrypted-video.mp4 diff --git a/dom/media/test/short-vp9-encrypted-video.mp4^headers^ b/dom/media/test/short-vp9-encrypted-video.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/short-vp9-encrypted-video.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/short.mp4 b/dom/media/test/short.mp4 Binary files differnew file mode 100644 index 0000000000..802da047bc --- /dev/null +++ b/dom/media/test/short.mp4 diff --git a/dom/media/test/short.mp4.gz b/dom/media/test/short.mp4.gz Binary files differnew file mode 100644 index 0000000000..efb95e38e3 --- /dev/null +++ b/dom/media/test/short.mp4.gz diff --git a/dom/media/test/short.mp4^headers^ b/dom/media/test/short.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/short.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/shorter_audio_than_video_3s.webm b/dom/media/test/shorter_audio_than_video_3s.webm Binary files differnew file mode 100644 index 0000000000..5f8f49b4ac --- /dev/null +++ b/dom/media/test/shorter_audio_than_video_3s.webm diff --git a/dom/media/test/shorter_audio_than_video_3s.webm^headers^ b/dom/media/test/shorter_audio_than_video_3s.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/shorter_audio_than_video_3s.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/sin-441-1s-44100-afconvert.mp4 b/dom/media/test/sin-441-1s-44100-afconvert.mp4 Binary files differnew file mode 100644 index 0000000000..2e2763823d --- /dev/null +++ b/dom/media/test/sin-441-1s-44100-afconvert.mp4 diff --git a/dom/media/test/sin-441-1s-44100-fdk_aac.mp4 b/dom/media/test/sin-441-1s-44100-fdk_aac.mp4 Binary files differnew file mode 100644 index 0000000000..34b54a1849 --- /dev/null +++ b/dom/media/test/sin-441-1s-44100-fdk_aac.mp4 diff --git a/dom/media/test/sin-441-1s-44100-lame.mp3 b/dom/media/test/sin-441-1s-44100-lame.mp3 Binary files differnew file mode 100644 index 0000000000..f0c0164c0a --- /dev/null +++ b/dom/media/test/sin-441-1s-44100-lame.mp3 diff --git a/dom/media/test/sin-441-1s-44100.flac b/dom/media/test/sin-441-1s-44100.flac Binary files differnew file mode 100644 index 0000000000..960044638c --- /dev/null +++ b/dom/media/test/sin-441-1s-44100.flac diff --git a/dom/media/test/sin-441-1s-44100.ogg b/dom/media/test/sin-441-1s-44100.ogg Binary files differnew file mode 100644 index 0000000000..16c197b633 --- /dev/null +++ b/dom/media/test/sin-441-1s-44100.ogg diff --git a/dom/media/test/sin-441-1s-44100.opus b/dom/media/test/sin-441-1s-44100.opus Binary files differnew file mode 100644 index 0000000000..795034521d --- /dev/null +++ b/dom/media/test/sin-441-1s-44100.opus diff --git a/dom/media/test/sine.webm b/dom/media/test/sine.webm Binary files differnew file mode 100644 index 0000000000..3913ffa874 --- /dev/null +++ b/dom/media/test/sine.webm diff --git a/dom/media/test/sine.webm^headers^ b/dom/media/test/sine.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/sine.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/single-xing-header-no-content-length.mp3 b/dom/media/test/single-xing-header-no-content-length.mp3 Binary files differnew file mode 100644 index 0000000000..aef54e220a --- /dev/null +++ b/dom/media/test/single-xing-header-no-content-length.mp3 diff --git a/dom/media/test/single-xing-header-no-content-length.mp3^headers^ b/dom/media/test/single-xing-header-no-content-length.mp3^headers^ new file mode 100644 index 0000000000..abfeb4ce28 --- /dev/null +++ b/dom/media/test/single-xing-header-no-content-length.mp3^headers^ @@ -0,0 +1,3 @@ +HTTP 200 OK +Content-Length: invalid +Cache-Control: no-store diff --git a/dom/media/test/sintel-short-clearkey-subsample-encrypted-audio.webm b/dom/media/test/sintel-short-clearkey-subsample-encrypted-audio.webm Binary files differnew file mode 100644 index 0000000000..7497096ba5 --- /dev/null +++ b/dom/media/test/sintel-short-clearkey-subsample-encrypted-audio.webm diff --git a/dom/media/test/sintel-short-clearkey-subsample-encrypted-audio.webm^headers^ b/dom/media/test/sintel-short-clearkey-subsample-encrypted-audio.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/sintel-short-clearkey-subsample-encrypted-audio.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/sintel-short-clearkey-subsample-encrypted-video.webm b/dom/media/test/sintel-short-clearkey-subsample-encrypted-video.webm Binary files differnew file mode 100644 index 0000000000..0f7609439d --- /dev/null +++ b/dom/media/test/sintel-short-clearkey-subsample-encrypted-video.webm diff --git a/dom/media/test/sintel-short-clearkey-subsample-encrypted-video.webm^headers^ b/dom/media/test/sintel-short-clearkey-subsample-encrypted-video.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/sintel-short-clearkey-subsample-encrypted-video.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/small-shot-mp3.mp4 b/dom/media/test/small-shot-mp3.mp4 Binary files differnew file mode 100644 index 0000000000..61fe0ac719 --- /dev/null +++ b/dom/media/test/small-shot-mp3.mp4 diff --git a/dom/media/test/small-shot-mp3.mp4^headers^ b/dom/media/test/small-shot-mp3.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/small-shot-mp3.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/small-shot.flac b/dom/media/test/small-shot.flac Binary files differnew file mode 100644 index 0000000000..0da7c9044e --- /dev/null +++ b/dom/media/test/small-shot.flac diff --git a/dom/media/test/small-shot.m4a b/dom/media/test/small-shot.m4a Binary files differnew file mode 100644 index 0000000000..51a23c5b49 --- /dev/null +++ b/dom/media/test/small-shot.m4a diff --git a/dom/media/test/small-shot.mp3 b/dom/media/test/small-shot.mp3 Binary files differnew file mode 100644 index 0000000000..f9397a5106 --- /dev/null +++ b/dom/media/test/small-shot.mp3 diff --git a/dom/media/test/small-shot.mp3^headers^ b/dom/media/test/small-shot.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/small-shot.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/small-shot.ogg b/dom/media/test/small-shot.ogg Binary files differnew file mode 100644 index 0000000000..1a41623f81 --- /dev/null +++ b/dom/media/test/small-shot.ogg diff --git a/dom/media/test/small-shot.ogg^headers^ b/dom/media/test/small-shot.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/small-shot.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/sound.ogg b/dom/media/test/sound.ogg Binary files differnew file mode 100644 index 0000000000..edda4e9128 --- /dev/null +++ b/dom/media/test/sound.ogg diff --git a/dom/media/test/sound.ogg^headers^ b/dom/media/test/sound.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/sound.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/spacestorm-1000Hz-100ms.ogg b/dom/media/test/spacestorm-1000Hz-100ms.ogg Binary files differnew file mode 100644 index 0000000000..994041e1b0 --- /dev/null +++ b/dom/media/test/spacestorm-1000Hz-100ms.ogg diff --git a/dom/media/test/spacestorm-1000Hz-100ms.ogg^headers^ b/dom/media/test/spacestorm-1000Hz-100ms.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/spacestorm-1000Hz-100ms.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/split.webm b/dom/media/test/split.webm Binary files differnew file mode 100644 index 0000000000..9207017fb6 --- /dev/null +++ b/dom/media/test/split.webm diff --git a/dom/media/test/split.webm^headers^ b/dom/media/test/split.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/split.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/street.mp4 b/dom/media/test/street.mp4 Binary files differnew file mode 100644 index 0000000000..837d23b383 --- /dev/null +++ b/dom/media/test/street.mp4 diff --git a/dom/media/test/street.mp4^headers^ b/dom/media/test/street.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/street.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/sync.webm b/dom/media/test/sync.webm Binary files differnew file mode 100644 index 0000000000..91ce6320b5 --- /dev/null +++ b/dom/media/test/sync.webm diff --git a/dom/media/test/test-1-mono.opus b/dom/media/test/test-1-mono.opus Binary files differnew file mode 100644 index 0000000000..d5198e9ceb --- /dev/null +++ b/dom/media/test/test-1-mono.opus diff --git a/dom/media/test/test-1-mono.opus^headers^ b/dom/media/test/test-1-mono.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-1-mono.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test-2-stereo.opus b/dom/media/test/test-2-stereo.opus Binary files differnew file mode 100644 index 0000000000..7115cac243 --- /dev/null +++ b/dom/media/test/test-2-stereo.opus diff --git a/dom/media/test/test-2-stereo.opus^headers^ b/dom/media/test/test-2-stereo.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-2-stereo.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test-3-LCR.opus b/dom/media/test/test-3-LCR.opus Binary files differnew file mode 100644 index 0000000000..145536f3e7 --- /dev/null +++ b/dom/media/test/test-3-LCR.opus diff --git a/dom/media/test/test-3-LCR.opus^headers^ b/dom/media/test/test-3-LCR.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-3-LCR.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test-4-quad.opus b/dom/media/test/test-4-quad.opus Binary files differnew file mode 100644 index 0000000000..731b867b2e --- /dev/null +++ b/dom/media/test/test-4-quad.opus diff --git a/dom/media/test/test-4-quad.opus^headers^ b/dom/media/test/test-4-quad.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-4-quad.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test-5-5.0.opus b/dom/media/test/test-5-5.0.opus Binary files differnew file mode 100644 index 0000000000..7eb2faa812 --- /dev/null +++ b/dom/media/test/test-5-5.0.opus diff --git a/dom/media/test/test-5-5.0.opus^headers^ b/dom/media/test/test-5-5.0.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-5-5.0.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test-6-5.1.opus b/dom/media/test/test-6-5.1.opus Binary files differnew file mode 100644 index 0000000000..526515eb7b --- /dev/null +++ b/dom/media/test/test-6-5.1.opus diff --git a/dom/media/test/test-6-5.1.opus^headers^ b/dom/media/test/test-6-5.1.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-6-5.1.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test-7-6.1.opus b/dom/media/test/test-7-6.1.opus Binary files differnew file mode 100644 index 0000000000..8b6a7ce329 --- /dev/null +++ b/dom/media/test/test-7-6.1.opus diff --git a/dom/media/test/test-7-6.1.opus^headers^ b/dom/media/test/test-7-6.1.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-7-6.1.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test-8-7.1.opus b/dom/media/test/test-8-7.1.opus Binary files differnew file mode 100644 index 0000000000..e56176a30f --- /dev/null +++ b/dom/media/test/test-8-7.1.opus diff --git a/dom/media/test/test-8-7.1.opus^headers^ b/dom/media/test/test-8-7.1.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-8-7.1.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test-stereo-phase-inversion-180.opus b/dom/media/test/test-stereo-phase-inversion-180.opus Binary files differnew file mode 100644 index 0000000000..ce70290002 --- /dev/null +++ b/dom/media/test/test-stereo-phase-inversion-180.opus diff --git a/dom/media/test/test-stereo-phase-inversion-180.opus^headers^ b/dom/media/test/test-stereo-phase-inversion-180.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/test-stereo-phase-inversion-180.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/test_VideoPlaybackQuality.html b/dom/media/test/test_VideoPlaybackQuality.html new file mode 100644 index 0000000000..67636f9ea6 --- /dev/null +++ b/dom/media/test/test_VideoPlaybackQuality.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test basic functionality of VideoPlaybackQuality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function test() { + var video = document.createElement("video"); + ok(video.getVideoPlaybackQuality, "getVideoPlaybackQuality should be exposed with pref set"); + + var vpq = video.getVideoPlaybackQuality(); + ok(vpq, "getVideoPlaybackQuality should return an object"); + ok(vpq.creationTime <= performance.now(), "creationTime should be in the past"); + is(vpq.totalVideoFrames, 0, "totalVideoFrames should be 0"); + is(vpq.droppedVideoFrames, 0, "droppedVideoFrames should be 0"); + + var vpq2 = video.getVideoPlaybackQuality(); + ok(vpq !== vpq2, "getVideoPlaybackQuality should return a new object"); + ok(vpq.creationTime <= vpq2.creationTime, "VideoPlaybackQuality objects should have increasing creationTime"); + + var audio = document.createElement("audio"); + ok(!audio.getVideoPlaybackQuality, "getVideoPlaybackQuality should not be available on Audio elements"); + + video.src = "seek.webm"; + video.play(); + video.addEventListener("ended", function () { + vpq = video.getVideoPlaybackQuality(); + ok(vpq.creationTime <= performance.now(), "creationTime should be in the past"); + ok(vpq.totalVideoFrames > 0, "totalVideoFrames should be > 0"); + ok(vpq.droppedVideoFrames >= 0, "droppedVideoFrames should be >= 0"); + ok(vpq.droppedVideoFrames <= vpq.totalVideoFrames, "droppedVideoFrames should be <= totalVideoFrames"); + + SpecialPowers.pushPrefEnv({"set": [["media.video_stats.enabled", false]]}, function () { + vpq = video.getVideoPlaybackQuality(); + is(vpq.creationTime, 0, "creationTime should be 0"); + is(vpq.totalVideoFrames, 0, "totalVideoFrames should be 0"); + is(vpq.droppedVideoFrames, 0, "droppedVideoFrames should be 0"); + + SimpleTest.finish(); + }); + }); +} + +addLoadEvent(function() { + SpecialPowers.pushPrefEnv({"set": + [ + ["media.mediasource.enabled", true], + ] + }, test); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_VideoPlaybackQuality_disabled.html b/dom/media/test/test_VideoPlaybackQuality_disabled.html new file mode 100644 index 0000000000..1c41b79d8b --- /dev/null +++ b/dom/media/test/test_VideoPlaybackQuality_disabled.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test basic functionality of VideoPlaybackQuality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function test() { + var video = document.createElement("video"); + ok(!video.getVideoPlaybackQuality, "getVideoPlaybackQuality should be hidden behind a pref"); + var accessThrows = false; + try { + video.getVideoPlaybackQuality(); + } catch (e) { + accessThrows = true; + } + ok(accessThrows, "getVideoPlaybackQuality should be hidden behind a pref"); + SimpleTest.finish(); +} + +addLoadEvent(function() { + SpecialPowers.pushPrefEnv({"set": + [ + ["media.mediasource.enabled", false], + ] + }, test); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_access_control.html b/dom/media/test/test_access_control.html new file mode 100644 index 0000000000..bad43dff22 --- /dev/null +++ b/dom/media/test/test_access_control.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=451958 +--> +<head> + <title>Test for Bug 451958</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=451958">Mozilla Bug 451958</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 451958 **/ + +function openWindow() { + window.open("http://example.org:80/tests/dom/media/test/file_access_controls.html", "", "width=500,height=500"); +} + +function run() { + SpecialPowers.pushPrefEnv({ + "set": [ + ["dom.security.https_first", false], + ], + }, openWindow); +} + +function done() { + mediaTestCleanup(); + SimpleTest.finish(); +} + +addLoadEvent(run); +SimpleTest.waitForExplicitFinish(); + + +window.addEventListener("message", receiveMessage); + +function receiveMessage(event) +{ + if (event.origin !== "http://example.org") { + ok(false, "Received message from wrong domain"); + return; + } + + if (event.data.done == "true") { + done(); + return; + } + + ok(event.data.result, event.data.message); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_arraybuffer.html b/dom/media/test/test_arraybuffer.html new file mode 100644 index 0000000000..9ef84c53dc --- /dev/null +++ b/dom/media/test/test_arraybuffer.html @@ -0,0 +1,83 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1462967 +--> +<head> + <title>Test for Bug 1457661</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1457661">Mozilla Bug 1457661</a> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +// Test for Bug 1457661; Ensure that readyState properly move to 4 when using arrayBuffer obtained from XMLHttpRequest + +var manager = new MediaTestManager; + +function getBlob(url, callback) { + const req = new XMLHttpRequest(); + req.addEventListener("load", function() { + callback(req.response); + }); + req.open("GET", url, true); + req.responseType = "arraybuffer"; + req.send(); +} + +function startTest(test, token) { + manager.started(token); + // Fetch the media resource using XHR so we can be sure the entire + // resource is loaded before we test buffered ranges. This ensures + // we have deterministic behaviour. + getBlob(test.name, function(arr) { + const v = document.createElement("video"); + const events = [ "suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", + "waiting", "pause", "durationchange", "seeking", "seeked" ]; + function logEvent(e) { + info(test.name + ": got " + e.type + " event"); + } + events.forEach(function(e) { + v.addEventListener(e, logEvent); + }); + once(v, "stalled", function(e) { + // Resource fetch algorithm in local mode should never fire stalled event. + // https://html.spec.whatwg.org/multipage/media.html#concept-media-load-resource + ok(false, test.name + ": got stalled"); + removeNodeAndSource(v); + manager.finished(token); + }); + once(v, "canplaythrough", function(e) { + ok(true, test.name + ": got canplaythrough"); + is(v.readyState, v.HAVE_ENOUGH_DATA, test.name + ": readyState is HAVE_ENOUGH_DATA"); + removeNodeAndSource(v); + manager.finished(token); + }); + const blob = new Blob([arr], {type:test.type}); + const blobUrl = URL.createObjectURL(blob); + + document.body.appendChild(v); + v.preload = "auto"; + v.src = blobUrl; + v.load(); + }); +} + +SimpleTest.waitForExplicitFinish(); +// Note: No need to set media test prefs, since we're using XHR to fetch +// media data. +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_aspectratio_mp4.html b/dom/media/test/test_aspectratio_mp4.html new file mode 100644 index 0000000000..5e01875439 --- /dev/null +++ b/dom/media/test/test_aspectratio_mp4.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=975978 +--> + +<head> + <title>Media test: default video size</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=975978">Mozilla Bug 975978</a> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +// MP4 video with display size is difference to decode frame size. +// The display size is recorded in TrackHeaderBox 'tkhd' of this mp4 video. +var resource = + { name:"pixel_aspect_ratio.mp4", type:"video/mp4", width:525, height:288 }; + +var v = document.createElement("video"); +v.onloadedmetadata = function() { + is(v.videoWidth, resource.width, "Intrinsic width should match video width"); + is(v.videoHeight, resource.height, "Intrinsic height should match video height"); + SimpleTest.finish(); +} +v.addEventListener("error", function(ev) { + if (v.readyState < v.HAVE_METADATA) { + info("Video element returns with readyState " + v.readyState + " error.code " + v.error.code); + todo(false, "This platform doesn't support to retrieve MP4 metadata."); + SimpleTest.finish(); + } +}); + +v.src = resource.name; +v.preload = "auto"; + +document.body.appendChild(v); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_audio1.html b/dom/media/test/test_audio1.html new file mode 100644 index 0000000000..a5d9f12ab9 --- /dev/null +++ b/dom/media/test/test_audio1.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: Audio Constructor Test 1</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var a1 = new Audio(); + if (!a1.canPlayType(test.type)) + return; + manager.started(token); + + is(a1.getAttribute("preload"), "auto", "preload:auto automatically set"); + is(a1.src, "", "Src set?"); + a1 = null; + manager.finished(token); +} + +manager.runTests(gAudioTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_audio2.html b/dom/media/test/test_audio2.html new file mode 100644 index 0000000000..fde9adc791 --- /dev/null +++ b/dom/media/test/test_audio2.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: Audio Constructor Test 2</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var tmpAudio = new Audio(); + +var manager = new MediaTestManager; + +function startTest(test, token) { + if (!tmpAudio.canPlayType(test.type)) + return; + manager.started(token); + var a1 = new Audio(test.name); + is(a1.getAttribute("preload"), "auto", "Preload automatically set to auto"); + ok(a1.src.endsWith("/" + test.name), "src OK"); + manager.finished(token); +} + +manager.runTests(gAudioTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_audioDocumentTitle.html b/dom/media/test/test_audioDocumentTitle.html new file mode 100644 index 0000000000..2913debb39 --- /dev/null +++ b/dom/media/test/test_audioDocumentTitle.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=463830 +--> +<head> + <title>Test for Bug 463830</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=463830">Mozilla Bug 463830</a> +<p id="display"></p> +<iframe id="i"></iframe> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 463830 **/ + +var gTests = [ + { file: "r11025_s16_c1.wav", title: "r11025_s16_c1.wav" } +]; + +var gTestNum = 0; + +addLoadEvent(runTest); + +var title; +var i = document.getElementById("i"); + +function runTest() { + if (gTestNum == gTests.length) { + SimpleTest.finish(); + return; + } + if (gTestNum == 0) { + i.addEventListener("load", function() { + is(i.contentDocument.title, title, "Doc title incorrect"); + setTimeout(runTest, 0); + }); + } + + title = gTests[gTestNum].title; + i.src = gTests[gTestNum].file; + gTestNum++; +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_background_video_cancel_suspend_taint.html b/dom/media/test/test_background_video_cancel_suspend_taint.html new file mode 100644 index 0000000000..fc48be524b --- /dev/null +++ b/dom/media/test/test_background_video_cancel_suspend_taint.html @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Suspend Cancels (Element Taint)</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript"> +"use strict"; + +var manager = new MediaTestManager; + +/** + * @param {HTMLMediaElement} video Video element under test. + * @returns {Promise} Promise that is resolved when video decode resumes. + */ +function testSuspendTimerCanceledWhenTainted(video) { + function ended() { + video.removeEventListener("mozcancelvideosuspendtimer", canceled); + ok(false, `${video.token} ended before suspend cancels`); + this.ended_resolve(); + } + + function canceled() { + video.removeEventListener("ended", ended); + ok(true, `${video.token} suspend cancels`); + this.canceled_resolve(); + } + + let p = Promise.race([ + new Promise((resolve) => { + video.ended_resolve = resolve; + video.addEventListener('ended', ended, { 'once': true }); + }), + new Promise((resolve) => { + video.canceled_resolve = resolve; + video.addEventListener('mozcancelvideosuspendtimer', canceled, { 'once': true }); + }) + ]); + + Log(video.token, "Mark tainted"); + + let c = document.createElement('canvas'); + let g = c.getContext('2d'); + g.drawImage(video, 0, 0, c.width, c.height); + ok(video.hasSuspendTaint(), 'video used with drawImage is tainted.'); + + return p; +} + +startTest({ + desc: 'Test Background Video Suspend Cancels (Element Taint)', + prefs: [ + [ "media.test.video-suspend", true ], + [ "media.suspend-background-video.enabled", true ], + [ "media.suspend-background-video.delay-ms", 10000 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + waitUntilVisible(v) + .then(() => waitUntilPlaying(v)) + .then(() => testSuspendTimerStartedWhenHidden(v)) + .then(() => testSuspendTimerCanceledWhenTainted(v)) + .then(() => { manager.finished(token); }); + } +}); +</script> diff --git a/dom/media/test/test_background_video_cancel_suspend_visible.html b/dom/media/test/test_background_video_cancel_suspend_visible.html new file mode 100644 index 0000000000..73aaa4783e --- /dev/null +++ b/dom/media/test/test_background_video_cancel_suspend_visible.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Suspend Cancels (Visibility)</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript"> +"use strict"; + +var manager = new MediaTestManager; + +/** + * Check that making the element visible before suspend timer delay causes the + * the suspend timer to be canceled. + * @param {HTMLMediaElement} video Video element under test. + * @returns {Promise} Promise that is resolved when video decode resumes. + */ +function testSuspendTimerCanceledWhenShown(video) { + function ended() { + video.removeEventListener("mozcancelvideosuspendtimer", canceled); + ok(false, `${video.token} ended before suspend cancels`); + this.ended_resolve(); + } + + function canceled() { + video.removeEventListener("ended", ended); + ok(true, `${video.token} suspend cancels`); + this.canceled_resolve(); + } + + let p = Promise.race([ + new Promise((resolve) => { + video.ended_resolve = resolve; + video.addEventListener('ended', ended, { 'once': true }); + }), + new Promise((resolve) => { + video.canceled_resolve = resolve; + video.addEventListener('mozcancelvideosuspendtimer', canceled, { 'once': true }); + }) + ]); + + Log(video.token, "Set visible"); + video.setVisible(true); + + return p; +} + +startTest({ + desc: 'Test Background Video Suspend Cancels (Visibility)', + prefs: [ + [ "media.test.video-suspend", true ], + [ "media.suspend-background-video.enabled", true ], + [ "media.suspend-background-video.delay-ms", 10000 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + waitUntilPlaying(v) + .then(() => testSuspendTimerStartedWhenHidden(v)) + .then(() => testSuspendTimerCanceledWhenShown(v)) + .then(() => { + ok(true, `${v.token} finished`); + manager.finished(token); + }); + } +}); diff --git a/dom/media/test/test_background_video_drawimage_with_suspended_video.html b/dom/media/test/test_background_video_drawimage_with_suspended_video.html new file mode 100644 index 0000000000..1b1b4264f2 --- /dev/null +++ b/dom/media/test/test_background_video_drawimage_with_suspended_video.html @@ -0,0 +1,76 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Displays Video Frame via drawImage When Suspended</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<style> +video, canvas { + border: 1px solid black; +} +</style> +<script type="text/javascript"> +"use strict"; + +var manager = new MediaTestManager; + +function drawVideoToCanvas(v) { + console.log('drawVideoToCanvas'); + let c = document.createElement('canvas'); + c.width = 4; + c.height = 4; + c.style.width = 64; + c.style.height = 64; + document.body.appendChild(c); + + let gfx = c.getContext('2d'); + if (!gfx) { + throw Error("Unable to obtain context '2d' from canvas"); + } + + gfx.drawImage(v, 0, 0, 4, 4); + let imageData = gfx.getImageData(0, 0, 4, 4); + let pixels = imageData.data; + + // Check that pixels aren't all the same colour. + // Implements by checking against rgb of the first pixel. + let rr = pixels[0], + gg = pixels[1], + bb = pixels[2], + allSame = true; + + for (let i = 0; i < 4*4; i++) { + let r = pixels[4*i+0]; + let g = pixels[4*i+1]; + let b = pixels[4*i+2]; + if (r != rr || g != gg || b != bb) { + allSame = false; + break; + } + } + + ok(!allSame, "Pixels aren't all the same color"); +} + +startTest({ + desc: 'Test Background Video Displays Video Frame via drawImage When Suspended', + prefs: [ + [ "media.test.video-suspend", true ], + [ "media.suspend-background-video.enabled", true ], + [ "media.suspend-background-video.delay-ms", 500 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + waitUntilPlaying(v) + .then(() => testVideoSuspendsWhenHidden(v)) + .then(() => { + drawVideoToCanvas(v); + manager.finished(token); + }); + } +}); +</script> diff --git a/dom/media/test/test_background_video_ended_event.html b/dom/media/test/test_background_video_ended_event.html new file mode 100644 index 0000000000..7ef8ec81f6 --- /dev/null +++ b/dom/media/test/test_background_video_ended_event.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Suspends</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript"> +"use strict"; + +var manager = new MediaTestManager; + +startTest({ + desc: "Test background video doesn't fire the 'ended' event twice.", + prefs: [ + [ "media.test.video-suspend", true ], + [ "media.suspend-background-video.enabled", true ], + [ "media.suspend-background-video.delay-ms", 100 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + let count = 0; + v.addEventListener("ended", function() { + is(++count, 1, `${token} should get only one 'ended' event.`); + }); + + /* + * This test checks that, after a video element had finished its playback, + * resuming video decoder doesn't dispatch 2nd ended event. + * This issue was found in bug 1349097. + */ + waitUntilPlaying(v) + .then(() => testVideoSuspendsWhenHidden(v)) + .then(() => waitUntilEnded(v)) + .then(() => testVideoResumesWhenShown(v)) + .then(() => { + // Wait for a while and finish the test. We should get only one 'ended' event. + setTimeout(function() { + removeNodeAndSource(v); + manager.finished(token); + }, 3000); + }); + } +}); +</script> diff --git a/dom/media/test/test_background_video_no_suspend_disabled.html b/dom/media/test/test_background_video_no_suspend_disabled.html new file mode 100644 index 0000000000..0d6ede5c7e --- /dev/null +++ b/dom/media/test/test_background_video_no_suspend_disabled.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Doesn't Suspend When Feature Disabled</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script> +"use strict"; + +var manager = new MediaTestManager; + +startTest({ + desc: "Test Background Video Doesn't Suspend When Feature Disabled.", + prefs: [ + [ 'media.test.video-suspend', true ], + [ 'media.suspend-background-video.enabled', false ], + [ 'media.suspend-background-video.delay-ms', 0 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + /* This test checks that suspend doesn't occur when the feature is disabled */ + waitUntilPlaying(v) + .then(() => checkVideoDoesntSuspend(v)) + .then(() => { + ok(true, 'Video ended before decode was suspended'); + manager.finished(token); }) + .catch((e) => { + ok(false, 'Test Failed: ' + e.toString()); + manager.finished(token); }); + } +}); +</script>
\ No newline at end of file diff --git a/dom/media/test/test_background_video_no_suspend_not_in_tree.html b/dom/media/test/test_background_video_no_suspend_not_in_tree.html new file mode 100644 index 0000000000..327fda4403 --- /dev/null +++ b/dom/media/test/test_background_video_no_suspend_not_in_tree.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Doesn't Suspend When Timeout Is Longer Than Video</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script> +"use strict"; + +var manager = new MediaTestManager; + +var MIN_DELAY = 100; + +/** + * @param {string} url video src. + * @returns {HTMLMediaElement} The created video element. + */ +function createVideoNotAppendToDoc(url, token, width, height) { + // Default size of (160, 120) is used by other media tests. + if (width === undefined) { width = 160; } + if (height === undefined) { height = 3*width/4; } + + let v = document.createElement('video'); + v.token = token; + v.width = width; + v.height = height; + v.src = url; + return v; +} + +startTest({ + desc: "Test Background Video Doesn't Suspend When If The Video Is Not In Tree.", + prefs: [ + [ 'media.test.video-suspend', true ], + [ 'media.suspend-background-video.enabled', true ], + [ 'media.suspend-background-video.delay-ms', MIN_DELAY ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + let v = createVideoNotAppendToDoc(test.name, token); + manager.started(token); + + /* This test checks that suspend doesn't occur if a video element is not + append to tree. */ + waitUntilPlaying(v) + .then(() => checkVideoDoesntSuspend(v)) + .then(() => { + ok(true, 'Video ended before decode was suspended'); + manager.finished(token); }) + .catch((e) => { + ok(false, 'Test Failed: ' + e.toString()); + manager.finished(token); }); + } +}); +</script>
\ No newline at end of file diff --git a/dom/media/test/test_background_video_no_suspend_short_vid.html b/dom/media/test/test_background_video_no_suspend_short_vid.html new file mode 100644 index 0000000000..d1716755fc --- /dev/null +++ b/dom/media/test/test_background_video_no_suspend_short_vid.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Doesn't Suspend When Timeout Is Longer Than Video</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script> +"use strict"; + +var manager = new MediaTestManager; + +startTest({ + desc: "Test Background Video Doesn't Suspend When Timeout Is Longer Than Video.", + prefs: [ + [ 'media.test.video-suspend', true ], + [ 'media.suspend-background-video.enabled', true ], + // Gizmo.mp4 is about 5.6s + [ 'media.suspend-background-video.delay-ms', 10000 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + /* This test checks that suspend doesn't occur when the delay is longer + than the duration of the video that's playing */ + waitUntilPlaying(v) + .then(() => checkVideoDoesntSuspend(v)) + .then(() => { + ok(true, 'Video ended before decode was suspended'); + manager.finished(token); }) + .catch((e) => { + ok(false, 'Test Failed: ' + e.toString()); + manager.finished(token); }); + } +}); +</script>
\ No newline at end of file diff --git a/dom/media/test/test_background_video_resume_after_end_show_last_frame.html b/dom/media/test/test_background_video_resume_after_end_show_last_frame.html new file mode 100644 index 0000000000..68f7179e12 --- /dev/null +++ b/dom/media/test/test_background_video_resume_after_end_show_last_frame.html @@ -0,0 +1,141 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Suspends</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript"> +"use strict"; + +var manager = new MediaTestManager; + +function testSameContent(video1, video2) { + if (video1.videoWidth != video2.videoWidth || + video1.videoHeight != video2.videoHeight) { + ok(false, `${video1.token} video1 and video2 have different dimensions.`); + return; + } + + let w = video1.videoWidth; + let h = video1.videoHeight; + let c1 = document.createElement('canvas'); + let c2 = document.createElement('canvas'); + c1.width = w; + c1.height = h; + c2.width = w; + c2.height = h; + + let gfx1 = c1.getContext('2d'); + let gfx2 = c2.getContext('2d'); + if (!gfx1 || !gfx2) { + ok(false, "Unable to obtain context '2d' from canvas"); + return; + } + + gfx1.drawImage(video1, 0, 0, w, h); + gfx2.drawImage(video2, 0, 0, w, h); + + // Get content out. + let contentWidth = 4; + let contentHeight = 4; + let imageData1 = gfx1.getImageData(0, 0, contentWidth, contentHeight); + let imageData2 = gfx2.getImageData(0, 0, contentWidth, contentHeight); + let pixels1 = imageData1.data; + let pixels2 = imageData2.data; + + // Check that the content of two video are identical. + for (let i = 0; i < contentWidth*contentHeight; i++) { + let pixelCount = 4 * i; + if (pixels1[pixelCount+0] != pixels2[pixelCount+0] || + pixels1[pixelCount+1] != pixels2[pixelCount+1] || + pixels1[pixelCount+2] != pixels2[pixelCount+2] || + pixels1[pixelCount+3] != pixels2[pixelCount+3]) { + ok(false, `${video1.token} video1 and video2 have different content.`); + return; + } + } + + ok(true, `${video1.token} video1 and video2 have identical content.`); +} + +function waitUntilSeekToLastFrame(video) { + Log(video.token, "Waiting for seeking to the last frame"); + function callSeekToNextFrame() { + video.seekToNextFrame().then( + () => { + if (!video.seenEnded) { + callSeekToNextFrame(); + } + }, + () => { + // When seek reaches the end, the promise is resolved before 'ended' + // is fired. The resolver calls callSeekToNextFrame() to schedule + // another seek and then the 'ended' handler calls finish() to shut + // down the MediaDecoder which will reject the seek promise. So we don't + // raise an error in this case. + ok(video.seenEnded, "seekToNextFrame() failed."); + } + ); + } + + return new Promise(function(resolve, reject) { + video.seenEnded = false; + video.addEventListener("ended", () => { + video.seenEnded = true; + resolve(); + }, true); + callSeekToNextFrame(video); + }); +} + +startTest({ + desc: "Test resume an ended video shows the last frame.", + prefs: [ + [ "media.test.video-suspend", true ], + [ "media.suspend-background-video.enabled", true ], + [ "media.suspend-background-video.delay-ms", 100 ], + [ "media.dormant-on-pause-timeout-ms", -1], + [ "media.decoder.skip-to-next-key-frame.enabled", false] + ], + tests: gDecodeSuspendTests, + + runTest: async (test, token) => { + let v = appendVideoToDocWithoutLoad(token); + let vMuted = appendVideoToDocWithoutLoad(token+"-muted"); + vMuted.muted = true; + let vReference = appendVideoToDocWithoutLoad(token+"-ref"); + manager.started(token); + + /* + * This test checks that, after a video element had finished its playback, + * resuming video decoder should seek to the last frame. + * This issue was found in bug 1358057. + */ + await waitUntilVisible(v); + await Promise.all([ + loadAndWaitUntilLoadedmetadata(v, test.name), + loadAndWaitUntilLoadedmetadata(vMuted, test.name), + loadAndWaitUntilLoadedmetadata(vReference, test.name, "auto"), + ]); + + await waitUntilPlaying(v); + await waitUntilPlaying(vMuted); + await testVideoSuspendsWhenHidden(v); + await testVideoSuspendsWhenHidden(vMuted); + await Promise.all([ + waitUntilEnded(v), + waitUntilEnded(vMuted), + waitUntilSeekToLastFrame(vReference), + ]); + await testVideoOnlySeekCompletedWhenShown(v); + await testVideoOnlySeekCompletedWhenShown(vMuted); + testSameContent(v, vReference); + testSameContent(vMuted, vReference); + removeNodeAndSource(v); + removeNodeAndSource(vMuted); + removeNodeAndSource(vReference); + manager.finished(token); + } +}); +</script> diff --git a/dom/media/test/test_background_video_resume_looping_video_without_audio.html b/dom/media/test/test_background_video_resume_looping_video_without_audio.html new file mode 100644 index 0000000000..3ec64c6d79 --- /dev/null +++ b/dom/media/test/test_background_video_resume_looping_video_without_audio.html @@ -0,0 +1,81 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Resume suspended looping video which doesn't contain audio track</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <script src="background_video.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script class="testbody" type="text/javascript"> +/** + * This test is used to ensure that the looping video (without audio track) which + * has been suspended can continute to playback correctly after we resume video + * decoding. + */ +async function startTest() { + const video = await createVisibleVideo(); + await startVideo(video); + await suspendVideoDecoding(video); + await resumeVideoDecoding(video); + await checkIfVideoIsStillPlaying(video); + endTestAndClearVideo(video); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({ 'set': [ + ["media.test.video-suspend", true], + ["media.suspend-background-video.enabled", true], + ["media.suspend-background-video.delay-ms", 0], + ]}, () => { + startTest(); +}); + +/** + * The following are test helper functions. + */ +async function createVisibleVideo() { + let video = document.createElement("video"); + video.src = "gizmo-noaudio.webm"; + video.controls = true; + video.loop = true; + document.body.appendChild(video); + info(`ensure video becomes visible`); + await waitUntilVisible(video); + return video; +} + +async function startVideo(video) { + info(`start playing video`); + const played = video && await video.play().then(() => true, () => false); + ok(played, "video has started playing"); +} + +async function suspendVideoDecoding(video) { + info(`suspend video decoding`); + video.setVisible(false); + await nextVideoSuspends(video); + info(`suspended video decoding`); +} + +async function resumeVideoDecoding(video) { + info(`resume video decoding.`); + video.setVisible(true); + await nextVideoResumes(video); + info(`resumed video decoding`); +} + +async function checkIfVideoIsStillPlaying(video) { + await once(video, "timeupdate"); + ok(!video.paused, "video is still playing after resuming video decoding.") +} + +function endTestAndClearVideo(video) { + removeNodeAndSource(video); + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/dom/media/test/test_background_video_suspend.html b/dom/media/test/test_background_video_suspend.html new file mode 100644 index 0000000000..f68740954b --- /dev/null +++ b/dom/media/test/test_background_video_suspend.html @@ -0,0 +1,81 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Suspends</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css" /> +<script type="text/javascript"> + "use strict"; + + var manager = new MediaTestManager; + + var MIN_DELAY = 100; + + function testDelay(v, start, min) { + let end = performance.now(); + let delay = end - start; + ok(delay > min, `${v.token} suspended with a delay of ${delay} ms`); + } + + async function runTest(test, token) { + let video = appendVideoToDocWithoutLoad(token); + manager.started(token); + + let visible = waitUntilVisible(video); + let ended = nextVideoEnded(video); + let playing = nextVideoPlaying(video); + let resumes = nextVideoResumes(video); + let suspends = nextVideoSuspends(video); + + Log(token, "Waiting until video becomes visible"); + await visible; + + Log(token, "Waiting for metadata loaded"); + await loadAndWaitUntilLoadedmetadata(video, test.name); + + Log(token, "Start playing"); + video.play(); + + Log(token, "Waiting for video playing"); + await playing; + + let start = performance.now(); + + Log(token, "Set hidden"); + video.setVisible(false); + + Log(token, "Waiting for video suspend"); + await suspends; + + testDelay(video, start, MIN_DELAY); + + Log(token, "Set visible"); + video.setVisible(true); + + Log(token, "Waiting for video resume"); + await resumes; + + Log(token, "Waiting for ended"); + await ended; + + ok(video.currentTime >= video.duration, 'current time approximates duration.'); + + removeNodeAndSource(video); + manager.finished(token); + } + + startTest({ + desc: 'Test Background Video Suspends', + prefs: [ + ["media.test.video-suspend", true], + ["media.suspend-background-video.enabled", true], + // Use a short delay to ensure video decode suspend happens before end + // of video. + ["media.suspend-background-video.delay-ms", MIN_DELAY], + ["privacy.reduceTimerPrecision", false] + ], + tests: gDecodeSuspendTests, + runTest + }); +</script>
\ No newline at end of file diff --git a/dom/media/test/test_background_video_suspend_ends.html b/dom/media/test/test_background_video_suspend_ends.html new file mode 100644 index 0000000000..fea46afffe --- /dev/null +++ b/dom/media/test/test_background_video_suspend_ends.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Suspended Video Fires 'ended' Event</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css" /> +<script type="text/javascript"> + "use strict"; + + PARALLEL_TESTS = 1; + + var manager = new MediaTestManager; + + async function runTest(test, token) { + let video = appendVideoToDoc(test.name, token); + manager.started(token); + + // This test checks that 'ended' event is received for videos with + // suspended video decoding. This is important for looping video logic + // handling in HTMLMediaElement. + + let ended = nextVideoEnded(video); + let suspends = nextVideoSuspends(video); + + Log(token, "Start playing"); + video.play(); + + Log(token, "Set hidden"); + video.setVisible(false); + + Log(token, "Waiting for video suspend"); + await suspends; + + Log(token, "Waiting for ended"); + await ended; + + ok(video.currentTime >= video.duration, 'current time approximates duration.'); + + manager.finished(token); + } + + startTest({ + desc: "Test Background Suspended Video Fires 'ended' Event", + prefs: [ + ["media.test.video-suspend", true], + ["media.suspend-background-video.enabled", true], + // User a short delay to ensure video decode suspend happens before end + // of video. + ["media.suspend-background-video.delay-ms", 1000] + ], + tests: gDecodeSuspendTests, + runTest + }); +</script>
\ No newline at end of file diff --git a/dom/media/test/test_background_video_suspend_ready_state.html b/dom/media/test/test_background_video_suspend_ready_state.html new file mode 100644 index 0000000000..e33d257e09 --- /dev/null +++ b/dom/media/test/test_background_video_suspend_ready_state.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Check element's ready state while suspending video decoding</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +/** + * This test is used to ensure that the media element's ready state won't be + * incorrectly changed to `HAVE_METADATA` or lower when seeking happens on a + * null decoder that is caused by suspending video decoding. + */ +add_task(async function setupTestingPref() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.test.video-suspend", true], + ["media.suspend-background-video.enabled", true], + ["media.suspend-background-video.delay-ms", 0], + ], + }); +}); + +add_task(async function testReadyStateWhenSuspendingVideoDecoding() { + const video = await createPlayingVideo(); + assertVideoReadyStateIsSufficientForPlaying(video); + await suspendVideoDecoding(video); + await seekVideo(video); + assertVideoReadyStateIsSufficientForPlaying(video); +}); + +async function createPlayingVideo() { + let video = document.createElement("video"); + video.src = "gizmo.mp4"; + video.controls = true; + video.loop = true; + document.body.appendChild(video); + ok(await video.play().then(_=>true, _=>false), "video started playing"); + return video; +} + +function assertVideoReadyStateIsSufficientForPlaying(video) { + ok(video.readyState > HTMLMediaElement.HAVE_METADATA, + `Ready state ${video.readyState} is suffient for playing`); +} + +async function suspendVideoDecoding(video) { + video.setVisible(false); + nextVideoSuspends(video); + info(`suspended video decoding`); + // Because the suspend event we received can only indicate MDSM finishes the + // setup of suspending decoding, but the actual setting the null decoder + // happens on MediaFormatReader where we are not able to observe the behavior + // via event. Instread of implementing something in MFR to propagate the event + // or changing the timing of current suspend event, which might increase the + // maintenance effect, Here choose to use a simple workaround to wait for a + // short while to ensure the decoding has been switched to the null decoder. + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + await new Promise(resolve => setTimeout(resolve, 2000)); +} + +async function seekVideo(video) { + video.currentTime = 0; + ok(await new Promise(r => video.onseeked = r).then(_=>true, _=>false), + `seeking completed`); +} + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/test_background_video_tainted_by_capturestream.html b/dom/media/test/test_background_video_tainted_by_capturestream.html new file mode 100644 index 0000000000..4ceba7fff9 --- /dev/null +++ b/dom/media/test/test_background_video_tainted_by_capturestream.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Is Tainted By captureStream</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript"> +"use strict"; + +var manager = new MediaTestManager; + +function captureVideoAsStream(v) { + v.mozCaptureStream(); +} + +startTest({ + desc: 'Test Background Video Is Tainted By captureStream', + prefs: [ + [ "media.test.video-suspend", true ], + [ "media.suspend-background-video.enabled", true ], + [ "media.suspend-background-video.delay-ms", 1000 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + ok(true, `${test.name}`); + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + waitUntilPlaying(v) + .then(() => { + captureVideoAsStream(v); + ok(v.hasSuspendTaint(), "Video is tainted after captured"); + return checkVideoDoesntSuspend(v); + }) + .then(() => { + ok(true, 'Video ended before decode was suspended'); + manager.finished(token); + }) + .catch((e) => { + ok(false, 'Test failed: ' + e.toString()); + manager.finished(token); + }); + } +}); +</script> diff --git a/dom/media/test/test_background_video_tainted_by_createimagebitmap.html b/dom/media/test/test_background_video_tainted_by_createimagebitmap.html new file mode 100644 index 0000000000..42bdd8e246 --- /dev/null +++ b/dom/media/test/test_background_video_tainted_by_createimagebitmap.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Is Tainted By createImageBitmap</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript"> +"use strict"; + +var manager = new MediaTestManager; + +startTest({ + desc: 'Test Background Video Is Tainted By createImageBitmap', + prefs: [ + [ "media.test.video-suspend", true ], + [ "media.suspend-background-video.enabled", true ], + [ "media.suspend-background-video.delay-ms", 1000 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + ok(true, `${test.name}`); + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + waitUntilPlaying(v) + .then(() => createImageBitmap(v)) + .then(() => { + ok(v.hasSuspendTaint(), "Video is tainted after drawing to canvas"); + return checkVideoDoesntSuspend(v); + }) + .then(() => { + ok(true, 'Video ended before decode was suspended'); + manager.finished(token); + }) + .catch((e) => { + ok(false, 'Test failed: ' + e.toString()); + manager.finished(token); + }); + } +}); +</script>
\ No newline at end of file diff --git a/dom/media/test/test_background_video_tainted_by_drawimage.html b/dom/media/test/test_background_video_tainted_by_drawimage.html new file mode 100644 index 0000000000..d41cf53631 --- /dev/null +++ b/dom/media/test/test_background_video_tainted_by_drawimage.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Background Video Is Tainted By drawImage</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="manifest.js"></script> +<script src="background_video.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript"> +"use strict"; + +var manager = new MediaTestManager; + +function drawVideoToCanvas(v) { + let w = v.width, + h = v.height, + c = document.createElement('canvas'); + c.width = w; + c.height = h; + document.body.appendChild(c); + + let gfx = c.getContext('2d'); + if (!gfx) { + throw Error("Unable to obtain context '2d' from canvas"); + } + + gfx.drawImage(v, 0, 0, w, h); +} + +startTest({ + desc: 'Test Background Video Is Tainted By drawImage', + prefs: [ + [ "media.test.video-suspend", true ], + [ "media.suspend-background-video.enabled", true ], + [ "media.suspend-background-video.delay-ms", 1000 ] + ], + tests: gDecodeSuspendTests, + runTest: (test, token) => { + ok(true, `${test.name}`); + let v = appendVideoToDoc(test.name, token); + manager.started(token); + + waitUntilPlaying(v) + .then(() => { + drawVideoToCanvas(v); + ok(v.hasSuspendTaint(), "Video is tainted after drawing to canvas"); + return checkVideoDoesntSuspend(v); + }) + .then(() => { + ok(true, 'Video ended before decode was suspended'); + manager.finished(token); + }) + .catch((e) => { + ok(false, 'Test failed: ' + e.toString()); + manager.finished(token); + }); + } +}); +</script>
\ No newline at end of file diff --git a/dom/media/test/test_buffered.html b/dom/media/test/test_buffered.html new file mode 100644 index 0000000000..86d8eec28a --- /dev/null +++ b/dom/media/test/test_buffered.html @@ -0,0 +1,117 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=462957 +--> +<head> + <title>Test for Bug 462957</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462957">Mozilla Bug 462957</a> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +// Test for Bug 462957; HTMLMediaElement.buffered. + +var manager = new MediaTestManager; + +function testBuffered(e) { + var v = e.target; + + // The whole media should be buffered... + var b = v.buffered; + is(b.length, 1, v._name + ": Should be buffered in one range"); + is(b.start(0), 0, v._name + ": First range start should be media start"); + ok(Math.abs(b.end(0) - v.duration) < 0.1, v._name + ": First range end should be media end"); + + // Ensure INDEX_SIZE_ERR is thrown when we access outside the range + var caught = false; + try { + b.start(-1); + } catch (ex) { + caught = ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR; + } + is(caught, true, v._name + ": Should throw INDEX_SIZE_ERR on under start bounds range"); + + caught = false; + try { + b.end(-1); + } catch (ex) { + caught = ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR; + } + is(caught, true, v._name + ": Should throw INDEX_SIZE_ERR on under end bounds range"); + + caught = false; + try { + b.start(b.length); + } catch (ex) { + caught = ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR; + } + is(caught, true, v._name + ": Should throw INDEX_SIZE_ERR on over start bounds range"); + + caught = false; + try { + b.end(b.length); + } catch (ex) { + caught = ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR; + } + is(caught, true, v._name + ": Should throw INDEX_SIZE_ERR on over end bounds range"); + + removeNodeAndSource(v); + manager.finished(v._token); +} + +function fetch(url, fetched_callback) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); + xhr.responseType = "blob"; + + var loaded = function (event) { + if (xhr.status == 200 || xhr.status == 206) { + ok(true, `${url}: Fetch succeeded, status=${xhr.status}`); + // Request fulfilled. Note sometimes we get 206... Presumably because either + // httpd.js or Necko cached the result. + fetched_callback(window.URL.createObjectURL(xhr.response)); + } else { + ok(false, `${url}: Fetch failed, headers=${xhr.getAllResponseHeaders()}`); + } + }; + + xhr.addEventListener("load", loaded); + xhr.send(); +} + +function startTest(test, token) { + // Fetch the media resource using XHR so we can be sure the entire + // resource is loaded before we test buffered ranges. This ensures + // we have deterministic behaviour. + var onfetched = function(uri) { + var v = document.createElement('video'); + v._token = token; + v.src = uri; + v._name = test.name; + v._test = test; + v.addEventListener("loadeddata", testBuffered, {once: true}); + document.body.appendChild(v); + }; + + manager.started(token); + fetch(test.name, onfetched); +} + +// Note: No need to set media test prefs, since we're using XHR to fetch +// media data. +manager.runTests(gSeekTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug1113600.html b/dom/media/test/test_bug1113600.html new file mode 100644 index 0000000000..37a9cb0adb --- /dev/null +++ b/dom/media/test/test_bug1113600.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that a video element captured to a stream mid-playback can be played to the end</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +PARALLEL_TESTS = 1; +SimpleTest.requestCompleteLog(); +var manager = new MediaTestManager; + +function startTest(test, token) { + var v = document.createElement('video'); + v.style = "background-color:#aca;"; + v.width = 160; + v.height = 120; + + manager.started(token); + + v.src = test.name; + + v.ontimeupdate = function() { + if (v.currentTime < test.duration / 4) { + // Allow some time to pass before starting the capture. + return; + } + v.ontimeupdate = null; + v.mozCaptureStreamUntilEnded(); + info(test.name + " capture started at " + v.currentTime + ". Duration=" + test.duration); + }; + + v.onended = function() { + ok(true, test.name + " ended"); + removeNodeAndSource(v); + manager.finished(token); + }; + + document.body.appendChild(v); + v.play(); +} + +manager.runTests(gSmallTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug1120222.html b/dom/media/test/test_bug1120222.html new file mode 100644 index 0000000000..69027bc2e3 --- /dev/null +++ b/dom/media/test/test_bug1120222.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1120222 +--> +<head> + <title>Test for Bug 1120222</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +let count = 0; + +function startTest(test, token) { + manager.started(token); + var elemType = /^audio/.test(test.type) ? "audio" : "video"; + var v = document.createElement(elemType); + v.token = token; + v.src = test.name; + + v.addEventListener("play", (e) => { + document.title = `Test Title ${count++}`; + ok(true, "changed title while media was playing") + removeNodeAndSource(e.target); + manager.finished(e.target.token); + }); + + document.body.appendChild(v); + v.play(); +} + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug1242338.html b/dom/media/test/test_bug1242338.html new file mode 100644 index 0000000000..7b72153a6e --- /dev/null +++ b/dom/media/test/test_bug1242338.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Bug 1242338</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var video = document.createElement('video'); + video.preload = "metadata"; + video.token = token; + + var handler = { + "ontimeout": function() { + Log(token, "timed out"); + } + }; + manager.started(token, handler); + + video.src = test.name; + video.name = test.name; + + function finish() { + video.finished = true; + video.removeEventListener("loadedmetadata", onLoadedmetadata); + video.removeEventListener("ended", onEnded); + removeNodeAndSource(video); + manager.finished(video.token); + } + + function onLoadedmetadata() { + // seek to the media's duration + var duration = video.duration; + console.log("onloadedmetadata(), duration = " + duration); + video.currentTime = duration; + } + + function onEnded() { + ok(video.ended, test.name + " checking playback has ended"); + ok(!video.finished, test.name + " shouldn't be finished"); + ok(!video.seenEnded, test.name + " shouldn't be ended"); + video.seenEnded = true; + + ok(true, "Seeking to the duration triggers ended event"); + finish(); + } + + video.addEventListener("loadedmetadata", onLoadedmetadata); + video.addEventListener("ended", onEnded); + + document.body.appendChild(video); +} + +manager.runTests(gSeekTests, startTest); + +</script> +</pre> +</body> +</html>
\ No newline at end of file diff --git a/dom/media/test/test_bug1248229.html b/dom/media/test/test_bug1248229.html new file mode 100644 index 0000000000..3165795622 --- /dev/null +++ b/dom/media/test/test_bug1248229.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test garbage collection of captured stream (bug 1248229)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body onload="doTest()"> +<video id="v" src="black100x100-aspect3to2.ogv"></video> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +function doTest() { + /* global v */ + window.oak = v.mozCaptureStreamUntilEnded(); + v.mozCaptureStreamUntilEnded(); + v.play(); + + v.onended = function() { + info("Got ended."); + v.onended = null; + SpecialPowers.exactGC(function() { + info("GC completed."); + v.play(); + SimpleTest.finish(); + }); + } +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug1431810_opus_downmix_to_mono.html b/dom/media/test/test_bug1431810_opus_downmix_to_mono.html new file mode 100644 index 0000000000..647ddf0489 --- /dev/null +++ b/dom/media/test/test_bug1431810_opus_downmix_to_mono.html @@ -0,0 +1,139 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: disable phase inversion in opus decoder</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<audio preload=none id="a" controls></audio> +<audio preload=none id="b" controls></audio> +<script class="testbody" type="text/javascript"> +/* + This test makes use of an (stereo) opus file with phase inversion of 180 degrees (right = -left => right + left = 0). + Firstly, the phase inversion is verified on a normal stereo playback. + Secondly, mono playback is forced which results in the phase inversion being disabled (Bug 1431810). +*/ +SimpleTest.waitForExplicitFinish(); + +/* global a, b */ + +function areChannelsInverted(b1, b2) { + for (var i = 0; i < b1.length; i++) { + if (Math.abs(b1[i] + b2[i]) > 9e-2) { + return false; + } + } + return true; +} + +function areChannelsEqual(b1, b2) { + for (var i = 0; i < b1.length; i++) { + if (Math.abs(b1[i] - b2[i]) > 9e-3) { + return false; + } + } + return true; +} + +function isSilent(b) { + for (var i = 0; i < b.length; i++) { + if (b[i] != 0.0) { + return false; + } + } + return true; +} + +function mediaElementWithPhaseInversion(audioContext, mediaElement, success) { + let audio_source = audioContext.createMediaElementSource(mediaElement); + let script_processor = audioContext.createScriptProcessor(); + audio_source.connect(script_processor); + + mediaElement.onplay = () => { + script_processor.onaudioprocess = (e) => { + let right = e.inputBuffer.getChannelData(0); + let left = e.inputBuffer.getChannelData(1); + + // This is leading or trailing silence + // produced by ScriptProcessor. + if (isSilent(right) && isSilent(left)) { + return; + } + + ok(areChannelsInverted(right, left), "Channels must be inverted"); + } + } + + mediaElement.onended = () => { + ok(true, "End of file."); + mediaElement.onended = null; + script_processor.onaudioprocess = null; + success(); + } + + mediaElement.src = "test-stereo-phase-inversion-180.opus"; + // Normal playback channels will by inverted + mediaElement.play(); +} + +function mediaElementWithPhaseInversionDisabled(audioContext, mediaElement, success) { + let audio_source = audioContext.createMediaElementSource(mediaElement); + let script_processor = audioContext.createScriptProcessor(); + audio_source.connect(script_processor); + + mediaElement.onplay = () => { + script_processor.onaudioprocess = (e) => { + let right = e.inputBuffer.getChannelData(0); + let left = e.inputBuffer.getChannelData(1); + + // This is leading or trailing silence + // produced by ScriptProcessor. + if (isSilent(right) && isSilent(left)) { + return; + } + + ok(!areChannelsInverted(right, left), "Channels must not be inverted"); + ok(areChannelsEqual(right, left), "Channels must be equal"); + } + } + + mediaElement.onended = () => { + ok(true, "End of file."); + mediaElement.onended = null; + script_processor.onaudioprocess = null; + success(); + } + + mediaElement.src = "test-stereo-phase-inversion-180.opus"; + + // Downmix to mono will force to disable opus phase inversion + SpecialPowers.pushPrefEnv({"set": [["accessibility.monoaudio.enable", true]]}) + .then(() => { + mediaElement.play(); + }); +} + +let ac = new AudioContext(); + +function testPhaseInversion(mediaElement) { + return new Promise((accept, reject) => { + mediaElementWithPhaseInversion(ac, a, accept); + }); +} + +function testPhaseInversionDisabled(mediaElement) { + return new Promise((accept, reject) => { + mediaElementWithPhaseInversionDisabled(ac, b, accept); + }); +} + +// Start testing +testPhaseInversion(a) +.then( () => testPhaseInversionDisabled(b) ) +.then( () => SimpleTest.finish() ) + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug1512958.html b/dom/media/test/test_bug1512958.html new file mode 100644 index 0000000000..2513515542 --- /dev/null +++ b/dom/media/test/test_bug1512958.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that pausing and resuming a captured media element with audio doesn't stall</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<audio id="a"></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +function dumpEvent({target, type}) { + info(`${target.name} GOT EVENT ${type} currentTime=${target.currentTime} ` + + `paused=${target.paused} ended=${target.ended} ` + + `readyState=${target.readyState}`); +} + +function wait(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +const a = document.getElementById('a'); + +const events = ["timeupdate", "seeking", "seeked", "ended", "playing", "pause"]; +for (let ev of events) { + a.addEventListener(ev, dumpEvent); +} + +(async () => { + try { + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("Timeouts for shortcutting test-timeout"); + + const test = getPlayableAudio(gTrackTests.filter(t => t.duration > 2)); + if (!test) { + todo(false, "No playable audio"); + return; + } + + // Start playing and capture + a.src = test.name; + a.name = test.name; + const ac = new AudioContext(); + ac.createMediaElementSource(a); + a.play(); + do { + await new Promise(r => a.ontimeupdate = r); + } while(a.currentTime == 0) + + // Pause to trigger recreating tracks in DecodedStream + a.pause(); + await new Promise(r => a.onpause = r); + + // Resuming should now work. Bug 1512958 would cause a stall because the + // original track wasn't ended and we'd block on it. + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1512958#c5 + a.play(); + await new Promise(r => a.onplaying = r); + a.currentTime = test.duration - 1; + await Promise.race([ + new Promise(res => a.onended = res), + wait(30000).then(() => Promise.reject(new Error("Timeout"))), + ]); + } catch(e) { + ok(false, e); + } finally { + SimpleTest.finish(); + } +})(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug1553262.html b/dom/media/test/test_bug1553262.html new file mode 100644 index 0000000000..19b937f7fe --- /dev/null +++ b/dom/media/test/test_bug1553262.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Bug 1553262</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script> + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + + const video = document.createElement('video') + const source = new AudioContext().createMediaElementSource(video) + const stream = canvas.captureStream() + + const xhr = new XMLHttpRequest() + + context.rect(256, -32768, 16, 16) + video.srcObject = stream + for (let i = 0; i < 16; i++) { + xhr.open('P', '', false) + xhr.send() + } + + video.srcObject = stream + ok(true, "success") +</script> +</body> +</html> diff --git a/dom/media/test/test_bug448534.html b/dom/media/test/test_bug448534.html new file mode 100644 index 0000000000..ed1135d85a --- /dev/null +++ b/dom/media/test/test_bug448534.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=448534 +--> + +<head> + <title>Test for Bug 448534</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=448535">Mozilla Bug 448534</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function loaded(event) { + var v = event.target; + info(v.token + ": event=" + event.type); + if (v._finished) + return; + v.play(); +} + +function started(event) { + var v = event.target; + info(v.token + ": event=" + event.type); + // For a short file, it could reach the end before 'play' received. We will + // skip the test for 'paused' would be true when ended. + if (v._finished || v.ended) + return; + ok(!v.paused, v.token + ": Video should not be paused while playing"); + v.remove(); + v._played = true; +} + +function stopped(event) { + var v = event.target; + info(v.token + ": event=" + event.type); + if (v._finished) + return; + v._finished = true; + ok(v.paused, v.token + ": Video should be paused after removing from the Document"); + removeNodeAndSource(v); + manager.finished(v.token); +} + + +function startTest(test, token) { + var v = document.createElement('video'); + v.preload = "metadata"; + v.token = token; + manager.started(token); + v.src = test.name; + v._played = false; + v._finished = false; + v.addEventListener("loadedmetadata", loaded); + v.addEventListener("play", started); + v.addEventListener("pause", stopped); + document.body.appendChild(v); +} + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug463162.xhtml b/dom/media/test/test_bug463162.xhtml new file mode 100644 index 0000000000..a84b3488d1 --- /dev/null +++ b/dom/media/test/test_bug463162.xhtml @@ -0,0 +1,78 @@ +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:svg="http://www.w3.org/2000/svg"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=463162 +--> +<head> + <title>Test for Bug 463162</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=463162">Mozilla Bug 463162</a> + +<script class="testbody" type="text/javascript"> +<![CDATA[ + +var gExpectedResult = { + 'a1' : 'error', + 'a2' : 'loaded', + 'a3' : 'loaded', + 'a4' : 'error', +}; + +var gResultCount = 0; + +function onError(event, id) { + is('error', gExpectedResult[id], 'unexpected error loading ' + id); + gResultCount++; + dump('error('+id+') expected ' + gExpectedResult[id] + ' gResultCount=' + gResultCount + '\n'); + if (gResultCount == 4) + SimpleTest.finish(); +} + +function onMetaData(id) { + is('loaded', gExpectedResult[id], 'unexpected loadedmetadata loading ' + id); + gResultCount++; + dump('onMetaData('+id+') expected ' + gExpectedResult[id] + ' gResultCount=' + gResultCount + '\n'); + if (gResultCount == 4) + SimpleTest.finish(); +} + +]]> +</script> + +<video id="a1" preload="metadata" onloadedmetadata="onMetaData('a1');"><sauce/><source type="bad" src="404" onerror="onError(event, 'a1');"/></video> +<video id="a2" preload="metadata" onloadedmetadata="onMetaData('a2');"><source onerror="onError(event, 'a2');"/></video> +<video id="a3" preload="metadata" onloadedmetadata="onMetaData('a3');"><html:source onerror="onError(event, 'a3');"/></video> +<video id="a4" preload="metadata" onloadedmetadata="onMetaData('a4');"><svg:source/><source onerror="onError(event, 'a4');" type="bad" src="404"/></video> + +<script class="testbody" type="text/javascript"> +<![CDATA[ + +function setSource(id, res) { + var v = document.getElementById(id); + v.firstChild.src = res.name; + v.firstChild.type = res.type; +} + +var t = getPlayableVideo(gSmallTests); + +setSource('a1', t); +setSource('a2', t); +setSource('a3', t); +setSource('a4', t); + +SimpleTest.waitForExplicitFinish(); + +]]> +</script> + +<pre id="test"> + +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug465498.html b/dom/media/test/test_bug465498.html new file mode 100644 index 0000000000..157a972e77 --- /dev/null +++ b/dom/media/test/test_bug465498.html @@ -0,0 +1,83 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: Bug 465498 - Seeking after playback ended</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=465498">Mozilla Bug 465498</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(e) { + var v = e.target; + info(v._name + " loadedmetadata"); + e.target.play(); +} + +function playbackEnded(e) { + var v = e.target; + info(v._name + " ended"); + if (v._finished) + return; + ok(v.currentTime >= v.duration - 0.1 && v.currentTime <= v.duration + 0.1, + "Checking currentTime at end: " + v.currentTime + " for " + v._name); + ok(v.ended, "Checking playback has ended for " + v._name); + v.pause(); + v.currentTime = 0; + ok(!v.ended, "Checking ended is no longer true for " + v._name); + v._seeked = true; +} + +function seekEnded(e) { + var v = e.target; + info(v._name + " seeked"); + if (v._finished) + return; + ok(v.currentTime == 0, "Checking currentTime after seek: " + + v.currentTime + " for " + v._name); + ok(!v.ended, "Checking ended is false for " + v._name); + v._finished = true; + removeNodeAndSource(v); + manager.finished(v.token); +} + +function seeking(e) { + var v = e.target; + info(v._name + " seeking"); +} + +function initTest(test, token) { + var type = getMajorMimeType(test.type); + var v = document.createElement(type); + if (!v.canPlayType(test.type)) + return; + v.preload = "metadata"; + v.token = token; + manager.started(token); + v._name = test.name; + + var s = document.createElement("source"); + s.type = test.type; + s.src = test.name; + v.appendChild(s); + + v._seeked = false; + v._finished = false; + v.addEventListener("loadedmetadata", startTest); + v.addEventListener("ended", playbackEnded); + v.addEventListener("seeked", seekEnded); + v.addEventListener("seeking", seeking); + document.body.appendChild(v); +} + +manager.runTests(gSmallTests, initTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug495145.html b/dom/media/test/test_bug495145.html new file mode 100644 index 0000000000..3686e10270 --- /dev/null +++ b/dom/media/test/test_bug495145.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=495145 +--> + +<head> + <title>Bug 495145 - pausing while ended shouldn't cause problems</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=495145">Mozilla Bug 495145</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function start(e) { + e.target.play(); +} + +function ended1(e) { + var v = e.target; + if (v._finished) + return; + + ++v._endCount; + if (v._endCount == 2) { + ok(true, "Playing after pause while ended works for " + v._name); + v._finished = true; + v.removeEventListener("loadedmetadata", start); + v.removeEventListener("ended", ended1); + removeNodeAndSource(v); + manager.finished(v.token); + return; + } + + v.pause(); + v.play(); +} + +function ended2(e) { + var v = e.target; + if (v._finished) + return; + + v.pause(); + v.currentTime = 0; +} + +function seeked2(e) { + var v = e.target; + if (v._finished) + return; + + ok(v.paused, "Paused after seek after pause while ended for " + v._name); + v._finished = true; + v.removeEventListener("loadedmetadata", start); + v.removeEventListener("ended", ended2); + v.removeEventListener("seeked", seeked2); + removeNodeAndSource(v); + manager.finished(v.token); +} + +function createVideo(test, x, token) { + var v = document.createElement('video'); + v.preload = "metadata"; + v.token = token; + manager.started(token); + v.src = test.name; + v._name = test.name + "#" + x; + v._endCount = 0; + v._finished = false; + v.addEventListener("loadedmetadata", start); + v.addEventListener("ended", x == 1 ? ended1 : ended2); + if (x == 2) + v.addEventListener("seeked", seeked2); + document.body.appendChild(v); +} + +function startTest(test, token) { + createVideo(test, 1, token + "a"); + createVideo(test, 2, token + "b"); +} + +manager.runTests(gSmallTests, startTest); + + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug495300.html b/dom/media/test/test_bug495300.html new file mode 100644 index 0000000000..bf3b921402 --- /dev/null +++ b/dom/media/test/test_bug495300.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=495300 +--> + +<head> + <title>Bug 495300 - seeking to the end should behave as "ended"</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=495300">Mozilla Bug 495300</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function filename(uri) { + return uri.substr(uri.lastIndexOf("/")+1); +} + +function mediaEnded(event) { + ok(true, "Got expected 'ended' event: " + filename(event.target.currentSrc)); + + if (event.target._expectedDuration) + ok(Math.abs(event.target.currentTime - event.target._expectedDuration) < 0.1, + "currentTime equals duration: " + filename(event.target.currentSrc)); + + event.target.removeEventListener("ended", mediaEnded); + manager.finished(event.target.token); + removeNodeAndSource(event.target); +} + +function mediaLoadedmetadata(event) { + event.target.currentTime = event.target.duration; + event.target.removeEventListener("loadedmetadata", mediaLoadedmetadata); +} + +function startTest(test, token) { + var elemType = /^audio/.test(test.type) ? "audio" : "video"; + var v1 = document.createElement(elemType); + v1.preload = "auto"; + + v1.src = test.name; + if (test.duration) { + v1._expectedDuration = test.duration; + } + v1.addEventListener("loadedmetadata", mediaLoadedmetadata); + v1.addEventListener("ended", mediaEnded); + v1.load(); + + v1.token = token; + manager.started(token); +} + +manager.runTests(gSeekTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug654550.html b/dom/media/test/test_bug654550.html new file mode 100644 index 0000000000..f57afae2b4 --- /dev/null +++ b/dom/media/test/test_bug654550.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=654550 +--> + +<head> + <title>Test for Bug 654550</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=654550">Mozilla Bug 654550</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + /* Test for Bug 654550 */ + + // Parallel test must be disabled for media.video_stats.enabled is a global setting + // to prevent the setting from changing unexpectedly in the middle of the test. + PARALLEL_TESTS = 1; + SimpleTest.waitForExplicitFinish(); + var manager = new MediaTestManager; + + function checkStats(v, aShouldBeEnabled) { + if (aShouldBeEnabled) { + ok(v.mozParsedFrames != 0, + "At least one value should be different from 0 if stats are enabled"); + } else { + ok(!v.mozParsedFrames, + "mozParsedFrames should be 0 if stats are disabled"); + ok(!v.mozDecodedFrames, + "mozDecodedFrames should be 0 if stats are disabled"); + ok(!v.mozPresentedFrames, + "mozPresentedFrames should be 0 if stats are disabled"); + ok(!v.mozPaintedFrames, + "mozPaintedFrames should be 0 if stats are disabled"); + } + + } + + function ontimeupdate_statsEnabled(event) { + var v = event.target; + v.removeEventListener('timeupdate', ontimeupdate_statsEnabled); + checkStats(v, true); + SpecialPowers.popPrefEnv( + function() { + v.addEventListener("timeupdate", ontimeupdate_statsDisabled); + }); + } + + function ontimeupdate_statsDisabled(event) { + var v = event.target; + v.removeEventListener('timeupdate', ontimeupdate_statsDisabled); + checkStats(v, false); + removeNodeAndSource(v); + manager.finished(v.token); + } + + function startTest(test, token) { + var v = document.createElement('video'); + v.token = token; + v.src = test.name; + // playback may reach the end before pref is changed for the duration is short + // set 'loop' to true to keep playing so that we won't miss 'timeupdate' events + v.loop = true; + manager.started(token); + SpecialPowers.pushPrefEnv({"set": [["media.video_stats.enabled", true]]}, + function() { + v.play(); + v.addEventListener("timeupdate", ontimeupdate_statsEnabled); + }); + } + + SpecialPowers.pushPrefEnv({"set": [["media.video_stats.enabled", false]]}, + function() { + manager.runTests(gVideoTests, startTest); + }); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug686942.html b/dom/media/test/test_bug686942.html new file mode 100644 index 0000000000..66b48d69f0 --- /dev/null +++ b/dom/media/test/test_bug686942.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=686942 +--> + +<head> + <title>Test for Bug 448534</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=686942">Mozilla Bug 686942</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function onloaded(event) { + var v = event.target; + v.removeEventListener("loadedmetadata", onloaded); + v.currentTime = v.duration; + +} + +function checkNotPlaying(v) { + ok(v.currentTime == 0, "Should not be playing after seek to end and back to beginning"); + v._finished = true; + manager.finished(v.token); + removeNodeAndSource(v); +} + +function onseeked(event) { + var v = event.target; + v.removeEventListener("seeked", onseeked); + setTimeout(function() { checkNotPlaying(v); }, 500); +} + +function onended(event) { + var v = event.target; + v.removeEventListener("ended", onended); + if (v._finished) + return; + v.addEventListener("seeked", onseeked); + v.currentTime = 0; +} + +function startTest(test, token) { + var v = document.createElement('video'); + v.preload = "auto"; + v.token = token; + manager.started(token); + v.src = test.name; + v._played = false; + v._finished = false; + v.addEventListener("loadedmetadata", onloaded); + v.addEventListener("ended", onended); + + document.body.appendChild(v); +} + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug726904.html b/dom/media/test/test_bug726904.html new file mode 100644 index 0000000000..bf8e2536ca --- /dev/null +++ b/dom/media/test/test_bug726904.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=726904 +--> + +<head> + <title>Media test: default video size</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body onload="bodyLoaded();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=726904">Mozilla Bug 726904</a> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var v1 = document.createElement("video"), + v2 = document.createElement("video"), + poster = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAAAAACl1GkQAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAALJJREFUeNrtwQENAAAAwqD3T20ON6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHg0cq4AATRk8BYAAAAASUVORK5CYII", + resource = getPlayableVideo(gSmallTests); + +function bodyLoaded(){ + // Note: For DASH, width and height would vary once the video started playing, so + // the values would not correlate with those in manifest.js. Since this test has + // no playing, this should not affect the result. + is(v1.videoWidth, resource.width, "Intrinsic width should match video width"); + is(v1.videoHeight, resource.height, "Intrinsic height should match video height"); + is(v2.clientWidth, 400, "clientWidth should be 400"); + is(v2.clientHeight, 400, "clientHeight should be 400"); + SimpleTest.finish(); +} + +if (resource) { + v1.poster = v2.poster = poster; + + v1.src = v2.src = "http://mochi.test:8888/tests/dom/media/test/" + resource.name; + + v1.preload = "auto"; + v2.preload = "none"; + + v1.muted = v2.muted = true; + + document.body.appendChild(v1); + document.body.appendChild(v2); +} else { + todo(false, "No types supported"); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug874897.html b/dom/media/test/test_bug874897.html new file mode 100644 index 0000000000..7801487fe3 --- /dev/null +++ b/dom/media/test/test_bug874897.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=874897 +--> + +<head> + <title>Test for Bug 874897</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function loadeddata(e) { + var v = e.target; + ok(v.readyState >= v.HAVE_CURRENT_DATA, + "readyState must be >= HAVE_CURRENT_DATA for " + v._name); + + var canvas = document.createElement("canvas"); + canvas.width = 210; + canvas.height = 120; + document.body.appendChild(canvas); + var ctx = canvas.getContext("2d"); + try { + ctx.drawImage(v, 0, 0, v.videoWidth, v.videoHeight, 0, 0, canvas.width, canvas.height); + ok(true, "Shouldn't throw exception while drawing to canvas from video for " + v._name); + } catch (ex) { + ok(false, "Shouldn't throw exception while drawing to canvas from video for " + v._name); + } + + v._finished = true; + v.remove(); + manager.finished(v.token); +} + +function startTest(test, token) { + var type = getMajorMimeType(test.type); + if (type != "video") + return; + + var v = document.createElement('video'); + v.token = token; + manager.started(token); + v.src = test.name; + v._name = test.name; + v._finished = false; + v.autoplay = true; + v.style.display = "none"; + v.addEventListener("loadeddata", loadeddata); + document.body.appendChild(v); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest); +function beginTest() { + manager.runTests(gAspectRatioTests, startTest); +} + +</script> +</pre> + +</body> +</html> diff --git a/dom/media/test/test_bug879717.html b/dom/media/test/test_bug879717.html new file mode 100644 index 0000000000..c669773d3f --- /dev/null +++ b/dom/media/test/test_bug879717.html @@ -0,0 +1,130 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for bug 879717, check that a video element can be drawn into a canvas at various states of playback</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +var canvas = document.createElement('canvas'); +document.body.appendChild(canvas); + +var checkDrawImage = function(eventName, videoElement) { + var exception = null; + var exceptionName = "nothing"; + try { + var ctx = canvas.getContext('2d'); + ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height); + } catch (e) { + exception = e; + exceptionName = e.name; + } + ok(exception === null, + "drawImage shouldn't throw an exception on " + eventName + + " of " + videoElement.testName + ", got " + exceptionName); +}; + +var checkDrawImageEventHandler = function(ev) { + checkDrawImage(ev.type, ev.target); +}; +var startTest = function(media, token) { + manager.started(token); + + // File playback + var v1 = document.createElement("video"); + v1.autoplay = true; + + // Captured file playback + var v2 = document.createElement("video"); + + // Stream playback + var v3 = document.createElement("video"); + v3.autoplay = true; + + v1.gotLoadeddata = false; + v2.gotLoadeddata = false; + v3.gotLoadeddata = false; + + v1.testName = "v1 (" + media.name + ")"; + v2.testName = "v2 (Captured " + media.name + ")"; + v3.testName = "v3 (Stream of " + media.name + ")"; + + checkDrawImage("beforeplay", v1); + checkDrawImage("beforeplay", v2); + checkDrawImage("beforeplay", v3); + + v1.onloadedmetadata = checkDrawImageEventHandler; + v2.onloadedmetadata = checkDrawImageEventHandler; + v3.onloadedmetadata = checkDrawImageEventHandler; + + v1.onplay = checkDrawImageEventHandler; + v2.onplay = checkDrawImageEventHandler; + v3.onplay = checkDrawImageEventHandler; + + function onplaying(ev) { + if (!ev.target.gotPlaying) { + ev.target.gotPlaying = true; + checkDrawImageEventHandler(ev); + } + } + v1.onplaying = onplaying; + v2.onplaying = onplaying; + v3.onplaying = onplaying; + + var onloadeddata = function(ev) { + ev.target.gotLoadeddata = true; + checkDrawImageEventHandler(ev); + }; + + v1.onloadeddata = onloadeddata; + v2.onloadeddata = onloadeddata; + v3.onloadeddata = onloadeddata; + + var checkFinished = function() { + if (!v1.testFinished || !v2.testFinished || !v3.testFinished) { + return; + } + + ok(v1.gotLoadeddata, v1.testName + " should have gotten the 'loadeddata' event callback"); + ok(v2.gotLoadeddata, v2.testName + " should have gotten the 'loadeddata' event callback"); + ok(v3.gotLoadeddata, v3.testName + " should have gotten the 'loadeddata' event callback"); + + manager.finished(token); + }; + + var onended = function(ev) { + checkDrawImageEventHandler(ev); + removeNodeAndSource(ev.target); + ev.target.testFinished = true; + checkFinished(); + }; + + v1.onended = onended; + v2.onended = onended; + v3.onended = onended; + + document.body.appendChild(v1); + document.body.appendChild(v2); + document.body.appendChild(v3); + + v1.src = media.name; + v2.src = media.name; + v2.preload = 'metadata'; + + v2.addEventListener('loadedmetadata', function () { + v3.srcObject = v2.mozCaptureStreamUntilEnded(); + v2.play(); + }); +} + +manager.runTests(getPlayableVideos(gSmallTests), startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug895305.html b/dom/media/test/test_bug895305.html new file mode 100644 index 0000000000..56ed3c775c --- /dev/null +++ b/dom/media/test/test_bug895305.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=895305 +https://bugzilla.mozilla.org/show_bug.cgi?id=905320 +--> +<head> + <meta charset='utf-8'> + <title>Regression test for bug 895305 and 905320 - TextTrack* leaks</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var audio = document.createElement("audio"); + +// Check leaking on TextTrackList objects. +/* global ttl, ttc */ +window.ttl = audio.textTracks; +ttl.addEventListener("click", function(){}); + +// Check leaking on VTTCue objects. +window.ttc = new VTTCue(3, 4, "Test."); +ttc.addEventListener("click", function() {}); + +// Check leaking on TextTrack objects. +audio.addTextTrack("subtitles", "label", "en-CA"); +ttl[0].addEventListener("click", function() {}); + +ok(true); // Need to have at least one assertion for Mochitest to be happy. +SimpleTest.finish(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_bug919265.html b/dom/media/test/test_bug919265.html new file mode 100644 index 0000000000..40eff135e4 --- /dev/null +++ b/dom/media/test/test_bug919265.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=919265 +--> +<head> + <meta charset='utf-8'> + <title>Regression test for bug 919265 - Leak on VTTCue::GetCueAsHTML()</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +// We shouldn't leak upon shutdown. +(new VTTCue(0, 0, "")).getCueAsHTML(); + +// We need to assert something for Mochitest to be happy. +ok(true); +SimpleTest.finish(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_can_play_type.html b/dom/media/test/test_can_play_type.html new file mode 100644 index 0000000000..a28d137783 --- /dev/null +++ b/dom/media/test/test_can_play_type.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=469247 +--> +<head> + <title>Test for Bug 469247</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469247">Mozill +a Bug 469247</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + +<video id="v"></video> + +<pre id="test"> +<script type="application/javascript"> + +var v = document.getElementById('v'); + +function check(type, expected) { + is(v.canPlayType(type), expected, type); +} + +// Invalid types +check("foo/bar", ""); +check("", ""); +check("!!!", ""); + +mediaTestCleanup(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_can_play_type_mpeg.html b/dom/media/test/test_can_play_type_mpeg.html new file mode 100644 index 0000000000..40a1225922 --- /dev/null +++ b/dom/media/test/test_can_play_type_mpeg.html @@ -0,0 +1,166 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=799315 +--> +<head> + <title>Test for MP4 and MP3 support</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + +<video id="v"></video> + +<pre id="test"> +<script> + +function check_mp4(v, enabled) { + function check(type, expected) { + var ex = enabled ? expected : ""; + is(v.canPlayType(type), ex, type + "='" + ex + "'"); + } + + check("video/mp4", "maybe"); + check("video/x-m4v", "maybe"); + check("audio/mp4", "maybe"); + check("audio/x-m4a", "maybe"); + + // Not the MIME type that other browsers respond to, so we won't either. + check("audio/m4a", ""); + check("video/m4v", ""); + + check("audio/aac", "maybe"); + check("audio/aacp", "maybe"); + + // H.264 Constrained Baseline Profile Level 3.0, AAC-LC + check("video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"", "probably"); + + // H.264 Constrained Baseline Profile Level 3.0, mp3 + check("video/mp4; codecs=\"avc1.42E01E, mp3\"", "probably"); + + check("video/mp4; codecs=\"avc1.42001E, mp4a.40.2\"", "probably"); + check("video/mp4; codecs=\"avc1.58A01E, mp4a.40.2\"", "probably"); + + // H.264 Main Profile Level 3.0, AAC-LC + check("video/mp4; codecs=\"avc1.4D401E, mp4a.40.2\"", "probably"); + // H.264 Main Profile Level 3.1, AAC-LC + check("video/mp4; codecs=\"avc1.4D401F, mp4a.40.2\"", "probably"); + // H.264 Main Profile Level 4.0, AAC-LC + check("video/mp4; codecs=\"avc1.4D4028, mp4a.40.2\"", "probably"); + // H.264 High Profile Level 3.0, AAC-LC + check("video/mp4; codecs=\"avc1.64001E, mp4a.40.2\"", "probably"); + // H.264 High Profile Level 3.1, AAC-LC + check("video/mp4; codecs=\"avc1.64001F, mp4a.40.2\"", "probably"); + + check("video/mp4; codecs=\"avc1.42E01E\"", "probably"); + check("video/mp4; codecs=\"avc1.42001E\"", "probably"); + check("video/mp4; codecs=\"avc1.58A01E\"", "probably"); + check("video/mp4; codecs=\"avc1.4D401E\"", "probably"); + check("video/mp4; codecs=\"avc1.64001F\"", "probably"); + + // AAC-LC + check("audio/mp4; codecs=\"mp4a.40.2\"", "probably"); + check("audio/mp4; codecs=mp4a.40.2", "probably"); + check("audio/x-m4a; codecs=\"mp4a.40.2\"", "probably"); + check("audio/x-m4a; codecs=mp4a.40.2", "probably"); + + check("audio/mp4; codecs=\"mp4a.40.2,\"", ""); // Invalid codecs string + + // HE-AAC v1 + check("audio/mp4; codecs=\"mp4a.40.5\"", "probably"); + check("audio/mp4; codecs=mp4a.40.5", "probably"); + check("audio/x-m4a; codecs=\"mp4a.40.5\"", "probably"); + check("audio/x-m4a; codecs=mp4a.40.5", "probably"); + // HE-AAC v2 + check("audio/mp4; codecs=\"mp4a.40.29\"", "probably"); + + // Opus + check("audio/mp4; codecs=\"opus\"", "probably"); + check("audio/mp4; codecs=opus", "probably"); + + // Flac. + var haveFlac = getPref("media.flac.enabled"); + check("audio/mp4; codecs=\"flac\"", haveFlac ? "probably" : ""); + check("audio/mp4; codecs=flac", haveFlac ? "probably" : ""); + + // VP9. + [ "video/mp4; codecs=vp9", + "video/mp4; codecs=\"vp9\"", + "video/mp4; codecs=\"vp9.0\"" + ].forEach((codec) => { + // canPlayType should support VP9 in MP4... + check(codec, "probably"); + if (!IsSupportedAndroid()) { + // VP9 codec is disabled on Android devices with no HW decoder. So skip it + // on Android for now. + ok(MediaSource.isTypeSupported(codec), "VP9 in MP4 should be supported in MSE"); + } + }); + + var haveAV1 = getPref("media.av1.enabled"); + check("video/mp4; codecs=\"av1\"", haveAV1 ? "probably" : ""); +} + +function check_mp3(v, enabled) { + function check(type, expected) { + var ex = enabled ? expected : ""; + is(v.canPlayType(type), ex, type + "='" + ex + "'"); + } + + check("audio/mpeg", "maybe"); + check("audio/mp3", "maybe"); + + check("audio/mpeg; codecs=\"mp3\"", "probably"); + check("audio/mpeg; codecs=mp3", "probably"); + + check("audio/mp3; codecs=\"mp3\"", "probably"); + check("audio/mp3; codecs=mp3", "probably"); +} + +function IsMacOS() { + return navigator.userAgent.includes("Mac OS"); +} + +function IsLinux() { + return navigator.userAgent.includes("Linux"); +} + +function getPref(name) { + return SpecialPowers.getBoolPref(name, false); +} + +function IsSupportedAndroid() { + return getAndroidVersion() >= 14; +} + +function IsJellyBeanOrLater() { + return getAndroidVersion() >= 16; +} + +var haveMp4 = + getPref("media.wmf.enabled") || + IsMacOS() || + IsSupportedAndroid() || + (IsLinux() && getPref("media.ffmpeg.enabled")); + +check_mp4(document.getElementById('v'), haveMp4); + +var haveMp3 = + getPref("media.wmf.enabled") || + (IsLinux() && getPref("media.ffmpeg.enabled")) || + (IsSupportedAndroid() && + ((IsJellyBeanOrLater() && getPref("media.android-media-codec.enabled")))) || + IsMacOS(); + +check_mp3(document.getElementById('v'), haveMp3); + +mediaTestCleanup(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_can_play_type_no_ogg.html b/dom/media/test/test_can_play_type_no_ogg.html new file mode 100644 index 0000000000..2e63f191d2 --- /dev/null +++ b/dom/media/test/test_can_play_type_no_ogg.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=469247 +--> +<head> + <title>Test for Bug 469247: Ogg backend disabled</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469247">Mozill +a Bug 469247</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + +<video id="v"></video> + +<pre id="test"> +<script src="can_play_type_ogg.js"></script> +<script> + +SimpleTest.waitForExplicitFinish(); + +function finish() { + mediaTestCleanup(); + SimpleTest.finish(); +} + +SpecialPowers.pushPrefEnv({"set": [["media.ogg.enabled", false]]}, + function() { + check_ogg(document.getElementById('v'), false, finish); + } +); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_can_play_type_ogg.html b/dom/media/test/test_can_play_type_ogg.html new file mode 100644 index 0000000000..3e44f8ba8c --- /dev/null +++ b/dom/media/test/test_can_play_type_ogg.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=469247 +--> +<head> + <title>Test for Bug 469247: Ogg backend</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469247">Mozill +a Bug 469247</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + +<video id="v"></video> + +<pre id="test"> +<script src="can_play_type_ogg.js"></script> +<script> + +SimpleTest.waitForExplicitFinish(); + +function finish() { + mediaTestCleanup(); + SimpleTest.finish(); +} + +check_ogg(document.getElementById('v'), true, finish); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_can_play_type_wave.html b/dom/media/test/test_can_play_type_wave.html new file mode 100644 index 0000000000..e6d4e29d86 --- /dev/null +++ b/dom/media/test/test_can_play_type_wave.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=469247 +--> +<head> + <title>Test for Bug 469247: WAVE backend</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469247">Mozill +a Bug 469247</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + +<video id="v"></video> + +<pre id="test"> +<script src="can_play_type_wave.js"></script> +<script> +check_wave(document.getElementById('v'), true); + +mediaTestCleanup(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_can_play_type_webm.html b/dom/media/test/test_can_play_type_webm.html new file mode 100644 index 0000000000..6b0e2adfad --- /dev/null +++ b/dom/media/test/test_can_play_type_webm.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=566245 +--> +<head> + <title>Test for Bug 566245: WebM backend</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=566245">Mozill +a Bug 566245</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + +<video id="v"></video> + +<pre id="test"> +<script src="can_play_type_webm.js"></script> +<script> + async function runTest() { + try { + await check_webm(document.getElementById('v'), true); + mediaTestCleanup(); + } catch (e) { + info("Exception " + e.message); + ok(false, "Threw exception " + e.message); + } + SimpleTest.finish(); + } + SimpleTest.waitForExplicitFinish(); + addLoadEvent(runTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_capture_stream_av_sync.html b/dom/media/test/test_capture_stream_av_sync.html new file mode 100644 index 0000000000..b5754c683f --- /dev/null +++ b/dom/media/test/test_capture_stream_av_sync.html @@ -0,0 +1,276 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>A/V sync test for stream capturing</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<p>Following canvas will capture and show the video frame when the video becomes audible</p><br> +<canvas id="canvas" width="640" height="480"></canvas> +<script type="application/javascript"> + +/** + * This test will capture stream before the video starts playing, and check if + * A/V sync will keep sync during playing. + */ +add_task(async function testAVSyncForStreamCapturing() { + createVideo(); + captureStreamFromVideo(); + await playMedia(); + await testAVSync(); + destroyVideo(); +}); + +/** + * This test will check if A/V is still on sync after we switch the media sink + * from playback-based sink to mediatrack-based sink. + */ +add_task(async function testAVSyncWhenSwitchingMediaSink() { + createVideo(); + await playMedia({resolveAfterReceivingTimeupdate : 5}); + captureStreamFromVideo(); + await testAVSync(); + destroyVideo(); +}); + +/** + * This test will check if A/V is still on sync after we change the playback + * rate on the captured stream. + */ +add_task(async function testAVSyncWhenChangingPlaybackRate() { + createVideo(); + captureStreamFromVideo(); + await playMedia(); + const playbackRates = [0.25, 0.5, 1.0, 1.5, 2.0]; + for (let rate of playbackRates) { + setPlaybackRate(rate); + // TODO : when playback rate set to 1.5+x, the A/V will become less stable + // in testing so we raise the fuzzy frames for that, but also increase the + // test times. As at that speed, precise A/V becomes trivial because we + // can't really tell the difference. But it would be good for us to + // investigate if we could make A/V sync work better at that extreme high + // rate. + if (rate >= 1.5) { + await testAVSync({ expectedAVSyncTestTimes : 4, fuzzyFrames : 10}); + } else { + await testAVSync({ expectedAVSyncTestTimes : 2 }); + } + } + destroyVideo(); +}); + +/** + * Following are helper functions + */ +const DEBUG = false; +function info_debug(msg) { + if (DEBUG) { + info(msg); + } +} + +function createVideo() { + const video = document.createElement("video"); + // This video is special for testing A/V sync, it only produce audible sound + // once per second, and when the sound comes out, you can check the position + // of the square to know if the A/V keeps sync. + video.src = "sync.webm"; + video.loop = true; + video.controls = true; + video.width = 640; + video.height = 480; + video.id = "video"; + document.body.appendChild(video); +} + +function destroyVideo() { + const video = document.getElementById("video"); + video.src = null; + video.remove(); +} + +async function playMedia({ resolveAfterReceivingTimeupdate } = {}) { + const video = document.getElementById("video"); + ok(await video.play().then(_=>true,_=>false), "video started playing"); + if (resolveAfterReceivingTimeupdate > 0) { + // Play it for a while to ensure the clock growing on the normal audio sink. + for (let idx = 0; idx < resolveAfterReceivingTimeupdate; idx++) { + await new Promise(r => video.ontimeupdate = r); + } + } +} + +async function captureStreamFromVideo() { + const video = document.getElementById("video"); + let ac = new AudioContext(); + let analyser = ac.createAnalyser(); + analyser.frequencyBuf = new Float32Array(analyser.frequencyBinCount); + analyser.smoothingTimeConstant = 0; + analyser.fftSize = 2048; // 1024 bins + let sourceNode = ac.createMediaElementSource(video); + sourceNode.connect(analyser); + analyser.connect(ac.destination); + video.analyser = analyser; +} + +// This method will capture the stream from the video element, and check if A/V +// keeps sync during capturing. `callback` parameter will be executed after +// finishing capturing. +// @param [optional] expectedAVSyncTestTimes +// The amount of times that A/V sync test performs. +// @param [optional] fuzzyFrames +// This will fuzz the result from +0 (perfect sync) to -X to +X frames. +async function testAVSync({ expectedAVSyncTestTimes = 5, fuzzyFrames = 5} = {}) { + return new Promise(r => { + const analyser = document.getElementById("video").analyser; + let testIdx = 0; + let hasDetectedAudibleFrame = false; + // As we only want to detect the audible frame at the first moment when + // sound becomes audible, so we always skip the first audible frame because + // it might not be the start, but the tail part (where audio is being + // decaying to silence) when we start detecting. + let hasSkippedFirstFrame = false; + analyser.notifyAnalysis = () => { + let {frequencyBuf} = analyser; + analyser.getFloatFrequencyData(frequencyBuf); + if (checkIfBufferIsSilent(frequencyBuf)) { + info_debug("no need to paint the silent frame"); + hasDetectedAudibleFrame = false; + requestAnimationFrame(analyser.notifyAnalysis); + return; + } + if (hasDetectedAudibleFrame) { + info_debug("detected audible frame already"); + requestAnimationFrame(analyser.notifyAnalysis); + return; + } + hasDetectedAudibleFrame = true; + if (!hasSkippedFirstFrame) { + info("skip the first audible frame"); + hasSkippedFirstFrame = true; + requestAnimationFrame(analyser.notifyAnalysis); + return; + } + const video = document.getElementById("video"); + info(`paint audible frame`); + const cvs = document.getElementById("canvas"); + let context = cvs.getContext('2d'); + context.drawImage(video, 0, 0, 640, 480); + if (checkIfAVIsOnSyncFuzzy(context, fuzzyFrames)) { + ok(true, `test ${testIdx++} times, a/v is in sync!`); + } else { + ok(false, `test ${testIdx++} times, a/v is out of sync!`); + } + if (testIdx == expectedAVSyncTestTimes) { + r(); + return; + } + requestAnimationFrame(analyser.notifyAnalysis); + } + analyser.notifyAnalysis(); + }); +} + +function checkIfBufferIsSilent(buffer) { + for (let data of buffer) { + // when sound is audible, its values are around -200 and the silence values + // are around -800. + if (data > -200) { + return false; + } + } + return true; +} + +// This function will check the pixel data from the `context` to see if the +// square appears in the right place. As we can't control the exact timing +// of rendering video frames in the compositor, so the result would be fuzzy. +function checkIfAVIsOnSyncFuzzy(context, fuzzyFrames) { + const squareLength = 48; + // Canvas is 640*480, so perfect sync is the left-top corner when the square + // shows up in the middle. + const perfectSync = + { x: 320 - squareLength/2.0 , + y: 240 - squareLength/2.0 }; + let isAVSyncFuzzy = false; + // Get the whole partial section of image and detect where the square is. + let imageData = context.getImageData(0, perfectSync.y, 640, squareLength); + for (let i = 0; i < imageData.data.length; i += 4) { + // If the pixel's color is red, then this position will be the left-top + // corner of the square. + if (isPixelColorRed(imageData.data[i], imageData.data[i+1], + imageData.data[i+2])) { + const pos = ImageIdxToRelativeCoordinate(imageData, i); + let diff = calculateFrameDiffenceInXAxis(pos.x, perfectSync.x); + info(`find the square in diff=${diff}`); + // Maybe we check A/V sync too early or too late, try to adjust the diff + // to guess the previous correct position where the square should be. + if (diff > fuzzyFrames) { + diff = adjustFrameDiffBasedOnMediaTime(diff); + const video = document.getElementById("video"); + info(`adjusted diff to ${diff} (time=${video.currentTime})`); + } + if (diff <= fuzzyFrames) { + isAVSyncFuzzy = true; + } + context.putImageData(imageData, 0, 0); + break; + } + } + if (!isAVSyncFuzzy) { + const ctx = document.getElementById('canvas'); + info(ctx.toDataURL()); + } + return isAVSyncFuzzy; +} + +// Input an imageData and its idx, then return a relative coordinate on the +// range of given imageData. +function ImageIdxToRelativeCoordinate(imageData, idx) { + const offset = idx / 4; // RGBA + return { x: offset % imageData.width, y: offset / imageData.width }; +} + +function calculateFrameDiffenceInXAxis(squareX, targetX) { + const offsetX = Math.abs(targetX - squareX); + const xSpeedPerFrame = 640 / 60; // video is 60fps + return offsetX / xSpeedPerFrame; +} + +function isPixelColorRed(r, g, b) { + // As the rendering color would vary in the screen on different platforms, so + // we won't strict the R should be 255, just check if it's larger than a + // certain threshold. + return r > 200 && g < 10 && b < 10; +} + +function setPlaybackRate(rate) { + const video = document.getElementById("video"); + info(`change playback rate from ${video.playbackRate} to ${rate}`); + document.getElementById("video").playbackRate = rate; +} + +function adjustFrameDiffBasedOnMediaTime(currentDiff) { + // The audio wave can be simply regarded as being composed by "start", "peak" + // and "tail". The "start" part is the sound gradually becoming louder and the + // "tail" is gradually becoming silent. We want to check the "peak" part which + // should happn on evert second regularly (1s, 2s, 3s ...) However, this check + // is triggered by `requestAnimationFrame()` and we can't guarantee that + // we're checking the peak part while the function is being called. Therefore, + // we have to do an adjustment by the video time, to know if we're checking + // the audio wave too early or too late in order to get a consistent result. + const video = document.getElementById("video"); + const videoCurrentTimeFloatPortion = video.currentTime % 1; + const timeOffset = + videoCurrentTimeFloatPortion > 0.5 ? + 1 - videoCurrentTimeFloatPortion : // too early + videoCurrentTimeFloatPortion; // too late + const frameOffset = timeOffset / 0.016; // 60fps, 1 frame=0.016s + info(`timeOffset=${timeOffset}, frameOffset=${frameOffset}`); + return Math.abs(currentDiff - frameOffset); +} + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/test_chaining.html b/dom/media/test/test_chaining.html new file mode 100644 index 0000000000..6ebf94c88d --- /dev/null +++ b/dom/media/test/test_chaining.html @@ -0,0 +1,92 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: chained ogg files.</title> + <meta charset='utf-8'> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function finish_test(element) { + removeNodeAndSource(element); + manager.finished(element.token); +} + +function onended(e) { + var t = e.target; + is(t._metadataCount, t._links, "We should have received "+ t._links + + " metadataloaded event. " + t.src); + + // If we encounter a file that has links with a different numbers of channel, + // we stop the decoding at the end of the first link. Hence, we report normal + // |seekable| and |buffered| values. + if (t._links != 1) { + is(t.seekable.length, 0, "No seekable ranges should be reported." + t.src); + is(t.buffered.length, 0, "No buffered region should be reported." + t.src); + } + + is(t.played.length, 1, "The played region should be continuous." + t.src); + + if (t._links != 1) { + var oldCurrentTime = t.currentTime; + t.currentTime = 0.0; + is(t.currentTime, oldCurrentTime, + "Seeking should be disabled when playing chained media." + t.src); + } + + finish_test(t); +} + +function onmetadataloaded(e) { + var t = e.target; + if (! t._metadataCount) { + t._metadataCount = 0; + } + + if (t._metadataCount > 1 && t._links === 1) { + ok(false, "We should receive only one \"loadedmetadata\" event for a chained file we don't support.") + } + + // We should be able to assert equality here, but somehow it fails (rarely but + // still) on try. Instead, we give it a little slack and assert that the index + // increases monotonically. + ok(t.mozGetMetadata().index >= t._metadataCount || t._links === 1, + "The metadata index value should increase." + t.src); + + ok(t.currentTime >= t._prevCurrentTime, + "The currenttime should be increased correctly in new chained part."); + t._prevCurrentTime = t.currentTime; + + // The files have all a user comment name 'index' that increments at each link + // in the chained media. + t._metadataCount++; + if (!t.playing && !t.ended) { + t.play(); + } +} + +function startTest(test, token) { + var elemType = /^audio/.test(test.type) ? "audio" : "video"; + var element = document.createElement(elemType); + document.body.appendChild(element); + manager.started(token); + element._links= test.links; + element.src = test.name; + element.token = token; + element.controls = true; + element.addEventListener("loadedmetadata", onmetadataloaded); + element.addEventListener("ended", onended); + element.preload = "metadata"; + element._prevCurrentTime = 0; +} + +manager.runTests(gChainingTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_cloneElementVisually_ended_video.html b/dom/media/test/test_cloneElementVisually_ended_video.html new file mode 100644 index 0000000000..331dda2db9 --- /dev/null +++ b/dom/media/test/test_cloneElementVisually_ended_video.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test cloneElementVisually</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="https://example.com:443/tests/dom/media/test/cloneElementVisually_helpers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<div id="content"> + <h1>Original</h1> + <video id="original"></video> + <h1>Clone</h1> +</div> +<div id="results"> + <h1>Results</h1> + <canvas id="left"></canvas> + <canvas id="right"></canvas> +</div> + +<script type="application/javascript"> + +/* import-globals-from cloneElementVisually_helpers.js */ + +/** + * Test that when we start cloning a video that has already ended, the + * clone displays the last frame from the video. + */ +add_task(async () => { + await setup(); + + let originalVideo = document.getElementById("original"); + let ended = waitForEventOnce(originalVideo, "ended"); + await originalVideo.play(); + await ended; + + await withNewClone(originalVideo, async clone => { + await SpecialPowers.wrap(originalVideo).cloneElementVisually(clone); + ok(await assertVideosMatch(originalVideo, clone), + "Visual clone should display final frame."); + }); +}); + +</script> + +</body> +</html> diff --git a/dom/media/test/test_cloneElementVisually_mediastream.html b/dom/media/test/test_cloneElementVisually_mediastream.html new file mode 100644 index 0000000000..5bfcf7673f --- /dev/null +++ b/dom/media/test/test_cloneElementVisually_mediastream.html @@ -0,0 +1,70 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test cloneElementVisually</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="https://example.com:443/tests/dom/media/test/cloneElementVisually_helpers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<div id="content"> + <h1>Original</h1> + <video id="original"></video> + <h1>MediaStream</h1> + <video id="streamTarget"></video> + <h1>Clone</h1> +</div> +<div id="results"> + <h1>Results</h1> + <canvas id="left"></canvas> + <canvas id="right"></canvas> +</div> + +<script type="application/javascript"> + +/* import-globals-from cloneElementVisually_helpers.js */ + +/** + * Test that we can clone a video that is playing a MediaStream. + */ +add_task(async () => { + await setup(); + + let originalVideo = document.getElementById("original"); + let stream = originalVideo.mozCaptureStream(); + let streamTarget = document.getElementById("streamTarget"); + originalVideo.setAttribute("loop", true); + let playingPromise = waitForEventOnce(originalVideo, "playing"); + await originalVideo.play(); + await playingPromise; + + streamTarget.srcObject = stream; + playingPromise = waitForEventOnce(streamTarget, "playing"); + await streamTarget.play(); + await playingPromise + + await withNewClone(originalVideo, async clone => { + await SpecialPowers.wrap(streamTarget).cloneElementVisually(clone); + + originalVideo.loop = false; + originalVideo.currentTime = originalVideo.duration - 0.1; + await waitForEventOnce(streamTarget, "ended"); + + ok(await assertVideosMatch(originalVideo, streamTarget), + "Should match Original video"); + ok(await assertVideosMatch(streamTarget, clone), + "Should match MediaStream"); + }); + + // Capturing a stream from a video "taints" it which prevents testing + // shutdown decoder behaviour. To avoid interfering with future tests, + // we replace the video. + let newVideo = originalVideo.cloneNode(); + originalVideo.parentNode.replaceChild(newVideo, originalVideo); +}); + +</script> + +</body> +</html> diff --git a/dom/media/test/test_cloneElementVisually_mediastream_multitrack.html b/dom/media/test/test_cloneElementVisually_mediastream_multitrack.html new file mode 100644 index 0000000000..04d1ed484c --- /dev/null +++ b/dom/media/test/test_cloneElementVisually_mediastream_multitrack.html @@ -0,0 +1,88 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test cloneElementVisually</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="https://example.com:443/tests/dom/media/test/cloneElementVisually_helpers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<div id="content"> + <h1>Originals</h1> + <div id="originalContainer"></div> + <canvas id="canvas"></canvas> + <h1>MediaStream</h1> + <div id="streamTargetContainer"></div> + <h1>Clone</h1> +</div> +<div id="results"> + <h1>Results</h1> + <canvas id="left"></canvas> + <canvas id="right"></canvas> +</div> + +<script type="application/javascript"> + +/* import-globals-from cloneElementVisually_helpers.js */ + +/** + * Test that a clone of a video that is playing a MediaStream properly tracks + * the selected video track. + */ +add_task(async () => { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.track.enabled", true], + ], + }); + + let originalVideo = document.createElement("video"); + originalVideo.id = "original"; + document.getElementById("originalContainer").appendChild(originalVideo); + + let streamTarget = document.createElement("video"); + document.getElementById("streamTargetContainer").appendChild(streamTarget); + + await setup(); + + let [track1] = originalVideo.mozCaptureStream().getTracks(); + let playingPromise = waitForEventOnce(originalVideo, "playing"); + await originalVideo.play(); + await playingPromise; + + let canvas = document.getElementById("canvas"); + canvas.width = originalVideo.videoWidth / 2; + canvas.height = originalVideo.videoHeight / 2; + let ctx = canvas.getContext("2d"); + let [track2] = canvas.captureStream().getTracks(); + ctx.fillStyle = "green"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + streamTarget.srcObject = new MediaStream([track1, track2]); + playingPromise = waitForEventOnce(streamTarget, "playing"); + await streamTarget.play(); + await playingPromise; + + await withNewClone(originalVideo, async clone => { + SpecialPowers.wrap(streamTarget).cloneElementVisually(clone); + + let selectedTrackIdx = streamTarget.videoTracks.selectedIndex; + streamTarget.videoTracks[++selectedTrackIdx % 2].selected = true; + await waitForEventOnce(streamTarget, "resize"); + + ok(await assertVideosMatch(streamTarget, clone), + "Should match MediaStream"); + }); + + // Capturing a stream from a video "taints" it which prevents testing + // shutdown decoder behaviour. To avoid interfering with future tests, + // we replace the video. + let newVideo = originalVideo.cloneNode(); + originalVideo.parentNode.replaceChild(newVideo, originalVideo); +}); + +</script> + +</body> +</html> diff --git a/dom/media/test/test_cloneElementVisually_no_suspend.html b/dom/media/test/test_cloneElementVisually_no_suspend.html new file mode 100644 index 0000000000..d576bf8ab3 --- /dev/null +++ b/dom/media/test/test_cloneElementVisually_no_suspend.html @@ -0,0 +1,90 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test cloneElementVisually</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="https://example.com:443/tests/dom/media/test/cloneElementVisually_helpers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<div id="content"> + <h1>Original</h1> + <video id="original"></video> + <h1>MediaStream</h1> + <video id="streamTarget"></video> + <h1>Clone</h1> +</div> +<div id="results"> + <h1>Results</h1> + <canvas id="left"></canvas> + <canvas id="right"></canvas> +</div> + +<script type="application/javascript"> + +/* import-globals-from cloneElementVisually_helpers.js */ + +/** + * Tests that cloning a video prevents the decoder from being suspended + * if the original video stops being visible. + */ +add_task(async () => { + await setup(); + + let originalVideo = document.getElementById("original"); + await setVideoSrc(originalVideo, LONG_VIDEO); + + await originalVideo.play(); + + // Ensure that hiding and pausing this video will cause us to + // try suspending it. + await ensureVideoSuspendable(originalVideo); + + await withNewClone(originalVideo, async clone => { + SpecialPowers.wrap(originalVideo).cloneElementVisually(clone); + + // Go back to the beginning of the video to give us enough time to + // fail to suspend the video when it's being cloned before the + // video ends. + originalVideo.removeAttribute("loop"); + originalVideo.currentTime = 0; + await waitForEventOnce(originalVideo, "seeked"); + + let suspendTimerFired = false; + + let listener = () => { + suspendTimerFired = true; + } + originalVideo.addEventListener("mozstartvideosuspendtimer", listener); + + // Have to do this to access normally-preffed off binding methods for some + // reason. + // See bug 1544257. + SpecialPowers.wrap(originalVideo).setVisible(false); + + await waitForEventOnce(originalVideo, "ended"); + + originalVideo.removeEventListener("mozstartvideosuspendtimer", listener); + + ok(!suspendTimerFired, + "mozstartvideosuspendtimer should not have fired."); + + // Have to do this to access normally-preffed off binding methods for some + // reason. + // See bug 1544257. + SpecialPowers.wrap(originalVideo).setVisible(true); + }); + + await originalVideo.play(); + + // With the clone gone, the original video should be able to suspend now. + await ensureVideoSuspendable(originalVideo); + + await setVideoSrc(originalVideo, TEST_VIDEO_1); +}); + +</script> + +</body> +</html> diff --git a/dom/media/test/test_cloneElementVisually_paused.html b/dom/media/test/test_cloneElementVisually_paused.html new file mode 100644 index 0000000000..1812becdd8 --- /dev/null +++ b/dom/media/test/test_cloneElementVisually_paused.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test cloneElementVisually</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="https://example.com:443/tests/dom/media/test/cloneElementVisually_helpers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<div id="content"> + <h1>Original</h1> + <video id="original"></video> + <h1>Clone</h1> +</div> +<div id="results"> + <h1>Results</h1> + <canvas id="left"></canvas> + <canvas id="right"></canvas> +</div> + +<script type="application/javascript"> + +/* import-globals-from cloneElementVisually_helpers.js */ + +/** + * Test that when we start cloning a paused video, the clone displays + * the first paused frame. + */ +add_task(async () => { + await setup(); + + let originalVideo = document.getElementById("original"); + await withNewClone(originalVideo, async clone => { + await SpecialPowers.wrap(originalVideo).cloneElementVisually(clone); + + ok(await assertVideosMatch(originalVideo, clone), + "Initial paused frame should match."); + }); +}); + +</script> + +</body> +</html> diff --git a/dom/media/test/test_cloneElementVisually_poster.html b/dom/media/test/test_cloneElementVisually_poster.html new file mode 100644 index 0000000000..40f60e4961 --- /dev/null +++ b/dom/media/test/test_cloneElementVisually_poster.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test cloneElementVisually with poster</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="https://example.com:443/tests/dom/media/test/cloneElementVisually_helpers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<div id="content"> + <h1>Original</h1> + <video id="original"></video> + <h1>Clone</h1> +</div> +<div id="results"> + <h1>Results</h1> + <canvas id="left"></canvas> + <canvas id="right"></canvas> +</div> + +<script type="application/javascript"> + +/* import-globals-from cloneElementVisually_helpers.js */ + +/** + * Test that when we clone a video with a poster, the poster does not prevent + * the cloned video from displaying properly (as in bug 1532692). + */ +add_task(async () => { + await setup(); + + let originalVideo = document.getElementById("original"); + const POSTER_URL = "https://example.com:443/tests/dom/media/test/poster-test.jpg"; + originalVideo.setAttribute("poster", POSTER_URL); + + await withNewClone(originalVideo, async clone => { + await SpecialPowers.wrap(originalVideo).cloneElementVisually(clone); + originalVideo.loop = false; + originalVideo.currentTime = originalVideo.duration - 0.1; + let endedPromise = waitForEventOnce(originalVideo, "ended"); + await originalVideo.play(); + await endedPromise; + + ok(await assertVideosMatch(originalVideo, clone), + "Video with a poster should clone properly."); + }); +}); + +</script> + +</body> +</html> diff --git a/dom/media/test/test_cloneElementVisually_resource_change.html b/dom/media/test/test_cloneElementVisually_resource_change.html new file mode 100644 index 0000000000..3a66906ea2 --- /dev/null +++ b/dom/media/test/test_cloneElementVisually_resource_change.html @@ -0,0 +1,67 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test cloneElementVisually</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="https://example.com:443/tests/dom/media/test/cloneElementVisually_helpers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<div id="content"> + <h1>Original</h1> + <video id="original"></video> + <h1>MediaStream</h1> + <video id="streamTarget"></video> + <h1>Clone</h1> +</div> +<div id="results"> + <h1>Results</h1> + <canvas id="left"></canvas> + <canvas id="right"></canvas> +</div> + +<script type="application/javascript"> + +/* import-globals-from cloneElementVisually_helpers.js */ + +/** + * Tests that cloning survives changes to the underlying video resource. + */ +add_task(async () => { + await setup(); + + let originalVideo = document.getElementById("original"); + originalVideo.setAttribute("loop", true); + await originalVideo.play(); + + await withNewClone(originalVideo, async clone => { + SpecialPowers.wrap(originalVideo).cloneElementVisually(clone); + + await waitForEventOnce(originalVideo, "timeupdate"); + + originalVideo.pause(); + await waitForEventOnce(originalVideo, "pause"); + + ok(await assertVideosMatch(originalVideo, clone), + "Initial video should match."); + + await setVideoSrc(originalVideo, TEST_VIDEO_2); + + await originalVideo.play(); + await waitForEventOnce(originalVideo, "timeupdate"); + + originalVideo.pause(); + await waitForEventOnce(originalVideo, "pause"); + + ok(await assertVideosMatch(originalVideo, clone), + "New video should match."); + }); + + await setVideoSrc(originalVideo, TEST_VIDEO_1); +}); + +</script> + +</body> +</html> diff --git a/dom/media/test/test_clone_media_element.html b/dom/media/test/test_clone_media_element.html new file mode 100644 index 0000000000..35e5cd69d0 --- /dev/null +++ b/dom/media/test/test_clone_media_element.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test: cloned media element should continue to play to the end even after the source of the original element is cleared</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// tests must run in sequence otherwise concurrent running test will also +// update media cache which will hide the fact media cache not updated +// after changes in media cache streams. +PARALLEL_TESTS = 1; + +function startTest(test, token) { + manager.started(token); + info("Trying to load " + token); + var v = document.createElement('video'); + v.preload = "metadata"; + v.token = token; + v.src = test.name; + + v.onloadedmetadata = function(evt) { + info(evt.target.token + " metadata loaded."); + evt.target.onloadedmetadata = null; + var clone = evt.target.cloneNode(false); + clone.token = evt.target.token; + clone.play(); + + clone.onloadstart = function(event) { + info("cloned " + event.target.token + " start loading."); + event.target.onloadstart = null; + removeNodeAndSource(v); + } + + clone.onended = function(event) { + ok(true, "cloned " + event.target.token + " ended."); + event.target.onended = null; + removeNodeAndSource(event.target); + manager.finished(event.target.token); + } + } +} + +var manager = new MediaTestManager; +manager.runTests(gSmallTests.concat(gPlayedTests), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_closing_connections.html b/dom/media/test/test_closing_connections.html new file mode 100644 index 0000000000..c5eb565447 --- /dev/null +++ b/dom/media/test/test_closing_connections.html @@ -0,0 +1,58 @@ +hg diff<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=479863 +--> +<head> + <title>Test for Bug 479863 --- loading many connections</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript" src="use_large_cache.js"></script> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=479863">Mozilla Bug 479863</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<script type="application/javascript"> +window.onload = function() { + ok(true, "loaded metadata for all videos"); + mediaTestCleanup(); + SimpleTest.finish(); +} + +/* With normal per-domain connection limits and a naive implementation, we + won't ever be able to load all these videos because the first 15 (or whatever) + will each take up one HTTP connection (which will be suspended) and then + the others will be blocked by the per-domain HTTP connection limit. We + pass this test by closing the connection for non-buffered videos after + we've got the first frame. +*/ + +var resource = getPlayableVideo(gClosingConnectionsTest); + +SimpleTest.waitForExplicitFinish(); +function beginTest() { + if (resource != null) { + for (var i=0; i<20; ++i) { + var v = document.createElement("video"); + v.src = resource.name; + v.preload = "metadata"; + document.body.appendChild(v); + } + } else { + todo(false, "No types supported"); + } +} +beginTest(); +</script> + +<pre id="test"> +<script type="application/javascript"> +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_constants.html b/dom/media/test/test_constants.html new file mode 100644 index 0000000000..1d4a8da250 --- /dev/null +++ b/dom/media/test/test_constants.html @@ -0,0 +1,228 @@ +<!DOCTYPE HTML> +<html> +<!-- + Adapted from: + http://simon.html5.org/test/html/dom/interfaces/htmlelement/htmlmediaelement/const-unsigned-short/001.htm +--> +<head> + <title>Media test: constants</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<video><source></video><audio><source></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +is(HTMLElement.NETWORK_EMPTY, undefined); +is(HTMLElement.NETWORK_IDLE, undefined); +is(HTMLElement.NETWORK_LOADING, undefined); +is(HTMLElement.NETWORK_NO_SOURCE, undefined); +is(HTMLElement.HAVE_NOTHING, undefined); +is(HTMLElement.HAVE_METADATA, undefined); +is(HTMLElement.HAVE_CURRENT_DATA, undefined); +is(HTMLElement.HAVE_FUTURE_DATA, undefined); +is(HTMLElement.HAVE_ENOUGH_DATA, undefined); +is(HTMLElement.MEDIA_ERR_ABORTED, undefined); +is(HTMLElement.MEDIA_ERR_NETWORK, undefined); +is(HTMLElement.MEDIA_ERR_DECODE, undefined); +is(HTMLElement.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(HTMLMediaElement.NETWORK_EMPTY, 0); +is(HTMLMediaElement.NETWORK_IDLE, 1); +is(HTMLMediaElement.NETWORK_LOADING, 2); +is(HTMLMediaElement.NETWORK_NO_SOURCE, 3); +is(HTMLMediaElement.HAVE_NOTHING, 0); +is(HTMLMediaElement.HAVE_METADATA, 1); +is(HTMLMediaElement.HAVE_CURRENT_DATA, 2); +is(HTMLMediaElement.HAVE_FUTURE_DATA, 3); +is(HTMLMediaElement.HAVE_ENOUGH_DATA, 4); +is(HTMLMediaElement.MEDIA_ERR_ABORTED, undefined); +is(HTMLMediaElement.MEDIA_ERR_NETWORK, undefined); +is(HTMLMediaElement.MEDIA_ERR_DECODE, undefined); +is(HTMLMediaElement.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(HTMLVideoElement.NETWORK_EMPTY, 0); +is(HTMLVideoElement.NETWORK_IDLE, 1); +is(HTMLVideoElement.NETWORK_LOADING, 2); +is(HTMLVideoElement.NETWORK_NO_SOURCE, 3); +is(HTMLVideoElement.HAVE_NOTHING, 0); +is(HTMLVideoElement.HAVE_METADATA, 1); +is(HTMLVideoElement.HAVE_CURRENT_DATA, 2); +is(HTMLVideoElement.HAVE_FUTURE_DATA, 3); +is(HTMLVideoElement.HAVE_ENOUGH_DATA, 4); +is(HTMLVideoElement.MEDIA_ERR_ABORTED, undefined); +is(HTMLVideoElement.MEDIA_ERR_NETWORK, undefined); +is(HTMLVideoElement.MEDIA_ERR_DECODE, undefined); +is(HTMLVideoElement.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(HTMLAudioElement.NETWORK_EMPTY, 0); +is(HTMLAudioElement.NETWORK_IDLE, 1); +is(HTMLAudioElement.NETWORK_LOADING, 2); +is(HTMLAudioElement.NETWORK_NO_SOURCE, 3); +is(HTMLAudioElement.HAVE_NOTHING, 0); +is(HTMLAudioElement.HAVE_METADATA, 1); +is(HTMLAudioElement.HAVE_CURRENT_DATA, 2); +is(HTMLAudioElement.HAVE_FUTURE_DATA, 3); +is(HTMLAudioElement.HAVE_ENOUGH_DATA, 4); +is(HTMLAudioElement.MEDIA_ERR_ABORTED, undefined); +is(HTMLAudioElement.MEDIA_ERR_NETWORK, undefined); +is(HTMLAudioElement.MEDIA_ERR_DECODE, undefined); +is(HTMLAudioElement.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(HTMLSourceElement.NETWORK_EMPTY, undefined); +is(HTMLSourceElement.NETWORK_IDLE, undefined); +is(HTMLSourceElement.NETWORK_LOADING, undefined); +is(HTMLSourceElement.NETWORK_NO_SOURCE, undefined); +is(HTMLSourceElement.HAVE_NOTHING, undefined); +is(HTMLSourceElement.HAVE_METADATA, undefined); +is(HTMLSourceElement.HAVE_CURRENT_DATA, undefined); +is(HTMLSourceElement.HAVE_FUTURE_DATA, undefined); +is(HTMLSourceElement.HAVE_ENOUGH_DATA, undefined); +is(HTMLSourceElement.MEDIA_ERR_ABORTED, undefined); +is(HTMLSourceElement.MEDIA_ERR_NETWORK, undefined); +is(HTMLSourceElement.MEDIA_ERR_DECODE, undefined); +is(HTMLSourceElement.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(MediaError.NETWORK_EMPTY, undefined); +is(MediaError.NETWORK_IDLE, undefined); +is(MediaError.NETWORK_LOADING, undefined); +is(MediaError.NETWORK_NO_SOURCE, undefined); +is(MediaError.HAVE_NOTHING, undefined); +is(MediaError.HAVE_METADATA, undefined); +is(MediaError.HAVE_CURRENT_DATA, undefined); +is(MediaError.HAVE_FUTURE_DATA, undefined); +is(MediaError.HAVE_ENOUGH_DATA, undefined); +is(MediaError.MEDIA_ERR_ABORTED, 1); +is(MediaError.MEDIA_ERR_NETWORK, 2); +is(MediaError.MEDIA_ERR_DECODE, 3); +is(MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, 4); +is(document.body.NETWORK_EMPTY, undefined); +is(document.body.NETWORK_IDLE, undefined); +is(document.body.NETWORK_LOADING, undefined); +is(document.body.NETWORK_NO_SOURCE, undefined); +is(document.body.HAVE_NOTHING, undefined); +is(document.body.HAVE_METADATA, undefined); +is(document.body.HAVE_CURRENT_DATA, undefined); +is(document.body.HAVE_FUTURE_DATA, undefined); +is(document.body.HAVE_ENOUGH_DATA, undefined); +is(document.body.MEDIA_ERR_ABORTED, undefined); +is(document.body.MEDIA_ERR_NETWORK, undefined); +is(document.body.MEDIA_ERR_DECODE, undefined); +is(document.body.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(document.getElementsByTagName("video")[0].NETWORK_EMPTY, 0); +is(document.getElementsByTagName("video")[0].NETWORK_IDLE, 1); +is(document.getElementsByTagName("video")[0].NETWORK_LOADING, 2); +is(document.getElementsByTagName("video")[0].NETWORK_NO_SOURCE, 3); +is(document.getElementsByTagName("video")[0].HAVE_NOTHING, 0); +is(document.getElementsByTagName("video")[0].HAVE_METADATA, 1); +is(document.getElementsByTagName("video")[0].HAVE_CURRENT_DATA, 2); +is(document.getElementsByTagName("video")[0].HAVE_FUTURE_DATA, 3); +is(document.getElementsByTagName("video")[0].HAVE_ENOUGH_DATA, 4); +is(document.getElementsByTagName("video")[0].MEDIA_ERR_ABORTED, undefined); +is(document.getElementsByTagName("video")[0].MEDIA_ERR_NETWORK, undefined); +is(document.getElementsByTagName("video")[0].MEDIA_ERR_DECODE, undefined); +is(document.getElementsByTagName("video")[0].MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(document.getElementsByTagName("audio")[0].NETWORK_EMPTY, 0); +is(document.getElementsByTagName("audio")[0].NETWORK_IDLE, 1); +is(document.getElementsByTagName("audio")[0].NETWORK_LOADING, 2); +is(document.getElementsByTagName("audio")[0].NETWORK_NO_SOURCE, 3); +is(document.getElementsByTagName("audio")[0].HAVE_NOTHING, 0); +is(document.getElementsByTagName("audio")[0].HAVE_METADATA, 1); +is(document.getElementsByTagName("audio")[0].HAVE_CURRENT_DATA, 2); +is(document.getElementsByTagName("audio")[0].HAVE_FUTURE_DATA, 3); +is(document.getElementsByTagName("audio")[0].HAVE_ENOUGH_DATA, 4); +is(document.getElementsByTagName("audio")[0].MEDIA_ERR_ABORTED, undefined); +is(document.getElementsByTagName("audio")[0].MEDIA_ERR_NETWORK, undefined); +is(document.getElementsByTagName("audio")[0].MEDIA_ERR_DECODE, undefined); +is(document.getElementsByTagName("audio")[0].MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(document.getElementsByTagName("source")[0].NETWORK_EMPTY, undefined); +is(document.getElementsByTagName("source")[0].NETWORK_IDLE, undefined); +is(document.getElementsByTagName("source")[0].NETWORK_LOADING, undefined); +is(document.getElementsByTagName("source")[0].NETWORK_NO_SOURCE, undefined); +is(document.getElementsByTagName("source")[0].HAVE_NOTHING, undefined); +is(document.getElementsByTagName("source")[0].HAVE_METADATA, undefined); +is(document.getElementsByTagName("source")[0].HAVE_CURRENT_DATA, undefined); +is(document.getElementsByTagName("source")[0].HAVE_FUTURE_DATA, undefined); +is(document.getElementsByTagName("source")[0].HAVE_ENOUGH_DATA, undefined); +is(document.getElementsByTagName("source")[0].MEDIA_ERR_ABORTED, undefined); +is(document.getElementsByTagName("source")[0].MEDIA_ERR_NETWORK, undefined); +is(document.getElementsByTagName("source")[0].MEDIA_ERR_DECODE, undefined); +is(document.getElementsByTagName("source")[0].MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(HTMLElement.prototype.NETWORK_EMPTY, undefined); +is(HTMLElement.prototype.NETWORK_IDLE, undefined); +is(HTMLElement.prototype.NETWORK_LOADING, undefined); +is(HTMLElement.prototype.NETWORK_NO_SOURCE, undefined); +is(HTMLElement.prototype.HAVE_NOTHING, undefined); +is(HTMLElement.prototype.HAVE_METADATA, undefined); +is(HTMLElement.prototype.HAVE_CURRENT_DATA, undefined); +is(HTMLElement.prototype.HAVE_FUTURE_DATA, undefined); +is(HTMLElement.prototype.HAVE_ENOUGH_DATA, undefined); +is(HTMLElement.prototype.MEDIA_ERR_ABORTED, undefined); +is(HTMLElement.prototype.MEDIA_ERR_NETWORK, undefined); +is(HTMLElement.prototype.MEDIA_ERR_DECODE, undefined); +is(HTMLElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(HTMLMediaElement.prototype.NETWORK_EMPTY, 0, "HTMLMediaElement.prototype.NETWORK_EMPTY"); +is(HTMLMediaElement.prototype.NETWORK_IDLE, 1, "HTMLMediaElement.prototype.NETWORK_IDLE"); +is(HTMLMediaElement.prototype.NETWORK_LOADING, 2, "HTMLMediaElement.prototype.NETWORK_LOADING"); +is(HTMLMediaElement.prototype.NETWORK_NO_SOURCE, 3, "HTMLMediaElement.prototype.NETWORK_NO_SOURCE"); +is(HTMLMediaElement.prototype.HAVE_NOTHING, 0, "HTMLMediaElement.prototype.HAVE_NOTHING"); +is(HTMLMediaElement.prototype.HAVE_METADATA, 1, "HTMLMediaElement.prototype.HAVE_METADATA"); +is(HTMLMediaElement.prototype.HAVE_CURRENT_DATA, 2, "HTMLMediaElement.prototype.HAVE_CURRENT_DATA"); +is(HTMLMediaElement.prototype.HAVE_FUTURE_DATA, 3, "HTMLMediaElement.prototype.HAVE_FUTURE_DATA"); +is(HTMLMediaElement.prototype.HAVE_ENOUGH_DATA, 4, "HTMLMediaElement.prototype.HAVE_ENOUGH_DATA"); +is(HTMLMediaElement.prototype.MEDIA_ERR_ABORTED, undefined, "HTMLMediaElement.prototype.MEDIA_ERR_ABORTED"); +is(HTMLMediaElement.prototype.MEDIA_ERR_NETWORK, undefined, "HTMLMediaElement.prototype.MEDIA_ERR_NETWORK"); +is(HTMLMediaElement.prototype.MEDIA_ERR_DECODE, undefined, "HTMLMediaElement.prototype.MEDIA_ERR_DECODE"); +is(HTMLMediaElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined, "HTMLMediaElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED"); +is(HTMLVideoElement.prototype.NETWORK_EMPTY, 0); +is(HTMLVideoElement.prototype.NETWORK_IDLE, 1); +is(HTMLVideoElement.prototype.NETWORK_LOADING, 2); +is(HTMLVideoElement.prototype.NETWORK_NO_SOURCE, 3); +is(HTMLVideoElement.prototype.HAVE_NOTHING, 0); +is(HTMLVideoElement.prototype.HAVE_METADATA, 1); +is(HTMLVideoElement.prototype.HAVE_CURRENT_DATA, 2); +is(HTMLVideoElement.prototype.HAVE_FUTURE_DATA, 3); +is(HTMLVideoElement.prototype.HAVE_ENOUGH_DATA, 4); +is(HTMLVideoElement.prototype.MEDIA_ERR_ABORTED, undefined); +is(HTMLVideoElement.prototype.MEDIA_ERR_NETWORK, undefined); +is(HTMLVideoElement.prototype.MEDIA_ERR_DECODE, undefined); +is(HTMLVideoElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(HTMLAudioElement.prototype.NETWORK_EMPTY, 0); +is(HTMLAudioElement.prototype.NETWORK_IDLE, 1); +is(HTMLAudioElement.prototype.NETWORK_LOADING, 2); +is(HTMLAudioElement.prototype.NETWORK_NO_SOURCE, 3); +is(HTMLAudioElement.prototype.HAVE_NOTHING, 0); +is(HTMLAudioElement.prototype.HAVE_METADATA, 1); +is(HTMLAudioElement.prototype.HAVE_CURRENT_DATA, 2); +is(HTMLAudioElement.prototype.HAVE_FUTURE_DATA, 3); +is(HTMLAudioElement.prototype.HAVE_ENOUGH_DATA, 4); +is(HTMLAudioElement.prototype.MEDIA_ERR_ABORTED, undefined); +is(HTMLAudioElement.prototype.MEDIA_ERR_NETWORK, undefined); +is(HTMLAudioElement.prototype.MEDIA_ERR_DECODE, undefined); +is(HTMLAudioElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(HTMLSourceElement.prototype.NETWORK_EMPTY, undefined); +is(HTMLSourceElement.prototype.NETWORK_IDLE, undefined); +is(HTMLSourceElement.prototype.NETWORK_LOADING, undefined); +is(HTMLSourceElement.prototype.NETWORK_NO_SOURCE, undefined); +is(HTMLSourceElement.prototype.HAVE_NOTHING, undefined); +is(HTMLSourceElement.prototype.HAVE_METADATA, undefined); +is(HTMLSourceElement.prototype.HAVE_CURRENT_DATA, undefined); +is(HTMLSourceElement.prototype.HAVE_FUTURE_DATA, undefined); +is(HTMLSourceElement.prototype.HAVE_ENOUGH_DATA, undefined); +is(HTMLSourceElement.prototype.MEDIA_ERR_ABORTED, undefined); +is(HTMLSourceElement.prototype.MEDIA_ERR_NETWORK, undefined); +is(HTMLSourceElement.prototype.MEDIA_ERR_DECODE, undefined); +is(HTMLSourceElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined); +is(MediaError.prototype.NETWORK_EMPTY, undefined); +is(MediaError.prototype.NETWORK_IDLE, undefined); +is(MediaError.prototype.NETWORK_LOADING, undefined); +is(MediaError.prototype.NETWORK_NO_SOURCE, undefined); +is(MediaError.prototype.HAVE_NOTHING, undefined); +is(MediaError.prototype.HAVE_METADATA, undefined); +is(MediaError.prototype.HAVE_CURRENT_DATA, undefined); +is(MediaError.prototype.HAVE_FUTURE_DATA, undefined); +is(MediaError.prototype.HAVE_ENOUGH_DATA, undefined); +is(MediaError.prototype.MEDIA_ERR_ABORTED, 1); +is(MediaError.prototype.MEDIA_ERR_NETWORK, 2); +is(MediaError.prototype.MEDIA_ERR_DECODE, 3); +is(MediaError.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED, 4); +ok(document.getElementsByTagName("video")[0].buffered instanceof TimeRanges, "video.buffered must be TimeRanges object"); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_controls.html b/dom/media/test/test_controls.html new file mode 100644 index 0000000000..5c9015fdf2 --- /dev/null +++ b/dom/media/test/test_controls.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: controls</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<video id='v1'></video><audio id='a1'></audio> +<video id='v2' controls></video><audio id='a2' controls></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var v1 = document.getElementById('v1'); +var a1 = document.getElementById('a1'); +var v2 = document.getElementById('v2'); +var a2 = document.getElementById('a2'); +ok(!v1.controls, "v1.controls should be false by default"); +ok(!a1.controls, "v1.controls should be false by default"); +ok(v2.controls, "v2.controls should be true"); +ok(a2.controls, "v2.controls should be true"); +v2.controls=false; +a2.controls=false; +ok(!v2.controls, "v2.controls should be false"); +ok(!a2.controls, "a2.controls should be false"); +v2.controls=true; +a2.controls=true; +ok(v2.controls, "v2.controls should be true"); +ok(a2.controls, "a2.controls should be true"); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_cueless_webm_seek-1.html b/dom/media/test/test_cueless_webm_seek-1.html new file mode 100644 index 0000000000..db58a89665 --- /dev/null +++ b/dom/media/test/test_cueless_webm_seek-1.html @@ -0,0 +1,136 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=657791 +--> +<head> + <title>Test for Bug 657791</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=657791">Mozilla Bug 657791</a> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +// Subset of seek tests for cueless WebMs. When random seeking (rather than just +// in buffered ranges) is implemented for WebM, these tests can be removed and +// the cueless WebM(s) references can be moved to the general test_seek test +// array. +// Test array is defined in manifest.js + +var manager = new MediaTestManager; + +// Exercise functionality as in test_seek-1 +function testWebM1(e) { + var v = e.target; + v.removeEventListener('loadeddata', testWebM1); + + var startPassed = false; + var endPassed = false; + var seekFlagStart = false; + var seekFlagEnd = false; + var readonly = true; + var completed = false; + + ok(v.buffered.length >= 1, "Should have a buffered range"); + var halfBuffered = v.buffered.end(0) / 2; + + function start() { + is(v.seekable.start(0), v.buffered.start(0), "Seekable start should be buffered start"); + is(v.seekable.end(0), v.buffered.end(0), "Seekable end should be buffered end"); + ok(!completed, "Should not be completed yet"); + ok(!v.seeking, "seeking should default to false"); + try { + v.seeking = true; + readonly = v.seeking === false; + } + catch(ex) { + readonly = "threw exception: " + ex; + } + is(readonly, true, "seeking should be readonly"); + + v.currentTime = halfBuffered; + seekFlagStart = v.seeking; + } + + function seekStarted() { + ok(!completed, "should not be completed yet"); + startPassed = true; + } + + function seekEnded() { + ok(!completed, "should not be completed yet"); + ok(Math.abs(v.currentTime - halfBuffered) < 0.1, + "Video currentTime should be around " + halfBuffered + ": " + v.currentTime + " (seeked)"); + endPassed = true; + seekFlagEnd = v.seeking; + v.play(); + } + + function playbackEnded() { + ok(!completed, "should not be completed yet"); + + completed = true; + ok(startPassed, "seeking event"); + ok(endPassed, "seeked event"); + ok(seekFlagStart, "seeking flag on start should be true"); + ok(!seekFlagEnd, "seeking flag on end should be false"); + removeNodeAndSource(v); + manager.finished(v._token); + } + + once(v, "ended", playbackEnded); + once(v, "seeking", seekStarted); + once(v, "seeked", seekEnded); + + start(); +} + +// Fetch the media resource using XHR so we can be sure the entire +// resource is loaded before we test buffered ranges. This ensures +// we have deterministic behaviour. +function fetch(url, fetched_callback) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); + xhr.responseType = "blob"; + + var loaded = function (event) { + if (xhr.status == 200 || xhr.status == 206) { + // Request fulfilled. Note sometimes we get 206... Presumably because either + // httpd.js or Necko cached the result. + fetched_callback(window.URL.createObjectURL(xhr.response)); + } else { + ok(false, "Fetch failed headers=" + xhr.getAllResponseHeaders()); + } + }; + + xhr.addEventListener("load", loaded); + xhr.send(); +} + +function startTest(test, token) { + var onfetched = function(uri) { + var v = document.createElement('video'); + v._token = token; + v.src = uri; + v.addEventListener("loadeddata", testWebM1); + document.body.appendChild(v); + } + manager.started(token); + fetch(test.name, onfetched); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gCuelessWebMTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_cueless_webm_seek-2.html b/dom/media/test/test_cueless_webm_seek-2.html new file mode 100644 index 0000000000..720cc18399 --- /dev/null +++ b/dom/media/test/test_cueless_webm_seek-2.html @@ -0,0 +1,126 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=657791 +--> +<head> + <title>Test for Bug 657791</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=657791">Mozilla Bug 657791</a> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +// Subset of seek tests for cueless WebMs. When random seeking (rather than just +// in buffered ranges) is implemented for WebM, these tests can be removed and +// the cueless WebM(s) references can be moved to the general test_seek test +// array. +// Test array is defined in manifest.js + +var manager = new MediaTestManager; + +// Exercise functionality as in test_seek-2 +function testWebM2(e) { + var v = e.target; + v.removeEventListener('loadeddata', testWebM2); + + var startPassed = false; + var endPassed = false; + var completed = false; + + ok(v.buffered.length >= 1, "Should have a buffered range"); + var halfBuffered = v.buffered.end(0) / 2; + + function start() { + if (completed) + return; + + is(v.seekable.start(0), v.buffered.start(0), "Seekable start should be buffered start"); + is(v.seekable.end(0), v.buffered.end(0), "Seekable end should be buffered end"); + v.currentTime=halfBuffered; + v.play(); + } + + function seekStarted() { + if (completed) + return; + + startPassed = true; + } + + function seekEnded() { + if (completed) + return; + + endPassed = true; + } + + function playbackEnded() { + if (completed) + return; + + completed = true; + ok(startPassed, "send seeking event"); + ok(endPassed, "send seeked event"); + ok(v.ended, "Checking playback has ended"); + ok(Math.abs(v.currentTime - v.duration) <= 0.1, "Checking currentTime at end: " + v.currentTime); + removeNodeAndSource(v); + manager.finished(v._token); + } + + v.addEventListener("ended", playbackEnded); + v.addEventListener("seeking", seekStarted); + v.addEventListener("seeked", seekEnded); + + start(); +} + +// Fetch the media resource using XHR so we can be sure the entire +// resource is loaded before we test buffered ranges. This ensures +// we have deterministic behaviour. +function fetch(url, fetched_callback) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); + xhr.responseType = "blob"; + + var loaded = function (event) { + if (xhr.status == 200 || xhr.status == 206) { + // Request fulfilled. Note sometimes we get 206... Presumably because either + // httpd.js or Necko cached the result. + fetched_callback(window.URL.createObjectURL(xhr.response)); + } else { + ok(false, "Fetch failed headers=" + xhr.getAllResponseHeaders()); + } + }; + + xhr.addEventListener("load", loaded); + xhr.send(); +} + +function startTest(test, token) { + var onfetched = function(uri) { + var v = document.createElement('video'); + v._token = token; + v.src = uri; + v.addEventListener("loadeddata", testWebM2); + document.body.appendChild(v); + } + manager.started(token); + fetch(test.name, onfetched); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gCuelessWebMTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_cueless_webm_seek-3.html b/dom/media/test/test_cueless_webm_seek-3.html new file mode 100644 index 0000000000..d6e3e50d7d --- /dev/null +++ b/dom/media/test/test_cueless_webm_seek-3.html @@ -0,0 +1,120 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=657791 +--> +<head> + <title>Test for Bug 657791</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=657791">Mozilla Bug 657791</a> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +// Subset of seek tests for cueless WebMs. When random seeking (rather than just +// in buffered ranges) is implemented for WebM, these tests can be removed and +// the cueless WebM(s) references can be moved to the general test_seek test +// array. +// Test array is defined in manifest.js + +var manager = new MediaTestManager; + +// Exercise functionality as in test_seek-3 +function testWebM3(e) { + var v = e.target; + v.removeEventListener('loadeddata', testWebM3); + + var completed = false; + var gotTimeupdate = false; + + ok(v.buffered.length >= 1, "Should have a buffered range"); + var halfBuffered = v.buffered.end(0) / 2; + + function start() { + if (completed) + return; + + is(v.seekable.start(0), v.buffered.start(0), "Seekable start should be buffered start"); + is(v.seekable.end(0), v.buffered.end(0), "Seekable end should be buffered end"); + v.currentTime=halfBuffered; + } + + function timeupdate() { + gotTimeupdate = true; + v.removeEventListener("timeupdate", timeupdate); + } + + function seekStarted() { + if (completed) + return; + + v.addEventListener("timeupdate", timeupdate); + } + + function seekEnded() { + if (completed) + return; + + var t = v.currentTime; + ok(Math.abs(t - halfBuffered) <= 0.1, "Video currentTime should be around " + halfBuffered + ": " + t); + ok(gotTimeupdate, "Should have got timeupdate between seeking and seekended"); + completed = true; + removeNodeAndSource(v); + manager.finished(v._token); + } + + v.addEventListener("seeking", seekStarted); + v.addEventListener("seeked", seekEnded); + + start() +} + +// Fetch the media resource using XHR so we can be sure the entire +// resource is loaded before we test buffered ranges. This ensures +// we have deterministic behaviour. +function fetch(url, fetched_callback) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); + xhr.responseType = "blob"; + + var loaded = function (event) { + if (xhr.status == 200 || xhr.status == 206) { + // Request fulfilled. Note sometimes we get 206... Presumably because either + // httpd.js or Necko cached the result. + fetched_callback(window.URL.createObjectURL(xhr.response)); + } else { + ok(false, "Fetch failed headers=" + xhr.getAllResponseHeaders()); + } + }; + + xhr.addEventListener("load", loaded); + xhr.send(); +} + +function startTest(test, token) { + var onfetched = function(uri) { + var v = document.createElement('video'); + v._token = token; + v.src = uri; + v.addEventListener("loadeddata", testWebM3); + document.body.appendChild(v); + } + manager.started(token); + fetch(test.name, onfetched); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gCuelessWebMTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_currentTime.html b/dom/media/test/test_currentTime.html new file mode 100644 index 0000000000..b38c8c2c53 --- /dev/null +++ b/dom/media/test/test_currentTime.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: currentTime</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<video id='v1'></video><audio id='a1'></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var v1 = document.getElementById('v1'); +var a1 = document.getElementById('a1'); +is(v1.currentTime, 0.0); +is(a1.currentTime, 0.0); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_debug_data_helpers.html b/dom/media/test/test_debug_data_helpers.html new file mode 100644 index 0000000000..f96aafc09b --- /dev/null +++ b/dom/media/test/test_debug_data_helpers.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> +<head> +<title>Test the special debug APIs give expected data</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +<script type="text/javascript" src="manifest.js"></script> +<script class="testbody" type="text/javascript"> +add_task(async function testMozRequestDebugInfo() { + let video = document.createElement("video"); + video.src = "gizmo.mp4"; + document.body.appendChild(video); + await video.play(); + let debugData = await SpecialPowers.wrap(video).mozRequestDebugInfo(); + // Verify various members are present and as expected. + ok(debugData, "Should get some debug data"); + ok(debugData.decoder.hasAudio, "Should have audio"); + ok(debugData.decoder.hasVideo, "Should have video"); + is( + debugData.decoder.reader.videoWidth, + 560, + "Video should have expected width" + ); + is( + debugData.decoder.reader.videoHeight, + 320, + "Video should have expected height" + ); + ok( + debugData.decoder.stateMachine.mediaTime >= 0, + "Media time should be positive" + ); + removeNodeAndSource(video); +}); + +add_task(async function testMozDebugReaderData() { + let video = document.createElement("video"); + let mediaSource = new MediaSource(); + video.src = URL.createObjectURL(mediaSource); + await once(mediaSource, "sourceopen"); + const sourceBuffer = mediaSource.addSourceBuffer("video/webm"); + let fetchResponse = await fetch("bipbop_short_vp8.webm"); + sourceBuffer.appendBuffer(await fetchResponse.arrayBuffer()); + await once(sourceBuffer, "updateend"); + mediaSource.endOfStream(); + await once(mediaSource, "sourceended"); + document.body.appendChild(video); + await video.play(); + let debugData = await SpecialPowers.wrap(mediaSource).mozDebugReaderData(); + // Verify various members are present and as expected. + ok(debugData, "Should get some debug data"); + is(debugData.reader.videoWidth, 400, "Video should have expected width"); + is(debugData.reader.videoHeight, 300, "Video should have expected height"); + ok( + debugData.demuxer.audioTrack.numSamples > 0, + "Audio track should have demuxed some samples" + ); + ok( + debugData.demuxer.audioTrack.ranges.length, + "Audio track should have some buffered range" + ); + ok( + debugData.demuxer.videoTrack.numSamples > 0, + "Video track should have demuxed some samples" + ); + ok( + debugData.demuxer.videoTrack.ranges.length, + "Video track should have some buffered range" + ); + removeNodeAndSource(video); +}); +</script> +</head> +</html> diff --git a/dom/media/test/test_decode_error.html b/dom/media/test/test_decode_error.html new file mode 100644 index 0000000000..27b83cd3f9 --- /dev/null +++ b/dom/media/test/test_decode_error.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: unknown/invalid formats raise decode error</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function startTest(test, token) { + var ok = function (condition, name) { + SimpleTest.ok(condition, test.name + ": " + name); + } + var is = function (a, b, name) { + SimpleTest.is(a, b, test.name + ": " + name); + } + + var v = document.createElement("video"); + manager.started(token); + v.addEventListener("error", function (event) { + var el = event.currentTarget; + is(event.type, "error", "Expected event of type 'error'"); + ok(el.error, "Element 'error' attr expected to have a value"); + ok(el.error instanceof MediaError, "Element 'error' attr expected to be MediaError"); + if (v.readyState == v.HAVE_NOTHING) { + is(el.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, "Expected media not supported error"); + } else { + is(el.error.code, MediaError.MEDIA_ERR_DECODE, "Expected a decode error"); + } + ok(typeof el.error.message === 'string' || el.error.message instanceof String, "Element 'message' attr expected to be a string"); + ok(el.error.message.length, "Element 'message' attr has content"); + el._sawError = true; + manager.finished(token); + }); + + v.addEventListener("loadeddata", function () { + ok(false, "Unexpected loadeddata event"); + manager.finished(token); + }); + + v.autoplay = true; + v.addEventListener("ended", function () { + ok(false, "Unexpected ended event"); + manager.finished(token); + }); + + v.src = test.name; // implicitly starts a load. +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({ + "set": [ + ["media.cache_size", 40000], + ] +}, beginTest); +function beginTest() { + manager.runTests(gDecodeErrorTests, startTest); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_decode_error_crossorigin.html b/dom/media/test/test_decode_error_crossorigin.html new file mode 100644 index 0000000000..24c1430a5b --- /dev/null +++ b/dom/media/test/test_decode_error_crossorigin.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Invalid formats raise decode errors with default messages for CORS cross-origin media</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +const manager = new MediaTestManager; +let gotErrSrcNotSupported = false; +let gotErrDecode = false; + +function startTest(test, token) { + const is = function(a, b, name) { + SimpleTest.is(a, b, `${test.name}: ${name}`); + }; + const v = document.createElement("video"); + manager.started(token); + v.addEventListener("error", event => { + if (v.readyState == v.HAVE_NOTHING) { + is(v.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, + "Expected code for a load error"); + is(v.error.message, "Failed to open media", + "Expected message for a load error"); + gotErrSrcNotSupported = true; + } else { + is(v.error.code, MediaError.MEDIA_ERR_DECODE, + "Expected code for a decode error"); + is(v.error.message, "Failed to decode media", + "Expected message for a decode error"); + gotErrDecode = true; + } + manager.finished(token); + }); + + v.autoplay = true; + + // CORS-cross-origin URL. + v.src = `http://example.com/tests/dom/media/test/${test.name}`; +} + +gTestPrefs.push(["media.cache_size", 40000]); +manager.onFinished = () => { + ok(gotErrSrcNotSupported, "At least one test led to src-not-supported"); + ok(gotErrDecode, "At least one test led to a decode error"); +}; +manager.runTests(gErrorTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_decoder_disable.html b/dom/media/test/test_decoder_disable.html new file mode 100644 index 0000000000..dd0d2cc51b --- /dev/null +++ b/dom/media/test/test_decoder_disable.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=448600 +--> +<head> + <title>Test for Bug 448600</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=448600">Mozilla Bug 448600</a> +<p id="display"></p> + + +<pre id="test"> +<script type="application/javascript"> + +function filename(uri) { + return uri.substr(uri.lastIndexOf("/")+1); +} + +function e(id) { + return document.getElementById(id); +} + +var gLoadError = {}; + +gLoadError.video1 = 0; +gLoadError.video2 = 0; +gLoadError.video3 = 0; + +var gErrorCount = 0; + +SimpleTest.waitForExplicitFinish(); + +function finishTest() { + is(e('video1').currentSrc, + "", + 'video1 currentSrc should be empty when there\'s no playable typed source children'); + is(filename(e('video2').currentSrc), + filename(e('video2').src), + 'video2 currentSrc should match src'); + is(filename(e('video3').currentSrc), + filename(e('video3').src), + 'video3 currentSrc should match src'); + + is(gLoadError.video1, 2, "Expect one error per invalid source child on video1"); + is(gLoadError.video2, 1, "Expect one error on video2"); + is(gLoadError.video3, 1, "Expect one error on video3"); + + SimpleTest.finish(); +} + +function videoError(event, id) { + gLoadError[id]++; + gErrorCount++; + if (gErrorCount >= 4) { + finishTest(); + } +} + +</script> +<!-- We make the resource URIs unique to ensure that they are (re)loaded with the new disable-decoder prefs. --> +<div id="content"> +</div> +<script> +function makeVideos() { + document.getElementById('content').innerHTML = '<video id="video1" preload="metadata"><source type="video/ogg" src="320x240.ogv?decoder_disabled=1" onerror="videoError(event, \'video1\');"/><source type="audio/wave" src="r11025_u8_c1.wav?decoder_disabled=1" id=\'s2\' onerror="videoError(event, \'video1\');"/></video><video id="video2" preload="metadata" src="320x240.ogv?decoder_disabled=2" onerror="videoError(event, \'video2\');"></video><video id="video3" preload="metadata" src="r11025_u8_c1.wav?decoder_disabled=2" onerror="videoError(event, \'video3\');"></video>'; +} + +SpecialPowers.pushPrefEnv({"set": [["media.ogg.enabled", false], ["media.wave.enabled", false]]}, makeVideos); +</script> + +</pre> + +</body> +</html> diff --git a/dom/media/test/test_defaultMuted.html b/dom/media/test/test_defaultMuted.html new file mode 100644 index 0000000000..77bfa3d29a --- /dev/null +++ b/dom/media/test/test_defaultMuted.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: defaultMuted</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="../../../dom/html/test/reflect.js"></script> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=706731">Mozilla Bug 706731</a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <video id='v1'></video><audio id='a1'></audio> + <video id='v2' muted></video><audio id='a2' muted></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> + reflectBoolean({ + element: document.createElement("video"), + attribute: { content: "muted", idl: "defaultMuted" }, + }); + + reflectBoolean({ + element: document.createElement("audio"), + attribute: { content: "muted", idl: "defaultMuted" }, + }); + + var v1 = document.getElementById('v1'); + var a1 = document.getElementById('a1'); + var v2 = document.getElementById('v2'); + var a2 = document.getElementById('a2'); + + // Check that muted state correspond to the default value. + is(v1.muted, false, "v1.muted should be false by default"); + is(a1.muted, false, "a1.muted should be false by default"); + is(v2.muted, true, "v2.muted should be true by default"); + is(a2.muted, true, "a2.muted should be true by default"); + + // Changing defaultMuted value should not change current muted state. + v1.defaultMuted = true; + a1.defaultMuted = true; + v2.defaultMuted = false; + a2.defaultMuted = false; + + is(v1.muted, false, "v1.muted should not have changed"); + is(a1.muted, false, "a1.muted should not have changed"); + is(v2.muted, true, "v2.muted should not have changed"); + is(a2.muted, true, "a2.muted should not have changed"); + + mediaTestCleanup(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_delay_load.html b/dom/media/test/test_delay_load.html new file mode 100644 index 0000000000..05877aa911 --- /dev/null +++ b/dom/media/test/test_delay_load.html @@ -0,0 +1,108 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=479711 +--> +<head> + <title>Test for Bug 479711</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> + <script> + + var gRegisteredElements = []; + var testWindows = []; + + function register(v) { + gRegisteredElements.push(v); + } + + function loaded() { + info("onload fired!"); + + for (var i = 0; i < gRegisteredElements.length; ++i) { + var v = gRegisteredElements[i]; + ok(v.readyState >= v.HAVE_CURRENT_DATA, + v._name + ":" + v.id + " is not ready before onload fired (" + v.readyState + ")"); + } + + for (i=0; i<testWindows.length; ++i) { + testWindows[i].close(); + } + + mediaTestCleanup(); + + SimpleTest.finish(); + } + + addLoadEvent(loaded); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=479711">Mozilla Bug 479711</a> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 479711 **/ + +function createVideo(name, type, id) { + var v = document.createElement("video"); + v.preload = "metadata"; + // Make sure each video is a unique resource + v.src = name + "?" + id; + v._name = name; + v.id = id; + register(v); + return v; +} + +var test = getPlayableVideo(gSmallTests); + +// Straightforward add, causing a load. +var v = createVideo(test.name, test.type, "1"); +document.body.appendChild(v); + +// Load, add, then remove. +v = createVideo(test.name, test.type, "1"); +v.load(); +document.body.appendChild(v); +v.remove(); + +// Load and add. +v = createVideo(test.name, test.type, "2"); +v.load(); +document.body.appendChild(v); + +// Load outside of doc. +v = createVideo(test.name, test.type, "3"); +v.load(); + +// Open a new window for the following test. We open it here instead of in +// the event handler to ensure that our document load event doesn't fire while +// window.open is spinning the event loop. +var w = window.open("", "testWindow", "width=400,height=400"); +testWindows.push(w); + +v = createVideo(test.name, test.type, "4"); +v.onloadstart = function(e) { + // Using a new window to do this is a bit annoying, but if we use an iframe here, + // delaying of the iframe's load event might interfere with the firing of our load event + // in some confusing way. So it's simpler just to use another window. + w.document.body.appendChild(v); +}; +v.load(); // load started while in this document, this doc's load will block until + // the video's finished loading (in the other document). + +if (gRegisteredElements.length) { + SimpleTest.waitForExplicitFinish(); +} else { + todo(false, "No types supported"); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_duration_after_error.html b/dom/media/test/test_duration_after_error.html new file mode 100644 index 0000000000..ad6bbe414f --- /dev/null +++ b/dom/media/test/test_duration_after_error.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test playback of media files that should have errors</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function checkDuration(name, e, test) { + if (test.duration) { + ok(Math.abs(e.duration - test.duration) < 0.1, + name + " duration (" + e.duration + ") should be around " + test.duration); + } else { + ok(false, "Test doesn't include the duration field!") + } +} + +function startTest(test, token) { + manager.started(token); + + let v = document.createElement('video'); + v._loadedMetadata = false; + let name = test.name; + + v.onloadedmetadata = function() { + v.onloadedmetadata = null; + v._loadedMetadata = true; + ok(v._loadedMetadata , name + " has loaded metadata."); + } + + v.onerror = function() { + v.onerror = null; + ok(v._loadedMetadata , name + " should load metadata before getting error."); + checkDuration(name, v, test); + manager.finished(token); + } + + v.src = name; + document.body.appendChild(v); + v.play(); +} + +manager.runTests(gDurationTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_autoplay.html b/dom/media/test/test_eme_autoplay.html new file mode 100644 index 0000000000..c8947f63e0 --- /dev/null +++ b/dom/media/test/test_eme_autoplay.html @@ -0,0 +1,115 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/* import-globals-from eme.js */ +var manager = new MediaTestManager; + +var EMEmanifest = [ + { + name:"bipbop 10s", + tracks: [ + { + name:"video", + type:"video/mp4; codecs=\"avc1.4d4015\"", + fragments:[ "bipbop-cenc-video-10s.mp4", + ] + } + ], + keys: { + "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311", + }, + sessionType:"temporary", + sessionCount:1, + duration:10.01 + }, +]; + +function startTest(test, token) +{ + manager.started(token); + + let v = document.createElement("video"); + v.controls = true; + v.autoplay = true; + + document.body.appendChild(v); + + var eventCounts = { play: 0, playing: 0}; + function ForbiddenEvents(e) { + var video = e.target; + ok(video.readyState >= video.HAVE_FUTURE_DATA, "Must not have received event too early"); + is(eventCounts[e.type], 0, "event should have only be fired once"); + eventCounts[e.type]++; + } + // Log events for debugging. + var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", + "waiting", "pause", "durationchange", "seeking", "seeked"]; + function logEvent(e) { + info("got " + e.type + " event"); + } + events.forEach(function(e) { + v.addEventListener(e, logEvent); + }); + v.addEventListener("play", ForbiddenEvents); + v.addEventListener("playing", ForbiddenEvents); + + var gotWaitingForKey = 0; + + let waitForKey = new EMEPromise; + v.addEventListener("waitingforkey", function() { + gotWaitingForKey += 1; + waitForKey.resolve(); + }); + + v.addEventListener("loadedmetadata", function() { + ok(SpecialPowers.do_lookupGetter(v, "isEncrypted").apply(v), + TimeStamp(token) + " isEncrypted should be true"); + is(v.isEncrypted, undefined, "isEncrypted should not be accessible from content"); + }); + + let finish = new EMEPromise; + v.addEventListener("playing", function() { + ok(true, TimeStamp(token) + " got playing event"); + // We expect only one waitingForKey as we delay until all sessions are ready. + // I.e. one waitingForKey should be fired, after which, we process all sessions, + // so it should not be possible to be blocked by a key after that point. + ok(gotWaitingForKey == 1, "Expected number 1 wait, got: " + gotWaitingForKey); + + finish.resolve(); + }); + + Promise.all([ + LoadInitData(v, test, token), + CreateAndSetMediaKeys(v, test, token), + LoadTest(test, v, token, false /* do not call endOfStream */), + waitForKey.promise]) + .then(values => { + let initData = values[0]; + return ProcessInitData(v, test, token, initData); + }) + .then(sessions => { + Log(token, "Updated all sessions, loading complete"); + finish.promise.then(() => CloseSessions(v, sessions)); + return finish.promise; + }) + .catch(reason => ok(false, reason)) + .then(() => manager.finished(token)); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(EMEmanifest, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_canvas_blocked.html b/dom/media/test/test_eme_canvas_blocked.html new file mode 100644 index 0000000000..22986493c4 --- /dev/null +++ b/dom/media/test/test_eme_canvas_blocked.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager(); + +function startTest(test, token) { + manager.started(token); + + let v = document.createElement("video"); + v.preload = "auto"; // Required due to "canplay" not firing for MSE unless we do this. + + var p1 = new EMEPromise(); + v.addEventListener("loadeddata", function(ev) { + var video = ev.target; + var canvas = document.createElement("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + document.body.appendChild(canvas); + var ctx = canvas.getContext("2d"); + ctx.drawImage(video, 0, 0); + if (canvas.width || canvas.height) { + let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height).data; + for (let byte of pixels) { + if (byte != 0) { + ok(false, "Should not draw EME video to canvas"); + // We don't need a log for each pixel, break after 1st failure. + break; + } + } + } + p1.resolve(); + }); + + let p2 = SetupEME(v, test, token); + + Promise.all([p1.promise, p2]) + .catch(reason => ok(false, reason)) + .then(() => { + CleanUpMedia(v); + manager.finished(token); + }); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gEMETests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_createMediaKeys_iframes.html b/dom/media/test/test_eme_createMediaKeys_iframes.html new file mode 100644 index 0000000000..6fe3dc9809 --- /dev/null +++ b/dom/media/test/test_eme_createMediaKeys_iframes.html @@ -0,0 +1,192 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test creation of MediaKeys in iframes</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody"> +// Helper functions. + +// We take navigator explicitly as an argument to avoid ambiguity in fetching +// it. This is to avoid issues with the following +// ``` +// iframe.contentWindow.createMediaKeys = createMediaKeys; +// await iframe.contentWindow.createMediaKeys(); +// ``` +// If we don't pass a navigator, and just use `navigator` in the function, this +// ends up being equivalent to +// ``` +// iframe.contentWindow.createMediaKeys = createMediaKeys; +// await iframe.contentWindow.createMediaKeys(window.navigator); +// ``` +// i.e. the function will use the navigator from the global window for the top +// browsing context, not the iframe's. This would result in the tests not +// correctly testing within the iframe. +async function createMediaKeys(aNavigator) { + const clearKeyOptions = [ + { + initDataTypes: ["webm"], + videoCapabilities: [{ contentType: 'video/webm; codecs="vp9"' }], + }, + ]; + + let access = await aNavigator.requestMediaKeySystemAccess( + "org.w3.clearkey", + clearKeyOptions + ); + + return access.createMediaKeys(); +} +// End helper functions. + +// These tests check that the following work using different iframe combinations +// - navigator.requestMediaKeySystem(...) successfully grants access. +// - the resulting MediaKeySystemAccess object's createMediaKeys() creates +// MediaKeys as expected. + +// Same origin iframe, using src attribute, wait for onload. +add_task(async () => { + info( + "Starting same origin iframe, using src attribute, wait for onload test" + ); + let iframe = document.createElement("iframe"); + let iframeLoadPromise = new Promise(r => { + iframe.onload = r; + }); + iframe.src = "file_eme_createMediaKeys.html"; + document.body.appendChild(iframe); + await iframeLoadPromise; + info("iframe loaded"); + + // Setup our handler for when the iframe messages to tell us if it + // created MediaKeys or not. + let iframeMessagePromise = new Promise(r => { + window.onmessage = message => { + is( + message.data, + "successCreatingMediaKeys", + "iframe should have posted us a message saying keys were successfully created" + ); + r(); + }; + }); + // Post a message to the iframe to ask it to try and create media keys. + iframe.contentWindow.postMessage("", "*"); + // Wait until we've got a message back from our iframe. + await iframeMessagePromise; +}); + +// Same origin iframe, call via JS, wait for onload. +add_task(async () => { + info("Starting same origin iframe, call via JS, wait for onload test"); + let iframe = document.createElement("iframe"); + let iframeLoadPromise = new Promise(r => { + iframe.onload = r; + }); + iframe.src = ""; // No src iframes are same origin. + document.body.appendChild(iframe); + await iframeLoadPromise; + info("iframe loaded"); + + try { + iframe.contentWindow.createMediaKeys = createMediaKeys; + let mediaKeys = await iframe.contentWindow.createMediaKeys( + iframe.contentWindow.navigator + ); + ok(mediaKeys, "Should get media keys"); + } catch (e) { + ok( + false, + `Should not get any errors while trying to get media keys, got ${e}` + ); + } +}); + +// Same origin iframe, call via JS, *do not* wait for onload. +// +// Note, sites shouldn't do this, because +// https://bugzilla.mozilla.org/show_bug.cgi?id=543435 +// means not waiting for onload results in weird behavior, however +// https://bugzilla.mozilla.org/show_bug.cgi?id=1675360 +// shows sites doing this in the wild because historically this worked in +// Firefox. +// +// Breaking this test case isn't necessarily against any specifications +// I'm (bryce) aware of, but it will probably break site compat, so be really +// sure you want to before doing so. +add_task(async () => { + info( + "Starting same origin iframe, call via JS, *do not* wait for onload test" + ); + let iframe = document.createElement("iframe"); + let iframeLoadPromise = new Promise(r => { + iframe.onload = r; + }); + iframe.src = ""; // No src iframes are same origin. + document.body.appendChild(iframe); + info("iframe appended (we're not waiting for load)"); + + try { + iframe.contentWindow.createMediaKeys = createMediaKeys; + let mediaKeys = await iframe.contentWindow.createMediaKeys( + iframe.contentWindow.navigator + ); + ok(mediaKeys, "Should get media keys"); + + // We await the load to see if they keys persist through the load. + // This could fail if gecko internally associates the keys with the + // about:blank page that is replaced by the load. + await iframeLoadPromise; + ok(mediaKeys, "Media keys should still exist after the load"); + } catch (e) { + ok( + false, + `Should not get any errors while trying to get media keys, got ${e}` + ); + } +}); + +// Different origin iframe, using src attribute, wait for onload +add_task(async () => { + info( + "Starting different origin iframe, using src attribute, wait for onload test" + ); + let iframe = document.createElement("iframe"); + let iframeLoadPromise = new Promise(r => { + iframe.onload = r; + }); + // Make our iframe cross origin (see build/pgo/server-locations.txt for more + // info the url used). + iframe.src = + "https://w3c-test.org:443/tests/dom/media/test/file_eme_createMediaKeys.html"; + iframe.allow = "encrypted-media"; + document.body.appendChild(iframe); + await iframeLoadPromise; + info("iframe loaded"); + + // Setup our handler for when the iframe messages to tell us if it + // created MediaKeys or not. + let iframeMessagePromise = new Promise(r => { + window.onmessage = message => { + is( + message.data, + "successCreatingMediaKeys", + "iframe should have posted us a message saying keys were successfully created" + ); + r(); + }; + }); + // Post a message to the iframe to ask it to try and create media keys. + iframe.contentWindow.postMessage("", "*"); + // Wait until we've got a message back from our iframe. + await iframeMessagePromise; +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_detach_media_keys.html b/dom/media/test/test_eme_detach_media_keys.html new file mode 100644 index 0000000000..69b812032a --- /dev/null +++ b/dom/media/test/test_eme_detach_media_keys.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<video id="v" controls></video> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function createAndSet() { + return new Promise(function(resolve, reject) { + var m; + navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, gCencMediaKeySystemConfig) + .then(function (access) { + return access.createMediaKeys(); + }) + .then(function (mediaKeys) { + m = mediaKeys; + return document.getElementById("v").setMediaKeys(mediaKeys); + }) + .then(function() { + resolve(m); + }); + } +)} + +var m1,m2; + +// Test that if we create and set two MediaKeys on one video element, +// that if the first MediaKeys we set on the media elemnt is still usable +// after the second MediaKeys has been set on the media element. + +createAndSet().then((m) => { + m1 = m; // Stash MediaKeys. + return createAndSet(); +}) +.then((m) => { + m2 = m; + is(document.getElementById("v").mediaKeys, m2, "Should have set MediaKeys on media element"); + ok(document.getElementById("v").mediaKeys != m1, "First MediaKeys should no longer be set on media element"); + var s = m1.createSession("temporary"); + return s.generateRequest("webm", StringToArrayBuffer(atob('YAYeAX5Hfod+V9ANHtANHg=='))); +}) +.then(() => { + ok(true, "Was able to generateRequest using second CDM"); + SimpleTest.finish(); +}, () => { + ok(false, "Was *NOT* able to generateRequest using second CDM"); + SimpleTest.finish(); +}); + + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_detach_reattach_same_mediakeys_during_playback.html b/dom/media/test/test_eme_detach_reattach_same_mediakeys_during_playback.html new file mode 100644 index 0000000000..e47fae5891 --- /dev/null +++ b/dom/media/test/test_eme_detach_reattach_same_mediakeys_during_playback.html @@ -0,0 +1,141 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script> +</head> +<body> +<pre id="test"> +<video id="v" controls></video> +<script class="testbody" type="text/javascript"> +/* import-globals-from eme.js */ +var manager = new MediaTestManager; + +var EMEmanifest = [ + { + name:"bipbop 10s", + tracks: [ + { + name:"video", + type:"video/mp4; codecs=\"avc1.4d4015\"", + fragments:[ "bipbop-cenc-video-10s.mp4", + ] + } + ], + keys: { + "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311", + }, + sessionType:"temporary", + sessionCount:1, + duration:10.01 + }, +]; + +function sleep(time) { + return new Promise((resolve) => setTimeout(resolve, time)); +} + +// To check if playback can be blocked and resumed correctly after +// detaching original mediakeys and reattach it back. +function startTest(test, token) +{ + manager.started(token); + + var mk_ori; + let finish = new EMEPromise; + + let v = document.getElementById("v"); + let sessions = []; + function onSessionCreated(session) { + sessions.push(session); + } + + function closeSessions() { + let p = new EMEPromise; + Promise.all(sessions.map(s => s.close())) + .then(p.resolve, p.reject); + return p.promise; + } + + function setMediaKeysToElement(mk, solve, reject) { + v.setMediaKeys(mk).then(solve, reject); + } + + function ReattachOriMediaKeys() { + function onOriMediaKeysSetOK() { + ok(true, TimeStamp(token) + " (ENCRYPTED) Set original MediaKeys back OK!"); + } + function onOriMediaKeysSetFailed() { + ok(false, " Failed to set original mediakeys back."); + } + + function onCanPlayAgain(ev) { + Promise.all([closeSessions()]) + .then(() => { + ok(true, " (ENCRYPTED) Playback can be resumed."); + manager.finished(token); + }, () => { + ok(false, TimeStamp(token) + " Sessions are closed incorrectly."); + manager.finished(token); + }); + } + + once(v, "canplay", onCanPlayAgain); + setMediaKeysToElement(mk_ori, onOriMediaKeysSetOK, onOriMediaKeysSetFailed) + } + + function triggerSeek() { + v.currentTime = v.duration / 2; + } + + function onCanPlay(ev) { + function onSetMediaKeysToNullOK() { + ok(true, TimeStamp(token) + " Set MediaKeys to null. OK!"); + + triggerSeek(); + + SimpleTest.requestFlakyTimeout("To reattach mediakeys back again in 5s."); + sleep(5000).then(ReattachOriMediaKeys); + } + function onSetMediaKeysToNullFailed() { + ok(false, TimeStamp(token) + " Set MediaKeys to null. FAILED!"); + } + + SimpleTest.requestFlakyTimeout("To detach mediakeys after receiving 'canplay' event in 2s"); + sleep(2000).then(() => { + setMediaKeysToElement(null, onSetMediaKeysToNullOK, onSetMediaKeysToNullFailed); + }); + } + + once(v, "canplay", onCanPlay); + + var p1 = LoadInitData(v, test, token); + var p2 = CreateAndSetMediaKeys(v, test, token); + var p3 = LoadTest(test, v, token); + Promise.all([p1, p2, p3]) + .then(values => { + let initData = values[0]; + // stash the mediakeys + mk_ori = v.mediaKeys; + initData.map(ev => { + let session = v.mediaKeys.createSession(); + onSessionCreated(session); + MakeRequest(test, token, ev, session); + }); + }) + .then(() => { + return finish.promise; + }) + .catch(reason => ok(false, reason)) +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(EMEmanifest, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_getstatusforpolicy.html b/dom/media/test/test_eme_getstatusforpolicy.html new file mode 100644 index 0000000000..2031d04df5 --- /dev/null +++ b/dom/media/test/test_eme_getstatusforpolicy.html @@ -0,0 +1,93 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test getStatusForPolicy on ClearKey CDM</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<video id="v" controls></video> +<script class="testbody" type="text/javascript"> + +add_task(async function setupTestingPrefs() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.eme.hdcp-policy-check.enabled", true], + ], + }); +}); + +// We expect that ClearKey has HDCP 2.0 compliant. +const expectedResults = [ + { + minHdcpVersion : "1.0", + expectedResult : "usable" + }, + { + minHdcpVersion : "1.1", + expectedResult : "usable" + }, + { + minHdcpVersion : "1.2", + expectedResult : "usable" + }, + { + minHdcpVersion : "1.3", + expectedResult : "usable" + }, + { + minHdcpVersion : "1.4", + expectedResult : "usable" + }, + { + minHdcpVersion : "2.0", + expectedResult : "usable" + }, + { + minHdcpVersion : "2.1", + expectedResult : "usable" + }, + { + minHdcpVersion : "2.2", + expectedResult : "output-restricted" + }, + { + minHdcpVersion : "2.3", + expectedResult : "output-restricted" + }, +]; + +add_task(async function testGetStatusForPolicy() { + for (let result of expectedResults) { + let mediaKey = await createMediaKeysAndSet(); + let video = document.getElementById("v"); + is(video.mediaKeys, mediaKey, + "Should have set MediaKeys on media element"); + let keyStatus = await + video.mediaKeys.getStatusForPolicy({minHdcpVersion : result.minHdcpVersion}) + .catch(e => ok(false, "getStatusForPolicy failed!")); + info(`getStatusForPolicy for HDCP ${result.minHdcpVersion} : ${keyStatus}`); + is(keyStatus, result.expectedResult, + `Expected ${result.expectedResult}, got ${keyStatus}`); + } +}); + +// Helper function +function createMediaKeysAndSet() { + return navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, gCencMediaKeySystemConfig) + .then(function (access) { + return access.createMediaKeys(); + }) + .then(function (mediaKeys) { + document.getElementById("v").setMediaKeys(mediaKeys); + return mediaKeys; + }); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_initDataTypes.html b/dom/media/test/test_eme_initDataTypes.html new file mode 100644 index 0000000000..587e6fc161 --- /dev/null +++ b/dom/media/test/test_eme_initDataTypes.html @@ -0,0 +1,130 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var tests = [ + { + name: "One keyId", + initDataType: 'keyids', + initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"]}', + expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"],"type":"temporary"}', + sessionType: 'temporary', + expectPass: true, + }, + { + name: "Two keyIds", + initDataType: 'keyids', + initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}', + expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"temporary"}', + sessionType: 'temporary', + expectPass: true, + }, + { + name: "Two keyIds, temporary session", + initDataType: 'keyids', + initData: '{"type":"temporary", "kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}', + expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"temporary"}', + sessionType: 'temporary', + expectPass: true, + }, + { + name: "Two keyIds, persistent session, type before kids", + initDataType: 'keyids', + initData: '{"type":"persistent-license", "kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}', + expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"persistent-license"}', + sessionType: 'persistent-license', + expectPass: false, + }, + { + name: "Invalid keyId", + initDataType: 'keyids', + initData: '{"kids":["0"]}', + sessionType: 'temporary', + expectPass: false, + }, + { + name: "Empty keyId", + initDataType: 'keyids', + initData: '{"kids":[""]}', + sessionType: 'temporary', + expectPass: false, + }, + { + name: "Invalid initData", + initDataType: 'keyids', + initData: 'invalid initData', + sessionType: 'temporary', + expectPass: false, + }, + { + name: "'webm' initDataType", + initDataType: 'webm', + initData: 'YAYeAX5Hfod+V9ANHtANHg==', + expectedRequest: '{"kids":["YAYeAX5Hfod-V9ANHtANHg"],"type":"temporary"}', + sessionType: 'temporary', + expectPass: true, + }, + { + name: "'webm' initDataType with non 16 byte keyid", + initDataType: 'webm', + initData: 'YAYeAX5Hfod', + expectedRequest: '{\"kids\":[\"YAYeAX5Hfoc\"],\"type\":\"temporary\"}', + sessionType: 'temporary', + expectPass: true, + }, +]; + +function PrepareInitData(initDataType, initData) +{ + if (initDataType == "keyids") { + return new TextEncoder().encode(initData); + } else if (initDataType == "webm") { + return StringToArrayBuffer(atob(initData)); + } +} + +function Test(test) { + return new Promise(function(resolve, reject) { + var configs = [{ + initDataTypes: [test.initDataType], + videoCapabilities: [{contentType: 'video/mp4' }], + }]; + navigator.requestMediaKeySystemAccess('org.w3.clearkey', configs) + .then((access) => access.createMediaKeys()) + .then((mediaKeys) => { + var session = mediaKeys.createSession(test.sessionType); + session.addEventListener("message", function(event) { + is(event.messageType, "license-request", "'" + test.name + "' MediaKeyMessage type should be license-request."); + var text = new TextDecoder().decode(event.message); + is(text, test.expectedRequest, "'" + test.name + "' got expected response."); + is(text == test.expectedRequest, test.expectPass, + "'" + test.name + "' expected to " + (test.expectPass ? "pass" : "fail")); + resolve(); + }); + var initData = PrepareInitData(test.initDataType, test.initData); + return session.generateRequest(test.initDataType, initData); + } + ).catch((x) => { + ok(!test.expectPass, "'" + test.name + "' expected to fail."); + resolve(); + }); + }); +} + +SimpleTest.waitForExplicitFinish(); +Promise.all(tests.map(Test)).then(function() { + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_mfcdm_generate_request.html b/dom/media/test/test_eme_mfcdm_generate_request.html new file mode 100644 index 0000000000..57be325e36 --- /dev/null +++ b/dom/media/test/test_eme_mfcdm_generate_request.html @@ -0,0 +1,93 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media Engine only test : test EME API for supported key systems</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<script class="testbody" type="text/javascript"> + +/** + * This test is aiming to test whether we can use EME API to generate a request + * for all supported key systems. However, we use our mock CDM (MF ClearKey) for + * external key systems like Widevine and PlayReady in order to avoid any + * possible interfering, such as returning incorrect support types (bug 1851914) + * and we can also test hardward DRM key system without being limited by + * machine capability. + * + * As this test doesn't involve any communication with the license server, that + * is why we can use our mock CDM (no decryption needed). + */ + +add_task(async function setupTestingPrefs() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.wmf.media-engine.enabled", 2], + ["media.eme.playready.enabled", true], + ["media.eme.widevine.experiment.enabled", true], + // This is used to trigger Widevine CDM installation check + ["media.gmp-widevinecdm-l1.enabled", true], + ["media.eme.wmf.clearkey.enabled", true], + // Use the mock clearkey CDM to create cdm for all other key systems. + ["media.eme.wmf.use-mock-cdm-for-external-cdms", true], + // Our mock CDM doesn't implement 'IsTypeSupportedEx()', only 'IsTypeSupported()' + ["media.eme.playready.istypesupportedex", false], + ], + }); +}); + +const kKeySystems = [ + "com.microsoft.playready.recommendation", + "com.microsoft.playready.recommendation.3000", + "com.microsoft.playready.recommendation.3000.clearlead", + "com.widevine.alpha.experiment", + "com.widevine.alpha.experiment2", + "org.w3.clearkey", +]; + +add_task(async function testKeySystemRequestForMFCDMs() { + for (let keySystem of kKeySystems) { + await testKeySystemRequest(keySystem); + info(`done testing ${keySystem}!`); + } +}); + +async function testKeySystemRequest(keySystem) { + const fakeKID = '{"kids":["a1234567890"]}'; + // Mock CDM only supports temporary type. + const sessionType = 'temporary'; + const configs = [{ + initDataTypes: ['keyids'], + videoCapabilities: [{ contentType: `video/mp4;codecs="avc1.640028"` }], + sessionTypes : [sessionType], + }]; + info(`requestMediaKeySystemAccess for ${keySystem}`); + let access = await navigator.requestMediaKeySystemAccess(keySystem, configs) + .catch(e => ok(false, `failed to create key system access`)); + + info('creating media key'); + let mediaKeys = await access.createMediaKeys() + .catch(e => ok(false, `failed to create media key`));; + + info(`creating a temporary media key session`); + let session = mediaKeys.createSession(sessionType); + let messagePromise = new Promise(r => { + session.addEventListener('message', event => { + is(event.messageType, 'license-request', + 'MediaKeyMessage type should be license-request'); + ok(true, `created request and received message event`); + session.close().then(() => { r(); }); + }); + }); + await session.generateRequest( + 'keyids', + new TextEncoder().encode(fakeKID)) + .catch(e => ok(false, `failed to generate request`)); + await messagePromise; +} + +</script> +</body> +</html> diff --git a/dom/media/test/test_eme_mfcdm_getstatusforpolicy.html b/dom/media/test/test_eme_mfcdm_getstatusforpolicy.html new file mode 100644 index 0000000000..7e22be25d9 --- /dev/null +++ b/dom/media/test/test_eme_mfcdm_getstatusforpolicy.html @@ -0,0 +1,115 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test getStatusForPolicy on MFCDM</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<video id="v" controls></video> +<script class="testbody" type="text/javascript"> + +add_task(async function setupTestingPrefs() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.eme.hdcp-policy-check.enabled", true], + ["media.wmf.media-engine.enabled", 2], + ["media.eme.playready.enabled", true], + ["media.eme.widevine.experiment.enabled", true], + // This is used to trigger Widevine CDM installation check + ["media.gmp-widevinecdm-l1.enabled", true], + ["media.eme.wmf.clearkey.enabled", true], + // Use the mock clearkey CDM to create cdm for all other key systems. + ["media.eme.wmf.use-mock-cdm-for-external-cdms", true], + // Our mock CDM doesn't implement 'IsTypeSupportedEx()', only 'IsTypeSupported()' + ["media.eme.playready.istypesupportedex", false], + ], + }); +}); + +// We expect that all key system have HDCP 2.1 compliant, which is pre-defined +// in `WMFClearKeyCDMFactory::IsTypeSupported`. +const expectedResults = [ + { + minHdcpVersion : "1.0", + expectedResult : "usable" + }, + { + minHdcpVersion : "1.1", + expectedResult : "usable" + }, + { + minHdcpVersion : "1.2", + expectedResult : "usable" + }, + { + minHdcpVersion : "1.3", + expectedResult : "usable" + }, + { + minHdcpVersion : "1.4", + expectedResult : "usable" + }, + { + minHdcpVersion : "2.0", + expectedResult : "usable" + }, + { + minHdcpVersion : "2.1", + expectedResult : "usable" + }, + { + minHdcpVersion : "2.2", + expectedResult : "output-restricted" + }, + { + minHdcpVersion : "2.3", + expectedResult : "output-restricted" + }, +]; + +const kKeySystems = [ + "com.microsoft.playready.recommendation", + "com.microsoft.playready.recommendation.3000", + "com.microsoft.playready.recommendation.3000.clearlead", + "com.widevine.alpha.experiment", + "com.widevine.alpha.experiment2", + "org.w3.clearkey", +]; + +add_task(async function testGetStatusForPolicy() { + for (let keySystem of kKeySystems) { + for (let result of expectedResults) { + let mediaKey = await createMediaKeysAndSet(keySystem); + let video = document.getElementById("v"); + is(video.mediaKeys, mediaKey, + "Should have set MediaKeys on media element"); + let keyStatus = await + video.mediaKeys.getStatusForPolicy({minHdcpVersion : result.minHdcpVersion}) + .catch(e => ok(false, "getStatusForPolicy failed!")); + info(`getStatusForPolicy for HDCP ${result.minHdcpVersion} : ${keyStatus}`); + is(keyStatus, result.expectedResult, + `Expected ${result.expectedResult}, got ${keyStatus}`); + } + } +}); + +// Helper function +function createMediaKeysAndSet(keySystem) { + return navigator.requestMediaKeySystemAccess(keySystem, gCencMediaKeySystemConfig) + .then(function (access) { + return access.createMediaKeys(); + }) + .then(function (mediaKeys) { + document.getElementById("v").setMediaKeys(mediaKeys); + return mediaKeys; + }); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_missing_pssh.html b/dom/media/test/test_eme_missing_pssh.html new file mode 100644 index 0000000000..29f77d021a --- /dev/null +++ b/dom/media/test/test_eme_missing_pssh.html @@ -0,0 +1,92 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> + </head> + <body> + <audio controls id="audio"></audio> + <pre id="test"> + <script class="testbody" type="text/javascript"> + + // Tests that a fragmented MP4 file without a PSSH, but with valid encrypted + // tracks with valid TENC boxes, is able to load with EME. + // We setup MSE before starting up EME, so that we exercise the "waiting for + // cdm" step in the MediaDecoderStateMachine. + + SimpleTest.waitForExplicitFinish(); + + var pssh = [ + 0x00, 0x00, 0x00, 0x00, + 0x70, 0x73, 0x73, 0x68, // BMFF box header (76 bytes, 'pssh') + 0x01, 0x00, 0x00, 0x00, // Full box header (version = 1, flags = 0) + 0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // SystemID + 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, + 0x00, 0x00, 0x00, 0x01, // KID_count (1) + 0x2f, 0xef, 0x8a, 0xd8, 0x12, 0xdf, 0x42, 0x97, + 0x83, 0xe9, 0xbf, 0x6e, 0x5e, 0x49, 0x3e, 0x53, + 0x00, 0x00, 0x00, 0x00 // Size of Data (0) + ]; + + var audio = document.getElementById("audio"); + + function LoadEME() { + var options = [{ + initDataType: 'cenc', + audioType: 'audio/mp4; codecs="mp4a.40.2"', + }]; + navigator.requestMediaKeySystemAccess("org.w3.clearkey", options) + .then((keySystemAccess) => { + return keySystemAccess.createMediaKeys(); + }, bail("Failed to request key system access.")) + + .then((mediaKeys) => { + audio.setMediaKeys(mediaKeys); + var session = mediaKeys.createSession(); + once(session, "message", (message) => { + is(message.messageType, 'license-request', "Expected a license-request"); + var license = new TextEncoder().encode(JSON.stringify({ + 'keys': [{ + 'kty':'oct', + 'kid':'L--K2BLfQpeD6b9uXkk-Uw', + 'k':HexToBase64('7f412f0575f44f718259beef56ec7771') + }], + 'type': 'temporary' + })); + session.update(license); + }); + session.generateRequest('cenc', new Uint8Array(pssh)); + }); + } + + function DownloadMedia(url, type, mediaSource) { + return new Promise(function(resolve, reject) { + var sourceBuffer = mediaSource.addSourceBuffer(type); + fetchWithXHR(url, (response) => { + once(sourceBuffer, "updateend", resolve); + sourceBuffer.appendBuffer(new Uint8Array(response)); + }); + }); + } + + function LoadMSE() { + var ms = new MediaSource(); + audio.src = URL.createObjectURL(ms); + + once(ms, "sourceopen", ()=>{ + DownloadMedia('short-audio-fragmented-cenc-without-pssh.mp4', 'audio/mp4; codecs="mp4a.40.2"', ms) + .then(() => { ms.endOfStream(); LoadEME();}); + }); + + audio.addEventListener("loadeddata", SimpleTest.finish); + } + + LoadMSE(); + + </script> + </pre> + </body> +</html> diff --git a/dom/media/test/test_eme_non_mse_fails.html b/dom/media/test/test_eme_non_mse_fails.html new file mode 100644 index 0000000000..6ff17d59ff --- /dev/null +++ b/dom/media/test/test_eme_non_mse_fails.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 1131392 - Test that EME does not work for non-MSE media</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/* import-globals-from eme.js */ +var manager = new MediaTestManager; + +function DoSetMediaKeys(v, test, token) +{ + var options = [{ + initDataTypes: ["cenc"], + audioCapabilities: [{contentType: test.audioType}], + videoCapabilities: [{contentType: test.videoType}], + }]; + + return navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options) + + .then(function(keySystemAccess) { + return keySystemAccess.createMediaKeys(); + }) + + .catch(function() { + ok(false, token + " was not expecting failure (yet)"); + }) + + .then(function(mediaKeys) { + return v.setMediaKeys(mediaKeys); + }); +} + +function TestSetMediaKeys(test, token) +{ + manager.started(token); + + var v = document.createElement("video"); + + v.addEventListener("encrypted", function() { + ok(false, token + " should not fire encrypted event"); + }); + + var loadedMetadata = false; + v.addEventListener("loadedmetadata", function() { + loadedMetadata = true; + }); + + v.addEventListener("error", function() { + ok(true, token + " expected error event"); + ok(loadedMetadata, token + " expected loadedmetadata to have fired"); + manager.finished(token); + }); + + v.src = test.name; +} + +function TestSetSrc(test, token) +{ + manager.started(token); + + var v = document.createElement("video"); + v.addEventListener("error", function(err) { + ok(true, token + " got error setting src on video element, as expected"); + manager.finished(token); + }); + + DoSetMediaKeys(v, test, token) + + .then(function() { + v.src = test.name; + }) + + .catch(function() { + ok(false, token + " got error setting media keys"); + }); +} + +function startTest(test, token) +{ + TestSetMediaKeys(test, token + "_setMediaKeys"); + TestSetSrc(test, token + "_setSrc"); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gEMENonMSEFailTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_playback.html b/dom/media/test/test_eme_playback.html new file mode 100644 index 0000000000..bcfa058e34 --- /dev/null +++ b/dom/media/test/test_eme_playback.html @@ -0,0 +1,188 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/* import-globals-from eme.js */ +var manager = new MediaTestManager; + +function ArrayBuffersEqual(a, b) { + if (a.byteLength != b.byteLength) { + return false; + } + var ua = new Uint8Array(a); + var ub = new Uint8Array(b); + for (var i = 0; i < ua.length; i++) { + if (ua[i] != ub[i]) { + return false; + } + } + return true; +} + +function KeysChangeFunc(session, keys, token) { + session.keyIdsReceived = []; + for (var keyid in keys) { + Log(token, "Set " + keyid + " to false in session[" + session.sessionId + "].keyIdsReceived"); + session.keyIdsReceived[keyid] = false; + } + return function(ev) { + var s = ev.target; + s.gotKeysChanged = true; + + var keyList = []; + var valueList = []; + var map = s.keyStatuses; + + // Test that accessing keys not known to the CDM has expected behaviour. + var absentKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, + 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]); + is(map.has(absentKey), false, "Shouldn't have a key that's not in the media"); + is(map.get(absentKey), undefined, "Unknown keys should undefined status"); + + // Verify known keys have expected status. + for (let [key, val] of map.entries()) { + is(key.constructor, ArrayBuffer, "keyId should be ArrayBuffer"); + ok(map.has(key), "MediaKeyStatusMap.has() should work."); + is(map.get(key), val, "MediaKeyStatusMap.get() should work."); + keyList.push(key); + valueList.push(val); + is(val, "usable", token + ": key status should be usable"); + var kid = Base64ToHex(window.btoa(ArrayBufferToString(key))); + ok(kid in s.keyIdsReceived, TimeStamp(token) + " session[" + s.sessionId + "].keyIdsReceived contained " + kid + " as expected."); + s.keyIdsReceived[kid] = true; + } + + var index = 0; + for (var keyId of map.keys()) { + ok(ArrayBuffersEqual(keyId, keyList[index]), "MediaKeyStatusMap.keys() should correspond to entries"); + index++; + } + index = 0; + for (let val of map.values()) { + is(val, valueList[index], "MediaKeyStatusMap.values() should correspond to entries"); + index++; + } + } +} + +function startTest(test, token) +{ + manager.started(token); + + var sessions = []; + + function onSessionCreated(session) { + sessions.push(session); + session.addEventListener("keystatuseschange", KeysChangeFunc(session, test.keys, token)); + + session.numKeystatuseschangeEvents = 0; + session.numOnkeystatuseschangeEvents = 0; + + session.addEventListener("keystatuseschange", function() { + session.numKeystatuseschangeEvents += 1; + }); + session.onkeystatuseschange = function() { + session.numOnkeystatuseschangeEvents += 1; + }; + + session.numMessageEvents = 0; + session.numOnMessageEvents = 0; + session.addEventListener("message", function() { + session.numMessageEvents += 1; + }); + session.onmessage = function() { + session.numOnMessageEvents += 1; + }; + } + + let v = document.createElement("video"); + document.body.appendChild(v); + + var gotEncrypted = 0; + let finish = new EMEPromise; + + v.addEventListener("encrypted", function(ev) { + gotEncrypted += 1; + }); + + v.addEventListener("loadedmetadata", function() { + ok(SpecialPowers.do_lookupGetter(v, "isEncrypted").apply(v), + TimeStamp(token) + " isEncrypted should be true"); + is(v.isEncrypted, undefined, "isEncrypted should not be accessible from content"); + }); + + v.addEventListener("ended", function(ev) { + ok(true, TimeStamp(token) + " got ended event"); + + is(gotEncrypted, test.sessionCount, + TimeStamp(token) + " encrypted events expected: " + test.sessionCount + + ", actual: " + gotEncrypted); + + ok(Math.abs(test.duration - v.duration) < 0.1, + TimeStamp(token) + " Duration of video should be corrrect"); + ok(Math.abs(test.duration - v.currentTime) < 0.1, + TimeStamp(token) + " Current time should be same as duration"); + + // Verify all sessions had all keys went sent to the CDM usable, and thus + // that we received keystatuseschange event(s). + is(sessions.length, test.sessionCount, TimeStamp(token) + " should have " + + test.sessionCount + + " session" + (test.sessionCount === 1 ? "" : "s")); + var keyIdsReceived = []; + for (var keyid in test.keys) { keyIdsReceived[keyid] = false; } + for (var i = 0; i < sessions.length; i++) { + var session = sessions[i]; + ok(session.gotKeysChanged, + TimeStamp(token) + " session[" + session.sessionId + + "] should have received at least one keychange event"); + for (let kid in session.keyIdsReceived) { + Log(token, "session[" + session.sessionId + "] key " + kid + " = " + (session.keyIdsReceived[kid] ? "true" : "false")); + if (session.keyIdsReceived[kid]) { keyIdsReceived[kid] = true; } + } + ok(session.numKeystatuseschangeEvents > 0, TimeStamp(token) + " should get key status changes"); + is(session.numKeystatuseschangeEvents, session.numOnkeystatuseschangeEvents, + TimeStamp(token) + " should have as many keystatuseschange event listener calls as event handler calls."); + + ok(session.numMessageEvents > 0, TimeStamp(token) + " should get message events"); + is(session.numMessageEvents, session.numOnMessageEvents, + TimeStamp(token) + " should have as many message event listener calls as event handler calls."); + } + for (let kid in keyIdsReceived) { + ok(keyIdsReceived[kid], TimeStamp(token) + " key with id " + kid + " was usable as expected"); + } + + CloseSessions(v, sessions).then(finish.resolve, finish.reject); + }); + + Promise.all([ + LoadInitData(v, test, token), + CreateAndSetMediaKeys(v, test, token), + LoadTest(test, v, token)]) + .then(values => { + v.play(); + let initData = values[0]; + initData.map(ev => { + let session = v.mediaKeys.createSession(); + onSessionCreated(session); + MakeRequest(test, token, ev, session); + }); + return finish.promise; + }) + .catch(reason => ok(false, reason)) + .then(() => manager.finished(token)); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gEMETests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_protection_query.html b/dom/media/test/test_eme_protection_query.html new file mode 100644 index 0000000000..8bf97d8100 --- /dev/null +++ b/dom/media/test/test_eme_protection_query.html @@ -0,0 +1,250 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test Encrypted Media Extensions - Protection Query</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +// Tests in this file check that output protection queries are performed and +// handled correctly. This is done by using a special clear key key system that +// emits key status to track protection status. + +// Special key system used for these tests. +const kClearKeyWithProtectionQuery = + "org.mozilla.clearkey_with_protection_query"; +const kTestFile = "bipbop-cenc-video-10s.mp4"; +const kTestMimeType = 'video/mp4; codecs="avc1.4d4015"'; +const kTestKeyId = "7e571d037e571d037e571d037e571d11"; // Hex representation +const kTestKey = "7e5733337e5733337e5733337e573311"; + +// This is the special key-id used by the mozilla clearkey CDM to signal +// protection query status. As hex it is "6f75747075742d70726f74656374696f6e", +// the hex translates to ascii "output-protection". +const kProtectionQueryKeyIdString = "output-protection"; + +// Options for requestMediaKeySystemAccess +const kKeySystemOptions = [ + { + initDataTypes: ["cenc"], + videoCapabilities: [{ contentType: kTestMimeType }], + }, +]; + +// Helper to setup EME on `video`. +// @param video the HTMLMediaElement to configure EME on. +// @returns a media key session for the video. Callers can use this to +// configure the `onkeystatuseschange` event handler for each test. Callers +// *should not* configure other aspects of the session as this helper already +// does so. +async function setupEme(video) { + // Start setting up EME. + let access = await navigator.requestMediaKeySystemAccess( + kClearKeyWithProtectionQuery, + kKeySystemOptions + ); + let mediaKeys = await access.createMediaKeys(); + await video.setMediaKeys(mediaKeys); + + let session = video.mediaKeys.createSession(); + + video.onencrypted = async encryptedEvent => { + session.onmessage = messageEvent => { + // Handle license messages. Hard code the license because we always test + // with the same file and we know what the license should be. + const license = { + keys: [ + { + kty: "oct", + kid: HexToBase64(kTestKeyId), + k: HexToBase64(kTestKey), + }, + ], + type: "temporary", + }; + + const encodedLicense = new TextEncoder().encode(JSON.stringify(license)); + + session.update(encodedLicense); + }; + + session.generateRequest( + encryptedEvent.initDataType, + encryptedEvent.initData + ); + }; + + return session; +} + +// Helper to setup MSE media on `video`. +// @param video the HTMLMediaElement to configure MSE on. +async function setupMse(video) { + const mediaSource = new MediaSource(); + video.src = URL.createObjectURL(mediaSource); + await once(mediaSource, "sourceopen"); + const sourceBuffer = mediaSource.addSourceBuffer("video/mp4"); + let fetchResponse = await fetch(kTestFile); + sourceBuffer.appendBuffer(await fetchResponse.arrayBuffer()); + await once(sourceBuffer, "updateend"); + mediaSource.endOfStream(); + await once(mediaSource, "sourceended"); +} + +// Helper to create a video element and append it to the page. +function createAndAppendVideo() { + const video = document.createElement("video"); + video.id = "video"; + // Loop in case tests run slowly, we want video to keep playing until we + // get expected events. + video.loop = true; + document.body.appendChild(video); + return video; +} + +// Helper to remove a video from the page. +function removeVideo() { + let video = document.getElementById("video"); + CleanUpMedia(video); +} + +// Helper to get the status for the kProtectionQueryKeyIdString key id. A +// session can (and will) have other keys with their own status, but we want +// to check this special key to find the protection query status. +function getKeyStatusForProtectionKeyId(session) { + for (let [keyId, status] of session.keyStatuses) { + if (ArrayBufferToString(keyId) == kProtectionQueryKeyIdString) { + return status; + } + } + return null; +} + +async function getDisplayMedia() { + SpecialPowers.wrap(document).notifyUserGestureActivation(); + return navigator.mediaDevices.getDisplayMedia(); +} + +// Tests playing encrypted media, starting a screen capture during playback, +// then stopping the capture while playback continues. +async function testProtectionQueryWithCaptureDuringVideo() { + let video = createAndAppendVideo(); + + // Configure the video and start it playing. KeyId should be usable (not restricted). + let session = await setupEme(video); + let keyStatusChangedPromise1 = new Promise( + resolve => + (session.onkeystatuseschange = () => { + // We may get status changes prior to kProtectionQueryKeyIdString changing, + // ensure we wait for the first kProtectionQueryKeyIdString change. + if (getKeyStatusForProtectionKeyId(session)) { + resolve(); + } + }) + ); + await setupMse(video); + await Promise.all([video.play(), keyStatusChangedPromise1]); + is( + getKeyStatusForProtectionKeyId(session), + "usable", + "Should be usable as capture hasn't started" + ); + + let keyStatusChangedPromise2 = new Promise( + resolve => (session.onkeystatuseschange = resolve) + ); + let [displayMediaStream] = await Promise.all([ + // Start a screen capture, this should restrict output. + getDisplayMedia(), + keyStatusChangedPromise2, + ]); + is( + getKeyStatusForProtectionKeyId(session), + "output-restricted", + "Should be output-restricted as capture is happening" + ); + + // Stop the screen capture, output should be usable again. + let keyStatusChangedPromise3 = new Promise( + resolve => (session.onkeystatuseschange = resolve) + ); + displayMediaStream.getTracks().forEach(track => track.stop()); + displayMediaStream = null; + await keyStatusChangedPromise3; + is( + getKeyStatusForProtectionKeyId(session), + "usable", + "Should be usable as capture has stopped" + ); + + removeVideo(); +} + +// Tests starting a screen capture, then starting encrypted playback, then +// stopping the screen capture while encrypted playback continues. +async function testProtectionQueryWithCaptureStartingBeforeVideo() { + // Start capture before setting up video. + let displayMediaStream = await getDisplayMedia(); + + let video = createAndAppendVideo(); + + // Configure the video and start it playing. KeyId should be restricted already. + let session = await setupEme(video); + let keyStatusChangedPromise1 = new Promise( + resolve => + (session.onkeystatuseschange = () => { + // We may get status changes prior to kProtectionQueryKeyIdString changing, + // ensure we wait for the first kProtectionQueryKeyIdString change. In + // rare cases the first protection status can be "usable" due to racing + // between playback and the machinery that detects WebRTC capture. To + // avoid this, wait for the first 'output-restricted' notification, + // which will either be the first event, or will quickly follow 'usable'. + if (getKeyStatusForProtectionKeyId(session) == "output-restricted") { + resolve(); + } + }) + ); + await setupMse(video); + await Promise.all([video.play(), keyStatusChangedPromise1]); + is( + getKeyStatusForProtectionKeyId(session), + "output-restricted", + "Should be restricted as capture is happening" + ); + + // Stop the screen capture, output should be usable again. + let keyStatusChangedPromise2 = new Promise( + resolve => (session.onkeystatuseschange = resolve) + ); + displayMediaStream.getTracks().forEach(track => track.stop()); + displayMediaStream = null; + await keyStatusChangedPromise2; + is( + getKeyStatusForProtectionKeyId(session), + "usable", + "Should be usable as capture has stopped" + ); + + removeVideo(); +} + +add_task(async function setupEnvironment() { + await SpecialPowers.pushPrefEnv({ + set: [ + // Need test key systems for test key system. + ["media.clearkey.test-key-systems.enabled", true], + // Need relaxed navigator permissions for getDisplayMedia. + ["media.navigator.permission.disabled", true], + ], + }); +}); +add_task(testProtectionQueryWithCaptureDuringVideo); +add_task(testProtectionQueryWithCaptureStartingBeforeVideo); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_pssh_in_moof.html b/dom/media/test/test_eme_pssh_in_moof.html new file mode 100644 index 0000000000..d1965be844 --- /dev/null +++ b/dom/media/test/test_eme_pssh_in_moof.html @@ -0,0 +1,141 @@ +<!DOCTYPE HTML>
+<html>
+
+ <head>
+ <title>Test Encrypted Media Extensions</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="manifest.js"></script>
+ <script type="text/javascript" src="eme.js"></script>
+ </head>
+
+ <body>
+ <script class="testbody" type="text/javascript">
+ let manager = new MediaTestManager;
+
+ let psshTests = [
+ { name: "bear-640x360-cenc-key-rotation",
+ tracks : [
+ {
+ name: "video",
+ type: "video/mp4; codecs=\"avc1.64000d\"",
+ fragments: ["bear-640x360-v_frag-cenc-key_rotation.mp4"],
+ initDatas: 6
+ },
+ {
+ name: "audio",
+ type: "audio/mp4; codecs=\"mp4a.40.2\"",
+ fragments: ["bear-640x360-a_frag-cenc-key_rotation.mp4"],
+ initDatas: 7
+ }
+ ],
+ keys : {
+ "30313233343536373839303132333435" :
+ "ebdd62f16814d27b68ef122afce4ae3c"
+ }
+ },
+ { name: "bipbop-clearkey-keyrotation-clear-lead",
+ tracks : [
+ {
+ name: "video",
+ type: "video/mp4; codecs=\"avc1.4d4015\"",
+ fragments: ["bipbop-clearkey-keyrotation-clear-lead-video.mp4"],
+ initDatas: 3
+ },
+ {
+ name: "audio",
+ type: "audio/mp4; codecs=\"mp4a.40.2\"",
+ fragments: ["bipbop-clearkey-keyrotation-clear-lead-audio.mp4"],
+ initDatas: 3
+ }
+ ],
+ keys : {
+ "00112233445566778899aabbccddeeff" :
+ "00112233445566778899aabbccddeeff",
+ "112233445566778899aabbccddeeff00" :
+ "112233445566778899aabbccddeeff00"
+ }
+ }
+ ];
+
+ // Specialized create media keys function, since the one in eme.js relies
+ // on listening for encrypted events, and we want to manage those
+ // ourselves within this test.
+ async function createAndSetMediaKeys(video, test, token) {
+ function streamType(type) {
+ var x = test.tracks.find(o => o.name == type);
+ return x ? x.type : undefined;
+ }
+
+ var configuration = { initDataTypes: ["cenc"] };
+ if (streamType("video")) {
+ configuration.videoCapabilities = [{contentType: streamType("video")}];
+ }
+ if (streamType("audio")) {
+ configuration.audioCapabilities = [{contentType: streamType("audio")}];
+ }
+ let keySystemAccess = await navigator.requestMediaKeySystemAccess(
+ "org.w3.clearkey", [configuration]);
+ let mediaKeys = await keySystemAccess.createMediaKeys();
+ return video.setMediaKeys(mediaKeys);
+ }
+
+ function startTest(test, token) {
+ manager.started(token);
+ let video = document.createElement("video");
+ document.body.appendChild(video);
+
+ let encryptedEventCount = 0;
+
+ let initDatas = new Map();
+
+ function handleEncrypted(event) {
+ // We get one 'encrypted' event for every run of contiguous PSSH boxes
+ // in each stream. Note that some of the PSSH boxes contained in the
+ // "bear" streams aren't in the Common Open PSSH box format, so our
+ // ClearKey CDM will reject those license requests. Some of the init
+ // data is also repeated.
+ encryptedEventCount++;
+
+ let hexStr = StringToHex(new TextDecoder().decode(event.initData));
+ if (initDatas.has(hexStr)) {
+ // Already have a session for this.
+ return;
+ }
+
+ let initData = new Uint8Array(event.initData);
+ is(event.initDataType, "cenc", "'encrypted' event should have 'cenc' " +
+ "initDataType");
+ Log(token, "encrypted event => len=" + initData.length + " " + hexStr);
+ let session = event.target.mediaKeys.createSession();
+ initDatas.set(hexStr, session);
+ session.addEventListener("message", e => {
+ e.target.update(
+ GenerateClearKeyLicense(e.message, test.keys));
+ });
+
+ session.generateRequest(event.initDataType, event.initData);
+ }
+
+ video.addEventListener("encrypted", handleEncrypted);
+
+ video.addEventListener("ended", () => {
+ let expectedEncryptedEvents =
+ test.tracks.reduce((sum, track) => sum += track.initDatas, 0);
+ is(encryptedEventCount, expectedEncryptedEvents,
+ "Should get one 'encrypted' event per run of contiguous PSSH " +
+ "boxes in media.");
+ manager.finished(token);
+ });
+
+ video.autoplay = true;
+
+ createAndSetMediaKeys(video, test, token)
+ .then(() => LoadTest(test, video, token))
+ }
+
+ manager.runTests(psshTests, startTest);
+
+ </script>
+ </body>
+</html>
diff --git a/dom/media/test/test_eme_requestKeySystemAccess.html b/dom/media/test/test_eme_requestKeySystemAccess.html new file mode 100644 index 0000000000..b044fe8c84 --- /dev/null +++ b/dom/media/test/test_eme_requestKeySystemAccess.html @@ -0,0 +1,477 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +const SUPPORTED_LABEL = "pass label"; + +function ValidateConfig(name, expected, observed) { + info("ValidateConfig " + name); + info("expected cfg=" + JSON.stringify(expected)); + info("observed cfg=" + JSON.stringify(observed)); + + is(observed.label, expected.label, name + " label should match"); + if (expected.initDataTypes) { + ok(expected.initDataTypes.every((element, index, array) => observed.initDataTypes.includes(element)), name + " initDataTypes should match."); + } + + if (expected.audioCapabilities) { + ok(expected.audioCapabilities.length == 1, "Test function can only handle one capability."); + ok(observed.audioCapabilities.length == 1, "Test function can only handle one capability."); + is(observed.audioCapabilities[0].contentType, expected.audioCapabilities[0].contentType, name + " audioCapabilities should match."); + } + if (typeof expected.videoCapabilities !== 'undefined') { + info("expected.videoCapabilities=" + expected.videoCapabilities); + dump("expected.videoCapabilities=" + expected.videoCapabilities + "\n"); + ok(expected.videoCapabilities.length == 1, "Test function can only handle one capability."); + ok(observed.videoCapabilities.length == 1, "Test function can only handle one capability."); + is(observed.videoCapabilities[0].contentType, expected.videoCapabilities[0].contentType, name + " videoCapabilities should match."); + } + if (expected.sessionTypes) { + is(expected.sessionTypes.length, observed.sessionTypes.length, "Should have expected number of sessionTypes"); + for (var i = 0; i < expected.sessionTypes.length; i++) { + is(expected[i], observed[i], "Session type " + i + " should match"); + } + } +} + +function Test(test) { + var name = "'" + test.name + "'"; + return new Promise(function(resolve, reject) { + var p; + if (test.options) { + var keySystem = (test.keySystem !== undefined) ? test.keySystem : CLEARKEY_KEYSYSTEM; + p = navigator.requestMediaKeySystemAccess(keySystem, test.options); + } else { + p = navigator.requestMediaKeySystemAccess(keySystem); + } + p.then( + function(keySystemAccess) { + ok(test.shouldPass, name + " passed and was expected to " + (test.shouldPass ? "pass" : "fail")); + is(keySystemAccess.keySystem, CLEARKEY_KEYSYSTEM, "CDM keySystem should be in MediaKeySystemAccess.keySystem"); + ValidateConfig(name, test.expectedConfig, keySystemAccess.getConfiguration()); + resolve(); + }, + function(ex) { + if (test.shouldPass) { + info(name + " failed: " + ex); + } + ok(!test.shouldPass, name + " failed and was expected to " + (test.shouldPass ? "pass" : "fail")); + resolve(); + }); + }); +} + +var tests = [ + { + name: 'Empty keySystem string', + keySystem: '', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + } + ], + shouldPass: false, + }, + { + name: 'Empty options specified', + options: [ ], + shouldPass: false, + }, + { + name: 'Undefined options', + shouldPass: false, + }, + { + name: 'Basic MP4 cenc', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4'}], + videoCapabilities: [{contentType: 'video/mp4'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4'}], + videoCapabilities: [{contentType: 'video/mp4'}], + }, + shouldPass: true, + }, + { + name: 'Invalid keysystem failure', + keySystem: 'bogusKeySystem', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + } + ], + shouldPass: false, + }, + { + name: 'Invalid initDataType', + options: [ + { + initDataTypes: ['bogus'], + audioCapabilities: [{contentType: 'audio/mp4'}], + } + ], + shouldPass: false, + }, + { + name: 'Valid initDataType after invalid', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['bogus', 'invalid', 'cenc'], + audioCapabilities: [{contentType: 'audio/mp4'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4'}], + }, + shouldPass: true, + }, + { + name: 'Invalid videoType', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/bogus'}], + } + ], + shouldPass: false, + }, + { + name: 'Invalid distinctiveIdentifier fails', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + distinctiveIdentifier: 'bogus', + persistentState: 'bogus', + } + ], + shouldPass: false, + }, + { + name: 'distinctiveIdentifier is prohibited for ClearKey', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + distinctiveIdentifier: 'required', + } + ], + shouldPass: false, + }, + { + name: 'Invalid persistentState fails', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + persistentState: 'bogus', + } + ], + shouldPass: false, + }, + { + name: 'Invalid robustness unsupported', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4', robustness: 'very much so'}], + } + ], + shouldPass: false, + }, + { + name: 'Unexpected config entry should be ignored', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + unexpectedEntry: 'this should be ignored', + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + }, + shouldPass: true, + }, + { + name: 'Invalid option followed by valid', + options: [ + { + label: "this config should not be supported", + initDataTypes: ['bogus'], + }, + { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + }, + shouldPass: true, + }, + { + name: 'Persistent-license should not be supported by ClearKey', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + sessionTypes: ['persistent-license'], + persistentState: 'optional', + } + ], + shouldPass: false, + }, + { + name: 'Persistent-usage-record should not be supported by ClearKey', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4'}], + sessionTypes: ['persistent-usage-record'], + persistentState: 'optional', + } + ], + shouldPass: false, + }, + { + name: 'MP4 audio container', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4'}], + }, + shouldPass: true, + }, + { + name: 'MP4 audio container with AAC-LC', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}], + }, + shouldPass: true, + }, + { + name: 'MP4 audio container with invalid codecs', + options: [ + { + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4; codecs="bogus"'}], + } + ], + shouldPass: false, + }, + { + name: 'MP4 audio container with mp3 is unsupported', + options: [ + { + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4; codecs="mp3"'}], + } + ], + shouldPass: false, + }, + { + name: 'MP4 video container type with an mp3 codec is unsupported', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4; codecs="mp3"'}], + } + ], + shouldPass: false, + }, + { + name: 'MP4 audio container type with a video codec is unsupported', + options: [ + { + initDataTypes: ['cenc'], + audioCapabilities: [{contentType: 'audio/mp4; codecs="avc1.42E01E"'}], + } + ], + shouldPass: false, + }, + { + name: 'MP4 video container with constrained baseline h.264', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}], + }, + shouldPass: true, + }, + { + name: 'MP4 video container with invalid codecs', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4; codecs="bogus"'}], + } + ], + shouldPass: false, + }, + { + name: 'MP4 video container with both audio and video codec type in videoType', + options: [ + { + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E,mp4a.40.2"'}], + } + ], + shouldPass: false, + }, + { + name: 'MP4 audio and video type both specified', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}], + audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['cenc'], + videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}], + audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}], + }, + shouldPass: true, + }, + { + name: 'Basic WebM video', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['webm'], + videoCapabilities: [{contentType: 'video/webm'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['webm'], + videoCapabilities: [{contentType: 'video/webm'}], + }, + shouldPass: true, + }, + { + name: 'Basic WebM audio', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['webm'], + audioCapabilities: [{contentType: 'audio/webm'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['webm'], + audioCapabilities: [{contentType: 'audio/webm'}], + }, + shouldPass: true, + }, + { + name: 'Webm with Vorbis audio and VP8 video.', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['webm'], + videoCapabilities: [{contentType: 'video/webm;codecs="vp8"'}], + audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['webm'], + videoCapabilities: [{contentType: 'video/webm;codecs="vp8"'}], + audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}], + }, + shouldPass: true, + }, + { + name: 'Webm with Vorbis audio and VP9 video.', + options: [ + { + label: SUPPORTED_LABEL, + initDataTypes: ['webm'], + videoCapabilities: [{contentType: 'video/webm;codecs="vp9"'}], + audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}], + } + ], + expectedConfig: { + label: SUPPORTED_LABEL, + initDataTypes: ['webm'], + videoCapabilities: [{contentType: 'video/webm;codecs="vp9"'}], + audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}], + }, + shouldPass: true, + }, + { + name: 'Webm with bogus video.', + options: [ + { + initDataTypes: ['webm'], + videoCapabilities: [{contentType: 'video/webm;codecs="bogus"'}], + } + ], + shouldPass: false, + }, +]; + +SimpleTest.waitForExplicitFinish(); +Promise.all(tests.map(Test)).then(function() { + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_requestMediaKeySystemAccess_with_app_approval.html b/dom/media/test/test_eme_requestMediaKeySystemAccess_with_app_approval.html new file mode 100644 index 0000000000..ceba459dae --- /dev/null +++ b/dom/media/test/test_eme_requestMediaKeySystemAccess_with_app_approval.html @@ -0,0 +1,202 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions access can be gated by application</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// These test cases should be used to make a request to +// requestMediaKeySystemAccess and have the following members: +// name: a name describing the test. +// askAppApproval: used to set prefs such so that Gecko will ask for app +// approval for EME if true, or not if false. +// appApproves: used to set prefs to simulate app approval of permission +// request, true if the app approves the request, false if not. +// expectedKeySystemAccess: true if we expect to be granted key system access, +// false if not. +const testCases = [ + { + name: "Don't check for app approval", + askAppApproval: false, + expectedKeySystemAccess: true, + }, + { + name: "Check for app approval and app denies request", + askAppApproval: true, + appApproves: false, + expectedKeySystemAccess: false, + }, + { + name: "Check for app approval and app allows request", + askAppApproval: true, + appApproves: true, + expectedKeySystemAccess: true, + }, +]; + +// Options for requestMediaKeySystemAccess that are expected to work. +const options = [{ + initDataTypes: ['webm'], + audioCapabilities: [ + { contentType: 'audio/webm; codecs="opus"' }, + ], + videoCapabilities: [ + { contentType: 'video/webm; codecs="vp8"' } + ] +}]; + +async function setTestPrefs({askAppApproval, appApproves}) { + if (!askAppApproval) { + // Test doesn't want app approval, set pref so we don't ask and unset prefs + // used to determine permission response as we don't need them. + await SpecialPowers.pushPrefEnv({ + set: [["media.eme.require-app-approval", false]], + clear: [ + ["media.eme.require-app-approval.prompt.testing"], + ["media.eme.require-app-approval.prompt.testing.allow"], + ] + }); + return; + } + + // Test wants app approval, and will approve deny requests per appApproces + // value, set prefs accordingly. + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.eme.require-app-approval", true], + ["media.eme.require-app-approval.prompt.testing", true], + ["media.eme.require-app-approval.prompt.testing.allow", appApproves], + ], + }); +} + +// Run a test case that makes a single requestMediaKeySystemAccess call. The +// outcome of such a test run should depend on the test case's setting of +// preferences controlling the eme app approval. +async function testSingleRequest(testCase) { + await setTestPrefs(testCase); + + try { + await navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options); + ok(testCase.expectedKeySystemAccess, + `testSingleRequest ${testCase.name}: allowed media key system access.`); + } catch(e) { + is(e.name, + "NotSupportedError", + "Should get NotSupportedError when request is blocked."); + is(e.message, + "The application embedding this user agent has blocked MediaKeySystemAccess", + "Should get blocked error message."); + ok(!testCase.expectedKeySystemAccess, + `testSingleRequest ${testCase.name}: denied media key system access.`); + } +} + +// Run a test case that, but using invalid arguments for +// requestMediaKeySystemAccess. Because we expect the args to be checked +// before requesting app approval, this test ensures that we always fail when +// using bad args, regardless of the app approval prefs set. +async function testRequestWithInvalidArgs(testCase) { + const badOptions = [{ + initDataTypes: ['badType'], + audioCapabilities: [ + { contentType: 'audio/webm; codecs="notACodec"' }, + ], + videoCapabilities: [ + { contentType: 'video/webm; codecs="notACodec"' } + ] + }]; + + await setTestPrefs(testCase); + + // Check that calls with a bad key system fail. + try { + await navigator.requestMediaKeySystemAccess("BadKeySystem", options); + ok(false, + `testRequestWithInvalidArgs ${testCase.name}: should not get access when using bad key system.`); + } catch(e) { + is(e.name, + "NotSupportedError", + "Should get NotSupportedError using bad key system."); + is(e.message, + "Key system is unsupported", + "Should get not supported key system error message."); + } + + // Check that calls with the bad options fail. + try { + await navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, badOptions); + ok(false, + `testRequestWithInvalidArgs ${testCase.name}: should not get access when using bad options.`); + } catch(e) { + is(e.name, + "NotSupportedError", + "Should get NotSupportedError using bad options."); + is(e.message, + "Key system configuration is not supported", + "Should get not supported config error message."); + } +} + +// Run a test case and make multiple requests with the same case. Check that +// all requests are resolved with the expected outcome. +async function testMultipleRequests(testCase) { + // Number of requests to concurrently make. + const NUM_REQUESTS = 5; + + await setTestPrefs(testCase); + + let resolveHandler = () => { + ok(testCase.expectedKeySystemAccess, + `testMultipleRequests ${testCase.name}: allowed media key system access.`); + } + + let rejectHandler = e => { + is(e.name, + "NotSupportedError", + "Should get NotSupportedError when request is blocked."); + is(e.message, + "The application embedding this user agent has blocked MediaKeySystemAccess", + "Should get blocked error message."); + ok(!testCase.expectedKeySystemAccess, + `testMultipleRequests ${testCase.name}: denied media key system access.`); + } + + let accessPromises = []; + for(let i = 0; i < NUM_REQUESTS; i++) { + // Request access then chain to our resolve and reject handlers. The + // handlers assert test state then resolve the promise chain. Ensuring the + // chain is always resolved allows us to correctly await all outstanding + // requests -- otherwise rejects short circuit the Promise.all call below. + let accessPromise = navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options) + .then(resolveHandler, rejectHandler); + accessPromises.push(accessPromise); + } + // Wait for all promises to be resolved. If not, we'll time out. Because + // our reject handler chains back into a resolved promise, this should wait + // for all requests to be serviced, even when requestMediaKeySystemAccess's + // promise is rejected. + await Promise.all(accessPromises); +} + +// The tests rely on prefs being set, so run them in sequence. If we run in +// parallel the tests break each other by overriding prefs. +for (const testCase of testCases) { + add_task(() => testSingleRequest(testCase)); +} +for (const testCase of testCases) { + add_task(() => testRequestWithInvalidArgs(testCase)); +} +for (const testCase of testCases) { + add_task(() => testMultipleRequests(testCase)); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_request_notifications.html b/dom/media/test/test_eme_request_notifications.html new file mode 100644 index 0000000000..6c44f892a6 --- /dev/null +++ b/dom/media/test/test_eme_request_notifications.html @@ -0,0 +1,82 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function SetPrefs(prefs) { + return SpecialPowers.pushPrefEnv({"set": prefs}); +} + +function observe() { + return new Promise(function(resolve, reject) { + var observer = function(subject, topic, data) { + SpecialPowers.Services.obs.removeObserver(observer, "mediakeys-request"); + resolve(JSON.parse(data).status); + }; + SpecialPowers.Services.obs.addObserver(observer, "mediakeys-request"); + }); +} + +function Test(test) { + var p = test.prefs ? SetPrefs(test.prefs) : Promise.resolve(); + var name = "'" + test.keySystem + "'"; + + var res = observe().then((status) => { + is(status, test.expectedStatus, name + " expected status"); + }); + + p.then(() => navigator.requestMediaKeySystemAccess(test.keySystem, gCencMediaKeySystemConfig)) + .then((keySystemAccess) => keySystemAccess.createMediaKeys()); + + return res; +} + +var tests = [ + { + keySystem: CLEARKEY_KEYSYSTEM, + expectedStatus: 'cdm-created', + prefs: [["media.eme.enabled", false]] + }, + { + keySystem: "com.widevine.alpha", + expectedStatus: 'api-disabled', + prefs: [["media.eme.enabled", false]] + }, + { + keySystem: "com.widevine.alpha", + expectedStatus: 'cdm-disabled', + prefs: [["media.eme.enabled", true], ["media.gmp-widevinecdm.enabled", false]] + }, + { + keySystem: "com.widevine.alpha", + expectedStatus: 'cdm-not-installed', + prefs: [["media.eme.enabled", true], ["media.gmp-widevinecdm.enabled", true]] + }, + { + keySystem: CLEARKEY_KEYSYSTEM, + expectedStatus: 'cdm-created', + prefs: [["media.eme.enabled", true]] + } +]; + +SimpleTest.waitForExplicitFinish(); +tests + .reduce(function(p, c, i, array) { + return p.then(function() { + return Test(c); + }); + }, Promise.resolve()) + .then(SimpleTest.finish); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_sample_groups_playback.html b/dom/media/test/test_eme_sample_groups_playback.html new file mode 100644 index 0000000000..cef1e26b33 --- /dev/null +++ b/dom/media/test/test_eme_sample_groups_playback.html @@ -0,0 +1,130 @@ +<!DOCTYPE HTML> +<html> + +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> + +<body> + <video controls id="video"></video> + <pre id="test"> + <script class="testbody" type="text/javascript"> + + // Tests that files with a default key and a seperate sample keyids in the + // sgpd box play correctly (if the keyid from the sgpd box is not parsed + // or assigned to the sample we will wait indefinitely for the default + // key). + + SimpleTest.waitForExplicitFinish(); + + // Test files for samples encrypted with different media keys. + var gEMESampleGoupTests = [ + { + name:"video with 4 keys in sgpd (sbgp in traf sgpd in stbl)", + track: { + name:"video", + type:"video/mp4; codecs=\"avc1.64000d\"", + fragments:[ "sample-encrypted-sgpdstbl-sbgptraf.mp4" + ] + }, + keys: { + // "keyid" : "key" + "279926496a7f5d25da69f2b3b2799a7f": "5544694d47473326622665665a396b36", + "597669572e55547e656b56586e2f6f68": "7959493a764556786527517849756635", + "205b2b293a342f3d3268293e6f6f4e29": "3a4f3674376d6c48675a273464447b40", + "32783e367c2e4d4d6b46467b3e6b5478": "3e213f6d45584f51713d534f4b417855", + }, + sessionType:"temporary", + sessionCount:1, + duration:2, + }, + ], + test = gEMESampleGoupTests[0]; + + var video = document.getElementById("video"); + video.addEventListener("encrypted", () => { + Log(test.name, "Recieved encrypted event"); + }); + + video.addEventListener("waitingforkey", () => { + Log(test.name, "waitingforkey"); + ok(false, test.name + " Video is waitingforkey, indicating that the samples are not being assigned the correct id from the sgpd box!"); + SimpleTest.finish(); + }); + + function LoadEME() { + var options = [{ + initDataType: "cenc", + videoType: test.track.type, + }]; + + return navigator.requestMediaKeySystemAccess("org.w3.clearkey", options) + .then((keySystemAccess) => { + return keySystemAccess.createMediaKeys(); + }, bail("Failed to request key system access.")) + + .then((mediaKeys) => { + video.setMediaKeys(mediaKeys); + + var session = mediaKeys.createSession(); + once(session, "message", (ev) => { + is(ev.messageType, "license-request", "Expected a license-request"); + session.update(GenerateClearKeyLicense(ev.message, test.keys)); + }); + + var json = JSON.stringify({ + "kids":Object.keys(test.keys).map(HexToBase64) + }); + var request = new TextEncoder().encode(json); + session.generateRequest("keyids", request) + .then(e => { + Log(test.name, "Request license success"); + }, reason => { + Log("Request license failed! " + reason); + }); + }); + } + + function DownloadMedia(url, type, mediaSource) { + return new Promise((resolve, reject) => { + var sourceBuffer = mediaSource.addSourceBuffer(type); + fetchWithXHR(url, (response) => { + once(sourceBuffer, "updateend", resolve); + sourceBuffer.appendBuffer(new Uint8Array(response)); + }); + }); + } + + function LoadMSE() { + // Only set the source of the video and download the tracks after we + // have set the license keys, so we don't hit the waitingforkey event + // unless samples are being incorrectly assigned the default key + // (and we can safely fail). + LoadEME() + .then(() => { + var ms = new MediaSource(); + video.src = URL.createObjectURL(ms); + + once(ms, "sourceopen", () => { + Promise.all(test.track.fragments.map(fragment => DownloadMedia(fragment, test.track.type, ms))) + .then(() => { + ms.endOfStream(); + video.play(); + }); + }); + + once(video, "ended", SimpleTest.finish); + }); + } + + LoadMSE(); + + </script> + </pre> +</body> + +</html>
\ No newline at end of file diff --git a/dom/media/test/test_eme_session_callable_value.html b/dom/media/test/test_eme_session_callable_value.html new file mode 100644 index 0000000000..3139c36157 --- /dev/null +++ b/dom/media/test/test_eme_session_callable_value.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function Test() { + navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, gCencMediaKeySystemConfig) + .then(access => access.createMediaKeys()) + .then(mediaKeys => { + var initData = (new TextEncoder()).encode( 'this is an invalid license, and that is ok'); + var s = mediaKeys.createSession("temporary"); + s.generateRequest("cenc", initData); // ignore result. + // "update()" call should fail, because MediaKeySession is "not callable" + // yet, since CDM won't have had a chance to set the sessionId on MediaKeySession. + return s.update(initData); + }) + .then(()=>{ok(false, "An exception should be thrown; MediaKeySession should be not callable."); SimpleTest.finish();}, + ()=>{ok(true, "We expect this to fail; MediaKeySession should be not callable."); SimpleTest.finish();}); +} + +SimpleTest.waitForExplicitFinish(); +Test(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_setMediaKeys_before_attach_MediaSource.html b/dom/media/test/test_eme_setMediaKeys_before_attach_MediaSource.html new file mode 100644 index 0000000000..1493cfdcb8 --- /dev/null +++ b/dom/media/test/test_eme_setMediaKeys_before_attach_MediaSource.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function beginTest() { + var video = document.createElement("video"); + + navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, gCencMediaKeySystemConfig) + .then(function(keySystemAccess) { + return keySystemAccess.createMediaKeys(); + }) + .then(mediaKeys => { + return video.setMediaKeys(mediaKeys); + }) + .then(() => { + var ms = new MediaSource(); + ms.addEventListener("sourceopen", ()=>{ok(true, "MediaSource should open"); SimpleTest.finish();}); + video.addEventListener("error", ()=>{ok(false, "Shouldn't error."); SimpleTest.finish();}); + video.src = URL.createObjectURL(ms); + }); +} + +SimpleTest.waitForExplicitFinish(); +beginTest(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_special_key_system.html b/dom/media/test/test_eme_special_key_system.html new file mode 100644 index 0000000000..0addc06ebc --- /dev/null +++ b/dom/media/test/test_eme_special_key_system.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test Encrypted Media Extensions - Special key system</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +function requestProtectionQueryKeySystemAccess() { + const kKeySystemOptions = [ + { + initDataTypes: ["cenc"], + videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.4d4015"' }], + }, + ]; + const kClearKeyWithProtectionQuery = + "org.mozilla.clearkey_with_protection_query"; + return navigator.requestMediaKeySystemAccess( + kClearKeyWithProtectionQuery, + kKeySystemOptions + ); +} +// Tests that org.mozilla.clearkey_with_protection_query cannot be accessed from JS if not preffed on. +add_task(async function protectionQueryKeySystemShouldBeHidden() { + try { + // Should throw since special key systems are not enabled. + await requestProtectionQueryKeySystemAccess(); + ok( + false, + "Test should have thrown by default because media.clearkey.test-key-systems.enabled should not be set" + ); + } catch (e) { + is(e.name, "NotSupportedError", "Should get not supported error"); + is( + e.message, + "Key system is unsupported", + "Should get message that key system is unsupported" + ); + } +}); + +// Tests that org.mozilla.clearkey_with_protection_query can be accessed from JS if preffed on. +add_task(async function protectionQueryKeySystemShouldBeExposed() { + await SpecialPowers.pushPrefEnv({ + set: [["media.clearkey.test-key-systems.enabled", true]], + }); + try { + // Should not throw since special key systems are enabled. + let access = await requestProtectionQueryKeySystemAccess(); + ok( + access, + "Should get access to protection query key system when preffed on" + ); + } catch (e) { + ok(false, "Test should not have thrown and key system should be available"); + } +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_stream_capture_blocked_case1.html b/dom/media/test/test_eme_stream_capture_blocked_case1.html new file mode 100644 index 0000000000..0fc8d28364 --- /dev/null +++ b/dom/media/test/test_eme_stream_capture_blocked_case1.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function startTest(test, token) +{ + // Case 1. setting MediaKeys on an element captured by MediaElementSource should fail. + var case1token = token + "_case1"; + let v1 = document.createElement("video"); + + function setMediaKeys() { + let p = new EMEPromise; + CreateMediaKeys(v1, test, case1token) + .then(mediaKeys => { + v1.setMediaKeys(mediaKeys) + .then(() => { + p.reject(`${case1token} setMediaKeys shouldn't succeed.`); + }, () => { + ok(true, TimeStamp(case1token) + " setMediaKeys failed as expected."); + p.resolve(); + }) + }, p.reject); + return p.promise; + } + + var context = new AudioContext(); + context.createMediaElementSource(v1); + v1.addEventListener("loadeddata", function(ev) { + ok(false, TimeStamp(case1token) + " should never reach loadeddata, as setMediaKeys should fail"); + }); + + manager.started(case1token); + + Promise.all([ + LoadTest(test, v1, case1token), + setMediaKeys()]) + .catch(reason => ok(false, reason)) + .then(() => { + CleanUpMedia(v1); + manager.finished(case1token); + }); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gEMETests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_stream_capture_blocked_case2.html b/dom/media/test/test_eme_stream_capture_blocked_case2.html new file mode 100644 index 0000000000..b60538caf0 --- /dev/null +++ b/dom/media/test/test_eme_stream_capture_blocked_case2.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function startTest(test, token) +{ + // Case 2. creating a MediaElementSource on a media element should always succeed + // (no matter whether it's restricted content or not), and + var p1 = new EMEPromise; + var case2token = token + "_case2"; + let v2 = document.createElement("video"); + + v2.addEventListener("loadeddata", function(ev) { + ok(true, case2token + " should reach loadeddata"); + var threw = false; + try { + var context = new AudioContext(); + context.createMediaElementSource(v2); + } catch (e) { + threw = true; + } + ok(!threw, "Should always work when creating a MediaElementSource."); + p1.resolve(); + }); + + manager.started(case2token); + let p2 = SetupEME(v2, test, case2token); + + Promise.all([p1.promise, p2]) + .catch(reason => ok(false, reason)) + .then(() => { + CleanUpMedia(v2); + manager.finished(case2token); + }); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gEMETests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_stream_capture_blocked_case3.html b/dom/media/test/test_eme_stream_capture_blocked_case3.html new file mode 100644 index 0000000000..e25a900956 --- /dev/null +++ b/dom/media/test/test_eme_stream_capture_blocked_case3.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function startTest(test, token) +{ + // Case 3. capturing a media element with mozCaptureStream that has a MediaKeys should fail. + var p1 = new EMEPromise; + var case3token = token + "_case3"; + let v3 = document.createElement("video"); + + v3.addEventListener("loadeddata", function(ev) { + ok(true, TimeStamp(case3token) + " should reach loadeddata"); + var threw = false; + try { + v3.mozCaptureStreamUntilEnded(); + } catch (e) { + threw = true; + } + ok(threw, TimeStamp(case3token) + " Should throw an error calling mozCaptureStreamUntilEnded an EME video."); + p1.resolve(); + }); + + manager.started(case3token); + let p2 = SetupEME(v3, test, case3token); + + Promise.all([p1.promise, p2]) + .catch(reason => ok(false, reason)) + .then(() => { + CleanUpMedia(v3); + manager.finished(case3token); + }); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gEMETests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_unsetMediaKeys_then_capture.html b/dom/media/test/test_eme_unsetMediaKeys_then_capture.html new file mode 100644 index 0000000000..3ecdc79dbf --- /dev/null +++ b/dom/media/test/test_eme_unsetMediaKeys_then_capture.html @@ -0,0 +1,108 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/* import-globals-from eme.js */ +var manager = new MediaTestManager; + +// Test that if we can capture a video frame while playing clear content after +// removing the MediaKeys object which was used for a previous encrypted content +// playback on the same video element +function startTest(test, token) +{ + manager.started(token); + var sessions = []; + function onSessionCreated(session) { + sessions.push(session); + } + + function closeSessions() { + let p = new EMEPromise; + Promise.all(sessions.map(s => s.close())) + .then(p.resolve, p.reject); + return p.promise; + } + + let v = document.createElement("video"); + document.body.appendChild(v); + + let finish = new EMEPromise; + + function onVideoEnded(ev) { + ok(true, TimeStamp(token) + " (ENCRYPTED) content playback ended."); + + function playClearVideo() { + var p1 = once(v, 'loadeddata', (e) => { + ok(true, TimeStamp(token) + " Receiving event 'loadeddata' for (CLEAR) content."); + let canvasElem = document.createElement('canvas'); + document.body.appendChild(canvasElem); + let ctx2d = canvasElem.getContext('2d'); + + var gotTypeError = false; + try { + ctx2d.drawImage(v, 0, 0); + } catch (ex) { + if (ex instanceof TypeError) { + gotTypeError = true; + } + } + ok(!gotTypeError, TimeStamp(token) + " Canvas2D context drawImage succeed.") + }); + v.src = 'bipbop_225w_175kbps.mp4'; + v.play(); + Promise.all([p1]).then(() => { + manager.finished(token); + }, () => { + ok(false, TimeStamp(token) + " Something wrong."); + manager.finished(token); + }); + } + + closeSessions() + .then(() => { + v.setMediaKeys(null) + .then(() => { + ok(true, TimeStamp(token) + " Setting MediaKeys to null."); + playClearVideo(); + }, () => { + ok(false, TimeStamp(token) + " Setting MediaKeys to null."); + });; + }); + } + + once(v, "ended", onVideoEnded); + + // Create a MediaKeys object and set to HTMLMediaElement then start the playback. + Promise.all([ + LoadInitData(v, test, token), + CreateAndSetMediaKeys(v, test, token), + LoadTest(test, v, token)]) + .then(values => { + let initData = values[0]; + v.play(); + initData.map(ev => { + let session = v.mediaKeys.createSession(); + onSessionCreated(session); + MakeRequest(test, token, ev, session); + }); + }) + .then(() => { + return finish.promise; + }) + .catch(reason => ok(false, reason)) +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gEMETests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_waitingforkey.html b/dom/media/test/test_eme_waitingforkey.html new file mode 100644 index 0000000000..c12a3b228f --- /dev/null +++ b/dom/media/test/test_eme_waitingforkey.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Encrypted Media Extensions</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/* import-globals-from eme.js */ +var manager = new MediaTestManager; + +function startTest(test, token) +{ + manager.started(token); + + let v = document.createElement("video"); + document.body.appendChild(v); + + var gotWaitingForKey = 0; + var gotOnwaitingforkey = 0; + + let waitForKey = new EMEPromise; + v.addEventListener("waitingforkey", function() { + gotWaitingForKey += 1; + waitForKey.resolve(); + }); + + v.onwaitingforkey = function() { + gotOnwaitingforkey += 1; + }; + + v.addEventListener("loadedmetadata", function() { + ok(SpecialPowers.do_lookupGetter(v, "isEncrypted").apply(v), + TimeStamp(token) + " isEncrypted should be true"); + is(v.isEncrypted, undefined, "isEncrypted should not be accessible from content"); + }); + + let finish = new EMEPromise; + v.addEventListener("ended", function() { + ok(true, TimeStamp(token) + " got ended event"); + // We expect only one waitingForKey as we delay until all sessions are ready. + // I.e. one waitingForKey should be fired, after which, we process all sessions, + // so it should not be possible to be blocked by a key after that point. + ok(gotWaitingForKey == 1, "Expected number 1 wait, got: " + gotWaitingForKey); + ok(gotOnwaitingforkey == gotWaitingForKey, "Should have as many event listener calls as event handler calls, got: " + gotOnwaitingforkey); + + finish.resolve(); + }); + + Promise.all([ + LoadInitData(v, test, token), + CreateAndSetMediaKeys(v, test, token), + LoadTest(test, v, token), + waitForKey.promise]) + .then(values => { + let initData = values[0]; + return ProcessInitData(v, test, token, initData); + }) + .then(sessions => { + Log(token, "Updated all sessions, loading complete -> Play"); + v.play(); + finish.promise.then(() => CloseSessions(v, sessions)); + return finish.promise; + }) + .catch(reason => ok(false, reason)) + .then(() => manager.finished(token)); +} + +SimpleTest.waitForExplicitFinish(); +manager.runTests(gEMETests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_eme_wideinve_l1_installation.html b/dom/media/test/test_eme_wideinve_l1_installation.html new file mode 100644 index 0000000000..fa6a0c350b --- /dev/null +++ b/dom/media/test/test_eme_wideinve_l1_installation.html @@ -0,0 +1,86 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Widevine L1 installation</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<script class="testbody" type="text/javascript"> + +// This test mostly follows the patten of test_eme_request_notifications.html. + +var manager = new MediaTestManager; + +function SetPrefs(prefs) { + return SpecialPowers.pushPrefEnv({"set": prefs}); +} + +function observe() { + return new Promise(function(resolve, reject) { + var observer = function(subject, topic, data) { + SpecialPowers.Services.obs.removeObserver(observer, "mediakeys-request"); + resolve(JSON.parse(data).status); + }; + SpecialPowers.Services.obs.addObserver(observer, "mediakeys-request"); + }); +} + +function Test(test) { + var p = test.prefs ? SetPrefs(test.prefs) : Promise.resolve(); + var name = "'" + test.keySystem + "'"; + + var res = observe().then((status) => { + is(status, test.expectedStatus, name + " expected status"); + }); + + p.then(() => navigator.requestMediaKeySystemAccess(test.keySystem, gCencMediaKeySystemConfig)) + .then((keySystemAccess) => keySystemAccess.createMediaKeys()); + + return res; +} + +SimpleTest.waitForExplicitFinish(); + +const tests = [ + // GMP L1 pref is disabled + { + keySystem: "com.widevine.alpha.experiment", + expectedStatus: 'cdm-disabled', + prefs: [ + ["media.eme.enabled", true], + ["media.wmf.media-engine.enabled", 2], + ["media.eme.widevine.experiment.enabled", true], + ["media.gmp-widevinecdm-l1.enabled", false], + ] + }, + { + keySystem: "com.widevine.alpha.experiment2", + expectedStatus: 'cdm-disabled', + }, + // Enable GMP L1 pref + { + keySystem: "com.widevine.alpha.experiment", + expectedStatus: 'cdm-not-installed', + prefs: [ + ["media.gmp-widevinecdm-l1.enabled", true], + ] + }, + { + keySystem: "com.widevine.alpha.experiment2", + expectedStatus: 'cdm-not-installed', + }, +]; + +tests.reduce(function(p, c, i, array) { + return p.then(function() { + return Test(c); + }); +}, Promise.resolve()) +.then(SimpleTest.finish); + +</script> +</body> +</html> diff --git a/dom/media/test/test_eme_wv_privacy.html b/dom/media/test/test_eme_wv_privacy.html new file mode 100644 index 0000000000..a050d2a528 --- /dev/null +++ b/dom/media/test/test_eme_wv_privacy.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test generating encrypted request in Widevine privacy mode</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="eme.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function Test() { + return new Promise(function(resolve, reject) { + var configs = [{ + initDataTypes: ['keyids'], + videoCapabilities: [{contentType: 'video/mp4' }], + }]; + navigator.requestMediaKeySystemAccess('com.widevine.alpha', configs) + .then((access) => access.createMediaKeys(), + (e) => { throw e; }) + .then((mediaKeys) => { + var session = mediaKeys.createSession('temporary'); + session.addEventListener('message', event => { + is(event.messageType, 'license-request', + 'MediaKeyMessage type should be license-request.'); + const request = new Uint8Array(event.message); + info('request generated[' + request.length + ']: [' + request + ']'); + ok(request.length == 2 && request[0] == 0x08 && request[1] == 0x04, + 'Widevine license request should be [0x08, 0x04] in privacy mode'); + session.close().then(() => { resolve(); }); + }); + return session.generateRequest('keyids', + new TextEncoder().encode('{"kids":["MDAwMDAwMDAwMDAwMDAwMQ=="]}')); + }, + (e) => { throw e; }) + .catch((e) => { + is(e.name, 'NotSupportedError', + 'Should only be rejected when "not supported"'); + resolve(); + }); + }); +} + +SimpleTest.waitForExplicitFinish(); +Test().then(function() { + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_empty_resource.html b/dom/media/test/test_empty_resource.html new file mode 100644 index 0000000000..8f65bb503d --- /dev/null +++ b/dom/media/test/test_empty_resource.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1094549 +--> +<head> + <title>Test for Bug 1094549</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094549">Mozilla Bug 1094549</a> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +// Shorter timeout for this test should finish soon. +SimpleTest.requestLongerTimeout(0.3); + +function finish(v) { + isnot(v.error, null, "should've got an error event"); + SimpleTest.finish(); +} + +function onload() { + info("iframe loaded"); + var v = SpecialPowers.wrap(document.body.getElementsByTagName("iframe")[0]) + .contentDocument.body.getElementsByTagName("video")[0]; + + // Got 'error' as expected, finish the test. + if (v.error) { + finish(v); + return; + } + + // Otherwise, wait for it. + v.onerror = function() { + finish(v); + } +} + +SimpleTest.waitForExplicitFinish(); +var f = document.createElement("iframe"); +// Assign a resource file with zero length and expect the error event from +// the video element since decoding metadata will fail. +f.src = "data:video/webm,"; +f.addEventListener("load", onload); +document.body.appendChild(f); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_error_in_video_document.html b/dom/media/test/test_error_in_video_document.html new file mode 100644 index 0000000000..e376ea95e3 --- /dev/null +++ b/dom/media/test/test_error_in_video_document.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=604067 +--> +<head> + <title>Test for Bug 604067</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=604067">Mozilla Bug 604067</a> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 604067 **/ + +function documentVideo() { + return document.body.getElementsByTagName("iframe")[0] + .contentDocument.body.getElementsByTagName("video")[0]; +} + +function check() { + var v = documentVideo(); + + // Debug info for Bug 608634 + ok(true, "iframe src=" + document.body.getElementsByTagName("iframe")[0].src); + is(v.readyState, v.HAVE_NOTHING, "Ready state"); + + isnot(v.error, null, "Error object"); + is(v.networkState, v.NETWORK_NO_SOURCE, "Network state"); + is(v.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, "Expected media not supported error"); + SimpleTest.finish(); +} + +// Find an error test that we'd think we should be able to play (if it +// wasn't already known to fail). +var t = getPlayableVideo(gErrorTests); +if (!t) { + todo(false, "No types supported"); +} else { + SimpleTest.waitForExplicitFinish(); + + var f = document.createElement("iframe"); + f.src = t.name; + f.addEventListener("load", check); + document.body.appendChild(f); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_error_on_404.html b/dom/media/test/test_error_on_404.html new file mode 100644 index 0000000000..8f82b8a07e --- /dev/null +++ b/dom/media/test/test_error_on_404.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=476731 +--> +<head> + <title>Test for Bug 476731</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=476731">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 476731 **/ + +var videos = []; + +function FinishedLoads() { + if (!videos.length) + return false; + for (var i=0; i<videos.length; ++i) { + if (videos[i]._loadedData) { + // A video loadeddata, it should have 404'd. Signal the end of the test + // so the error will be reported. + return true; + } + if (!videos[i]._loadError) { + return false; + } + } + return true; +} + +function loadError(evt) { + var v = evt.target; + is(v._loadError, false, "Shouldn't receive multiple error events for " + v.src); + v._loadError = true; + is(v._loadStart, true, "Receive loadstart for " + v.src); + is(v._loadedData, false, "Shouldn't receive loadeddata for " + v.src); + if (FinishedLoads(videos)) + SimpleTest.finish(); +} + +function loadedData(evt) { + evt.target._loadedData = true; +} + +function loadStart(evt) { + evt.target._loadStart = true; +} + +// Create all video objects. +for (var i=0; i<g404Tests.length; ++i) { + var v = document.createElement("video"); + v.preload = "metadata"; + var test = g404Tests[i]; + if (!v.canPlayType(test.type)) { + continue; + } + v.src = test.name; + v._loadedData = false; + v._loadStart = false; + v._loadError = false; + v.addEventListener("error", loadError); + v.addEventListener("loadstart", loadStart); + v.addEventListener("loadeddata", loadedData); + document.body.appendChild(v); // Will start load. + videos.push(v); +} + +if (!videos.length) { + todo(false, "No types supported"); +} else { + SimpleTest.waitForExplicitFinish(); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_fastSeek-forwards.html b/dom/media/test/test_fastSeek-forwards.html new file mode 100644 index 0000000000..1e50021b13 --- /dev/null +++ b/dom/media/test/test_fastSeek-forwards.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1022913 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1022913</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1022913">Mozilla Bug 1022913</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + + // Test that if we're doing a fastSeek() forwards that we don't end up + // seeking backwards. This can happen if the keyframe before the seek + // target is before the current playback position. We'd prefer to seek to + // the keyframe after the seek target in this case, but we don't implement + // this yet (bug 1026330). + var manager = new MediaTestManager; + + var onSecondSeekComplete = function(event) { + var v = event.target; + v.removeEventListener("seeked", onSecondSeekComplete); + ok(v.currentTime >= v.firstSeekTarget, v.name + " seek never go backwards. time=" + v.currentTime + " firstSeekTarget=" + v.firstSeekTarget + " secondSeekTarget=" + v.secondSeekTarget); + manager.finished(v.token); + removeNodeAndSource(v); + }; + + var onFirstSeekComplete = function(event) { + var v = event.target; + v.removeEventListener("seeked", onFirstSeekComplete); + // Seek to 75% of the way between the start and the first keyframe + // using fastSeek. We then test that the currentTime doesn't drop back + // to the previous keyframe, currentTime should go forwards. + v.addEventListener("seeked", onSecondSeekComplete); + v.secondSeekTarget = v.keyframes[1] * 0.75; + v.fastSeek(v.secondSeekTarget); + } + + var onLoadedMetadata = function(event) { + // Seek to the mid-point between the start and the first keyframe. + var v = event.target; + v.removeEventListener("loadedmetadata", onLoadedMetadata); + v.addEventListener("seeked", onFirstSeekComplete); + v.firstSeekTarget = v.keyframes[1] * 0.5; + v.currentTime = v.firstSeekTarget; + } + + function startTest(test, token) { + manager.started(token); + let v = document.createElement("video"); + v.src = test.name; + v.name = test.name; + v.preload = "metadata"; + v.token = token; + v.target = 0; + v.keyframes = test.keyframes; + v.keyframeIndex = 0; + ok(v.keyframes.length >= 2, v.name + " - video should have at least two sync points"); + v.addEventListener("loadedmetadata", onLoadedMetadata); + document.body.appendChild(v); + } + + manager.runTests(gFastSeekTests, startTest); + + </script> +</body> +</html> diff --git a/dom/media/test/test_fastSeek.html b/dom/media/test/test_fastSeek.html new file mode 100644 index 0000000000..2245bcc9bf --- /dev/null +++ b/dom/media/test/test_fastSeek.html @@ -0,0 +1,88 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=778077 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 778077</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=778077">Mozilla Bug 778077</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + + /** Test for Bug 778077 - HTMLMediaElement.fastSeek() **/ + // Iterate through a list of keyframe timestamps, and seek to + // halfway between the keyframe and the keyframe after it. + var manager = new MediaTestManager; + + function doSeek(v) { + // fastSeek to half way between this keyframe and the next, or if this is the last + // keyframe seek to halfway between this keyframe and the end of media. + var nextKeyFrame = (v.keyframeIndex + 1) < v.keyframes.length ? v.keyframes[v.keyframeIndex + 1] : v.duration; + v.target = (v.keyframes[v.keyframeIndex] + nextKeyFrame) / 2; + v.fastSeek(v.target); + ok(Math.abs(v.currentTime - v.target) < 0.01, + v.name + " seekTo=" + v.target + " currentTime (" + v.currentTime + ") should be close to seek target initially"); + } + + function onloadedmetadata(event) { + var v = event.target; + doSeek(v); + } + + function onseeked(event) { + var v = event.target; + var keyframe = v.keyframes[v.keyframeIndex]; + + // Check that the current time ended up roughly after the keyframe. + // We must be a bit fuzzy here, as the decoder backend may actually + // seek to the audio sample prior to the keyframe. + ok(v.currentTime >= keyframe - 0.05, + v.name + " seekTo=" + v.target + " currentTime (" + v.currentTime + + ") should be end up roughly after keyframe (" + keyframe + ") after fastSeek"); + + ok(v.currentTime <= v.target, + v.name + " seekTo=" + v.target + " currentTime (" + v.currentTime + + ") should be end up less than target after fastSeek"); + + v.keyframeIndex++ + if (v.keyframeIndex == v.keyframes.length) { + v.src = ""; + v.remove(); + manager.finished(v.token); + } else { + doSeek(v); + } + } + + function startTest(test, token) { + manager.started(token); + let v = document.createElement("video"); + v.src = test.name; + v.name = test.name; + v.preload = "metadata"; + v.token = token; + v.target = 0; + v.keyframes = test.keyframes; + v.keyframeIndex = 0; + ok(v.keyframes.length, v.name + " - video should have at least one sync point"); + v.addEventListener("loadedmetadata", onloadedmetadata); + v.addEventListener("seeked", onseeked); + document.body.appendChild(v); + } + + manager.runTests(gFastSeekTests, startTest); + + </script> +</body> +</html> diff --git a/dom/media/test/test_fragment_noplay.html b/dom/media/test/test_fragment_noplay.html new file mode 100644 index 0000000000..6a1119f342 --- /dev/null +++ b/dom/media/test/test_fragment_noplay.html @@ -0,0 +1,127 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: fragment tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="fragment_noplay.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +// Fragment parameters to try +var gFragmentParams = [ + // W3C Media fragment tests + // http://www.w3.org/2008/WebVideo/Fragments/TC/ua-test-cases + { fragment: "#t=banana", start: null, end: null }, // TC0027-UA + { fragment: "#t=3,banana", start: null, end: null }, // TC0028-UA + { fragment: "#t=banana,7", start: null, end: null }, // TC0029-UA + { fragment: "#t='3'", start: null, end: null }, // TC0030-UA + { fragment: "#t=3-7", start: null, end: null }, // TC0031-UA + { fragment: "#t=3:7", start: null, end: null }, // TC0032-UA + { fragment: "#t=3,7,9", start: null, end: null }, // TC0033-UA + { fragment: "#t%3D3", start: null, end: null }, // TC0034-UA + { fragment: "#%74=3", start: 3, end: null }, // TC0035-UA + { fragment: "#t=%33", start: 3, end: null }, // TC0036-UA + { fragment: "#t=3%2C7", start: 3, end: 7 }, // TC0037-UA + { fragment: "#t=%6Ept:3", start: 3, end: null }, // TC0038-UA + { fragment: "#t=npt%3A3", start: 3, end: null }, // TC0039-UA + { fragment: "#t=-1,3", start: null, end: null }, // TC0044-UA + { fragment: "#t=3&", start: 3, end: null }, // TC0051-UA + { fragment: "#u=12&t=3", start: 3, end: null }, // TC0052-UA + { fragment: "#t=foo:7&t=npt:3", start: 3, end: null }, // TC0053-UA + { fragment: "#&&=&=tom&jerry=&t=3&t=meow:0#", start: 3, end: null }, // TC0054-UA + { fragment: "#t=7&t=3", start: 3, end: null }, // TC0055-UA + { fragment: "#T=3,7", start: null, end: null }, // TC0058-UA + { fragment: "#t=", start: null, end: null }, // TC0061-UA + { fragment: "#t=.", start: null, end: null }, // TC0062-UA + { fragment: "#t=.0", start: null, end: null }, // TC0063-UA + { fragment: "#t=0s", start: null, end: null }, // TC0064-UA + { fragment: "#t=,0s", start: null, end: null }, // TC0065-UA + { fragment: "#t=0s,0s", start: null, end: null }, // TC0066-UA + { fragment: "#t=00:00:00s", start: null, end: null }, // TC0067-UA + { fragment: "#t=s", start: null, end: null }, // TC0068-UA + { fragment: "#t=npt:", start: null, end: null }, // TC0069-UA + { fragment: "#t=1e-1:", start: null, end: null }, // TC0070-UA + { fragment: "#t=00:00:01.1e-1", start: null, end: null }, // TC0071-UA + { fragment: "#t=3.", start: 3, end: null }, // TC0072-UA + { fragment: "#t=0:0:0", start: null, end: null }, // TC0073-UA + { fragment: "#t=0:00:60", start: null, end: null }, // TC0074-UA + { fragment: "#t=0:01:60", start: null, end: null }, // TC0075-UA + { fragment: "#t=0:60:00", start: null, end: null }, // TC0076-UA + { fragment: "#t=0:000:000", start: null, end: null }, // TC0077-UA + { fragment: "#t=00:00:03,00:00:07", start: 3, end: 7 }, // TC0078-UA + { fragment: "#t=3,00:00:07", start: 3, end: 7 }, // TC0079-UA + { fragment: "#t=00:00.", start: null, end: null }, // TC0080-UA + { fragment: "#t=0:00:00.", start: null, end: null }, // TC0081-UA + { fragment: "#t=0:00:10e-1", start: null, end: null }, // TC0082-UA + { fragment: "#t=0:00:60.000", start: null, end: null }, // TC0083-UA + { fragment: "#t=0:60:00.000", start: null, end: null }, // TC0084-UA + { fragment: "#t=3,7&t=foo", start: 3, end: 7 }, // TC0085-UA + { fragment: "#foo&t=3,7", start: 3, end: 7 }, // TC0086-UA + { fragment: "#t=3,7&foo", start: 3, end: 7 }, // TC0087-UA + { fragment: "#t=3,7&&", start: 3, end: 7 }, // TC0088-UA + { fragment: "#&t=3,7", start: 3, end: 7 }, // TC0089-UA + { fragment: "#&&t=3,7", start: 3, end: 7 }, // TC0090-UA + { fragment: "#&t=3,7&", start: 3, end: 7 }, // TC0091-UA + { fragment: "#t%3d10", start: null, end: null }, // TC0092-UA + { fragment: "#t=10%26", start: null, end: null }, // TC0093-UA + { fragment: "#&t=3,7,", start: null, end: null } // TC0094-UA +]; + +function createTestArray() { + var tests = []; + var tmpVid = document.createElement("video"); + + for (var testNum=0; testNum<gFragmentTests.length; testNum++) { + var test = gFragmentTests[testNum]; + if (!tmpVid.canPlayType(test.type)) { + continue; + } + + for (var fragNum=0; fragNum<gFragmentParams.length; fragNum++) { + var p = gFragmentParams[fragNum]; + var t = {}; + t.name = test.name + p.fragment; + t.type = test.type; + t.duration = test.duration; + t.start = p.start; + t.end = p.end; + tests.push(t); + } + } + return tests; +} + +function startTest(test, token) { + var video = document.createElement('video'); + manager.started(token); + video.preload = "metadata"; + video.src = test.name; + video.token = token; + video.controls = true; + document.body.appendChild(video); + var name = test.name + " fragment test"; + var localIs = function(n) { return function(a, b, msg) { + is(a, b, n + ": " + msg); + }}(name); + var localOk = function(n) { return function(a, msg) { + ok(a, n + ": " + msg); + }}(name); + var localFinish = function(v, m) { return function() { + removeNodeAndSource(v); + m.finished(v.token); + }}(video, manager); + window.test_fragment_noplay(video, test.start, test.end, localIs, localOk, localFinish); +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_fragment_play.html b/dom/media/test/test_fragment_play.html new file mode 100644 index 0000000000..eab422bab1 --- /dev/null +++ b/dom/media/test/test_fragment_play.html @@ -0,0 +1,91 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="fragment_play.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +PARALLEL_TESTS = 1; +var manager = new MediaTestManager; + +// Fragment parameters to try. These tests +// try playing the video. Tests for other fragment +// formats are in test_fragment_noplay.html. +var gFragmentParams = [ + { fragment: "", start: null, end: null }, + { fragment: "#t=,", start: null, end: null }, + { fragment: "#t=3,3", start: null, end: null }, + { fragment: "#t=7,3", start: null, end: null }, + { fragment: "#t=7,15", start: 7, end: null }, + { fragment: "#t=15,20", start: 9.287982, end: null }, + { fragment: "#t=5", start: 5, end: null }, + { fragment: "#t=5.5", start: 5.5, end: null }, + { fragment: "#t=5,", start: null, end: null }, + { fragment: "#t=,5", start: 0, end: 5, todo: "See bugs 682141 and 720248" }, + { fragment: "#t=2.5,5.5", start: 2.5, end: 5.5, todo: "See bugs 682141 and 720248" }, + { fragment: "#t=1,2.5", start: 1, end: 2.5, todo: "See bugs 682141 and 720248" }, + { fragment: "#t=,15", start: 0, end: null } +]; + +function createTestArray() { + var tests = []; + var tmpVid = document.createElement("video"); + + for (var testNum=0; testNum<gFragmentTests.length; testNum++) { + var test = gFragmentTests[testNum]; + if (!tmpVid.canPlayType(test.type)) { + continue; + } + + for (var fragNum=0; fragNum<gFragmentParams.length; fragNum++) { + var p = gFragmentParams[fragNum]; + var t = {}; + t.name = test.name + p.fragment; + t.type = test.type; + t.duration = test.duration; + t.start = p.start; + t.end = p.end; + t.todo = p.todo; + tests.push(t); + } + } + return tests; +} + +function startTest(test, token) { + if (test.todo) { + todo(false, test.todo); + return; + } + var video = document.createElement('video'); + manager.started(token); + video.preload = "metadata"; + video.src = test.name; + video.token = token; + video.controls = true; + document.body.appendChild(video); + var name = test.name + " fragment test"; + var localIs = function(n) { return function(a, b, msg) { + is(a, b, n + ": " + msg); + }}(name); + var localOk = function(n) { return function(a, msg) { + ok(a, n + ": " + msg); + }}(name); + var localFinish = function(v, m) { return function() { + removeNodeAndSource(v); + m.finished(v.token); + }}(video, manager); + window.test_fragment_play(video, test.start, test.end, localIs, localOk, localFinish); +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_hevc_playback.html b/dom/media/test/test_hevc_playback.html new file mode 100644 index 0000000000..6327008102 --- /dev/null +++ b/dom/media/test/test_hevc_playback.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test HEVC video playback</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +/** + * This test is used to check whether non-MSE HEVC video can be played on the + * platform. HEVC can only be played if we have platform decoder supports + * hardware decoding. Currently we can only do that on Windows. + */ +add_task(async function testHEVCPlayback() { + let video = document.createElement('video'); + info(`try to play HEVC video`); + video.src = "hevc_white_frame.mp4"; + video.controls = true; + document.body.appendChild(video); + ok(await video.play().then(_=>true, _=>false), "video started playing"); + ok(await new Promise(r => video.onended = r).then(_=>true, _=>false), + "video played to end"); + +}); + + +// This test video contains an inband SPS that is different from the SPS in the +// extradata, so we would recreate a new decoder. +add_task(async function testHEVCInbandConfigChange() { + let video = document.createElement('video'); + info(`try to play HEVC video`); + video.src = "hevc_white_red_frames.mp4"; + video.playbackRate = 2.0; // speed up the test. + video.controls = true; + document.body.appendChild(video); + ok(await video.play().then(_=>true, _=>false), "video started playing"); + ok(await new Promise(r => video.onended = r).then(_=>true, _=>false), + "video played to end"); +}); + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/test_hevc_support.html b/dom/media/test/test_hevc_support.html new file mode 100644 index 0000000000..36fe44a500 --- /dev/null +++ b/dom/media/test/test_hevc_support.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test HEVC video support</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +/** + * This test is used to check we can get correct HEVC support information from + * `canPlayType` and mediaCapabilities API on different platforms. + */ +add_task(async function testHEVCSupport() { + const os = SpecialPowers.Services.appinfo.OS; + + const contentType = 'video/mp4; codecs="hev1.1.6.L93.B0"'; + const canPlay = document.createElement('video').canPlayType(contentType); + if (os == "WINNT") { + ok(canPlay != "", `HEVC is supported`); + } else { + ok(canPlay == "", "HEVC is not supported on current platform"); + } + + const videoConfiguration = { + type: "file", + video: { + contentType, + width: 1920, + height: 1080, + bitrate: 1000000, + framerate: 30, + }, + }; + const capability = await navigator.mediaCapabilities.decodingInfo(videoConfiguration); + if (os == "WINNT") { + ok(capability.supported, `HEVC is supported`); + ok(capability.powerEfficient, `HEVC is powerEfficient`); + } else { + ok(!capability.supported, "HEVC is not supported on current platform"); + } +}); + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/test_hls_player_independency.html b/dom/media/test/test_hls_player_independency.html new file mode 100644 index 0000000000..cea5c140ed --- /dev/null +++ b/dom/media/test/test_hls_player_independency.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test playback of 2 HLS video at the same page </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> + <div id='player1'> + <video id='player4x3' controls autoplay> + </video> + </div> + <p> 4x3 basic stream<span> + <span> + <div height = 10> + <span> + <div id='player2'> + <video id='player16x9' controls autoplay> + </video> + </div> + <p> 16x9 basic stream<span> + +<script class="testbody" type="text/javascript"> + +function startTest() { + var v4x3 = document.getElementById('player4x3'); + var v16x9 = document.getElementById('player16x9'); + + var p1 = once(v4x3, 'ended', function onended(e) { + is(v4x3.videoWidth, 400, "4x3 content, the width should be 400."); + is(v4x3.videoHeight, 300, "4x3 content, the height should be 300."); + }); + + var p2 = once(v16x9, 'ended', function onended(e) { + is(v16x9.videoWidth, 416, "16x9 content, the width should be 416."); + is(v16x9.videoHeight, 234, "16x9 content, the height should be 234."); + }); + + v4x3.src = serverUrl + "/bipbop_4x3_single.m3u8"; + v16x9.src = serverUrl + "/bipbop_16x9_single.m3u8"; + Promise.all([p1, p2]).then(() => { + SimpleTest.finish(); + }); +} + +startTest(); +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_hw_video_decoding.html b/dom/media/test/test_hw_video_decoding.html new file mode 100644 index 0000000000..f93ab9b0a8 --- /dev/null +++ b/dom/media/test/test_hw_video_decoding.html @@ -0,0 +1,119 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test video hardware decoding</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +/** + * This test is used to check hardware video decoding on different platforms. + */ +const PLATFORMS = { + // TODO : add Linux and Android, media-gpu doesn't run on them yet + WINNT: { + process: "GPU", + tests: [ + { + file: "gizmo.mp4", + decoder: "wmf H264 codec hardware video decoder", + }, + // TODO : enable VP9 for Windows. The current machine on CI doesn't + // support VP9 HW. See bug 1861755. + // { + // file: "gizmo.webm", + // decoder: "wmf VP9 codec hardware video decoder", + // }, + // TODO : add AV1, see bug 1861501. + ], + }, + Darwin: { + process: "RDD", + tests: [ + { + file: "gizmo.mp4", + decoder: "apple hardware VT decoder", + }, + // TODO : enable VP9 for MacOS. The current machine on CI doesn't support + // VP9 HW. See bug 1861741. + // { + // file: "gizmo.webm", + // decoder: "apple hardware VT decoder", + // }, + ], + }, +}; + +add_task(async function testHardwareVideoDecoding() { + const platformName = SpecialPowers.Services.appinfo.OS; + const platformTest = PLATFORMS[platformName]; + for (const test of platformTest.tests) { + info( + `Testing ${test.file} on ${platformName} : expect ${test.decoder} in ${platformTest.process}` + ); + await createAndPlayVideo(test.file); + await assertRunningProcessAndDecoderName({ + expectedProcess: platformTest.process, + expectedDecoder: test.decoder, + }); + await waitVideoPlayToEnd(); + } +}); + +// Following are helper functions +async function createAndPlayVideo(fileUrl) { + const video = document.createElement("video"); + document.body.appendChild(video); + video.src = fileUrl; + ok( + await video.play().then( + () => true, + () => false + ), + "video started playing" + ); + // Waiting for timeupdate to ensure the video decoder has been created + // correctly. + await new Promise(r => (video.ontimeupdate = r)); +} + +async function assertRunningProcessAndDecoderName( + { expectedProcess, expectedDecoder } = {} +) { + const video = document.querySelector("video"); + ok(!video.paused, "checking a playing video that should be hw decoding"); + + const debugInfo = await SpecialPowers.wrap(video).mozRequestDebugInfo(); + const videoDecoderName = debugInfo.decoder.reader.videoDecoderName; + + const isExpectedDecoder = + videoDecoderName.indexOf(`${expectedDecoder}`) == 0; + ok( + isExpectedDecoder, + `Playback running by decoder '${videoDecoderName}', expected '${expectedDecoder}'` + ); + + const isExpectedProcess = + videoDecoderName.indexOf(`(${expectedProcess} remote)`) > 0; + ok( + isExpectedProcess, + `Playback running in process '${videoDecoderName}', expected '${expectedProcess}'` + ); +} + +async function waitVideoPlayToEnd() { + const video = document.querySelector("video"); + if (video.ended) { + ok(true, "video reached to end!"); + } else { + await new Promise(r => (video.onended = r)); + } + // Remove current video so that we can check next video later. + document.body.removeChild(video); +} + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/test_imagecapture.html b/dom/media/test/test_imagecapture.html new file mode 100644 index 0000000000..d61dd358bb --- /dev/null +++ b/dom/media/test/test_imagecapture.html @@ -0,0 +1,128 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1041393 +--> +<head> + <meta charset="utf-8"> + <title>ImageCapture tests</title> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1041393">ImageCapture tests</a> +<script type="application/javascript"> + +// Check if the callback returns even no JS reference on it. +async function gcTest(track) { + const repeat = 100; + const promises = []; + for (let i = 0; i < repeat; ++i) { + const imageCapture = new ImageCapture(track); + promises.push(new Promise((resolve, reject) => { + imageCapture.onphoto = resolve; + imageCapture.onerror = () => + reject(new Error(`takePhoto gcTest failure for capture ${i}`)); + })); + imageCapture.takePhoto(); + } + info("Call gc "); + SpecialPowers.gc(); + await Promise.all(promises); +} + +// Continue calling takePhoto() in rapid succession. +async function rapidTest(track) { + const repeat = 100; + const imageCapture = new ImageCapture(track); + // "error" can fire synchronously in `takePhoto` + const errorPromise = new Promise(r => imageCapture.onerror = r); + for (let i = 0; i < repeat; ++i) { + imageCapture.takePhoto(); + } + for (let i = 0; i < repeat; ++i) { + await Promise.race([ + new Promise(r => imageCapture.onphoto = r), + errorPromise.then(() => Promise.reject(new Error("Capture failed"))), + ]); + } +} + +// Check if the blob is decodable. +async function blobTest(track) { + const imageCapture = new ImageCapture(track); + // "error" can fire synchronously in `takePhoto` + const errorPromise = new Promise(r => imageCapture.onerror = r); + imageCapture.takePhoto(); + const blob = await Promise.race([ + new Promise(r => imageCapture.onphoto = r), + errorPromise.then(() => Promise.reject(new Error("Capture failed"))), + ]); + + const img = new Image(); + img.src = URL.createObjectURL(blob.data); + await new Promise((resolve, reject) => { + img.onload = resolve; + img.onerror = () => reject(new Error("Decode failed")); + }); +} + +// It should return an error event after disabling video track. +async function trackTest(track) { + const imageCapture = new ImageCapture(track); + track.enabled = false; + try { + const errorPromise = new Promise(r => imageCapture.onerror = r); + imageCapture.takePhoto(); + const error = await Promise.race([ + errorPromise, + new Promise(r => imageCapture.onphoto = r).then( + () => Promise.reject(new Error("Disabled video track should fail"))), + ]); + is(error.imageCaptureError.code, error.imageCaptureError.PHOTO_ERROR, + "Expected error code") + } finally { + track.enabled = true; + } +} + +async function init() { + // Use loopback camera if available, otherwise fake. + // MediaTrackGraph will be the backend of ImageCapture. + await setupGetUserMediaTestPrefs(); + let stream = await navigator.mediaDevices.getUserMedia({video: true}); + return stream.getVideoTracks()[0]; +} + +async function start() { + try { + const track = await init(); + info("ImageCapture track disable test."); + await trackTest(track); + info("ImageCapture blob test."); + await blobTest(track); + info("ImageCapture rapid takePhoto() test."); + await rapidTest(track); + info("ImageCapture multiple instances test."); + await gcTest(track); + } catch (e) { + ok(false, "Unexpected error during test: " + e); + } finally { + SimpleTest.finish(); + } +} + +SimpleTest.requestCompleteLog(); +SimpleTest.waitForExplicitFinish(); + +SpecialPowers.pushPrefEnv({ + "set": [ + ["dom.imagecapture.enabled", true], + ["media.navigator.permission.disabled", true], + ], +}, start); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_info_leak.html b/dom/media/test/test_info_leak.html new file mode 100644 index 0000000000..e09b63b031 --- /dev/null +++ b/dom/media/test/test_info_leak.html @@ -0,0 +1,174 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=478957 +--> +<head> + <title>Test for Bug 478957</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478957">Mozilla Bug 478957</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<div id="log" style="font-size: small;"></div> + +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 478957 **/ + +// Tests whether we leak events and state change info when loading stuff from local files from a webserver. + +var manager = new MediaTestManager; + +var gEventTypes = [ 'loadstart', 'progress', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'play', 'pause', 'loadedmetadata', 'loadeddata', 'waiting', 'playing', 'canplay', 'canplaythrough', 'seeking', 'seeked', 'timeupdate', 'ended', 'ratechange', 'durationchange', 'volumechange' ]; + +var gExpectedEvents = ['loadstart', 'error']; + +function createTestArray() { + var tests = []; + var tmpVid = document.createElement("video"); + + return makeInfoLeakTests().then(infoLeakTests => { + for (var testNum=0; testNum < infoLeakTests.length; testNum++) { + var test = infoLeakTests[testNum]; + if (!tmpVid.canPlayType(test.type)) { + continue; + } + + var t = {}; + t.name = test.src; + t.type = test.type; + + tests.push(t); + } + return tests; + }) +} + +function log(msg) { + info(msg); + var l = document.getElementById('log'); + l.innerHTML += msg + "<br>"; +} + +function finish(v) { + log("finish: " + v.name); + clearInterval(v.checkStateInterval); + + for (var i=0; i<gEventTypes.length; i++) { + v.removeEventListener(gEventTypes[i], listener); + } + removeNodeAndSource(v); + + manager.finished(v.token); + v = null; +} + +function listener(evt) { + var v = evt.target; + log(filename(v.name) + ': got ' + evt.type); + + // On slow machines like B2G emulator, progress timer could time out before + // receiving any HTTP notification. We will ignore the 'stalled' event to + // pass the tests. + if (evt.type == 'stalled') { + return; + } + + ok(v.eventNum < gExpectedEvents.length, filename(v.name) + " Too many events received"); + var expected = (v.eventNum < gExpectedEvents.length) ? gExpectedEvents[v.eventNum] : "NoEvent"; + is(evt.type, expected, filename(v.name) + " Events received in wrong order"); + v.eventNum++; + if (v.eventNum == gExpectedEvents.length) { + // In one second, move onto the next test. This give a chance for any + // other events to come in. Note: we don't expect any events to come + // in, unless we've leaked some info, and 1 second should be enough time + // for the leak to show up. + setTimeout(function() {finish(v);}, 1000); + } +} + +function createMedia(type, src, token) { + var tag = getMajorMimeType(type); + var v = document.createElement(tag); + for (var i=0; i<gEventTypes.length; i++) { + v.addEventListener(gEventTypes[i], listener); + } + v.preload = "metadata"; + v.src = src; + v.name = src; + document.body.appendChild(v); + v.eventNum = 0; + v.token = token; + setTimeout( + function() { + v.checkStateInterval = setInterval(function(){checkState(v);},1); + }, 0); +} + +// Define our own ok() and is() functions. The mochitest ones take ages constructing the log +// of all the passes, so only report failures. +function test_ok(b, msg) { + if (!b) { + log("FAILED test_ok: " + msg); + ok(b, msg); + } +} + +function test_is(a, b, msg) { + if (a != b) { + log("FAILED test_is: " + msg); + is(a,b,msg); + } +} + +function filename(uri) { + return uri.substr(uri.lastIndexOf("/")+1); +} + +function checkState(v) { + test_ok(v.networkState <= HTMLMediaElement.NETWORK_LOADING || + v.networkState == HTMLMediaElement.NETWORK_NO_SOURCE, + "NetworkState of " + v.networkState + " was leaked."); + test_ok(v.readyState == HTMLMediaElement.HAVE_NOTHING, + "Ready state of " + v.readyState + " was leaked"); + test_is(v.seeking, false, "Seeking leaked"); + test_is(v.currentTime, 0, "Leaked currentTime"); + test_ok(isNaN(v.duration), "Leaked duration"); + test_is(v.paused, true, "Paused leaked"); + test_is(v.ended, false, "Ended leaked"); + test_is(v.autoplay, false, "Autoplay leaked"); + test_is(v.controls, false, "Controls leaked"); + test_is(v.muted, false, "muted leaked"); + test_ok(v.error==null || v.error.code==MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, + "Error code should not exist or be SRC_NOT_SUPPORTED. v.error=" + + (v.error ? v.error.code : "null")); + test_ok(filename(v.currentSrc) == filename(v.name) || + v.networkState == HTMLMediaElement.NETWORK_NO_SOURCE, + "currentSrc should match candidate uri, if we've got a valid source"); +} + + +function startTest(test, token) { + manager.started(token); + log("Testing: " + test.type + " @ " + test.name); + createMedia(test.type, test.name, token); +} + +SimpleTest.waitForExplicitFinish(); +createTestArray().then(testArray => { + manager.runTests(testArray, startTest); +}); + +</script> +</pre> + +</body> +</html> diff --git a/dom/media/test/test_invalid_reject.html b/dom/media/test/test_invalid_reject.html new file mode 100644 index 0000000000..583847fe12 --- /dev/null +++ b/dom/media/test/test_invalid_reject.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8" /> + <title>Test rejection of invalid files</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var v = document.createElement('video'); + manager.started(token); + + // Set up event handlers. Seeing any of these is a failure. + function badEvent(type) { return function(e) { + ok(false, test.name + " should not fire '" + type + "' event"); + }}; + var events = [ + 'loadeddata', 'load', + 'canplay', 'canplaythrough', + 'playing' + ]; + events.forEach( function(e) { + v.addEventListener(e, badEvent(e)); + }); + + // Seeing a decoder error is a success. + v.addEventListener("error", function onerror(e) { + if (v.readyState == v.HAVE_NOTHING) { + is(v.error.code, v.error.MEDIA_ERR_SRC_NOT_SUPPORTED, + "decoder should reject " + test.name); + } else { + is(v.error.code, v.error.MEDIA_ERR_DECODE, + "decoder should reject " + test.name); + } + v.removeEventListener('error', onerror); + manager.finished(token); + }); + + // Now try to load and play the file, which should result in the + // error event handler above being called, terminating the test. + document.body.appendChild(v); + v.src = test.name; + v.play(); +} + +manager.runTests(gInvalidTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_invalid_reject_play.html b/dom/media/test/test_invalid_reject_play.html new file mode 100644 index 0000000000..3e658f94b8 --- /dev/null +++ b/dom/media/test/test_invalid_reject_play.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8" /> + <title>Test rejection of invalid files during playback</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var v = document.createElement('video'); + manager.started(token); + + // Seeing a decoder error is a success. + v.addEventListener("error", function onerror(e) { + is(v.error.code, v.error.MEDIA_ERR_DECODE, + "decoder should reject " + test.name); + v.removeEventListener("error", onerror); + manager.finished(token); + }); + + v.addEventListener("ended", function onended(e) { + ok(false, "decoder should have rejected file before playback ended"); + v.removeEventListener("ended", onended); + manager.finished(token); + }); + + document.body.appendChild(v); + v.src = test.name; + v.play(); +} + +manager.runTests(gInvalidPlayTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_invalid_seek.html b/dom/media/test/test_invalid_seek.html new file mode 100644 index 0000000000..8aa514b977 --- /dev/null +++ b/dom/media/test/test_invalid_seek.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: invalide seek test</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<video id='v'></video> +<pre id="test"> +<script class="testbody" type="text/javascript"> +// http://www.whatwg.org/specs/web-apps/current-work/#dom-media-seek +// If the media element's readyState is HAVE_NOTHING, then the user agent +// must raise an InvalidStateError exception. +var v = document.getElementById('v'); +var passed = false; + +ok(v.readyState == HTMLMediaElement.HAVE_NOTHING, + "Invalid ready state in media element"); + +try { + v.seek(1); +} +catch(e) { + passed = true; +} + +ok(passed, "Video did not raise error during invalid seek"); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_load.html b/dom/media/test/test_load.html new file mode 100644 index 0000000000..de8fd63948 --- /dev/null +++ b/dom/media/test/test_load.html @@ -0,0 +1,217 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=479859 +--> +<head> + <title>Test for Bug 479859</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=479859">Mozilla Bug 479859</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="text/javascript"> + +function log(msg) { + //document.getElementById('log').innerHTML += "<p>" + msg + "</p>"; +} + +// We don't track: progress, canplay, canplaythrough and stalled events, +// as these can be delivered out of order, and/or multiple times. +var gEventTypes = [ 'loadstart', 'abort', 'error', 'emptied', 'play', + 'pause', 'loadedmetadata', 'loadeddata', 'waiting', 'playing', 'seeking', + 'seeked', 'timeupdate', 'ended', 'ratechange', 'durationchange', 'volumechange' ]; + +var gEventNum = 0; +var gTestNum = 0; +var gTestFileNum = 0; +var gExpectedEvents = null; +var gTest = null; +var gTestName = "?"; + +function listener(evt) { + log('event ' + evt.type); + ok(gEventNum < gExpectedEvents.length, gTestName+" - corrent number of events received"); + var expected = (gEventNum < gExpectedEvents.length) ? gExpectedEvents[gEventNum] : "NoEvent"; + is(evt.type, expected, gTestName+" - events received in order"); + gEventNum++; + if (gEventNum == gExpectedEvents.length) { + setTimeout(nextTest, 0); + } +} + +function source_error(evt) { + log('event source_error'); + ok(evt.type == "error", "Should only get error events here"); + ok(gEventNum < gExpectedEvents.length, gTestName+" - corrent number of events received"); + var expected = (gEventNum < gExpectedEvents.length) ? gExpectedEvents[gEventNum] : "NoEvent"; + is("source_error", expected, gTestName+" - events received in order"); + gEventNum++; + if (gEventNum == gExpectedEvents.length) { + setTimeout(nextTest, 0); + } +} + +var gMedia = null; + +function createMedia(tag) { + gMedia = document.createElement(tag); + gMedia.preload = "metadata"; + for (var i=0; i<gEventTypes.length; i++) { + gMedia.addEventListener(gEventTypes[i], listener); + } +} + +function addSource(src, type) { + var s = document.createElement("source"); + s.addEventListener("error", source_error); + s.src = src; + s.type = type; + gMedia.appendChild(s); + return s; +} + +function prependSource(src, type) { + var s = document.createElement("source"); + s.addEventListener("error", source_error); + s.src = src; + s.type = type; + gMedia.insertBefore(s, gMedia.firstChild); + return s; +} + +var gTests = [ + { + // Test 0: adding video to doc, then setting src should load implicitly. + create(src, type) { + document.body.appendChild(gMedia); + gMedia.src = src; + }, + expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata'] + }, { + // Test 1: adding video to doc, then adding source. + create(src, type) { + document.body.appendChild(gMedia); + addSource(src, type); + }, + expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata'] + },{ + // Test 2: video with multiple source, the first of which are bad, we should load the last, + // and receive error events for failed loads on the source children. + create(src, type) { + document.body.appendChild(gMedia); + addSource("404a", type); + addSource("404b", type); + addSource(src, type); + }, + expectedEvents: ['loadstart', 'source_error', 'source_error', 'durationchange', 'loadedmetadata', 'loadeddata'] + }, { + // Test 3: video with bad src, good <source>, ensure that <source> aren't used. + create(src, type) { + gMedia.src = "404a"; + addSource(src, type); + document.body.appendChild(gMedia); + }, + expectedEvents: ['loadstart', 'error'] + }, { + // Test 4: video with only bad source, loading, then adding a good source + // - should resume load. + create(src, type) { + addSource("404a", type); + var s2 = addSource("404b", type); + s2.addEventListener("error", + function(e) { + // Should awaken waiting load, causing successful load. + addSource(src, type); + }); + document.body.appendChild(gMedia); + }, + expectedEvents: ['loadstart', 'source_error', 'source_error', 'durationchange', 'loadedmetadata', 'loadeddata'] + }, { + // Test 5: video with only 1 bad source, let it fail to load, then prepend + // a good <source> to the video, it shouldn't be selected, because the + // "pointer" should be after the last child - the bad source. + prepended: false, + create(src, type) { + var prepended = false; + addSource("404a", type); + var s2 = addSource("404b", type); + s2.addEventListener("error", + function(e) { + // Should awaken waiting load, causing successful load. + if (!prepended) { + prependSource(src, type); + prepended = true; + } + }); + document.body.appendChild(gMedia); + }, + expectedEvents: ['loadstart', 'source_error', 'source_error'] + }, { + // Test 6: (Bug 1165203) preload="none" then followed by an explicit + // call to load() should load metadata + create(src, type) { + gMedia.preload = "none"; + gMedia.src = src; + document.body.appendChild(gMedia); + addSource(src, type); + gMedia.load(); + }, + expectedEvents: ['emptied', 'loadstart', 'durationchange', 'loadedmetadata', 'loadeddata'] + } +]; + +function nextTest() { + if (gMedia) { + for (var i=0; i<gEventTypes.length; i++) { + gMedia.removeEventListener(gEventTypes[i], listener); + } + removeNodeAndSource(gMedia); + gMedia = null; + } + gEventNum = 0; + + if (gTestNum == gTests.length) { + gTestNum = 0; + ++gTestFileNum; + if (gTestFileNum == gSmallTests.length) { + SimpleTest.finish(); + return; + } + } + + var src = gSmallTests[gTestFileNum].name; + var type = gSmallTests[gTestFileNum].type; + + var t = gTests[gTestNum]; + gTestNum++; + + createMedia(type.match(/^audio\//) ? "audio" : "video"); + if (!gMedia.canPlayType(type)) { + // Unsupported type, skip to next test + nextTest(); + return; + } + + gTestName = "Test " + src + " " + (gTestNum - 1); + log("Starting " + gTestName); + gExpectedEvents = t.expectedEvents; + + t.create(src, type); +} + +addLoadEvent(nextTest); +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> + +<div id="log" style="font-size: small"></div> +</body> +</html> diff --git a/dom/media/test/test_load_candidates.html b/dom/media/test/test_load_candidates.html new file mode 100644 index 0000000000..2bc1eb531b --- /dev/null +++ b/dom/media/test/test_load_candidates.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=465458 +--> +<head> + <title>Test for Bug 465458</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=465458">Mozilla Bug 465458</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 465458 **/ + +var manager = new MediaTestManager; + +function finish(evt) { + var v = evt.target; + is(v._error, 2, "Should have received 2 error events before loaded"); + v._finished = true; + // remove error event handler, because this would otherwise + // cause a failure on Windows 7, see bug 1024535 + v.onerror = null; + v.remove(); + manager.finished(v.token); +} + +function errorHandler(evt) { + evt.target.parentNode._error++; +} + +var extension = { + "audio/wav" : "wav", + "audio/x-wav": "wav", + "video/ogg" : "ogv", + "audio/ogg" : "oga", + "video/webm" : "webm" +}; + +function startTest(test, token) { + var v = document.createElement('video'); + v.preload = "auto"; + v.onerror = function(){ok(false,"Error events on source children should not bubble");} + v.token = token; + manager.started(token); + v._error = 0; + v._finished = false; + v._name = test.name; + + var s1 = document.createElement("source"); + s1.type = test.type; + s1.src = "404." + extension[test.type]; + s1.addEventListener("error", errorHandler); + v.appendChild(s1); + + var s2 = document.createElement("source"); + s2.type = test.type; + s2.src = "test_load_candidates.html"; // definitely an invalid media file, regardless of its actual mime type... + s2.addEventListener("error", errorHandler); + v.appendChild(s2); + + var s3 = document.createElement("source"); + s3.type = test.type; + s3.src = test.name; + v.appendChild(s3); + + v.addEventListener("loadeddata", finish); + document.body.appendChild(v); +} + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_load_same_resource.html b/dom/media/test/test_load_same_resource.html new file mode 100644 index 0000000000..f3e6992e8c --- /dev/null +++ b/dom/media/test/test_load_same_resource.html @@ -0,0 +1,106 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test loading of the same resource in multiple elements</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.requestCompleteLog(); +var manager = new MediaTestManager; + +function checkDuration(actual, expected, name) { + ok(Math.abs(actual - expected) < 0.1, + `${name} duration: ${actual} expected: ${expected}`); +} + +function cloneLoaded(event) { + var e = event.target; + ok(true, `${e.token} loaded OK`); + checkDuration(e.duration, e._expectedDuration, e.token); + removeNodeAndSource(e); + manager.finished(e.token); +} + +function tryClone(e) { + var clone = e.cloneNode(false); + clone.token = `${e.token}(cloned)`; + manager.started(clone.token); + manager.finished(e.token); + + // Log events for debugging. + var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", + "waiting", "pause"]; + function logEvent(evt) { + var event = evt.target; + info(`${event.token} got ${evt.type}`); + } + events.forEach(function(event) { + clone.addEventListener(event, logEvent); + }); + + + checkDuration(e.duration, e._expectedDuration, e.token); + clone._expectedDuration = e._expectedDuration; + + clone.addEventListener("loadeddata", cloneLoaded, {once: true}); + clone.addEventListener("loadstart", function(evt) { + info(`${evt.target.token} starts loading.`); + // Since there is only one H264 decoder instance, we have to delete the + // decoder of the original element for the cloned element to load. However, + // we can't delete the decoder too early otherwise cloning decoder will + // fail to kick in. We wait for 'loadstart' event of the cloned element to + // know when the decoder is already cloned and we can delete the decoder of + // the original element. + removeNodeAndSource(e); + }, {once: true}); +} + +// This test checks that loading the same URI twice in different elements at the same time +// uses the same resource without doing another network fetch. One of the gCloneTests +// uses dynamic_resource.sjs to return one resource on the first fetch and a different resource +// on the second fetch. These resources have different lengths, so if the cloned element +// does a network fetch it will get a resource with the wrong length and we get a test +// failure. + +async function initTest(test, token) { + var e = document.createElement("video"); + e.preload = "auto"; + e.src = test.name; + e._expectedDuration = test.duration; + ok(true, `Trying to load ${test.name}, duration=${test.duration}`); + e.token = token; + manager.started(token); + + // Since 320x240.ogv is less than 32KB, we need to wait for the + // 'suspend' event to ensure the partial block is flushed to the cache + // otherwise the cloned resource will create a new channel when it + // has no data to read at position 0. The new channel will download + // a different file than the original resource and fail the duration + // test. + let p1 = once(e, "loadeddata"); + let p2 = once(e, "suspend"); + await p1; + await p2; + tryClone(e); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + {"set": [ + ["logging.MediaDecoder", "Debug"], + ["logging.HTMLMediaElement", "Debug"], + ["logging.MediaCache", "Debug"], + ]}, + manager.runTests.bind(manager, gCloneTests, initTest)); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_load_source.html b/dom/media/test/test_load_source.html new file mode 100644 index 0000000000..95a925b61f --- /dev/null +++ b/dom/media/test/test_load_source.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=534571 +--> +<head> + <title>Test for Bug 534571</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=534571">Mozilla Bug 534571</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 534571 **/ + +// Test that when we load a video from a source child and then change the +// source's src attribute and load again, that the subsequent loads work. + +var v = null; +var s = null; + +function finish(event) { + ok(true, "Should have played both videos"); + SimpleTest.finish(); +} + +var first = null; +var second = null; + +function ended(event) { + s.type = second.type; + s.src = second.name; + v.removeEventListener("ended", ended); + v.addEventListener("ended", finish); + v.load(); +} + +// Find 2 videos we can play. +v = document.createElement('video'); +for (var i=0; i<gPlayTests.length; i++) { + if (!v.canPlayType(gPlayTests[i].type)) + continue; + if (!first) { + first = gPlayTests[i]; + } else if (!second) { + second = gPlayTests[i]; + break; + } +} + +if (first && second) { + s = document.createElement('source'); + s.type = first.type; + s.src = first.name; + v.appendChild(s); + v.autoplay = true; + v.addEventListener("ended", ended); + document.body.appendChild(v); + SimpleTest.waitForExplicitFinish(); +} else { + todo(false, "Need at least two media of supported types for this test!"); +} + + + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_load_source_empty_type.html b/dom/media/test/test_load_source_empty_type.html new file mode 100644 index 0000000000..9ceee9af46 --- /dev/null +++ b/dom/media/test/test_load_source_empty_type.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Load resource from source element with empty type</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="type"><source src="gizmo.mp4" type></video> +<video id="type-and-equal"><source src="gizmo.mp4" type=></video> +<video id="type-and-equal-quotation-marks"><source src="gizmo.mp4" type=""></video> +<script class="testbody" type="text/javascript"> +/** + * This test is used to ensure that media element can start loading when its + * child source element with empty type property. We would test following forms, + * `type`, `type=` and `type=""`. + */ +SimpleTest.waitForExplicitFinish(); + +const videos = document.getElementsByTagName("video"); +const videoNum = videos.length; +let loadedElementsNum = 0; + +for (let video of videos) { + video.addEventListener("loadeddata", + () => { + ok(true, `loaded element '${video.id}'`); + if (++loadedElementsNum == videoNum) { + SimpleTest.finish(); + } + }, { once: true}); +} +</script> +</body> +</html> diff --git a/dom/media/test/test_loop.html b/dom/media/test/test_loop.html new file mode 100644 index 0000000000..943059edad --- /dev/null +++ b/dom/media/test/test_loop.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test looping support</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + manager.started(token); + var v = document.createElement('video'); + v.token = token; + v.src = test.name; + v.name = test.name; + v.playCount = 0; + v.seekingCount = 0; + v.seekedCount = 0; + v.loop = true; + + v.addEventListener("play", function (e) { + e.target.playCount += 1; + ok(e.target.playCount == 1, "Should get exactly one play event."); + }); + + v.addEventListener("seeking", function (e) { + e.target.seekingCount += 1; + }); + + v.addEventListener("seeked", function (e) { + e.target.seekedCount += 1; + if (e.target.seekedCount == 2) { + ok(e.target.seekingCount == 2, "Expect matched pairs of seeking/seeked events."); + e.target.loop = false; + } + }); + + v.addEventListener("ended", function (e) { + ok(!e.target.loop, "Shouldn't get ended event while looping."); + removeNodeAndSource(e.target); + manager.finished(e.target.token); + }); + + document.body.appendChild(v); + v.play(); +} + +manager.runTests(gSmallTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_looping_eventsOrder.html b/dom/media/test/test_looping_eventsOrder.html new file mode 100644 index 0000000000..7d070de72f --- /dev/null +++ b/dom/media/test/test_looping_eventsOrder.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Looping events order</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<script type="text/javascript"> +/** + * This test is used to ensure the events order when media is looping back to + * the start position. We should see events in following order. + * 'seeking' -> 'timeupdate' -> 'seeked'. + */ +SimpleTest.waitForExplicitFinish(); + +var tests = [ + { name:"small-shot.ogg", type:"audio/ogg" }, + { name:"seek-short.webm", type:"video/webm" } +]; + +async function testTimeupdateChanged({name, type}) { + info(`- start testPlay for name=${name} -`); + const element = document.createElement(getMajorMimeType(type)); + element.src = name; + element.loop = true; + + await once(element, "canplay"); + ok(await element.play().then(() => true, () => false), `start playing ${name}`); + + let gotTimeUpdated = false; + await once(element, "seeking"); + element.addEventListener("timeupdate", function() { + gotTimeUpdated = true; + }, {once: true}); + await once(element, "seeked"); + ok(gotTimeUpdated, "Got timeupdate between seeking and seeked."); + + removeNodeAndSource(element); +} + +(async function startTest() { + for (let test of tests) { + await testTimeupdateChanged(test); + } + SimpleTest.finish(); +})(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_media_selection.html b/dom/media/test/test_media_selection.html new file mode 100644 index 0000000000..42f5a9bd43 --- /dev/null +++ b/dom/media/test/test_media_selection.html @@ -0,0 +1,142 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: media selection</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="application/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function maketest(attach_media, name, type, check_metadata) { + return function (token) { + var e = document.createElement('video'); + e.preload = "metadata"; + token = name + "-" + token; + manager.started(token); + var errorRun = false; + if (check_metadata) { + e.addEventListener('loadedmetadata', function () { + ok(e.readyState >= HTMLMediaElement.HAVE_METADATA, + 'test ' + token + ' readyState ' + e.readyState + ' expected >= ' + HTMLMediaElement.HAVE_METADATA); + is(e.currentSrc.substring(e.currentSrc.length - name.length), name, 'test ' + token); + // The load can go idle due to cache size limits + ok(e.networkState >= HTMLMediaElement.NETWORK_IDLE, + 'test ' + token + ' networkState = ' + e.networkState + ' expected >= ' + HTMLMediaElement.NETWORK_IDLE); + check_metadata(e); + removeNodeAndSource(e); + manager.finished(token); + }); + } else { + e.addEventListener('error', function onerror(event) { + is(errorRun, false, "error handler should run once only!"); + errorRun = true; + is(e.readyState, HTMLMediaElement.HAVE_NOTHING, + 'test ' + token + ' readyState should be HAVE_NOTHING when load fails.'); + e.removeEventListener('error', onerror, true); + removeNodeAndSource(e); + manager.finished(token); + }, true); + } + attach_media(e, name, type); + } +} + +function set_src(element, name, type) { + element.src = name; + document.body.appendChild(element); +} + +function add_source(element, name, type) { + do_add_source(element, name, type); + document.body.appendChild(element); +} + +function do_add_source(element, name, type) { + var source = document.createElement('source'); + if (type) { + source.type = type; + } + source.src = name; + element.appendChild(source); +} + +function add_sources_last(element, name, type) { + do_add_source(element, name, 'unsupported/type'); + do_add_source(element, name, type); + document.body.appendChild(element); +} + +function add_sources_first(element, name, type) { + do_add_source(element, name, type); + do_add_source(element, name, 'unsupported/type'); + document.body.appendChild(element); +} + +function late_add_sources_last(element, name, type) { + document.body.appendChild(element); + do_add_source(element, name, 'unsupported/type'); + do_add_source(element, name, type); +} + +function late_add_sources_first(element, name, type) { + document.body.appendChild(element); + do_add_source(element, name, type); + do_add_source(element, name, 'unsupported/type'); +} + +var nextTest = 0; +var subtests = [ + maketest(add_source, 'unknown.raw', 'bogus/type', null) +]; + +var tmpVid = document.createElement('video'); + +for (var i = 0; i < gSmallTests.length; ++i) { + var test = gSmallTests[i]; + var src = test.name; + var type = test.type; + + if (!tmpVid.canPlayType(type)) + continue; + + // The following nested function hack is to ensure that 'test' is correctly + // captured in the closure and we don't end up getting the value 'test' + // had in the last iteration of the loop. I blame Brendan. + var check = function(t) { return function (e) { + checkMetadata(t.name, e, t); + }}(test); + + var otherType = type.match(/^video\//) ? "audio/x-wav" : "video/ogg"; + subtests.push(maketest(set_src, src, null, check), + maketest(add_source, src, null, check), + maketest(add_source, src, type, check), + maketest(add_sources_last, src, null, check), + maketest(add_sources_first, src, type, check), + + // type hint matches a decoder, actual type matches different decoder + maketest(add_source, src, otherType, check), + maketest(add_source, 'unknown.raw', type, null), + + // should not start loading, type excludes it from media candiate list + maketest(add_source, src, 'bogus/type', null), + + // element doesn't notice source children attached later, needs bug 462455 fixed + maketest(late_add_sources_last, src, type, check), + maketest(late_add_sources_first, src, type, check)); +} + +function startTest(t, token) { + t(token); +} + +manager.runTests(subtests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_media_sniffer.html b/dom/media/test/test_media_sniffer.html new file mode 100644 index 0000000000..68e2bba8af --- /dev/null +++ b/dom/media/test/test_media_sniffer.html @@ -0,0 +1,67 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: sniffing</title> + <meta charset='utf-8'> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function finish_test(element) { + element.removeEventListener("error", onerror); + removeNodeAndSource(element); + manager.finished(element.token); +} + +function onmetadataloaded(e) { + var t = e.target; + ++t.srcIndex; + ok(true, "The media loads when loaded via " + t.src); + if (t.srcIndex < t.srcList.length) { + t.src = t.srcList[t.srcIndex]; + } else { + finish_test(t); + } +} + +function onerror(e) { + var t = e.target; + t.removeEventListener('error', onerror); + ok(false, "The media could not be loaded." + t.src + "\n"); + finish_test(t); +} + +function startTest(test, token) { + var elemType = /^audio/.test(test.type) ? "audio" : "video"; + var element = document.createElement(elemType); + // This .sjs file serve the media file without Content-Type header, or with a + // specific Content-Type header. + var baseSrc = 'contentType.sjs?file=' + test.name; + element.srcList = [ + baseSrc + "&nomime", + baseSrc + "&type=application/octet-stream", + baseSrc + "&type=audio/wav", + baseSrc + "&type=text/html", + baseSrc + "&type=absolute_nonsense" + ]; + element.srcIndex = 0; + element.src = element.srcList[element.srcIndex]; + element.token = token; + element.controls = true; + element.preload = "metadata"; + document.body.appendChild(element); + manager.started(token); + element.addEventListener("loadedmetadata", onmetadataloaded); + element.addEventListener("error", onerror); +} + +manager.runTests(gSnifferTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediacapabilities_resistfingerprinting.html b/dom/media/test/test_mediacapabilities_resistfingerprinting.html new file mode 100644 index 0000000000..1f07d1c707 --- /dev/null +++ b/dom/media/test/test_mediacapabilities_resistfingerprinting.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1369309</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1461454">Mozilla Bug 1461454</a> +<a target="_blank" href="https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/13543">Tor Issue 13543</a> + +<script type="application/javascript"> +async function testWhetherSpoofed(resistFingerprinting) { + + var unsupportedVideoConfiguration = { + contentType: 'video/bogus', + width: 800, + height: 600, + bitrate: 3000, + framerate: 24, + }; + var supportedVideoConfiguration = { + contentType: 'video/webm; codecs="vp09.00.10.08"', + width: 800, + height: 600, + bitrate: 3000, + framerate: 24, + }; + + await SpecialPowers.pushPrefEnv({ + "set": [ + ["privacy.resistFingerprinting", resistFingerprinting] + ], + }); + + var result; + + result = await navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: unsupportedVideoConfiguration + }); + is(result.supported, false, "video/bogus should be unsupported."); + is(result.smooth, false, "smooth is false when unsupported."); + is(result.powerEfficient, false, "powerEfficient is false when unsupported."); + + result = await navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: supportedVideoConfiguration + }); + is(result.supported, true, "'video/webm; codecs=\"vp09.00.10.08\"' should be supported."); + if (resistFingerprinting) { + is(result.smooth, true, "smooth should be spoofed to true in RFP mode."); + is(result.powerEfficient, false, "powerEfficient should be spoofed to false in RFP mode."); + } +} + +async function start() { + await testWhetherSpoofed(true); + await testWhetherSpoofed(false); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +start(); +</script> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_avoid_recursion.html b/dom/media/test/test_mediarecorder_avoid_recursion.html new file mode 100644 index 0000000000..0c733b9fc2 --- /dev/null +++ b/dom/media/test/test_mediarecorder_avoid_recursion.html @@ -0,0 +1,61 @@ +<html> +<head> + <title>MediaRecorder infinite recursion with requestData() calls in "dataavailable" event</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=897776">Mozill +a Bug 897776</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> +async function startTest() { + try { + await setupGetUserMediaTestPrefs(); + let stream = await navigator.mediaDevices.getUserMedia({audio: true}); + let mediaRecorder = new MediaRecorder(stream); + let count = 0; + mediaRecorder.onerror = function () { + ok(false, 'Unexpected onerror callback fired'); + SimpleTest.finish(); + }; + mediaRecorder.onwarning = function () { + ok(false, 'Unexpected onwarning callback fired'); + }; + mediaRecorder.ondataavailable = function (e) { + ++count; + info("got ondataavailable data size = " + e.data.size); + // no more requestData() to prevent busy main thread from starving + // the encoding thread + if (count == 30) { + info("track.stop"); + stream.getTracks()[0].stop(); + } else if (count < 30 && mediaRecorder.state == 'recording') { + info("requestData again"); + mediaRecorder.requestData(); + } + }; + mediaRecorder.onstop = function () { + ok(true, "requestData within ondataavailable successfully avoided infinite recursion"); + SimpleTest.finish(); + }; + mediaRecorder.start(); + info("mediaRecorder start"); + mediaRecorder.requestData(); + info("mediaRecorder requestData"); + } catch (e) { + ok(false, 'Unexpected error fired with: ' + e); + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +startTest(); + +</script> +</pre> +</body> +</html> + diff --git a/dom/media/test/test_mediarecorder_bitrate.html b/dom/media/test/test_mediarecorder_bitrate.html new file mode 100644 index 0000000000..693b27e3bf --- /dev/null +++ b/dom/media/test/test_mediarecorder_bitrate.html @@ -0,0 +1,127 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Bitrate</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; +var results = []; + +/** + * Starts a test on every media recorder file included to check that + * the bitrate control works + */ +function startTest(test, token) { + manager.started(token); + runTest(test, token, 1000000); + runTest(test, token, 100000); +} + +function runTest(test, token, bitrate) { + var element = document.createElement('video'); + + element.token = token; + + element.src = test.name; + element.preload = "metadata"; + element.onloadedmetadata = function () { + info("loadedmetadata"); + const stream = element.mozCaptureStreamUntilEnded(); + element.onloadedmetadata = null; + element.play(); + + const mediaRecorder = new MediaRecorder(stream, {videoBitsPerSecond: bitrate}); + mediaRecorder.start(); + is(mediaRecorder.state, 'recording', 'Media recorder should be recording'); + is(mediaRecorder.stream, stream, + 'Media recorder stream = element stream at the start of recording'); + + var onStopFired = false; + var onDataAvailableFired = false; + var encoded_size = 0; + + mediaRecorder.onerror = function () { + ok(false, 'Unexpected onerror callback fired'); + }; + + mediaRecorder.onwarning = function () { + ok(false, 'Unexpected onwarning callback fired'); + }; + + // This handler verifies that only a single onstop event handler is fired. + mediaRecorder.onstop = function () { + if (onStopFired) { + ok(false, 'onstop unexpectedly fired more than once'); + } else { + onStopFired = true; + + // ondataavailable should always fire before onstop + if (onDataAvailableFired) { + ok(true, 'onstop fired after ondataavailable'); + info("test " + test.name + " encoded@" + bitrate + "=" + encoded_size); + if (results[test.name]) { + var big, small, temp; + big = {}; + big.bitrate = bitrate; + big.size = encoded_size; + small = results[test.name]; + // Don't assume the order that these will finish in + if (results[test.name].bitrate > bitrate) { + temp = big; + big = small; + small = temp; + } + // Ensure there is a big enough difference in the encoded + // sizes + ok(small.size*1.25 < big.size, + test.name + ' encoded@' + big.bitrate + '=' + big.size + + ' > encoded@' + small.bitrate + '=' + small.size); + manager.finished(token); + } else { + results[test.name] = {}; + results[test.name].bitrate = bitrate; + results[test.name].size = encoded_size; + } + } else { + ok(false, 'onstop fired without an ondataavailable event first'); + } + } + }; + + // This handler verifies that only a single ondataavailable event handler + // is fired with the blob generated having greater than zero size + // and a correct mime type. + mediaRecorder.ondataavailable = function (evt) { + if (onDataAvailableFired) { + ok(false, 'ondataavailable unexpectedly fired more than once'); + } else { + onDataAvailableFired = true; + + ok(evt instanceof BlobEvent, + 'Events fired from ondataavailable should be BlobEvent'); + is(evt.type, 'dataavailable', + 'Event type should dataavailable'); + ok(evt.data.size > 0, + 'Blob data received should be greater than zero'); + encoded_size = evt.data.size; + + // onstop should not have fired before ondataavailable + if (onStopFired) { + ok(false, 'ondataavailable unexpectedly fired later than onstop'); + manager.finished(token); + } + } + }; + }; +} + +manager.runTests(gMediaRecorderVideoTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_creation.html b/dom/media/test/test_mediarecorder_creation.html new file mode 100644 index 0000000000..cd23cb7a96 --- /dev/null +++ b/dom/media/test/test_mediarecorder_creation.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Creation</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +/** + * Starts a test on every media recorder file included to check that + * a media recorder object created with a stream derived from a media + * element with that file produces the correct starting attribute values. + */ +function startTest(test, token) { + var element = document.createElement('audio'); + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.stream = element.mozCaptureStreamUntilEnded(); + + var mediaRecorder = new MediaRecorder(element.stream); + + is(mediaRecorder.stream, element.stream, + 'Stream should be provided stream on creation'); + is(mediaRecorder.mimeType, '', + 'mimeType should be an empty string on creation'); + is(mediaRecorder.state, 'inactive', + 'state should be inactive on creation'); + + manager.finished(token); +} + +manager.runTests(gMediaRecorderTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_creation_fail.html b/dom/media/test/test_mediarecorder_creation_fail.html new file mode 100644 index 0000000000..2630f069b0 --- /dev/null +++ b/dom/media/test/test_mediarecorder_creation_fail.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Record with media.ogg.enabled = false</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +function testThrows(stream, options, errorName, message, testName) { + try { + new MediaRecorder(stream, options); + } catch(e) { + is(e.name, errorName, testName); + is(e.message, message, testName); + return; + } + ok(!errorName, testName); +} +(async () => { + SimpleTest.waitForExplicitFinish(); + await SpecialPowers.pushPrefEnv({set: [ + ["media.ogg.enabled", false], + ["media.encoder.webm.enabled", false], + ]}); + const stream = new AudioContext().createMediaStreamDestination().stream; + testThrows( + stream, {mimeType: "audio/ogg"}, "NotSupportedError", + "MediaRecorder constructor: audio/ogg indicates an unsupported container", + "Creating an ogg recorder without ogg support throws"); + testThrows( + stream, {mimeType: "audio/webm"}, "NotSupportedError", + "MediaRecorder constructor: audio/webm indicates an unsupported container", + "Creating a webm recorder without webm support throws"); + testThrows( + stream, {mimeType: "video/webm"}, "NotSupportedError", + "MediaRecorder constructor: video/webm indicates an unsupported container", + "Creating a webm recorder without webm support throws"); + testThrows( + stream, {mimeType: "apa/bepa"}, "NotSupportedError", + "MediaRecorder constructor: apa/bepa is not a valid media type", + "Creating a recorder for a bogus mime type throws"); + testThrows( + stream, {}, null, null, + "Creating a default recorder never throws, even without container support"); + const recorder = new MediaRecorder(stream); + try { + recorder.start(); + ok(false, "Starting a recorder without container support should throw"); + } catch(e) { + is(e.name, "NotSupportedError", + "Starting a recorder without container support throws"); + } + SimpleTest.finish(); +})(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_fires_start_event_once_when_erroring.html b/dom/media/test/test_mediarecorder_fires_start_event_once_when_erroring.html new file mode 100644 index 0000000000..537e1dbb47 --- /dev/null +++ b/dom/media/test/test_mediarecorder_fires_start_event_once_when_erroring.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Bug 1395022 - MediaRecorder fires start event when erroring.</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1395022">Mozilla Bug 1395022</a>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+function startTest() {
+ let audioContext = new AudioContext();
+ let destination1 = audioContext.createMediaStreamDestination();
+ let oscilator = audioContext.createOscillator();
+ oscilator.connect(destination1);
+ oscilator.start();
+
+ let destination2 = audioContext.createMediaStreamDestination();
+
+ let rec = new MediaRecorder(destination1.stream);
+
+ let numStartEvents = 0;
+
+ rec.onstart = () => {
+ numStartEvents += 1;
+ is(numStartEvents, 1, "One start event should be fired by the recorder");
+ // Trigger an error in the recorder
+ destination1.stream.addTrack(destination2.stream.getTracks()[0]);
+ };
+
+ rec.onerror = () => {
+ is(numStartEvents, 1, "One start event should have been fired by the recorder");
+ SimpleTest.finish();
+ };
+
+ rec.start();
+}
+
+SimpleTest.waitForExplicitFinish();
+startTest();
+
+</script>
+</head>
+</html>
\ No newline at end of file diff --git a/dom/media/test/test_mediarecorder_multipletracks.html b/dom/media/test/test_mediarecorder_multipletracks.html new file mode 100644 index 0000000000..40fbfb92ce --- /dev/null +++ b/dom/media/test/test_mediarecorder_multipletracks.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that MediaRecorder fires an error event when started with >1 track of a kind</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/dom/media/webrtc/tests/mochitests/head.js"></script> +</head> +<body> +<script class="testbody"> +"use strict"; + +(async () => { + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("Failure timeouts"); + + try { + const stream = new MediaStream; + const recorder = new MediaRecorder(stream); + + { + info("Testing with two audio tracks"); + const ac = new AudioContext; + const track = ac.createMediaStreamDestination().stream.getTracks()[0]; + stream.addTrack(track); + stream.addTrack(track.clone()); + mustThrowWith("Starting with multiple audio tracks", + "NotSupportedError", + () => recorder.start()); + await Promise.all([ + haveNoEvent(recorder, "start"), + haveNoEvent(recorder, "error"), + haveNoEvent(recorder, "stop"), + ]); + for (let t of stream.getTracks()) { + stream.removeTrack(t); + t.stop(); + } + } + + { + info("Testing with two video tracks"); + const canvas = document.createElement("canvas"); + canvas.getContext("2d"); + const track = canvas.captureStream().getTracks()[0]; + stream.addTrack(track); + stream.addTrack(track.clone()); + mustThrowWith("Starting with multiple video tracks", + "NotSupportedError", + () => recorder.start()); + await Promise.all([ + haveNoEvent(recorder, "start"), + haveNoEvent(recorder, "error"), + haveNoEvent(recorder, "stop"), + ]); + for (let t of stream.getTracks()) { + stream.removeTrack(t); + t.stop(); + } + } + } catch(e) { + ok(false, `${e}\n${e.stack}`); + } finally { + SimpleTest.finish(); + } +})(); +</script> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_onerror_pause.html b/dom/media/test/test_mediarecorder_onerror_pause.html new file mode 100644 index 0000000000..55ee5fb535 --- /dev/null +++ b/dom/media/test/test_mediarecorder_onerror_pause.html @@ -0,0 +1,107 @@ +<html> +<head> + <title>Bug 957439 - Media Recording - Assertion fail at Pause if unsupported input stream.</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=957439">Mozilla Bug 957439</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function unexpected(e) { + ok(false, `Got unexpected ${e.type} event`); +} + + +async function startTest() { + // also do general checks on mimetype support for audio-only + ok(MediaRecorder.isTypeSupported("audio/ogg"), + 'Should support audio/ogg'); + ok(MediaRecorder.isTypeSupported('audio/ogg; codecs=opus'), + 'Should support audio/ogg+opus'); + ok(!MediaRecorder.isTypeSupported('audio/ogg; codecs=foobar'), + 'Should not support audio/ogg + unknown_codec'); + ok(MediaRecorder.isTypeSupported("video/webm"), + 'Should support video/webm'); + ok(!MediaRecorder.isTypeSupported("video/mp4"), + 'Should not support video/mp4'); + + try { + await setupGetUserMediaTestPrefs(); + const expectedMimeType = 'video/webm; codecs="vp8, opus"'; + const stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true}); + const [audioTrack] = stream.getAudioTracks(); + + // Expected event sequence should be: + // 1. start + // 2. error (from removed track) + // 3. dataavailable + // 4. stop + const mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, 'Stream should be provided on creation'); + + mediaRecorder.onstart = unexpected; + mediaRecorder.onerror = unexpected; + mediaRecorder.ondataavailable = unexpected; + mediaRecorder.onstop = unexpected; + + mediaRecorder.start(); + is(mediaRecorder.state, 'recording', 'state should be recording'); + is(mediaRecorder.mimeType, '', 'mimetype should be unset'); + + await new Promise(r => mediaRecorder.onstart = r); + mediaRecorder.onstart = unexpected; + ok(true, 'start event fired'); + is(mediaRecorder.mimeType, expectedMimeType, 'mimetype should be set'); + + // Trigger an error + stream.removeTrack(audioTrack); + + const err = await new Promise(r => mediaRecorder.onerror = r); + mediaRecorder.onerror = unexpected; + ok(true, 'error event fired'); + is(err.error.name, 'InvalidModificationError', + 'Error name should be InvalidModificationError.'); + ok(err.error.stack.includes('test_mediarecorder_onerror_pause.html'), + 'Events fired from onerror should include an error with a stack trace indicating ' + + 'an error in this test'); + is(mediaRecorder.mimeType, '', 'mimetype should be unset'); + is(mediaRecorder.state, 'inactive', 'state is inactive'); + + try { + mediaRecorder.pause(); + ok(false, 'pause should fire an exception if called on an inactive recorder'); + } catch(e) { + ok(e instanceof DOMException, 'pause should fire an exception ' + + 'if called on an inactive recorder'); + is(e.name, 'InvalidStateError', 'Exception name should be InvalidStateError'); + } + + const evt = await new Promise(r => mediaRecorder.ondataavailable = r); + mediaRecorder.ondataavailable = unexpected; + ok(true, 'dataavailable event fired'); + isnot(evt.data.size, 0, 'data size should not be zero'); + ok(evt instanceof BlobEvent, + 'Events fired from ondataavailable should be BlobEvent'); + is(evt.data.type, expectedMimeType, 'blob mimeType is set'); + + await new Promise(r => mediaRecorder.onstop = r); + mediaRecorder.onstop = unexpected; + ok(true, 'onstop event fired'); + is(mediaRecorder.state, 'inactive', 'state should be inactive'); + } catch (err) { + ok(false, `Unexpected error fired with: ${err}`); + } finally { + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +window.onload = startTest; + +</script> +</head> +</html> diff --git a/dom/media/test/test_mediarecorder_pause_resume_video.html b/dom/media/test/test_mediarecorder_pause_resume_video.html new file mode 100644 index 0000000000..a9b3d6a034 --- /dev/null +++ b/dom/media/test/test_mediarecorder_pause_resume_video.html @@ -0,0 +1,130 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Recording doesn't record during pause</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/dom/canvas/test/captureStream_common.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<div id="content"> + <canvas id="video-src-canvas"></canvas> + <video id="recorded-video"></video> +</div> +<script class="testbody" type="text/javascript"> + +function startTest() { + // Setup canvas and take a stream from it + let canvas = document.getElementById("video-src-canvas"); + + let canvas_size = 100; + let new_canvas_size = 50; + + canvas.width = canvas.height = canvas_size; + + let helper = new CaptureStreamTestHelper2D(100, 100); + helper.drawColor(canvas, helper.red); + + let canvasStream = canvas.captureStream(); + // Canvas set up + + // Check values for events + let numDataAvailabledRaised = 0; + // Recorded data that will be playback. + let blob; + + let mediaRecorder = new MediaRecorder(canvasStream); + is(mediaRecorder.stream, canvasStream, + "Media recorder stream = canvas stream at the start of recording"); + + mediaRecorder.onwarning = () => ok(false, "warning unexpectedly fired"); + + mediaRecorder.onerror = () => ok(false, "Recording failed"); + + mediaRecorder.ondataavailable = ev => { + info("Got 'dataavailable' event"); + ++numDataAvailabledRaised; + // Save recorded data for playback + blob = ev.data; + }; + + mediaRecorder.onstart = () => { + info("Got 'start' event"); + // We just want one frame encoded before we pause + mediaRecorder.pause(); + // We may rewrite this once we settle Bug 1363915, could listen for pause event instead + is(mediaRecorder.state, 'paused', 'Media recorder should be paused'); + + // Wait a while, then while paused draw blue at another size, then again + // green at the original size and resume. + let numberOfPaintsSincePause = 0; + window.requestAnimationFrame(function draw() { + numberOfPaintsSincePause++; + if (numberOfPaintsSincePause == 8) { + canvas.width = canvas.height = new_canvas_size; + helper.drawColor(canvas, helper.blue); + } else if (numberOfPaintsSincePause == 60) { + canvas.width = canvas.height = canvas_size; + helper.drawColor(canvas, helper.green); + } else if (numberOfPaintsSincePause == 68) { + // Waited 8 draws since changing canvas to green, should be safe to resume + mediaRecorder.resume(); + } else if (numberOfPaintsSincePause > 120) { + mediaRecorder.stop(); + return; // Early return, we don't want to request any more animation frames + } + window.requestAnimationFrame(draw); + }); + }; + + mediaRecorder.onstop = () => { + info("Got 'stop' event"); + is(mediaRecorder.state, 'inactive', 'Media recorder should be incative after stop'); + is(numDataAvailabledRaised, 1, "Expected 1 dataavailable event"); + + ok(blob, "Should have gotten a data blob"); + let video = document.getElementById("recorded-video"); + video.id = "recorded-video"; + video.src = URL.createObjectURL(blob); + // Setup a check to make sure we don't play back any blue + let checkVideoHasNoBlue = () => { + if(helper.isPixel(helper.getPixel(video), helper.blue, 128)) { + ok(false, "Video should have no blue frames"); + // Remove handler so we don't spam the log + video.ontimeupdate = null; + } + }; + video.ontimeupdate = checkVideoHasNoBlue; + video.onerror = () => { + ok(false, "Should be able to play the recording. Got error. code=" + video.error.code); + SimpleTest.finish(); + }; + video.onended = () => { + ok(helper.isPixel(helper.getPixel(video), helper.green, 128), "Last frame should be green"); + SimpleTest.finish(); + }; + // The video will resize once it loads its metadata, only listen for resizes after that + video.onloadedmetadata = () => { + ok(video.videoWidth === canvas_size && video.videoHeight === canvas_size, + "video element should be same size as canvas once metadata is loaded"); + // We shouldn't have any resize events once the video is loaded + video.onresize = () => { + ok(false, "Should not have any resize events!"); + }; + }; + + video.play(); + }; + + mediaRecorder.start(); + is(mediaRecorder.state, "recording", "Media recorder should be recording"); +} + +SimpleTest.waitForExplicitFinish(); +startTest(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_playback_can_repeat.html b/dom/media/test/test_mediarecorder_playback_can_repeat.html new file mode 100644 index 0000000000..4cf2735088 --- /dev/null +++ b/dom/media/test/test_mediarecorder_playback_can_repeat.html @@ -0,0 +1,87 @@ +<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test MediaRecorder Recording creates videos that can playback more than once</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/dom/canvas/test/captureStream_common.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<div id="content">
+ <canvas id="video-src-canvas"></canvas>
+ <video id="recorded-video" loop></video>
+</div>
+<script class="testbody" type="text/javascript">
+
+(async function() {
+ try {
+ SimpleTest.waitForExplicitFinish();
+ await startTest();
+ } catch(e) {
+ ok(false, `Got error msg '${e}'`);
+ } finally {
+ SimpleTest.finish();
+ }
+})();
+
+async function startTest() {
+ let canvas = document.getElementById("video-src-canvas");
+
+ let canvas_size = 100;
+ canvas.width = canvas.height = canvas_size;
+ let helper = new CaptureStreamTestHelper2D(canvas_size, canvas_size);
+ helper.drawColor(canvas, helper.red);
+
+ let stream = canvas.captureStream();
+ let mediaRecorder = new MediaRecorder(stream);
+ is(mediaRecorder.stream, stream,
+ "Media recorder stream = canvas stream at the beginning of recording");
+ new Promise(r => mediaRecorder.onerror = err => r(err)).then(
+ err => Promise.reject(`MediaRecorder: error unexpectedly fired. Code ${err.name}`));
+
+ mediaRecorder.start();
+ await new Promise(r => mediaRecorder.onstart = r);
+ info("Media recorder started");
+ // Feed some more data into the recorder so the output has a non trivial duration.
+ // This avoids the case where we have only 1 frame in the output, which breaks
+ // looping (this is expected as a WebM with 1 video frame has no duration).
+ let counter = 0;
+ let draw = () => {
+ counter++;
+ helper.drawColor(canvas, helper.blue);
+ if(counter > 2) {
+ mediaRecorder.stop();
+ return;
+ }
+ requestAnimationFrame(draw);
+ };
+ requestAnimationFrame(draw);
+
+ // When recorder is stopped get recorded data.
+ const data = await new Promise(r => mediaRecorder.ondataavailable = ev => r(ev));
+ info(`Media recorder get availiable data`);
+ const blob = data.data;
+
+ await new Promise(r => mediaRecorder.onstop = r);
+ info("Media recorder stopped");
+ ok(blob, "Should have gotten a data blob");
+ const video = document.getElementById("recorded-video");
+ new Promise(r => video.onerror = err => r(err)).then(
+ err => Promise.reject(`Video: error unexpectedly fired. Code ${err.code}`));
+ video.src = URL.createObjectURL(blob);
+ video.play();
+ await new Promise(r => video.onplaying = r);
+ for (let idx = 0; idx < 2; idx++) {
+ await new Promise(r => video.onseeking = r);
+ ok(true, `waiting until video finishes seeking`);
+ await new Promise(r => video.onseeked = r);
+ ok(true, "video finished seeked");
+ }
+ video.pause();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/media/test/test_mediarecorder_principals.html b/dom/media/test/test_mediarecorder_principals.html new file mode 100644 index 0000000000..00dcaa5a5b --- /dev/null +++ b/dom/media/test/test_mediarecorder_principals.html @@ -0,0 +1,132 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=489415 +--> +<head> + <title>Test for MediaRecorder Reaction to Principal Change</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<div> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1018299">Test for MediaRecorder Principal Handling</a> +</div> + +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +let throwOutside = e => setTimeout(() => { throw e; }); + +// Loading data from a resource that changes origins while streaming should +// be detected by the media cache and result in a null principal so that the +// MediaRecorder usages below fail. + +// This test relies on midflight-redirect.sjs returning the the first quarter of +// the resource as a byte range response, and then hanging up, and when Firefox +// requests the remainder midflight-redirect.sjs serves a redirect to another origin. + +async function testPrincipals(resource) { + if (!resource) { + todo(false, "No types supported"); + return; + } + await testPrincipals1(resource); + await testPrincipals2(resource); +} + +function makeVideo() { + let video = document.createElement("video"); + video.preload = "metadata"; + video.controls = true; + document.body.appendChild(video); + return video; +} + +// First test: Load file from same-origin first, then get redirected to +// another origin before attempting to record stream. +async function testPrincipals1(resource) { + let video = makeVideo(); + video.src = + "http://mochi.test:8888/tests/dom/media/test/midflight-redirect.sjs" + + "?resource=" + resource.name + "&type=" + resource.type; + + let errorBarrier = once(video, "error"); + // Wait for the video to load to metadata. We can then start capturing. + // Must also handle the download bursting and hitting the error before we + // reach loadedmetadata. Normally we reach loadedmetadata first, but + // rarely we hit the redirect first. + await Promise.race([once(video, "loadedmetadata"), errorBarrier]); + + let rec = new MediaRecorder(video.mozCaptureStreamUntilEnded()); + video.play(); + + // Wait until we hit a playback error. This means our download has hit the redirect. + await errorBarrier; + + // Try to record, it should be blocked with a security error. + try { + rec.start(); + ok(false, "mediaRecorder.start() must throw SecurityError, but didn't throw at all"); + } catch (ex) { + is(ex.name, "SecurityError", "mediaRecorder.start() must throw SecurityError"); + } + removeNodeAndSource(video); +} + +// Second test: Load file from same-origin first, but record ASAP, before +// getting redirected to another origin. +async function testPrincipals2(resource) { + let video = makeVideo(); + video.src = + "http://mochi.test:8888/tests/dom/media/test/midflight-redirect.sjs" + + "?resource=" + resource.name + "&type=" + resource.type; + + // Wait for the video to load to metadata. We can then start capturing. + // Must also handle the download bursting and hitting the error before we + // reach loadedmetadata. Normally we reach loadedmetadata first, but + // rarely we hit the redirect first. + await Promise.race([once(video, "loadedmetadata"), once(video, "error")]); + + let ended = false; + once(video, "ended", () => ended = true); + + // Start capturing. It should work. + let rec; + let errorBarrier; + try { + rec = new MediaRecorder(video.mozCaptureStreamUntilEnded()); + errorBarrier = nextEvent(rec, "error"); + rec.start(); + ok(true, "mediaRecorder.start() should not throw here, and didn't"); + } catch (ex) { + ok(false, "mediaRecorder.start() unexpectedly threw " + ex.name + " (" + ex.message + ")"); + } + + // Play the video, this should result in a SecurityError on the recorder. + let hasStopped = once(rec, "stop"); + video.play(); + let error = (await errorBarrier).error; + is(error.name, "SecurityError", "mediaRecorder.onerror must fire SecurityError"); + ok(error.stack.includes('test_mediarecorder_principals.html'), + 'Events fired from onerror should include an error with a stack trace indicating ' + + 'an error in this test'); + is(ended, false, "Playback should not have reached end"); + await hasStopped; + is(ended, false, "Playback should definitely not have reached end"); + + removeNodeAndSource(video); +} + +testPrincipals({ name:"pixel_aspect_ratio.mp4", type:"video/mp4", duration:28 }) + .catch(e => throwOutside(e)) + .then(() => SimpleTest.finish()); + +</script> +</pre> + +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_4ch_audiocontext.html b/dom/media/test/test_mediarecorder_record_4ch_audiocontext.html new file mode 100644 index 0000000000..99f57f181e --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_4ch_audiocontext.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Record AudioContext with four channels</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> + +<script class="testbody" type="text/javascript"> + +function startTest() { + var context = new AudioContext(); + var buffer = context.createBuffer(4, 80920, context.sampleRate); + for (var i = 0; i < 80920; ++i) { + for(var j = 0; j < 4; ++j) { + buffer.getChannelData(j)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate); + } + } + + var source = context.createBufferSource(); + source.buffer = buffer; + source.loop = true; + var dest = context.createMediaStreamDestination(); + var stopTriggered = false; + var onstopTriggered = false; + dest.channelCount = 4; + var expectedMimeType = 'audio/ogg; codecs=opus'; + source.channelCountMode = 'explicit'; + source.connect(dest); + var elem = document.createElement('audio'); + elem.srcObject = dest.stream; + source.start(0); + elem.play(); + let mMediaRecorder = new MediaRecorder(dest.stream); + mMediaRecorder.onwarning = function() { + ok(false, 'onwarning unexpectedly fired'); + }; + + mMediaRecorder.onerror = function() { + ok(false, 'onerror unexpectedly fired'); + }; + + mMediaRecorder.onstop = function() { + ok(true, 'onstop fired successfully'); + is(mMediaRecorder.state, 'inactive', 'check recording status is inactive'); + onstopTriggered = true; + SimpleTest.finish(); + }; + mMediaRecorder.ondataavailable = function (e) { + ok(e.data.size > 0, 'check blob has data'); + is(e.data.type, expectedMimeType, 'blob should have expected mimetype'); + if (!stopTriggered) { + is(mMediaRecorder.mimeType, expectedMimeType, 'recorder should have expected mimetype'); + mMediaRecorder.stop(); + is(mMediaRecorder.mimeType, '', 'recorder should have reset its mimetype'); + stopTriggered = true; + } else if (onstopTriggered) { + ok(false, 'ondataavailable should come before onstop event'); + } + }; + try { + mMediaRecorder.start(1000); + is('recording', mMediaRecorder.state, "check record state recording"); + } catch (e) { + ok(false, 'Can t record audio context'); + } +} + +startTest(); +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_addtracked_stream.html b/dom/media/test/test_mediarecorder_record_addtracked_stream.html new file mode 100644 index 0000000000..639531f7f2 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_addtracked_stream.html @@ -0,0 +1,182 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder recording a constructed MediaStream</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/dom/canvas/test/captureStream_common.js"></script> + <script src="/tests/dom/media/webrtc/tests/mochitests/head.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<div id="content"> +</div> +<script> +SimpleTest.waitForExplicitFinish(); +runTestWhenReady(async () => { + const canvas = document.createElement("canvas"); + canvas.width = canvas.height = 100; + document.getElementById("content").appendChild(canvas); + + const helper = new CaptureStreamTestHelper2D(100, 100); + helper.drawColor(canvas, helper.red); + + const audioCtx = new AudioContext(); + const osc = audioCtx.createOscillator(); + osc.frequency.value = 1000; + osc.start(); + const dest = audioCtx.createMediaStreamDestination(); + osc.connect(dest); + + const stream = dest.stream; + + // Timeouts are experienced intermittently in Linux due to no sound in the + // destination. As a workaround wait for the source sound to arrive. + const sourceAnalyser = new AudioStreamAnalyser(audioCtx, stream); + const sourceAudioReady = sourceAnalyser.waitForAnalysisSuccess(array => { + const freq = osc.frequency.value; + const lowerFreq = freq / 2; + const upperFreq = freq + 1000; + const lowerAmp = array[sourceAnalyser.binIndexForFrequency(lowerFreq)]; + const freqAmp = array[sourceAnalyser.binIndexForFrequency(freq)]; + const upperAmp = array[sourceAnalyser.binIndexForFrequency(upperFreq)]; + info("Analysing source audio. " + + lowerFreq + ": " + lowerAmp + ", " + + freq + ": " + freqAmp + ", " + + upperFreq + ": " + upperAmp); + return lowerAmp < 50 && freqAmp > 200 && upperAmp < 50; + }); + await sourceAudioReady; + info("Source Audio content ok"); + + canvas.captureStream(0).getVideoTracks().forEach(t => stream.addTrack(t)); + + const blobs = []; + + let mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, + "Media recorder stream = constructed stream at the start of recording"); + + + mediaRecorder.ondataavailable = evt => { + info("ondataavailable fired"); + + is(mediaRecorder.state, "inactive", "Blob received after stopping"); + is(blobs.length, 0, "This is the first and only blob"); + ok(evt instanceof BlobEvent, + "Events fired from ondataavailable should be BlobEvent"); + is(evt.type, "dataavailable", + "Event type should dataavailable"); + ok(evt.data.size >= 0, + "Blob data size received is greater than or equal to zero"); + + blobs.push(evt.data); + }; + + const stopped = haveEvent(mediaRecorder, "stop", wait(5000, new Error("Timeout"))); + const stoppedNoErrors = Promise.all([ + stopped, + haveNoEvent(mediaRecorder, "warning", stopped), + haveNoEvent(mediaRecorder, "error", stopped) + ]); + + mediaRecorder.start(); + is(mediaRecorder.state, "recording", "Media recorder should be recording"); + + await haveEvent(mediaRecorder, "start", wait(5000, new Error("Timeout"))); + info("onstart fired"); + + // The recording can be too short to cause any checks with + // waitForAnalysisSuccess(). Waiting a bit here solves this. + await wait(500); + + is(mediaRecorder.state, "recording", + "Media recorder is recording before being stopped"); + mediaRecorder.stop(); + is(mediaRecorder.state, "inactive", + "Media recorder is inactive after being stopped"); + is(mediaRecorder.stream, stream, + "Media recorder stream = constructed stream post recording"); + + await stoppedNoErrors; + info("Got 'stop' event"); + + ok(blobs.length == 1, "Should have gotten one data blob"); + + // Clean up recording sources + osc.stop(); + stream.getTracks().forEach(t => t.stop()); + + // Sanity check the recording + const video = document.createElement("video"); + document.getElementById("content").appendChild(video); + video.id = "recorded-video"; + + const blob = new Blob(blobs); + ok(blob.size > 0, "Recorded blob should contain data"); + + video.src = URL.createObjectURL(blob); + video.preload = "metadata"; + + info("Waiting for metadata to be preloaded"); + + await haveEvent(video, "loadedmetadata", wait(5000, new Error("Timeout"))); + info("Playback of recording loaded metadata"); + + const recordingStream = video.mozCaptureStream(); + is(recordingStream.getVideoTracks().length, 1, + "Recording should have one video track"); + is(recordingStream.getAudioTracks().length, 1, + "Recording should have one audio track"); + + const ended = haveEvent(video, "ended", wait(5000, new Error("Timeout"))); + const endedNoError = Promise.all([ + ended, + haveNoEvent(video, "error", ended), + ]); + + const analyser = new AudioStreamAnalyser(audioCtx, recordingStream); + const audioReady = analyser.waitForAnalysisSuccess(array => { + const freq = osc.frequency.value; + const lowerFreq = freq / 2; + const upperFreq = freq + 1000; + const lowerAmp = array[analyser.binIndexForFrequency(lowerFreq)]; + const freqAmp = array[analyser.binIndexForFrequency(freq)]; + const upperAmp = array[analyser.binIndexForFrequency(upperFreq)]; + info("Analysing audio. " + + lowerFreq + ": " + lowerAmp + ", " + + freq + ": " + freqAmp + ", " + + upperFreq + ": " + upperAmp); + return lowerAmp < 50 && freqAmp > 200 && upperAmp < 50; + }, endedNoError.then(() => new Error("Audio check failed"))); + + const videoReady = helper.pixelMustBecome( + video, helper.red, { + threshold: 128, + infoString: "Should become red", + cancelPromise: endedNoError.then(() => new Error("Video check failed")), + }); + + video.play(); + + try { + await endedNoError; + } finally { + analyser.disconnect(); + let url = video.src; + video.src = ""; + URL.revokeObjectURL(url); + } + + info("Playback of recording ended without error"); + + await audioReady; + info("Audio content ok"); + + await videoReady; + info("Video content ok"); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_audiocontext.html b/dom/media/test/test_mediarecorder_record_audiocontext.html new file mode 100644 index 0000000000..686faaeb6b --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_audiocontext.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Record AudioContext</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> + +<script class="testbody" type="text/javascript"> + +function startTest() { + var context = new AudioContext(); + var buffer = context.createBuffer(1, 80920, context.sampleRate); + for (var i = 0; i < 80920; ++i) { + buffer.getChannelData(0)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate); + } + + var source = context.createBufferSource(); + source.buffer = buffer; + source.loop = true; + + var dest = context.createMediaStreamDestination(); + source.connect(dest); + var elem = document.createElement('audio'); + elem.srcObject = dest.stream; + source.start(0); + elem.play(); + let mMediaRecorder = new MediaRecorder(dest.stream); + mMediaRecorder.onwarning = function() { + ok(false, 'onwarning unexpectedly fired'); + }; + + mMediaRecorder.onerror = function() { + ok(false, 'onerror unexpectedly fired'); + }; + + mMediaRecorder.onstop = function() { + ok(true, 'onstop fired successfully'); + is(mMediaRecorder.state, 'inactive', 'check recording status is inactive'); + SimpleTest.finish(); + }; + mMediaRecorder.ondataavailable = function (e) { + if (mMediaRecorder.state == 'recording') { + is(mMediaRecorder.mimeType, 'audio/ogg; codecs=opus', 'Expected MediaRecorder mimetype'); + is(e.data.type, 'audio/ogg; codecs=opus', 'Expected Blob mimetype'); + ok(e.data.size > 0, 'check blob has data'); + mMediaRecorder.stop(); + } + }; + try { + mMediaRecorder.start(1000); + is('recording', mMediaRecorder.state, "check record state recording"); + } catch (e) { + ok(false, 'Can t record audio context'); + } +} + +startTest(); +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_audiocontext_mlk.html b/dom/media/test/test_mediarecorder_record_audiocontext_mlk.html new file mode 100644 index 0000000000..4128702aef --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_audiocontext_mlk.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>capture for possible memory leak when record AudioContext</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=973765">Mozill +a Bug 973765</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + // This test case want to capture the memory leak if exit the browser after running those script. + var ac = new window.AudioContext(); + var destStream = ac.createMediaStreamDestination().stream; + var recorder = new MediaRecorder(destStream); + recorder.start(1000); + is(recorder.state, 'recording', 'Media recorder should be recording'); + is(recorder.stream, destStream, + 'Media recorder stream = element stream at the start of recording'); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_audionode.html b/dom/media/test/test_mediarecorder_record_audionode.html new file mode 100644 index 0000000000..8a57437b81 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_audionode.html @@ -0,0 +1,135 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Record AudioContext Node</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968109">Mozilla Bug 968109</a> + +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function setUpSource(contextType, nodeType) { + // Use contextType to choose offline or real-time context. + const context = contextType == "offline"? + new OfflineAudioContext(2 , 80920, 44100) : new AudioContext(); + const buffer = context.createBuffer(2, 80920, context.sampleRate); + for (let i = 0; i < 80920; ++i) { + buffer.getChannelData(0)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate); + buffer.getChannelData(1)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate); + } + + const source = context.createBufferSource(); + source.buffer = buffer; + source.loop = true; + + source.start(0); + + // nodeType decides which node in graph should be the source of recording. + let node; + if (nodeType == "source") { + node = source; + } else if (nodeType == "splitter") { + const splitter = context.createChannelSplitter(); + source.connect(splitter); + node = splitter; + } else if (nodeType == "destination") { + source.connect(context.destination); + node = context.destination; + } + // Explicitly start offline context. + if (contextType == "offline") { + context.startRendering(); + } + + return node; +} + +async function testRecord(source, mimeType) { + const isOffline = source.context instanceof OfflineAudioContext; + const recorder = new MediaRecorder(source, 0, {mimeType}); + is(recorder.mimeType, mimeType, "Mime type is set"); + const extendedMimeType = `${mimeType || "audio/ogg"}; codecs=opus`; + + recorder.onwarning = () => ok(false, "should not fire onwarning"); + recorder.onerror = () => ok(false, "should not fire onerror"); + if (!isOffline) { + recorder.onstop = () => ok(false, "should not fire stop yet"); + } + + recorder.start(1000); + is("recording", recorder.state, "state should become recording after calling start()"); + is(recorder.mimeType, mimeType, "Mime type is not changed by start()"); + + await new Promise(r => recorder.onstart = r); + is(recorder.mimeType, extendedMimeType, "Mime type is fully defined"); + + const chunks = []; + let {data} = await new Promise(r => recorder.ondataavailable = r); + if (!isOffline) { + is(recorder.state, "recording", "Expected to still be recording"); + } + is(data.type, extendedMimeType, "Blob has fully defined mimetype"); + isnot(data.size, 0, "should get data and its length should be > 0"); + chunks.push(data); + + if (isOffline) { + await new Promise(r => recorder.onstop = r); + is(recorder.state, "inactive", "Offline context should end by itself"); + } else { + is(recorder.state, "recording", "Expected to still be recording"); + recorder.stop(); + ({data} = await new Promise(r => recorder.ondataavailable = r)); + is(recorder.state, "inactive", "Expected to be inactive after last blob"); + isnot(data.size, 0, "should get data and its length should be > 0"); + chunks.push(data); + + await new Promise(r => recorder.onstop = r); + is(recorder.state, "inactive", "state should remain inactive after stop event"); + } + return new Blob(chunks, {type: chunks[0].type}); +} + +addLoadEvent(async () => { + const src = setUpSource(); + let didThrow = false; + try { + new MediaRecorder(src); + } catch (e) { + didThrow = true; + } + ok(didThrow, "MediaRecorder(AudioNode) should be hidden behind a pref"); + + await SpecialPowers.pushPrefEnv({set: [ + ["media.recorder.audio_node.enabled", true], + ]}); + + // Test with various context and source node types. + for (const mimeType of [ + "audio/ogg", + "audio/webm", + "video/webm", + "", + ]) { + for (const {context, node} of [ + {context: "", node: "source"}, + {context: "", node: "splitter"}, + {context: "offline", node: "destination"}, + ]) { + info(`Testing recording ${context || "regular"} context and ${node} ` + + `node with mimeType '${mimeType}'`); + await testRecord(setUpSource(context, node), mimeType); + } + } + + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_canvas_captureStream.html b/dom/media/test/test_mediarecorder_record_canvas_captureStream.html new file mode 100644 index 0000000000..0b6cd6dbb5 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_canvas_captureStream.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Recording canvas stream</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/dom/canvas/test/captureStream_common.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<div id="content"> +</div> +<script class="testbody" type="text/javascript"> + +function startTest() { + var canvas = document.createElement("canvas"); + canvas.width = canvas.height = 100; + document.getElementById("content").appendChild(canvas); + + var helper = new CaptureStreamTestHelper2D(100, 100); + helper.drawColor(canvas, helper.red); + + var stream = canvas.captureStream(0); + + var blob; + + let mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, + "Media recorder stream = canvas stream at the start of recording"); + + mediaRecorder.onwarning = () => ok(false, "warning unexpectedly fired"); + + mediaRecorder.onerror = () => ok(false, "Recording failed"); + + mediaRecorder.ondataavailable = ev => { + is(blob, undefined, "Should only get one dataavailable event"); + blob = ev.data; + }; + + mediaRecorder.onstart = () => { + info("Got 'start' event"); + // We just want one frame encoded, to see that the recorder produces something readable. + mediaRecorder.stop(); + }; + + mediaRecorder.onstop = () => { + info("Got 'stop' event"); + ok(blob, "Should have gotten a data blob"); + + var video = document.createElement("video"); + video.id = "recorded-video"; + video.src = URL.createObjectURL(blob); + video.play(); + video.onerror = err => { + ok(false, "Should be able to play the recording. Got error. code=" + video.error.code); + SimpleTest.finish(); + }; + document.getElementById("content").appendChild(video); + helper.pixelMustBecome(video, helper.red, { + threshold: 128, + infoString: "Should become red" + }).then(SimpleTest.finish); + }; + + mediaRecorder.start(); + is(mediaRecorder.state, "recording", "Media recorder should be recording"); +} + +SimpleTest.waitForExplicitFinish(); +startTest(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_changing_video_resolution.html b/dom/media/test/test_mediarecorder_record_changing_video_resolution.html new file mode 100644 index 0000000000..d6354ee5a1 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_changing_video_resolution.html @@ -0,0 +1,174 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Recording canvas stream that dynamically changes resolution</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<div id="content"> +</div> +<script class="testbody" type="text/javascript"> + +function startTest() { + let canvas = document.createElement("canvas"); + const resolution_change = [ + {width: 100, height: 100, color: "red"}, + {width: 150, height: 150, color: "blue"}, + {width: 100, height: 100, color: "red"}, + ]; + canvas.width = resolution_change[0].width; + canvas.height = resolution_change[0].height; + + let ctx = canvas.getContext("2d"); + ctx.fillStyle = resolution_change[0].color; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + // The recorded stream coming from canvas. + let stream = canvas.captureStream(); + + // Check values for events + let numDataAvailabledRaised = 0; + let numResizeRaised = 0; + // Recorded data that will be playback. + let blob; + + // Media recorder for VP8 and canvas stream. + let mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, + "Media recorder stream = canvas stream at the start of recording"); + + // Not expected events. + mediaRecorder.onwarning = () => ok(false, "MediaRecorder: onwarning unexpectedly fired"); + mediaRecorder.onerror = err => { + ok(false, "MediaRecorder: onerror unexpectedly fired. Code " + err.name); + SimpleTest.finish(); + }; + + // When recorder is stopped get recorded data. + mediaRecorder.ondataavailable = ev => { + info("Got 'dataavailable' event"); + ++numDataAvailabledRaised; + is(blob, undefined, "Should only get one dataavailable event"); + // Save recorded data for playback + blob = ev.data; + }; + + mediaRecorder.onstart = () => { + info('onstart fired successfully'); + }; + + mediaRecorder.onstop = () => { + info("Got 'stop' event"); + is(numDataAvailabledRaised, 1, "Should have gotten 1 dataavailable event"); + // Playback stream and verify resolution changes. + ok(blob, "Should have gotten a data blob"); + + let video = document.createElement("video"); + video.id = "recorded-video"; + video.src = URL.createObjectURL(blob); + video.preload = "metadata"; + + video.onerror = err => { + ok(false, "Should be able to play the recording. Got error. code=" + video.error.code); + SimpleTest.finish(); + }; + + // Check that the encoded frames have the correct sizes. + video.onresize = function() { + if (numResizeRaised < resolution_change.length) { + is(video.videoWidth, resolution_change[numResizeRaised].width, + "onresize width should be as expected"); + is(video.videoHeight, resolution_change[numResizeRaised].height, + "onresize height should be as expected"); + } else { + ok(false, "Got more resize events than expected"); + } + ++numResizeRaised; + }; + + video.onloadedmetadata = function() { + info("loadedmetadata"); + seekThroughFrames(); + }; + + video.onended = function() { + is(numResizeRaised, resolution_change.length, "Expected number of resize events"); + SimpleTest.finish(); + // This shouldn't be needed, however video.ended may not be set after + // seeking to the final frame. This can result in seekToNextFrame being + // called again by seekThroughFrames and onended being invoked again, + // resulting in multiple finish() calls. + // FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=1386489 + video.onended = null; + }; + + document.getElementById("content").appendChild(video); + + function seekThroughFrames() { + info("Seeking to next frame"); + video.seekToNextFrame() + .then(() => { + info("Seeking to next frame finished. width=" + video.videoWidth + + ", height=" + video.videoHeight); + + if (video.ended) { + return; + } + + // After seeking finished we queue the next seek task on the event + // loop so it gets in the same queue as the "resize" events. + setTimeout(seekThroughFrames, 0); + }) + .catch(error => { + ok(false, "seekToNextFrame rejected: " + error); + }); + } + }; + + // Start here by stream recorder. + mediaRecorder.start(); + is(mediaRecorder.state, "recording", "Media recorder should be recording"); + requestAnimationFrame(draw); + + // Change resolution in every frame + // Stop recorder on last frame + let countFrames = 0; + let previous_time = performance.now(); + function draw(timestamp) { + if (timestamp - previous_time < 100) { + requestAnimationFrame(draw); + return; + } + previous_time = timestamp; + + if (countFrames == resolution_change.length) { + mediaRecorder.stop(); + return; + } + + canvas.width = resolution_change[countFrames].width; + canvas.height = resolution_change[countFrames].height; + ctx.fillStyle = resolution_change[countFrames].color; + // Resize and draw canvas + ctx.fillRect(0, 0, canvas.width, canvas.height); + // Register draw to be called on next rendering + requestAnimationFrame(draw); + countFrames++; + } +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + { + "set": [ + ["media.seekToNextFrame.enabled", true ], + ["media.video-queue.send-to-compositor-size", 1] + ] + }, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_downsize_resolution.html b/dom/media/test/test_mediarecorder_record_downsize_resolution.html new file mode 100644 index 0000000000..f9422a3897 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_downsize_resolution.html @@ -0,0 +1,148 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Recording canvas dynamically changes to greater resolution</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/dom/canvas/test/captureStream_common.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<div id="content"> +</div> +<script class="testbody" type="text/javascript"> + +function startTest() { + var canvas = document.createElement("canvas"); + var canvas_size = 100; + var new_canvas_size = 50; + canvas.width = canvas.height = canvas_size; + + var helper = new CaptureStreamTestHelper2D(canvas_size, canvas_size); + helper.drawColor(canvas, helper.red); + + // The recorded stream coming from canvas. + var stream = canvas.captureStream(); + + // Check values for events + var numDataAvailabledRaised = 0; + var numResizeRaised = 0; + // Recorded data that will be playback. + var blob; + + // Media recorder for VP8 and canvas stream. + var mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, + "Media recorder stream = canvas stream at the beginning of recording"); + + // Not expected events. + mediaRecorder.onwarning = () => ok(false, "MediaRecorder: onwarning unexpectedly fired"); + mediaRecorder.onerror = err => { + ok(false, "MediaRecorder: onerror unexpectedly fired. Code " + err.name); + SimpleTest.finish(); + } + + // When recorder is stopped get recorded data. + mediaRecorder.ondataavailable = ev => { + info("Got 'dataavailable' event"); + ++numDataAvailabledRaised; + is(blob, undefined, "On dataavailable event blob is undefined"); + // Save recorded data for playback + blob = ev.data; + }; + + mediaRecorder.onstart = () => { + info('onstart fired successfully'); + }; + + mediaRecorder.onstop = () => { + info("Got 'stop' event"); + is(numDataAvailabledRaised, 1, "Expected 1 dataavailable event"); + + // Playback stream and verify resolution changes. + ok(blob, "Should have gotten a data blob"); + var video = document.createElement("video"); + video.id = "recorded-video"; + video.src = URL.createObjectURL(blob); + video.onerror = err => { + ok(false, "Should be able to play the recording. Got error. code=" + video.error.code); + SimpleTest.finish(); + }; + + // Check here that resize is correct in the playback stream. + video.onresize = function() { + ++numResizeRaised; + if (numResizeRaised == 1) { + is(this.videoWidth, canvas_size, "1st resize event original width"); + is(this.videoHeight, canvas_size, "1st resize event original height "); + } else if (numResizeRaised == 2) { + is(this.videoWidth, new_canvas_size, "2nd resize event new width"); + is(this.videoHeight, new_canvas_size, "2nd resize event new height"); + } else { + ok(false, "Only 2 numResizeRaised events are expected"); + } + }; + + video.onended = () => { + is(numResizeRaised, 2, "Expected 2 resize event"); + }; + document.getElementById("content").appendChild(video); + video.play(); + + // Check last color + helper.pixelMustBecome(video, helper.red, { + threshold: 128, + infoString: "Should become red", + }).then(() => { + video.onresize = {}; + video.onended = {}; + SimpleTest.finish(); + }); + }; + + // Start here by stream recorder. + mediaRecorder.start(); + is(mediaRecorder.state, "recording", "Media recorder started"); + requestAnimationFrame(draw); + + // Change resolution every 100ms + var countFrames=0; + var previous_time = performance.now(); + function draw(timestamp) { + if (timestamp - previous_time < 100) { + requestAnimationFrame(draw); + return; + } + previous_time = timestamp; + + var size = 0; + var color = ""; + if (countFrames < 1) { + // Initial size + size = canvas_size; + color = helper.blue; + } else if (countFrames < 2) { + // upsize + size = new_canvas_size; + color = helper.red; + } else { + // Stop recoredr on last frame + mediaRecorder.stop(); + return; + } + // Resize and draw canvas + canvas.width = canvas.height = size; + helper.drawColor(canvas, color); + // Register next draw on every call + requestAnimationFrame(draw); + countFrames++; + } +} + +SimpleTest.waitForExplicitFinish(); +startTest(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_getdata_afterstart.html b/dom/media/test/test_mediarecorder_record_getdata_afterstart.html new file mode 100644 index 0000000000..3b181ed8db --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_getdata_afterstart.html @@ -0,0 +1,81 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 951008 Test MediaRecorder Record has start event</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> + +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + + var element = document.createElement('audio'); + var hasonstart = false; + var hasondataavailable = false; + var mMediaRecorder; + + element.token = token; + manager.started(token); + element.src = test.name; + element.test = test; + element.stream = element.mozCaptureStream(); + + mMediaRecorder = new MediaRecorder(element.stream); + is(mMediaRecorder.mimeType, '', 'Expected MediaRecorder mimetype'); + mMediaRecorder.onwarning = function() { + ok(false, 'onwarning unexpectedly fired'); + }; + + mMediaRecorder.onerror = function() { + ok(false, 'onerror unexpectedly fired'); + }; + + mMediaRecorder.onstart = function() { + info('onstart fired successfully'); + hasonstart = true; + is(mMediaRecorder.mimeType, 'audio/ogg; codecs=opus', + "MediaRecorder mimetype as expected"); + mMediaRecorder.requestData(); + }; + + mMediaRecorder.onstop = function() { + info('onstop fired successfully'); + ok(hasondataavailable, "should have ondataavailable before onstop"); + is(mMediaRecorder.state, 'inactive', 'check recording status is inactive'); + SimpleTest.finish(); + }; + + mMediaRecorder.ondataavailable = function (e) { + info('ondataavailable fired successfully'); + if (mMediaRecorder.state == 'recording') { + hasondataavailable = true; + ok(hasonstart, "should have had start event first"); + is(e.data.type, mMediaRecorder.mimeType, + "blob's mimeType matches the recorder's"); + mMediaRecorder.stop(); + } + }; + + // Start recording once metadata are parsed. + element.onloadedmetadata = function() { + element.oncanplaythrough = null; + mMediaRecorder.start(0); + is(mMediaRecorder.state, 'recording', 'Media recorder should be recording'); + is(mMediaRecorder.stream, element.stream, + 'Media recorder stream = element stream at the start of recording'); + }; + + element.play(); +} + +manager.runTests(gMediaRecorderTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_gum_video_timeslice.html b/dom/media/test/test_mediarecorder_record_gum_video_timeslice.html new file mode 100644 index 0000000000..961a9644b2 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_gum_video_timeslice.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Record gUM video with Timeslice</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<pre id="test"> +<div id="content" style="display: none"> +</div> +<script class="testbody" type="text/javascript"> + +async function startTest() { + try { + await setupGetUserMediaTestPrefs(); + let stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true}); + let dataAvailableCount = 0; + let onDataAvailableFirst = false; + const expectedMimeType = 'video/webm; codecs="vp8, opus"'; + + let mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, + 'Media recorder stream = element stream at the start of recording'); + mediaRecorder.onwarning = function() { + ok(false, 'onwarning unexpectedly fired'); + }; + + mediaRecorder.onerror = function() { + ok(false, 'onerror unexpectedly fired'); + }; + + mediaRecorder.onstop = function() { + ok(false, 'Unexpected onstop callback fired'); + }; + + mediaRecorder.onstart = function() { + is(mediaRecorder.mimeType, expectedMimeType, 'Expected mime type'); + }; + + mediaRecorder.ondataavailable = function (evt) { + info('ondataavailable fired'); + dataAvailableCount++; + + ok(evt instanceof BlobEvent, + 'Events fired from ondataavailable should be BlobEvent'); + is(evt.type, 'dataavailable', + 'Event type should dataavailable'); + ok(evt.data.size >= 0, + 'Blob data size ' + evt.data.size + ' received is greater than or equal to zero'); + is(evt.data.type, expectedMimeType, 'Expected blob mime type'); + + // We'll stop recording upon the 1st blob being received + if (dataAvailableCount === 1) { + mediaRecorder.onstop = function (event) { + info('onstop fired'); + + if (!onDataAvailableFirst) { + ok(false, 'onstop unexpectedly fired before ondataavailable'); + } + + ok(true, 'onstop fired successfully'); + is(mediaRecorder.state, 'inactive', + 'check recording status is inactive'); + SimpleTest.finish(); + }; + + mediaRecorder.stop(); + is(mediaRecorder.state, 'inactive', + 'Media recorder is inactive after being stopped'); + + } else if (dataAvailableCount === 2) { + // Ensure we've received at least two ondataavailable events before + // onstop + onDataAvailableFirst = true; + } + }; + + mediaRecorder.start(250); + is(mediaRecorder.state, 'recording', 'Media recorder should be recording'); + is(mediaRecorder.mimeType, '', 'Expected mime type'); + } catch (err) { + ok(false, 'Unexpected error fired with: ' + err); + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +startTest(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_gum_video_timeslice_mixed.html b/dom/media/test/test_mediarecorder_record_gum_video_timeslice_mixed.html new file mode 100644 index 0000000000..5e9e4d3023 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_gum_video_timeslice_mixed.html @@ -0,0 +1,100 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Record gUM video with Timeslice, and playback of mixed memory and file blobs</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<pre id="test"> +<script type="text/javascript"> +function unexpected({type}) { + ok(false, `${type} unexpectedly fired`); +} + +(async () => { + SimpleTest.waitForExplicitFinish(); + let blobUrl = null; + let stream = null; + try { + // This is the memory limit per blob. If a blob is larger than this, + // MediaRecorder will put it in a file. For this test we need to get at + // least one blob under, and one blob over the limit. + const memoryLimit = 50000; + await SpecialPowers.pushPrefEnv({set: [ + ["media.recorder.max_memory", memoryLimit], + ]}); + // We always use fake devices since the loopback ones don't make enough + // pixels change per frame to make the encoded frames large enough. + await pushGetUserMediaTestPrefs({fakeAudio: true, fakeVideo: true}); + stream = await navigator.mediaDevices.getUserMedia( + {audio: true, video: true}); + const blobs = []; + + let mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, + "Media recorder stream = element stream at the start of recording"); + mediaRecorder.start(); + mediaRecorder.addEventListener("warning", unexpected); + mediaRecorder.addEventListener("error", unexpected); + mediaRecorder.addEventListener("stop", unexpected); + await new Promise(r => mediaRecorder.onstart = r); + + for (let hasMemory = false; !hasMemory;) { + mediaRecorder.requestData(); + const {data} = await new Promise(r => mediaRecorder.ondataavailable = r); + blobs.push(data); + ok(data.size < memoryLimit, "Blob should be small enough at start"); + hasMemory = data.size > 0 && data.size < memoryLimit; + info(`Blob is ${data.size} bytes.${hasMemory ? " In memory." : ""}`); + } + info("Got a memory blob"); + + SimpleTest.requestFlakyTimeout("Wait for file blob"); + for (let hasFile = false, waitTimeMs = 500; !hasFile; waitTimeMs *= 4) { + info(`Waiting ${waitTimeMs/1000} seconds for file blob`); + await new Promise(r => setTimeout(r, waitTimeMs)); + mediaRecorder.requestData(); + const {data} = await new Promise(r => mediaRecorder.ondataavailable = r); + blobs.push(data); + hasFile = data.size > memoryLimit; + info(`Blob is ${data.size} bytes. In ${hasFile ? "file" : "memory"}.`); + } + info("Got a file blob"); + + mediaRecorder.stop(); + const {data} = await new Promise(r => mediaRecorder.ondataavailable = r); + blobs.push(data); + mediaRecorder.removeEventListener("stop", unexpected); + await new Promise(r => mediaRecorder.onstop = r); + + const video = document.createElement("video"); + const blob = new Blob(blobs); + blobUrl = URL.createObjectURL(blob); + video.src = blobUrl; + info(`Starting playback. Blob-size=${blob.size}`); + video.play(); + + await Promise.race([ + new Promise(res => video.onended = res), + new Promise((res, rej) => video.onerror = () => rej(video.error.message)), + ]); + } catch (e) { + ok(false, e); + } finally { + if (stream) { + for (const t of stream.getTracks()) { + t.stop(); + } + } + if (blobUrl) { + URL.revokeObjectURL(blobUrl); + } + SimpleTest.finish(); + } +})(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_immediate_stop.html b/dom/media/test/test_mediarecorder_record_immediate_stop.html new file mode 100644 index 0000000000..8ed7c321a0 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_immediate_stop.html @@ -0,0 +1,115 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Immediate Stop</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +/** + * Stops the media recorder immediately after starting the recorder. This test + * verifies whether the media recorder can handle this scenario nicely. The + * return blob size should be greater than zero, but its duration would be zero + * length when play. + */ +function startTest(test, token) { + var element = document.createElement('audio'); + var expectedMimeType = test.type; + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.stream = element.mozCaptureStreamUntilEnded(); + + var mediaRecorder = + new MediaRecorder(element.stream, {mimeType: expectedMimeType}); + var onStopFired = false; + var onDataAvailableFired = false; + + mediaRecorder.onerror = function () { + ok(false, 'Unexpected onerror callback fired'); + }; + + mediaRecorder.onwarning = function () { + ok(false, 'Unexpected onwarning callback fired'); + }; + + // This handler verifies that only a single onstop event handler is fired. + mediaRecorder.onstop = function () { + if (onStopFired) { + ok(false, 'onstop unexpectedly fired more than once'); + } else { + onStopFired = true; + + // ondataavailable should always fire before onstop + if (onDataAvailableFired) { + manager.finished(token); + } else { + ok(false, 'onstop fired without an ondataavailable event first'); + } + } + }; + + // This handler verifies that only a single ondataavailable event handler + // is fired with the blob generated having greater than zero size + // and a correct mime type. + mediaRecorder.ondataavailable = function (evt) { + if (onDataAvailableFired) { + ok(false, 'ondataavailable unexpectedly fired more than once'); + } else { + onDataAvailableFired = true; + + ok(evt instanceof BlobEvent, + 'Events fired from ondataavailable should be BlobEvent'); + is(evt.type, 'dataavailable', + 'Event type should dataavailable'); + + // The initialization of encoder can be cancelled. + // On some platforms, the stop method may run after media stream track + // available, so the blob can contain the header data. + is(evt.data.type, expectedMimeType, + 'Blob data received and should have mime type'); + is(mediaRecorder.mimeType, expectedMimeType, + 'Media Recorder mime type in ondataavailable = ' + expectedMimeType); + ok(evt.data.size >= 0, 'Blob size can not be negative'); + + // onstop should not have fired before ondataavailable + if (onStopFired) { + ok(false, 'ondataavailable unexpectedly fired later than onstop'); + manager.finished(token); + } + } + }; + + // This handler completes a start and stop of recording and verifies + // respective media recorder state. + element.onloadedmetadata = function () { + element.onloadedmetadata = null; + element.play(); + mediaRecorder.start(); + is(mediaRecorder.state, 'recording', 'Media recorder should be recording'); + is(mediaRecorder.stream, element.stream, + 'Media recorder stream = element stream at the start of recording'); + + mediaRecorder.stop(); + is(mediaRecorder.state, 'inactive', + 'Media recorder is inactive after being stopped'); + is(mediaRecorder.stream, element.stream, + 'Media recorder stream = element stream post recording'); + }; + + element.preload = "metadata"; +} + +manager.runTests(gMediaRecorderTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_no_timeslice.html b/dom/media/test/test_mediarecorder_record_no_timeslice.html new file mode 100644 index 0000000000..6ed148a108 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_no_timeslice.html @@ -0,0 +1,106 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Record No Timeslice</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +/** + * Starts a test on every media recorder file included to check that a + * stream derived from the file can be recorded with no time slice provided. + */ +function startTest(test, token) { + var element = document.createElement('audio'); + var expectedMimeType = test.type; + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.stream = element.mozCaptureStreamUntilEnded(); + + var mediaRecorder = + new MediaRecorder(element.stream, {mimeType: expectedMimeType}); + var onStopFired = false; + var onDataAvailableFired = false; + + mediaRecorder.onerror = function () { + ok(false, 'Unexpected onerror callback fired'); + }; + + mediaRecorder.onwarning = function () { + ok(false, 'Unexpected onwarning callback fired'); + }; + + // This handler verifies that only a single onstop event handler is fired. + mediaRecorder.onstop = function () { + if (onStopFired) { + ok(false, 'onstop unexpectedly fired more than once'); + } else { + onStopFired = true; + + // ondataavailable should always fire before onstop + if (onDataAvailableFired) { + ok(true, 'onstop fired after ondataavailable'); + manager.finished(token); + } else { + ok(false, 'onstop fired without an ondataavailable event first'); + } + } + }; + + // This handler verifies that only a single ondataavailable event handler + // is fired with the blob generated having greater than zero size + // and a correct mime type. + mediaRecorder.ondataavailable = function (evt) { + if (onDataAvailableFired) { + ok(false, 'ondataavailable unexpectedly fired more than once'); + } else { + onDataAvailableFired = true; + + ok(evt instanceof BlobEvent, + 'Events fired from ondataavailable should be BlobEvent'); + is(evt.type, 'dataavailable', + 'Event type should dataavailable'); + ok(evt.data.size > 0, + 'Blob data received should be greater than zero'); + is(evt.data.type, expectedMimeType, + 'Blob data received should have type = ' + expectedMimeType); + + is(mediaRecorder.mimeType, expectedMimeType, + 'Mime type in ondataavailable = ' + expectedMimeType); + + // onstop should not have fired before ondataavailable + if (onStopFired) { + ok(false, 'ondataavailable unexpectedly fired later than onstop'); + manager.finished(token); + } + } + }; + + element.preload = "metadata"; + + element.onloadedmetadata = function () { + element.onloadedmetadata = null; + mediaRecorder.start(); + is(mediaRecorder.state, 'recording', + 'Media recorder should be recording'); + is(mediaRecorder.stream, element.stream, + 'Media recorder stream = element stream at the start of recording'); + + element.play(); + } +} + +manager.runTests(gMediaRecorderTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_session.html b/dom/media/test/test_mediarecorder_record_session.html new file mode 100644 index 0000000000..88795d82d0 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_session.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=909670 +--> +<head> + <meta charset="utf-8"> + <title>Test for Media Recoder recording session</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function startTest(test, token) { + var element = document.createElement('audio'); + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.stream = element.mozCaptureStream(); + + var mStopCount = 0; + // Start and stop recording session three times continuously. + var mExpectStopCount = 3; + var mediaRecorder = new MediaRecorder(element.stream); + + // Stop callback. + // Suppose to receive mExpectStopCount + mediaRecorder.onstop = function stopCallback() { + mStopCount++; + + info("MediaRecorder.onstop callback: (" + mStopCount + ")"); + + if (mExpectStopCount === mStopCount) + { + manager.finished(token); + } + } + + // data avaliable. + mediaRecorder.ondataavailable = function(evt) {} + + mediaRecorder.onerror = function(err) { + ok(false, 'Unexpected error fired with:' + err); + } + + mediaRecorder.onwarning = function() { + ok(false, 'Unexpected warning fired'); + } + + element.preload = "metadata"; + + element.onloadedmetadata = function () { + element.onloadedmetadata = null; + element.play(); + for (var i = 0; i < mExpectStopCount; i++) { + mediaRecorder.start(1000); + mediaRecorder.stop(); + } + } + +} + +manager.runTests(gMediaRecorderTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_startstopstart.html b/dom/media/test/test_mediarecorder_record_startstopstart.html new file mode 100644 index 0000000000..b4cc62c709 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_startstopstart.html @@ -0,0 +1,75 @@ + <!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder crash on sequence start stop start method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<div id="content" style="display: none"> +</div> +<script class="testbody" type="text/javascript"> + +function startTest() { + var ac = new window.AudioContext(); + var dest = ac.createMediaStreamDestination(); + var recorder = new MediaRecorder(dest.stream); + var stopCount = 0; + var dataavailable = 0; + var expectedMimeType = 'audio/ogg; codecs=opus'; + recorder.onstop = function (e) { + info('onstop fired'); + is(recorder.stream, dest.stream, + 'Media recorder stream = element stream post recording'); + stopCount++; + if (stopCount == 2) { + if (dataavailable >= 2) { + SimpleTest.finish(); + } else { + ok(false, 'Should have at least two dataavailable events'); + } + } + } + recorder.ondataavailable = function (evt) { + info('ondataavailable fired'); + ok(evt instanceof BlobEvent, + 'Events fired from ondataavailable should be BlobEvent'); + is(evt.type, 'dataavailable', + 'Event type should dataavailable'); + // If script runs slower, it may generate header data in blob from encoder + if (evt.data.size > 0) { + info('blob size = ' + evt.data.size); + is(evt.data.type, expectedMimeType, + 'Blob data received should have type = ' + expectedMimeType); + } + dataavailable++; + } + recorder.onerror = function (e) { + ok(false, 'it should execute normally without exception'); + } + recorder.onwarning = function() { + ok(false, 'onwarning unexpectedly fired'); + }; + + recorder.start(2000); + is(recorder.state, 'recording', 'Media recorder should be recording'); + recorder.stop(); + is(recorder.state, 'inactive', 'check recording status is inactive'); + recorder.start(10000); // This bug would crash on this line without this fix. + is(recorder.state, 'recording', 'check recording status is recording'); + // Simulate delay stop, only delay stop no no stop can trigger crash. + setTimeout(function() { + recorder.stop(); + is(recorder.state, 'inactive','check recording status is recording'); + }, 1000); +} + +SimpleTest.requestFlakyTimeout("untriaged"); +startTest(); +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> + diff --git a/dom/media/test/test_mediarecorder_record_timeslice.html b/dom/media/test/test_mediarecorder_record_timeslice.html new file mode 100644 index 0000000000..3e547e77b4 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_timeslice.html @@ -0,0 +1,105 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Record Timeslice</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +/** + * Starts a test on every media recorder file included to check that a stream + * derived from the file can be recorded with a timeslice provided + */ +function startTest(test, token) { + var element = document.createElement('audio'); + var expectedMimeType = test.type; + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.preload = "auto"; + + // Set up MediaRecorder once loadedmetadata fires and tracks are available. + element.onloadedmetadata = function() { + element.onloadedmetadata = null; + + const stream = element.mozCaptureStream(); + const mediaRecorder = + new MediaRecorder(stream, {mimeType: expectedMimeType}); + + mediaRecorder.onerror = function () { + ok(false, 'Unexpected onerror callback fired'); + }; + + mediaRecorder.onwarning = function () { + ok(false, 'Unexpected onwarning callback fired'); + }; + + mediaRecorder.onstop = function () { + ok(false, 'Unexpected onstop callback fired'); + }; + + var dataAvailableCount = 0; + var onDataAvailableFirst = false; + + // This handler fires every 250ms to generate a blob. + mediaRecorder.ondataavailable = function (evt) { + info('ondataavailable fired'); + dataAvailableCount++; + + ok(evt instanceof BlobEvent, + 'Events fired from ondataavailable should be BlobEvent'); + is(evt.type, 'dataavailable', + 'Event type should dataavailable'); + ok(evt.data.size >= 0, + 'Blob data size received is greater than or equal to zero'); + + is(evt.data.type, expectedMimeType, + 'Blob data received should have type = ' + expectedMimeType); + is(mediaRecorder.mimeType, expectedMimeType, + 'Mime type in ondataavailable = ' + mediaRecorder.mimeType); + + // We'll stop recording upon the 1st blob being received + if (dataAvailableCount === 1) { + mediaRecorder.onstop = function (event) { + info('onstop fired'); + + if (!onDataAvailableFirst) { + ok(false, 'onstop unexpectedly fired before ondataavailable'); + } + element.pause(); + manager.finished(token); + }; + + mediaRecorder.stop(); + is(mediaRecorder.state, 'inactive', + 'Media recorder is inactive after being stopped'); + is(mediaRecorder.stream, stream, + 'Media recorder stream = element stream post recording'); + + } else if (dataAvailableCount === 2) { + // Ensure we've received at least two ondataavailable events before onstop + onDataAvailableFirst = true; + } + }; + + mediaRecorder.start(1); + element.play(); + is(mediaRecorder.state, 'recording', 'Media recorder should be recording'); + is(mediaRecorder.stream, stream, + 'Media recorder stream = element stream at the start of recording'); + }; +} + +manager.runTests(gMediaRecorderTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_record_upsize_resolution.html b/dom/media/test/test_mediarecorder_record_upsize_resolution.html new file mode 100644 index 0000000000..d02fd08e44 --- /dev/null +++ b/dom/media/test/test_mediarecorder_record_upsize_resolution.html @@ -0,0 +1,148 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Recording canvas dynamically changes to greater resolution</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/dom/canvas/test/captureStream_common.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<div id="content"> +</div> +<script class="testbody" type="text/javascript"> + +function startTest() { + var canvas = document.createElement("canvas"); + var canvas_size = 100; + var new_canvas_size = 150; + canvas.width = canvas.height = canvas_size; + + var helper = new CaptureStreamTestHelper2D(canvas_size, canvas_size); + helper.drawColor(canvas, helper.red); + + // The recorded stream coming from canvas. + var stream = canvas.captureStream(); + + // Check values for events + var numDataAvailabledRaised = 0; + var numResizeRaised = 0; + // Recorded data that will be playback. + var blob; + + // Media recorder for VP8 and canvas stream. + var mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, + "Media recorder stream = canvas stream at the beginning of recording"); + + // Not expected events. + mediaRecorder.onwarning = () => ok(false, "MediaRecorder: onwarning unexpectedly fired"); + mediaRecorder.onerror = err => { + ok(false, "MediaRecorder: onerror unexpectedly fired. Code " + err.name); + SimpleTest.finish(); + } + + // When recorder is stopped get recorded data. + mediaRecorder.ondataavailable = ev => { + info("Got 'dataavailable' event"); + ++numDataAvailabledRaised; + is(blob, undefined, "On dataavailable event blob is undefined"); + // Save recorded data for playback + blob = ev.data; + }; + + mediaRecorder.onstart = () => { + info('onstart fired successfully'); + }; + + mediaRecorder.onstop = () => { + info("Got 'stop' event"); + is(numDataAvailabledRaised, 1, "Expected 1 dataavailable event"); + + // Playback stream and verify resolution changes. + ok(blob, "Should have gotten a data blob"); + var video = document.createElement("video"); + video.id = "recorded-video"; + video.src = URL.createObjectURL(blob); + video.onerror = err => { + ok(false, "Should be able to play the recording. Got error. code=" + video.error.code); + SimpleTest.finish(); + }; + + // Check here that resize is correct in the playback stream. + video.onresize = function() { + ++numResizeRaised; + if (numResizeRaised == 1) { + is(this.videoWidth, canvas_size, "1st resize event original width"); + is(this.videoHeight, canvas_size, "1st resize event original height "); + } else if (numResizeRaised == 2) { + is(this.videoWidth, new_canvas_size, "2nd resize event new width"); + is(this.videoHeight, new_canvas_size, "2nd resize event new height"); + } else { + ok(false, "Only 2 numResizeRaised events are expected"); + } + }; + + video.onended = () => { + is(numResizeRaised, 2, "Expected 2 resize event"); + }; + document.getElementById("content").appendChild(video); + video.play(); + + // Check last color + helper.pixelMustBecome(video, helper.red, { + threshold: 128, + infoString: "Should become red", + }).then(() => { + video.onresize = {}; + video.onended = {}; + SimpleTest.finish(); + }); + }; + + // Start here by stream recorder. + mediaRecorder.start(); + is(mediaRecorder.state, "recording", "Media recorder started"); + requestAnimationFrame(draw); + + // Change resolution every 100 ms + var countFrames=0; + var previous_time = performance.now(); + function draw(timestamp) { + if (timestamp - previous_time < 100) { + requestAnimationFrame(draw); + return; + } + previous_time = timestamp; + + var size = 0; + var color = ""; + if (countFrames < 1) { + // Initial size + size = canvas_size; + color = helper.blue; + } else if (countFrames < 2) { + // upsize + size = new_canvas_size; + color = helper.red; + }else { + // Stop recoredr on last frame + mediaRecorder.stop(); + return; + } + // Resize and draw canvas + canvas.width = canvas.height = size; + helper.drawColor(canvas, color); + // Register next draw on every call + requestAnimationFrame(draw); + countFrames++; + } +} + +SimpleTest.waitForExplicitFinish(); +startTest(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_reload_crash.html b/dom/media/test/test_mediarecorder_reload_crash.html new file mode 100644 index 0000000000..f6d008261f --- /dev/null +++ b/dom/media/test/test_mediarecorder_reload_crash.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that reloading media recorder object</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=894348">Mozill +a Bug 894348</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + for (let i = 0; i< 5; i++) { + /* eslint-disable no-undef */ + try { o0 = document.createElement('audio') } catch(e) { } + try { o0.src = "sound.ogg" } catch(e) { } + try { (document.body || document.documentElement).appendChild(o0) } catch(e) { } + try { o1 = o0.mozCaptureStreamUntilEnded(); } catch(e) { } + try { o2 = new MediaRecorder(o1) } catch(e) { } + try { o2.start(0) } catch(e) { } + /* eslint-enable no-undef */ + SpecialPowers.gc(); + } + ok(true, "pass the crash test"); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_state_event_order.html b/dom/media/test/test_mediarecorder_state_event_order.html new file mode 100644 index 0000000000..feba055f4d --- /dev/null +++ b/dom/media/test/test_mediarecorder_state_event_order.html @@ -0,0 +1,83 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder fires an event after changing state</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +/** + * The flow of test is start()=>pause()=>resume()=>stop(). In each steps, + * this test verifies whether each MediaRecorder methods properly change + * its state before firing an event. Checking the state is done in the + * corresponding event handlers. + */ +function startTest(test, token) { + var element = document.createElement('audio'); + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.stream = element.mozCaptureStream(); + + var mediaRecorder = new MediaRecorder(element.stream); + + mediaRecorder.onwarning = function() { + ok(false, 'onwarning unexpectedly fired'); + }; + + mediaRecorder.onerror = function() { + ok(false, 'onerror unexpectedly fired'); + }; + + mediaRecorder.onstart = function() { + info('onstart fired successfully'); + is(mediaRecorder.state, 'recording', + 'Media Recorder changes state to recording before firing a start event'); + mediaRecorder.pause(); + }; + + mediaRecorder.onpause = function() { + info('onpause fired successfully'); + is(mediaRecorder.state, 'paused', + 'Media Recorder changes state to paused before firing a pause event'); + mediaRecorder.resume(); + }; + + mediaRecorder.onresume = function() { + info('onresume fired successfully'); + is(mediaRecorder.state, 'recording', + 'Media Recorder changes state to recording before firing a resume event'); + mediaRecorder.stop(); + }; + + mediaRecorder.onstop = function() { + info('onstop fired successfully'); + is(mediaRecorder.state, 'inactive', + 'Media Recorder changes state to inactive before firing a stop event'); + SimpleTest.finish(); + }; + + // Call start() once metadata are parsed. + element.onloadedmetadata = function() { + element.play(); + mediaRecorder.start(); + is(mediaRecorder.state, 'recording', 'Media recorder should be recording'); + is(mediaRecorder.stream, element.stream, + 'Media recorder stream = element stream at the start of recording'); + }; +} + +manager.runTests(gMediaRecorderTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_state_transition.html b/dom/media/test/test_mediarecorder_state_transition.html new file mode 100644 index 0000000000..5d6483b7de --- /dev/null +++ b/dom/media/test/test_mediarecorder_state_transition.html @@ -0,0 +1,280 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder State Transition</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +// List of operation tests for media recorder objects to verify if running +// these operations should result in an exception or not +var operationTests = [ + { + operations: ['stop'], + isValid: true + }, + { + operations: ['requestData'], + isValid: false + }, + { + operations: ['pause'], + isValid: false + }, + { + operations: ['resume'], + isValid: false + }, + { + operations: ['start'], + isValid: true + }, + { + operations: ['start'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'pause'], + isValid: true + }, + { + operations: ['start', 'pause'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'start'], + isValid: false + }, + { + operations: ['start', 'resume'], + isValid: true + }, + { + operations: ['pause', 'start'], + isValid: false + }, + { + operations: ['resume', 'start'], + isValid: false + }, + { + operations: ['requestData', 'start'], + isValid: false + }, + { + operations: ['stop', 'start'], + isValid: true + }, + { + operations: ['start', 'stop'], + isValid: true + }, + { + operations: ['start', 'stop'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'requestData'], + isValid: true + }, + { + operations: ['start', 'requestData'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'pause', 'stop'], + isValid: true + }, + { + operations: ['start', 'pause', 'start'], + isValid: false + }, + { + operations: ['start', 'pause', 'pause'], + isValid: true + }, + { + operations: ['start', 'pause', 'requestData'], + isValid: true + }, + { + operations: ['start', 'pause', 'resume'], + isValid: true + }, + { + operations: ['start', 'pause', 'resume'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'resume', 'resume'], + isValid: true + }, + { + operations: ['start', 'resume', 'resume'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'resume', 'stop'], + isValid: true + }, + { + operations: ['start', 'resume', 'stop'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'stop', 'start'], + isValid: true + }, + { + operations: ['start', 'stop', 'start'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'stop', 'pause'], + isValid: false + }, + { + operations: ['start', 'stop', 'resume'], + isValid: false + }, + { + operations: ['start', 'stop', 'requestData'], + isValid: false + }, + { + operations: ['start', 'stop', 'stop'], + isValid: true + }, + { + operations: ['start', 'pause', 'resume', 'resume'], + isValid: true + }, + { + operations: ['start', 'pause', 'resume', 'resume'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'pause', 'pause', 'resume'], + isValid: true + }, + { + operations: ['start', 'pause', 'pause', 'resume'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'stop', 'start', 'stop'], + isValid: true + }, + { + operations: ['start', 'stop', 'start', 'stop'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'stop', 'start', 'pause'], + isValid: true + }, + { + operations: ['start', 'stop', 'start', 'pause'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'stop', 'start', 'resume'], + isValid: true + }, + { + operations: ['start', 'stop', 'start', 'resume'], + isValid: true, + timeSlice: 200 + }, + { + operations: ['start', 'stop', 'start', 'requestData'], + isValid: true + }, + { + operations: ['start', 'stop', 'start', 'requestData'], + isValid: true, + timeSlice: 200 + }, +]; + +/** + * Runs through each available state transition test by running all + * available operations on a media recorder object. Then, we report + * back if the test was expected through an exception or not. + * + * @param {MediaStream} testStream the media stream used for media recorder + * operation tests + */ +function runStateTransitionTests(testStream) { + for (const operationTest of operationTests) { + var mediaRecorder = new MediaRecorder(testStream); + var operationsString = operationTest.operations.toString(); + + try { + for (const operation of operationTest.operations) { + if (operationTest.timeSlice && operation === 'start') { + operationsString += ' with timeslice ' + operationTest.timeSlice; + mediaRecorder[operation](operationTest.timeSlice); + } else { + mediaRecorder[operation](); + } + } + + ok(operationTest.isValid, `${operationsString} should succeed`); + } catch (err) { + if (operationTest.isValid) { + ok(false, `${operationsString} failed unexpectedly with ${err.name}`); + } else { + is(err.name, "InvalidStateError", + `${operationsString} expected to fail with InvalidStateError`); + } + } + } +} + +/** + * Starts a test on every media recorder file included to check that various + * state transition flows that can happen in the media recorder object throw + * exceptions when they are expected to and vice versa. + */ +function startTest(test, token) { + var element = document.createElement('audio'); + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.stream = element.mozCaptureStream(); + + element.oncanplaythrough = function () { + element.oncanplaythrough = null; + runStateTransitionTests(element.stream); + manager.finished(token); + }; + + element.play(); +} + +manager.runTests(gMediaRecorderTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediarecorder_webm_support.html b/dom/media/test/test_mediarecorder_webm_support.html new file mode 100644 index 0000000000..6b115ee33a --- /dev/null +++ b/dom/media/test/test_mediarecorder_webm_support.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media Recording - test WebM MIME support</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +ok(MediaRecorder.isTypeSupported('audio/webm'), + 'Should support audio/webm'); +ok(MediaRecorder.isTypeSupported('AUDIO/WEBM'), + 'Should support audio/webm, upper case'); +ok(MediaRecorder.isTypeSupported('AuDiO/wEbM'), + 'Should support audio/webm, mixed case'); + +ok(MediaRecorder.isTypeSupported('audio/webm;codecs=opus'), + 'Should support audio/webm;codecs=opus'); +ok(MediaRecorder.isTypeSupported('AUDIO/WEBM;CODECS=opus'), + 'Should support audio/webm;codecs=opus, upper case'); +ok(MediaRecorder.isTypeSupported('AuDiO/wEbM;cOdEcS=opus'), + 'Should support audio/webm;codecs=opus, mixed case'); + +ok(MediaRecorder.isTypeSupported('video/webm'), + 'Should support video/webm'); +ok(MediaRecorder.isTypeSupported('VIDEO/WEBM'), + 'Should support video/webm, upper case'); +ok(MediaRecorder.isTypeSupported('vIdEo/WeBm'), + 'Should support video/webm, mixed case'); + +ok(MediaRecorder.isTypeSupported('video/webm; codecs="vp8"'), + 'Should support video/webm; codecs="vp8"'); +ok(MediaRecorder.isTypeSupported('VIDEO/WEBM; CODECS="vp8"'), + 'Should support video/webm; codecs="vp8", upper case'); +ok(MediaRecorder.isTypeSupported('vIdEo/WeBm; CoDeCs="vp8"'), + 'Should support video/webm; codecs="vp8", mixed case'); + +ok(MediaRecorder.isTypeSupported('video/webm; codecs="vp8.0"'), + 'Should support video/webm; codecs="vp8.0"'); +ok(MediaRecorder.isTypeSupported('VIDEO/WEBM; CODECS="vp8.0"'), + 'Should support video/webm; codecs="vp8.0", upper case'); +ok(MediaRecorder.isTypeSupported('vIdEo/WeBm; CoDeCs="vp8.0"'), + 'Should support video/webm; codecs="vp8.0", mixed case'); + +ok(!MediaRecorder.isTypeSupported('video/webm; codecs="vp8, vorbis"'), + 'Should not support video/webm + vp8/vorbis'); +ok(!MediaRecorder.isTypeSupported('video/webm; codecs="vp9, vorbis"'), + 'Should not support video/webm + vp9/vorbis'); +ok(MediaRecorder.isTypeSupported('video/webm; codecs="vp8, opus"'), + 'Should support video/webm + vp8/opus'); +ok(!MediaRecorder.isTypeSupported('video/webm; codecs="vp9, opus"'), + 'Should not support video/webm + vp9/opus'); +</script> +</head> +</html> diff --git a/dom/media/test/test_mediastream_as_eventarget.html b/dom/media/test/test_mediastream_as_eventarget.html new file mode 100644 index 0000000000..f09c277583 --- /dev/null +++ b/dom/media/test/test_mediastream_as_eventarget.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test MediaStream as EventTarget</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + var ms = new MediaStream(); + var listenerForFooWasCalled = false; + ms.addEventListener("foo", () => { listenerForFooWasCalled = true; }); + var listenerForAddTrackWasCalled = false; + ms.addEventListener("addtrack", () => { listenerForAddTrackWasCalled = true; }); + var handlerForAddTrackWasCalled = false; + ms.onaddtrack = () => { handlerForAddTrackWasCalled = true; }; + + ms.dispatchEvent(new Event("foo")); + ms.dispatchEvent(new Event("addtrack")); + + ok(listenerForFooWasCalled, + "Should have called the event listener for 'foo'"); + ok(listenerForAddTrackWasCalled, + "Should have called the event listener for 'addtrack'"); + ok(handlerForAddTrackWasCalled, + "Should have called the event handler for 'addtrack'") + </script> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/dom/media/test/test_mediatrack_consuming_mediaresource.html b/dom/media/test/test_mediatrack_consuming_mediaresource.html new file mode 100644 index 0000000000..515df5c053 --- /dev/null +++ b/dom/media/test/test_mediatrack_consuming_mediaresource.html @@ -0,0 +1,198 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test track interfaces when consuming media resources</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +const manager = new MediaTestManager; + +function startTest(test, token) { + const elemType = getMajorMimeType(test.type); + const element = document.createElement(elemType); + + let audioOnchange = 0; + let audioOnaddtrack = 0; + let audioOnremovetrack = 0; + let videoOnchange = 0; + let videoOnaddtrack = 0; + let videoOnremovetrack = 0; + let isPlaying = false; + + isnot(element.audioTracks, undefined, + 'HTMLMediaElement::AudioTracks() property should be available.'); + isnot(element.videoTracks, undefined, + 'HTMLMediaElement::VideoTracks() property should be available.'); + + element.audioTracks.onaddtrack = function(e) { + audioOnaddtrack++; + } + + element.audioTracks.onremovetrack = function(e) { + audioOnremovetrack++; + } + + element.audioTracks.onchange = function(e) { + audioOnchange++; + } + + element.videoTracks.onaddtrack = function(e) { + videoOnaddtrack++; + } + + element.videoTracks.onremovetrack = function(e) { + videoOnremovetrack++; + } + + element.videoTracks.onchange = function(e) { + videoOnchange++; + } + + function checkTrackNotRemoved() { + is(audioOnremovetrack, 0, 'Should have no calls of onremovetrack on audioTracks.'); + is(videoOnremovetrack, 0, 'Should have no calls of onremovetrack on videoTracks.'); + if (isPlaying) { + is(element.audioTracks.length, test.hasAudio ? 1 : 0, + 'Expected length of audioTracks.'); + is(element.videoTracks.length, test.hasVideo ? 1 : 0, + 'Expected length of videoTracks.'); + } + } + + function checkTrackRemoved() { + is(element.audioTracks.length, 0, 'The length of audioTracks should be 0.'); + is(element.videoTracks.length, 0, 'The length of videoTracks should be 0.'); + if (isPlaying) { + is(audioOnremovetrack, test.hasAudio ? 1 : 0, + 'Expected calls of onremovetrack on audioTracks.'); + is(videoOnremovetrack, test.hasVideo ? 1 : 0, + 'Expected calls of onremovetrack on videoTracks.'); + } + } + + function onended() { + ok(true, 'Event ended is expected to be fired on element.'); + checkTrackNotRemoved(); + element.onended = null; + element.onplaying = null; + element.onpause = null; + element.src = ""; + is(element.audioTracks.length, 0, 'audioTracks have been forgotten'); + is(element.videoTracks.length, 0, 'videoTracks have been forgotten'); + is(audioOnremovetrack, 0, 'No audio removetrack events yet'); + is(videoOnremovetrack, 0, 'No video removetrack events yet'); + setTimeout(() => { + checkTrackRemoved(); + manager.finished(element.token); + }, 100); + } + + function checkTrackAdded() { + isPlaying = true; + if (test.hasAudio) { + is(audioOnaddtrack, 1, 'Calls of onaddtrack on audioTracks should be 1.'); + is(element.audioTracks.length, 1, 'The length of audioTracks should be 1.'); + ok(element.audioTracks[0].enabled, 'Audio track should be enabled as default.'); + } + if (test.hasVideo) { + is(videoOnaddtrack, 1, 'Calls of onaddtrack on videoTracks should be 1.'); + is(element.videoTracks.length, 1, 'The length of videoTracks should be 1.'); + is(element.videoTracks.selectedIndex, 0, + 'The first video track is set selected as default.'); + } + } + + function setTrackEnabled(enabled) { + if (test.hasAudio) { + element.audioTracks[0].enabled = enabled; + } + if (test.hasVideo) { + element.videoTracks[0].selected = enabled; + } + } + + function checkTrackChanged(calls, enabled) { + if (test.hasAudio) { + is(audioOnchange, calls, 'Calls of onchange on audioTracks should be '+calls); + is(element.audioTracks[0].enabled, enabled, + 'Enabled value of the audio track should be ' +enabled); + } + if (test.hasVideo) { + is(videoOnchange, calls, 'Calls of onchange on videoTracks should be '+calls); + is(element.videoTracks[0].selected, enabled, + 'Selected value of the video track should be ' +enabled); + var index = enabled ? 0 : -1; + is(element.videoTracks.selectedIndex, index, + 'SelectedIndex of video tracks should be ' +index); + } + } + + function onpause() { + element.onpause = null; + if (element.ended) { + return; + } + if (steps == 1) { + setTrackEnabled(false); + element.onplaying = onplaying; + element.play(); + steps++; + } else if (steps == 2) { + setTrackEnabled(true); + element.onplaying = onplaying; + element.play(); + steps++; + } + } + + function onplaying() { + element.onplaying = null; + if (element.ended) { + return; + } + if (steps == 1) { + element.onpause = onpause; + element.pause(); + checkTrackAdded(); + } else if (steps == 2) { + element.onpause = onpause; + element.pause(); + checkTrackChanged(1, false); + } else if (steps == 3) { + checkTrackChanged(2, true); + } + } + + var steps = 0; + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.onplaying = onplaying; + element.onended = onended; + element.play(); + steps++; +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + { + "set": [ + ["media.track.enabled", true] + ] + }, + function() { + manager.runTests(gTrackTests, startTest); + }); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediatrack_consuming_mediastream.html b/dom/media/test/test_mediatrack_consuming_mediastream.html new file mode 100644 index 0000000000..b930ca4fdc --- /dev/null +++ b/dom/media/test/test_mediatrack_consuming_mediastream.html @@ -0,0 +1,146 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test track interfaces when consuming a MediaStream from gUM</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +async function startTest() { + let steps = 0; + let audioOnchange = 0; + let audioOnaddtrack = 0; + let videoOnchange = 0; + let videoOnaddtrack = 0; + let isPlaying = false; + let element = document.createElement("video"); + let stream; + try { + await setupGetUserMediaTestPrefs(); + stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true}); + } catch (err) { + ok(false, 'Unexpected error fired with: ' + err); + SimpleTest.finish(); + return; + } + + element.audioTracks.onaddtrack = function(e) { + audioOnaddtrack++; + }; + + element.audioTracks.onchange = function(e) { + audioOnchange++; + }; + + element.videoTracks.onaddtrack = function(e) { + videoOnaddtrack++; + }; + + element.videoTracks.onchange = function(e) { + videoOnchange++; + }; + + function checkTrackRemoved() { + if (isPlaying) { + is(element.audioTracks.length, 0, 'The length of audioTracks should be 0.'); + is(element.videoTracks.length, 0, 'The length of videoTracks should be 0.'); + } + } + + element.onended = function() { + ok(true, 'Event ended is expected to be fired on element.'); + checkTrackRemoved(); + element.onended = null; + element.onplaying = null; + element.onpause = null; + SimpleTest.finish(); + } + + function checkTrackAdded() { + isPlaying = true; + is(audioOnaddtrack, 1, 'Calls of onaddtrack on audioTracks should be 1.'); + is(element.audioTracks.length, 1, 'The length of audioTracks should be 1.'); + ok(element.audioTracks[0].enabled, 'Audio track should be enabled as default.'); + is(videoOnaddtrack, 1, 'Calls of onaddtrack on videoTracks should be 1.'); + is(element.videoTracks.length, 1, 'The length of videoTracks should be 1.'); + is(element.videoTracks.selectedIndex, 0, + 'The first video track is set selected as default.'); + } + + function setTrackEnabled(enabled) { + element.audioTracks[0].enabled = enabled; + element.videoTracks[0].selected = enabled; + } + + function checkTrackChanged(calls, enabled) { + is(audioOnchange, calls, 'Calls of onchange on audioTracks should be '+calls); + is(element.audioTracks[0].enabled, enabled, + 'Enabled value of the audio track should be ' +enabled); + is(videoOnchange, calls, 'Calls of onchange on videoTracks should be '+calls); + is(element.videoTracks[0].selected, enabled, + 'Selected value of the video track should be ' +enabled); + var index = enabled ? 0 : -1; + is(element.videoTracks.selectedIndex, index, + 'SelectedIndex of video tracks should be ' +index); + } + + function onpause() { + element.onpause = null; + if (element.ended) { + return; + } + if (steps == 1) { + setTrackEnabled(false); + element.onplaying = onplaying; + element.play(); + steps++; + } else if (steps == 2) { + setTrackEnabled(true); + element.onplaying = onplaying; + element.play(); + steps++; + } + } + + function onplaying() { + element.onplaying = null; + if (element.ended) { + return; + } + if (steps == 1) { + element.onpause = onpause; + element.pause(); + checkTrackAdded(); + } else if (steps == 2) { + element.onpause = onpause; + element.pause(); + checkTrackChanged(1, false); + } else if (steps == 3) { + checkTrackChanged(2, true); + stream.getTracks().forEach(t => t.stop()); + } + } + + element.onplaying = onplaying; + element.srcObject = stream; + + steps++; + await element.play(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + { + "set": [ + ["media.track.enabled", true] + ] + }, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediatrack_events.html b/dom/media/test/test_mediatrack_events.html new file mode 100644 index 0000000000..5eae94f804 --- /dev/null +++ b/dom/media/test/test_mediatrack_events.html @@ -0,0 +1,135 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test events of media track interfaces</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +async function startTest() { + let steps = 0; + let element = document.createElement("video"); + let stream; + try { + await setupGetUserMediaTestPrefs(); + stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true}); + } catch (err) { + ok(false, 'Unexpected error fired with: ' + err); + SimpleTest.finish(); + return; + } + + function verifyEvent(e, type) { + is(e.type, type, "Event type should be " + type); + ok(e.isTrusted, "Event should be trusted."); + ok(!e.bubbles, "Event shouldn't bubble."); + ok(!e.cancelable, "Event shouldn't be cancelable."); + } + + element.audioTracks.onaddtrack = function(e) { + ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent"); + ok(true, 'onaddtrack is expected to be called from audioTracks.'); + verifyEvent(e, "addtrack"); + }; + + element.audioTracks.onremovetrack = function(e) { + ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent"); + ok(true, 'onremovetrack is expected to be called from audioTracks.'); + verifyEvent(e, "removetrack"); + }; + + element.audioTracks.onchange = function(e) { + ok(e instanceof window.Event, "Event fired from onchange should be a simple event."); + ok(true, 'onchange is expected to be called from audioTracks.'); + verifyEvent(e, "change"); + }; + + element.videoTracks.onaddtrack = function(e) { + ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent"); + ok(true, 'onaddtrack is expected to be called from videoTracks.'); + verifyEvent(e, "addtrack"); + }; + + element.videoTracks.onremovetrack = function(e) { + ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent"); + ok(true, 'onremovetrack is expected to be called from videoTracks.'); + verifyEvent(e, "removetrack"); + }; + + element.videoTracks.onchange = function(e) { + ok(e instanceof window.Event, "Event fired from onchange should be a simple event."); + ok(true, 'onchange is expected to be called from videoTracks.'); + verifyEvent(e, "change"); + }; + + element.onended = function() { + ok(true, 'Event ended is expected to be fired on element.'); + element.onended = null; + element.onplaying = null; + element.onpause = null; + //This helps to prevent these events from firing after SimpleTest.finish() + //on B2G ICS Emulator, but not sure they have been run at all, then + element.audioTracks.onremovetrack = null; + element.audioTracks.onaddtrack = null; + element.audioTracks.onchange = null; + element.videoTracks.onremovetrack = null; + element.videoTracks.onaddtrack = null; + element.videoTracks.onchange = null; + SimpleTest.finish(); + } + + function onpause() { + element.onpause = null; + if (element.ended) { + return; + } + if (steps == 1) { + element.audioTracks[0].enabled = false; + element.videoTracks[0].selected = false; + element.onplaying = onplaying; + element.play(); + steps++; + } + } + + function onplaying() { + element.onplaying = null; + if (element.ended) { + return; + } + if (steps == 1) { + element.onpause = onpause; + element.pause(); + } else if (steps == 2) { + stream.getTracks().forEach(t => t.stop()); + } + } + + element.onplaying = onplaying; + element.srcObject = stream; + + isnot(element.audioTracks, undefined, + 'HTMLMediaElement::AudioTracks() property should be available.'); + isnot(element.videoTracks, undefined, + 'HTMLMediaElement::VideoTracks() property should be available.'); + + steps++; + await element.play(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + { + "set": [ + ["media.track.enabled", true] + ] + }, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediatrack_parsing_ogg.html b/dom/media/test/test_mediatrack_parsing_ogg.html new file mode 100644 index 0000000000..aabd40e2a3 --- /dev/null +++ b/dom/media/test/test_mediatrack_parsing_ogg.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test events of media track interfaces</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function localCheckMetadata(msg, e) { + ok(msg in gOggTrackInfoResults, "File: " + msg + " is in pre-parsed gOggTrackInfoResults list"); + var r = gOggTrackInfoResults[msg]; + + var hasExpectedAudio = r && r.hasOwnProperty("audio_id"); + var hasExpectedVideo = r && r.hasOwnProperty("video_id"); + + var hasParsedAudio = e.audioTracks.length >= 1; + var hasParsedVideo = e.videoTracks.length >= 1; + + ok(!(hasExpectedAudio ^ hasParsedAudio), "Check availability of expected/parsed audio"); + ok(!(hasExpectedVideo ^ hasParsedVideo), "Check availability of expected/parsed video"); + if (hasParsedAudio) { + is(e.audioTracks.length, 1, "The length of audio track should be 1"); + is(e.audioTracks[0].id, r.audio_id, "File: " + msg + ", Audio track id"); + is(e.audioTracks[0].kind, r.audio_kind, "File: " + msg + ", Audio track kind"); + is(e.audioTracks[0].language, r.audio_language, "File: " + msg + ", Audio track language"); + is(e.audioTracks[0].label, r.audio_label, "File: " + msg + ", Audio track label"); + } + if (hasParsedVideo) { + is(e.videoTracks.length, 1, "The length of video track should be 1"); + is(e.videoTracks[0].id, r.video_id, "File: " + msg + ", Video track id"); + is(e.videoTracks[0].kind, r.video_kind, "File: " + msg + ", Video track kind"); + is(e.videoTracks[0].language, r.video_language, "File: " + msg + ", Video track language"); + is(e.videoTracks[0].label, r.video_label, "File: " + msg + ", Video track label"); + } +} + +function startTest(test, token) { + var v = document.createElement('video'); + v.preload = "metadata"; + v.token = token; + manager.started(token); + + v.src = test.name; + v.name = test.name; + + v.onloadedmetadata = function(evt) { + localCheckMetadata(evt.target.name, evt.target); + evt.target.finished = true; + evt.target.onloadedmetadata = null; + removeNodeAndSource(evt.target); + manager.finished(evt.target.token); + }; + + document.body.appendChild(v); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.track.enabled", true]]}, + function() { + manager.runTests(gMultitrackInfoOggPlayList, startTest); + } +); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mediatrack_replay_from_end.html b/dom/media/test/test_mediatrack_replay_from_end.html new file mode 100644 index 0000000000..16b0cbeb97 --- /dev/null +++ b/dom/media/test/test_mediatrack_replay_from_end.html @@ -0,0 +1,160 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test media tracks if replay after playback has ended</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +const manager = new MediaTestManager; + +function startTest(test, token) { + // Scenario to test: + // 1. Audio tracks and video tracks should be added to the track list when + // metadata has loaded, and all tracks should remain even after we seek to + // the end. + // 2. No tracks should be added back to the list if we replay from the end, + // and no tracks should be removed from the list after we seek to the end. + // 3. After seek to the middle from end of playback, all tracks should remain + // in the list if we play from here, and no tracks should be removed from + // the list after we seek to the end. + // 4. Unsetting the media element's src attribute should remove all tracks. + + const elemType = getMajorMimeType(test.type); + const element = document.createElement(elemType); + + let audioOnaddtrack = 0; + let audioOnremovetrack = 0; + let videoOnaddtrack = 0; + let videoOnremovetrack = 0; + let isPlaying = false; + let steps = 0; + + element.audioTracks.onaddtrack = function(e) { + audioOnaddtrack++; + } + + element.audioTracks.onremovetrack = function(e) { + audioOnremovetrack++; + } + + element.videoTracks.onaddtrack = function(e) { + videoOnaddtrack++; + } + + element.videoTracks.onremovetrack = function(e) { + videoOnremovetrack++; + } + + function testExpectedAddtrack(expectedCalls) { + if (test.hasAudio) { + is(audioOnaddtrack, expectedCalls, + 'Calls of onaddtrack on audioTracks should be '+expectedCalls+' times.'); + } + if (test.hasVideo) { + is(videoOnaddtrack, expectedCalls, + 'Calls of onaddtrack on videoTracks should be '+expectedCalls+' times.'); + } + } + + function testExpectedRemovetrack(expectedCalls) { + if (test.hasAudio) { + is(audioOnremovetrack, expectedCalls, + 'Calls of onremovetrack on audioTracks should be '+expectedCalls+' times.'); + } + if (test.hasVideo) { + is(videoOnremovetrack, expectedCalls, + 'Calls of onremovetrack on videoTracks should be '+expectedCalls+' times.'); + } + } + + function finishTesting() { + element.onpause = null; + element.onseeked = null; + element.onplaying = null; + element.onended = null; + manager.finished(element.token); + } + + function onended() { + if (isPlaying) { + switch(steps) { + case 1: + testExpectedAddtrack(1); + testExpectedRemovetrack(0); + element.onplaying = onplaying; + element.play(); + steps++; + break; + case 2: + testExpectedAddtrack(1); + testExpectedRemovetrack(0); + element.currentTime = element.duration * 0.5; + element.onplaying = onplaying; + element.play(); + steps++; + break; + case 3: + testExpectedAddtrack(1); + testExpectedRemovetrack(0); + element.src = ""; + setTimeout(() => { + testExpectedAddtrack(1); + testExpectedRemovetrack(1); + finishTesting(); + }, 0); + break; + } + } else { + ok(true, 'Finish the test anyway if ended is fired before other events.'); + finishTesting(); + } + } + + function seekToEnd() { + element.onpause = null; + element.currentTime = element.duration * 1.1; + } + + function onseeked() { + element.onseeked = null; + element.onpause = seekToEnd; + element.pause(); + } + + function onplaying() { + isPlaying = true; + element.onplaying = null; + element.onseeked = onseeked; + } + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + element.onplaying = onplaying; + element.onended = onended; + element.play(); + steps++; +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + { + "set": [ + ["media.track.enabled", true] + ] + }, + function() { + manager.runTests(gTrackTests, startTest); + }); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_metadata.html b/dom/media/test/test_metadata.html new file mode 100644 index 0000000000..2fc6ddffec --- /dev/null +++ b/dom/media/test/test_metadata.html @@ -0,0 +1,81 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test returning metadata from media files with mozGetMetadata()</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<div id="output"></div> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var a = document.createElement('audio'); + a.preload = "metadata"; + a.token = token; + manager.started(token); + + a.src = test.name; + a.name = test.name; + + // Tags should not be available immediately. + var exception_fired = false; + try { + a.mozGetMetadata(); + } catch (e) { + is(e.name, 'InvalidStateError', + "early mozGetMetadata() should throw InvalidStateError"); + exception_fired = true; + } + ok(exception_fired, + "mozGetMetadata() should throw an exception before HAVE_METADATA"); + + // Wait until metadata has loaded. + a.addEventListener('loadedmetadata', function() { + // read decoded tags + let tags = a.mozGetMetadata(); + ok(tags, "mozGetMetadata() should return a truthy value"); + // Dump them out. + var d = document.getElementById('output'); + var html = '<table>\n'; + html += '<caption><p>Called getMozMetadata()' + html += ' on '+test.name+'</p></caption>\n'; + html += '<tr><th>tag</th>'; + html += '<th>decoded value</th><th>expected value</th></tr>\n'; + for (let tag in tags) { + html += '<tr><td>'+tag+'</td>'; + html += '<td>'+tags[tag]+'</td>'; + html += '<td>'+test.tags[tag]+'</td>'; + html += '</tr>\n'; + } + if (!Object.keys(tags).length) { + html += '<tr><td colspan=3 align=center><em>no tags</em></td></tr>\n'; + } + html += '</table>\n'; + var div = document.createElement('div'); + div.innerHTML = html; + d.appendChild(div); + // Verify decoded tag values. + for (let tag in tags) { + is(tags[tag], test.tags[tag], "Tag '"+tag+"' should match"); + } + // Verify expected tag values + for (let tag in test.tags) { + is(tags[tag], test.tags[tag], "Tag '"+tag+"' should match"); + } + removeNodeAndSource(a); + manager.finished(token); + }); +} + +manager.runTests(gMetadataTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_midflight_redirect_blocked.html b/dom/media/test/test_midflight_redirect_blocked.html new file mode 100644 index 0000000000..ea85673b45 --- /dev/null +++ b/dom/media/test/test_midflight_redirect_blocked.html @@ -0,0 +1,87 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Test mid-flight cross site redirects are blocked</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + </head> + <body> + <pre id='test'> + <script class="testbody" type='application/javascript'> + + function testIfLoadsToMetadata(test, useCors) { + return new Promise(function(resolve, reject) { + var elemType = getMajorMimeType(test.type); + var element = document.createElement(elemType); + + if (useCors) { + element.crossOrigin = "anonymous"; + } + + // Log events for debugging. + [ + "suspend", "play", "canplay", "canplaythrough", "loadstart", + "loadedmetadata", "loadeddata", "playing", "ended", "error", + "stalled", "emptied", "abort", "waiting", "pause" + ].forEach((eventName) => { + element.addEventListener(eventName, (event)=> { + info(test.name + " " + event.type); + }); + }); + + element.addEventListener("loadedmetadata", ()=>{ + resolve(true); + removeNodeAndSource(element); + }); + + element.addEventListener("error", ()=>{ + resolve(false); + removeNodeAndSource(element); + }); + + // Note: request redirect before the end of metadata, otherwise we won't + // error before metadata has loaded if mixed origins are allowed. + element.src = "midflight-redirect.sjs?resource=" + test.name + + (useCors ? "&cors" : "") + + "&type=" + test.type + + "&redirectAt=200"; + element.preload = "metadata"; + document.body.appendChild(element); + element.load() + }); + } + + let v = document.createElement("video"); + const testCases = gSmallTests.filter(t => v.canPlayType(t.type)); + + async function testMediaLoad(message, {useCors}) { + for (let test of testCases) { + let loaded = await testIfLoadsToMetadata(test, useCors); + is(loaded, useCors, test.name + " " + message); + } + } + + async function runTest() { + try { + SimpleTest.info("Test that all media do not play without CORS..."); + await testMediaLoad("expected to be blocked", {useCors: false}); + + SimpleTest.info("Test that all media play if CORS used..."); + await testMediaLoad("expected to play with CORS", {useCors: true}); + } catch (e) { + info("Exception " + e.message); + ok(false, "Threw exception " + e.message); + } + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(runTest); + + </script> + </pre> + </body> +</html> diff --git a/dom/media/test/test_mixed_principals.html b/dom/media/test/test_mixed_principals.html new file mode 100644 index 0000000000..c1deaef697 --- /dev/null +++ b/dom/media/test/test_mixed_principals.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=489415 +--> +<head> + <title>Test for Bug 489415</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <style> + video { + width: 40%; + border: solid black 1px; + } + </style> +</head> + +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=489415">Mozilla Bug 489415</a> + <p id="display"></p> + <pre id="test"> + <script type="text/javascript"> + SimpleTest.waitForExplicitFinish(); + + var pushPrefs = (...p) => SpecialPowers.pushPrefEnv({ set: p }); + var count = 0; + + function canReadBack(video) { + var c = document.createElement("canvas"); + var ctx = c.getContext("2d"); + ctx.drawImage(video, 0, 0); + try { + var data_url = c.toDataURL(); + var empty_canvas = document.createElement("canvas"); + if (empty_canvas.toDataURL() === data_url) { + info("Readback check returned same data URL as empty canvas."); + } else { + info("Readback check returned different data URL than empty canvas."); + } + return true; + } catch (ex) { + return false; + } + } + + function runTest(origin, shouldReadBackOnLoad) { + return new Promise(function (resolve, reject) { + // Load will redirect mid-flight, which will be detected and should error, + // and we should no longer be able to readback. + var video = document.createElement("video"); + video.preload = "metadata"; + video.controls = true; + var url = "http://" + origin + "/tests/dom/media/test/midflight-redirect.sjs" + + "?resource=pixel_aspect_ratio.mp4&type=video/mp4"; + SimpleTest.info("Loading from " + url); + video.src = url; + document.body.appendChild(video); + + once(video, "loadeddata", () => { + is(canReadBack(video), shouldReadBackOnLoad, "Should be able to readback"); + video.play(); + }); + + once(video, "error", () => { + if(video.readyState == video.HAVE_METADATA) { + is(canReadBack(video), true, "Should be able to readback with readyState == HAVE_METADATA"); + } else { + is(canReadBack(video), false, "Should not be able to readback with readyState != HAVE_METADATA"); + } + + removeNodeAndSource(video); + resolve(); + }); + + once(video, "ended", () => { + ok(false, "Should not be able to playback to end, we should have errored!"); + removeNodeAndSource(video); + resolve(); + }); + + }); + } + + Promise.all([ + runTest("mochi.test:8888", true), + runTest("example.org", false), + ]).then(SimpleTest.finish); + + </script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mozHasAudio.html b/dom/media/test/test_mozHasAudio.html new file mode 100644 index 0000000000..c25873c786 --- /dev/null +++ b/dom/media/test/test_mozHasAudio.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test playback of media files that should play OK</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function onloadedmetadata(e) { + var t = e.target; + is(t.mozHasAudio, t.hasAudio, "The element reports the wrong audio property." + t.token); + manager.finished(t.token); +} + +function startTest(test, token) { + var elemType = /^audio/.test(test.type) ? "audio" : "video"; + var element = document.createElement(elemType); + element.preload = "auto"; + + element.token = token; + manager.started(token); + + element.src = test.name; + element.name = test.name; + element.hasAudio = elemType == "video" ? test.hasAudio : undefined; + element.addEventListener("loadedmetadata", onloadedmetadata); + + element.load(); +} + +manager.runTests(gTrackTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_mp3_broadcast.html b/dom/media/test/test_mp3_broadcast.html new file mode 100644 index 0000000000..7922d8b4b6 --- /dev/null +++ b/dom/media/test/test_mp3_broadcast.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> + +<head> + <title>Test playback of broadcast-like streams</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> + +<body> + <audio controls id=a style="width: 100%;"></audio> + <script type="module"> + SimpleTest.waitForExplicitFinish(); + const streams = [ + // An mp3 bytestream consisting of a complete mp3 file with a XING + // header, that has duration information, but served without a + // `Content-Length`. It is followed by a second mp3 bytestream that + // also has a XING header. While some software are able to play the + // entire file, Web browser don't. + { src: "two-xing-header-no-content-length.mp3", duration: 1 }, + // An mp3 bytestream consisting of a complete mp3 file with a XING + // header, that has duration information, but served without a + // `Content-Length` header. It is followed by a second mp3 bytestream that + // doesn't have a XING header. + // This scenario is typical in radio broadcast scenario, when the + // live-stream has a pre-recorded prelude. The reported duration, + // after "ended" has been received, is the duration of playback. + { src: "single-xing-header-no-content-length.mp3", duration: 11.050839}, + ]; + var audio = window.a; + // Prevent ESLint error about top-level await + (async function () { + for (let i of streams) { + audio.src = i.src; + audio.load(); + audio.play(); + audio.onerror = (e) => { + ok(false, `${i}: error: ${e.message}}`); + }; + await once(audio, "ended"); + ok(true, `${i}: playback through the end`); + is(audio.duration, i.duration, "Duration at end is correct"); + is(audio.currentTime, i.duration, "Current time at end is correct"); + } + SimpleTest.finish(); + })() + </script> +</body> + +</html> + diff --git a/dom/media/test/test_mp3_with_multiple_ID3v2.html b/dom/media/test/test_mp3_with_multiple_ID3v2.html new file mode 100644 index 0000000000..1f2f946520 --- /dev/null +++ b/dom/media/test/test_mp3_with_multiple_ID3v2.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Play mp3 file with multiple ID3v2 tags</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +add_task(async function testPlayMP3WithMultipleID3Tags() { + info(`adjust cache size`); + await SpecialPowers.pushPrefEnv( + // The second ID3v2 header is huge (4622361 bytes) so the first audio samle + // in this file is in the position 4945370, so we have to extend the size of + // the cache. + {"set": [["media.cache_size", 5000000]]} + ); + + info(`create audio and wait its loading`); + let audio = document.createElement('audio'); + audio.src = "multi_id3v2.mp3"; + document.body.appendChild(audio); + await new Promise(r => audio.onloadeddata = r); + ok(true, `finishing loading data.`) +}); + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/test_multiple_mediastreamtracks.html b/dom/media/test/test_multiple_mediastreamtracks.html new file mode 100644 index 0000000000..fb28d8652e --- /dev/null +++ b/dom/media/test/test_multiple_mediastreamtracks.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test the ability of MediaStream with multiple MediaStreamTracks</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +async function startTest() { + try { + await setupGetUserMediaTestPrefs(); + let orgStream = await navigator.mediaDevices.getUserMedia({audio: true, video: true}); + let a = orgStream.getAudioTracks()[0]; + let v = orgStream.getVideoTracks()[0]; + let stream = new MediaStream([a, a, a, a, v, v, v].map(track => track.clone())); + let element = document.createElement("video"); + + element.onloadedmetadata = function() { + is(stream.getAudioTracks().length, 4, 'Length of audio tracks should be 4.'); + is(stream.getVideoTracks().length, 3, 'Length of vudio tracks should be 3.'); + SimpleTest.finish(); + }; + + element.srcObject = stream; + element.play(); + } catch (err) { + ok(false, 'Unexpected error fired with: ' + err); + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + { + "set": [ + ["media.track.enabled", true] + ] + }, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_networkState.html b/dom/media/test/test_networkState.html new file mode 100644 index 0000000000..8001ca514c --- /dev/null +++ b/dom/media/test/test_networkState.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: networkState</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body onunload="mediaTestCleanup();"> +<video id='v1'></video><audio id='a1'></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +"use strict"; +var v1 = document.getElementById('v1'); +var a1 = document.getElementById('a1'); +var passed = "truthy"; + +try { + v1.networkState = 0; +} catch (e) { + passed = !passed; +} +try { + a1.networkState = 0; +} catch (e) { + passed = !passed; +} +ok(passed === true, + "Setting networkState throws in strict mode (readonly attribute)"); +</script> + +<script class="testbody" type="text/javascript"> +var v1 = document.getElementById('v1'); +var a1 = document.getElementById('a1'); +var passed = false; + +var oldv1ns = v1.networkState, olda1ns = a1.networkState; +try { + v1.networkState = 0; + a1.networkState = 0; + passed = v1.networkState === oldv1ns && a1.networkState === olda1ns; +} catch (e) { } +ok(passed, "Should not be able to modify networkState (readonly attribute)"); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_new_audio.html b/dom/media/test/test_new_audio.html new file mode 100644 index 0000000000..e1f8964f73 --- /dev/null +++ b/dom/media/test/test_new_audio.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=528566 +--> +<head> + <title>Test for Bug 528566</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=528566">Mozilla Bug 528566</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 528566 **/ + +var manager = new MediaTestManager; + +var player = new Audio(); + +function startTest(test, token) { + if (!player.canPlayType(test.type)) { + return; + } + manager.started(token); + var a = new Audio(test.name); + a.autoplay = true; + document.body.appendChild(a); + a.addEventListener("ended", + function(e){ + ok(true, "[" + a.src + "]We should get to the end. Oh look we did."); + a.remove(); + manager.finished(token); + }); +} + +manager.runTests(gAudioTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_no_load_event.html b/dom/media/test/test_no_load_event.html new file mode 100644 index 0000000000..1e2717d983 --- /dev/null +++ b/dom/media/test/test_no_load_event.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=715469 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 715469</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body onload="start();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=715469">Mozilla Bug 715469</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> + +<script type="application/javascript"> + +/** Test for Bug 715469 **/ + +var gotLoadEvent = false; + +function start() { + var resource = getPlayableVideo(gSmallTests); + if (resource == null) { + todo(false, "No types supported"); + } else { + SimpleTest.waitForExplicitFinish(); + var v = document.createElement("video"); + v.src = resource.name; + + v.addEventListener("load", function() { + gotLoadEvent = true; + }); + + v.addEventListener("ended", finished); + document.body.appendChild(v); + v.play(); + } +} + +function finished() { + is(gotLoadEvent, false, "Should not receive a load on the video element"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_not_reset_playbackRate_when_removing_nonloaded_media_from_document.html b/dom/media/test/test_not_reset_playbackRate_when_removing_nonloaded_media_from_document.html new file mode 100644 index 0000000000..f1b8cc8b15 --- /dev/null +++ b/dom/media/test/test_not_reset_playbackRate_when_removing_nonloaded_media_from_document.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Do not reset playback rate when removing non-loaded media from a document</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script class="testbody" type="text/javascript"> +/** + * When removing media from a document, it should only trigger internal pause, + * instead of the pause method, which would trigger loading process and reset + * the media's playback rate for non-loaded media. + */ +async function startTest() { + info(`create a media and append it to a document`); + const audio = document.createElement("audio"); + document.body.appendChild(audio); + + info(`change audio's playbackRate and remove it from a document`); + const expectedRate = 0.1; + audio.playbackRate = expectedRate; + await once(audio, "ratechange"); + is(audio.playbackRate, expectedRate, + `${audio.playbackRate} is equal to ${expectedRate}`); + audio.remove(); + + info(`queue a macrotask to check if the playback rate is still unchanged`); + setTimeout(() => { + // If we unexpectedly reset the playback rate, it would happen in a + // microtask when removing media from a document [1] (Await a stable state), + // which would always be run before the macrotask. + // [1] https://html.spec.whatwg.org/#playing-the-media-resource:remove-an-element-from-a-document + is(audio.playbackRate, expectedRate, + `${audio.playbackRate} is equal to ${expectedRate}`); + SimpleTest.finish(); + }, 0); +} + +SimpleTest.waitForExplicitFinish(); +onload = startTest; + +</script> +</body> +</html> diff --git a/dom/media/test/test_paused.html b/dom/media/test/test_paused.html new file mode 100644 index 0000000000..17af4d3898 --- /dev/null +++ b/dom/media/test/test_paused.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: paused</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<video id='v1'></video><audio id='a1'></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var v1 = document.getElementById('v1'); +var a1 = document.getElementById('a1'); +ok(v1.paused, "v1.paused must initially be true"); +ok(a1.paused, "a1.paused must initially be true"); +mediaTestCleanup(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_paused_after_ended.html b/dom/media/test/test_paused_after_ended.html new file mode 100644 index 0000000000..83f27a921f --- /dev/null +++ b/dom/media/test/test_paused_after_ended.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: paused</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function ended(evt) { + var v = evt.target; + v.removeEventListener("ended", ended); + is(v.gotPause, true, "We should have received a \"pause\" event.") + is(v.paused, true, v._name + " must be paused after end"); + manager.finished(v.token); + removeNodeAndSource(v); +} + +function pause(evt) { + var v = evt.target; + v.removeEventListener("pause", pause); + v.gotPause = true; +} + +function startTest(test, token) { + var v = document.createElement('video'); + document.body.appendChild(v); + v.token = token; + manager.started(v.token); + v.src = test.name; + v._name = test.name; + v._finished = false; + v.load(); + is(v.paused, true, v._name + " must be paused at start"); + + v.play(); + is(v.paused, false, v._name + " must not be paused after play"); + + v.addEventListener("pause", pause); + v.addEventListener("ended", ended); +} + +manager.runTests(gPausedAfterEndedTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_periodic_timeupdate.html b/dom/media/test/test_periodic_timeupdate.html new file mode 100644 index 0000000000..5d40c7e38a --- /dev/null +++ b/dom/media/test/test_periodic_timeupdate.html @@ -0,0 +1,100 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Periodic timeupdate test</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +/** + * To ensure that when dispatching periodic `timeupdate` event, we would only + * dispatch that once within 250ms according to the spec. This test would end + * after receiving certain number of timeupdate` event. + */ +const sNumPeriodicTimeupdatesToEndTestAfter = 5; +const sTimeThreshold = 250; + +add_task(async function testPeriodicTimeupdateShouldOnlyBeDispatchedOnceWithin250Ms() { + const video = document.createElement('video'); + video.src = "gizmo.mp4"; + video.loop = true; + video._timeupdateCount = 0; + document.body.appendChild(video); + ok(await video.play().then(_=>true,_=>false), "video started playing"); + const culprit = createCulpritToMakeMainThreadBusy(); + await new Promise(r => { + function endTest() { + video.removeEventListener("timeupdate", checkTimeupdate); + culprit.shutdown(); + r(); + } + video.onseeking = () => { + info(`seeking starts (looping back to the head)`); + video._ignoreEvents = true; + } + video.onseeked = () => { + info(`seeking ends`); + video._ignoreEvents = false; + } + function checkTimeupdate(event) { + // When reaching to the end, video would perform a seek to the start + // position where one mandatory `timeupdate` would be dispatched. + if (video._ignoreEvents) { + info(`ignore non-periodic timeupdate because that is allowed to be dispatched within ${sTimeThreshold}ms`); + return; + } + + const now = performance.now(); + if (video._prevTime === undefined) { + info(`recevied the first 'timeupdate'`); + video._prevTime = now; + return; + } + + const timeDiff = now - video._prevTime; + if (timeDiff < sTimeThreshold) { + ok(false, `Time diff ${timeDiff} is smaller than ${sTimeThreshold}ms!`); + endTest(); + return; + } + + ok(true, `Time diff ${timeDiff} since last time received 'timeupdate'`); + video._prevTime = now; + info(`check timeupdate ${++video._timeupdateCount} time`); + if (video._timeupdateCount == sNumPeriodicTimeupdatesToEndTestAfter) { + endTest(); + } + }; + video.addEventListener("timeupdate", checkTimeupdate); + }); +}); + +window.onmessage = _ => blockMainThreadForMilliseconds(1); + +/** + * Following are helper functions + */ +function blockMainThreadForMilliseconds(ms) { + const lastTime = performance.now(); + while (lastTime + ms > performance.now()); +} + +function createCulpritToMakeMainThreadBusy() { + let culprit = {}; + culprit._id = setInterval(_ => { + blockMainThreadForMilliseconds(1000); + }, 0); + culprit.shutdown = _ => { + clearInterval(culprit._id); + } + for (let i = 0; i < 5000; ++i) { + window.postMessage("foo", "*"); + } + return culprit; +} + +</script> +</head> +<body> +</body> +</html> diff --git a/dom/media/test/test_play_events.html b/dom/media/test/test_play_events.html new file mode 100644 index 0000000000..44b819b488 --- /dev/null +++ b/dom/media/test/test_play_events.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> + +var manager = new MediaTestManager; + +var tokens = { + 0: ["play"], + "play": ["canplay"], + "canplay": ["playing"], + "playing": ["canplay", "canplaythrough"], + "canplaythrough": ["canplay", "canplaythrough"] +}; + +function gotPlayEvent(event) { + var v = event.target; + ok(tokens[v._state].includes(event.type), + "Check expected event got " + event.type + " at " + v._state + " for " + v.src + + " tokens["+v._state+"]=" + tokens[v._state] + + " tokens["+v._state+"].indexOf(event.type)=" + tokens[v._state].indexOf(event.type)); + v._state = event.type; +} + +function ended(event) { + var v = event.target; + removeNodeAndSource(v); + manager.finished(v.token); +} + +function initTest(test, token) { + var v = document.createElement('video'); + v.token = token; + manager.started(token); + v._state = 0; + + ["play", "canplay", "playing", "canplaythrough"].forEach(function (e) { + v.addEventListener(e, gotPlayEvent); + }); + + v.addEventListener("ended", ended); + + v.src = test.name; + document.body.appendChild(v); // Causes load. + v.play(); +} + +manager.runTests(gSmallTests, initTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_play_events_2.html b/dom/media/test/test_play_events_2.html new file mode 100644 index 0000000000..022bb5373a --- /dev/null +++ b/dom/media/test/test_play_events_2.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: play() method via DOM 0 handlers</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +var manager = new MediaTestManager; + +var tokens = { + 0: ["play"], + "play": ["canplay"], + "canplay": ["playing"], + "playing": ["canplay", "canplaythrough"], + "canplaythrough": ["canplay", "canplaythrough"] +}; + +function gotPlayEvent(event) { + var v = event.target; + ok(tokens[v._state].includes(event.type), + "Check expected event got " + event.type + " at " + v._state + " for " + v.src); + v._state = event.type; +} + +function ended(event) { + var v = event.target; + v._finished = true; + removeNodeAndSource(v); + manager.finished(v.token); +} + +function startTest(test, token) { + var v = document.createElement('video'); + v.token = token; + manager.started(token); + v._state = 0; + v._finished = false; + + ["play", "canplay", "playing", "canplaythrough"].forEach(function (e) { + v["on" + e] = gotPlayEvent; + }); + + v.onended = ended; + + v.src = test.name; + document.body.appendChild(v); // Causes load. + v.play(); +} + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_play_promise_1.html b/dom/media/test/test_play_promise_1.html new file mode 100644 index 0000000000..ce4e287f34 --- /dev/null +++ b/dom/media/test/test_play_promise_1.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playBeforeCanPlay +// Case: invoke play() on an element that doesn't have enough data +// Expected result: resolve the promise + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.src = test.name; + ok(element.readyState == HTMLMediaElement.HAVE_NOTHING); + + element.play().then( + (result) => { + if (result == undefined) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result}.`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_10.html b/dom/media/test/test_play_promise_10.html new file mode 100644 index 0000000000..1c0096986c --- /dev/null +++ b/dom/media/test/test_play_promise_10.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: loadRejectsPendingPromises +// Case: invoke load() on an element with pending promises. +// Expected result: reject all the pending promises with AbortError DOM exception. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.play().then( + (result) => { + ok(false, `${token} is resolved with ${result}.`); + }, + (error) => { + if (error.name == "AbortError") { + ok(true, `${token} is rejected with ${error.name}.`); + } else { + ok(false, `${token} is rejected with ${error.name}.`); + } + } + ).then( () => { manager.finished(token); } ); + element.load(); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_11.html b/dom/media/test/test_play_promise_11.html new file mode 100644 index 0000000000..a59baf5657 --- /dev/null +++ b/dom/media/test/test_play_promise_11.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: newSrcRejectPendingPromises +// Case: change src of an element with pending promises. +// Expected result: reject all the pending promises. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.play().then( + (result) => { + ok(false, `${token} is resolved with ${result}.`); + }, + (error) => { + if (error.name == "AbortError") { + ok(true, `${token} is rejected with ${error.name}.`); + } else { + ok(false, `${token} is rejected with ${error.name}.`); + } + } + ).then( () => { manager.finished(token); } ); + element.src = test.name; +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_12.html b/dom/media/test/test_play_promise_12.html new file mode 100644 index 0000000000..50972885eb --- /dev/null +++ b/dom/media/test/test_play_promise_12.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: pausePlayAfterPlaybackStarted +// Case: invoke pause() and then play() on an element that is already playing. +// Expected result: resolve the promise with undefined. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.preload = "auto"; + element.src = test.name; + element.play(); + once(element, "playing").then(() => { + element.pause(); + element.play().then( + (result) => { + if (result == undefined) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result}.`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_13.html b/dom/media/test/test_play_promise_13.html new file mode 100644 index 0000000000..aacab88895 --- /dev/null +++ b/dom/media/test/test_play_promise_13.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: loadAlgorithmDoesNotCancelTasks +// Case: re-invoke the load() on an element which had dispatched a task to resolve a promise. +// Expected result: the already dispatched promise should still be resolved with undefined. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.preload = "auto"; + element.src = test.name; + + // We must wait for "canplay" event; otherwise, invoke play() will lead to a + // pending promise and will then be rejected by the following load(). + once(element, "canplay").then(() => { + // The play() promise will be queued to be resolved immediately, which means + // the promise is not in the pending list. + element.play().then( + (result) => { + if (result == undefined) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result}.`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); + element.src = test.name; // Re-invoke the load algorithm again. + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_14.html b/dom/media/test/test_play_promise_14.html new file mode 100644 index 0000000000..066138ecad --- /dev/null +++ b/dom/media/test/test_play_promise_14.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: loadAlgorithmKeepPromisesPendingWhenNotPausing +// Case: step1: create an element with its paused member to be fause and networkState to be NETWORK_EMPTY. +// stpe2: invoke load() on the element and the load() leaves the promise pending. +// Expected result: the pending promise should finally be resolved. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + // Invoke play() -> (1) the promise will be left pending. + // (2) invoke load() -> (1) set the networkState to be NETWORK_NO_SOURCE. + // (2) queue a task to run resouce selection algorithm. + element.play().then( + (result) => { + if (result == undefined) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result}.`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); + + once(element, "play").then(() => { + // The resouce selection algorithm has been done. + // -> set the networkState to be NETWORK_EMPTY because there is no valid resource to load. + ok(element.networkState == HTMLMediaElement.NETWORK_EMPTY); + + // Invoke load() again and since the networkState is NETWORK_EMPTY, the load() does not reject the pending promise. + // The load() will queue a task to run resouce selection algorithm which will change the readyState and finally resolve the pending promise. + element.src = test.name; + + // Since the networkState is NETWORK_EMPTY, the load() does not set paused to be true. + ok(!element.paused, `loadAlgorithmKeepPromisesPendingWhenNotPausing(${token}).paused should be false.`); + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_15.html b/dom/media/test/test_play_promise_15.html new file mode 100644 index 0000000000..b8bce48651 --- /dev/null +++ b/dom/media/test/test_play_promise_15.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: loadAlgorithmRejectPromisesWhenPausing +// Case: step1: create an element with its paused member to be fause and networkState to be NETWORK_NO_SOURCE. +// stpe2: invoke load() on the element and the load() rejects the pending promise. +// Expected result: reject the pending promise with AbortError DOM exception. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + // Invoke play() -> (1) the promise will be left pending. + // (2) invoke load() -> (1) set the networkState to be NETWORK_NO_SOURCE. + // (2) queue a task to run resouce selection algorithm. + element.play().then( + (result) => { + ok(false, `${token} is resolved with ${result}.`); + }, + (error) => { + if (error.name == "AbortError") { + ok(true, `${token} is rejected with ${error.name}.`); + } else { + ok(false, `${token} is rejected with ${error.name}.`); + } + } + ).then( () => { manager.finished(token); } ); + + ok(element.networkState == HTMLMediaElement.NETWORK_NO_SOURCE); + + // Invoke load() again and since the networkState is NETWORK_NO_SOURCE, the load() rejects the pending promise. + element.src = test.name; + + // Since the networkState is not NETWORK_EMPTY, the load() sets paused to be true. + ok(element.paused, `loadAlgorithmRejectPromisesWhenPausing(${token}).paused should be true.`); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_16.html b/dom/media/test/test_play_promise_16.html new file mode 100644 index 0000000000..a643e7fff8 --- /dev/null +++ b/dom/media/test/test_play_promise_16.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: loadAlgorithmResolveOrdering +// Case: invoke load() on an element should resolve pending promises in order. +// Expected result: the pending promises are resolved in order. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.preload = "auto"; + element.src = test.name; + once(element, "canplay").then(() => { + let firstPromiseResolved = false; + + // play + element.play().then( + () => { firstPromiseResolved = true; }, + () => { ok(false, `loadAlgorithmResolveOrdering(${token}) should not be rejected.`); } + ); + + // play again + element.play().then( + () => { ok(firstPromiseResolved, `loadAlgorithmResolveOrdering(${token}), the first play should already be resolved.`); }, + () => { ok(false, `loadAlgorithmResolveOrdering(${token}) should not be rejected.`); } + ).then( () => { manager.finished(token); } ); + + // triger load + element.src = test.name; + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_17.html b/dom/media/test/test_play_promise_17.html new file mode 100644 index 0000000000..5e5eb71fd5 --- /dev/null +++ b/dom/media/test/test_play_promise_17.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: loadAlgorithmRejectOrdering +// Case: invoke load() on an element should reject pending promises in order. +// Expected result: the pending promises are rejected in order. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + let firstPromiseRejected = false; + + // play + element.play().then( + () => { ok(false, `loadAlgorithmRejectOrdering(${token}) should not be resolved.`); }, + () => { firstPromiseRejected = true; } + ); + + // play again + element.play().then( + () => { ok(false, `loadAlgorithmRejectOrdering(${token}) should not be resolved.`); }, + () => { ok(firstPromiseRejected, `loadAlgorithmRejectOrdering(${token}), the first play should already be rejected.`); } + ).then( () => { manager.finished(token); } ); + + // triger load + element.src = test.name; +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_18.html b/dom/media/test/test_play_promise_18.html new file mode 100644 index 0000000000..e0c0837fdf --- /dev/null +++ b/dom/media/test/test_play_promise_18.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: 'playing' event should come before promise resolving +// Case: invoke play() on an element which has valis source +// Expected result: receive a 'playing' event before the promise is resolved + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.src = test.name; + element.receivedPlayingEvent = false; + + element.addEventListener("playing", () => { + element.receivedPlayingEvent = true; + }); + + element.play().then( + (result) => { + if (result == undefined && element.receivedPlayingEvent) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result} and receivedPlayingEvent = ${element.receivedPlayingEvent}`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_2.html b/dom/media/test/test_play_promise_2.html new file mode 100644 index 0000000000..c4befdbe91 --- /dev/null +++ b/dom/media/test/test_play_promise_2.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playWhenCanPlay +// Case: invoke play() on an element that has enough data +// Expected result: resolve the promise + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.preload = "auto"; + element.src = test.name; + once(element, "canplay").then(() => { + element.play().then( + (result) => { + if (result == undefined) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result}.`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_3.html b/dom/media/test/test_play_promise_3.html new file mode 100644 index 0000000000..8ffacdae03 --- /dev/null +++ b/dom/media/test/test_play_promise_3.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playAfterPlaybackStarted +// Case: invoke play() on an element that is already playing +// Expected result: resolve the promise + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.preload = "auto"; + element.src = test.name; + once(element, "playing").then(() => { + ok(element.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA, `playAfterPlaybackStarted(${token})`); + ok(!element.paused, `playAfterPlaybackStarted(${token})`); + element.play().then( + (result) => { + if (result == undefined) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result}.`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); + }); + + element.play(); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_4.html b/dom/media/test/test_play_promise_4.html new file mode 100644 index 0000000000..dfcd96e0b9 --- /dev/null +++ b/dom/media/test/test_play_promise_4.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="play_promise.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playNotSupportedContent +// Case: invoke play() on an element with an unsupported content +// Expected result: reject the promise with NotSupportedError DOM exception + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.src = getNotSupportedFile(test.name); + element.play().then( + (result) => { + ok(false, `${token} is resolved with ${result}.`); + }, + (error) => { + if (error.name == "NotSupportedError") { + ok(true, `${token} is rejected with ${error.name}.`); + } else { + ok(false, `${token} is rejected with ${error.name}.`); + } + } + ).then( () => { manager.finished(token); } ); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_5.html b/dom/media/test/test_play_promise_5.html new file mode 100644 index 0000000000..a4c3eeb936 --- /dev/null +++ b/dom/media/test/test_play_promise_5.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="play_promise.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playWithErrorAlreadySet +// Case: invoke play() on an element with MEDIA_ERR_SRC_NOT_SUPPORTED has been set +// Expected result: reject the promise with NotSupportedError DOM exception + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.src = getNotSupportedFile(test.name); + once(element, "error").then(() => { + ok(element.error.code == MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); + element.play().then( + (result) => { + ok(false, `${token} is resolved with ${result}.`); + }, + (error) => { + if (error.name == "NotSupportedError") { + ok(true, `${token} is rejected with ${error.name}.`); + } else { + ok(false, `${token} is rejected with ${error.name}.`); + } + } + ).then( () => { manager.finished(token); } ); + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_6.html b/dom/media/test/test_play_promise_6.html new file mode 100644 index 0000000000..dcbea3f108 --- /dev/null +++ b/dom/media/test/test_play_promise_6.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="play_promise.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playSwitchToValidSrcAfterError +// Case: invoke play() on an element which had its source changed (to a valid source) after suffering from an error +// Expected result: resolve the promise with undefined + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.src = getNotSupportedFile(test.name); + once(element, "error").then(() => { + ok(element.error.code == MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); + element.src = test.name; + element.play().then( + (result) => { + if (result == undefined) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result}.`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_7.html b/dom/media/test/test_play_promise_7.html new file mode 100644 index 0000000000..1abbe42f33 --- /dev/null +++ b/dom/media/test/test_play_promise_7.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="play_promise.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playSwitchToInvalidSrcAfterError +// Case: invoke play() on an element which had its source changed (to a invalid source) after suffering from an error +// Expected result: reject the promise with NotSupportedError DOM exception + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.src = getNotSupportedFile(test.name); + once(element, "error").then(() => { + ok(element.error.code == MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); + element.src = getNotSupportedFile(test.name); + ok(element.error == null); + ok(element.readyState == HTMLMediaElement.HAVE_NOTHING); + element.play().then( + (result) => { + ok(false, `${token} is resolved with ${result}.`); + }, + (error) => { + if (error.name == "NotSupportedError") { + ok(true, `${token} is rejected with ${error.name}.`); + } else { + ok(false, `${token} is rejected with ${error.name}.`); + } + } + ).then( () => { manager.finished(token); } ); + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_8.html b/dom/media/test/test_play_promise_8.html new file mode 100644 index 0000000000..d61e12c9fe --- /dev/null +++ b/dom/media/test/test_play_promise_8.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playAndPauseWhenCanplay +// Case: invlke play() and then pause() on an element that already has enough data to play +// Expected result: resolve the promise +// Note: the pause() doesn't cancel the play() because it was alredy been queued to be resolved. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.preload = "auto"; + element.src = test.name; + once(element, "canplay").then(() => { + element.play().then( + (result) => { + if (result == undefined) { + ok(true, `${token} is resolved with ${result}.`); + } else { + ok(false, `${token} is resolved with ${result}.`); + } + }, + (error) => { + ok(false, `${token} is rejected with ${error.name}.`); + } + ).then( () => { manager.finished(token); } ); + ok(!element.paused, `playAndPauseWhenCanplay(${token}) element should not be paused.`); + element.pause(); + ok(element.paused, `playAndPauseWhenCanplay(${token}) element should be paused.`); + }); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_promise_9.html b/dom/media/test/test_play_promise_9.html new file mode 100644 index 0000000000..c3a3856515 --- /dev/null +++ b/dom/media/test/test_play_promise_9.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: promise-based play() method</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +// Name: playAndPauseBeforeCanPlay +// Case: invlke play() and then pause() on an element that deoen't have enough data to play. +// Expected result: reject the promise with AbortError DOM exception. +// Note: the pause() cancels the play() because the promise is still pending. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + let element = document.createElement(getMajorMimeType(test.type)); + ok(element.readyState == HTMLMediaElement.HAVE_NOTHING); + element.play().then( + (result) => { + ok(false, `${token} is resolved with ${result}.`); + }, + (error) => { + if (error.name == "AbortError") { + ok(true, `${token} is rejected with ${error.name}.`); + } else { + ok(false, `${token} is rejected with ${error.name}.`); + } + } + ).then( () => { manager.finished(token); } ); + ok(!element.paused, `playAndPauseBeforeCanPlay(${token}) element should not be paused.`); + element.pause(); + ok(element.paused, `playAndPauseBeforeCanPlay(${token}) element should be paused.`); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_play_twice.html b/dom/media/test/test_play_twice.html new file mode 100644 index 0000000000..e94f28a031 --- /dev/null +++ b/dom/media/test/test_play_twice.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test playback of media files that should play OK</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var video = document.createElement('video'); + video.token = token; + manager.started(token); + video.src = test.name; + video.name = test.name; + video.playingCount = 0; + video._playedOnce = false; + + var check = function(t, v) { return function() { + checkMetadata(t.name, v, test); + }}(test, video); + + var noLoad = function(t, v) { return function() { + ok(false, t.name + " should not fire 'load' event"); + }}(test, video); + + function finish(v) { + removeNodeAndSource(v); + manager.finished(v.token); + } + + function mayFinish(v) { + if (v.seenEnded && v.seenSuspend) { + finish(v); + } + } + + var checkEnded = function(t, v) { return function() { + if (t.duration) { + ok(Math.abs(v.currentTime - t.duration) < 0.1, + t.name + " current time at end: " + v.currentTime); + } + + is(v.readyState, v.HAVE_CURRENT_DATA, t.name + " checking readyState"); + ok(v.ended, t.name + " checking playback has ended"); + ok(v.playingCount > 0, "Expect at least one playing event"); + v.playingCount = 0; + + if (v._playedOnce) { + v.seenEnded = true; + mayFinish(v); + } else { + v._playedOnce = true; + v.play(); + } + }}(test, video); + + var checkSuspended = function(t, v) { return function() { + if (v.seenSuspend) { + return; + } + + v.seenSuspend = true; + ok(true, t.name + " got suspend"); + mayFinish(v); + }}(test, video); + + var checkPlaying = function(t, v) { return function() { + is(t.name, v.name, "Should be testing file we think we're testing..."); + v.playingCount++; + }}(test, video); + + video.addEventListener("load", noLoad); + video.addEventListener("loadedmetadata", check); + video.addEventListener("playing", checkPlaying); + + // We should get "ended" and "suspend" events for every resource + video.addEventListener("ended", checkEnded); + video.addEventListener("suspend", checkSuspended); + + document.body.appendChild(video); + video.play(); +} + +manager.runTests(gReplayTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_playback.html b/dom/media/test/test_playback.html new file mode 100644 index 0000000000..5e28861e93 --- /dev/null +++ b/dom/media/test/test_playback.html @@ -0,0 +1,108 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test playback of media files that should play OK</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var video = document.createElement('video'); + video.preload = "metadata"; + video.token = token; + video.prevTime = 0; + video.seenEnded = false; + video.seenSuspend = false; + + var handler = { + "ontimeout": function() { + Log(token, "timed out: ended=" + video.seenEnded + ", suspend=" + video.seenSuspend); + } + }; + manager.started(token, handler); + + video.src = test.name; + video.name = test.name; + + var check = function(t, v) { return function() { + is(t.name, v.name, t.name + ": Name should match #1"); + checkMetadata(t.name, v, t); + }}(test, video); + + var noLoad = function(t, v) { return function() { + ok(false, t.name + " should not fire 'load' event"); + }}(test, video); + + var noError = function(t, v) { return function() { + ok(false, t.name + " should not fire 'error' event " + v.error.message); + }}(test, video); + + var finish = function() { + video.finished = true; + video.removeEventListener("timeupdate", timeUpdate); + removeNodeAndSource(video); + manager.finished(video.token); + } + + // We should get "ended" and "suspend" events to finish the test. + var mayFinish = function() { + if (video.seenEnded && video.seenSuspend) { + finish(); + } + } + + var checkEnded = function(t, v) { return function() { + is(t.name, v.name, t.name + ": Name should match #2"); + checkMetadata(t.name, v, test); + is(v.readyState, v.HAVE_CURRENT_DATA, t.name + " checking readyState"); + ok(v.ended, t.name + " checking playback has ended"); + ok(!v.finished, t.name + " shouldn't be finished"); + ok(!v.seenEnded, t.name + " shouldn't be ended"); + + v.seenEnded = true; + mayFinish(); + }}(test, video); + + var checkSuspended = function(t, v) { return function() { + if (v.seenSuspend) { + return; + } + is(t.name, v.name, t.name + ": Name should match #3"); + + v.seenSuspend = true; + mayFinish(); + }}(test, video); + + var timeUpdate = function(t, v) { return function() { + if (v.prevTime > v.currentTime) { + ok(false, t.name + " time should run forwards: p=" + + v.prevTime + " c=" + v.currentTime); + } + v.prevTime = v.currentTime; + }}(test, video); + + video.addEventListener("load", noLoad); + video.addEventListener("error", noError); + video.addEventListener("loadedmetadata", check); + video.addEventListener("timeupdate", timeUpdate); + + // We should get "ended" and "suspend" events for every resource + video.addEventListener("ended", checkEnded); + video.addEventListener("suspend", checkSuspended); + + document.body.appendChild(video); + video.play(); +} + +manager.runTests(gPlayTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_playback_and_bfcache.html b/dom/media/test/test_playback_and_bfcache.html new file mode 100644 index 0000000000..3b1236c530 --- /dev/null +++ b/dom/media/test/test_playback_and_bfcache.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test media playback and bfcache</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.requestFlakyTimeout("Need some timer to wait for the audio to play"); + SimpleTest.waitForExplicitFinish(); + var duration = 0; + + // The test opens a page and another page with a media element is loaded. + // The media element plays an audio file and starts again and sends + // statistics about it and then history.back() is called. The test waits + // for 1s + duration of the audio file and goes forward. The audio playback + // shouldn't have progressed while the page was in the bfcache. + function test() { + let bc1 = new BroadcastChannel("bc1"); + let pageshow1Count = 0; + bc1.onmessage = function(e) { + if (e.data == "pageshow") { + ++pageshow1Count; + info("Page 1 pageshow " + pageshow1Count); + if (pageshow1Count == 1) { + bc1.postMessage("loadNext"); + } else if (pageshow1Count == 2) { + setTimeout(function() { + bc1.postMessage("forward"); + bc1.close(); + }, (Math.round(duration) + 1) * 1000); + } + } + }; + + let bc2 = new BroadcastChannel("bc2"); + let pageshow2Count = 0; + let statisticsCount = 0; + bc2.onmessage = function(e) { + if (e.data.event == "pageshow") { + ++pageshow2Count; + info("Page 2 pageshow " + pageshow2Count); + if (pageshow2Count == 2) { + ok(e.data.persisted, "Should have persisted the page."); + bc2.postMessage("statistics"); + } + } else { + ++statisticsCount; + if (statisticsCount == 1) { + duration = e.data.duration; + bc2.postMessage("back"); + } else { + is(statisticsCount, 2, "Should got two play events."); + ok(e.data.currentTime < e.data.duration, + "Should have stopped the playback while the page was in bfcache." + + "currentTime: " + e.data.currentTime + " duration: " + e.data.duration); + bc2.close(); + SimpleTest.finish(); + } + } + }; + + window.open("file_playback_and_bfcache.html", "", "noopener"); + } + </script> +</head> +<body onload="test()"> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/dom/media/test/test_playback_errors.html b/dom/media/test/test_playback_errors.html new file mode 100644 index 0000000000..7b3f046099 --- /dev/null +++ b/dom/media/test/test_playback_errors.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test playback of media files that should have errors</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var video = document.createElement('video'); + manager.started(token); + video._errorCount = 0; + video._ignore = false; + function endedTest(v) { + if (v._ignore) + return; + v._ignore = true; + v.remove(); + manager.finished(token); + } + var checkError = function(t, v) { return function(evt) { + v._errorCount++; + is(v._errorCount, 1, t.name + " only one error fired"); + endedTest(v); + }}(test, video); + var checkEnded = function(t, v) { return function() { + ok(false, t.name + " successfully played"); + endedTest(v); + }}(test, video); + video.addEventListener("error", checkError); + video.addEventListener("ended", checkEnded); + video.src = test.name; + document.body.appendChild(video); + video.play(); +} + +manager.runTests(gErrorTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_playback_hls.html b/dom/media/test/test_playback_hls.html new file mode 100644 index 0000000000..7d5c777fc1 --- /dev/null +++ b/dom/media/test/test_playback_hls.html @@ -0,0 +1,91 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test playback of HLS with simple m3u8 that should play OK</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var video = document.createElement('video'); + video.preload = "metadata"; + video.token = token; + video.prevTime = 0; + video.seenEnded = false; + + var handler = { + "ontimeout": function() { + Log(token, "timed out: ended=" + video.seenEnded); + } + }; + manager.started(token, handler); + + video.src = test.name; + video.name = test.name; + + var check = function(t, v) { return function() { + is(t.name, v.name, t.name + ": Name should match #1"); + checkMetadata(t.name, v, t); + }}(test, video); + + var noLoad = function(t, v) { return function() { + ok(false, t.name + " should not fire 'load' event"); + }}(test, video); + + var finish = function() { + video.finished = true; + video.removeEventListener("timeupdate", timeUpdate); + removeNodeAndSource(video); + manager.finished(video.token); + } + + // We should get "ended" events to finish the test. + var mayFinish = function() { + if (video.seenEnded) { + finish(); + } + } + + var checkEnded = function(t, v) { return function() { + is(t.name, v.name, t.name + ": Name should match #2"); + checkMetadata(t.name, v, test); + is(v.readyState, v.HAVE_CURRENT_DATA, t.name + " checking readyState"); + ok(v.ended, t.name + " checking playback has ended"); + ok(!v.finished, t.name + " shouldn't be finished"); + ok(!v.seenEnded, t.name + " shouldn't be ended"); + + v.seenEnded = true; + mayFinish(); + }}(test, video); + + var timeUpdate = function(t, v) { return function() { + if (v.prevTime > v.currentTime) { + ok(false, t.name + " time should run forwards: p=" + + v.prevTime + " c=" + v.currentTime); + } + v.prevTime = v.currentTime; + }}(test, video); + + video.addEventListener("load", noLoad); + video.addEventListener("loadedmetadata", check); + video.addEventListener("timeupdate", timeUpdate); + + // We should get "ended" events for the hls resource + video.addEventListener("ended", checkEnded); + + document.body.appendChild(video); + video.play(); +} + +manager.runTests(gHLSTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_playback_rate.html b/dom/media/test/test_playback_rate.html new file mode 100644 index 0000000000..b44ebe27ee --- /dev/null +++ b/dom/media/test/test_playback_rate.html @@ -0,0 +1,175 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for the playbackRate property </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type='application/javascript'> + +let manager = new MediaTestManager; + +function rangeCheck(lhs, rhs, threshold) { + var diff = Math.abs(lhs - rhs); + if (diff < threshold) { + return true; + } + return false; +} + +function checkPlaybackRate(wallclock, media, expected, threshold) { + if (rangeCheck(media / wallclock, expected, threshold)) { + return true; + } + return false; +} + +// Those value are expected to match those at the top of HTMLMediaElement.cpp. +let VERY_SLOW_RATE = 1 / 32, + SLOW_RATE = 1 / 16, + FAST_RATE = 16, + VERY_FAST_RATE = 20, + NULL_RATE = 0.0; + +function ontimeupdate(e) { + var t = e.target; + // Skip short files for SoundTouch doesn't work well on small number of samples. + if (t.gotEnded || t.duration < 2) { + return; + } + t.testedForSlowdown = true; + if (t.currentTime > t.duration / 2) { + t.oldCurrentTime = t.currentTime; + t.timestamp = Date.now(); + var delta = t.oldCurrentTime, + delta_wallclock = (t.timestamp - t.startTimestamp - t.bufferingTime) / 1000; + + t.preservesPitch = false; + is(t.preservesPitch, false, t.name + ": If we disable the pitch preservation, it should appear as such."); + + t.bufferingTime = 0; + + is(t.playbackRate, SLOW_RATE, t.name + ": The playback rate shoud be "+SLOW_RATE+"."); + ok(checkPlaybackRate(delta_wallclock, delta, SLOW_RATE, 0.25), t.name + ": We are effectively slowing down playback. (" + delta_wallclock + ", " + delta + ")"); + t.removeEventListener("timeupdate", ontimeupdate); + t.addEventListener("pause", onpaused); + t.playbackRate = NULL_RATE; + t.oldCurrentTime = t.currentTime; + setTimeout(function() { + afterNullPlaybackRate(e); + }, 100); + } +} + +function onpaused(e) { + var t = e.target; + t.pausedReceived = true; +} + +function afterNullPlaybackRate(e) { + var t = e.target; + + // skip if we have received 'ended' event or 'ended' event is pending. + if (t.gotEnded || t.ended) { + return; + } + + t.testedForNull = true; + + ok(t.currentTime == t.oldCurrentTime, t.name + ": Current time should not change when playbackRate is null (" + t.currentTime + " " + t.oldCurrentTime + ")."); + ok(!t.paused, t.name + ": The element should not be in paused state."); + t.removeEventListener("paused", onpaused); + is(t.pausedReceived, undefined, t.name + ": Paused event should not have been received."); + t.timestamp = Date.now(); + t.oldCurrentTime = t.currentTime; + t.playbackRate = VERY_FAST_RATE; + is(t.playbackRate, VERY_FAST_RATE, t.name + ": Playback rate should be clamped to " + VERY_FAST_RATE + "."); +} + +function onended(e) { + var t = e.target; + t.gotEnded = true; + + t.bufferingTime = 0; + // If we got "ended" too early, skip these tests. + if (t.testedForSlowdown && t.testedForNull) { + is(t.playbackRate, FAST_RATE, t.name + ": The playback rate should still be "+FAST_RATE+"."); + ok(!t.muted, t.name + ": The audio should be muted when playing at high speed, but should not appear as such."); + is(t.currentTime, t.duration, t.name + ": Current time should be equal to the duration (not change by playback rate)."); + } + finish_test(t); +} + +function onratechange(e) { + if (!e.target.ratechangecount) { + e.target.ratechangecount = 0; + } + e.target.ratechangecount++; +} + +function finish_test(element) { + removeNodeAndSource(element); + manager.finished(element.token); +} + +// These two functions handle the case when the playback pauses for buffering. It +// adjusts the timestamps to be accurate. Despite the fact that the web servers +// is supposed to be on the same machine, buffering pauses can occur (rarely, +// but still). +function onplaying(e) { + var t = e.target; + if (t.bufferingTimestamp != undefined) { + t.bufferingTime += (Date.now() - t.bufferingTimestamp); + t.bufferingTimestamp = undefined; + } +} + +function onwaiting(e) { + var t = e.target; + t.bufferingTimestamp = Date.now(); +} + +function onvolumechange(e) { + ok(false, e.target.name + ": We should not receive a volumechange event when changing the playback rate."); +} + +function startTest(test, token) { + let elemType = /^audio/.test(test.type) ? "audio" : "video"; + let element = document.createElement(elemType); + element.src = test.name; + element.name = test.name; + element.preload = "metadata"; + element.token = token; + element.controls = true; + element.bufferingTime = 0; + document.body.appendChild(element); + element.addEventListener("ratechange", onratechange); + element.addEventListener("timeupdate", ontimeupdate); + element.addEventListener("ended", onended); + element.addEventListener("waiting", onwaiting); + element.addEventListener("playing", onplaying); + element.addEventListener("volumechange", onvolumechange); + manager.started(token); + element.startTimestamp = Date.now(); + is(element.preservesPitch, true, test.name + ": Pitch preservation should be enabled by default."); + element.addEventListener("loadedmetadata", function() { + is(element.playbackRate, 1.0, test.name + ": playbackRate should be initially 1.0"); + is(element.defaultPlaybackRate, 1.0, test.name + ": defaultPlaybackRate should be initially 1.0"); + element.playbackRate = VERY_SLOW_RATE; + is(element.playbackRate, VERY_SLOW_RATE, test.name + ": PlaybackRate should be " + VERY_SLOW_RATE + "."); + element.play(); + element.playbackRate = SLOW_RATE; + }); +} + +manager.runTests(gPlayedTests, startTest); + +</script> +</pre> +<div id="elements"> +</div> +</body> +</html> diff --git a/dom/media/test/test_playback_rate_playpause.html b/dom/media/test/test_playback_rate_playpause.html new file mode 100644 index 0000000000..fb57e50942 --- /dev/null +++ b/dom/media/test/test_playback_rate_playpause.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that the playbackRate property is not reset when resuming the playback</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type='application/javascript'> + +let manager = new MediaTestManager; + +function ontimeupdate(e) { + var t = e.target; + if (t.currentTime != 0.0) { + info(t.token + " t.currentTime=" + t.currentTime +"\n"); + t.removeEventListener("timeupdate", ontimeupdate); + t.pause(); + is(t.playbackRate, 0.5, "PlaybackRate should not have changed after pause."); + } else { + info(t.token + " t.currentTime == 0.0.\n"); + } +} + +function onpaused(e) { + var t = e.target; + dump(t.token + " onpaused.\n"); + t.play(); + is(t.playbackRate, 0.5, "PlaybackRate should not have changed after resuming playback."); + finish_test(t); +} + +function finish_test(element) { + dump(element.token + " finish_test.\n"); + removeNodeAndSource(element); + manager.finished(element.token); +} + +function startTest(test, token) { + let elemType = /^audio/.test(test.type) ? "audio" : "video"; + let element = document.createElement(elemType); + element.src = test.name; + element.token = token; + element.controls = true; + element.playbackRate = 0.5; + element.preload = "metadata"; + element.addEventListener("timeupdate", ontimeupdate); + element.addEventListener("pause", onpaused); + element.addEventListener("loadedmetadata", function() { + dump(element.token + " loadedmetadata\n"); + element.play(); + }); + document.body.appendChild(element); + manager.started(token); +} + +manager.runTests(gPlayedTests, startTest); + +</script> +</pre> +<div id="elements"> +</div> +</body> +</html> diff --git a/dom/media/test/test_playback_reactivate.html b/dom/media/test/test_playback_reactivate.html new file mode 100644 index 0000000000..dec5330ce5 --- /dev/null +++ b/dom/media/test/test_playback_reactivate.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test playback with dormant of media files that should play OK</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/* This testcase wants to test a video element's playback is not break + by dormant. + When the metadata is loaded, we remove the video element to trigger dormant. + Then set a timer to append the video element back and play it. + Test pass if the video plays to the end. +*/ + +var manager = new MediaTestManager; + +function startTest(test, token) { + var video = document.createElement('video'); + video.preload = "metadata"; + video.token = token; + + var handler = { + "ontimeout": function() { + Log(token, "timed out: ended=" + video.seenEnded + ", suspend=" + video.seenSuspend); + } + }; + manager.started(token, handler); + + video.src = test.name; + video.name = test.name; + + var check = function(t, v) { return function() { + is(t.name, v.name, t.name + ": Name should match #1"); + Log(v.token, "removeChild: " + v.name); + document.body.removeChild(v); + var appendAndPlayElement = function() { + Log(v.token, "appendChild: " + v.name); + document.body.appendChild(v); + Log(v.token, "Element play: " + v.name); + v.play(); + } + setTimeout(appendAndPlayElement, 2000); + }}(test, video); + + var finish = function() { + video.finished = true; + removeNodeAndSource(video); + manager.finished(video.token); + } + + var checkEnded = function(t, v) { return function() { + is(t.name, v.name, t.name + ": Name should match #2"); + checkMetadata(t.name, v, t); + is(v.readyState, v.HAVE_CURRENT_DATA, t.name + " checking readyState"); + ok(v.ended, t.name + " checking playback has ended"); + + finish(); + }}(test, video); + + + video.addEventListener("loadedmetadata", check); + video.addEventListener("ended", checkEnded); + + document.body.appendChild(video); +} + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_played.html b/dom/media/test/test_played.html new file mode 100644 index 0000000000..f6c05f7070 --- /dev/null +++ b/dom/media/test/test_played.html @@ -0,0 +1,288 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test played member for media elements</title> +<script type="text/javascript" src="/MochiKit/MochiKit.js"></script> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +<script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id='test'> +<script class="testbody" type='application/javascript'> + +let manager = new MediaTestManager; + +function finish_test(element) { + removeNodeAndSource(element); + manager.finished(element.token); +} + +// Check that a file has been played in its entirety. +function check_full_file_played(element) { + element.addEventListener('ended', (function(e) { + let interval_count = e.target.played.length; + is(interval_count, 1, element.token + ": played.length must be 1"); + is(element.played.start(0), 0, element.token + ": start time shall be 0"); + is(element.played.end(0), e.target.duration, element.token + ": end time shall be duration"); + finish_test(e.target); + })); +} + +var tests = [ +// Without playing, check that player.played.length == 0. +{ + setup(element) { + element.addEventListener("loadedmetadata", function() { + is(element.played.length, 0, element.token + ": initial played.length equals zero"); + finish_test(element); + }); + }, + name: "test1" +}, +// Play the file, test the range we have. +{ + setup(element) { + check_full_file_played(element); + element.play(); + }, + name: "test2" +}, + +// Play the second half of the file, pause, play +// an check we have only one range. +{ + setup (element) { + element.onended = function (e) { + var t = e.target; + t.onended = null; + check_full_file_played(t); + t.pause(); + t.currentTime = 0; + t.play(); + }; + element.addEventListener("loadedmetadata", function() { + element.currentTime = element.duration / 2; + element.play(); + }); + }, + name: "test3" +}, + +// Play the first half of the file, seek back, while +// continuing to play. We shall have only one range. +{ + setup (element) { + let onTimeUpdate = function() { + if (element.currentTime > element.duration / 2) { + info(element.token + ": currentTime=" + element.currentTime + ", duration=" + element.duration); + element.removeEventListener("timeupdate", onTimeUpdate); + element.pause(); + var oldEndRange = element.played.end(0); + element.currentTime = element.duration / 4; + is(element.played.end(0), oldEndRange, + element.token + ": When seeking back, |played| should not be changed"); + element.play(); + } + } + element.addEventListener("timeupdate", onTimeUpdate); + check_full_file_played(element); + element.play(); + }, + name: "test4" +}, + +// Play and seek to have two ranges, and check that, as well a +// boundaries. +{ + setup (element) { + let seekTarget = 0; + let onTimeUpdate = function() { + if (element.currentTime > element.duration / 2) { + info(element.token + ": currentTime=" + element.currentTime + ", duration=" + element.duration); + element.removeEventListener("timeupdate", onTimeUpdate); + element.pause(); + // Remember seek target for later comparison since duration may change + // during playback. + seekTarget = element.currentTime = element.duration / 10; + element.currentTime = seekTarget; + element.play(); + } + } + + element.addEventListener("loadedmetadata", function() { + element.addEventListener("timeupdate", onTimeUpdate); + }); + + + element.addEventListener("ended", (function() { + if(element.played.length > 1) { + is(element.played.length, 2, element.token + ": element.played.length == 2"); + is(element.played.start(1), seekTarget, element.token + ": we should have seeked forward by one tenth of the duration"); + is(element.played.end(1), element.duration, element.token + ": end of second range shall be the total duration"); + } + is(element.played.start(0), 0, element.token + ": start of first range shall be 0"); + finish_test(element); + })); + + element.play(); + }, + name: "test5" +}, + +// Play to create two ranges, in the reverse order. check that they are sorted. +{ + setup (element) { + function end() { + element.pause(); + let p = element.played; + ok(p.length >= 1, element.token + ": There should be at least one range=" + p.length); + is(p.start(0), seekTarget, element.token + ": Start of first range should be the sixth of the duration"); + ok(p.end(p.length - 1) > 5 * element.duration / 6, element.token + ": End of last range should be greater that five times the sixth of the duration"); + finish_test(element); + } + + let seekTarget = 0; + function pauseseekrestart() { + element.pause(); + // Remember seek target for later comparison since duration may change + // during playback. + seekTarget = element.duration / 6; + element.currentTime = seekTarget; + element.play(); + } + + function onTimeUpdate_pauseseekrestart() { + if (element.currentTime > 5 * element.duration / 6) { + element.removeEventListener("timeupdate", onTimeUpdate_pauseseekrestart); + pauseseekrestart(); + element.addEventListener("timeupdate", onTimeUpdate_end); + } + } + + function onTimeUpdate_end() { + if (element.currentTime > 3 * element.duration / 6) { + element.removeEventListener("timeupdate", onTimeUpdate_end); + end(); + } + } + + element.addEventListener("timeupdate", onTimeUpdate_pauseseekrestart); + + element.addEventListener('loadedmetadata', function() { + element.currentTime = 4 * element.duration / 6; + element.play(); + }); + }, + name: "test6" +}, +// Seek repeatedly without playing. No range should appear. +{ + setup(element) { + let index = 1; + + element.addEventListener('seeked', function() { + index++; + element.currentTime = index * element.duration / 5; + is(element.played.length, 0, element.token + ": played.length should be 0"); + if (index == 5) { + finish_test(element); + } + }); + + element.addEventListener('loadedmetadata', function() { + element.currentTime = element.duration / 5; + }); + }, + name: "test7" +}, +// Play for a bit, then seek to the end: two ranges when "ended" is received. +// Load another resource (invalid): no range +// Load another resource (valid): still no range +{ + setup(element) { + let index = 1; + let seeked = false; + + element.addEventListener('timeupdate', function() { + index++; + if (index == 2) { + is(element.played.length, 1); + element.currentTime = element.currentTime + element.duration / 100; + } + if (seeked) { + is(element.played.length, 2, "After seeking, played.length should be 2"); + } + }); + element.addEventListener('seeked', function() { + seeked = true; + }); + element.addEventListener('ended', function() { + // For very short media file, timing is unreliable, it can be that the + // file has finished playing, before the seek, and so there is only one + // range in `played`. + if (seeked) { + is(element.played.length, 2, element.token + "After ended, played.length should be 2"); + } else { + is(element.played.length, 1, element.token + "After ended, a short media file played.length should be 1 if it has ended before the seek"); + } + let src_bck = element.src; + element.src = "bogus.duh"; + is(element.played.length, 0, "After subsequent invalid load, played.length should be 0"); + element.src = src_bck; + is(element.played.length, 0, "After subsequent valid load, played.length should be 0"); + finish_test(element); + }); + element.addEventListener('loadedmetadata', function() { + element.play(); + }); + }, + name: "test8" +} +]; + +function createTestArray() { + var A = []; + for (var i=0; i<tests.length; i++) { + for (var k=0; k<gPlayedTests.length; k++) { + var t = {}; + t.setup = tests[i].setup; + t.name = tests[i].name + "-" + gPlayedTests[k].name; + t.type = gPlayedTests[k].type; + t.src = gPlayedTests[k].name; + A.push(t); + } + } + return A; +} + +function startTest(test, token) { + var elemType = getMajorMimeType(test.type); + var element = document.createElement(elemType); + element.src = test.src; + element.token = token; + element.preload = "metadata"; + test.setup(element); + manager.started(token); + + // Log events for debugging. + var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", + "waiting", "pause"]; + function logEvent(e) { + var v = e.target; + info(v.token + ": got " + e.type); + } + events.forEach(function(e) { + element.addEventListener(e, logEvent); + }); + +} + + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_preload_actions.html b/dom/media/test/test_preload_actions.html new file mode 100644 index 0000000000..d027147c71 --- /dev/null +++ b/dom/media/test/test_preload_actions.html @@ -0,0 +1,581 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=548523 +--> +<head> + <title>Test for Bug 548523</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=548523">Mozilla Bug 548523</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<!-- <button onClick="SimpleTest.finish();">Finish</button> --> +<div>Tests complete: <span id="log" style="font-size: small;"></span></div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 548523 **/ + +SimpleTest.requestCompleteLog(); +var manager = new MediaTestManager; + +manager.onFinished = function() { + is(gotLoadEvent, true, "Should not have delayed the load event indefinitely"); +}; + +var test = getPlayableVideo(gSeekTests); +var baseName = test.name; +var gTest = test; +var bogusSrc = "bogus.duh"; +var bogusType = "video/bogus"; +var gotLoadEvent = false; +var finished = false; + +addLoadEvent(function() {gotLoadEvent=true;}); + +function log(m) { + var l = document.getElementById("log"); + l.innerHTML += m; +} + +function maybeFinish(v, n) { + if (v._finished) { + return; + } + v._finished = true; + log(n + ","); + removeNodeAndSource(v); + manager.finished(v.token); +} + +function filename(uri) { + return uri.substr(uri.lastIndexOf("/")+1); +} + +// Every test must have a setup(v) function, and must call maybeFinish() when test is complete. +var tests = [ + { + // 1. Add preload:none video with src to document. Load should halt at NETWORK_IDLE and HAVE_NOTHING, + // after receiving a suspend event. Should not receive loaded events until after we call load(). + // Note the suspend event is explictly sent by our "stop the load" code, but other tests can't rely + // on it for the preload:metadata case, as there can be multiple suspend events when loading metadata. + suspend(e) { + var v = e.target; + is(v._gotLoadStart, true, "(1) Must get loadstart."); + is(v._gotLoadedMetaData, false, "(1) Must not get loadedmetadata."); + is(v.readyState, v.HAVE_NOTHING, "(1) ReadyState must be HAVE_NOTHING"); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(1) NetworkState must be NETWORK_IDLE"); + maybeFinish(v, 1); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "none"; + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("suspend", this.suspend); + v.src = test.name; + document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none. + }, + + name: "test1", + }, + { + // 2. Add preload:metadata video with src to document. Should halt with NETWORK_IDLE, HAVE_CURRENT_DATA + // after suspend event and after loadedmetadata. + loadeddata(e) { + var v = e.target; + is(v._gotLoadStart, true, "(2) Must get loadstart."); + is(v._gotLoadedMetaData, true, "(2) Must get loadedmetadata."); + ok(v.readyState >= v.HAVE_CURRENT_DATA, "(2) ReadyState must be >= HAVE_CURRENT_DATA"); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(2) NetworkState must be NETWORK_IDLE"); + maybeFinish(v, 2); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "metadata"; + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadeddata", this.loadeddata); + v.src = test.name; + document.body.appendChild(v); // Causes implicit load, which will be halted after + // metadata due to preload:metadata. + }, + + name: "test2", + }, + { + // 3. Add preload:auto to document. Should receive canplaythrough eventually. + canplaythrough(e) { + var v = e.target; + is(v._gotLoadStart, true, "(3) Must get loadstart."); + is(v._gotLoadedMetaData, true, "(3) Must get loadedmetadata."); + maybeFinish(v, 3); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "auto"; + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("canplaythrough", this.canplaythrough); + v.src = test.name; // Causes implicit load. + document.body.appendChild(v); + }, + + name: "test3", + }, + { + // 4. Add preload:none video to document. Call play(), should load then play through. + suspend(e) { + var v = e.target; + if (v._gotSuspend) { + return; // We can receive multiple suspend events, like the one after download completes. + } + v._gotSuspend = true; + is(v._gotLoadStart, true, "(4) Must get loadstart."); + is(v._gotLoadedMetaData, false, "(4) Must not get loadedmetadata."); + is(v.readyState, v.HAVE_NOTHING, "(4) ReadyState must be HAVE_NOTHING"); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(4) NetworkState must be NETWORK_IDLE"); + v.play(); // Should load and play through. + }, + + ended(e) { + ok(true, "(4) Got playback ended"); + maybeFinish(e.target, 4); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v._gotSuspend = false; + v.preload = "none"; + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("suspend", this.suspend); + v.addEventListener("ended", this.ended); + v.src = test.name; + document.body.appendChild(v); + }, + + name: "test4", + }, + { + // 5. preload:none video without resource, add to document, will implicitly start a + // preload:none load. Add a src, it shouldn't load. + suspend(e) { + var v = e.target; + is(v._gotLoadStart, true, "(5) Must get loadstart."); + is(v._gotLoadedMetaData, false, "(5) Must not get loadedmetadata."); + is(v.readyState, v.HAVE_NOTHING, "(5) ReadyState must be HAVE_NOTHING"); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(5) NetworkState must be NETWORK_IDLE"); + maybeFinish(v, 5); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "none"; + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("suspend", this.suspend); + document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource. + v.src = test.name; // Load should start, and halt at preload:none. + }, + + name: "test5", + }, + { + // 6. preload:none video without resource, add to document, will implicitly start a + // preload:none load. Add a source, it shouldn't load. + suspend(e) { + var v = e.target; + is(v._gotLoadStart, true, "(6) Must get loadstart."); + is(v._gotLoadedMetaData, false, "(6) Must not get loadedmetadata."); + is(v.readyState, v.HAVE_NOTHING, "(6) ReadyState must be HAVE_NOTHING"); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(6) NetworkState must be NETWORK_IDLE"); + maybeFinish(v, 6); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "none"; + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("suspend", this.suspend); + document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource. + var s = document.createElement("source"); + s.src = test.name; + s.type = test.type; + v.appendChild(s); // Load should start, and halt at preload:none. + }, + + name: "test6", + }, + { + // 7. create a preload:none document with multiple sources, the first of which is invalid. + // Add to document, then play. It should load and play through the second source. + suspend(e) { + var v = e.target; + if (v._gotSuspend) + return; // We can receive multiple suspend events, like the one after download completes. + v._gotSuspend = true; + is(v._gotLoadStart, true, "(7) Must get loadstart."); + is(v._gotLoadedMetaData, false, "(7) Must not get loadedmetadata."); + is(v.readyState, v.HAVE_NOTHING, "(7) ReadyState must be HAVE_NOTHING"); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(7) NetworkState must be NETWORK_IDLE"); + v.play(); // Should load and play through. + }, + + ended(e) { + ok(true, "(7) Got playback ended"); + var v = e.target; + is(v._gotErrorEvent, true, "(7) Should get error event from first source load failure"); + maybeFinish(v, 7); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "none"; + v._gotErrorEvent = false; + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("suspend", this.suspend); + v.addEventListener("ended", this.ended); + var s1 = document.createElement("source"); + s1.src = "not-a-real-file.404" + s1.type = test.type; + s1.addEventListener("error", function(e){v._gotErrorEvent = true;}); + v.appendChild(s1); + var s2 = document.createElement("source"); + s2.src = test.name; + s2.type = test.type; + v.appendChild(s2); + document.body.appendChild(v); // Causes implicit load, which will be halt at preload:none on the second resource. + }, + + name: "test7", + }, + { + // 8. Change preload value from none to metadata should cause metadata to be loaded. + loadeddata(e) { + var v = e.target; + is(v._gotLoadedMetaData, true, "(8) Must get loadedmetadata."); + ok(v.readyState >= v.HAVE_CURRENT_DATA, "(8) ReadyState must be >= HAVE_CURRENT_DATA on suspend."); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(8) NetworkState must be NETWORK_IDLE when load is halted"); + maybeFinish(v, 8); + }, + + setup(v) { + v._gotLoadedMetaData = false; + v.preload = "none"; + v.addEventListener("loadstart", function(e){v.preload = "metadata";}); + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadeddata", this.loadeddata); + v.src = test.name; // Causes implicit load. + document.body.appendChild(v); + }, + + name: "test8", + }, + /*{ + // 9. Change preload value from metadata to auto should cause entire media to be loaded. + // For some reason we don't always receive the canplaythrough event, particuarly on this test. + // We've disabled this test until bug 568402 is fixed. + canplaythrough: + function(e) { + var v = e.target; + is(v._gotLoadStart, true, "(9) Must get loadstart."); + is(v._gotLoadedMetaData, true, "(9) Must get loadedmetadata."); + maybeFinish(v, 9); + }, + + setup: + function(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "metadata"; + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); + v.addEventListener("loadeddata", function(){v.preload = "auto"}, false); + v.addEventListener("canplaythrough", this.canplaythrough, false); + v.src = test.name; // Causes implicit load. + document.body.appendChild(v); + }, + },*/ + { + // 10. Change preload value from none to auto should cause entire media to be loaded. + canplaythrough(e) { + var v = e.target; + is(v._gotLoadedMetaData, true, "(10) Must get loadedmetadata."); + maybeFinish(v, 10); + }, + + setup(v) { + v._gotLoadedMetaData = false; + v.preload = "none"; + v.addEventListener("loadstart", function(e){v.preload = "auto";}); + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("canplaythrough", this.canplaythrough); + v.src = test.name; // Causes implicit load. + document.body.appendChild(v); + }, + + name: "test10", + }, + { + // 11. Change preload value from none to metadata should cause metadata to load. + loadeddata(e) { + var v = e.target; + is(v._gotLoadedMetaData, true, "(11) Must get loadedmetadata."); + ok(v.readyState >= v.HAVE_CURRENT_DATA, "(11) ReadyState must be >= HAVE_CURRENT_DATA."); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(11) NetworkState must be NETWORK_IDLE."); + maybeFinish(v, 11); + }, + + setup(v) { + v._gotLoadedMetaData = false; + v.preload = "none"; + v.addEventListener("loadstart", function(e){v.preload = "metadata";}); + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadeddata", this.loadeddata); + v.src = test.name; // Causes implicit load. + document.body.appendChild(v); + }, + + name: "test11", + }, + { + // 13. Change preload value from auto to none after specifying a src + // should load according to preload none, no buffering should have taken place + suspend(e) { + var v = e.target; + is(v._gotLoadStart, true, "(13) Must get loadstart."); + is(v._gotLoadedMetaData, false, "(13) Must not get loadedmetadata."); + is(v.readyState, v.HAVE_NOTHING, "(13) ReadyState must be HAVE_NOTHING"); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(13) NetworkState must be NETWORK_IDLE"); + maybeFinish(v, 13); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "auto"; + v.src = test.name; + v.preload = "none"; + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("suspend", this.suspend); + document.body.appendChild(v); // Causes implicit load, should load according to preload none + document.createElement("source"); + }, + + name: "test13", + }, + { + // 14. Add preload:metadata video with src to document. Play(), should play through. + loadeddata(e) { + var v = e.target; + is(v._gotLoadStart, true, "(14) Must get loadstart."); + is(v._gotLoadedMetaData, true, "(14) Must get loadedmetadata."); + ok(v.readyState >= v.HAVE_CURRENT_DATA, "(14) ReadyState must be >= HAVE_CURRENT_DATA"); + // bug 962949 + // is(v.networkState, v.NETWORK_IDLE, "(14) NetworkState must be NETWORK_IDLE"); + v.play(); + }, + + ended(e) { + ok(true, "(14) Got playback ended"); + var v = e.target; + maybeFinish(v, 14); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "metadata"; + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("ended", this.ended); + v.addEventListener("loadeddata", this.loadeddata); + v.src = test.name; + document.body.appendChild(v); // Causes implicit load, which will be halted after + // metadata due to preload:metadata. + }, + + name: "test14", + }, + { + // 15. Autoplay should override preload:none. + ended(e) { + ok(true, "(15) Got playback ended."); + var v = e.target; + maybeFinish(v, 15); + }, + + setup(v) { + v._gotLoadStart = false; + v._gotLoadedMetaData = false; + v.preload = "none"; + v.autoplay = true; + v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}); + v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}); + v.addEventListener("ended", this.ended); + v.src = test.name; // Causes implicit load. + document.body.appendChild(v); + + // Log events for debugging. + var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", + "waiting", "pause"]; + function logEvent(e) { + info(e.target.token + ": got " + e.type); + } + events.forEach(function(e) { + v.addEventListener(e, logEvent); + }); + }, + + name: "test15", + }, + { + // 16. Autoplay should override preload:metadata. + ended(e) { + ok(true, "(16) Got playback ended."); + var v = e.target; + maybeFinish(v, 16); + }, + + setup(v) { + v.preload = "metadata"; + v.autoplay = true; + v.addEventListener("ended", this.ended); + v.src = test.name; // Causes implicit load. + document.body.appendChild(v); + }, + + name: "test16", + }, + { + // 17. On a preload:none video, adding autoplay should disable preload none, i.e. don't break autoplay! + ended(e) { + ok(true, "(17) Got playback ended."); + var v = e.target; + maybeFinish(v, 17); + }, + + setup(v) { + v.addEventListener("ended", this.ended); + v.preload = "none"; + document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none. + v.autoplay = true; + v.src = test.name; + }, + + name: "test17", + }, + { + // 18. On a preload='none' video, call play() before load algorithms's sync + // has run, the play() call should override preload='none'. + ended(e) { + ok(true, "(18) Got playback ended."); + var v = e.target; + maybeFinish(v, 18); + }, + + setup(v) { + v.addEventListener("ended", this.ended); + v.preload = "none"; + v.src = test.name; // Schedules async section to continue load algorithm. + document.body.appendChild(v); + v.play(); // Should cause preload:none to be overridden. + }, + + name: "test18", + }, + { + // 19. Set preload='auto' on first video source then switching preload='none' and swapping the video source to another. + // The second video should not start playing as it's preload state has been changed to 'none' from 'auto' + setup(v) { + v.preload = "auto"; + v.src = test.name; + // add a listener for when the video has loaded, so we know preload auto has worked + v.onloadedmetadata = function() { + is(v.preload, "auto", "(19) preload is initially auto"); + // set preload state to none and switch video sources + v.preload="none"; + v.src = test.name + "?asdf"; + + v.onloadedmetadata = function() { + ok(false, "(19) 'loadedmetadata' shouldn't fire when preload is none"); + } + + var ontimeout = function() { + v.removeEventListener("suspend", onsuspend); + ok(false, "(19) 'suspend' should've fired"); + maybeFinish(v, 19); + } + var cancel = setTimeout(ontimeout, 10000); + + var onsuspend = function() { + v.removeEventListener("suspend", onsuspend); + clearTimeout(cancel); + is(v.readyState, 0, "(19) no buffering has taken place"); + maybeFinish(v, 19); + } + v.addEventListener("suspend", onsuspend); + } + document.body.appendChild(v); + }, + + name: "test19", + } +]; + +var iterationCount = 0; +function startTest(t, token) { + if (t == tests[0]) { + ++iterationCount; + info("iterationCount=" + iterationCount); + } + if (iterationCount == 2) { + // Do this series of tests on logically different resources + t.name = baseName + "?" + Math.floor(Math.random()*100000); + } + var v = document.createElement("video"); + v.token = token; + t.setup(v); + manager.started(token); +} + +var twiceTests = tests.concat(tests); +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest); +function beginTest() { + manager.runTests(twiceTests, startTest); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_preload_attribute.html b/dom/media/test/test_preload_attribute.html new file mode 100644 index 0000000000..1e415035c5 --- /dev/null +++ b/dom/media/test/test_preload_attribute.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=479863 +--> +<head> + <title>Test for Bug 479863</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=479863">Mozilla Bug 479863</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<video id='v1'></video><audio id='a1'></audio> +<video id='v2' preload="auto"></video><audio id='a2' preload="auto"></audio> + +<pre id="test"> +<script type="application/javascript"> +var v1 = document.getElementById('v1'); +var a1 = document.getElementById('a1'); +var v2 = document.getElementById('v2'); +var a2 = document.getElementById('a2'); +is(v1.getAttribute("preload"), null, "video preload via getAttribute should be null by default"); +is(a1.getAttribute("preload"), null, "video preload via getAttribute should be null by default"); +is(v1.preload, "", "v1.preload should be empty by default"); +is(a1.preload, "", "a1.preload should be empty by default"); +is(v2.preload, "auto", "v2.preload should be auto"); +is(a2.preload, "auto", "a2.preload should be auto"); + +v1.preload = "auto"; +a1.preload = "auto"; +is(v1.preload, "auto", "video.preload should be auto"); +is(a1.preload, "auto", "audio.preload should be auto"); +is(v1.getAttribute("preload"), "auto", "video preload attribute should be auto"); +is(a1.getAttribute("preload"), "auto", "video preload attribute should be auto"); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_preload_suspend.html b/dom/media/test/test_preload_suspend.html new file mode 100644 index 0000000000..7f1146360f --- /dev/null +++ b/dom/media/test/test_preload_suspend.html @@ -0,0 +1,112 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 479863</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function checkSuspendCount(evt) { + var v = evt.target; + ++v.suspendCount; + is(v.networkState, v.NETWORK_IDLE, v.name + " got suspended, count=" + v.suspendCount); + if (v.suspendCount == v.expectedSuspendCount) { + removeNodeAndSource(v); + manager.finished(v.name); + } + if (v.suspendCount > v.expectedSuspendCount) { + ok(false, v.name + " got too many suspend events"); + } +} + +var tests = [ + { + name: 'v1', + preload: 'none', + expectedSuspendCount: 2, + onsuspend(evt) { + checkSuspendCount(evt); + if (evt.target.suspendCount == 1) { + evt.target.preload = 'auto'; + } + } + }, + { + name: 'v2', + preload: 'auto', + expectedSuspendCount: 1, + onsuspend: checkSuspendCount + }, + { + name: 'v3', + preload: 'none', + autoplay: true, + expectedSuspendCount: 1, + onsuspend: checkSuspendCount + }, + { + name: 'v4', + preload: 'none', + expectedSuspendCount: 2, + onsuspend(evt) { + checkSuspendCount(evt); + if (evt.target.suspendCount == 1) { + evt.target.play(); + } + } + }, + // disable v5 since media element doesn't support 'load' event anymore. + /*{ + name: 'v5', + preload: 'none', + expectedSuspendCount: 2, + onsuspend: function(evt) { + checkSuspendCount(evt); + if (evt.target.suspendCount == 1) { + evt.target.currentTime = 0.1; + } + } + },*/ + { + name: 'v6', + preload: 'none', + expectedSuspendCount: 2, + onsuspend(evt) { + checkSuspendCount(evt); + if (evt.target.suspendCount == 1) { + evt.target.autoplay = true; + } + } + } +]; + +function startTest(test, token) { + var v = document.createElement("video"); + v.name = test.name; + var key = Math.random(); + v.src = "seek.ogv?key=" + key + "&id=" + v.name; + v.preload = test.preload; + v.suspendCount = 0; + v.expectedSuspendCount = test.expectedSuspendCount; + if (test.autoplay) { + v.autoplay = true; + } + v.onsuspend = test.onsuspend; + document.body.appendChild(v); + manager.started(v.name); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, function() { + manager.runTests(tests, startTest); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_preserve_playbackrate_after_ui_play.html b/dom/media/test/test_preserve_playbackrate_after_ui_play.html new file mode 100644 index 0000000000..98bdd66675 --- /dev/null +++ b/dom/media/test/test_preserve_playbackrate_after_ui_play.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <title> Bug 1013933 - preserve playbackRate after clicking play button </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <script type="application/javascript" src="browserElementTestHelpers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + +<div id="content"> + <video width="320" height="240" id="video" controls mozNoDynamicControls preload="auto"></video> +</div> + +<script type="text/javascript"> +/* + * Positions of the UI elements, relative to the upper-left corner of the + * <video> box. + */ +const videoHeight = 240; +const playButtonWidth = 28; +const playButtonHeight = 28; +const playButtonCenterX = 0 + Math.round(playButtonWidth / 2); +const playButtonCenterY = videoHeight - Math.round(playButtonHeight / 2); + +var expectedPlaybackRate = 0.5 + +function runTest() { + var video = document.getElementById("video"); + video.src = "audio.wav"; + video.loop = true; + video.playbackRate = expectedPlaybackRate; + + video.oncanplaythrough = function() { + video.oncanplaythrough = null; + is(video.paused, true, "video is not playing yet."); + is(video.playbackRate, expectedPlaybackRate, + "playbackRate is correct before clicking play button."); + + // Click the play button + synthesizeMouse(video, playButtonCenterX, playButtonCenterY, { }); + }; + + video.onplay = function() { + video.onplay = null; + is(video.paused, false, "video starts playing."); + is(video.playbackRate, expectedPlaybackRate, + "playbackRate is correct after clicking play button."); + video.pause(); + SimpleTest.finish(); + }; +} + +window.addEventListener("load", runTest); +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_progress.html b/dom/media/test/test_progress.html new file mode 100644 index 0000000000..b958b2b335 --- /dev/null +++ b/dom/media/test/test_progress.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: progress events</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function do_progress(e) { + var v = e.target; + ok(!v._finished, "Check no progress events after completed for " + v._name); +} + +function do_ended(e) { + var v = e.target; + ok(!v._finished, "Only one ended event for " + v._name); + v._finished = true; + v.removeEventListener("ended", do_ended); + v.removeEventListener("progress", do_progress); + removeNodeAndSource(v); + manager.finished(v.token); +} + +function startTest(test, token) { + var type = /^video/.test(test.type) ? "video" : "audio"; + var v = document.createElement(type); + v.token = token; + manager.started(token); + v.src = test.name; + v.autoplay = true; + v._name = test.name; + v._finished = false; + v.addEventListener("ended", do_ended); + v.addEventListener("progress", do_progress); + document.body.appendChild(v); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest); +function beginTest() { + manager.runTests(gProgressTests, startTest); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_reactivate.html b/dom/media/test/test_reactivate.html new file mode 100644 index 0000000000..43675f7771 --- /dev/null +++ b/dom/media/test/test_reactivate.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test reactivation of a media element from a dead document</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> + +<iframe id="frame" src="reactivate_helper.html"></iframe> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var elements; + +function playElement(e) { + // All elements played out, finish the test case. + if (!e) { + SimpleTest.finish(); + return; + } + + e.play(); + info("Element play: " + e._name); + var reviveElement = function() { + document.body.appendChild(e); + e.onended = function() { + info("Element ended: " + e._name); + removeNodeAndSource(e); + // Play next element. + playElement(elements.pop()); + } + } + setTimeout(reviveElement, 2000); +} + +function loadedAll(elementList) { + elements = elementList; + + // Log events for debugging. + var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", + "waiting", "pause"]; + function logEvent(e) { + info(e.target._name + ": got " + e.type); + } + elementList.forEach(function(element) { + events.forEach(function(evt) { + element.addEventListener(evt, logEvent); + }); + }); + + // Blow away the subframe + document.body.removeChild(document.getElementById("frame")); + + // Play elements one by one to avoid hitting bug 847903 on MacOSX. + playElement(elements.pop()); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_readyState.html b/dom/media/test/test_readyState.html new file mode 100644 index 0000000000..17c363c503 --- /dev/null +++ b/dom/media/test/test_readyState.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: readyState</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<video id='v1'></video><audio id='a1'></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +"use strict"; +var v1 = document.getElementById('v1'); +var a1 = document.getElementById('a1'); +var passed = "truthy"; + +is(v1.readyState, 0); +is(a1.readyState, 0); + +try { + v1.readyState = 0; +} catch (e) { + passed = !passed; +} +try { + a1.readyState = 0; +} catch (e) { + passed = !passed; +} +ok(passed === true, + "Setting readyState throws in strict mode (readonly attribute)"); +</script> + +<script class="testbody" type="text/javascript"> +var v1 = document.getElementById('v1'); +var a1 = document.getElementById('a1'); +var passed = false; + +is(v1.readyState, 0); +is(a1.readyState, 0); + +try { + v1.readyState = 1; + a1.readyState = 1; + passed = v1.readyState === 0 && a1.readyState === 0; +} catch(e) { } +ok(passed, "Should not be able to set readyState (readonly attribute)"); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_referer.html b/dom/media/test/test_referer.html new file mode 100644 index 0000000000..4ce78d5fb3 --- /dev/null +++ b/dom/media/test/test_referer.html @@ -0,0 +1,88 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=584480 +--> +<head> + <title>Test for Bug 584480</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=584480">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +var media = []; + +function checkComplete() { + for (var i=0; i<media.length; ++i) { + if (!media[i]._complete) { + return; + } + } + + SimpleTest.finish(); +} + +function removeNode(v) { + v.removeEventListener("error", loadError); + v.removeEventListener("loadedmetadata", loadedMetadata); + v.remove(); + v.src = ""; +} + +function loadError(evt) { + // If no referer is sent then the sjs returns an error + ok(false, "check referer is sent with media request"); + evt.target._complete = true; + checkComplete(); + removeNode(evt.target); +} + +function loadedMetadata(evt) { + // If a referer is sent then the sjs returns a valid media + ok(true, "check referer is sent with media request"); + evt.target._complete = true; + checkComplete(); + removeNode(evt.target); +} + +// Create all media objects. +for (var i=0; i<gSmallTests.length; ++i) { + var test = gSmallTests[i]; + var type; + if (/^video/.test(test.type)) { + type = "video" + } else { + type = "audio"; + } + var v = document.createElement(type); + if (!v.canPlayType(test.type)) { + continue; + } + // ensure metadata is loaded for default preload is none on b2g + v.preload = "metadata"; + v.autoplay = "true"; + v._complete = false; + v.addEventListener("error", loadError); + v.addEventListener("loadedmetadata", loadedMetadata); + v.src = 'referer.sjs?name=' + test.name + '&type=' + test.type; + document.body.appendChild(v); // Will start load. + media.push(v); +} + +if (!media.length) { + todo(false, "No types supported"); +} else { + SimpleTest.waitForExplicitFinish(); +} +</script> +</pre> + +</body> +</html> diff --git a/dom/media/test/test_replay_metadata.html b/dom/media/test/test_replay_metadata.html new file mode 100644 index 0000000000..dab022885f --- /dev/null +++ b/dom/media/test/test_replay_metadata.html @@ -0,0 +1,120 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=467972 +--> +<head> + <title>Test for Bug 467972</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=467972">Mozilla Bug 467972</a> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +// Test for Bug 467972. Tests that when we play to end, seek to 0, and play again, that we don't +// send/receive multiple loadeddata and loadedmetadata events. + +var manager = new MediaTestManager; + +function seekStarted(evt) { + var v = evt.target; + v._gotSeekStarted = true; +} + +function seekEnded(evt) { + var v = evt.target; + v._gotSeekEnded = true; + v.play(); +} + +function loadedData(evt) { + var v = evt.target; + v._loadedDataCount++; + ok(v._loadedDataCount <= 1, "No more than 1 onloadeddata event for " + v._name); +} + +function loadedMetaData(evt) { + var v = evt.target; + v._loadedMetaDataCount++; + ok(v._loadedMetaDataCount <= 1, "No more than 1 onloadedmetadata event for " + v._name); + checkMetadata(v._name, v, v._test); + v.play(); +} + +function playing(evt) { + evt.target._playingCount++; +} + +function removeNodeAndListener(n) { + n.removeEventListener("loadedmetadata", loadedMetaData); + n.removeEventListener("ended", playbackEnded); + n.removeEventListener("playing", playing); + n.removeEventListener("loadeddata", loadedData); + n.removeEventListener("seeking", seekStarted); + n.removeEventListener("seeked", seekEnded); + removeNodeAndSource(n); +} + +function playbackEnded(evt) { + var v = evt.target; + v._endCount++; + ok(v.currentTime >= v.duration-0.1 && v.currentTime <= v.duration + 0.1, + "CurrentTime (" + v.currentTime + ") should be around " + v.duration + + " for " + v._name); + if (!v._playedOnce) { + v.currentTime = 0; + ok(v.seeking, "seeking should be true for " + v._name); + ok(!v.ended, "ended shouldn't be true once seeking has begun for " + v._name); + v._playedOnce = true; + } else { + ok(v._gotSeekEnded, "Should have received seekended for " + v._name); + ok(v._gotSeekStarted, "Should have received seekstarted for " + v._name); + is(v._loadedDataCount, 1, "Should have 1 onloadeddata event for " + v._name); + is(v._loadedMetaDataCount, 1, "Should have 1 onloadedmetadata event for " + v._name); + is(v._endCount, 2, "Should have received two ended events for " + v._name); + ok(v._playingCount > 0, "Should have at least one playing event for " + v._name); + v._finished = true; + removeNodeAndListener(v); + manager.finished(v.token); + } +} + +function startTest(test, token) { + var v = document.createElement('video'); + v.preload = "auto"; + v.token = token; + manager.started(token); + v.src = test.name; + v._name = test.name; + v._playedOnce = false; + v._gotSeekEnded = false; + v._gotSeekStarted = false; + v._loadedDataCount = 0; + v._loadedMetaDataCount = 0; + v._playingCount = 0; + v._endCount = 0; + v._test = test; + v._finished = false; + v.addEventListener("loadedmetadata", loadedMetaData); + v.addEventListener("ended", playbackEnded); + v.addEventListener("playing", playing); + v.addEventListener("loadeddata", loadedData); + v.addEventListener("seeking", seekStarted); + v.addEventListener("seeked", seekEnded); + document.body.appendChild(v); +} + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_reset_events_async.html b/dom/media/test/test_reset_events_async.html new file mode 100644 index 0000000000..482ec55986 --- /dev/null +++ b/dom/media/test/test_reset_events_async.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=975270 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript" src="manifest.js"></script> + <script type="application/javascript"> + + /** Test for Bug 975270 **/ + // Test that 'emptied' and 'abort' events are fired asynchronously when re-starting + // media load. + SimpleTest.waitForExplicitFinish(); + + var a = document.createElement("audio"); + a._abort = 0; + a._emptied = 0; + a.preload = "metadata"; // On B2G we default to preload:none. + + is(a.networkState, HTMLMediaElement.NETWORK_EMPTY, "Shouldn't be loading"); + + a.addEventListener("abort", function(e) { a._abort++; }); + a.addEventListener("emptied", function(e) { a._emptied++; }); + a.addEventListener("loadedmetadata", + function(e) { + is(a._abort, 0, "Should not have received 'abort' before 'loadedmetadata"); + is(a._emptied, 0, "Should not have received 'emptied' before 'loadedmetadata"); + + a.addEventListener("loadstart", + function() { + is(a._abort, 1, "Should have received 'abort' before 'loadstart"); + is(a._emptied, 1, "Should have received 'emptied' before 'loadstart"); + SimpleTest.finish(); + }); + + a.src = ""; + is(a._abort, 0, "Should not have received 'abort' during setting a.src=''"); + is(a._emptied, 0, "Should not have received 'emptied' during setting a.src=''"); + }); + + a.src = getPlayableAudio(gSmallTests).name; + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/media/test/test_reset_src.html b/dom/media/test/test_reset_src.html new file mode 100644 index 0000000000..a30f9cc3ef --- /dev/null +++ b/dom/media/test/test_reset_src.html @@ -0,0 +1,98 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=804875 +--> + +<head> + <title>Test for bug 804875</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" +href="https://bugzilla.mozilla.org/show_bug.cgi?id=804875">Mozilla Bug 804875</a> + +<canvas></canvas> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function finish(v) { + removeNodeAndSource(v); + manager.finished(v.token); +} + +function onLoadedData_Audio(e) { + var t = e.target; + is(t.videoHeight, 0, t.name + ": videoHeight should be zero when there is no video."); + is(t.videoWidth, 0, t.name + ": videoWidth should be zero when there is no video."); + is(t.mozPaintedFrames, 0, t.name + ": mozPaintedFrames should be zero when there is no video."); + is(t.mozFrameDelay, 0, t.name + ": mozFrameDelay should be zero when there is no video."); + var c = document.getElementsByTagName("canvas")[0].getContext("2d"); + var threw = false; + try { + c.drawImage(t, 0, 0, t.videoHeight, t.videoWidth); + } catch (ex) { + threw = true; + } + ok(!threw, t.name + ": Even though we don't succeed to draw a video frame on the canvas, we shouldn't throw."); + finish(t); +} + +function onTimeUpdate_Video(e) { + var t = e.target; + if (t.currentTime < t.duration / 4) { + return; + } + t.removeEventListener("timeupdate", onTimeUpdate_Video); + // There's no guarantee that a video frame composite notification reaches + // us before timeupdate fires. + ok(t.mozPaintedFrames >= 0, t.name + ": mozPaintedFrames should be positive or zero, is " + t.mozPaintedFrames + "."); + ok(t.mozFrameDelay >= 0, t.name + ": mozFrameDelay should be positive or zero, is " + t.mozFrameDelay + "."); + + if (t._firstTime) { + // eslint-disable-next-line no-self-assign + t.src = t.src; + t._firstTime = false; + } else { + var source = getPlayableAudio(gPlayTests); + if (!source) { + todo("No audio file available.") + finish(t); + } else { + t.removeEventListener("loadeddata", onLoadedData_Video); + t.addEventListener("loadeddata", onLoadedData_Audio); + t.src = source.name; + } + } +} + +function onLoadedData_Video(e) { + var t = e.target; + isnot(t.videoHeight, 0, t.name + ": We should have a videoHeight."); + isnot(t.videoWidth, 0, t.name + ": We should have a videoWidth."); + t.addEventListener("timeupdate", onTimeUpdate_Video); + t.play(); +} + +function startTest(test, token) { + var v = document.createElement('video'); + document.body.appendChild(v); + v._firstTime = true; + v.addEventListener("loadeddata", onLoadedData_Video); + v.src = test.name; + v.token = token; + v.name = test.name; + v.play(); + manager.started(token); +} + +manager.runTests(getPlayableVideos(gSmallTests.concat(gSeekTests)), startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_resolution_change.html b/dom/media/test/test_resolution_change.html new file mode 100644 index 0000000000..403f9b505d --- /dev/null +++ b/dom/media/test/test_resolution_change.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test playback of files with resolution changes</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var manager = new MediaTestManager;
+
+function loadedData(e) {
+ var v = e.target;
+ v.addEventListener("resize", resize);
+ v.play();
+}
+
+function resize(e) {
+ var v = e.target;
+ v.seenResolutionChange = true;
+}
+
+function ended(e) {
+ var v = e.target;
+ ok(v.seenResolutionChange, v.token + ": A resolution change should have ocurred by the end of playback");
+ removeNodeAndSource(v);
+ manager.finished(v.token);
+}
+
+function startTest(test, token) {
+ var v = document.createElement('video');
+ v.preload = "metadata";
+ v.token = token;
+ v.src = test.name;
+ v.seenResolutionChange = false;
+
+ v.addEventListener("loadeddata", loadedData)
+ v.addEventListener("ended", ended);
+
+ manager.started(token);
+ document.body.appendChild(v);
+}
+
+manager.runTests(gResolutionChangeTests, startTest);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/media/test/test_resume.html b/dom/media/test/test_resume.html new file mode 100644 index 0000000000..0e22894be1 --- /dev/null +++ b/dom/media/test/test_resume.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: Test resume of server-dropped connections</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<audio preload="auto" id="a"></audio> +<iframe id="f"></iframe> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var key = Math.round(Math.random()*1000000000); +var a = document.getElementById("a"); +var f = document.getElementById("f"); + +function didEnd() { + ok(a.currentTime > 2.26, "Reached correct end time (got " + a.currentTime + ", expected > 2.26"); + SimpleTest.finish(); +} + +function didSendCancel() { + a.addEventListener("ended", didEnd); + a.play(); +} + +function didSuspend() { + a.removeEventListener("suspend", didSuspend); + + // Cache must have filled up, or something. Tell the Web server to drop + // our connection. + f.addEventListener("load", didSendCancel); + f.src = "cancellable_request.sjs?cancelkey=" + key; +} + +if (!a.canPlayType("audio/wave")) { + todo(false, "Test requires support for audio/wave"); +} else { + a.addEventListener("suspend", didSuspend); + a.src = "cancellable_request.sjs?key=" + key; + SimpleTest.waitForExplicitFinish(); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping.html b/dom/media/test/test_seamless_looping.html new file mode 100644 index 0000000000..94d020c834 --- /dev/null +++ b/dom/media/test/test_seamless_looping.html @@ -0,0 +1,199 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test for seamless loop of HTMLAudioElements</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<canvas id="canvas" width="300" height="300"></canvas> +<script type="application/javascript"> +/** + * This test is used to ensure every time we loop audio, the audio can loop + * seamlessly which means there won't have any silenece or noise between the + * end and the start. + */ + +SimpleTest.waitForExplicitFinish(); + +// Set DEBUG to true to add a canvas with a little drawing of what is going +// on, and actually outputs the audio to the speakers. +var DEBUG = true; +var LOOPING_COUNT = 0; +var MAX_LOOPING_COUNT = 10; +// Test files are at 44100Hz, files are one second long, and contain therefore +// 100 periods +var TONE_FREQUENCY = 441; + +(async function testSeamlesslooping() { + let wavFileURL = { + name: URL.createObjectURL(new Blob([createSrcBuffer()], { type: 'audio/wav' + })), + type: "audio/wav" + }; + + let testURLs = gSeamlessLoopingTests.splice(0) + testURLs.push(wavFileURL); + for (let testFile of testURLs) { + LOOPING_COUNT = 0; + info(`- create looping audio element ${testFile.name}`); + let audio = createAudioElement(testFile.name); + + info(`- start audio and analyze audio wave data to ensure looping audio without any silence or noise -`); + await playAudioAndStartAnalyzingWaveData(audio); + + info(`- test seamless looping multiples times -`); + for (LOOPING_COUNT = 0; LOOPING_COUNT < MAX_LOOPING_COUNT; LOOPING_COUNT++) { + await once(audio, "seeked"); + info(`- the round ${LOOPING_COUNT} of the seamless looping succeeds -`); + } + window.audio.remove(); + window.ac.close(); + } + + info(`- end of seamless looping test -`); + SimpleTest.finish(); +})(); + +/** + * Test utility functions + */ +function createSrcBuffer() { + // Generate the sine in floats, then convert, for simplicity. + let channels = 1; + let sampleRate = 44100; + let buffer = new Float32Array(sampleRate * channels); + let phase = 0; + const TAU = 2 * Math.PI; + for (let i = 0; i < buffer.length; i++) { + // Adjust the gain a little so we're sure it's not going to clip. This is + // important because we're converting to 16bit integer right after, and + // clipping will clearly introduce a discontinuity that will be + // mischaracterized as a looping click. + buffer[i] = Math.sin(phase) * 0.99; + phase += TAU * TONE_FREQUENCY / 44100; + if (phase > 2 * TAU) { + phase -= TAU; + } + } + + // Make a RIFF header, it's 23 bytes + let buf = new Int16Array(buffer.length + 23); + buf[0] = 0x4952; + buf[1] = 0x4646; + buf[2] = (2 * buffer.length + 15) & 0x0000ffff; + buf[3] = ((2 * buffer.length + 15) & 0xffff0000) >> 16; + buf[4] = 0x4157; + buf[5] = 0x4556; + buf[6] = 0x6d66; + buf[7] = 0x2074; + buf[8] = 0x0012; + buf[9] = 0x0000; + buf[10] = 0x0001; + buf[11] = 1; + buf[12] = 44100 & 0x0000ffff; + buf[13] = (44100 & 0xffff0000) >> 16; + buf[14] = (2 * channels * sampleRate) & 0x0000ffff; + buf[15] = ((2 * channels * sampleRate) & 0xffff0000) >> 16; + buf[16] = 0x0004; + buf[17] = 0x0010; + buf[18] = 0x0000; + buf[19] = 0x6164; + buf[20] = 0x6174; + buf[21] = (2 * buffer.length) & 0x0000ffff; + buf[22] = ((2 * buffer.length) & 0xffff0000) >> 16; + + // convert to int16 and copy. + for (let i = 0; i < buffer.length; i++) { + buf[i + 23] = Math.round(buffer[i] * (1 << 15)); + } + return buf; +} + +function createAudioElement(url) { + /* global audio */ + window.audio = document.createElement("audio"); + audio.src = url; + audio.controls = true; + audio.loop = true; + document.body.appendChild(audio); + return audio; +} + +async function playAudioAndStartAnalyzingWaveData(audio) { + createAudioWaveAnalyser(audio); + ok(await once(audio, "canplay").then(() => true, () => false), + `audio can start playing.`) + ok(await audio.play().then(() => true, () => false), + `audio started playing successfully.`); +} + +function createAudioWaveAnalyser(source) { + /* global ac, analyser */ + window.ac = new AudioContext(); + window.analyser = ac.createAnalyser(); + analyser.frequencyBuf = new Float32Array(analyser.frequencyBinCount); + analyser.smoothingTimeConstant = 0; + analyser.fftSize = 2048; // 1024 bins + + let sourceNode = ac.createMediaElementSource(source); + sourceNode.connect(analyser); + + if (DEBUG) { + analyser.connect(ac.destination); + analyser.timeDomainBuf = new Float32Array(analyser.frequencyBinCount); + let cvs = document.querySelector("canvas"); + analyser.c = cvs.getContext("2d"); + analyser.w = cvs.width; + analyser.h = cvs.height; + } + + analyser.notifyAnalysis = () => { + if (LOOPING_COUNT >= MAX_LOOPING_COUNT) { + return; + } + let {frequencyBuf} = analyser; + analyser.getFloatFrequencyData(frequencyBuf); + // Let things stabilize at the beginning. See bug 1441509. + if (LOOPING_COUNT > 1) { + analyser.doAnalysis(frequencyBuf, ac.sampleRate); + } + + if (DEBUG) { + let {c, w, h, timeDomainBuf} = analyser; + c.clearRect(0, 0, w, h); + analyser.getFloatTimeDomainData(timeDomainBuf); + for (let i = 0; i < frequencyBuf.length; i++) { + c.fillRect(i, h, 1, -frequencyBuf[i] + analyser.minDecibels); + } + + for (let i = 0; i < timeDomainBuf.length; i++) { + c.fillRect(i, h / 2, 1, -timeDomainBuf[i] * h / 2); + } + } + + requestAnimationFrame(analyser.notifyAnalysis); + } + + analyser.doAnalysis = (buf, ctxSampleRate) => { + // The size of an FFT is twice the number of bins in its output. + let fftSize = 2 * buf.length; + // first find a peak where we expect one. + let binIndexTone = 1 + Math.round(TONE_FREQUENCY * fftSize / ctxSampleRate); + ok(buf[binIndexTone] > -35, + `Could not find a peak: ${buf[binIndexTone]} db at ${TONE_FREQUENCY}Hz + (${source.src})`); + + // check that the energy some octaves higher is very low. + let binIndexOutsidePeak = 1 + Math.round(TONE_FREQUENCY * 4 * buf.length / ctxSampleRate); + ok(buf[binIndexOutsidePeak] < -84, + `Found unexpected high frequency content: ${buf[binIndexOutsidePeak]}db + at ${TONE_FREQUENCY * 4}Hz (${source.src})`); + } + + analyser.notifyAnalysis(); +} +</script> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping_cancel_looping_future_frames.html b/dom/media/test/test_seamless_looping_cancel_looping_future_frames.html new file mode 100644 index 0000000000..28a56af7ff --- /dev/null +++ b/dom/media/test/test_seamless_looping_cancel_looping_future_frames.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Seamless looping test cancel looping - no future frame</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript" src="manifest.js"></script> +</head> +<script type="application/javascript"> + +/** + * This test aims to check whether the future frames, which are the frames + * beyond EOS and will be played in the next round of looping, would be discared + * correctly if we cancel looping in the first looping round. + */ +add_task(async function testSeamlessLoopingVideoCancelLoopingDiscardFutureFrames() { + info(`create video and play it`); + let video = document.createElement('video'); + video.loop = true; + video.src = "gizmo.mp4"; + document.body.appendChild(video); + // speed up the test. + video.playbackRate = 2; + await video.play(); + + info(`wait until the video reaches to near end`); + let checkPoint1, checkPoint2; + await new Promise(r => { + video.ontimeupdate = _ => { + // When media almost reaches to the end, the audio track should already + // reach to the end before and started storing some future frames for next + // round of looping. + if (video.currentTime > video.duration - 1.5) { + info(`cancel looping`); + video.loop = false; + video.ontimeupdate = null; + checkPoint1 = new Date(); + r(); + } + } + }); + + // Because we've canceled looping, playback should reach to the end soon + // (less than 0.5 seconds, but we use 1 second as a threshold to avoid + // intermittent failure) But if we didn't discard future frames correctly, + // that would cause that the video plays more audio frames and requires more + // time to reach the end. Note, in the error case I encountered, the playback + // didn't discard future frames and kept decoding since then, which causes + // playing extra a whole audio track again. + info(`wait until video reaches to the end within correct remaining time`); + await once(video, "ended"); + checkPoint2 = new Date(); + const diffInSeconds = Math.abs(checkPoint1 - checkPoint2) / 1000; + ok(diffInSeconds < 2, + `finished playing within ${diffInSeconds} without incorrectly playing any future frame`); +}); + +</script> +<body> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping_duration.html b/dom/media/test/test_seamless_looping_duration.html new file mode 100644 index 0000000000..4a64a81759 --- /dev/null +++ b/dom/media/test/test_seamless_looping_duration.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Seamless looping test duration</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript" src="manifest.js"></script> +</head> +<script type="application/javascript"> + +/** + * This test aims to check that the media duration shouldn't be changed during + * seamless looping. + */ +add_task(async function testSeamlessLoopingDuration() { + info(`create video and play it`); + let video = document.createElement('video'); + video.loop = true; + video.src = "gizmo-short.mp4"; + document.body.appendChild(video); + await video.play(); + + video.ondurationchange = + _ => ok(false, "shouldn't change duration during looping!"); + + info(`test seamless looping multiples times`); + let MAX_LOOPING_COUNT = 10; + for (let count = 0; count < MAX_LOOPING_COUNT; count++) { + await once(video, "seeking"); + await once(video, "seeked"); + ok(true, `the round ${count} of the seamless looping succeeds`); + } +}); + +// This one tests the situation where both tracks reached EOS before entering +// looping state. +add_task(async function testSeamlessLoopingDuration2() { + info(`create video and play it to the end`); + let video = document.createElement('video'); + video.src = "gizmo-short.mp4"; + document.body.appendChild(video); + await video.play(); + await once(video, "ended"); + + info(`play video again`); + video.ondurationchange = + _ => ok(false, "shouldn't change duration during looping!"); + video.loop = true; + await video.play(); + + info(`test seamless looping multiples times`); + let MAX_LOOPING_COUNT = 10; + for (let count = 0; count < MAX_LOOPING_COUNT; count++) { + await once(video, "seeking"); + await once(video, "seeked"); + ok(true, `the round ${count} of the seamless looping succeeds`); + } +}); + +</script> +<body> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping_media_element_state.html b/dom/media/test/test_seamless_looping_media_element_state.html new file mode 100644 index 0000000000..c94de04912 --- /dev/null +++ b/dom/media/test/test_seamless_looping_media_element_state.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Seamless looping media element state</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript" src="manifest.js"></script> +</head> +<script type="application/javascript"> + +/** + * This test aims to check if the media element would change its ready state + * under `HAVE_CURRENT_DATA` when the seamless looping is performed. Because + * during seamless looping, we should always have current frame. + */ +add_task(async function testSeamlessLoopingMediaElementState() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.seamless-looping-video", true], + ], + }); + + info(`create video`); + let video = document.createElement('video'); + video.loop = true; + video.src = "gizmo-short.mp4"; + document.body.appendChild(video); + await video.play(); + + info(`test seamless looping multiples times`); + let MAX_LOOPING_COUNT = 10; + for (let count = 0; count < MAX_LOOPING_COUNT; count++) { + await once(video, "seeking"); + // If the video looping is not seamless, when playback reaches to the end, + // MDSM would trigger a seek in order to get the new frame from the start + // position. That would notify the media element that the status of the next + // frame is not available now due to seeking (NEXT_FRAME_UNAVAILABLE_SEEKING) + // and causes the media element dispatching `waiting` event. + video.onwaiting = () => { + ok(false, "should not get waiting event"); + } + await once(video, "seeked"); + video.onwaiting = null; + ok(true, `the round ${count} of the seamless looping succeeds`); + } +}); + +</script> +<body> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping_not_keep_painting_old_video_frames.html b/dom/media/test/test_seamless_looping_not_keep_painting_old_video_frames.html new file mode 100644 index 0000000000..6f0bc45f55 --- /dev/null +++ b/dom/media/test/test_seamless_looping_not_keep_painting_old_video_frames.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Seamless looping test : do not keep painting old video frames</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript" src="manifest.js"></script> +</head> +<script type="application/javascript"> + +/** + * This test is used to ensure that after seeking to EOS directly, video can + * display its frame sucessfully, not showing the incorrect frame which should + * be discarded during seeking. The test video contains three seconds white + * frames [0s-3s] and one second black frames [3s-4s], so after seeking to + * EOS and start looping video again, video should display white frames, instead + * of black frames. + */ +add_task(async function testSeamlessLoopingDoNotKeepPaintingOldVideoFrame() { + info(`create video and play it`); + const WIDTH = 10, HEIGHT = 10; + let video = document.createElement('video'); + video.loop = true; + video.src = "white-3s-black-1s.webm"; + video.width = WIDTH; + video.height = HEIGHT; + document.body.appendChild(video); + await video.play(); + + info(`seek to EOS (${video.duration}s) and waiting for looping`); + video.currentTime = video.duration; + await once(video, "seeked"); + + // We can't control the exact timing when the compositor would render next + // frame so we wait for the next timeupdate to ensure the media has been + // moved forward to the place where video should show white frames. + info(`wait for timeupdate then check the painted frame`); + await once(video, "timeupdate"); + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + canvas.width = WIDTH; + canvas.height = HEIGHT; + context.drawImage(video, 0, 0, canvas.width, canvas.height); + const pixelData = context.getImageData(0, 0, WIDTH, HEIGHT).data; + for (let idx = 0; idx < WIDTH * HEIGHT; idx++) { + let pixelCount = 4 * idx; // RGBA + // White frame's RGB value should be [255,255,255] + is(pixelData[pixelCount + 0], 255, `R should be 255`); + is(pixelData[pixelCount + 1], 255, `G should be 255`); + is(pixelData[pixelCount + 2], 255, `B should be 255`); + } +}); + +</script> +<body> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping_resume_video_decoding.html b/dom/media/test/test_seamless_looping_resume_video_decoding.html new file mode 100644 index 0000000000..14f7cdd331 --- /dev/null +++ b/dom/media/test/test_seamless_looping_resume_video_decoding.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Seamless looping test with resuming video decoding</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript" src="manifest.js"></script> +<script src="background_video.js"></script> +</head> +<script type="application/javascript"> + +/** + * This test aims to check if seamless looping can work well with the mechanism + * of resuming video decoding. When resuming decoding, MDSM will leave the + * looping state and go to video only seek state. We want to ensure that the + * timestamp of new video data that state requests will also be adjusted in + * order to keep video playback ongoing without video being frozen because + * frames get discarded. + */ +add_task(async function testSeamlessLoopingResumeVideoDecoding() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.test.video-suspend", true], + ["media.suspend-background-video.enabled", true], + ["media.suspend-background-video.delay-ms", 0], + ], + }); + + info(`create video and play it`); + let video = document.createElement('video'); + video.loop = true; + video.src = "gizmo.mp4"; + document.body.appendChild(video); + // speed up the test. + video.playbackRate = 2; + await video.play(); + + info(`test seamless looping once`); + await once(video, "seeked"); + ok(true, `loop back happened`); + + info(`suspend video decoding`); + video.setVisible(false); + await nextVideoSuspends(video); + info(`suspended video decoding`); + + info(`resume video decoding (enter video-only seek state)`); + video.setVisible(true); + await testVideoOnlySeekCompletedWhenShown(video); + info(`resumed video decoding and finished video-only seeking`); + + const lastPaintedFramesAmount = video.mozPaintedFrames; + info(`end test after looping one more time`); + await once(video, "seeked"); + + const currentPaintedFrameAmount = video.mozPaintedFrames; + ok(lastPaintedFramesAmount < currentPaintedFrameAmount, + `painted frames keeps growing from ${lastPaintedFramesAmount} to ${currentPaintedFrameAmount}`); +}); + +</script> +<body> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping_seek_current_time.html b/dom/media/test/test_seamless_looping_seek_current_time.html new file mode 100644 index 0000000000..888e5437c4 --- /dev/null +++ b/dom/media/test/test_seamless_looping_seek_current_time.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Seamless looping current time after seek</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript" src="manifest.js"></script> +</head> +<script type="application/javascript"> + +/** + * This test is used to ensure that the playback position won't be reset to ZERO + * incorrectly when performing seek on a looping media. + */ +add_task(async function testSeekVideoOnlyPlayback() { + info(`create and play a media which contains only video track`); + let video = createLoopingMedia("video", "gizmo-noaudio.webm"); + await video.play(); + await assertSeekingForwardShouldIncreaseCurrentTime(video); + removeNodeAndSource(video); +}); + +add_task(async function testSeekAudioOnlyPlayback() { + info(`create and play a media which contains only audio track`); + let audio = createLoopingMedia("audio", "flac-s24.flac"); + await audio.play(); + await assertSeekingForwardShouldIncreaseCurrentTime(audio); + removeNodeAndSource(audio); +}); + +add_task(async function testSeekBothTracksPlayback() { + info(`create and play a media which contains both tracks`); + let video = createLoopingMedia("video", "gizmo.mp4"); + await video.play(); + await assertSeekingForwardShouldIncreaseCurrentTime(video); + removeNodeAndSource(video); +}); + +// Following are helper functions +function createLoopingMedia(type, src) { + let media = document.createElement(type); + media.loop = true; + media.src = src; + document.body.appendChild(media); + return media; +} + +async function assertSeekingForwardShouldIncreaseCurrentTime(media) { + const currentTimeBeforeSeek = media.currentTime; + const target = media.duration / 2; + media.currentTime = target; + await once(media, "seeked"); + const currentTimeAfterSeek = media.currentTime; + ok(currentTimeAfterSeek > currentTimeBeforeSeek, + `media current time should keep going forward (target=${target}, ` + + `currentTime=${currentTimeBeforeSeek} -> ${currentTimeAfterSeek})`); +} + +</script> +<body> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping_shorter_audio_than_video.html b/dom/media/test/test_seamless_looping_shorter_audio_than_video.html new file mode 100644 index 0000000000..6e1105563e --- /dev/null +++ b/dom/media/test/test_seamless_looping_shorter_audio_than_video.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Seamless looping : shorter audio track than video track</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript" src="manifest.js"></script> +</head> +<script type="application/javascript"> + +/** + * This test is used to check whether we can play and loop a file in which the + * audio track is shorter than its video track. The file we used in the test has + * audio track (duration 3,001,000us), and video track (duration 3,047,000us) + */ +add_task(async function testSeamlessLoopingShorterAudioTrack() { + info(`create video and play it`); + let video = document.createElement('video'); + video.loop = true; + video.controls = true; + video.src = "shorter_audio_than_video_3s.webm"; + document.body.appendChild(video); + await video.play(); + + info(`test seamless looping multiples times`); + let MAX_LOOPING_COUNT = 1; + for (let count = 0; count < MAX_LOOPING_COUNT; count++) { + await once(video, "seeking"); + await once(video, "seeked"); + ok(true, `the round ${count} of the seamless looping succeeds`); + } +}); + +</script> +<body> +</body> +</html> diff --git a/dom/media/test/test_seamless_looping_video.html b/dom/media/test/test_seamless_looping_video.html new file mode 100644 index 0000000000..3bf99b0a62 --- /dev/null +++ b/dom/media/test/test_seamless_looping_video.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Seamless looping video canvas test</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="text/javascript" src="manifest.js"></script> +</head> +<canvas id="canvas"></canvas> +<video id="v"></video> +<script type="application/javascript"> + +/** + * This test aims to check if the video is seamless looping by capturing the + * image when loop happens. We use a video contains only white frames, so the + * captured frame should always be a white frame. If looping is not seamless, + * the captured frame would become a black frame. + */ +const WIDTH = 10, HEIGHT = 10; + +add_task(async function testSeamlessLoopingVideoCanvas() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["media.seamless-looping-video", true], + ], + }); + + info(`load video which only contains white frames`); + let video = document.getElementById("v"); + video.loop = true; + video.src = "white-short.webm"; + video.width = WIDTH; + video.height = HEIGHT; + await video.play(); + + info(`setup canvas`); + const cvs = document.getElementById("canvas"); + cvs.width = WIDTH; + cvs.height = HEIGHT; + + info(`test seamless looping multiples times`); + let MAX_LOOPING_COUNT = 10; + for (let count = 0; count < MAX_LOOPING_COUNT; count++) { + await once(video, "seeking"); + assertPaintedFrameIsWhiteFrame(); + await once(video, "seeked"); + ok(true, `the round ${count} of the seamless looping succeeds`); + } +}); + +function assertPaintedFrameIsWhiteFrame() { + info(`catpure image from video`); + const cvs = document.getElementById("canvas"); + let context = cvs.getContext('2d'); + if (!context) { + ok(false, "can't get 2d context"); + } + + context.drawImage(document.getElementById("v"), 0, 0, WIDTH, HEIGHT); + let imageData = context.getImageData(0, 0, WIDTH, HEIGHT); + for (let idx = 0; idx < WIDTH * HEIGHT; idx++) { + let pixelCount = 4 * idx; // RGBA + let data = imageData.data; + // White frame's RGB value should be [255,255,255] + is(data[pixelCount + 0], 255, `R should be 255`); + is(data[pixelCount + 1], 255, `G should be 255`); + is(data[pixelCount + 2], 255, `B should be 255`); + } +} +</script> +<body> +</body> +</html> diff --git a/dom/media/test/test_seek-1.html b/dom/media/test/test_seek-1.html new file mode 100644 index 0000000000..8690a475b6 --- /dev/null +++ b/dom/media/test/test_seek-1.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 1; + +function test_seek1(v, seekTime, is, ok, finish) { + +var startPassed = false; +var endPassed = false; +var seekFlagStart = false; +var seekFlagEnd = false; +var readonly = true; +var completed = false; + +function startTest() { + ok(!completed, "Should not be completed yet"); + ok(!v.seeking, "seeking should default to false"); + try { + v.seeking = true; + readonly = v.seeking === false; + } + catch(e) { + readonly = "threw exception: " + e; + } + is(readonly, true, "seeking should be readonly"); + + v.currentTime = seekTime; + seekFlagStart = v.seeking; +} + +function seekStarted() { + ok(!completed, "should not be completed yet"); + ok(Math.abs(v.currentTime - seekTime) < 0.1, + "Video currentTime should be around " + seekTime + ": " + v.currentTime + " (seeking)"); + startPassed = true; +} + +function seekEnded() { + ok(!completed, "shuld not be completed yet"); + ok(Math.abs(v.currentTime - seekTime) < 0.1, + "Video currentTime should be around " + seekTime + ": " + v.currentTime + " (seeked)"); + endPassed = true; + seekFlagEnd = v.seeking; + v.play(); +} + +function playbackEnded() { + ok(!completed, "should not be completed yet"); + + completed = true; + ok(startPassed, "seeking event"); + ok(endPassed, "seeked event"); + ok(seekFlagStart, "seeking flag on start should be true"); + ok(!seekFlagEnd, "seeking flag on end should be false"); + finish(); +} + +once(v, "ended", playbackEnded); +once(v, "loadedmetadata", startTest); +once(v, "seeking", seekStarted); +once(v, "seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-10.html b/dom/media/test/test_seek-10.html new file mode 100644 index 0000000000..6c02384ed4 --- /dev/null +++ b/dom/media/test/test_seek-10.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 10; + +function test_seek10(v, seekTime, is, ok, finish) { + +// Test bug 523335 - ensure that if we close a stream while seeking, we +// don't hang during shutdown. This test won't "fail" per se if it's regressed, +// it will instead start to cause random hangs in the mochitest harness on +// shutdown. + +function startTest() { + // Must be duration*0.9 rather than seekTime, else we don't hit that problem. + // This is probably due to the seek bisection finishing too quickly, before + // we can close the stream. + v.currentTime = v.duration * 0.9; +} + +function done(evt) { + ok(true, "We don't acutally test anything..."); + finish(); +} + +function seeking() { + ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime); + v.onerror = done; + v.src = "not a valid video file."; + v.load(); // Cause the existing stream to close. +} + +v.addEventListener("loadeddata", startTest); +v.addEventListener("seeking", seeking); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-11.html b/dom/media/test/test_seek-11.html new file mode 100644 index 0000000000..2207f684d7 --- /dev/null +++ b/dom/media/test/test_seek-11.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +PARALLEL_TESTS = 1; +const SEEK_TEST_NUMBER = 11; + +function test_seek11(v, seekTime, is, ok, finish) { + +// Test for bug 476973, multiple seeks to the same position shouldn't cause problems. + +var seekedNonZero = false; +var completed = false; +var target = 0; + +function startTest() { + if (completed) + return; + target = v.duration / 2; + v.currentTime = target; + v.currentTime = target; + v._seekTarget = target; +} + +function startSeeking() { + ok(v.currentTime >= v._seekTarget - 0.1, + "Video currentTime should be around " + v._seekTarget + ": " + v.currentTime); + if (!seekedNonZero) { + v.currentTime = target; + v._seekTarget = target; + seekedNonZero = true; + } +} + +function seekEnded() { + if (completed) + return; + + if (v.currentTime > 0) { + ok(v.currentTime > target - 0.1 && v.currentTime < target + 0.1, + "Seek to wrong destination " + v.currentTime); + v.currentTime = 0.0; + v._seekTarget = 0.0; + } else { + ok(seekedNonZero, "Successfully seeked to nonzero"); + ok(true, "Seek back to zero was successful"); + completed = true; + finish(); + } +} + +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeking", startSeeking); +v.addEventListener("seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-12.html b/dom/media/test/test_seek-12.html new file mode 100644 index 0000000000..28decabadc --- /dev/null +++ b/dom/media/test/test_seek-12.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 12; + +function test_seek12(v, seekTime, is, ok, finish) { +var completed = false; + +function startTest() { + if (completed) + return; + ok(!v.seeking, "seeking should default to false"); + v.currentTime = seekTime; + is(v.currentTime, seekTime, "currentTime must report seek target immediately"); + is(v.seeking, true, "seeking flag on start should be true"); +} + +function seekStarted() { + if (completed) + return; + //is(v.currentTime, seekTime, "seeking: currentTime must be seekTime"); + ok(Math.abs(v.currentTime - seekTime) < 0.01, "seeking: currentTime must be seekTime"); +} + +function seekEnded() { + if (completed) + return; + completed = true; + //is(v.currentTime, seekTime, "seeked: currentTime must be seekTime"); + ok(Math.abs(v.currentTime - seekTime) < 0.01, "seeked: currentTime must be seekTime"); + is(v.seeking, false, "seeking flag on end should be false"); + finish(); +} + +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeking", seekStarted); +v.addEventListener("seeked", seekEnded); +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-13.html b/dom/media/test/test_seek-13.html new file mode 100644 index 0000000000..81eda9b658 --- /dev/null +++ b/dom/media/test/test_seek-13.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 13; + +function test_seek13(v, seekTime, is, ok, finish) { +var completed = false; + +function startTest() { + if (completed) + return; + ok(!v.seeking, "seeking should default to false"); + v.currentTime = v.duration; + is(v.currentTime, v.duration, "currentTime must report seek target immediately"); + is(v.seeking, true, "seeking flag on start should be true"); +} + +function seekStarted() { + if (completed) + return; + //is(v.currentTime, v.duration, "seeking: currentTime must be duration"); + ok(Math.abs(v.currentTime - v.duration) < 0.01, + "seeking: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")"); +} + +function seekEnded() { + if (completed) + return; + //is(v.currentTime, v.duration, "seeked: currentTime must be duration"); + ok(Math.abs(v.currentTime - v.duration) < 0.01, + "seeked: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")"); + is(v.seeking, false, "seeking flag on end should be false"); +} + +function playbackEnded() { + if (completed) + return; + completed = true; + //is(v.currentTime, v.duration, "ended: currentTime must be duration"); + ok(Math.abs(v.currentTime - v.duration) < 0.01, + "ended: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")"); + is(v.seeking, false, "seeking flag on end should be false"); + is(v.ended, true, "ended must be true"); + finish(); +} + +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeking", seekStarted); +v.addEventListener("seeked", seekEnded); +v.addEventListener("ended", playbackEnded); +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-14.html b/dom/media/test/test_seek-14.html new file mode 100644 index 0000000000..7e19fe3bd3 --- /dev/null +++ b/dom/media/test/test_seek-14.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +const SEEK_TEST_NUMBER = 14; + +function test_seek14(v, seekTime, is, ok, finish) { + var completed = false; + + function startTest() { + v.play(); + v.currentTime = v.duration; + } + + function playbackEnded() { + if (completed) { + ok(false, "'ended' should only fire once."); + return; + } + completed = true; + // Finish the test after 700ms. We should receive only one 'ended' event. + setTimeout(finish, 700); + } + + v.addEventListener("loadedmetadata", startTest); + v.addEventListener("ended", playbackEnded); +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-2.html b/dom/media/test/test_seek-2.html new file mode 100644 index 0000000000..7b666df961 --- /dev/null +++ b/dom/media/test/test_seek-2.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +PARALLEL_TESTS = 1; +const SEEK_TEST_NUMBER = 2; + +function test_seek2(v, seekTime, is, ok, finish) { + +// Test seeking works if current time is set before video is +// playing. +var startPassed = false; +var endPassed = false; +var completed = false; + +function startTest() { + if (completed) + return; + + v.currentTime=seekTime; + v.play(); +} + +function seekStarted() { + if (completed) + return; + + ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime); + startPassed = true; +} + +function seekEnded() { + if (completed) + return; + + endPassed = true; +} + +function playbackEnded() { + if (completed) + return; + + completed = true; + ok(startPassed, "send seeking event"); + ok(endPassed, "send seeked event"); + ok(v.ended, "Checking playback has ended"); + ok(Math.abs(v.currentTime - v.duration) <= 0.1, "Checking currentTime at end: " + v.currentTime); + finish(); +} + +v.addEventListener("ended", playbackEnded); +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeking", seekStarted); +v.addEventListener("seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-3.html b/dom/media/test/test_seek-3.html new file mode 100644 index 0000000000..c030f03d20 --- /dev/null +++ b/dom/media/test/test_seek-3.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 3; + +function test_seek3(v, seekTime, is, ok, finish) { + +// Test seeking works if current time is set but video is not played. +var completed = false; +var gotTimeupdate = false; + +function startTest() { + if (completed) + return; + + v.currentTime=seekTime; +} + +function timeupdate() { + gotTimeupdate = true; + v.removeEventListener("timeupdate", timeupdate); +} + +function seekStarted() { + if (completed) + return; + + ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime); + v.addEventListener("timeupdate", timeupdate); +} + +function seekEnded() { + if (completed) + return; + + var t = v.currentTime; + ok(Math.abs(t - seekTime) <= 0.1, "Video currentTime should be around " + seekTime + ": " + t); + ok(gotTimeupdate, "Should have got timeupdate between seeking and seekended"); + completed = true; + finish(); +} + +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeking", seekStarted); +v.addEventListener("seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-4.html b/dom/media/test/test_seek-4.html new file mode 100644 index 0000000000..4e5c1fee59 --- /dev/null +++ b/dom/media/test/test_seek-4.html @@ -0,0 +1,70 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 4; + +function test_seek4(v, seekTime, is, ok, finish) { + +// Test for a seek, followed by another seek before the first is complete. +var seekCount = 0; +var completed = false; + +function startTest() { + if (completed) + return; + + v.currentTime=seekTime; + v._seekTarget=seekTime; +} + +function seekStarted() { + if (completed) + return; + + seekCount += 1; + + ok(v.currentTime >= v._seekTarget - 0.1, + "Video currentTime should be around " + v._seekTarget + ": " + v.currentTime); + if (seekCount == 1) { + v.currentTime=seekTime/2; + v._seekTarget=seekTime/2; + } +} + +function seekEnded() { + if (completed) + return; + + if (seekCount == 2) { + ok(Math.abs(v.currentTime - seekTime/2) <= 0.1, "seek on target: " + v.currentTime); + completed = true; + finish(); + } +} + +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeking", seekStarted); +v.addEventListener("seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-5.html b/dom/media/test/test_seek-5.html new file mode 100644 index 0000000000..a86477f77c --- /dev/null +++ b/dom/media/test/test_seek-5.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 5; + +function test_seek5(v, seekTime, is, ok, finish) { + +// Test for a seek, followed by a play before the seek completes, ensure we play at the end of the seek. +var startPassed = false; +var endPassed = false; +var completed = false; + +function startTest() { + if (completed) + return; + + v.currentTime=seekTime; +} + +function seekStarted() { + if (completed) + return; + ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime); + startPassed = true; + v.play(); +} + +function seekEnded() { + if (completed) + return; + endPassed = true; +} + +function playbackEnded() { + if (completed) + return; + ok(startPassed, "Got seeking event"); + ok(endPassed, "Got seeked event"); + completed = true; + finish(); +} + +v.addEventListener("ended", playbackEnded); +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeking", seekStarted); +v.addEventListener("seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-6.html b/dom/media/test/test_seek-6.html new file mode 100644 index 0000000000..32554c4c2f --- /dev/null +++ b/dom/media/test/test_seek-6.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 6; + +function test_seek6(v, seekTime, is, ok, finish) { + +// Test for bug identified by Chris Pearce in comment 40 on +// bug 449159. +var seekCount = 0; +var completed = false; +var interval; + +function poll() { + v.currentTime; +} + +function startTest() { + if (completed) + return; + interval = setInterval(poll, 10); + v.currentTime = Math.random() * v.duration; +} + +function seekEnded() { + if (completed) + return; + + seekCount++; + ok(true, "Seek " + seekCount); + if (seekCount == 3) { + clearInterval(interval); + completed = true; + finish(); + } else { + v.currentTime = Math.random() * v.duration; + } +} + +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-7.html b/dom/media/test/test_seek-7.html new file mode 100644 index 0000000000..96139d6f83 --- /dev/null +++ b/dom/media/test/test_seek-7.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 7; + +function test_seek7(v, seekTime, is, ok, finish) { + +// If a NaN is passed to currentTime, make sure this is caught +// otherwise an infinite loop in the Ogg backend occurs. +var completed = false; +var thrown1 = false; +var thrown3 = false; + +function startTest() { + if (completed) + return; + + try { + v.currentTime = NaN; + } catch(e) { + thrown1 = true; + } + + try { + v.currentTime = Math.random; + } catch(e) { + thrown3 = true; + } + + completed = true; + ok(thrown1, "Setting currentTime to invalid value of NaN"); + ok(thrown3, "Setting currentTime to invalid value of a function"); + finish(); +} + +v.addEventListener("loadedmetadata", startTest); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-8.html b/dom/media/test/test_seek-8.html new file mode 100644 index 0000000000..2f6e390eef --- /dev/null +++ b/dom/media/test/test_seek-8.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 8; + +function test_seek8(v, seekTime, is, ok, finish) { + +function startTest() { + v.currentTime = 1000; +} + +function seekEnded() { + ok(Math.abs(v.currentTime - v.duration) < 0.2, + "currentTime " + v.currentTime + " close to " + v.duration); + finish(); +} + +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek-9.html b/dom/media/test/test_seek-9.html new file mode 100644 index 0000000000..c03f6a75e3 --- /dev/null +++ b/dom/media/test/test_seek-9.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// The data being used in these tests is specified in manifest.js. +// The functions to build the test array and to run a specific test are in +// seek_support.js. + +const SEEK_TEST_NUMBER = 9; + +function test_seek9(v, seekTime, is, ok, finish) { + +function startTest() { + v.currentTime = -1000; +} + +function seekEnded() { + is(v.currentTime, 0, "currentTime clamped to 0"); + finish(); +} + +v.addEventListener("loadedmetadata", startTest); +v.addEventListener("seeked", seekEnded); + +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seekLies.html b/dom/media/test/test_seekLies.html new file mode 100644 index 0000000000..f3141eaabd --- /dev/null +++ b/dom/media/test/test_seekLies.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: server lies about range requests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onunload="mediaTestCleanup();"> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function on_metadataloaded() { + var v = document.getElementById('v'); + var d = Math.round(v.duration*1000); + ok(d == 4000, "Checking duration: " + d); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +<video id='v' + preload="metadata" + src='seekLies.sjs' + onloadedmetadata='on_metadataloaded();'></video> +</body> +</html> diff --git a/dom/media/test/test_seekToNextFrame.html b/dom/media/test/test_seekToNextFrame.html new file mode 100644 index 0000000000..755d06e622 --- /dev/null +++ b/dom/media/test/test_seekToNextFrame.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test seekToNextFrame of media files that should play OK</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var video = document.createElement('video'); + video.preload = "metadata"; + video.token = token; + video.seenSeeking = false; + video.seenEnded = false; + + var handler = { + "ontimeout": function() { + Log(token, "timed out: ended=" + video.seenEnded); + } + }; + manager.started(token, handler); + + video.src = test.name; + video.name = test.name; + + function callSeekToNextFrame() { + video.seekToNextFrame().then( + () => { + if (!video.seenSeeking) { + ok(false, video.token + ": Should have already received seeking event."); + } + video.seenSeeking = false; + if (!video.ended) { + callSeekToNextFrame(); + } + }, + () => { + ok(false, video.token + ": seekToNextFrame() failed."); + } + ); + } + + var onLoadedmetadata = function(t, v) { return function() { + callSeekToNextFrame(); + }}(test, video); + + var finish = function() { + video.finished = true; + video.removeEventListener("loadedmetadata", onLoadedmetadata); + video.removeEventListener("seeking", onSeeking); + removeNodeAndSource(video); + manager.finished(video.token); + } + + var onEnded = function(t, v) { return function() { + v.seenEnded = true; + finish(); + }}(test, video); + + var onSeeking = function(t, v) { return function() { + if (v.seenSeeking) { + ok(false, v.token + ": Should yet receive seeking event."); + } + v.seenSeeking = true; + }}(test, video); + + video.addEventListener("loadedmetadata", onLoadedmetadata); + video.addEventListener("seeking", onSeeking); + video.addEventListener("ended", onEnded); + + document.body.appendChild(video); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + { + "set": [ + ["media.seekToNextFrame.enabled", true ], + ["media.dormant-on-pause-timeout-ms", -1] + ] + }, + function() { + manager.runTests(gSeekToNextFrameTests, startTest); + }); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek_duration.html b/dom/media/test/test_seek_duration.html new file mode 100644 index 0000000000..0240f31f94 --- /dev/null +++ b/dom/media/test/test_seek_duration.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="seek_support.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** + * This test is used to make sure video's duration won't be changed when it + * reachs to the end after seeking to position where the time is very close to + * video's end time. + */ + +SimpleTest.waitForExplicitFinish(); + +async function test(name, videoProperties) +{ + const video = document.createElement('video'); + video.src = "bunny.webm"; + Object.assign(video, videoProperties); + document.body.appendChild(video); + + const loadedMetadata = once(video, "loadedmetadata"); + const canplay = once(video, "canplay"); + const end = once(video, "ended"); + + info(`- wait for ${name} video loading metadata -`); + await loadedMetadata; + const originalDuration = video.duration; + + info(`- seek ${name} video to the position which is close to end time -`); + // video's duration is 2.1 and the last key frame is in 2.0, we want to seek + // to that keyframe. + video.currentTime = originalDuration - 0.1; + + info(`- play ${name} video until it ends -`); + await canplay; + await video.play(); + await end; + + is(video.duration, originalDuration, `${name} duration shouldn't change`); + removeNodeAndSource(video); +} + +(async function startTest() { + await Promise.all([ + test("unmuted", {}), + test("muted", {muted: true}), + ]); + SimpleTest.finish(); +})(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek_negative.html b/dom/media/test/test_seek_negative.html new file mode 100644 index 0000000000..98f0b9c910 --- /dev/null +++ b/dom/media/test/test_seek_negative.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seeking to a negative time with readyState HAVE_NOTHING</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function startTest(test, token) { + var type = getMajorMimeType(test.type); + var v = document.createElement(type); + v.token = token; + manager.started(token); + + // Seek to negative start time. + v.currentTime = -123; + is(v.readyState, v.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + ok(!v.seeking, "can't be seeking prior src defined"); + is(v.currentTime, -123, "currentTime is original seek time"); + + v.src = test.name; + + // Initialize running variables. + v._name = test.name; + v._seekStarted = false; + v._seekCompleted = false; + v._metadata = false; + + var events = [ "suspend", "play", "canplay", "canplaythrough", "loadstart", + "loadedmetadata", "loadeddata", "playing", "ended", "error", + "stalled", "emptied", "abort", "waiting", "pause" ]; + function logEvent(e) { + var video = e.target; + Log(e.target.token, "got " + e.type + " with currentTime = " + video.currentTime); + } + events.forEach(function(e) { + v.addEventListener(e, logEvent); + }); + + once(v, "seeking", function() { + v._seekStarted = true; + ok(v.currentTime >= 0, "currentTime should be positive"); + }); + once(v, "seeked", function() { + v._seekCompleted = true; + ok(v.currentTime >= 0, "currentTime should be positive"); + }); + once(v, "loadedmetadata", function() { + v._metadata = true; + ok(v.seeking, "element is seeking once readyState is HAVE_METADATA"); + ok(v.currentTime >= 0, "currentTime should be positive"); + }); + once(v, "ended", function() { + ok(v._seekStarted, "seek should have started"); + ok(v._seekCompleted, "seek should have completed"); + ok(v._metadata, "loadedmetadata fired"); + ok(v.currentTime >= 0, "currentTime should be positive"); + removeNodeAndSource(v); + manager.finished(v.token); + }); + + v.play(); +} + + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek_nosrc.html b/dom/media/test/test_seek_nosrc.html new file mode 100644 index 0000000000..56461007bd --- /dev/null +++ b/dom/media/test/test_seek_nosrc.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seek tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var SEEK_TIME = 3.5; +var seekStarted = false; +var seekCompleted = false; +var metadata = false; + +var v = document.createElement('video'); +document.body.appendChild(v); +SimpleTest.registerCleanupFunction(function () { + v.remove(); +}); + +try { + v.currentTime = SEEK_TIME; +} catch (e) { + ok(false, "should not fire '" + e + "' event"); +} +is(v.readyState, v.HAVE_NOTHING, "readyState is HAVE_NOTHING"); +ok(!v.seeking, "can't be seeking prior src defined"); +is(v.currentTime, SEEK_TIME, "currentTime is default playback start position"); +once(v, "seeking", function() { + seekStarted = true; +}); +once(v, "seeked", function() { + seekCompleted = true; +}); +once(v, "loadedmetadata", function() { + metadata = true; + ok(v.seeking, "element is seeking once readyState is HAVE_METADATA"); +}); +once(v, "ended", function() { + ok(seekStarted, "seek should have started"); + ok(seekCompleted, "seek should have completed"); + ok(metadata, "loadedmetadata fired"); + ok(v.currentTime >= SEEK_TIME, "currentTime should be after seek time"); + SimpleTest.finish(); +}); + +v.src = "seek.webm"; +v.play(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek_out_of_range.html b/dom/media/test/test_seek_out_of_range.html new file mode 100644 index 0000000000..a477ebdd19 --- /dev/null +++ b/dom/media/test/test_seek_out_of_range.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: seeking off the end of a file</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +// Test if the ended event works correctly. + +async function initTest(test, token) { + var type = getMajorMimeType(test.type); + var v = document.createElement(type); + v.preload = "auto"; + v.token = token; + manager.started(token); + v.src = test.name; + v._name = test.name; + document.body.appendChild(v); + + await once(v, "loadedmetadata"); + info(`${v._name}: seeking to the end of the media.`); + v.currentTime = 3.0 * v.duration; + // Wait for 'seeked' and 'ended' to be fired. + await Promise.all([once(v, "seeked"), once(v, "ended")]); + // Check currentTime is near the end of the media. + ok(Math.abs(v.duration - v.currentTime) < 0.1, + "Should be at end of media for " + v._name + " t=" + v.currentTime + " d=" + v.duration); + // Call play() to start playback from the beginning. + v.play(); + await once(v, "ended"); + ok(v.ended, "Checking ended set after seeking to EOF and playing for " + v._name); + removeNodeAndSource(v); + manager.finished(v.token); +} + +manager.runTests(gSmallTests, initTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_seek_promise_bug1344357.html b/dom/media/test/test_seek_promise_bug1344357.html new file mode 100644 index 0000000000..6c441bc1cf --- /dev/null +++ b/dom/media/test/test_seek_promise_bug1344357.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: bug 1344357</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> + +// This test always succeeds at runtime but should not cause any leaks at the end of mochitests. + +let manager = new MediaTestManager; + +function initTest(test, token) { + manager.started(token); + + var win = window.open(); + var video = win.document.createElement("video"); + video.autoplay = true; + video.src = "http://example.com/tests/dom/media/test/" + test.name; + win.document.body.appendChild(video); + video.currentTime = test.duration / 2; + video.addEventListener("seeking", () => { + win.close(); + manager.finished(token); + }, true); +} + +manager.runTests(gSmallTests, initTest); + +</script>
\ No newline at end of file diff --git a/dom/media/test/test_seekable1.html b/dom/media/test/test_seekable1.html new file mode 100644 index 0000000000..45c84b35df --- /dev/null +++ b/dom/media/test/test_seekable1.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test seekable member for media elements</title> +<script type="text/javascript" src="/MochiKit/MochiKit.js"></script> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +<script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id='test'> +<script class="testbody" type='application/javascript'> + +let manager = new MediaTestManager; + +function finish_test(element) { + if (element.parentNode) + element.remove(); + element.src=""; + manager.finished(element.token); +} + +var tests = [ +// Test using a finite media stream, and a server supporting range requests +{ +setup(element) { + is(element.seekable.length, 0, "seekable.length should be initialy 0."); + element.addEventListener("loadedmetadata", function() { + is(element.seekable.length, 1, "seekable.length should be 1 for a server supporting range requests."); + + is(element.seekable.start(0), 0.0, "The start of the first range should be the initialTime."); + is(element.seekable.end(0), element.duration, "The end of the first range should be the duration.") + finish_test(element); + }); + } +} +]; + +function createTestArray() { + var A = []; + for (var k=0; k < gProgressTests.length; k++) { + var t = {}; + t.setup = tests[0].setup; + t.name = gProgressTests[k].name; + t.type = gProgressTests[k].type; + A.push(t); + } + return A; +} + +function startTest(test, token) { + var elemType = getMajorMimeType(test.type); + var element = document.createElement(elemType); + element.preload = "auto"; + element.src = test.name; + element.token = token; + test.setup(element); + manager.started(token); +} + +manager.runTests(createTestArray(), startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_setSinkId_after_loop.html b/dom/media/test/test_setSinkId_after_loop.html new file mode 100644 index 0000000000..6224daa417 --- /dev/null +++ b/dom/media/test/test_setSinkId_after_loop.html @@ -0,0 +1,126 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test setSinkId() after looping</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<script type="application/javascript"> +"use strict"; + +/** +This test captures loopback device audio to test that a media element produces +audio output soon after a setSinkId() call after looping. In bug 1838756, +incorrect timekeeping caused silence in the output as long as the duration of +loops completed. + **/ +add_task(async () => { + const audio = new Audio(); + audio.src = "sin-441-1s-44100.flac"; + audio.loop = true; + audio.controls = true; + // Mute initially so that delayed audio from before setSinkId does not + // trigger a false pass. + audio.muted = true; + document.body.appendChild(audio); + const canplaythroughPromise = new Promise(r => audio.oncanplaythrough = r); + // Let the audio loop at least twice, which would result in 2 extra seconds + // of silence with bug 1838756. + let count = 0; + const loopedPromise = new Promise(r => audio.onseeked = () => { + if (++count == 2) { + r(); + } + }); + + await SpecialPowers.pushPrefEnv({set: [ + // skip gUM permission prompt + ["media.navigator.permission.disabled", true], + // enumerateDevices() without focus + ["media.devices.unfocused.enabled", true], + ]}); + let loopbackInputLabel = + SpecialPowers.getCharPref("media.audio_loopback_dev", ""); + if (!navigator.userAgent.includes("Linux")) { + todo_isnot(loopbackInputLabel, "", "audio_loopback_dev"); + return; + } + isnot(loopbackInputLabel, "", + "audio_loopback_dev. Try --use-test-media-devices."); + const loopbackStream = + await navigator.mediaDevices.getUserMedia({audio: true}); + is(loopbackStream.getTracks()[0].label, loopbackInputLabel, + "loopback track label"); + + await canplaythroughPromise; + let loopbackNode; + try { + audio.play(); + await new Promise(r => audio.onplaying = r); + const ac = new AudioContext; + loopbackNode = ac.createMediaStreamSource(loopbackStream); + const processor1 = ac.createScriptProcessor(4096, 1, 0); + loopbackNode.connect(processor1); + + // Check that the loopback stream contains silence now. + const {inputBuffer} = await new Promise(r => processor1.onaudioprocess = r); + loopbackNode.disconnect(); + is(inputBuffer.getChannelData(0).find(value => value != 0.0), undefined, + "should have silence"); + + // Find output device + const devices = await navigator.mediaDevices.enumerateDevices(); + let loopbackOutputLabel = + SpecialPowers.getCharPref("media.cubeb.output_device", ""); + const outputDeviceInfo = devices.find( + ({kind, label}) => kind == "audiooutput" && label == loopbackOutputLabel + ); + ok(outputDeviceInfo, `found ${loopbackOutputLabel}`); + + await loopedPromise; + await audio.setSinkId(outputDeviceInfo.deviceId); + audio.muted = false; + // Use a new ScriptProcessor so that the first audioprocess event provides + // the rendering thread time after unmuting. + const processor2 = ac.createScriptProcessor(4096, 1, 0); + loopbackNode.connect(processor2); + + let seenAudioCount = 0; + let lastSample, firstTime; + while (seenAudioCount < ac.sampleRate) { + const event = await new Promise(r => processor2.onaudioprocess = r); + let samples = event.inputBuffer.getChannelData(0); + for (const sample of samples) { + if (!seenAudioCount) { + if (!firstTime) { + firstTime = event.playbackTime; + } + if (sample != 0.0) { + seenAudioCount = 1; + } else { + const delay = event.playbackTime - firstTime; + if (delay > 1.0) { + ok(false, `${delay} seconds passed without receiving audio`); + return; + } + } + } else if (sample != 0.0) { + ++seenAudioCount; + } else if (lastSample == 0.0) { + ok(false, "should not have two consecutive zero sample in audio"); + return; + } + lastSample = sample; + } + } + ok(true, "have one continuous second of audio"); + } finally { + if (loopbackNode) { + loopbackNode.disconnect(); + } + audio.pause(); + loopbackStream.getTracks()[0].stop(); + } +}); +</script> +</html> diff --git a/dom/media/test/test_source.html b/dom/media/test/test_source.html new file mode 100644 index 0000000000..944e95b1df --- /dev/null +++ b/dom/media/test/test_source.html @@ -0,0 +1,91 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: append source child</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<video id="v1"></video> +<audio id="a1"></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var v1 = document.getElementById("v1"); +var a1 = document.getElementById("a1"); +v1.preload = "auto"; +a1.preload = "auto"; + +is(v1.src, "", "src should be null"); +is(a1.src, "", "src should be null"); +is(v1.currentSrc, "", "currentSrc should be null"); +is(a1.currentSrc, "", "currentSrc should be null"); +is(v1.childNodes.length, 0, "should have no children"); +is(a1.childNodes.length, 0, "should have no children"); + +function newSource(filter) { + var candidates = gSmallTests.filter(function(x){return filter.test(x.type);}); + if (candidates.length) { + var e = document.createElement("source"); + e.type = candidates[0].type; + e.src = candidates[0].name; + return e; + } + return null + +} + +var audioLoaded = false; +var videoLoaded = false; + +function loaded(e) { + var media = e.target; + ok(media.networkState > 0, "networkState should be > 0"); + is(media.childNodes.length, 1, "should have 1 child"); + var sourceFile = media.currentSrc.substring(media.currentSrc.lastIndexOf('/')+1); + var resource = media.firstChild.src.substring(media.firstChild.src.lastIndexOf('/')+1); + is(sourceFile, resource, "loaded wrong resource!"); + if (media == a1) + audioLoaded = true; + else if (media == v1) + videoLoaded = true; + if (audioLoaded && videoLoaded) { + SimpleTest.finish(); + } +} + +v1.addEventListener('loadeddata', loaded); +a1.addEventListener('loadeddata', loaded); + +var videoSource = newSource(/^video/); +if (videoSource) { + v1.appendChild(videoSource); + v1.load(); +} else { + // No video backends? Don't test anything. + videoLoaded = true; +} + +var audioSource = newSource(/^audio/); +if (audioSource) { + a1.appendChild(audioSource); + a1.load(); +} else { + audioLoaded = true; +} + +if (!audioLoaded && !videoLoaded) { + SimpleTest.waitForExplicitFinish(); +} else { + if (audioLoaded) { + todo(false, "No audio types supported"); + } + if (videoLoaded) { + todo(false, "No video types supported"); + } +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_source_null.html b/dom/media/test/test_source_null.html new file mode 100644 index 0000000000..485edafd2d --- /dev/null +++ b/dom/media/test/test_source_null.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=752087 +--> +<head> + <title>Test for Bug 752087</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=752087">Mozilla Bug 752087</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> + +<video id="v"> +<script> +var v = document.getElementById('v'); +v.src = null; // crashes on NULL access if not handled + +ok(true, "setting video.src to null didn't crash!"); +var srcPath = v.src.split('/'); +ok(srcPath.length >= 3, "src should be within dom/media/test"); +is(srcPath[srcPath.length - 1], "null", "Setting src to null is handled like 'null' string"); +</script> +</video> +</body> +</html> diff --git a/dom/media/test/test_source_write.html b/dom/media/test/test_source_write.html new file mode 100644 index 0000000000..29fffebd10 --- /dev/null +++ b/dom/media/test/test_source_write.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=462455 +--> +<head> + <title>Test for Bug 462455</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462455">Mozilla Bug 462455</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> + +<video id="v"> +<script> +var loadStarted = false; +document.write('Pause parsing!'); +var v = document.getElementById('v'); + +var resource = getPlayableVideo(gSmallTests); +if (resource != null) { + var s = document.createElement("source"); + s.src = resource.name; + s.type = resource.type; + v.appendChild(s); +} + +ok(v.networkState == HTMLMediaElement.NETWORK_NO_SOURCE, + "We shouldn't start network load until the current task returns."); +</script> +</video> +</body> +</html> diff --git a/dom/media/test/test_standalone.html b/dom/media/test/test_standalone.html new file mode 100644 index 0000000000..620878a394 --- /dev/null +++ b/dom/media/test/test_standalone.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: standalone video documents</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body onload="doTest()"> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var iframes = []; + +for (let i=0; i<gSmallTests.length; ++i) { + var test = gSmallTests[i]; + + // We can't play WAV files in stand alone documents, so just don't + // run the test on non-video content types. + var tag = getMajorMimeType(test.type); + if (tag != "video" || !document.createElement("video").canPlayType(test.type)) + continue; + + let f = document.createElement("iframe"); + f.src = test.name; + f._test = test; + f.id = "frame" + i; + iframes.push(f); + document.body.appendChild(f); +} + + +function filename(uri) { + return uri.substr(uri.lastIndexOf("/")+1); +} + +function doTest() +{ + for (let i=0; i<iframes.length; ++i) { + let f = document.getElementById(iframes[i].id); + var v = f.contentDocument.body.firstChild; + is(v.tagName.toLowerCase(), "video", "Is video element"); + var src = filename(v.currentSrc); + is(src, iframes[i]._test.name, "Name ("+src+") should match ("+iframes[i]._test.name+")"); + is(v.controls, true, "Controls set (" + src + ")"); + is(v.autoplay, true, "Autoplay set (" + src + ")"); + } + SimpleTest.finish(); +} + +if (!iframes.length) { + todo(false, "No types supported"); +} else { + SimpleTest.waitForExplicitFinish(); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_capture_origin.html b/dom/media/test/test_streams_capture_origin.html new file mode 100644 index 0000000000..13d5589c0d --- /dev/null +++ b/dom/media/test/test_streams_capture_origin.html @@ -0,0 +1,90 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 1189506</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1189506">Mozilla Bug 1189506</a> +<p id="display"></p> +<video id="vin"></video> +<video id="vout"></video> +<video id="vout_cors" crossorigin></video> +<canvas id="cin" width="40" height="30"></canvas> +<canvas id="cout" width="40" height="30"></canvas> +<canvas id="cout_cors" width="40" height="30"></canvas> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> +/* global vin, vout, vout_cors, cin, cout, cout_cors */ + +/** Test for Bug 1189506 **/ + +SimpleTest.waitForExplicitFinish(); + +async function start() { + const resource = getPlayableVideo(gSmallTests).name; + vin.src = "http://example.org:8000/tests/dom/media/test/" + resource; + vin.preload = "metadata"; + + await new Promise(r => vin.onloadedmetadata = r); + vout.srcObject = vin.mozCaptureStreamUntilEnded(); + vout_cors.srcObject = vin.mozCaptureStreamUntilEnded(); + vin.play(); + vout.play(); + vout_cors.play(); + + await new Promise(r => vout.onended = r); + is(vin.ended, vout.ended, "Source media element ends first"); + + const ctxin = SpecialPowers.wrap(cin.getContext("2d")); + ctxin.drawImage(vin, 0, 0); + + { + info("Testing that the last frame is rendered"); + const powerCtx = SpecialPowers.wrap(cout.getContext("2d")); + powerCtx.drawImage(vout, 0, 0); + const datain = ctxin.getImageData(0, 0, cin.width, cin.height); + const dataout = powerCtx.getImageData(0, 0, cout.width, cout.height); + for (let i = 0; i < datain.data.length; i += 4) { + const pixelin = datain.data.slice(i, i + 4).join(','); + const pixelout = dataout.data.slice(i, i + 4).join(','); + if (pixelin != pixelout) { + is(pixelout, pixelin, `Pixel #${i/4} is rendered as expected`); + break; + } + } + is(datain.data.length / 4, cin.width * cin.height, + "Checked expected number of pixels"); + } + + { + info("Testing that the principal is set"); + const ctx = cout.getContext("2d"); + ctx.drawImage(vout, 0, 0); + SimpleTest.doesThrow(() => ctx.getImageData(0, 0, cout.width, cout.height), + "SecurityError"); + } + + { + info("Testing that the crossorigin attribute is ignored for MediaStreams"); + const ctx = cout_cors.getContext("2d"); + ctx.drawImage(vout_cors, 0, 0); + SimpleTest.doesThrow( + () => ctx.getImageData(0, 0, cout_cors.width, cout_cors.height), + "SecurityError"); + } +} + +(async () => { + try { await start(); } + catch(e) { ok(false, `Rejected with ${e}`); } + finally { SimpleTest.finish(); } +})(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_element_capture.html b/dom/media/test/test_streams_element_capture.html new file mode 100644 index 0000000000..098136dba7 --- /dev/null +++ b/dom/media/test/test_streams_element_capture.html @@ -0,0 +1,125 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that a MediaStream captured from one element plays back in another</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +const manager = new MediaTestManager(); + +function checkDrawImage(vout, msg) { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + ctx.drawImage(vout, 0, 0); + const imgData = ctx.getImageData(0, 0, 1, 1); + is(imgData.data[3], 255, msg); +} + +function maybeTodoGreaterThanOrEqual(a, b, msg) { + const isExpected = a >= b; + (isExpected ? ok : todo)( + isExpected, + `Got ${a}, expected at least ${b}; ${msg}` + ); +} + +async function startTest(test, token) { + manager.started(token); + const v = document.createElement('video'); + const vout = document.createElement('video'); + + v.token = token; + v.id = "MediaDecoder"; + vout.id = "MediaStream"; + + document.body.appendChild(vout); + + // Log events for debugging. + const events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", + "waiting", "pause"]; + function logEvent(e) { + Log(token, `${e.target.id} got ${e.type}`); + } + for (const e of events) { + v.addEventListener(e, logEvent); + vout.addEventListener(e, logEvent); + }; + + v.src = test.name; + v.preload = 'metadata'; + await new Promise(r => v.onloadedmetadata = r); + + const stream = v.mozCaptureStreamUntilEnded(); + vout.srcObject = stream; + is(vout.srcObject, stream, + `${token} set output element .srcObject correctly`); + + isnot(stream.getTracks().length, 0, `${token} results in some tracks`); + const hadVideoTracks = stream.getVideoTracks().length >= 1; + // Wait for the resource fetch algorithm to have run, so that the media + // element is hooked up to the MediaStream and ready to go. If we don't do + // this, we're not guaranteed to render the very first video frame, which + // can make this test fail the drawImage test when a video resource only + // contains one frame. + await new Promise(r => vout.onloadstart = r); + v.play(); + vout.play(); + + await Promise.race([ + Promise.all([ + new Promise(r => vout.onended = r), + new Promise(r => v.onended = r), + ]), + new Promise((res, rej) => vout.onerror = () => rej(new Error(vout.error.message))), + new Promise((res, rej) => v.onerror = () => rej(new Error(v.error.message))), + ]); + + let duration = test.duration; + if (typeof(test.contentDuration) == "number") { + duration = test.contentDuration; + } + if (duration) { + // Unexpected results are tracked in bug 1839502 + maybeTodoGreaterThanOrEqual(vout.currentTime, duration, + `${token} current time at end`); + } + is(vout.readyState, vout.HAVE_CURRENT_DATA, + `${token} checking readyState`); + ok(vout.ended, `${token} checking playback has ended`); + if (hadVideoTracks) { + ok(test.type.match(/^video/), `${token} is a video resource`); + checkDrawImage(vout, `${token} checking video frame pixel has been drawn`); + } + vout.remove(); + removeNodeAndSource(v); +} + +(async () => { + SimpleTest.requestCompleteLog(); + SimpleTest.waitForExplicitFinish(); + await SpecialPowers.pushPrefEnv( + { "set": [ + ["privacy.reduceTimerPrecision", false], + ]}); + let tests = gPlayTests; + // Filter out bug1377278.webm due to bug 1541401. + tests = tests.filter(t => !t.name.includes("1377278")); + + manager.runTests(tests, async (test, token) => { + try { + await startTest(test, token); + } catch(e) { + ok(false, `Caught exception for ${token}: ${e}`); + } + manager.finished(token); + }); +})(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_element_capture_mediatrack.html b/dom/media/test/test_streams_element_capture_mediatrack.html new file mode 100644 index 0000000000..6b4332d8af --- /dev/null +++ b/dom/media/test/test_streams_element_capture_mediatrack.html @@ -0,0 +1,100 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that a media element captureStream works when disabling MediaTracks</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +const manager = new MediaTestManager(); + +async function startTest(test, token) { + manager.started(token); + const v = document.createElement('video'); + + document.body.appendChild(v); + v.token = token; + v.id = "MediaDecoder"; + + // Log events for debugging. + const events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", + "waiting", "pause"]; + function logEvent(e) { + Log(token, `${token}: ${e.target.id} got ${e.type}`); + } + for (const e of events) { + v.addEventListener(e, logEvent); + }; + + v.src = test.name; + v.preload = 'metadata'; + await new Promise(r => v.onloadedmetadata = r); + + const stream = v.mozCaptureStream(); + + is(stream.getAudioTracks().length, Math.min(1, v.audioTracks.length), + `${token}: Expected number of audio tracks`); + is(stream.getVideoTracks().length, Math.min(1, v.videoTracks.length), + `${token}: Expected number of video tracks`); + + if (v.audioTracks.length) { + v.audioTracks[0].enabled = false; + const track = stream.getAudioTracks()[0]; + await new Promise(r => track.onended = r); + is(track.readyState, "ended", `${token}: Audio track has ended on removal`); + await new Promise(r => stream.onremovetrack = r); + is(stream.getAudioTracks().length, 0, + `${token}: Audio track was removed on removetrack`); + } + + if (v.videoTracks.length) { + v.videoTracks[0].selected = false; + const track = stream.getVideoTracks()[0]; + await new Promise(r => track.onended = r); + is(track.readyState, "ended", `${token}: Video track has ended on removal`); + await new Promise(r => stream.onremovetrack = r); + is(stream.getVideoTracks().length, 0, + `${token}: Video track was removed on removetrack`); + } + + stream.onaddtrack = () => ok(false, "Unexpected addtrack event"); + + v.play(); + + await Promise.race([ + new Promise(r => v.ontimeupdate = r), + new Promise((res, rej) => v.onerror = () => rej(new Error(v.error.message))), + ]); + + is(stream.getTracks().length, 0, `${token}: no tracks appeared during playback`); + removeNodeAndSource(v); +} + +(async () => { + SimpleTest.requestCompleteLog(); + SimpleTest.waitForExplicitFinish(); + await SpecialPowers.pushPrefEnv( + { "set": [ + ["media.track.enabled", true], + ]}); + let tests = gPlayTests; + // Filter out bug1377278.webm due to bug 1541401. + tests = tests.filter(t => !t.name.includes("1377278")); + + manager.runTests(tests, async (test, token) => { + try { + await startTest(test, token); + } catch(e) { + ok(false, `Caught exception for ${token}: ${e}`); + } + manager.finished(token); + }); +})(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_element_capture_playback.html b/dom/media/test/test_streams_element_capture_playback.html new file mode 100644 index 0000000000..ce083069ef --- /dev/null +++ b/dom/media/test/test_streams_element_capture_playback.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that capturing a stream doesn't stop the underlying element from firing events</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<audio id="a"></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var a = document.getElementById('a'); +var validTimeUpdate = false; + +function startTest() { + a.src = "big.wav"; + var context = new AudioContext(); + var node = context.createMediaElementSource(a); + node.connect(context.destination); + a.addEventListener("timeupdate", function() { + if (a.currentTime > 0.0 && a.currentTime < 5.0 && !validTimeUpdate) { + validTimeUpdate = true; + ok(true, "Received reasonable currentTime in a timeupdate"); + SimpleTest.finish(); + } + }); + a.addEventListener("ended", function() { + if (!validTimeUpdate) { + ok(false, "Received reasonable currentTime in a timeupdate"); + SimpleTest.finish(); + } + }); + a.play(); +} + +if (a.canPlayType("audio/wave")) { + startTest(); +} else { + todo(false, "No playable audio"); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_element_capture_reset.html b/dom/media/test/test_streams_element_capture_reset.html new file mode 100644 index 0000000000..625b0fe23f --- /dev/null +++ b/dom/media/test/test_streams_element_capture_reset.html @@ -0,0 +1,174 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that reloading, pausing and seeking in a media element that's being captured behaves as expected</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script src="manifest.js"></script> +</head> +<body> +<video id="v"></video> +<video id="vout"></video> +<video id="vout_untilended"></video> +<pre id="test"> +<script> +const v = document.getElementById('v'); +const vout = document.getElementById('vout'); +const vout_untilended = document.getElementById('vout_untilended'); + +function dumpEvent(event) { + const video = event.target; + info( + `${video.name}:${video.id} GOT EVENT ${event.type} ` + + `currentTime=${video.currentTime} paused=${video.paused} ` + + `ended=${video.ended} readyState=${video.readyState}` + ); +} + +function unexpected(event) { + ok(false, `${event.type} event received on ${event.target.id} unexpectedly`); +}; + +const events = ["timeupdate", "seeking", "seeked", "ended", "playing", "pause"]; +for (const e of events) { + v.addEventListener(e, dumpEvent); + vout.addEventListener(e, dumpEvent); + vout_untilended.addEventListener(e, dumpEvent); +} + +function isWithinEps(a, b, msg) { + ok(Math.abs(a - b) < 0.01, + "Got " + a + ", expected " + b + "; " + msg); +} + +function isGreaterThanOrEqualEps(a, b, msg) { + ok(a >= b - 0.01, + "Got " + a + ", expected at least " + b + "; " + msg); +} + +async function startTest(test) { + const seekTime = test.duration/2; + const contentDuration = test.contentDuration ?? test.duration; + + v.src = test.name; + v.name = test.name; + vout.name = test.name; + vout_untilended.name = test.name; + v.preload = "metadata"; + await new Promise(r => v.onloadedmetadata = r); + + vout.srcObject = v.mozCaptureStream(); + vout.play(); + + vout_untilended.srcObject = v.mozCaptureStreamUntilEnded(); + vout_untilended.play(); + + for (const track of [ + ...vout.srcObject.getTracks(), + ...vout_untilended.srcObject.getTracks(), + ]) { + ok(track.muted, `${track.kind} track ${track.id} should be muted`); + } + + v.play(); + + await Promise.all([ + ...vout.srcObject.getTracks(), + ...vout_untilended.srcObject.getTracks() + ].map(t => new Promise(r => t.onunmute = r))); + + await new Promise(r => v.onended = r); + isGreaterThanOrEqualEps(v.currentTime, test.duration, + "checking v.currentTime at first 'ended' event"); + + await Promise.all([ + new Promise(r => vout.onended = r), + new Promise(r => vout_untilended.onended = r), + ]); + + isGreaterThanOrEqualEps(vout.currentTime, contentDuration, + "checking vout.currentTime at first 'ended' event"); + ok(vout.ended, "checking vout has actually ended"); + ok(vout_untilended.ended, "checking vout_untilended has actually ended"); + + vout_untilended.srcObject.onaddtrack = unexpected; + vout_untilended.onplaying = unexpected; + vout_untilended.onended = unexpected; + + const voutPreSeekCurrentTime = vout.currentTime; + v.currentTime = seekTime; + await new Promise(r => v.onseeked = r); + + is(v.currentTime, seekTime, "Finished seeking"); + is(vout.currentTime, voutPreSeekCurrentTime, + "checking vout.currentTime has not changed after seeking"); + + v.play(); + vout.play(); + + await new Promise(r => v.onended = r); + isGreaterThanOrEqualEps(v.currentTime, test.duration, + "checking v.currentTime at second 'ended' event"); + + await new Promise(r => vout.onended = r); + isGreaterThanOrEqualEps(vout.currentTime, + (test.duration - seekTime) + contentDuration, + "checking vout.currentTime after seeking and playing through again"); + + v.src = test.name + "?1"; + vout.play(); + await v.play(); + + isnot(vout.srcObject.getTracks().length, 0, "There are some output tracks"); + + vout.onended = unexpected; + vout.srcObject.onremovetrack = unexpected; + + v.pause(); + await Promise.all( + vout.srcObject.getTracks().map(t => new Promise(r => t.onmute = r)) + ); + + for (const track of vout.srcObject.getTracks()) { + track.onunmute = unexpected; + } + + v.currentTime = 0; + await new Promise(r => v.onseeked = r); + + v.play(); + await Promise.all( + vout.srcObject.getTracks().map(t => new Promise(r => t.onunmute = r)) + ); + + vout.srcObject.onremovetrack = null; + + await new Promise(r => v.onended = r); + isGreaterThanOrEqualEps(v.currentTime, test.duration, + "checking v.currentTime at third 'ended' event"); + + await new Promise(r => vout.onended = r); + isGreaterThanOrEqualEps(vout.currentTime, + (test.duration - seekTime) + contentDuration*2, + "checking vout.currentTime after seeking, playing through and reloading"); +} + +(async () => { + SimpleTest.waitForExplicitFinish(); + try { + const testVideo = getPlayableVideo(gSmallTests); + if (testVideo) { + await startTest(testVideo); + } else { + todo(false, "No playable video"); + } + } catch(e) { + ok(false, `Error: ${e}`); + } finally { + SimpleTest.finish(); + } +})(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_element_capture_twice.html b/dom/media/test/test_streams_element_capture_twice.html new file mode 100644 index 0000000000..0e30be1801 --- /dev/null +++ b/dom/media/test/test_streams_element_capture_twice.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that capturing a media element, then reloading and capturing again, works</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<video id="v"></video> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +const v = document.getElementById('v'); + +function dumpEvent(event) { + const video = event.target; + info(video.name + " GOT EVENT " + event.type + + " currentTime=" + video.currentTime + + " paused=" + video.paused + + " ended=" + video.ended + + " readyState=" + video.readyState); +} + +const events = ["timeupdate", "seeking", "seeked", "ended", "playing", "pause"]; +for (let i = 0; i < events.length; ++i) { + v.addEventListener(events[i], dumpEvent); +} + +async function startTest(src) { + v.preload = "metadata"; + v.src = src; + await new Promise(r => v.onloadedmetadata = r); + const s1 = v.mozCaptureStream(); + const tracks = s1.getTracks(); + is(tracks.length, 2, "Expected total tracks, s1, capture 1"); + is(s1.getAudioTracks().length, 1, "Expected audio tracks, s1, capture 1"); + is(s1.getVideoTracks().length, 1, "Expected video tracks, s1, capture 1"); + is(s1.getAudioTracks()[0].readyState, "live", "Live audio, s1, capture 1"); + is(s1.getVideoTracks()[0].readyState, "live", "Live video, s1, capture 1"); + + v.src = null; + for (let i = 0; i < tracks.length; ++i) { + await Promise.race(tracks.map(t => new Promise(r => t.onended = r))); + await new Promise(r => s1.onremovetrack = r); + } + is(s1.getTracks().length, 0, "Expected total tracks, s1, metadata 2"); + + v.src = src; + await new Promise(r => v.onloadedmetadata = r); + is(s1.getTracks().length, 2, "Expected total tracks, s1, metadata 2"); + is(s1.getAudioTracks().length, 1, "Expected audio tracks, s1, metadata 2"); + is(s1.getVideoTracks().length, 1, "Expected video tracks, s1, metadata 2"); + is(s1.getAudioTracks()[0].readyState, "live", "Live audio, s1, metadata 2"); + is(s1.getVideoTracks()[0].readyState, "live", "Live video, s1, metadata 2"); + + const s2 = v.mozCaptureStream(); + is(s1.getTracks().length, 2, "Expected total tracks remains, s1, capture 2"); + is(s2.getTracks().length, 2, "Expected total tracks, s2, capture 2"); + is(s2.getAudioTracks().length, 1, "Expected audio tracks, s2, capture 2"); + is(s2.getVideoTracks().length, 1, "Expected video tracks, s2, capture 2"); + is(s2.getAudioTracks()[0].readyState, "live", "Live audio, s2, capture 2"); + is(s2.getVideoTracks()[0].readyState, "live", "Live video, s2, capture 2"); +} + +(async function() { + try { + await startTest("short-video.ogv"); + } catch(e) { + ok(false, `Caught error: ${e}${e.stack ? '\n' + e.stack : ''}`); + } finally { + SimpleTest.finish(); + } +})(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_firstframe.html b/dom/media/test/test_streams_firstframe.html new file mode 100644 index 0000000000..ea1dbd35c1 --- /dev/null +++ b/dom/media/test/test_streams_firstframe.html @@ -0,0 +1,67 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that a non-autoplaying, non-playing element with a MediaStream source triggers canplay and shows a first frame</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <script src="/tests/dom/canvas/test/captureStream_common.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +async function runTest() { + const canvas = document.createElement("canvas"); + canvas.getContext("2d"); + const helper = new CaptureStreamTestHelper2D(100, 100); + + const video = document.createElement("video"); + document.body.appendChild(video); + + video.srcObject = canvas.captureStream(); + helper.drawColor(canvas, helper.red); + + await Promise.race([ + new Promise(r => video.oncanplay = r), + new Promise(r => setTimeout(r, 30000)) + .then(() => Promise.reject(new Error("Canplay timeout"))), + ]); + + ok(true, "Got \"canplay\""); + is(video.readyState, video.HAVE_ENOUGH_DATA, "Expected readyState"); + ok(helper.isPixel(helper.getPixel(video), helper.red), + "First frame is rendered before playing"); + + helper.drawColor(canvas, helper.green); + await helper.pixelMustNotBecome(video, helper.green, { + time: 1000, + infoString: "Rendered first frame doesn't change on new frame from source" + }); + ok(helper.isPixel(helper.getPixel(video), helper.red), + "First frame is still rendered"); + + video.play(); + helper.drawColor(canvas, helper.blue); + await helper.pixelMustBecome(video, helper.blue, { + infoString: "New frame gets rendered when playing" + }); + + video.srcObject.getTracks().forEach(t => t.stop()); +} + +(async function() { + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("Explicit timeout reasons"); + try { + await runTest(); + } catch(e) { + ok(false, e); + } + SimpleTest.finish(); +})(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_gc.html b/dom/media/test/test_streams_gc.html new file mode 100644 index 0000000000..d2ba23042b --- /dev/null +++ b/dom/media/test/test_streams_gc.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test garbage collection of captured stream (bug 806754)</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body onload="doTest()">
+<audio id="a" preload="metadata"></audio>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+var a = document.getElementById('a');
+a.src = getPlayableAudio(gSmallTests).name;
+
+function forceGC() {
+ SpecialPowers.gc();
+ SpecialPowers.forceGC();
+ SpecialPowers.forceCC();
+}
+
+function doTest() {
+ a.mozCaptureStreamUntilEnded();
+
+ a.addEventListener("seeked", function() {
+ a.play();
+
+ a.addEventListener("play", function() {
+ a.addEventListener("ended", function() {
+ ok(true, "GC completed OK");
+ SimpleTest.finish();
+ });
+ });
+ });
+
+ a.currentTime = a.duration;
+ setTimeout(forceGC, 0);
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/media/test/test_streams_individual_pause.html b/dom/media/test/test_streams_individual_pause.html new file mode 100644 index 0000000000..c49b563d76 --- /dev/null +++ b/dom/media/test/test_streams_individual_pause.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for bug 1073406. Pausing a video element should not pause another playing the same stream.</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> + <script type="text/javascript" src="gUM_support.js"></script> +</head> +<body> +<video id="video1" autoplay></video> +<video id="video2" autoplay></video> +<script class="testbody" type="text/javascript"> +function getVideoImagePixelData(v) { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + ctx.drawImage(v, 0, 0); + const imgData = ctx.getImageData(canvas.width/2, canvas.height/2, 1, 1).data; + return "r" + imgData[0] + + "g" + imgData[1] + + "b" + imgData[2] + + "a" + imgData[3]; +} + +async function startTest() { + // This test expects fake devices so that the video color will change + // over time, explicitly request fakes. + await pushGetUserMediaTestPrefs({fakeAudio: true, fakeVideo: true}); + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + const video1 = document.getElementById('video1'); + const video2 = document.getElementById('video2'); + + video1.srcObject = stream; + video2.srcObject = stream; + + await new Promise(r => video1.onplaying = r); + video1.pause(); + await new Promise(r => video1.onpause = r); + + const v1PausedImageData = getVideoImagePixelData(video1); + const v2PausedImageData = getVideoImagePixelData(video2); + + while (getVideoImagePixelData(video2) == v2PausedImageData) { + info("video2 has not progressed. Waiting."); + await new Promise(r => video2.ontimeupdate = r); + } + + // Wait for a while to be sure video1 would have gotten a frame + // if it is playing. + for (let i = 3; i != 0; i--) { + await new Promise(r => video2.ontimeupdate = r); + } + info("video2 progressed OK"); + + isnot(video1.currentTime, video2.currentTime, + "v1 and v2 should not be at the same currentTime"); + is(getVideoImagePixelData(video1), v1PausedImageData, + "video1 video frame should not have updated since video1 paused"); + + for (const t of stream.getTracks()) { + t.stop(); + } +} + +SimpleTest.waitForExplicitFinish(); +(async function() { + try { + await startTest(); + } catch(error) { + ok(false, "getUserMedia should not fail, got " + error.name); + } finally { + SimpleTest.finish(); + } +})(); +</script> +</body> +</html> diff --git a/dom/media/test/test_streams_srcObject.html b/dom/media/test/test_streams_srcObject.html new file mode 100644 index 0000000000..8ea5797d14 --- /dev/null +++ b/dom/media/test/test_streams_srcObject.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test interactions of src and srcObject</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body onload="doTests()"> +<audio id="a1"></audio> +<audio id="a2"></audio> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var doTest = srcObject => new Promise(resolve => { + var a = document.getElementById('a1'); + a.src = getPlayableAudio(gSmallTests).name; + var b = new Audio(); + + var newSrc = a.src + "?2"; + b.src = newSrc; + is(b[srcObject], null, "Initial srcObject is null"); + var stream = a.mozCaptureStream(); + b[srcObject] = stream; + is(b[srcObject], stream, "Stream set correctly"); + try { + b[srcObject] = "invalid"; + ok(false, "Setting srcObject to an invalid value should throw."); + } catch (e) { + ok(e instanceof TypeError, "Exception should be a TypeError"); + } + is(b[srcObject], stream, "Stream not set to invalid value"); + is(b.src, newSrc, "src attribute not affected by setting srcObject"); + var step = 0; + b.addEventListener("loadedmetadata", function() { + if (step == 0) { + is(b.currentSrc, "", "currentSrc set to empty string while playing srcObject"); + b[srcObject] = null; + is(b[srcObject], null, "Stream set to null"); + // The resource selection algorithm will run again and choose b.src + } else if (step == 1) { + is(b.currentSrc, b.src, "currentSrc set to src now that srcObject is null"); + resolve(); + } + ++step; + }); + a.play(); + b.play(); +}); + +var doTests = () => doTest("srcObject") + .catch(e => ok(false, "Unexpected error: " + e)) + .then(() => SimpleTest.finish()) + .catch(e => ok(false, "Coding error: " + e)); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_streams_tracks.html b/dom/media/test/test_streams_tracks.html new file mode 100644 index 0000000000..845bc36ca3 --- /dev/null +++ b/dom/media/test/test_streams_tracks.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaStreamTrack interfaces</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +const manager = new MediaTestManager; + +function testTracks(tracks, hasTrack, kind, src) { + is(tracks.length, hasTrack ? 1 : 0, `Correct ${kind} track count for ${src}`); + for (const track of tracks) { + is(track.readyState, "live", `Track ${track.id} should still be live`); + is(track.kind, kind, `Correct track kind for track ${track.id} of ${src}`); + ok(/\{........-....-....-....-............\}/.test(track.id), + `id ${track.id} for ${track.kind} track of ${src} has correct form`); + } +} + +async function startTest(test, token) { + try { + info(`Starting test of ${test.name}`); + const element = document.createElement("video"); + + element.token = token; + manager.started(token); + + element.src = test.name; + element.test = test; + const stream = element.mozCaptureStreamUntilEnded(); + + element.play(); + + await new Promise(r => element.onloadedmetadata = r); + + testTracks(stream.getAudioTracks(), test.hasAudio, "audio", test.name); + testTracks(stream.getVideoTracks(), test.hasVideo, "video", test.name); + const tracks = stream.getTracks(); + + await new Promise(r => element.onended = r); + + for (let i = 0; i < tracks.length; ++i) { + await Promise.race( + tracks.map(t => new Promise(r => t.onended = r)) + ); + await new Promise(r => stream.onremovetrack = r); + } + + testTracks(stream.getAudioTracks(), false, "audio", test.name); + testTracks(stream.getVideoTracks(), false, "video", test.name); + } catch(e) { + ok(false, `Caught error: ${e}`); + } finally { + manager.finished(token); + } +} + +manager.runTests(gTrackTests, startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_suspend_media_by_inactive_docshell.html b/dom/media/test/test_suspend_media_by_inactive_docshell.html new file mode 100644 index 0000000000..7af2b63a3a --- /dev/null +++ b/dom/media/test/test_suspend_media_by_inactive_docshell.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test suspending media by inactive docShell</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="testVideo" src="gizmo.mp4" loop></video> +<script class="testbody" type="text/javascript"> +/** + * When calling `browser.suspendMediaWhenInactive`, it can set the docShell's + * corresponding flag that is used to suspend media when the docShell is + * inactive. This test is used to check if we can suspend/resume the media + * correctly when changing docShell's active state. + */ +async function startTest() { + const video = document.getElementById("testVideo"); + + info(`start video`); + await video.play(); + + info(`set docShell inactive which would suspend media`); + await setDocShellActive(false); + + info(`set docShell active which would resume media`); + await setDocShellActive(true); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + {"set": [["media.testing-only-events", true]]}, startTest); + +/** + * The following are test helper functions. + */ +function mediaSuspendedStateShouldEqualTo(expected) { + const video = document.getElementById("testVideo"); + const result = SpecialPowers.wrap(video).isSuspendedByInactiveDocOrDocShell; + is(result, expected, `media's suspended state is correct`); +} + +function setDocShellActive(isActive) { + const win = SpecialPowers.wrap(window); + const docShell = win.docShell; + let p = new Promise(r => { + docShell.chromeEventHandler.addEventListener("MozMediaSuspendChanged", + () => { + mediaSuspendedStateShouldEqualTo(!isActive); + r(); + }, {once : true} + ); + }); + + SpecialPowers.spawnChrome([isActive], active => { + // This flag is used to prevent media from playing when docShell is + // inactive. After updating `docshell.isActive`, it would suspend/resume + // media and we // wait suspending/resuming finishing by listening to + // `MozMediaSuspendChanged`. + this.browsingContext.top.suspendMediaWhenInactive = true; + this.browsingContext.top.isActive = active; + }); + + return p; +} + +</script> +</body> +</html> diff --git a/dom/media/test/test_temporary_file_blob_video_plays.html b/dom/media/test/test_temporary_file_blob_video_plays.html new file mode 100644 index 0000000000..87f6b3c4e6 --- /dev/null +++ b/dom/media/test/test_temporary_file_blob_video_plays.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test MediaRecorder Recording canvas stream</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/dom/canvas/test/captureStream_common.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<div id="content"> +</div> +<script class="testbody" type="text/javascript"> + +function startTest() { + var canvas = document.createElement("canvas"); + canvas.width = canvas.height = 100; + document.getElementById("content").appendChild(canvas); + + var helper = new CaptureStreamTestHelper2D(100, 100); + helper.drawColor(canvas, helper.red); + + var stream = canvas.captureStream(0); + + var blob; + + let mediaRecorder = new MediaRecorder(stream); + is(mediaRecorder.stream, stream, + "Media recorder stream = canvas stream at the start of recording"); + + mediaRecorder.onwarning = () => ok(false, "warning unexpectedly fired"); + + mediaRecorder.onerror = () => ok(false, "Recording failed"); + + mediaRecorder.ondataavailable = ev => { + is(blob, undefined, "Should only get one dataavailable event"); + blob = ev.data; + }; + + mediaRecorder.onstart = () => { + info("Got 'start' event"); + // We just want one frame encoded, to see that the recorder produces something readable. + mediaRecorder.stop(); + }; + + mediaRecorder.onstop = () => { + info("Got 'stop' event"); + ok(blob, "Should have gotten a data blob"); + + var video = document.createElement("video"); + video.id = "recorded-video"; + video.src = URL.createObjectURL(blob); + video.play(); + video.onerror = err => { + ok(false, "Should be able to play the recording. Got error. code=" + video.error.code); + SimpleTest.finish(); + }; + document.getElementById("content").appendChild(video); + helper.pixelMustBecome(video, helper.red, { + threshold: 128, + infoString: "Should become red", + }).then(SimpleTest.finish); + }; + + mediaRecorder.start(); + is(mediaRecorder.state, "recording", "Media recorder should be recording"); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({set:[["media.recorder.max_memory", 1]]}, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_timeupdate_small_files.html b/dom/media/test/test_timeupdate_small_files.html new file mode 100644 index 0000000000..fca35e5b71 --- /dev/null +++ b/dom/media/test/test_timeupdate_small_files.html @@ -0,0 +1,88 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=495319 +--> + +<head> + <title>Bug 495319 - playing back small audio files should fire timeupdate</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=495319">Mozilla Bug 495319</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function ended(e) { + var v = e.target; + ++v.counter.ended; + is(v.counter.ended, 1, v._name + " should see ended only once"); + ok(v.counter.timeupdate > 0, v._name + " should see at least one timeupdate: " + v.currentTime); + + // Rest event counters for we don't allow events after ended. + eventsToLog.forEach(function(event) { + v.counter[event] = 0; + }); + + // Finish the test after 500ms. We shouldn't receive any timeupdate events + // after the ended event, so this gives time for any pending timeupdate events + // to fire so we can ensure we don't regress behaviour. + setTimeout( + function() { + // Remove the event listeners before removing the video from the document. + // We should receive a timeupdate and pause event when we remove the element + // from the document (as the element is specified to behave as if pause() was + // invoked when it's removed from a document), and we don't want those + // confusing the test results. + v.removeEventListener("ended", ended); + eventsToLog.forEach(function(event) { + v.removeEventListener(event, logEvent); + }); + removeNodeAndSource(v); + manager.finished(v.token); + }, + 500); +} + +var eventsToLog = ["play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", + "loadeddata", "playing", "timeupdate", "error", "stalled", "emptied", "abort", + "waiting", "pause"]; + +function logEvent(event) { + var v = event.target; + ++v.counter[event.type]; + if (v.counter.ended > 0) { + is(v.counter[event.type], 0, v._name + " got unexpected " + event.type + " after ended"); + } +} + +function startTest(test, token) { + var type = getMajorMimeType(test.type); + var v = document.createElement(type); + v.token = token; + manager.started(token); + v.src = test.name; + v._name = test.name; + + // Keep how many events received for each event type. + v.counter = {}; + eventsToLog.forEach(function(e) { + v.addEventListener(e, logEvent); + v.counter[e] = 0; + }); + v.addEventListener("ended", ended); + v.counter.ended = 0; + document.body.appendChild(v); + v.play(); +} + +manager.runTests(gSmallTests, startTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_unseekable.html b/dom/media/test/test_unseekable.html new file mode 100644 index 0000000000..52c7eccc50 --- /dev/null +++ b/dom/media/test/test_unseekable.html @@ -0,0 +1,101 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: unseekable</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/* + +Test that unseekable media can't be seeked. We load a media that shouldn't +be seekable, and play through once. While playing through we repeatedly try +to seek and check that nothing happens when we do. We also verify that the +seekable ranges are empty. + +*/ + +var manager = new MediaTestManager; + +var onseeking = function(event) { + var v = event.target; + v.actuallySeeked = true; +}; + +var onseeked = function(event) { + var v = event.target; + v.actuallySeeked = true; +}; + +var ontimeupdate = function(event) { + var v = event.target; + + // Check that when we seek nothing happens. + var t = v.currentTime; + v.currentTime = v.currentTime /= 2; + ok(Math.abs(t - v.currentTime) < 0.01, "Current time shouldn't change when seeking in unseekable media: " + v.name); + + // Check that the seekable ranges are empty. + is(v.seekable.length, 0, "Should have no seekable ranges in unseekable media: " + v.name); +}; + +var onended = function(event) { + var v = event.target; + + // Remove the event listeners so that they can't run if there are any pending + // events. + v.removeEventListener("seeking", onseeking); + v.removeEventListener("seeked", onseeked); + v.removeEventListener("timeupdate", ontimeupdate); + v.removeEventListener("ended", onended); + + v.src = ""; + if (v.parentNode) { + v.remove(); + } + + // Verify that none of the seeks we did in timeupdate actually seeked. + ok(!v.actuallySeeked, "Should not be able to seek in unseekable media: " + v.name); + + manager.finished(v.token); +} + +function startTest(test, token) { + var v = document.createElement('video'); + manager.started(token); + v.name = test.name; + v.src = test.name; + v.token = token; + v.autoplay = "true"; + + v.actuallySeeked = false; + + v.addEventListener("seeking", onseeking); + v.addEventListener("seeked", onseeked); + v.addEventListener("timeupdate", ontimeupdate); + v.addEventListener("ended", onended); + + document.body.appendChild(v); +} + +function canPlay(candidates) { + var v = document.createElement("video"); + var resources = candidates.filter(function(x){return v.canPlayType(x.type);}); + return (resources.length); +} + +if (canPlay(gUnseekableTests)) { + manager.runTests(gUnseekableTests, startTest); +} else { + todo(false, "No files of supported format to test"); +} + + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_videoDocumentTitle.html b/dom/media/test/test_videoDocumentTitle.html new file mode 100644 index 0000000000..dd52dba26c --- /dev/null +++ b/dom/media/test/test_videoDocumentTitle.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=463830 +--> +<head> + <title>Test for Bug 463830</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=463830">Mozilla Bug 463830</a> +<p id="display"></p> +<iframe id="i"></iframe> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 463830 **/ + +var gTests = [ + { file: "320x240.ogv", title: "320x240.ogv" }, + { file: "bug461281.ogg", title: "bug461281.ogg" }, +]; + +var gTestNum = 0; + +addLoadEvent(runTest); + +var title; +var i = document.getElementById("i"); + +function runTest() { + if (gTestNum == gTests.length) { + SimpleTest.finish(); + return; + } + if (gTestNum == 0) { + i.addEventListener("load", function() { + is(i.contentDocument.title, title, "Doc title incorrect"); + setTimeout(runTest, 0); + }); + } + + title = gTests[gTestNum].title; + i.src = gTests[gTestNum].file; + gTestNum++; +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_videoPlaybackQuality_totalFrames.html b/dom/media/test/test_videoPlaybackQuality_totalFrames.html new file mode 100644 index 0000000000..1b69a3b64f --- /dev/null +++ b/dom/media/test/test_videoPlaybackQuality_totalFrames.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Count the tatol frames of a video</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +var startTest = function(test, token) { + manager.started(token); + var v = document.createElement('video'); + v.token = token; + document.body.appendChild(v); + v.src = test.name; + + function ended(event) { + var video = event.target; + is(video.getVideoPlaybackQuality().totalVideoFrames, test.totalFrameCount,test.name+ " totalFrames should match!"); + removeNodeAndSource(video); + manager.finished(video.token); + } + v.addEventListener("ended", ended); + v.play(); +}; + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + { + "set": [ + ["media.decoder.skip-to-next-key-frame.enabled", false], + ["media.av1.use-dav1d", true] + ] + }, + function() { + manager.runTests(getPlayableVideos(gFrameCountTests), startTest); + }); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_video_dimensions.html b/dom/media/test/test_video_dimensions.html new file mode 100644 index 0000000000..4d9c2a185f --- /dev/null +++ b/dom/media/test/test_video_dimensions.html @@ -0,0 +1,96 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that a video element has set video dimensions on loadedmetadata</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +var startTest = function(test, token) { + manager.started(token); + var v1 = document.createElement('video'); + var v2 = document.createElement('video'); + var vout = document.createElement('video'); + + // Avoid a race for hardware resources between v1 and v2 on platforms with + // a hardware decoder, like B2G. + v1.preload = 'none'; + v2.preload = 'none'; + + var numVideoElementsFinished = 0; + + var ondurationchange = function(ev) { + var v = ev.target; + info(v.testName + " got durationchange"); + v.durationchange = true; + }; + var onresize = function(ev) { + var v = ev.target; + info(v.testName + " got resize"); + ok(!v.resize, v.testName + " should only fire resize once for same size"); + v.resize = true; + ok(v.durationchange, v.testName + + " durationchange event should have been emitted before resize"); + is(v.videoWidth, test.width, v.testName + " width should be set on resize"); + is(v.videoHeight, test.height, v.testName + " height should be set on resize"); + }; + var onloadedmetadata = function(ev) { + var v = ev.target; + info(v.testName + " got loadedmetadata"); + ok(!v.loadedmetadata, v.testName + " should only fire loadedmetadata once"); + v.loadedmetadata = true; + ok(v.resize, v.testName + + " resize event should have been emitted before loadedmetadata"); + + numVideoElementsFinished += 1; + if (v === v1) { + removeNodeAndSource(v1); + v2.load(); + } + + if (v === v2) { + vout.srcObject = v2.mozCaptureStreamUntilEnded(); + v2.play(); + vout.play(); + } + + if (numVideoElementsFinished === 3) { + removeNodeAndSource(v2); + removeNodeAndSource(vout); + manager.finished(token); + } + }; + var setupElement = function(v, id) { + v.durationchange = false; + v.ondurationchange = ondurationchange; + v.resize = false; + v.onresize = onresize; + v.loadedmetadata = false; + v.onloadedmetadata = onloadedmetadata; + document.body.appendChild(v); + }; + + v1.testName = test.name; + v2.testName = test.name + " (Captured)"; + vout.testName = test.name + " (Stream)"; + + v1.src = test.name; + v2.src = test.name; + + setupElement(v1, "v1"); + setupElement(v2, "v2"); + setupElement(vout, "vout"); + + v1.play(); +}; + +manager.runTests(getPlayableVideos(gSmallTests), startTest); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_video_gzip_encoding.html b/dom/media/test/test_video_gzip_encoding.html new file mode 100644 index 0000000000..355a245713 --- /dev/null +++ b/dom/media/test/test_video_gzip_encoding.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Bug 1370177 gzipped mp4 with Content-Length</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="manifest.js"></script>
+ </head>
+ <body>
+ <!--
+ Tests that an MP4 file served over a "Content-Encoding: gzip"
+ HTTP channel with a "Content-Length" header set to the length
+ of the compressed file works.
+ -->
+ <video id='v' src="http://mochi.test:8888/tests/dom/media/test/gzipped_mp4.sjs" controls autoplay></video>
+ <script>
+ SimpleTest.waitForExplicitFinish();
+ var v = document.getElementById('v');
+ v.addEventListener("ended", ()=>{
+ SimpleTest.finish();
+ mediaTestCleanup();
+ });
+ </script>
+ </body>
+</html>
diff --git a/dom/media/test/test_video_in_audio_element.html b/dom/media/test/test_video_in_audio_element.html new file mode 100644 index 0000000000..a53adf9414 --- /dev/null +++ b/dom/media/test/test_video_in_audio_element.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1060896 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1060896</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> + <script type="application/javascript"> + + /** + * Test for Bug 1060896; tests that loading a video inside an audio element works. + **/ + + var manager = new MediaTestManager; + + function error(event) { + var a = event.target; + ok(!a.mozHasAudio, "Media must've had no active tracks to play"); + a.removeEventListener("error", error); + a.removeEventListener("ended", ended); + removeNodeAndSource(a); + manager.finished(a.token); + } + + function ended(event) { + var a = event.target; + a.removeEventListener("error", error); + a.removeEventListener("ended", ended); + removeNodeAndSource(a); + manager.finished(a.token); + } + + function initTest(test, token) { + var a = document.createElement('audio'); + a.token = token; + manager.started(token); + a.autoplay = true; + + a.addEventListener("error", error); + a.addEventListener("ended", ended); + + a.src = test.name; + } + + var videos = getPlayableVideos(gSmallTests); + // Bug 1216012, skip the test on emulator-kk. + if (getAndroidVersion() == 19) { + todo(false, "Test disabled on emulator-kk."); + } else { + manager.runTests(videos, initTest); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1060896">Mozilla Bug 1060896</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/media/test/test_video_low_power_telemetry.html b/dom/media/test/test_video_low_power_telemetry.html new file mode 100644 index 0000000000..be609f7ceb --- /dev/null +++ b/dom/media/test/test_video_low_power_telemetry.html @@ -0,0 +1,205 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1737682 + +This is a test of the macOS video low power telemetry, defined as GFX_MACOS_VIDEO_LOW_POWER +enums in Histograms.json. The test will load some video media files, play them for some +number of frames, then check that appropriate telemetry has been recorded. Since the +telemetry fires based on the number of frames painted, the test is structured around +the `media.video_stats.enabled` pref, which allows us to monitor the number of frames +that have been shown. The telemetry fires every 600 frames. To make sure we have enough +painted frames to trigger telemetry, we run the media for many frames and then check +that the expected telemetry value has been recorded at least once. + +The tests are run via the MediaTestManager, which loads and plays the video sequentially. +Since we want to test different telemetry outcomes, we have some special setup and teardown +steps we run before each video. We keep track of which test we are running with a simple +1-based index, `testIndex`. So our test structure is: + +1) Set some initial preferences that need to be set for the whole test series. +2) Start MediaTestManager with a set of media to play. +3) When a video arrives, increment testIndex and call preTest. +4) Run the video for PAINTED_FRAMES frames, then call postTest, which checks telemetry + and cleans up. +5) Tell the MediaTestManager we've finished with that video, which triggers the next. +--> + +<head> + <title>Test of macOS video low power telemetry</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1737682">Mozilla Bug 1737682</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + // Parallel test must be disabled for media.video_stats.enabled is a global setting + // to prevent the setting from changing unexpectedly in the middle of the test. + PARALLEL_TESTS = 1; + SimpleTest.waitForExplicitFinish(); + + // How many frames do we run? Must be more than the value set by the + // gfx.core-animation.low-power-telemetry-frames pref, because that's how + // many frames must be shown before telemetry is emitted. We present for + // longer than that to ensure that the telemetry is emitted at least once. + // This also has to be enough frames to overcome the animated "<video> is + // now fullscreen." popup that appears over the video. While that modal + // is visible and animating away, it will register as an overlay and + // prevent low power mode. As an estimate, we need at least 200 frames to + // ensure that animation has finished and there has been time to fire the + // telemetry at least once after it has finished. + const TELEMETRY_FRAMES = SpecialPowers.getIntPref("gfx.core-animation.low-power-telemetry-frames"); + const PAINTED_FRAMES = Math.max(Math.floor(TELEMETRY_FRAMES * 1.1), 200 + TELEMETRY_FRAMES); + info(`Running each video for ${PAINTED_FRAMES} frames.`); + + // Taken from TelemetryHistogramEnums.h + const GFX_MACOS_VIDEO_LOW_POWER_LowPower = 1; + const GFX_MACOS_VIDEO_LOW_POWER_FailWindowed = 3; + + var manager = new MediaTestManager; + + // Define some state variables that we'll use to manage multiple setup, + // check, and teardown steps using the same preTest and postTest functions. + var testIndex = 0; + var testsComplete = false; + + async function retrieveSnapshotAndClearTelemetry() { + return SpecialPowers.spawnChrome([], () => { + let hist = Services.telemetry.getHistogramById("GFX_MACOS_VIDEO_LOW_POWER"); + let snap = hist.snapshot(); + hist.clear(); + return snap; + }); + } + + function checkSnapshot(snap, category) { + if (!snap) { + return; + } + + // For debugging purposes, build a string of the snapshot values hashmap. + let valuesString = ''; + let keys = Object.keys(snap.values); + keys.forEach(k => { + valuesString += `[${k}] = ${snap.values[k]}, `; + }); + info(`Test ${testIndex} telemetry values are ${valuesString}`); + + // Since we've run the media for more frames than the telemetry needs to + // fire, we should have at least 1 of the expected value. + let val = snap.values[category]; + if (!val) { + val = 0; + } + ok(val > 0, `Test ${testIndex} enum ${category} should have at least 1 occurrence; found ${val}.`); + } + + async function doPreTest(v) { + if (testsComplete) { + manager.finished(v.token); + return; + } + + switch (testIndex) { + case 1: { + // Test 1 (FailWindowed): No special setup. + break; + } + + case 2: { + // Test 2 (LowPower): Enter fullscreen. + + // Wait one frame to ensure the old video is no longer in the layer tree, which + // causes problems with the telemetry. + await new Promise(resolve => requestAnimationFrame(resolve)); + + info("Attempting to enter fullscreen."); + ok(document.fullscreenEnabled, "Document should permit fullscreen-ing of elements."); + await SpecialPowers.wrap(v).requestFullscreen(); + ok(document.fullscreenElement, "Document should have one element in fullscreen."); + break; + } + } + } + + async function doPostTest(v) { + info(`Test ${testIndex} attempting to retrieve telemetry.`); + let snap = await retrieveSnapshotAndClearTelemetry(); + ok(snap, `Test ${testIndex} should have telemetry.`); + + switch (testIndex) { + case 1: { + // Test 1 (FailWindowed): Just check. + checkSnapshot(snap, GFX_MACOS_VIDEO_LOW_POWER_FailWindowed); + break; + } + + case 2: { + // Test 2 (LowPower): Check, then exit fullscreen. + checkSnapshot(snap, GFX_MACOS_VIDEO_LOW_POWER_LowPower); + + info("Attempting to exit fullscreen."); + await SpecialPowers.wrap(document).exitFullscreen(); + ok(!document.fullscreenElement, "Document should be out of fullscreen."); + + // This is the last test. + testsComplete = true; + break; + } + } + } + + function ontimeupdate(event) { + let v = event.target; + // Count painted frames to see when we should hit some telemetry threshholds. + if (v.mozPaintedFrames >= PAINTED_FRAMES) { + v.pause(); + v.removeEventListener("timeupdate", ontimeupdate); + + doPostTest(v).then(() => { + let token = v.token; + removeNodeAndSource(v); + manager.finished(token); + }); + } + } + + function startTest(test, token) { + manager.started(token); + + testIndex++; + info(`Starting test ${testIndex} video ${test.name}.`); + + let v = document.createElement('video'); + v.addEventListener("timeupdate", ontimeupdate); + v.token = token; + v.src = test.name; + v.loop = true; + document.body.appendChild(v); + + doPreTest(v).then(() => { + info(`Playing test ${testIndex}.`); + v.play(); + }); + } + + SpecialPowers.pushPrefEnv({"set": [ + ["media.video_stats.enabled", true], + ["gfx.core-animation.specialize-video", true], + ]}, + async function() { + // Clear out existing telemetry in case previous tests were displaying + // video. + info("Clearing initial telemetry."); + await retrieveSnapshotAndClearTelemetry(); + + ok(gVideoLowPowerTests.length >= 2, "Should have enough videos to test."); + manager.runTests(gVideoLowPowerTests, startTest); + }); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_video_stats_resistfingerprinting.html b/dom/media/test/test_video_stats_resistfingerprinting.html new file mode 100644 index 0000000000..2bc239b367 --- /dev/null +++ b/dom/media/test/test_video_stats_resistfingerprinting.html @@ -0,0 +1,90 @@ +<!DOCTYPE HTML> +<html> +<!-- +Mozilla Bug: +https://bugzilla.mozilla.org/show_bug.cgi?id=1369309 +Tor Ticket: +https://trac.torproject.org/projects/tor/ticket/15757 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1369309</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=682299">Mozilla Bug 1369309</a> +<a target="_blank" href="https://trac.torproject.org/projects/tor/ticket/15757">Tor Ticket 15757</a> + +<!-- The main testing script --> +<script class="testbody" type="text/javascript"> + var manager = new MediaTestManager; + const SPOOFED_FRAMES_PER_SECOND = 30; + const SPOOFED_DROPPED_RATIO = 0.05; + const MS_PER_TIME_ATOM = 100; // Not the default anymore, but what we test here. + // Push the setting of 'privacy.resistFingerprinting' into gTestPrefs, which + // will be set during MediaTestManager.runTests(). + gTestPrefs.push( + ["privacy.resistFingerprinting", true], + ["privacy.resistFingerprinting.reduceTimerPrecision.microseconds", MS_PER_TIME_ATOM * 1000], + ["privacy.resistFingerprinting.reduceTimerPrecision.jitter", false], + // We use 240p as the target resolution since 480p is greater than every video + // source in our test suite, so we need to use 240p here for allowing us to + // test dropped rate here. + ["privacy.resistFingerprinting.target_video_res", 240] + ); + var testCases = [ + { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, drop: false }, + { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966, drop: false }, + { name:"gizmo.mp4", type:"video/mp4", width:560, height:320, duration:5.56, drop: true } + ]; + + function checkStats(v, shouldDrop) { + // Rounding the current time to 100ms. + const secondsPerAtom = MS_PER_TIME_ATOM / 1000; + const currentTimeAtoms = Math.floor(v.currentTime / secondsPerAtom); + const currentTime = currentTimeAtoms * secondsPerAtom; + let dropRate = 0; + + if (shouldDrop) { + dropRate = SPOOFED_DROPPED_RATIO; + } + + is(v.mozParsedFrames, parseInt(currentTime * SPOOFED_FRAMES_PER_SECOND, 10), + "mozParsedFrames should be spoofed if fingerprinting resistance is enabled"); + is(v.mozDecodedFrames, parseInt(currentTime * SPOOFED_FRAMES_PER_SECOND, 10), + "mozDecodedFrames should be spoofed if fingerprinting resistance is enabled"); + is(v.mozPresentedFrames, + parseInt(currentTime * SPOOFED_FRAMES_PER_SECOND * (1 - dropRate), 10), + "mozPresentedFrames should be spoofed if fingerprinting resistance is enabled"); + is(v.mozPaintedFrames, + parseInt(currentTime * SPOOFED_FRAMES_PER_SECOND * (1 - dropRate), 10), + "mozPaintedFrames should be spoofed if fingerprinting resistance is enabled"); + is(v.mozFrameDelay, 0.0, + "mozFrameDelay should be 0.0 if fingerprinting resistance is enabled"); + let playbackQuality = v.getVideoPlaybackQuality(); + is(playbackQuality.totalVideoFrames, parseInt(currentTime * SPOOFED_FRAMES_PER_SECOND, 10), + "VideoPlaybackQuality.totalVideoFrames should be spoofed if fingerprinting resistance is enabled"); + is(playbackQuality.droppedVideoFrames, parseInt(currentTime * SPOOFED_FRAMES_PER_SECOND * dropRate, 10), + "VideoPlaybackQuality.droppedVideoFrames should be spoofed if fingerprinting resistance is enabled"); + } + + function startTest(test, token) { + let v = document.createElement("video"); + v.token = token; + v.src = test.name; + manager.started(token); + once(v, "ended", () => { + checkStats(v, test.drop); + removeNodeAndSource(v); + manager.finished(v.token); + }); + v.play(); + } + + manager.runTests(testCases, startTest); + +</script> +</body> +</html> diff --git a/dom/media/test/test_video_to_canvas.html b/dom/media/test/test_video_to_canvas.html new file mode 100644 index 0000000000..3267dc63f5 --- /dev/null +++ b/dom/media/test/test_video_to_canvas.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=486646 +--> + +<head> + <title>Test for Bug 486646</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<script class="testbody" type="text/javascript"> + +var manager = new MediaTestManager; + +function loaded(e) { + var v = e.target; + ok(v.readyState >= v.HAVE_CURRENT_DATA, + "readyState must be >= HAVE_CURRENT_DATA for " + v._name); + + var canvas = document.createElement("canvas"); + canvas.width = v.videoWidth; + canvas.height = v.videoHeight; + document.body.appendChild(canvas); + var ctx = canvas.getContext("2d"); + try { + ctx.drawImage(v, 0, 0); + ok(true, "Shouldn't throw exception while drawing to canvas from video for " + v._name); + } catch (ex) { + ok(false, "Shouldn't throw exception while drawing to canvas from video for " + v._name); + } + + v._finished = true; + v.remove(); + manager.finished(v.token); +} + +function startTest(test, token) { + var type = getMajorMimeType(test.type); + if (type != "video") + return; + + var v = document.createElement('video'); + v.token = token; + manager.started(token); + v.src = test.name; + v._name = test.name; + v._finished = false; + v.autoplay = true; + v.style.display = "none"; + v.addEventListener("ended", loaded); + document.body.appendChild(v); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest); +function beginTest() { + manager.runTests(gSmallTests, startTest); +} + +</script> +</pre> + +</body> +</html> diff --git a/dom/media/test/test_volume.html b/dom/media/test/test_volume.html new file mode 100644 index 0000000000..3d9e5bd91a --- /dev/null +++ b/dom/media/test/test_volume.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: volume attribute set</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<video id='v1'></video><audio id='a1'></audio> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function test(element, value, shouldThrow) { + var threw = null; + try { + element.volume = value; + } catch (ex) { + threw = ex.name; + } + is(shouldThrow, threw, "Case: " +element.id+ " setVolume=" + value); +} + + +var ids = [document.getElementById('v1'), document.getElementById('a1')]; + +for (let i=0; i<ids.length; i++) { + var element = ids[i]; + test(element, 0.0, null); + test(element, 1.0, null); + test(element, -0.1, "IndexSizeError"); + test(element, 1.1, "IndexSizeError"); + test(element, undefined, "TypeError"); + test(element, NaN, "TypeError"); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_vp9_superframes.html b/dom/media/test/test_vp9_superframes.html new file mode 100644 index 0000000000..c570561b31 --- /dev/null +++ b/dom/media/test/test_vp9_superframes.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that all VP9 frames are decoded (contains superframes)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function test() { + var video = document.createElement("video"); + video.src = "vp9-superframes.webm"; + video.play(); + video.addEventListener("ended", function () { + let vpq = video.getVideoPlaybackQuality(); + is(vpq.totalVideoFrames, 120, "totalVideoFrames must contains 120 frames"); + SimpleTest.finish(); + }); +} + +addLoadEvent(function() { + test(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/test/test_wav_ended1.html b/dom/media/test/test_wav_ended1.html new file mode 100644 index 0000000000..99f6e38243 --- /dev/null +++ b/dom/media/test/test_wav_ended1.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Wave Media test: ended</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +// Test if the ended event works correctly. +var endPassed = false; +var completed = false; + +function startTest() { + if (completed) + return; + var v = document.getElementById('v'); + v.play(); +} + +function playbackEnded() { + if (completed) + return; + + var v = document.getElementById('v'); + completed = true; + ok(v.currentTime >= 0.9 && v.currentTime <= 1.1, + "Checking currentTime at end: " + v.currentTime); + ok(v.ended, "Checking playback has ended"); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +<audio id='v' + onloadedmetadata='return startTest();' + onended='return playbackEnded();'> + <source type='audio/x-wav' src='r11025_s16_c1.wav'> +</audio> +</body> +</html> diff --git a/dom/media/test/test_wav_ended2.html b/dom/media/test/test_wav_ended2.html new file mode 100644 index 0000000000..0c172139f0 --- /dev/null +++ b/dom/media/test/test_wav_ended2.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Wave Media test: ended and replaying</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<!-- try with autoplay and no v.play in starttest, also with both --> +<pre id="test"> +<script class="testbody" type="text/javascript"> +// Test if audio can be replayed after ended. +var completed = false; +var playingCount = 0; +var endCount = 0; + +function startTest() { + if (completed) + return; + + var v = document.getElementById('v'); + v.play(); +} + +function playbackStarted() { + if (completed) + return; + + playingCount++; +} + +function playbackEnded() { + if (completed) + return; + + endCount++; + var v = document.getElementById('v'); + ok(v.currentTime >= 0.9 && v.currentTime <= 1.1, + "Checking currentTime at end: " + v.currentTime); + ok(v.ended, "Checking playback has ended"); + ok(playingCount > 0, "Expect at least one playing event"); + playingCount = 0; + if (endCount < 2) { + v.play(); + } else { + ok(endCount == 2, "Check playback after ended event"); + completed = true; + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +<audio id='v' + onloadedmetadata='return startTest();' + onplaying='return playbackStarted();' + onended='return playbackEnded();'> + <source type='audio/x-wav' src='r11025_s16_c1.wav'> +</audio> +</body> +</html> diff --git a/dom/media/test/tone2s-silence4s-tone2s.opus b/dom/media/test/tone2s-silence4s-tone2s.opus Binary files differnew file mode 100644 index 0000000000..e7d754926e --- /dev/null +++ b/dom/media/test/tone2s-silence4s-tone2s.opus diff --git a/dom/media/test/two-xing-header-no-content-length.mp3 b/dom/media/test/two-xing-header-no-content-length.mp3 Binary files differnew file mode 100644 index 0000000000..4d139e2886 --- /dev/null +++ b/dom/media/test/two-xing-header-no-content-length.mp3 diff --git a/dom/media/test/two-xing-header-no-content-length.mp3^headers^ b/dom/media/test/two-xing-header-no-content-length.mp3^headers^ new file mode 100644 index 0000000000..abfeb4ce28 --- /dev/null +++ b/dom/media/test/two-xing-header-no-content-length.mp3^headers^ @@ -0,0 +1,3 @@ +HTTP 200 OK +Content-Length: invalid +Cache-Control: no-store diff --git a/dom/media/test/variable-channel.ogg b/dom/media/test/variable-channel.ogg Binary files differnew file mode 100644 index 0000000000..77e116889c --- /dev/null +++ b/dom/media/test/variable-channel.ogg diff --git a/dom/media/test/variable-channel.ogg^headers^ b/dom/media/test/variable-channel.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/variable-channel.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/variable-channel.opus b/dom/media/test/variable-channel.opus Binary files differnew file mode 100644 index 0000000000..76b8991167 --- /dev/null +++ b/dom/media/test/variable-channel.opus diff --git a/dom/media/test/variable-channel.opus^headers^ b/dom/media/test/variable-channel.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/variable-channel.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/variable-preskip.opus b/dom/media/test/variable-preskip.opus Binary files differnew file mode 100644 index 0000000000..a82e831ce6 --- /dev/null +++ b/dom/media/test/variable-preskip.opus diff --git a/dom/media/test/variable-preskip.opus^headers^ b/dom/media/test/variable-preskip.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/variable-preskip.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/variable-samplerate.ogg b/dom/media/test/variable-samplerate.ogg Binary files differnew file mode 100644 index 0000000000..0c2726e835 --- /dev/null +++ b/dom/media/test/variable-samplerate.ogg diff --git a/dom/media/test/variable-samplerate.ogg^headers^ b/dom/media/test/variable-samplerate.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/variable-samplerate.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/variable-samplerate.opus b/dom/media/test/variable-samplerate.opus Binary files differnew file mode 100644 index 0000000000..1d15170798 --- /dev/null +++ b/dom/media/test/variable-samplerate.opus diff --git a/dom/media/test/variable-samplerate.opus^headers^ b/dom/media/test/variable-samplerate.opus^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/variable-samplerate.opus^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/vbr-head.mp3 b/dom/media/test/vbr-head.mp3 Binary files differnew file mode 100644 index 0000000000..35f4105491 --- /dev/null +++ b/dom/media/test/vbr-head.mp3 diff --git a/dom/media/test/vbr-head.mp3^headers^ b/dom/media/test/vbr-head.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/vbr-head.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/vbr.mp3 b/dom/media/test/vbr.mp3 Binary files differnew file mode 100644 index 0000000000..38eb376a97 --- /dev/null +++ b/dom/media/test/vbr.mp3 diff --git a/dom/media/test/vbr.mp3^headers^ b/dom/media/test/vbr.mp3^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/vbr.mp3^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/very-short.mp3 b/dom/media/test/very-short.mp3 Binary files differnew file mode 100644 index 0000000000..7dbdb20c3a --- /dev/null +++ b/dom/media/test/very-short.mp3 diff --git a/dom/media/test/video-overhang.ogg b/dom/media/test/video-overhang.ogg Binary files differnew file mode 100644 index 0000000000..e11b28fb5b --- /dev/null +++ b/dom/media/test/video-overhang.ogg diff --git a/dom/media/test/video-overhang.ogg^headers^ b/dom/media/test/video-overhang.ogg^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/video-overhang.ogg^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/vp9-short.webm b/dom/media/test/vp9-short.webm Binary files differnew file mode 100644 index 0000000000..16d32abee3 --- /dev/null +++ b/dom/media/test/vp9-short.webm diff --git a/dom/media/test/vp9-short.webm^headers^ b/dom/media/test/vp9-short.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/vp9-short.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/vp9-superframes.webm b/dom/media/test/vp9-superframes.webm Binary files differnew file mode 100644 index 0000000000..d695e42357 --- /dev/null +++ b/dom/media/test/vp9-superframes.webm diff --git a/dom/media/test/vp9-superframes.webm^headers^ b/dom/media/test/vp9-superframes.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/vp9-superframes.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/vp9.webm b/dom/media/test/vp9.webm Binary files differnew file mode 100644 index 0000000000..221877e303 --- /dev/null +++ b/dom/media/test/vp9.webm diff --git a/dom/media/test/vp9.webm^headers^ b/dom/media/test/vp9.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/vp9.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/vp9cake-short.webm b/dom/media/test/vp9cake-short.webm Binary files differnew file mode 100644 index 0000000000..2d353d98a7 --- /dev/null +++ b/dom/media/test/vp9cake-short.webm diff --git a/dom/media/test/vp9cake-short.webm^headers^ b/dom/media/test/vp9cake-short.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/vp9cake-short.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/vp9cake.webm b/dom/media/test/vp9cake.webm Binary files differnew file mode 100644 index 0000000000..4ea70ed302 --- /dev/null +++ b/dom/media/test/vp9cake.webm diff --git a/dom/media/test/vp9cake.webm^headers^ b/dom/media/test/vp9cake.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/vp9cake.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wave_metadata.wav b/dom/media/test/wave_metadata.wav Binary files differnew file mode 100644 index 0000000000..5e17547c30 --- /dev/null +++ b/dom/media/test/wave_metadata.wav diff --git a/dom/media/test/wave_metadata.wav^headers^ b/dom/media/test/wave_metadata.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wave_metadata.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wave_metadata_bad_len.wav b/dom/media/test/wave_metadata_bad_len.wav Binary files differnew file mode 100644 index 0000000000..b89c4818be --- /dev/null +++ b/dom/media/test/wave_metadata_bad_len.wav diff --git a/dom/media/test/wave_metadata_bad_len.wav^headers^ b/dom/media/test/wave_metadata_bad_len.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wave_metadata_bad_len.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wave_metadata_bad_no_null.wav b/dom/media/test/wave_metadata_bad_no_null.wav Binary files differnew file mode 100644 index 0000000000..18063048c3 --- /dev/null +++ b/dom/media/test/wave_metadata_bad_no_null.wav diff --git a/dom/media/test/wave_metadata_bad_no_null.wav^headers^ b/dom/media/test/wave_metadata_bad_no_null.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wave_metadata_bad_no_null.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wave_metadata_bad_utf8.wav b/dom/media/test/wave_metadata_bad_utf8.wav Binary files differnew file mode 100644 index 0000000000..b6f2a675b2 --- /dev/null +++ b/dom/media/test/wave_metadata_bad_utf8.wav diff --git a/dom/media/test/wave_metadata_bad_utf8.wav^headers^ b/dom/media/test/wave_metadata_bad_utf8.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wave_metadata_bad_utf8.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wave_metadata_unknown_tag.wav b/dom/media/test/wave_metadata_unknown_tag.wav Binary files differnew file mode 100644 index 0000000000..b19fb5170f --- /dev/null +++ b/dom/media/test/wave_metadata_unknown_tag.wav diff --git a/dom/media/test/wave_metadata_unknown_tag.wav^headers^ b/dom/media/test/wave_metadata_unknown_tag.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wave_metadata_unknown_tag.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wave_metadata_utf8.wav b/dom/media/test/wave_metadata_utf8.wav Binary files differnew file mode 100644 index 0000000000..352db285bb --- /dev/null +++ b/dom/media/test/wave_metadata_utf8.wav diff --git a/dom/media/test/wave_metadata_utf8.wav^headers^ b/dom/media/test/wave_metadata_utf8.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wave_metadata_utf8.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wavedata_alaw.wav b/dom/media/test/wavedata_alaw.wav Binary files differnew file mode 100644 index 0000000000..ef090d16e0 --- /dev/null +++ b/dom/media/test/wavedata_alaw.wav diff --git a/dom/media/test/wavedata_alaw.wav^headers^ b/dom/media/test/wavedata_alaw.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wavedata_alaw.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wavedata_float.wav b/dom/media/test/wavedata_float.wav Binary files differnew file mode 100644 index 0000000000..155f891d51 --- /dev/null +++ b/dom/media/test/wavedata_float.wav diff --git a/dom/media/test/wavedata_float.wav^headers^ b/dom/media/test/wavedata_float.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wavedata_float.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wavedata_s16.wav b/dom/media/test/wavedata_s16.wav Binary files differnew file mode 100644 index 0000000000..6a69cd78f6 --- /dev/null +++ b/dom/media/test/wavedata_s16.wav diff --git a/dom/media/test/wavedata_s16.wav^headers^ b/dom/media/test/wavedata_s16.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wavedata_s16.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wavedata_s24.wav b/dom/media/test/wavedata_s24.wav Binary files differnew file mode 100644 index 0000000000..dbdb6aac1e --- /dev/null +++ b/dom/media/test/wavedata_s24.wav diff --git a/dom/media/test/wavedata_s24.wav^headers^ b/dom/media/test/wavedata_s24.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wavedata_s24.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wavedata_u8.wav b/dom/media/test/wavedata_u8.wav Binary files differnew file mode 100644 index 0000000000..1d895c2ce0 --- /dev/null +++ b/dom/media/test/wavedata_u8.wav diff --git a/dom/media/test/wavedata_u8.wav^headers^ b/dom/media/test/wavedata_u8.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wavedata_u8.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/wavedata_ulaw.wav b/dom/media/test/wavedata_ulaw.wav Binary files differnew file mode 100644 index 0000000000..0874face21 --- /dev/null +++ b/dom/media/test/wavedata_ulaw.wav diff --git a/dom/media/test/wavedata_ulaw.wav^headers^ b/dom/media/test/wavedata_ulaw.wav^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/wavedata_ulaw.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/white-3s-black-1s.webm b/dom/media/test/white-3s-black-1s.webm Binary files differnew file mode 100644 index 0000000000..03dd1dcbda --- /dev/null +++ b/dom/media/test/white-3s-black-1s.webm diff --git a/dom/media/test/white-3s-black-1s.webm^headers^ b/dom/media/test/white-3s-black-1s.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/test/white-3s-black-1s.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/test/white-short.webm b/dom/media/test/white-short.webm Binary files differnew file mode 100644 index 0000000000..0b718cdf20 --- /dev/null +++ b/dom/media/test/white-short.webm diff --git a/dom/media/tests/crashtests/1281695.html b/dom/media/tests/crashtests/1281695.html new file mode 100644 index 0000000000..9865c3a509 --- /dev/null +++ b/dom/media/tests/crashtests/1281695.html @@ -0,0 +1,24 @@ + +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +function zombieWindow() +{ + var frame = document.createElement("iframe"); + document.body.appendChild(frame); + var frameWin = frame.contentWindow; + frame.remove(); + return frameWin; +} + +function boom() { + zombieWindow().navigator.mozGetUserMedia({ "fake": true, "audio": true }, function(stream) {}, function(e) {}); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/tests/crashtests/1306476.html b/dom/media/tests/crashtests/1306476.html new file mode 100644 index 0000000000..d15cbe57df --- /dev/null +++ b/dom/media/tests/crashtests/1306476.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <meta charset=utf-8> + <title>Bug 1348381: Integer overflow playing vorbis file</title> +</head> +<body> + <audio id=player controls + src="data:audio/ogg;base64,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"> + </audio> + <div id=result> + </div> + + <script type="application/javascript"> + function done() { + // Remove reftest-wait to terminate the test. + document.documentElement.removeAttribute("class"); + } + + function log(msg) { + // Append a status result. + let p = document.createElement("p"); + p.textContent = msg; + document.getElementById("result").appendChild(p); + } + + // Confirm playback completes. + let a = document.getElementById("player"); + a.addEventListener("ended", () => { + log("Playback completed."); + done(); + }); + a.addEventListener("error", () => { + log("Playback error."); + }); + + log("Starting playback..."); + a.play(); + + // Set a short timeout in case we hang. + setTimeout(() => { + log("Timed out!"); + done(); + }, 100); + </script> +</body> +</html> diff --git a/dom/media/tests/crashtests/1348381.html b/dom/media/tests/crashtests/1348381.html new file mode 100644 index 0000000000..b872e58794 --- /dev/null +++ b/dom/media/tests/crashtests/1348381.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title>Bug 1348381: Crash when recording extremely large canvas' captureStream</title> +</head> +</body> +<canvas id="c" height="0.6"></canvas> +<img id="img" src="data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA="></img> +<script type="application/javascript"> +const c = document.getElementById("c"); +const ctx = c.getContext('2d'); +const s = c.captureStream(0); +const mr = new MediaRecorder(s); +const t = s.getVideoTracks()[0]; +mr.start(); +const img = document.getElementById('img'); +t.enabled = false; +ctx.drawImage(img, 16, 18014398509481984); +setTimeout(() => document.documentElement.removeAttribute("class"), 100); +</script> +</body> +</html> diff --git a/dom/media/tests/crashtests/1367930_1.html b/dom/media/tests/crashtests/1367930_1.html new file mode 100644 index 0000000000..a4039a61a7 --- /dev/null +++ b/dom/media/tests/crashtests/1367930_1.html @@ -0,0 +1,39 @@ +<html> +<body> + <script> +var offer= "v=0\r\no=- 6276735615230473072 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE video\r\na=msid-semantic:WMS *\r\na=ice-ufrag:XoEUdw==\r\na=ice-pwd:hfNjAs9TU4NNuumB50mGfJwkqIEN8A==\r\na=ice-lite\r\na=setup:actpass\r\na=fingerprint:sha-256 0D:54:F2:D9:F3:10:00:2D:CD:14:C6:AC:CB:5D:E7:34:5E:6F:A8:BF:25:96:48:40:0B:C7:F9:18:6A:A6:73:3F\r\nm=video 9 UDP/TLS/RTP/SAVPF 100\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=mid:video\r\na=recvonly\r\na=rtcp-rsize\r\na=rtcp-mux\r\na=rtpmap:100 VP8/90000\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=rtcp-fb:100 goog-remb\r\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:4 urn:3gpp:video-orientation\r\na=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=rid:hi recv\r\na=rid:mid recv\r\na=rid:lo recv\r\na=simulcast: recv rid=hi,mid,lo\r\na=candidate:1796272311 1 UDP 2130706431 192.168.10.146 55984 typ host\r\na=end-of-candidates\r\n" + +var data = {}; +data.sdp = offer; +data.type = "offer"; + +console.log('OFFER', JSON.stringify(data.sdp)); + +var pc = new RTCPeerConnection(); + +navigator.mediaDevices.getUserMedia({video: true, fake: true}) + .then((stream) => { + return pc.addStream(stream); + }) + .then(() => { + return pc.setRemoteDescription(new RTCSessionDescription(data)); + }) + .then(function() { + var sender = pc.getSenders()[0]; + console.log('setting parameters'); + return sender.setParameters({encodings: [ + {rid: "hi", maxBitrate: 800000}, + {rid: "mid", maxBitrate: 400000, scaleDownResolutionBy: 2}, + {rid: "lo", maxBitrate: 150000, scaleDownResolutionBy: 4} + ]}); + }) + .then(function() { + return pc.createAnswer(); + }) + .then(function(answer) { + console.log('answer', JSON.stringify(answer.sdp)); + return pc.setLocalDescription(answer); + }); + </script> +</body> +</html> diff --git a/dom/media/tests/crashtests/1367930_2.html b/dom/media/tests/crashtests/1367930_2.html new file mode 100644 index 0000000000..e2ee6720c6 --- /dev/null +++ b/dom/media/tests/crashtests/1367930_2.html @@ -0,0 +1,25 @@ +<html> + <body> + <script> +const sdp = {"type":"offer","sdp":"v=0\r\no=- 6276735615230473072 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE video\r\na=msid-semantic:WMS *\r\na=ice-ufrag:XpXW4g==\r\na=ice-pwd:hjagMNwFF/kMOmWoULEFptwuQXkMVQ==\r\na=ice-lite\r\na=setup:actpass\r\na=fingerprint:sha-256 DC:FC:25:56:2B:88:77:2F:E4:FA:97:4E:2E:F1:D6:34:A6:A0:11:E2:E4:38:B3:98:08:D2:F7:9D:F5:E2:C1:15\r\nm=video 9 UDP/TLS/RTP/SAVPF 100\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=mid:video\r\na=recvonly\r\na=rtcp-rsize\r\na=rtcp-mux\r\na=rtpmap:100 VP8/90000\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=rtcp-fb:100 goog-remb\r\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:4 urn:3gpp:video-orientation\r\na=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=rid:hi recv\r\na=rid:mid recv\r\na=rid:lo recv\r\na=simulcast: recv rid=hi;mid;lo\r\na=candidate:1796272311 1 UDP 2130706431 127.0.0.1 33584 typ host\r\na=end-of-candidates\r\n"}; + +var pc = new RTCPeerConnection(); + +navigator.mediaDevices.getUserMedia({video: true, fake: true}) +.then(stream => pc.addStream(stream)) +.then(() => { + console.log('hum'); + pc.setRemoteDescription(sdp) + .then(function() { + return pc.createAnswer(); + }) + .then(function(answer) { + console.log(answer.sdp); + return pc.setLocalDescription(answer); + }) + .then(console.log('yay')) + .catch(e => console.error(e)); +}) + </script> + </body> +</html> diff --git a/dom/media/tests/crashtests/1429507_1.html b/dom/media/tests/crashtests/1429507_1.html new file mode 100644 index 0000000000..4290fe721a --- /dev/null +++ b/dom/media/tests/crashtests/1429507_1.html @@ -0,0 +1,29 @@ +<html class="reftest-wait"> + <body> + <script> + let o1; + let p1, p2; + window.addEventListener("MozReftestInvalidate", finish); + try { o1 = window.open("") } catch (e) {} + try { o1.location.reload() } catch (e) {} + try { o2 = new RTCPeerConnection({iceServers: [{"url": "stun:d"}]}) } catch (e) {} + try { p1 = o1.navigator.mediaDevices.getUserMedia({video: true, fake: true}).catch((error) => {}) } catch (e) {} + try { o2.createOffer({offerToReceiveVideo: true}).then((offer) => { + try { p2 = o1.navigator.mediaDevices.getUserMedia({video: true}) } catch (e) {}; + }) } catch (e) {} + + async function finish() { + try { + await p1; + } catch (e) {} + try { + await p2; + } catch (e) {} + try { + o1.close(); + } catch (e) {} + document.documentElement.className = ""; + } + </script> + </body> +</html> diff --git a/dom/media/tests/crashtests/1429507_2.html b/dom/media/tests/crashtests/1429507_2.html new file mode 100644 index 0000000000..3c3310d959 --- /dev/null +++ b/dom/media/tests/crashtests/1429507_2.html @@ -0,0 +1,31 @@ +<html class="reftest-wait"> + <body> + <script> + let o1; + let p1, p2; + window.addEventListener("MozReftestInvalidate", finish); + try { o1 = window.open("") } catch(e) { } + try { o1.location.reload() } catch(e) { } + try { o2 = o1.navigator } catch(e) { } + try { o3 = o2.mediaDevices } catch(e) { } + try { o4 = new XMLHttpRequest() } catch(e) { } + try { p1 = o3.getUserMedia({video: true, fake: true }).then((stream) => {}).catch((error) => {}) } catch (e) {} + try { o4.open("T", "aa", false) } catch(e) { } + try { o4.send() } catch(e) { } + try { p2 = o3.getUserMedia({video: true}).then((stream) => {}).catch((error) => {}) } catch (e) {} + + async function finish() { + try { + await p1; + } catch (e) {} + try { + await p2; + } catch (e) {} + try { + o1.close(); + } catch (e) {} + document.documentElement.className = ""; + } + </script> + </body> +</html> diff --git a/dom/media/tests/crashtests/1443212.html b/dom/media/tests/crashtests/1443212.html new file mode 100644 index 0000000000..3f0eedac90 --- /dev/null +++ b/dom/media/tests/crashtests/1443212.html @@ -0,0 +1,13 @@ +<script> +window.addEventListener("load", () => { + const c = document.createElement("canvas"); + c.getContext("2d"); + const stream = c.captureStream(); + const [track] = stream.getTracks(); + stream.removeTrack(track); + track.stop(); + stream.addTrack(track); + stream.removeTrack(track); + stream.addTrack(track); +}); +</script> diff --git a/dom/media/tests/crashtests/1453030.html b/dom/media/tests/crashtests/1453030.html new file mode 100644 index 0000000000..32be04ed1d --- /dev/null +++ b/dom/media/tests/crashtests/1453030.html @@ -0,0 +1,39 @@ +<html class="reftest-wait"> + <head> + <script> + let o3; + + var index = localStorage.index_1453030_html || 0; + localStorage.index_1453030_html = ++index; + + function getDTMF () { + try { o4 = o2.dtmf } catch(e) { } + try { o4.insertDTMF("1BC1D55", new Uint32Array([3538134876])[0], new Uint32Array([666182017])[0]) } catch (e) { } + + setTimeout(finish, 0); + } + + function finish() { + try { o3.close(); } catch (e) {} + document.documentElement.removeAttribute("class"); + } + onbeforeunload = function() { + try { o3.close(); } catch (e) {} + } + + if (index == 1) { + o1 = new RTCPeerConnection({ }, null) + window.navigator.mediaDevices.getUserMedia({video: true, fake: true}).then((stream) => { + o2 = o1.addTrack(stream.getVideoTracks()[0], stream) + }).catch((error) => {}) + o3 = window.open("datr=0") + setTimeout(getDTMF, 400) + setTimeout(window.location.reload.bind(window.location), 500); + } else { + try { delete localStorage["index_1453030_html"]; } catch (e) {} + finish(); + } + + </script> + </head> +</html> diff --git a/dom/media/tests/crashtests/1468451.html b/dom/media/tests/crashtests/1468451.html new file mode 100644 index 0000000000..40f2efac0d --- /dev/null +++ b/dom/media/tests/crashtests/1468451.html @@ -0,0 +1,10 @@ +<script> +alice = new RTCPeerConnection({ iceServers: [{ 'url': 'stun:2' }], }, null) +bob = new RTCPeerConnection({ }, null) +alice.createOffer({ offerToReceiveAudio: true }) +track = alice.getReceivers()[0].track +alice.createOffer({ }).then((offer) => { + bob.addEventListener('signalingstatechange', (x) => x.target.addTransceiver(track, {}), { }) + bob.close() +}) +</script> diff --git a/dom/media/tests/crashtests/1490700.html b/dom/media/tests/crashtests/1490700.html new file mode 100644 index 0000000000..ea881c3096 --- /dev/null +++ b/dom/media/tests/crashtests/1490700.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title>Bug 1490700 - Divide-by-zero for screen-capture with max-dimension 0</title> +</head> +</body> +<script type="application/javascript"> +async function test() { + SpecialPowers.wrap(document).notifyUserGestureActivation(); + await window.navigator.mediaDevices.getUserMedia({ + video: { + mediaSource: 'screen', + height: {max: 0}, + }, + }); + await window.navigator.mediaDevices.getUserMedia({ + video: { + mediaSource: 'screen', + advanced: [{height: 0}], + }, + }); + document.documentElement.removeAttribute("class"); +} + +test(); +</script> +</body> +</html> diff --git a/dom/media/tests/crashtests/1505957.html b/dom/media/tests/crashtests/1505957.html new file mode 100644 index 0000000000..d2ba7a997c --- /dev/null +++ b/dom/media/tests/crashtests/1505957.html @@ -0,0 +1,31 @@ +<html id='a' class="reftest-wait">
+<script>
+let w;
+window.addEventListener("MozReftestInvalidate", finish);
+window.onload=function() {
+ b.src=document.getElementById('c').innerHTML;
+ b.setAttribute('src', 'video-crash.webm');
+ document.documentElement.style.display='none';
+ w = window.top.open('');
+ var o = window.frames[0].document.body.childNodes[0];
+ document.getElementById('d').appendChild(o.parentNode.removeChild(o));
+ o = document.getElementById('a');
+ var p = o.parentNode;
+ o.setAttribute('id', 0)
+ p.removeChild(o);
+ p.appendChild(o);
+ o.setAttribute('style', 0)
+ p.removeChild(o);
+ p.appendChild(o);
+}
+function finish() {
+ try {
+ w.close();
+ } catch (e) {}
+ document.documentElement.className = "";
+}
+</script>
+<iframe id='b'></iframe>
+<object id='c'>
+<ruby id='d'>
+</html>
diff --git a/dom/media/tests/crashtests/1509442-1.html b/dom/media/tests/crashtests/1509442-1.html new file mode 100644 index 0000000000..eef877ecf8 --- /dev/null +++ b/dom/media/tests/crashtests/1509442-1.html @@ -0,0 +1,14 @@ +<!DOCTYPE HTML> +<meta charset="UTF-8"> +<script> + function start() { + o5=new AudioContext(); + o291=new Float32Array(0); + o388=document.write(""); + o389=o5.createBuffer(2,22050,44100); + o420=new AudioBufferSourceNode(o5, {buffer:o389,detune:27}); + o389.copyToChannel(o291,1,0); + document.close(); + } +</script> +<body onload="start()"></body> diff --git a/dom/media/tests/crashtests/1509442.html b/dom/media/tests/crashtests/1509442.html new file mode 100644 index 0000000000..ddce401933 --- /dev/null +++ b/dom/media/tests/crashtests/1509442.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="UTF-8"> +<body> +<iframe src="1509442-1.html" onload="document.documentElement.removeAttribute('class')"></iframe> +</body> +</html> diff --git a/dom/media/tests/crashtests/1510848.html b/dom/media/tests/crashtests/1510848.html new file mode 100644 index 0000000000..05e2c2d852 --- /dev/null +++ b/dom/media/tests/crashtests/1510848.html @@ -0,0 +1,4 @@ +<a>
+<dd>
+<video>
+<a>
diff --git a/dom/media/tests/crashtests/1511130.html b/dom/media/tests/crashtests/1511130.html new file mode 100644 index 0000000000..6bdebe8de1 --- /dev/null +++ b/dom/media/tests/crashtests/1511130.html @@ -0,0 +1,12 @@ +<script>
+document.addEventListener("DOMContentLoaded", function(){
+ var o = window.frames[0].document.body.childNodes[0];
+ a.appendChild(o.parentNode.removeChild(o));
+ o = document.body;
+ o.parentNode.appendChild(o);
+ o.parentNode.appendChild(o);
+})
+</script>
+<body text=''>
+<hgroup id='a'>
+<iframe src="video-crash.webm"></iframe>
diff --git a/dom/media/tests/crashtests/1516292.html b/dom/media/tests/crashtests/1516292.html new file mode 100644 index 0000000000..93c844c939 --- /dev/null +++ b/dom/media/tests/crashtests/1516292.html @@ -0,0 +1,16 @@ +<script> +function go() { + a.children[0].appendChild(b) +} +</script> +<body onload=go()> +<svg id="a"> +<foreignObject> +<li> +<video controls="" autoplay=""> +<li id="a" contenteditable="true"> +</li> +</svg> +<canvas id="b"> +<svg> +<use xlink:href="#a"> diff --git a/dom/media/tests/crashtests/1573536.html b/dom/media/tests/crashtests/1573536.html new file mode 100644 index 0000000000..1283183254 --- /dev/null +++ b/dom/media/tests/crashtests/1573536.html @@ -0,0 +1,18 @@ +<html class="reftest-wait"> +<head> + <script> + function start () { + window.navigator.mediaDevices.getUserMedia({ + 'audio': { + 'mediaSource': 'audioCapture' + }, + 'video': true, + 'fake': true + }).catch(() => Promise.resolve()) + .then(() => document.documentElement.removeAttribute("class")) + } + + window.addEventListener('load', start) + </script> +</head> +</html> diff --git a/dom/media/tests/crashtests/1576938.html b/dom/media/tests/crashtests/1576938.html new file mode 100644 index 0000000000..71a785e299 --- /dev/null +++ b/dom/media/tests/crashtests/1576938.html @@ -0,0 +1,16 @@ +<html class="reftest-wait"> +<head> +<script> +async function start () { + const peer = new RTCPeerConnection() + await peer.createOffer({'offerToReceiveVideo': true}) + const receiver = peer.getReceivers()[0] + peer.close() + receiver.track.clone() + document.documentElement.removeAttribute("class") +} + +document.addEventListener('DOMContentLoaded', start) +</script> +</head> +</html> diff --git a/dom/media/tests/crashtests/1594136.html b/dom/media/tests/crashtests/1594136.html new file mode 100644 index 0000000000..7f3189257e --- /dev/null +++ b/dom/media/tests/crashtests/1594136.html @@ -0,0 +1,15 @@ +<html> +<head> +<script> +function start () { + const context = new AudioContext(); + const {stream} = new MediaStreamAudioDestinationNode(context); + const [track] = stream.getTracks(); + track.stop(); + context.createMediaStreamTrackSource(track); +} + +document.addEventListener('DOMContentLoaded', start); +</script> +</head> +</html> diff --git a/dom/media/tests/crashtests/1749308.html b/dom/media/tests/crashtests/1749308.html new file mode 100644 index 0000000000..1c17c6e35c --- /dev/null +++ b/dom/media/tests/crashtests/1749308.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <script> + window.addEventListener("load", () => { + const context = new AudioContext({}) + const controller = new AbortController() + let processor = context.createScriptProcessor(512, 27, 2) + processor.addEventListener("audioprocess", async () => {}, { signal: controller.signal }) + processor = null; + SpecialPowers.forceGC() + for (let i = 0; i < 7; i++) { + controller.abort(); + } + }) + </script> +</head> +</html> diff --git a/dom/media/tests/crashtests/1764915.html b/dom/media/tests/crashtests/1764915.html new file mode 100644 index 0000000000..82534caac7 --- /dev/null +++ b/dom/media/tests/crashtests/1764915.html @@ -0,0 +1,14 @@ +<html> +<head> +<script> +window.addEventListener('load', async () => { + const frame = document.createElement('frame') + document.documentElement.appendChild(frame) + const peer = new RTCPeerConnection() + await peer.setRemoteDescription({}, () => {}, async () => await peer.getIdentityAssertion()) + peer.close() +}) +</script> +</head> +</html> + diff --git a/dom/media/tests/crashtests/1764933.html b/dom/media/tests/crashtests/1764933.html new file mode 100644 index 0000000000..55f6fa2db9 --- /dev/null +++ b/dom/media/tests/crashtests/1764933.html @@ -0,0 +1,15 @@ +<html> +<head> + <script> + window.addEventListener('load', async () => { + const peer = new RTCPeerConnection({}) + await peer.createOffer({ 'offerToReceiveVideo': true }) + const receivers = peer.getReceivers() + const sender = peer.addTrack(receivers[0].track) + peer.close() + await sender.getStats() + await sender.replaceTrack(receivers[0].track) + }) + </script> +</head> +</html> diff --git a/dom/media/tests/crashtests/1764940.html b/dom/media/tests/crashtests/1764940.html new file mode 100644 index 0000000000..67bce74b18 --- /dev/null +++ b/dom/media/tests/crashtests/1764940.html @@ -0,0 +1,14 @@ +<html> +<head> + <script> + document.addEventListener('DOMContentLoaded', async () => { + const peer = new RTCPeerConnection({ 'iceServers': [{ 'urls': 'stun:23.21.150.121' }] }) + const offer = await peer.createOffer({ 'offerToReceiveVideo': true }) + await peer.setRemoteDescription(offer) + const senders = peer.getSenders() + setTimeout(async () => await senders[1].setParameters({}), 334) + await peer.setRemoteDescription(offer) + }) + </script> +</head> +</html> diff --git a/dom/media/tests/crashtests/1766668.html b/dom/media/tests/crashtests/1766668.html new file mode 100644 index 0000000000..0ea142e563 --- /dev/null +++ b/dom/media/tests/crashtests/1766668.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<script> + document.addEventListener('DOMContentLoaded', async () => { + await navigator.mediaDevices.getUserMedia({ 'audio': {} }) + const peer = new RTCPeerConnection({ 'iceServers': [{ 'urls': 'stun:23.21.150.121' }], 'peerIdentity': 'B' }, {}) + const stream = await navigator.mediaDevices.getUserMedia({ 'audio': {} }) + stream.getTracks().forEach((track) => peer.addTrack(track, stream)) + try { offer = await peer.createOffer({}) } catch (e) { } + await peer.setRemoteDescription(offer) + }) +</script> diff --git a/dom/media/tests/crashtests/1783765.html b/dom/media/tests/crashtests/1783765.html new file mode 100644 index 0000000000..333ad8d444 --- /dev/null +++ b/dom/media/tests/crashtests/1783765.html @@ -0,0 +1,22 @@ +<script> +var timeout = async function (cmd) { + const timer = new Promise((resolve, reject) => { + const id = setTimeout(() => { + clearTimeout(id) + reject(new Error('Promise timed out!')) + }, 750) + }) + return Promise.race([cmd, timer]) +} +window.addEventListener('load', async () => { + let a = new RTCPeerConnection({ + 'iceServers': [{'urls': 'stun:23.21.150.121'}], + 'peerIdentity': 'x', + }) + let b = await timeout(a.createOffer({ })) + a.setLocalDescription(b) + try { a.setRemoteDescription(b) } catch (e) {} + a.setLocalDescription(b) +}) +</script> + diff --git a/dom/media/tests/crashtests/780790.html b/dom/media/tests/crashtests/780790.html new file mode 100644 index 0000000000..27eb2a961f --- /dev/null +++ b/dom/media/tests/crashtests/780790.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=780790 +--> +<head> + <meta charset="utf-8"> + <title>Simple gUM test - null success callback</title> + <script type="application/javascript"> + navigator.mozGetUserMedia({video: true, fake: true}, null, null); + </script> +</head> + +<body> +</body> +</html> diff --git a/dom/media/tests/crashtests/791270.html b/dom/media/tests/crashtests/791270.html new file mode 100644 index 0000000000..627552fb84 --- /dev/null +++ b/dom/media/tests/crashtests/791270.html @@ -0,0 +1,17 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=791270 +--> +<head> + <meta charset="utf-8"> + <title>Simple PeerConnection Video Test</title> + <script type="application/javascript"> + var pc = new RTCPeerConnection(); + pc.addStream(undefined); + </script> +</head> + +<body> +</body> +</html> diff --git a/dom/media/tests/crashtests/791278.html b/dom/media/tests/crashtests/791278.html new file mode 100644 index 0000000000..fd538f6788 --- /dev/null +++ b/dom/media/tests/crashtests/791278.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=791278 +--> +<head> + <meta charset="utf-8"> + <title>Simple PeerConnection Video Test - Invalid callback</title> + <script type="application/javascript"> + var pc1 = new RTCPeerConnection(); + pc1.setLocalDescription(function() {}); + + var pc2 = new RTCPeerConnection(); + pc2.setRemoteDescription(function() {}); + </script> +</head> + +<body> +</body> +</html> diff --git a/dom/media/tests/crashtests/791330.html b/dom/media/tests/crashtests/791330.html new file mode 100644 index 0000000000..fea2059a29 --- /dev/null +++ b/dom/media/tests/crashtests/791330.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=791330 +--> +<head> + <meta charset="utf-8"> + <title>PeerConnection test - operate on closed connection</title> + <script type="application/javascript"> + function finish() { + document.documentElement.removeAttribute("class"); + } + + function runTest() { + var pc = new RTCPeerConnection(); + pc.close(); + + navigator.mozGetUserMedia({audio: true, fake: true}, function (stream) { + try { + pc.addStream(stream); + pc.createOffer(function (offer) {}); + } + finally { + stream.getTracks().forEach(t => t.stop()); + + finish(); + } + }, function () {}); + } + </script> +</head> + +<body onload="setTimeout(runTest, 100)"> +</body> +</html> diff --git a/dom/media/tests/crashtests/799419.html b/dom/media/tests/crashtests/799419.html new file mode 100644 index 0000000000..7f815e73c8 --- /dev/null +++ b/dom/media/tests/crashtests/799419.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=799419 +--> +<head> + <meta charset="utf-8"> + <title>2 Peer Connections Create and Close + Fake Video</title> + <script type="application/javascript"> + function finish() { + document.documentElement.removeAttribute("class"); + } + + function boom() { + var v0 = new RTCPeerConnection(); + var v1 = new RTCPeerConnection(); + var v2 = document.getElementById("pc1video"); + var v3 = document.getElementById("pc2video"); + navigator.mozGetUserMedia({video:true, fake: true}, + function(stream) {}, function() {}); + v0.close(); + v1.close(); + + finish(); + } + </script> +</head> +<body onload="setTimeout(boom, 100)"> +<video id="pc1video" width="100" height="100" controls></video> +<video id="pc2video" width="100" height="100" controls></video> +</body> +</html> diff --git a/dom/media/tests/crashtests/801227.html b/dom/media/tests/crashtests/801227.html new file mode 100644 index 0000000000..2dded54510 --- /dev/null +++ b/dom/media/tests/crashtests/801227.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=801227 +--> +<head> + <meta charset="utf-8"> + <title>Abort due to page reload</title> + <script type="application/javascript"> + var pc = new RTCPeerConnection(); + + var index = localStorage.index || 0; + if (index < 3) { + localStorage.index = index + 1; + window.location.reload(); + } + + function finish() { + delete localStorage["index"]; + + pc.close(); + document.documentElement.removeAttribute("class"); + } + + navigator.mozGetUserMedia({ audio: true, fake: true }, function (aStream) { + pc.addStream(aStream); + finish(); + }, finish); + </script> +</head> + +<body> +</body> +</html> + diff --git a/dom/media/tests/crashtests/802982.html b/dom/media/tests/crashtests/802982.html new file mode 100644 index 0000000000..f034aff557 --- /dev/null +++ b/dom/media/tests/crashtests/802982.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=802982 +--> +<head> + <meta charset="utf-8"> + <title>Excessive getUserMedia calls</title> + <script type="application/javascript"> + + function finish() { + document.documentElement.removeAttribute("class"); + } + + function boom() + { + for (var j = 0; j < 100; ++j) { + navigator.mozGetUserMedia({video:true}, function(){}, function(){}); + } + finish(); // we're not waiting for success/error callbacks here + } + + </script> +</head> + +<body onload="setTimeout(boom, 100)"> +</html> diff --git a/dom/media/tests/crashtests/812785.html b/dom/media/tests/crashtests/812785.html new file mode 100644 index 0000000000..f26168e49b --- /dev/null +++ b/dom/media/tests/crashtests/812785.html @@ -0,0 +1,70 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=812785 +--> +<head> + <meta charset="utf-8"> + <title>Bug 812785 - WebRTC use-after-free crash</title> + <script type="application/javascript"> + var pc1, pc2, pc1_offer, pc2_answer, localAudio, remoteAudio; + + function onFailure(code) { + stop(); + } + + function stop() { + pc1.close(); pc1 = null; + pc2.close(); pc2 = null; + + var index = localStorage.index || 0; + if (index < 5) { + localStorage.index = index + 1; + window.location.reload(); + } + else { + finish(); + } + } + + function start() { + localAudio = document.getElementById("local"); + remoteAudio = document.getElementById("remote"); + + var stream = localAudio.mozCaptureStreamUntilEnded(); + + pc1 = new RTCPeerConnection(); + pc2 = new RTCPeerConnection(); + + pc1.addStream(stream); + pc1.createOffer(function (offer) { + pc1_offer = offer; + pc1.setLocalDescription(pc1_offer, function () { + pc2.setRemoteDescription(pc1_offer, function () { + pc2.createAnswer(function (answer) { + pc2_answer = answer; + pc2.setLocalDescription(pc2_answer, function () { + pc1.setRemoteDescription(pc2_answer, function step6() { + stop(); + }, onFailure); + }, onFailure); + }, onFailure); + }, onFailure); + }, onFailure); + }, onFailure); + } + + function finish() { + delete localStorage["index"]; + + document.documentElement.removeAttribute("class"); + } + </script> +</head> + +<body onload="setTimeout(start, 100)"> + <audio id="local" controls autoplay><source type="audio/wav" src="" /></audio> + <audio id="remote" controls></audio> +</body> +</html> + diff --git a/dom/media/tests/crashtests/822197.html b/dom/media/tests/crashtests/822197.html new file mode 100644 index 0000000000..97abc44229 --- /dev/null +++ b/dom/media/tests/crashtests/822197.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=822197 +--> +<head> + <meta charset="utf-8"> + <title>Bug 822197 - Many PeerConnections with CreateOffer</title> + <script type="application/javascript"> + var pcArray = []; + + function finish() { + document.documentElement.removeAttribute("class"); + } + + function start() { + for(var i = 0; i < 70; i++) { + var pc = new RTCPeerConnection(); + pc.createOffer(function() {}, function() {}); + pcArray.push(pc); + } + finish(); + } + </script> +</head> + +<body onload="setTimeout(start, 100)"> +</html> diff --git a/dom/media/tests/crashtests/834100.html b/dom/media/tests/crashtests/834100.html new file mode 100644 index 0000000000..0042581564 --- /dev/null +++ b/dom/media/tests/crashtests/834100.html @@ -0,0 +1,25 @@ +<html class="reftest-wait"> + <head> + <script language="javascript"> + +function start() { + remotePC = new RTCPeerConnection(); + var cand = new RTCIceCandidate( + {candidate: "1 1 UDP 1 127.0.0.1 34567 type host", + sdpMid: "helloworld", + sdbMid: "helloworld", // Mis-spelt attribute for bug 833948 compatibility. + sdpMLineIndex: 1 + }); + try {remotePC.addIceCandidate(cand);} catch(e) {} // bug 842075 - remove try when fixed + try {remotePC.addIceCandidate(cand, function(sdp){}, finish);} catch(e) {} // bug 842075 - remove try when fixed + finish(); +} + +function finish(arg) { + document.documentElement.removeAttribute("class"); +} + </script> + </head> + <body onload="setTimeout(start, 100)"> + </body> +</html> diff --git a/dom/media/tests/crashtests/836349.html b/dom/media/tests/crashtests/836349.html new file mode 100644 index 0000000000..651fde46ae --- /dev/null +++ b/dom/media/tests/crashtests/836349.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=836349 +--> +<head> + <meta charset="utf-8"> + <title>Bug 836349</title> + <script type="application/javascript"> + function crash() + { + var pc = new RTCPeerConnection(); + var ld = pc.localDescription; + dump(ld.sdp); + } + </script> +</head> + +<body onload="crash();"> +</html> diff --git a/dom/media/tests/crashtests/837324.html b/dom/media/tests/crashtests/837324.html new file mode 100644 index 0000000000..63162a336b --- /dev/null +++ b/dom/media/tests/crashtests/837324.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=837324 +--> +<head> + <meta charset="utf-8"> + <title>Bug 837324</title> + <script type="application/javascript"> + function finish() { + document.documentElement.removeAttribute("class"); + } + + function start() { + var o0 = new RTCPeerConnection(); + var o1 = new RTCIceCandidate({"candidate":"0 -65535 IP 0 stun.sipgate.net 3227326073 type ::ffff:192.0.2.128 host 2302600701","sdpMid":"video 3907077665 RTP/SAVPF 5000","sdpMLineIndex":7}); + try {o0.addIceCandidate(o1);} catch(e) {} // bug 842075 - remove try when fixed + + finish(); + } + </script> +</head> + +<body onload="setTimeout(start, 100)"> +</html> diff --git a/dom/media/tests/crashtests/855796.html b/dom/media/tests/crashtests/855796.html new file mode 100644 index 0000000000..da46276c53 --- /dev/null +++ b/dom/media/tests/crashtests/855796.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=855796 +--> +<head> + <meta charset="utf-8"> + <title>Bug 855796</title> + <script type="application/javascript"> + var pc1, pc2, pc1_offer, pc2_answer; + + function onFailure(code) { + stop(); + } + + function stop() { + pc1.close(); + pc1 = null; + pc2.close(); + pc2 = null; + document.documentElement.removeAttribute("class"); + } + + function step1(offer) { + pc1_offer = offer; + pc1_offer.sdp = "v=0\r\no=Mozilla-SIPUA 2208 0 IN IP4 0.0.0.0\r\ns=SIP Call\r\nt=0 0\r\na=ice-pwd:4450d5a4a5f097855c16fa079893be18\r\na=fingerprint:sha-256 23:9A:2E:43:94:42:CF:46:68:FC:62:F9:F4:48:61:DB:2F:8C:C9:FF:6B:25:54:9D:41:09:EF:83:A8:19:FC:B6\r\nm=audio 56187 RTP/SAVPF 109 0 8 101\r\nc=IN IP4 77.9.79.167\r\na=rtpmap:109 opus/48000/2\r\na=ptime:20\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-15\r\na=sendrecv\r\na=candidate:0 1 UDP 2113601791 192.168.178.20 56187 typ host\r\na=candidate:1 1 UDP 1694236671 77.9.79.167 56187 typ srflx raddr 192.168.178.20 rport 56187\r\na=candidate:0 2 UDP 2113601790 192.168.178.20 52955 typ host\r\na=candidate:1 2 UDP 1694236670 77.9.79.167 52955 typ srflx raddr 192.168.178.20 rport 52955\r\nm=video 49929 RTP/SAVPF 120\r\nc=IN IP4 77.9.79.167\r\na=rtpmap:120 VP8/90000\r\na=recvonly\r\na=candidate:0 1 UDP 2113601791 192.168.178.20 49929 typ host\r\na=candidate:1 1 UDP 1694236671 77.9.79.167 49929 typ srflx raddr 192.168.178.20 rport 49929\r\na=candidate:0 2 UDP 2113601790 192.168.178.20 50769 typ host\r\na=candidate:1 2 UDP 1694236670 77.9.79.167 50769 typ srflx raddr 192.168.178.20 rport 50769\r\nm=application 54054 SCTP/DTLS 5000 \r\nc=IN IP4 77.9.79.167\r\na=fmtp:HuRUu]Dtcl\\zM,7(OmEU%O$gU]x/z\tD protocol=webrtc-datachannel;streams=16\r\na=sendrecv\r\n"; + pc1.setLocalDescription(pc1_offer, step2, onFailure); + } + + function step2() { + pc2.setRemoteDescription(pc1_offer, step3, onFailure); + } + + function step3() { + pc2.createAnswer(step4, onFailure); + } + + function step4(answer) { + pc2_answer = answer; + pc2.setLocalDescription(pc2_answer, step5, onFailure); + } + + function step5() { + pc1.setRemoteDescription(pc2_answer, step6, onFailure); + } + + function step6() { + stop(); + } + + function start() { + pc1 = new RTCPeerConnection(); + pc2 = new RTCPeerConnection(); + navigator.mozGetUserMedia({audio:true, video:true, fake:true}, function(s) { + pc1.addStream(s); + navigator.mozGetUserMedia({audio:true, video:true, fake:true}, function(s) { + pc2.addStream(s); + pc1.createOffer(step1, onFailure); + }, onFailure); + }, onFailure); + } + </script> +</head> + +<body onload="setTimeout(start, 100)"> +</html> diff --git a/dom/media/tests/crashtests/860143.html b/dom/media/tests/crashtests/860143.html new file mode 100644 index 0000000000..2d17a8dace --- /dev/null +++ b/dom/media/tests/crashtests/860143.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=860143 +--> +<head> + <meta charset="utf-8"> + <title>bug 860143</title> + <script type="application/javascript"> + function start() { + var o0 = new window.RTCPeerConnection({ + iceServers: [ + { + url: "turn:AAAAAAAAAAAAAAAAA AAAAAAAAAAA AAAAAAAAAAAAA AA AAAAA AAAAAAAAAAA AAAAAAAAAAAAAAAA AAAAA AAAAAAAAAA, AAAAAAAAAAAAAAAA AAA AAAAAAAAAAAAAAA" + } + ] + }); + o0.close(); + } + </script> +</head> + +<body onload="start()"> +</body> +</html> diff --git a/dom/media/tests/crashtests/861958.html b/dom/media/tests/crashtests/861958.html new file mode 100644 index 0000000000..d6ea7e2e84 --- /dev/null +++ b/dom/media/tests/crashtests/861958.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=861958 +--> +<head> + <meta charset="utf-8"> + <title>bug 861958</title> + <script type="application/javascript"> + function start() { + var o0 = new window.RTCPeerConnection(); + var o1 = o0.createDataChannel("foo", { + "protocol": "text/char", + "preset": false, + "stream": 512 + }); + o0.close(); + } + </script> +</head> + +<body onload="start()"> +</body> +</html> diff --git a/dom/media/tests/crashtests/863929.html b/dom/media/tests/crashtests/863929.html new file mode 100644 index 0000000000..dc534e264f --- /dev/null +++ b/dom/media/tests/crashtests/863929.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=863929 +--> +<head> + <meta charset="utf-8"> + <title>Bug 863929</title> + <script type="application/javascript"> + var pc1, pc2, pc1_offer, pc2_answer; + + function onFailure(code) { + stop(); + } + + function stop() { + pc1.close(); + pc1 = null; + pc2.close(); + pc2 = null; + document.documentElement.removeAttribute("class"); + } + + function step1(offer) { + pc1_offer = offer; + pc1_offer.sdp = 'v=0\r\no=Mozilla-SIPUA 2208 0 IN IP4 0.0.0.0\r\ns=SIP Call\r\nt=0 0\r\na=ice-ufrag:96e36277\r\na=ice-pwd:4450d5a4a5f097855c16fa079893be18\r\na=fingerprint:sha-256 23:9A:2E:43:94:42:CF:46:68:FC:62:F9:F4:48:61:DB:2F:8C:C9:FF:6B:25:54:9D:41:09:EF:83:A8:19:FC:B6\r\nm=audio 56187 RTP/SAVPF 109 0 8 101\r\nc=IN IP4 77.9.79.167\r\na=rtpmap:109 opus/48000/2\r\na=ptime:20\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-15\r\na=sendrecv\r\na=candidate:0 1 UDP 2113601791 192.168.178.20 56187 typ host\r\na=candidate:1 1 UDP 1694236671 77.9.79.167 56187 typ srflx raddr 192.168.178.20 rport 56187\r\na=candidate:0 2 UDP 2113601790 192.168.178.20 52955 typ host\r\na=candidate:1 2 UDP 1694236670 77.9.79.167 52955 typ srflx raddr 192.168.178.20 rport 52955\r\nm=video 49929 RTP/SAVPF 120\r\nc=IN IP4 77.9.79.167\r\na=rtpmap:120 telephone-event/90000\r\na=recvonly\r\na=candidate:0 1 UDP 2113601791 192.168.178.20 49929 typ host\r\na=candidate:1 1 UDP 1694236671 77.9.79.167 49929 typ srflx raddr 192.168.178.20 rport 49929\r\na=candidate:0 2 UDP 2113601790 192.168.178.20 50769 typ host\r\na=candidate:1 2 UDP 1694236670 77.9.79.167 50769 typ srflx raddr 192.168.178.20 rport 50769\r\nm=application 54054 SCTP/DTLS 5000 \r\nc=IN IP4 77.9.79.167\r\na=fmtp:5000 protocol=webrtc-datachannel;streams=16\r\na=sendrecv\r\n'; + pc1.setLocalDescription(pc1_offer, step2, onFailure); + } + + function step2() { + pc2.setRemoteDescription(pc1_offer, step3, onFailure); + } + + function step3() { + pc2.createAnswer(step4, onFailure); + } + + function step4(answer) { + pc2_answer = answer; + pc2.setLocalDescription(pc2_answer, step5, onFailure); + } + + function step5() { + pc1.setRemoteDescription(pc2_answer, step6, onFailure); + } + + function step6() { + stop(); + } + + function start() { + pc1 = new RTCPeerConnection(); + pc2 = new RTCPeerConnection(); + navigator.mozGetUserMedia({audio:true, video:true, fake:true}, function(s) { + pc1.addStream(s); + navigator.mozGetUserMedia({audio:true, video:true, fake:true}, function(s) { + pc2.addStream(s); + pc1.createOffer(step1, onFailure); + }, onFailure); + }, onFailure); + } + </script> +</head> + +<body onload="start()"> +</html> diff --git a/dom/media/tests/crashtests/crashtests.list b/dom/media/tests/crashtests/crashtests.list new file mode 100644 index 0000000000..fd4ed80607 --- /dev/null +++ b/dom/media/tests/crashtests/crashtests.list @@ -0,0 +1,42 @@ +defaults pref(media.peerconnection.enabled,true) pref(media.navigator.permission.disabled,true) pref(dom.disable_open_during_load,false) pref(media.devices.insecure.enabled,true) pref(media.getusermedia.insecure.enabled,true) + +load 780790.html +load 791270.html +load 791278.html +load 791330.html +load 799419.html +load 802982.html +skip-if(isDebugBuild) load 812785.html +load 834100.html +load 836349.html +load 837324.html +load 855796.html +load 860143.html +load 861958.html +load 863929.html +load 1281695.html +load 1306476.html +load 1348381.html +load 1367930_1.html +load 1367930_2.html +asserts-if(Android,0-1) pref(browser.link.open_newwindow,2) load 1429507_1.html # window.open() in tab doesn't work for crashtest in e10s, this opens a new window instead +asserts-if(Android,0-1) pref(browser.link.open_newwindow,2) load 1429507_2.html # window.open() in tab doesn't work for crashtest in e10s, this opens a new window instead +load 1443212.html +asserts-if(Android,0-2) load 1453030.html +load 1468451.html +skip-if(wayland) skip-if(Android) load 1490700.html # wayland: bug 1856368, No screenshare on Android +load 1505957.html +load 1509442.html +load 1511130.html +load 1510848.html +load 1516292.html +load 1576938.html +skip-if(Android) pref(media.getusermedia.audiocapture.enabled,true) load 1573536.html +skip-if(!Android) pref(media.getusermedia.audiocapture.enabled,true) pref(media.navigator.permission.device,false) load 1573536.html # media.navigator.permission.device is mobile-only, so other platforms fail to set it (Bug 1350948) +load 1594136.html +load 1749308.html +load 1764915.html +load 1764933.html +load 1764940.html +load 1766668.html +load 1783765.html diff --git a/dom/media/tests/crashtests/datachannel-oom.html b/dom/media/tests/crashtests/datachannel-oom.html new file mode 100644 index 0000000000..e55ec651be --- /dev/null +++ b/dom/media/tests/crashtests/datachannel-oom.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title></title> + <script type="application/javascript"> + function start() { + var size = 2147483638; + new RTCPeerConnection().createDataChannel('a').send(new Uint8Array(size)); + var a = "a"; + var count = Math.floor(Math.log2(size)) - 1; + for (var i = 0; i < count; i++) { + a += a; + } + new RTCPeerConnection().createDataChannel('a').send(a) + } + </script> +</head> + +<body onload="start()"> +</body> +</html> |