diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/media/mediasource/test | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
297 files changed, 4787 insertions, 0 deletions
diff --git a/dom/media/mediasource/test/.eslintrc.js b/dom/media/mediasource/test/.eslintrc.js new file mode 100644 index 0000000000..e283e384ba --- /dev/null +++ b/dom/media/mediasource/test/.eslintrc.js @@ -0,0 +1,28 @@ +"use strict"; + +module.exports = { + // Globals from mediasource.js. We use false to indicate they should not + // be overwritten in scripts. + globals: { + addMSEPrefs: false, + fetchAndLoad: false, + fetchAndLoadAsync: false, + fetchWithXHR: false, + logEvents: false, + loadSegment: false, + must_not_reject: false, + must_not_throw: false, + must_reject: false, + must_throw: false, + once: false, + range: false, + runWithMSE: false, + wait: false, + waitUntilTime: false, + }, + // Use const/let instead of var for tighter scoping, avoiding redeclaration + rules: { + "no-var": "error", + "prefer-const": "error", + }, +}; diff --git a/dom/media/mediasource/test/1516754.webm b/dom/media/mediasource/test/1516754.webm Binary files differnew file mode 100644 index 0000000000..05a008d906 --- /dev/null +++ b/dom/media/mediasource/test/1516754.webm diff --git a/dom/media/mediasource/test/1516754.webm^headers^ b/dom/media/mediasource/test/1516754.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/1516754.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/aac20-48000-64000-1.m4s b/dom/media/mediasource/test/aac20-48000-64000-1.m4s Binary files differnew file mode 100644 index 0000000000..56506e1f2d --- /dev/null +++ b/dom/media/mediasource/test/aac20-48000-64000-1.m4s diff --git a/dom/media/mediasource/test/aac20-48000-64000-1.m4s^headers^ b/dom/media/mediasource/test/aac20-48000-64000-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/aac20-48000-64000-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/aac20-48000-64000-2.m4s b/dom/media/mediasource/test/aac20-48000-64000-2.m4s Binary files differnew file mode 100644 index 0000000000..3faff17ebf --- /dev/null +++ b/dom/media/mediasource/test/aac20-48000-64000-2.m4s diff --git a/dom/media/mediasource/test/aac20-48000-64000-2.m4s^headers^ b/dom/media/mediasource/test/aac20-48000-64000-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/aac20-48000-64000-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/aac20-48000-64000-init.mp4 b/dom/media/mediasource/test/aac20-48000-64000-init.mp4 Binary files differnew file mode 100644 index 0000000000..b70e016512 --- /dev/null +++ b/dom/media/mediasource/test/aac20-48000-64000-init.mp4 diff --git a/dom/media/mediasource/test/aac20-48000-64000-init.mp4^headers^ b/dom/media/mediasource/test/aac20-48000-64000-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/aac20-48000-64000-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/aac51-48000-128000-1.m4s b/dom/media/mediasource/test/aac51-48000-128000-1.m4s Binary files differnew file mode 100644 index 0000000000..3424acfecc --- /dev/null +++ b/dom/media/mediasource/test/aac51-48000-128000-1.m4s diff --git a/dom/media/mediasource/test/aac51-48000-128000-1.m4s^headers^ b/dom/media/mediasource/test/aac51-48000-128000-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/aac51-48000-128000-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/aac51-48000-128000-2.m4s b/dom/media/mediasource/test/aac51-48000-128000-2.m4s Binary files differnew file mode 100644 index 0000000000..b02bfd043d --- /dev/null +++ b/dom/media/mediasource/test/aac51-48000-128000-2.m4s diff --git a/dom/media/mediasource/test/aac51-48000-128000-2.m4s^headers^ b/dom/media/mediasource/test/aac51-48000-128000-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/aac51-48000-128000-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/aac51-48000-128000-init.mp4 b/dom/media/mediasource/test/aac51-48000-128000-init.mp4 Binary files differnew file mode 100644 index 0000000000..7d62401f28 --- /dev/null +++ b/dom/media/mediasource/test/aac51-48000-128000-init.mp4 diff --git a/dom/media/mediasource/test/aac51-48000-128000-init.mp4^headers^ b/dom/media/mediasource/test/aac51-48000-128000-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/aac51-48000-128000-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/avc3/init.mp4 b/dom/media/mediasource/test/avc3/init.mp4 Binary files differnew file mode 100644 index 0000000000..12fc38bd20 --- /dev/null +++ b/dom/media/mediasource/test/avc3/init.mp4 diff --git a/dom/media/mediasource/test/avc3/init.mp4^headers^ b/dom/media/mediasource/test/avc3/init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/avc3/init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/avc3/segment1.m4s b/dom/media/mediasource/test/avc3/segment1.m4s Binary files differnew file mode 100644 index 0000000000..d95a6adf02 --- /dev/null +++ b/dom/media/mediasource/test/avc3/segment1.m4s diff --git a/dom/media/mediasource/test/avc3/segment1.m4s^headers^ b/dom/media/mediasource/test/avc3/segment1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/avc3/segment1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop1.m4s b/dom/media/mediasource/test/bipbop/bipbop1.m4s Binary files differnew file mode 100644 index 0000000000..a237f2e91e --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop10.m4s b/dom/media/mediasource/test/bipbop/bipbop10.m4s Binary files differnew file mode 100644 index 0000000000..d1f5e6a0b0 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop10.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop10.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop10.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop10.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop11.m4s b/dom/media/mediasource/test/bipbop/bipbop11.m4s Binary files differnew file mode 100644 index 0000000000..57232fb359 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop11.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop11.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop11.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop11.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop12.m4s b/dom/media/mediasource/test/bipbop/bipbop12.m4s Binary files differnew file mode 100644 index 0000000000..f9b18713ee --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop12.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop12.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop12.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop12.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop13.m4s b/dom/media/mediasource/test/bipbop/bipbop13.m4s Binary files differnew file mode 100644 index 0000000000..f2a876946c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop13.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop13.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop13.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop13.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop2.m4s b/dom/media/mediasource/test/bipbop/bipbop2.m4s Binary files differnew file mode 100644 index 0000000000..baa0d8578c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop2s.mp4 b/dom/media/mediasource/test/bipbop/bipbop2s.mp4 Binary files differnew file mode 100644 index 0000000000..4fd8b9cb6e --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop2s.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop2s.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop2s.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop2s.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop3.m4s b/dom/media/mediasource/test/bipbop/bipbop3.m4s Binary files differnew file mode 100644 index 0000000000..ed313e668c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop3.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop3.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop4.m4s b/dom/media/mediasource/test/bipbop/bipbop4.m4s Binary files differnew file mode 100644 index 0000000000..7709ac08c5 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop4.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop4.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop5.m4s b/dom/media/mediasource/test/bipbop/bipbop5.m4s Binary files differnew file mode 100644 index 0000000000..6d36788e44 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop5.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop5.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop5.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop5.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop6.m4s b/dom/media/mediasource/test/bipbop/bipbop6.m4s Binary files differnew file mode 100644 index 0000000000..64f475c700 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop6.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop6.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop6.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop6.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop7.m4s b/dom/media/mediasource/test/bipbop/bipbop7.m4s Binary files differnew file mode 100644 index 0000000000..c148918d6d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop7.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop7.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop7.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop7.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop8.m4s b/dom/media/mediasource/test/bipbop/bipbop8.m4s Binary files differnew file mode 100644 index 0000000000..707dd48485 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop8.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop8.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop8.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop8.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop9.m4s b/dom/media/mediasource/test/bipbop/bipbop9.m4s Binary files differnew file mode 100644 index 0000000000..538cf72a4d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop9.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop9.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop9.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop9.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_300-3s.webm b/dom/media/mediasource/test/bipbop/bipbop_300-3s.webm Binary files differnew file mode 100644 index 0000000000..db578dc96c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_300-3s.webm diff --git a/dom/media/mediasource/test/bipbop/bipbop_300-3s.webm^headers^ b/dom/media/mediasource/test/bipbop/bipbop_300-3s.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_300-3s.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video1.m4s b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video1.m4s Binary files differnew file mode 100644 index 0000000000..3dad336e8e --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video2.m4s b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video2.m4s Binary files differnew file mode 100644 index 0000000000..dd7491241f --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-videoinit.mp4 b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-videoinit.mp4 Binary files differnew file mode 100644 index 0000000000..b1a2d44058 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-videoinit.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-videoinit.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-videoinit.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-videoinit.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio1.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio1.m4s Binary files differnew file mode 100644 index 0000000000..33da98b5a9 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio10.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio10.m4s Binary files differnew file mode 100644 index 0000000000..36a98afd29 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio10.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio10.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio10.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio10.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio11.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio11.m4s Binary files differnew file mode 100644 index 0000000000..23d4aa8d86 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio11.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio11.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio11.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio11.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio2.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio2.m4s Binary files differnew file mode 100644 index 0000000000..96f4bcc344 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio3.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio3.m4s Binary files differnew file mode 100644 index 0000000000..7de4bd0ca1 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio3.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio3.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio4.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio4.m4s Binary files differnew file mode 100644 index 0000000000..494c71eb92 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio4.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio4.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio5.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio5.m4s Binary files differnew file mode 100644 index 0000000000..b50496b6ce --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio5.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio5.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio5.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio5.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio6.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio6.m4s Binary files differnew file mode 100644 index 0000000000..02cf4d363c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio6.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio6.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio6.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio6.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio7.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio7.m4s Binary files differnew file mode 100644 index 0000000000..bb2252889f --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio7.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio7.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio7.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio7.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio8.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio8.m4s Binary files differnew file mode 100644 index 0000000000..04a6a7af91 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio8.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio8.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio8.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio8.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio9.m4s b/dom/media/mediasource/test/bipbop/bipbop_audio9.m4s Binary files differnew file mode 100644 index 0000000000..cb94b529a7 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio9.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_audio9.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audio9.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audio9.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_audioinit.mp4 b/dom/media/mediasource/test/bipbop/bipbop_audioinit.mp4 Binary files differnew file mode 100644 index 0000000000..bbf272197d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audioinit.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_audioinit.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_audioinit.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_audioinit.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_dash.mpd b/dom/media/mediasource/test/bipbop/bipbop_dash.mpd new file mode 100644 index 0000000000..532cdc65d5 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_dash.mpd @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H0M9.98S" profiles="urn:mpeg:dash:profile:full:2011"> + <ProgramInformation moreInformationURL="http://gpac.sourceforge.net"> + <Title>bipbop_dash.mpd handcrafted by JYA</Title> + </ProgramInformation> + + <Period duration="PT0H0M9.98S"> + <AdaptationSet segmentAlignment="true" maxWidth="400" maxHeight="300" maxFrameRate="90000" par="4:3" lang="und"> + <Representation id="1" mimeType="video/mp4" codecs="avc1.4d4015" width="400" height="300" frameRate="90000" sar="1:1" startWithSAP="1" bandwidth="226425"> + <SegmentList timescale="90000" duration="69043"> + <Initialization sourceURL="bipbop_videoinit.mp4"/> + <SegmentURL media="bipbop_video1.m4s"/> + <SegmentURL media="bipbop_video2.m4s"/> + <SegmentURL media="bipbop_video3.m4s"/> + <SegmentURL media="bipbop_video4.m4s"/> + <SegmentURL media="bipbop_video5.m4s"/> + <SegmentURL media="bipbop_video6.m4s"/> + <SegmentURL media="bipbop_video7.m4s"/> + <SegmentURL media="bipbop_video8.m4s"/> + <SegmentURL media="bipbop_video9.m4s"/> + <SegmentURL media="bipbop_video10.m4s"/> + <SegmentURL media="bipbop_video11.m4s"/> + <SegmentURL media="bipbop_video12.m4s"/> + <SegmentURL media="bipbop_video13.m4s"/> + </SegmentList> + </Representation> + </AdaptationSet> + <AdaptationSet segmentAlignment="true" lang="und"> + <Representation id="1" mimeType="audio/mp4" codecs="mp4a.40.2" audioSamplingRate="22050" startWithSAP="1" bandwidth="7206"> + <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/> + <SegmentList timescale="22050" duration="20101"> + <Initialization sourceURL="bipbop_audioinit.mp4"/> + <SegmentURL media="bipbop_audio1.m4s"/> + <SegmentURL media="bipbop_audio2.m4s"/> + <SegmentURL media="bipbop_audio3.m4s"/> + <SegmentURL media="bipbop_audio4.m4s"/> + <SegmentURL media="bipbop_audio5.m4s"/> + <SegmentURL media="bipbop_audio6.m4s"/> + <SegmentURL media="bipbop_audio7.m4s"/> + <SegmentURL media="bipbop_audio8.m4s"/> + <SegmentURL media="bipbop_audio9.m4s"/> + <SegmentURL media="bipbop_audio10.m4s"/> + <SegmentURL media="bipbop_audio11.m4s"/> + </SegmentList> + </Representation> + </AdaptationSet> + </Period> +</MPD> diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-1.m4s Binary files differnew file mode 100644 index 0000000000..2b95d49de9 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-2.m4s Binary files differnew file mode 100644 index 0000000000..3d95e7e2bf --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-init.mp4 Binary files differnew file mode 100644 index 0000000000..cc7a48b5ce --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.0-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-1.m4s Binary files differnew file mode 100644 index 0000000000..d67c4ef4cc --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-2.m4s Binary files differnew file mode 100644 index 0000000000..be155dbb9c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-init.mp4 Binary files differnew file mode 100644 index 0000000000..b67beb9548 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-1.m4s Binary files differnew file mode 100644 index 0000000000..2056aaec7f --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-2.m4s Binary files differnew file mode 100644 index 0000000000..ccdad15c39 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-init.mp4 Binary files differnew file mode 100644 index 0000000000..5b618c64d8 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.2-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-1.m4s Binary files differnew file mode 100644 index 0000000000..c834ea6ae8 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-2.m4s Binary files differnew file mode 100644 index 0000000000..aad6b355ae --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-init.mp4 Binary files differnew file mode 100644 index 0000000000..1f878bc84b --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.3-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-1.m4s Binary files differnew file mode 100644 index 0000000000..88f05ee8bb --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-2.m4s Binary files differnew file mode 100644 index 0000000000..23ecab42e2 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-init.mp4 Binary files differnew file mode 100644 index 0000000000..3e5ad8ad3b --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.4-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-1.m4s Binary files differnew file mode 100644 index 0000000000..df05700d87 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-2.m4s Binary files differnew file mode 100644 index 0000000000..14daa425c7 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-init.mp4 Binary files differnew file mode 100644 index 0000000000..2101dd876c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.5-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-1.m4s Binary files differnew file mode 100644 index 0000000000..ef0a4614fc --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-2.m4s Binary files differnew file mode 100644 index 0000000000..8f7c819867 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-init.mp4 Binary files differnew file mode 100644 index 0000000000..91f48ab6a1 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.6-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-1.m4s Binary files differnew file mode 100644 index 0000000000..dded8a37af --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-2.m4s Binary files differnew file mode 100644 index 0000000000..2a3c10859c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-init.mp4 Binary files differnew file mode 100644 index 0000000000..cf45610f7b --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.7-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-1.m4s Binary files differnew file mode 100644 index 0000000000..74f0addd4f --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-2.m4s Binary files differnew file mode 100644 index 0000000000..f062c85333 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-init.mp4 Binary files differnew file mode 100644 index 0000000000..30a0ab0fed --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.8-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-1.m4s Binary files differnew file mode 100644 index 0000000000..b74ebf1f64 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-2.m4s Binary files differnew file mode 100644 index 0000000000..eabd8a3411 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-init.mp4 Binary files differnew file mode 100644 index 0000000000..449722b0fd --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_0.9-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-1.m4s Binary files differnew file mode 100644 index 0000000000..e032afcc4f --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-2.m4s Binary files differnew file mode 100644 index 0000000000..6542c8d3d3 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-init.mp4 Binary files differnew file mode 100644 index 0000000000..0a9da048f0 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.0-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-1.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-1.m4s Binary files differnew file mode 100644 index 0000000000..1b8b22be4a --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-2.m4s b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-2.m4s Binary files differnew file mode 100644 index 0000000000..3de855982f --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-init.mp4 b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-init.mp4 Binary files differnew file mode 100644 index 0000000000..80b3814f7c --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-init.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-init.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-init.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_offset_1.1-init.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_trailing_skip_box_video1.m4s b/dom/media/mediasource/test/bipbop/bipbop_trailing_skip_box_video1.m4s Binary files differnew file mode 100644 index 0000000000..fa5d454277 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_trailing_skip_box_video1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_trailing_skip_box_video1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_trailing_skip_box_video1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_trailing_skip_box_video1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video1.m4s b/dom/media/mediasource/test/bipbop/bipbop_video1.m4s Binary files differnew file mode 100644 index 0000000000..9291182516 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video1.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video1.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video1.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video1.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video10.m4s b/dom/media/mediasource/test/bipbop/bipbop_video10.m4s Binary files differnew file mode 100644 index 0000000000..72c7afaca7 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video10.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video10.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video10.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video10.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video11.m4s b/dom/media/mediasource/test/bipbop/bipbop_video11.m4s Binary files differnew file mode 100644 index 0000000000..e6109f5e71 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video11.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video11.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video11.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video11.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video12.m4s b/dom/media/mediasource/test/bipbop/bipbop_video12.m4s Binary files differnew file mode 100644 index 0000000000..5c54a510f7 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video12.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video12.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video12.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video12.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video13.m4s b/dom/media/mediasource/test/bipbop/bipbop_video13.m4s Binary files differnew file mode 100644 index 0000000000..c64f38a337 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video13.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video13.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video13.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video13.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video2.m4s b/dom/media/mediasource/test/bipbop/bipbop_video2.m4s Binary files differnew file mode 100644 index 0000000000..cd34fae561 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video2.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video2.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video2.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video2.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video3.m4s b/dom/media/mediasource/test/bipbop/bipbop_video3.m4s Binary files differnew file mode 100644 index 0000000000..5a13340043 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video3.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video3.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video3.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video3.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video4.m4s b/dom/media/mediasource/test/bipbop/bipbop_video4.m4s Binary files differnew file mode 100644 index 0000000000..e8d96b6ed1 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video4.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video4.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video4.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video4.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video5.m4s b/dom/media/mediasource/test/bipbop/bipbop_video5.m4s Binary files differnew file mode 100644 index 0000000000..ca6a820468 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video5.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video5.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video5.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video5.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video6.m4s b/dom/media/mediasource/test/bipbop/bipbop_video6.m4s Binary files differnew file mode 100644 index 0000000000..fe9824355b --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video6.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video6.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video6.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video6.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video7.m4s b/dom/media/mediasource/test/bipbop/bipbop_video7.m4s Binary files differnew file mode 100644 index 0000000000..3351fa6859 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video7.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video7.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video7.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video7.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video8.m4s b/dom/media/mediasource/test/bipbop/bipbop_video8.m4s Binary files differnew file mode 100644 index 0000000000..af26ae5f9e --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video8.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video8.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video8.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video8.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_video9.m4s b/dom/media/mediasource/test/bipbop/bipbop_video9.m4s Binary files differnew file mode 100644 index 0000000000..25be672c15 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video9.m4s diff --git a/dom/media/mediasource/test/bipbop/bipbop_video9.m4s^headers^ b/dom/media/mediasource/test/bipbop/bipbop_video9.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_video9.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbop_videoinit.mp4 b/dom/media/mediasource/test/bipbop/bipbop_videoinit.mp4 Binary files differnew file mode 100644 index 0000000000..7c9c533c36 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_videoinit.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbop_videoinit.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbop_videoinit.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbop_videoinit.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bipbop/bipbopinit.mp4 b/dom/media/mediasource/test/bipbop/bipbopinit.mp4 Binary files differnew file mode 100644 index 0000000000..39f0575a71 --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbopinit.mp4 diff --git a/dom/media/mediasource/test/bipbop/bipbopinit.mp4^headers^ b/dom/media/mediasource/test/bipbop/bipbopinit.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/bipbop/bipbopinit.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/bug1718709_high_res.mp4 b/dom/media/mediasource/test/bug1718709_high_res.mp4 Binary files differnew file mode 100644 index 0000000000..3f211d2370 --- /dev/null +++ b/dom/media/mediasource/test/bug1718709_high_res.mp4 diff --git a/dom/media/mediasource/test/bug1718709_low_res.mp4 b/dom/media/mediasource/test/bug1718709_low_res.mp4 Binary files differnew file mode 100644 index 0000000000..dc5cd6b7f1 --- /dev/null +++ b/dom/media/mediasource/test/bug1718709_low_res.mp4 diff --git a/dom/media/mediasource/test/crashtests/1005366.html b/dom/media/mediasource/test/crashtests/1005366.html new file mode 100644 index 0000000000..aa8b7f652e --- /dev/null +++ b/dom/media/mediasource/test/crashtests/1005366.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +/* +user_pref("media.mediasource.enabled", true); +*/ + +function boom() +{ + var source = new window.MediaSource(); + var videoElement = document.createElementNS('http://www.w3.org/1999/xhtml', 'video'); + videoElement.src = URL.createObjectURL(source); + + setTimeout(function() { + var buf = source.addSourceBuffer("video/webm"); + buf.abort(); + buf.appendBuffer(new Float32Array(203)); + }, 0); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/mediasource/test/crashtests/1059035.html b/dom/media/mediasource/test/crashtests/1059035.html new file mode 100644 index 0000000000..9dfda34b82 --- /dev/null +++ b/dom/media/mediasource/test/crashtests/1059035.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +/* +user_pref("media.mediasource.enabled", true); +*/ + +function boom() +{ + var mediaSource = new MediaSource(); + var htmlAudio = document.createElement("audio"); + htmlAudio.src = URL.createObjectURL(mediaSource); + + setTimeout(function() { + var sourceBuffer = mediaSource.addSourceBuffer("video/webm"); + mediaSource.removeSourceBuffer(sourceBuffer); + sourceBuffer.remove(0, 0); + }, 0); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/mediasource/test/crashtests/926665.html b/dom/media/mediasource/test/crashtests/926665.html new file mode 100644 index 0000000000..ccac5a7644 --- /dev/null +++ b/dom/media/mediasource/test/crashtests/926665.html @@ -0,0 +1,26 @@ +<html>
+<head>
+<meta charset="UTF-8">
+<script style="display: none;" id="fuzz1" type="text/javascript">
+
+function boom()
+{
+ var mediaSource = new window.MediaSource();
+ var mediaSourceURL = URL.createObjectURL(mediaSource);
+ var v1 = document.createElement('video');
+ v1.src = mediaSourceURL;
+ mediaSource.addEventListener("sourceopen", function (e) {
+ var v2 = document.createElement('video');
+ v2.src = mediaSourceURL;
+ setTimeout(function () {
+ v2.src = "data:text/plain,1";
+ v1.src = "data:text/plain,2";
+ }, 0);
+ });
+}
+
+</script>
+</head>
+
+<body onload="boom();"></body>
+</html>
diff --git a/dom/media/mediasource/test/crashtests/931388.html b/dom/media/mediasource/test/crashtests/931388.html new file mode 100644 index 0000000000..cdb5bd9add --- /dev/null +++ b/dom/media/mediasource/test/crashtests/931388.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + var v = document.createElement('video'); + v.src = URL.createObjectURL(new MediaSource()); + v.play(); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/dom/media/mediasource/test/crashtests/crashtests.list b/dom/media/mediasource/test/crashtests/crashtests.list new file mode 100644 index 0000000000..e16ec261d2 --- /dev/null +++ b/dom/media/mediasource/test/crashtests/crashtests.list @@ -0,0 +1,4 @@ +test-pref(media.mediasource.enabled,true) load 926665.html +test-pref(media.mediasource.enabled,true) load 931388.html +test-pref(media.mediasource.enabled,true) load 1005366.html +test-pref(media.mediasource.enabled,true) load 1059035.html diff --git a/dom/media/mediasource/test/flac/00001.m4s b/dom/media/mediasource/test/flac/00001.m4s Binary files differnew file mode 100644 index 0000000000..02745ba2f8 --- /dev/null +++ b/dom/media/mediasource/test/flac/00001.m4s diff --git a/dom/media/mediasource/test/flac/00001.m4s^headers^ b/dom/media/mediasource/test/flac/00001.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/flac/00001.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/flac/00002.m4s b/dom/media/mediasource/test/flac/00002.m4s Binary files differnew file mode 100644 index 0000000000..cd6b1f5949 --- /dev/null +++ b/dom/media/mediasource/test/flac/00002.m4s diff --git a/dom/media/mediasource/test/flac/00002.m4s^headers^ b/dom/media/mediasource/test/flac/00002.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/flac/00002.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/flac/00003.m4s b/dom/media/mediasource/test/flac/00003.m4s Binary files differnew file mode 100644 index 0000000000..c5b78e1ce0 --- /dev/null +++ b/dom/media/mediasource/test/flac/00003.m4s diff --git a/dom/media/mediasource/test/flac/00003.m4s^headers^ b/dom/media/mediasource/test/flac/00003.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/flac/00003.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/flac/IS.mp4 b/dom/media/mediasource/test/flac/IS.mp4 Binary files differnew file mode 100644 index 0000000000..7f108602fd --- /dev/null +++ b/dom/media/mediasource/test/flac/IS.mp4 diff --git a/dom/media/mediasource/test/flac/IS.mp4^headers^ b/dom/media/mediasource/test/flac/IS.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/flac/IS.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/init-trackid2.mp4 b/dom/media/mediasource/test/init-trackid2.mp4 Binary files differnew file mode 100644 index 0000000000..c96da9d4df --- /dev/null +++ b/dom/media/mediasource/test/init-trackid2.mp4 diff --git a/dom/media/mediasource/test/init-trackid2.mp4^headers^ b/dom/media/mediasource/test/init-trackid2.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/init-trackid2.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/init-trackid3.mp4 b/dom/media/mediasource/test/init-trackid3.mp4 Binary files differnew file mode 100644 index 0000000000..e37d8ea098 --- /dev/null +++ b/dom/media/mediasource/test/init-trackid3.mp4 diff --git a/dom/media/mediasource/test/init-trackid3.mp4^headers^ b/dom/media/mediasource/test/init-trackid3.mp4^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/init-trackid3.mp4^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/mediasource.js b/dom/media/mediasource/test/mediasource.js new file mode 100644 index 0000000000..71d8d4ef9f --- /dev/null +++ b/dom/media/mediasource/test/mediasource.js @@ -0,0 +1,235 @@ +// Helpers for Media Source Extensions tests + +let gMSETestPrefs = [ + ["media.mediasource.enabled", true], + ["media.audio-max-decode-error", 0], + ["media.video-max-decode-error", 0], +]; + +// Called before runWithMSE() to set the prefs before running MSE tests. +function addMSEPrefs(...prefs) { + gMSETestPrefs = gMSETestPrefs.concat(prefs); +} + +async function runWithMSE(testFunction) { + await once(window, "load"); + await SpecialPowers.pushPrefEnv({ set: gMSETestPrefs }); + + const ms = new MediaSource(); + + const el = document.createElement("video"); + el.src = URL.createObjectURL(ms); + el.preload = "auto"; + + document.body.appendChild(el); + SimpleTest.registerCleanupFunction(() => { + el.remove(); + el.removeAttribute("src"); + el.load(); + }); + try { + await testFunction(ms, el); + } catch (e) { + ok(false, `${testFunction.name} failed with error ${e.name}`); + throw e; + } +} + +async function fetchWithXHR(uri) { + return new Promise(resolve => { + const 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(); + }); +} + +function range(start, end) { + const rv = []; + for (let i = start; i < end; ++i) { + rv.push(i); + } + return rv; +} + +function must_throw(f, msg, error = true) { + try { + f(); + ok(!error, msg); + } catch (e) { + ok(error, msg); + if (error === true) { + ok( + false, + `Please provide name of expected error! Got ${e.name}: ${e.message}.` + ); + } else if (e.name != error) { + throw e; + } + } +} + +async function must_reject(f, msg, error = true) { + try { + await f(); + ok(!error, msg); + } catch (e) { + ok(error, msg); + if (error === true) { + ok( + false, + `Please provide name of expected error! Got ${e.name}: ${e.message}.` + ); + } else if (e.name != error) { + throw e; + } + } +} + +const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); + +const must_not_throw = (f, msg) => must_throw(f, msg, false); +const must_not_reject = (f, msg) => must_reject(f, msg, false); + +async function once(target, name) { + return new Promise(r => target.addEventListener(name, r, { once: true })); +} + +function timeRangeToString(r) { + let str = "TimeRanges: "; + for (let i = 0; i < r.length; i++) { + str += "[" + r.start(i) + ", " + r.end(i) + ")"; + } + return str; +} + +async function loadSegment(sb, typedArrayOrArrayBuffer) { + const typedArray = + typedArrayOrArrayBuffer instanceof ArrayBuffer + ? new Uint8Array(typedArrayOrArrayBuffer) + : typedArrayOrArrayBuffer; + info( + `Loading buffer: [${typedArray.byteOffset}, ${ + typedArray.byteOffset + typedArray.byteLength + })` + ); + const beforeBuffered = timeRangeToString(sb.buffered); + const p = once(sb, "update"); + sb.appendBuffer(typedArray); + await p; + const afterBuffered = timeRangeToString(sb.buffered); + info( + `SourceBuffer buffered ranges grew from ${beforeBuffered} to ${afterBuffered}` + ); +} + +async function fetchAndLoad(sb, prefix, chunks, suffix) { + // Fetch the buffers in parallel. + const buffers = await Promise.all( + chunks.map(c => fetchWithXHR(prefix + c + suffix)) + ); + + // Load them in series, as required per spec. + for (const buffer of buffers) { + await loadSegment(sb, buffer); + } +} + +function loadSegmentAsync(sb, typedArrayOrArrayBuffer) { + const typedArray = + typedArrayOrArrayBuffer instanceof ArrayBuffer + ? new Uint8Array(typedArrayOrArrayBuffer) + : typedArrayOrArrayBuffer; + info( + `Loading buffer2: [${typedArray.byteOffset}, ${ + typedArray.byteOffset + typedArray.byteLength + })` + ); + const beforeBuffered = timeRangeToString(sb.buffered); + return sb.appendBufferAsync(typedArray).then(() => { + const afterBuffered = timeRangeToString(sb.buffered); + info( + `SourceBuffer buffered ranges grew from ${beforeBuffered} to ${afterBuffered}` + ); + }); +} + +function fetchAndLoadAsync(sb, prefix, chunks, suffix) { + // Fetch the buffers in parallel. + const buffers = {}; + const fetches = []; + for (const chunk of chunks) { + fetches.push( + fetchWithXHR(prefix + chunk + suffix).then( + ((c, x) => (buffers[c] = x)).bind(null, chunk) + ) + ); + } + + // Load them in series, as required per spec. + return Promise.all(fetches).then(function () { + let rv = Promise.resolve(); + for (const chunk of chunks) { + rv = rv.then(loadSegmentAsync.bind(null, sb, buffers[chunk])); + } + return rv; + }); +} + +// Register timeout function to dump debugging logs. +SimpleTest.registerTimeoutFunction(async function () { + for (const v of document.getElementsByTagName("video")) { + console.log(await SpecialPowers.wrap(v).mozRequestDebugInfo()); + } + for (const a of document.getElementsByTagName("audio")) { + console.log(await SpecialPowers.wrap(a).mozRequestDebugInfo()); + } +}); + +async function waitUntilTime(target, targetTime) { + await new Promise(resolve => { + target.addEventListener("waiting", function onwaiting() { + info("Got a waiting event at " + target.currentTime); + if (target.currentTime >= targetTime) { + target.removeEventListener("waiting", onwaiting); + resolve(); + } + }); + }); + ok(true, "Reached target time of: " + targetTime); +} + +// Log events for debugging. + +function logEvents(el) { + [ + "suspend", + "play", + "canplay", + "canplaythrough", + "loadstart", + "loadedmetadata", + "loadeddata", + "playing", + "ended", + "error", + "stalled", + "emptied", + "abort", + "waiting", + "pause", + "durationchange", + "seeking", + "seeked", + ].forEach(type => + el.addEventListener(type, e => info(`got ${e.type} event`)) + ); +} diff --git a/dom/media/mediasource/test/mochitest.ini b/dom/media/mediasource/test/mochitest.ini new file mode 100644 index 0000000000..f231255c1e --- /dev/null +++ b/dom/media/mediasource/test/mochitest.ini @@ -0,0 +1,213 @@ +[DEFAULT] +subsuite = media +support-files = + mediasource.js + seek.webm seek.webm^headers^ + seek_lowres.webm seek_lowres.webm^headers^ + bipbop/bipbop_300-3s.webm bipbop/bipbop_300-3s.webm^headers^ + bipbop/bipbop2s.mp4 bipbop/bipbop2s.mp4^headers^ + bipbop/bipbop_trailing_skip_box_video1.m4s + bipbop/bipbop_trailing_skip_box_video1.m4s^headers^ + bipbop/bipbopinit.mp4 bipbop/bipbop_audioinit.mp4 bipbop/bipbop_videoinit.mp4 + bipbop/bipbop1.m4s bipbop/bipbop_audio1.m4s bipbop/bipbop_video1.m4s + bipbop/bipbop2.m4s bipbop/bipbop_audio2.m4s bipbop/bipbop_video2.m4s + bipbop/bipbop3.m4s bipbop/bipbop_audio3.m4s bipbop/bipbop_video3.m4s + bipbop/bipbop4.m4s bipbop/bipbop_audio4.m4s bipbop/bipbop_video4.m4s + bipbop/bipbop5.m4s bipbop/bipbop_audio5.m4s bipbop/bipbop_video5.m4s + bipbop/bipbop6.m4s bipbop/bipbop_audio6.m4s bipbop/bipbop_video6.m4s + bipbop/bipbop7.m4s bipbop/bipbop_audio7.m4s bipbop/bipbop_video7.m4s + bipbop/bipbop8.m4s bipbop/bipbop_audio8.m4s bipbop/bipbop_video8.m4s + bipbop/bipbop9.m4s bipbop/bipbop_audio9.m4s bipbop/bipbop_video9.m4s + bipbop/bipbop10.m4s bipbop/bipbop_audio10.m4s bipbop/bipbop_video10.m4s + bipbop/bipbop11.m4s bipbop/bipbop_audio11.m4s bipbop/bipbop_video11.m4s + bipbop/bipbop12.m4s bipbop/bipbop_video12.m4s + bipbop/bipbop13.m4s bipbop/bipbop_video13.m4s + bipbop/bipbopinit.mp4^headers^ bipbop/bipbop_audioinit.mp4^headers^ bipbop/bipbop_videoinit.mp4^headers^ + bipbop/bipbop1.m4s^headers^ bipbop/bipbop_audio1.m4s^headers^ bipbop/bipbop_video1.m4s^headers^ + bipbop/bipbop2.m4s^headers^ bipbop/bipbop_audio2.m4s^headers^ bipbop/bipbop_video2.m4s^headers^ + bipbop/bipbop3.m4s^headers^ bipbop/bipbop_audio3.m4s^headers^ bipbop/bipbop_video3.m4s^headers^ + bipbop/bipbop4.m4s^headers^ bipbop/bipbop_audio4.m4s^headers^ bipbop/bipbop_video4.m4s^headers^ + bipbop/bipbop5.m4s^headers^ bipbop/bipbop_audio5.m4s^headers^ bipbop/bipbop_video5.m4s^headers^ + bipbop/bipbop6.m4s^headers^ bipbop/bipbop_audio6.m4s^headers^ bipbop/bipbop_video6.m4s^headers^ + bipbop/bipbop7.m4s^headers^ bipbop/bipbop_audio7.m4s^headers^ bipbop/bipbop_video7.m4s^headers^ + bipbop/bipbop8.m4s^headers^ bipbop/bipbop_audio8.m4s^headers^ bipbop/bipbop_video8.m4s^headers^ + bipbop/bipbop9.m4s^headers^ bipbop/bipbop_audio9.m4s^headers^ bipbop/bipbop_video9.m4s^headers^ + bipbop/bipbop10.m4s^headers^ bipbop/bipbop_audio10.m4s^headers^ bipbop/bipbop_video10.m4s^headers^ + bipbop/bipbop11.m4s^headers^ bipbop/bipbop_audio11.m4s^headers^ bipbop/bipbop_video11.m4s^headers^ + bipbop/bipbop12.m4s^headers^ bipbop/bipbop_video12.m4s^headers^ + bipbop/bipbop13.m4s^headers^ bipbop/bipbop_video13.m4s^headers^ + bipbop/bipbop_offset_0.0-1.m4s + bipbop/bipbop_offset_0.0-1.m4s^headers^ + bipbop/bipbop_offset_0.0-2.m4s + bipbop/bipbop_offset_0.0-2.m4s^headers^ + bipbop/bipbop_offset_0.0-init.mp4 + bipbop/bipbop_offset_0.0-init.mp4^headers^ + bipbop/bipbop_offset_0.1-1.m4s + bipbop/bipbop_offset_0.1-1.m4s^headers^ + bipbop/bipbop_offset_0.1-2.m4s + bipbop/bipbop_offset_0.1-2.m4s^headers^ + bipbop/bipbop_offset_0.1-init.mp4 + bipbop/bipbop_offset_0.1-init.mp4^headers^ + bipbop/bipbop_offset_0.2-1.m4s + bipbop/bipbop_offset_0.2-1.m4s^headers^ + bipbop/bipbop_offset_0.2-2.m4s + bipbop/bipbop_offset_0.2-2.m4s^headers^ + bipbop/bipbop_offset_0.2-init.mp4 + bipbop/bipbop_offset_0.2-init.mp4^headers^ + bipbop/bipbop_offset_0.3-1.m4s + bipbop/bipbop_offset_0.3-1.m4s^headers^ + bipbop/bipbop_offset_0.3-2.m4s + bipbop/bipbop_offset_0.3-2.m4s^headers^ + bipbop/bipbop_offset_0.3-init.mp4 + bipbop/bipbop_offset_0.3-init.mp4^headers^ + bipbop/bipbop_offset_0.4-1.m4s + bipbop/bipbop_offset_0.4-1.m4s^headers^ + bipbop/bipbop_offset_0.4-2.m4s + bipbop/bipbop_offset_0.4-2.m4s^headers^ + bipbop/bipbop_offset_0.4-init.mp4 + bipbop/bipbop_offset_0.4-init.mp4^headers^ + bipbop/bipbop_offset_0.5-1.m4s + bipbop/bipbop_offset_0.5-1.m4s^headers^ + bipbop/bipbop_offset_0.5-2.m4s + bipbop/bipbop_offset_0.5-2.m4s^headers^ + bipbop/bipbop_offset_0.5-init.mp4 + bipbop/bipbop_offset_0.5-init.mp4^headers^ + bipbop/bipbop_offset_0.6-1.m4s + bipbop/bipbop_offset_0.6-1.m4s^headers^ + bipbop/bipbop_offset_0.6-2.m4s + bipbop/bipbop_offset_0.6-2.m4s^headers^ + bipbop/bipbop_offset_0.6-init.mp4 + bipbop/bipbop_offset_0.6-init.mp4^headers^ + bipbop/bipbop_offset_0.7-1.m4s + bipbop/bipbop_offset_0.7-1.m4s^headers^ + bipbop/bipbop_offset_0.7-2.m4s + bipbop/bipbop_offset_0.7-2.m4s^headers^ + bipbop/bipbop_offset_0.7-init.mp4 + bipbop/bipbop_offset_0.7-init.mp4^headers^ + bipbop/bipbop_offset_0.8-1.m4s + bipbop/bipbop_offset_0.8-1.m4s^headers^ + bipbop/bipbop_offset_0.8-2.m4s + bipbop/bipbop_offset_0.8-2.m4s^headers^ + bipbop/bipbop_offset_0.8-init.mp4 + bipbop/bipbop_offset_0.8-init.mp4^headers^ + bipbop/bipbop_offset_0.9-1.m4s + bipbop/bipbop_offset_0.9-1.m4s^headers^ + bipbop/bipbop_offset_0.9-2.m4s + bipbop/bipbop_offset_0.9-2.m4s^headers^ + bipbop/bipbop_offset_0.9-init.mp4 + bipbop/bipbop_offset_0.9-init.mp4^headers^ + bipbop/bipbop_offset_1.0-1.m4s + bipbop/bipbop_offset_1.0-1.m4s^headers^ + bipbop/bipbop_offset_1.0-2.m4s + bipbop/bipbop_offset_1.0-2.m4s^headers^ + bipbop/bipbop_offset_1.0-init.mp4 + bipbop/bipbop_offset_1.0-init.mp4^headers^ + bipbop/bipbop_offset_1.1-1.m4s + bipbop/bipbop_offset_1.1-1.m4s^headers^ + bipbop/bipbop_offset_1.1-2.m4s + bipbop/bipbop_offset_1.1-2.m4s^headers^ + bipbop/bipbop_offset_1.1-init.mp4 + bipbop/bipbop_offset_1.1-init.mp4^headers^ + aac20-48000-64000-init.mp4 aac20-48000-64000-init.mp4^headers^ + aac20-48000-64000-1.m4s aac20-48000-64000-1.m4s^headers^ + aac20-48000-64000-2.m4s aac20-48000-64000-2.m4s^headers^ + aac51-48000-128000-init.mp4 aac51-48000-128000-init.mp4^headers^ + aac51-48000-128000-1.m4s aac51-48000-128000-1.m4s^headers^ + aac51-48000-128000-2.m4s aac51-48000-128000-2.m4s^headers^ + bipbop/bipbop_480_624kbps-videoinit.mp4 bipbop/bipbop_480_624kbps-videoinit.mp4^headers^ + bipbop/bipbop_480_624kbps-video1.m4s bipbop/bipbop_480_624kbps-video1.m4s^headers^ + bipbop/bipbop_480_624kbps-video2.m4s bipbop/bipbop_480_624kbps-video2.m4s^headers^ + flac/IS.mp4 flac/IS.mp4^headers^ flac/00001.m4s flac/00001.m4s^headers^ + flac/00002.m4s flac/00002.m4s^headers^ flac/00003.m4s flac/00003.m4s^headers^ + avc3/init.mp4 avc3/init.mp4^headers^ avc3/segment1.m4s avc3/segment1.m4s^headers^ + tags_before_cluster.webm + tags_before_cluster.webm^header^ + 1516754.webm 1516754.webm^headers^ + init-trackid2.mp4 init-trackid3.mp4 segment-2.0001.m4s segment-2.0002.m4s segment-3.0001.m4s segment-3.0002.m4s + init-trackid2.mp4^headers^ init-trackid3.mp4^headers^ segment-2.0001.m4s^headers^ segment-2.0002.m4s^headers^ + segment-3.0001.m4s^headers^ segment-3.0002.m4s^headers^ + wmf_mismatchedaudiotime.mp4 + bug1718709_low_res.mp4 + bug1718709_high_res.mp4 + whitenoise-he-aac-5s.mp4 + +[test_AbortAfterPartialMediaSegment.html] +[test_AppendPartialInitSegment.html] +[test_AVC3_mp4.html] +[test_AudioChange_mp4.html] +[test_AudioChange_mp4_WebAudio.html] +[test_AutoRevocation.html] +tags = firstpartyisolation +[test_BufferedSeek.html] +[test_BufferedSeek_mp4.html] +[test_BufferingWait.html] +[test_BufferingWait_mp4.html] +[test_ChangeType.html] +[test_ChangeWhileWaitingOnMissingData_mp4.html] +[test_DifferentStreamStartTimes.html] +[test_DrainOnMissingData_mp4.html] +[test_DurationChange.html] +[test_DurationUpdated.html] +[test_DurationUpdated_mp4.html] +[test_EndedEvent.html] +[test_EndOfStream.html] +[test_EndOfStream_mp4.html] +[test_Eviction_mp4.html] +[test_ExperimentalAsync.html] +[test_FrameSelection.html] +skip-if = toolkit == 'android' # bug 1341519, bug 1401090 +[test_FrameSelection_mp4.html] +skip-if = os == 'win' # bug 1487973, + (os == 'mac') # mac due to bug 1487973 +[test_HaveMetadataUnbufferedSeek.html] +[test_HaveMetadataUnbufferedSeek_mp4.html] +[test_HEAAC_extradata.html] +[test_InputBufferIsCleared.html] +[test_LiveSeekable.html] +[test_LoadedDataFired_mp4.html] +[test_LoadedMetadataFired.html] +[test_LoadedMetadataFired_mp4.html] +[test_MediaSource.html] +[test_MediaSource_capture_gc.html] +[test_MediaSource_memory_reporting.html] +[test_MediaSource_mp4.html] +[test_MediaSource_flac_mp4.html] +[test_MediaSource_disabled.html] +[test_MultipleInitSegments.html] +[test_MultipleInitSegments_mp4.html] +[test_NoAudioLoopBackData.html] +[test_NoAudioLoopBackData_Muted.html] +[test_NoVideoLoopBackData.html] +[test_OnEvents.html] +[test_PlayEvents.html] +[test_PlayEventsAutoPlaying.html] +[test_PlayEventsAutoPlaying2.html] +[test_RemoveSourceBuffer.html] +[test_Resolution_change_should_not_cause_video_freeze.html] +[test_ResumeAfterClearing_mp4.html] +[test_SeekableBeforeAndAfterEndOfStream.html] +[test_SeekableBeforeAndAfterEndOfStream_mp4.html] +[test_SeekableBeforeAndAfterEndOfStreamSplit.html] +[test_SeekableBeforeAndAfterEndOfStreamSplit_mp4.html] +[test_SeekNoData_mp4.html] +[test_SeekedEvent_mp4.html] +[test_SeekToEnd_mp4.html] +[test_SeekToLastFrame_mp4.html] +[test_SeekTwice_mp4.html] +[test_Sequence_mp4.html] +[test_SetModeThrows.html] +[test_SplitAppendDelay.html] +[test_SplitAppendDelay_mp4.html] +[test_SplitAppend.html] +[test_SplitAppend_mp4.html] +[test_Threshold_mp4.html] +[test_TimestampOffset_mp4.html] +[test_trackidchange_mp4.html] +[test_TruncatedDuration.html] +[test_TruncatedDuration_mp4.html] +[test_WaitingOnMissingData.html] +[test_WaitingOnMissingData_mp4.html] +[test_WaitingOnMissingDataEnded_mp4.html] +[test_WaitingToEndedTransition_mp4.html] +[test_WebMTagsBeforeCluster.html] +[test_WMFUnmatchedAudioDataTime.html] diff --git a/dom/media/mediasource/test/seek.webm b/dom/media/mediasource/test/seek.webm Binary files differnew file mode 100644 index 0000000000..72b0297233 --- /dev/null +++ b/dom/media/mediasource/test/seek.webm diff --git a/dom/media/mediasource/test/seek.webm^headers^ b/dom/media/mediasource/test/seek.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/seek.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/seek_lowres.webm b/dom/media/mediasource/test/seek_lowres.webm Binary files differnew file mode 100644 index 0000000000..8a76e06470 --- /dev/null +++ b/dom/media/mediasource/test/seek_lowres.webm diff --git a/dom/media/mediasource/test/seek_lowres.webm^headers^ b/dom/media/mediasource/test/seek_lowres.webm^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/seek_lowres.webm^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/segment-2.0001.m4s b/dom/media/mediasource/test/segment-2.0001.m4s Binary files differnew file mode 100644 index 0000000000..b63fd6aaa6 --- /dev/null +++ b/dom/media/mediasource/test/segment-2.0001.m4s diff --git a/dom/media/mediasource/test/segment-2.0001.m4s^headers^ b/dom/media/mediasource/test/segment-2.0001.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/segment-2.0001.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/segment-2.0002.m4s b/dom/media/mediasource/test/segment-2.0002.m4s Binary files differnew file mode 100644 index 0000000000..3a0051f10e --- /dev/null +++ b/dom/media/mediasource/test/segment-2.0002.m4s diff --git a/dom/media/mediasource/test/segment-2.0002.m4s^headers^ b/dom/media/mediasource/test/segment-2.0002.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/segment-2.0002.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/segment-3.0001.m4s b/dom/media/mediasource/test/segment-3.0001.m4s Binary files differnew file mode 100644 index 0000000000..71e33f0e8f --- /dev/null +++ b/dom/media/mediasource/test/segment-3.0001.m4s diff --git a/dom/media/mediasource/test/segment-3.0001.m4s^headers^ b/dom/media/mediasource/test/segment-3.0001.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/segment-3.0001.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/segment-3.0002.m4s b/dom/media/mediasource/test/segment-3.0002.m4s Binary files differnew file mode 100644 index 0000000000..10a3ce695d --- /dev/null +++ b/dom/media/mediasource/test/segment-3.0002.m4s diff --git a/dom/media/mediasource/test/segment-3.0002.m4s^headers^ b/dom/media/mediasource/test/segment-3.0002.m4s^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/segment-3.0002.m4s^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/tags_before_cluster.webm b/dom/media/mediasource/test/tags_before_cluster.webm Binary files differnew file mode 100644 index 0000000000..cf7d596b0e --- /dev/null +++ b/dom/media/mediasource/test/tags_before_cluster.webm diff --git a/dom/media/mediasource/test/tags_before_cluster.webm^header^ b/dom/media/mediasource/test/tags_before_cluster.webm^header^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/dom/media/mediasource/test/tags_before_cluster.webm^header^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/dom/media/mediasource/test/test_AVC3_mp4.html b/dom/media/mediasource/test/test_AVC3_mp4.html new file mode 100644 index 0000000000..dd20feed06 --- /dev/null +++ b/dom/media/mediasource/test/test_AVC3_mp4.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: AVC3 content playback.</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + + await fetchAndLoad(videosb, "avc3/init", [""], ".mp4"); + const p = once(el, "loadeddata"); + await fetchAndLoad(videosb, "avc3/segment", range(1, 2), ".m4s"); + await p; + is(videosb.buffered.length, 1, "continuous buffered range"); + ok(true, "got loadeddata"); + ms.endOfStream(); + await once(ms, "sourceended"); + ok(true, "endOfStream completed"); + // Now ensure that we can play to the end. + el.play(); + await once(el, "ended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_AbortAfterPartialMediaSegment.html b/dom/media/mediasource/test/test_AbortAfterPartialMediaSegment.html new file mode 100644 index 0000000000..4c695f48c7 --- /dev/null +++ b/dom/media/mediasource/test/test_AbortAfterPartialMediaSegment.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: can properly resume after a partial media segment header followed by abort </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +const VIDEO_CODEC_STRING = 'video/webm; codecs="vp09.00.51.08.01.01.01.01"'; + +const logError = (error) => { + console.error(error, error.message); + ok(false, "should not reach here"); +}; + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + + const supported = MediaSource.isTypeSupported(VIDEO_CODEC_STRING); + if (!supported) { + ok(true, "vp9 isn't supported on this platform, abort"); + SimpleTest.finish(); + return; + } + const sb = ms.addSourceBuffer(VIDEO_CODEC_STRING); + + const arrayBuffer = await fetchWithXHR("1516754.webm"); + info("- append init segment, a media segment and a partial media segment header -"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 87355 + 3000)); + + info("- wait for updateend -"); + await once(sb, "updateend"); + + // start seeking. + v.currentTime = 11; + v.addEventListener("seeked", () => { + info("- seek completed -"); + SimpleTest.finish(); + }); + + sb.abort(); + + info("- append init segment -"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 3150)); + info("- wait for updateend -"); + await once(sb, "updateend"); + info("- append media segment 10-15s -"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 159968, 72931)); + + // We now wait for seek to complete +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_AppendPartialInitSegment.html b/dom/media/mediasource/test/test_AppendPartialInitSegment.html new file mode 100644 index 0000000000..408c073bd6 --- /dev/null +++ b/dom/media/mediasource/test/test_AppendPartialInitSegment.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: split init segment and append them separately </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + // init segment is total 236 bytes. + info("- append partial init segment -"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 100)); + + info("- wait for updateend -"); + await once(sb, "updateend"); + + info("- append remaining init segment -"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 100, 136)); + + info("- wait for metadata -"); + await once(v, "loadedmetadata"); + is(v.videoWidth, 320, "videoWidth has correct initial value"); + is(v.videoHeight, 240, "videoHeight has correct initial value"); + + info("- wait for updateend -"); + await once(sb, "updateend"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_AudioChange_mp4.html b/dom/media/mediasource/test/test_AudioChange_mp4.html new file mode 100644 index 0000000000..9051af05a1 --- /dev/null +++ b/dom/media/mediasource/test/test_AudioChange_mp4.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +// This test checks loading a stereo segment, followed by a 5.1 segment plays without error. + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + logEvents(el); + + const audiosb = ms.addSourceBuffer("audio/mp4"); + el.addEventListener("error", e => { + ok(false, `should not fire ${e.type} event`); + SimpleTest.finish(); + }); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + let p = once(el, "loadedmetadata"); + await fetchAndLoad(audiosb, "aac20-48000-64000-", ["init"], ".mp4"); + await p; + ok(true, "got loadedmetadata event"); + p = Promise.all([once(el, "loadeddata"), once(el, "canplay")]); + await fetchAndLoad(audiosb, "aac20-48000-64000-", ["1"], ".m4s"); + await p; + ok(true, "got canplay event"); + el.play(); + await fetchAndLoad(audiosb, "aac51-48000-128000-", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "aac51-48000-128000-", ["2"], ".m4s"); + ms.endOfStream(); + await once(el, "ended"); + ok(el.currentTime >= 6, "played to the end"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_AudioChange_mp4_WebAudio.html b/dom/media/mediasource/test/test_AudioChange_mp4_WebAudio.html new file mode 100644 index 0000000000..c76342f793 --- /dev/null +++ b/dom/media/mediasource/test/test_AudioChange_mp4_WebAudio.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +// This test checks loading a stereo segment, followed by a 5.1 segment plays +// without error, when the audio is being routed to an AudioContext. + +const ac = new AudioContext(); + +runWithMSE(async (ms, el) => { + el.controls = true; + const source = ac.createMediaElementSource(el); + source.connect(ac.destination); + + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + logEvents(el); + + const audiosb = ms.addSourceBuffer("audio/mp4"); + el.addEventListener("error", e => { + ok(false, `should not fire ${e.type} event`); + SimpleTest.finish(); + }); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + let p = once(el, "loadedmetadata"); + await fetchAndLoad(audiosb, "aac20-48000-64000-", ["init"], ".mp4"); + await p; + ok(true, "got loadedmetadata event"); + p = Promise.all([once(el, "loadeddata"), once(el, "canplay")]); + await fetchAndLoad(audiosb, "aac20-48000-64000-", ["1"], ".m4s"); + await p; + ok(true, "got canplay event"); + el.play(); + await fetchAndLoad(audiosb, "aac51-48000-128000-", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "aac51-48000-128000-", ["2"], ".m4s"); + ms.endOfStream(); + await once(el, "ended"); + ok(el.currentTime >= 6, "played to the end"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_AutoRevocation.html b/dom/media/mediasource/test/test_AutoRevocation.html new file mode 100644 index 0000000000..42e9b0e6a5 --- /dev/null +++ b/dom/media/mediasource/test/test_AutoRevocation.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: auto-revocation</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(function() { + const ms = new MediaSource(); + const o = URL.createObjectURL(ms); + const v = document.createElement("video"); + + v.addEventListener("error", () => { + ok(true, "ObjectURL should be auto-revoked"); + SimpleTest.finish(); + }); + + v.addEventListener("stalled", () => { + ok(false, "If auto-revocation is gone, please turn on TODOs in browser_mediaSourceURL.js"); + SimpleTest.finish(); + }); + + setTimeout(function() { + v.src = o; + v.preload = "auto"; + document.body.appendChild(v); + }, 0); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_BufferedSeek.html b/dom/media/mediasource/test/test_BufferedSeek.html new file mode 100644 index 0000000000..039f56bc16 --- /dev/null +++ b/dom/media/mediasource/test/test_BufferedSeek.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seeking in buffered range</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm"))); + + const target = 2; + + v.addEventListener("loadedmetadata", () => { + ok(true, "received loadedmetadata"); + v.currentTime = target; + }); + + let wasSeeking = false; + + v.addEventListener("seeking", () => { + wasSeeking = true; + is(v.currentTime, target, "Video currentTime at target"); + }); + + await once(v, "seeked"); + ok(wasSeeking, "Received expected seeking and seeked events"); + is(v.currentTime, target, "Video currentTime at target"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_BufferedSeek_mp4.html b/dom/media/mediasource/test/test_BufferedSeek_mp4.html new file mode 100644 index 0000000000..e89e972c91 --- /dev/null +++ b/dom/media/mediasource/test/test_BufferedSeek_mp4.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seeking in buffered range</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("bipbop/bipbop2s.mp4"))); + + const target = 1.3; + + await once(v, "loadedmetadata"); + ok(true, "received loadedmetadata"); + v.currentTime = target; + + let wasSeeking = false; + + v.addEventListener("seeking", () => { + wasSeeking = true; + is(v.currentTime, target, "Video currentTime at target"); + }); + + await once(v, "seeked"); + ok(wasSeeking, "Received expected seeking and seeked events"); + is(v.currentTime, target, "Video currentTime at target"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_BufferingWait.html b/dom/media/mediasource/test/test_BufferingWait.html new file mode 100644 index 0000000000..289ddfe4d2 --- /dev/null +++ b/dom/media/mediasource/test/test_BufferingWait.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Don't get stuck buffering for too long when we have frames to show</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen")); + const sb = ms.addSourceBuffer("video/webm"); + ok(sb, "Create a SourceBuffer"); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + sb.addEventListener("error", e => { + ok(false, "Got Error: " + e); + SimpleTest.finish(); + }); + await loadSegment(sb, new Uint8Array(arrayBuffer, 0, 318)); + await loadSegment(sb, new Uint8Array(arrayBuffer, 318, 25523 - 318)); + await loadSegment(sb, new Uint8Array(arrayBuffer, 25523, 46712 - 25523)); + /* Note - Missing |46712, 67833 - 46712| segment here corresponding to (0.8, 1.2] */ + /* Note - Missing |67833, 88966 - 67833| segment here corresponding to (1.2, 1.6] */ + await loadSegment(sb, new Uint8Array(arrayBuffer, 88966)); + // 0.767 is the time of the last video sample +- 40ms. + info("Playing video. It should play for a bit, then fire 'waiting'"); + v.play(); + await waitUntilTime(v, .767 - 0.04); + const firstStop = Date.now(); + await loadSegment(sb, new Uint8Array(arrayBuffer, 46712, 67833 - 46712)); + await waitUntilTime(v, 1.167 - 0.04); + const waitDuration = (Date.now() - firstStop) / 1000; + ok(waitDuration < 15, `Should not spend inordinate amount of time buffering: ${waitDuration}`); + SimpleTest.finish(); + /* If we allow the rest of the stream to be played, we get stuck at + around 2s. See bug 1093133. + await once(v, "ended"); + SimpleTest.finish(); + await loadSegment(sb, new Uint8Array(arrayBuffer, 67833, 88966 - 67833)); + */ +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_BufferingWait_mp4.html b/dom/media/mediasource/test/test_BufferingWait_mp4.html new file mode 100644 index 0000000000..04e094a852 --- /dev/null +++ b/dom/media/mediasource/test/test_BufferingWait_mp4.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Don't get stuck buffering for too long when we have frames to show</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen")); + const sb = ms.addSourceBuffer("video/mp4"); + ok(sb, "Create a SourceBuffer"); + + sb.addEventListener("error", e => { + ok(false, "Got Error: " + e); + SimpleTest.finish(); + }); + await fetchAndLoad(sb, "bipbop/bipbop", ["init"], ".mp4"); + await fetchAndLoad(sb, "bipbop/bipbop", ["1"], ".m4s"); + await fetchAndLoad(sb, "bipbop/bipbop", ["2"], ".m4s"); + /* Note - Missing |bipbop3| segment here corresponding to (1.62, 2.41] */ + /* Note - Missing |bipbop4| segment here corresponding to (2.41, 3.20] */ + await fetchAndLoad(sb, "bipbop/bipbop", ["5"], ".m4s"); + // last audio sample has a start time of 1.578956s + info("Playing video. It should play for a bit, then fire 'waiting'"); + v.play(); + await waitUntilTime(v, 1.57895); + const firstStop = Date.now(); + await fetchAndLoad(sb, "bipbop/bipbop", ["3"], ".m4s"); + // last audio sample has a start time of 2.368435 + await waitUntilTime(v, 2.36843); + const waitDuration = (Date.now() - firstStop) / 1000; + ok(waitDuration < 15, `Should not spend inordinate amount of time buffering: ${waitDuration}`); + await fetchAndLoad(sb, "bipbop/bipbop", ["4"], ".m4s"); + ms.endOfStream(); + await once(v, "ended"); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_ChangeType.html b/dom/media/mediasource/test/test_ChangeType.html new file mode 100644 index 0000000000..690b9f61c4 --- /dev/null +++ b/dom/media/mediasource/test/test_ChangeType.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: changeType allow to change container and codec type</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(function(ms, el) { + el.controls = true; + once(ms, "sourceopen").then(function() { + // Log events for debugging. + const 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) { + el.addEventListener(e, logEvent); + }); + + ok(true, "Receive a sourceopen event"); + + const videosb = ms.addSourceBuffer("video/mp4"); + if (typeof videosb.changeType === "undefined") { + info("changeType API is not available"); + } + + el.addEventListener("error", e => { + ok(false, "should not fire '" + e.type + "' event"); + SimpleTest.finish(); + }); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + const loadedmetadataPromises = []; + loadedmetadataPromises.push(fetchAndLoad(videosb, "bipbop/bipbop", ["init"], ".mp4")); + loadedmetadataPromises.push(once(el, "loadedmetadata")); + Promise.all(loadedmetadataPromises) + .then(function() { + ok(true, "got loadedmetadata event"); + const canplayPromises = []; + canplayPromises.push(once(el, "loadeddata")); + canplayPromises.push(once(el, "canplay")); + canplayPromises.push(fetchAndLoad(videosb, "bipbop/bipbop", range(1, 3), ".m4s")); + return Promise.all(canplayPromises); + }) + .then(function() { + ok(true, "got canplay event"); + el.play(); + videosb.timestampOffset = el.buffered.end(0); + return fetchAndLoad(videosb, "bipbop/bipbop_480_624kbps-video", ["init"], ".mp4"); + }) + .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_480_624kbps-video", range(1, 3), ".m4s")) + .then(function() { + videosb.timestampOffset = el.buffered.end(0); + try { + videosb.changeType("video/webm"); + } catch (e) { + ok(false, "shouldn't throw an exception"); + SimpleTest.finish(); + throw e; + } + return fetchAndLoad(videosb, "bipbop/bipbop_300-3s", [""], ".webm"); + }) + .then(function() { + ms.endOfStream(); + return once(el, "ended"); + }) + .then(function() { + ok(el.currentTime >= el.buffered.end(0), "played to the end"); + SimpleTest.finish(); + }); + }); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_ChangeWhileWaitingOnMissingData_mp4.html b/dom/media/mediasource/test/test_ChangeWhileWaitingOnMissingData_mp4.html new file mode 100644 index 0000000000..b5889da560 --- /dev/null +++ b/dom/media/mediasource/test/test_ChangeWhileWaitingOnMissingData_mp4.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: resume from waiting even after format change occurred</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const sb = ms.addSourceBuffer("video/mp4"); + await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", ["init"], ".mp4"); + await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", range(1, 3), ".m4s"); + el.play(); + // let seek to the last audio frame. + // The seek will complete and then playback will stall. + el.currentTime = 1.532517; + await Promise.all([once(el, "seeked"), once(el, "waiting")]); + info("seek completed"); + await fetchAndLoad(sb, "bipbop/bipbop", ["init"], ".mp4"); + await fetchAndLoad(sb, "bipbop/bipbop", range(1, 4), ".m4s"); + ms.endOfStream(); + await once(el, "ended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_DifferentStreamStartTimes.html b/dom/media/mediasource/test/test_DifferentStreamStartTimes.html new file mode 100644 index 0000000000..197e809e4f --- /dev/null +++ b/dom/media/mediasource/test/test_DifferentStreamStartTimes.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: Mismatched stream start time playback test</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); +runWithMSE(async (ms, el) => { + el.controls = true; + el.autoplay = true; + for (let i = 0; i <= 0.5; i += 0.1) { + const offset = i.toFixed(1); + + info("----------------------"); + info("Running test for mismatched stream start times with offset of: " + offset); + info("----------------------"); + + ms = new MediaSource(); + el.removeAttribute("src"); + el.src = URL.createObjectURL(ms); + + await once(ms, "sourceopen"); + logEvents(el); + const videosb = ms.addSourceBuffer("video/mp4"); + ok(true, "Receive a sourceopen event"); + + el.addEventListener("error", e => { + ok(false, `should not fire ${e.type} event`); + SimpleTest.finish(); + }); + + let p = once(el, "loadedmetadata"); + await fetchAndLoad(videosb, "bipbop/bipbop_offset_" + offset + "-", ["init"], ".mp4"); + await p; + ok(true, "got loadedmetadata event"); + + p = Promise.all(["loadeddata", "canplay", "play", "playing"].map(e => once(el, e))); + await fetchAndLoad(videosb, "bipbop/bipbop_offset_" + offset + "-", range(1, 2), ".m4s"); + el.play(); + await p; + } + ok(true, "got all required event"); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_DrainOnMissingData_mp4.html b/dom/media/mediasource/test/test_DrainOnMissingData_mp4.html new file mode 100644 index 0000000000..ddc503aebf --- /dev/null +++ b/dom/media/mediasource/test/test_DrainOnMissingData_mp4.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: |waiting| event when source data is missing</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + // Set appendWindowEnd to ensure we only have about 6 frames worth. + // We must feed at least 6 frames to pass the MDSM pre-roll. + videosb.appendWindowEnd = .4; + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["1"], ".m4s"); + info("Invoking play()"); + const p = once(el, "playing"); + await el.play(); + await p; + info("got playing"); + await once(el, "waiting"); + info("got waiting"); + info("Loading more data"); + // Waiting will be fired on the last frame +- 40ms. + isfuzzy(el.currentTime, videosb.buffered.end(0) - 1 / 30, + 0.04, `Got a waiting event at ${el.currentTime}`); + videosb.appendWindowEnd = 1; + await fetchAndLoad(videosb, "bipbop/bipbop_video", [1], ".m4s"); + ms.endOfStream(); + await once(el, "ended"); + // These fuzz factors are bigger than they should be. We should investigate + // and fix them in bug 1137574. + is(el.duration, 0.801666, "Video has correct duration: " + el.duration); + is(el.currentTime, el.duration, "Video has correct currentTime."); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_DurationChange.html b/dom/media/mediasource/test/test_DurationChange.html new file mode 100644 index 0000000000..3c83e83fa4 --- /dev/null +++ b/dom/media/mediasource/test/test_DurationChange.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: check that duration change behaves properly</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318)); + await Promise.all([once(v, "loadedmetadata"), once(sb, "updateend")]); + is(v.duration, ms.duration, "video duration is mediasource one"); + must_not_throw(() => ms.duration = 0, "duration = 0 is valid initially"); + is(v.duration, 0, "reducing duration with no data buffered is valid"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 318)); + // Adding more data will fire durationchange. + await once(sb, "updateend"); + ok(true, "got updateend"); + // XXX: Duration should be exactly 4.0, see bug 1065207. + ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration"); + must_throw(() => ms.duration = 0, + "Must use remove for range removal", + "InvalidStateError"); + ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration"); + must_not_throw(() => ms.duration = 10, "setting duration past data is valid"); + is(v.duration, 10, "extending duration is always valid"); + // The last sample has a start time of 3.967000s and a end time of 4.001 (see bug 1065207). + must_not_throw(() => ms.duration = 3.967000, + "setting duration with >= highest frame presentation time is valid"); + is(v.duration, sb.buffered.end(0), + "duration is the highest end time reported by the buffered attribute "); + must_not_throw(() => ms.duration = 3.97, + "setting duration with >= highest frame presentation time is valid"); + is(v.duration, sb.buffered.end(0), + "duration is the highest end time reported by the buffered attribute "); + must_throw(() => ms.duration = 3.96, + "setting duration with < highest frame presentation time is not valid", + "InvalidStateError"); + is(v.duration, sb.buffered.end(0), + "duration is the highest end time reported by the buffered attribute "); + must_throw(() => ms.duration = -1, "can't set a negative duration", "TypeError"); + sb.remove(sb.buffered.end(0), Infinity); + is(sb.updating, true, "updating is true"); + must_throw(() => ms.duration = Infinity, + "setting the duration while updating is not allowed", + "InvalidStateError"); + must_throw(() => sb.abort(), + "Can't use abort while range removal is in progress", + "InvalidStateError"); + is(v.duration, sb.buffered.end(0), + "duration is the highest end time reported by the buffered attribute "); + await once(sb, "updateend"); + ms.endOfStream(); + await once(ms, "sourceended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_DurationUpdated.html b/dom/media/mediasource/test/test_DurationUpdated.html new file mode 100644 index 0000000000..eb54e76c90 --- /dev/null +++ b/dom/media/mediasource/test/test_DurationUpdated.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append data and check that mediasource duration got updated</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + let durationChangeCount = 0; + v.addEventListener("durationchange", () => durationChangeCount++); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318)); + + // Adding the first init segment will fire a durationchange. + await Promise.all([once(sb, "updateend"), once(v, "loadedmetadata")]); + ok(true, "got loadedmetadata"); + // Set mediasource duration to 0, so future appendBuffer + // will update the mediasource duration. + // Changing the duration will fire a durationchange. + ms.duration = 0; + sb.appendBuffer(new Uint8Array(arrayBuffer, 318)); + // Adding more data will fire durationchange. + await once(sb, "updateend"); + ok(true, "got updateend"); + // this will not fire durationchange as new duration == old duration + ms.endOfStream(); + await once(ms, "sourceended"); + is(durationChangeCount, 3, "durationchange not fired as many times as expected"); + // XXX: Duration should be exactly 4.0, see bug 1065207. + ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_DurationUpdated_mp4.html b/dom/media/mediasource/test/test_DurationUpdated_mp4.html new file mode 100644 index 0000000000..f263264b09 --- /dev/null +++ b/dom/media/mediasource/test/test_DurationUpdated_mp4.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append data and check that mediasource duration got updated</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + let durationChangeCount = 0; + v.addEventListener("durationchange", () => durationChangeCount++); + + const arrayBuffer = await fetchWithXHR("bipbop/bipbop2s.mp4"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 1395)); + + // Adding the first init segment will fire a durationchange. + await Promise.all([once(sb, "updateend"), once(v, "loadedmetadata")]); + ok(true, "got loadedmetadata"); + // Set mediasource duration to 0, so future appendBuffer + // will update the mediasource duration. + // Changing the duration will fire a durationchange. + ms.duration = 0; + sb.appendBuffer(new Uint8Array(arrayBuffer, 1395)); + // Adding more data will fire durationchange. + await once(sb, "updateend"); + ok(true, "got updateend"); + // this will not fire durationchange as new duration == old duration + ms.endOfStream(); + await once(ms, "sourceended"); + is(durationChangeCount, 3, "durationchange not fired as many times as expected"); + is(v.duration, 1.696666, "Video has correct duration"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_EndOfStream.html b/dom/media/mediasource/test/test_EndOfStream.html new file mode 100644 index 0000000000..b926869f1f --- /dev/null +++ b/dom/media/mediasource/test/test_EndOfStream.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: endOfStream call after an appendBuffer</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm"), 0, 88966)); + await once(sb, "updateend"); + await wait(0); + must_not_throw(() => ms.endOfStream(), "MediaSource.endOfStream succeeded"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_EndOfStream_mp4.html b/dom/media/mediasource/test/test_EndOfStream_mp4.html new file mode 100644 index 0000000000..9319b80390 --- /dev/null +++ b/dom/media/mediasource/test/test_EndOfStream_mp4.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: endOfStream call after an appendBuffer</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("bipbop/bipbop2s.mp4"))); + await once(sb, "updateend"); + await wait(0); + must_not_throw(() => ms.endOfStream(), "MediaSource.endOfStream succeeded"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_EndedEvent.html b/dom/media/mediasource/test/test_EndedEvent.html new file mode 100644 index 0000000000..ee43fa8cf5 --- /dev/null +++ b/dom/media/mediasource/test/test_EndedEvent.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm"))); + sb.addEventListener("updateend", () => ms.endOfStream()); + + // Test "ended" is fired when seeking to the end of the media + // once the duration is known. + ms.onsourceended = () => el.currentTime = el.duration; + await once(el, "ended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_Eviction_mp4.html b/dom/media/mediasource/test/test_Eviction_mp4.html new file mode 100644 index 0000000000..e336fae4c7 --- /dev/null +++ b/dom/media/mediasource/test/test_Eviction_mp4.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: QuotaExceededError when source buffer is full</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); +// We fill up the source buffer with audio data until the buffer is full. +// We ensure that QuotaExceededError is thrown once the buffer is full. +// We then seek to half the content. By that time, another appendBuffer must succeed +// as the auto-eviction would succeed (removing all data prior currentTime) + +addMSEPrefs( + ["media.mediasource.eviction_threshold.audio", 524288], + ["media.dormant-on-pause-timeout-ms", -1] // FIXME: bug 1319292 +); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + audiosb.mode = "sequence"; + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + const audioBuffer = await fetchWithXHR("bipbop/bipbop_audio1.m4s"); + + await must_reject(async () => { + // We are appending data repeatedly in sequence mode, there should be no gaps. + while (true) { + ok(audiosb.buffered.length <= 1, "there should be no gap in buffered ranges."); + audiosb.appendBuffer(audioBuffer); + await once(audiosb, "updateend"); + } + }, + "Fill up SourceBuffer by appending data until an exception is thrown.", + "QuotaExceededError"); + + is(audiosb.buffered.end(0), el.duration, "Duration is end of buffered range"); + const seekTime = audiosb.buffered.end(0) / 2; + el.currentTime = seekTime; + await once(el, "seeked"); + dump("dump: seeked to " + seekTime); + is(el.currentTime, seekTime, "correctly seeked to " + seekTime); + try { + audiosb.appendBuffer(audioBuffer); + await once(audiosb, "update"); + ok(true, "appendBuffer succeeded"); + } catch (ex) { + ok(false, "Shouldn't throw another time when data can be evicted"); + dump(JSON.stringify(await SpecialPowers.wrap(el).mozRequestDebugInfo())); + } + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_ExperimentalAsync.html b/dom/media/mediasource/test/test_ExperimentalAsync.html new file mode 100644 index 0000000000..6617716f26 --- /dev/null +++ b/dom/media/mediasource/test/test_ExperimentalAsync.html @@ -0,0 +1,102 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: testing removeAsync and appendBufferAsync</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +addMSEPrefs( + ["media.mediasource.eviction_threshold.audio", 524288], + ["media.dormant-on-pause-timeout-ms", -1], // FIXME: bug 1319292 + ["media.mediasource.experimental.enabled", true] +); + +// We fill up the source buffer with audio data until the buffer is full. +// We ensure that QuotaExceededError is thrown once the buffer is full. +// We then seek to half the content. By that time, another appendBuffer must succeed +// as the auto-eviction would succeed (removing all data prior currentTime) +// The test then fills the audio buffer and plays until the end. + +// Fill up the SourceBuffer by appending data repeatedly via doAppendDataFunc until +// an exception is thrown. +async function fillUpSourceBuffer(sourceBuffer, doAppendDataFunc, onCaughtExceptionCallback) { + try { + // We are appending data repeatedly in sequence mode, there should be no gaps. + while (true) { + ok(sourceBuffer.buffered.length <= 1, "there should be no gap in buffered ranges."); + await doAppendDataFunc(); + } + } catch (ex) { + ok(true, "appendBuffer promise got rejected"); + onCaughtExceptionCallback(ex); + } +} + +runWithMSE(async function(ms, el) { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + + // Test removeAsync + audiosb.mode = "sequence"; + const audioInitBuffer = await fetchWithXHR("bipbop/bipbop_audioinit.mp4"); + await audiosb.appendBufferAsync(audioInitBuffer); + const audioBuffer = await fetchWithXHR("bipbop/bipbop_audio1.m4s"); + fillUpSourceBuffer(audiosb, + function() { // doAppendDataFunc + return audiosb.appendBufferAsync(audioBuffer); + }, + async function(ex1) { // onCaughtExceptionCallback + is(ex1.name, "QuotaExceededError", "QuotaExceededError thrown"); + is(audiosb.buffered.end(0), el.duration, "Duration is end of buffered range"); + const seekTime = audiosb.buffered.end(0) / 2; + el.currentTime = seekTime; + await once(el, "seeked"); + dump("dump: seeked to " + seekTime); + is(el.currentTime, seekTime, "correctly seeked to " + seekTime); + await audiosb.appendBufferAsync(audioBuffer).catch(async function(ex2) { + ok(false, "Shouldn't throw another time when data can be evicted"); + dump(JSON.stringify(await SpecialPowers.wrap(el).mozRequestDebugInfo())); + SimpleTest.finish(); + }); + // Test that an error in remove return a rejected promise + await audiosb.removeAsync(5, 0).catch(async function(ex3) { + ok(true, "remove promise got rejected with end <= start"); + is(ex3.name, "TypeError"); + await audiosb.removeAsync(ms.duration + 1, Infinity).catch(async function(ex4) { + ok(true, "remove promise got rejected with start > duration"); + is(ex4.name, "TypeError"); + await audiosb.removeAsync(0, Infinity).catch(function(ex5) { + ok(false, "shouldn't throw"); + }); + ok(true, "remove succeeded"); + is(audiosb.buffered.length, 0, "buffered should be empty"); + audiosb.mode = "segment"; + audiosb.timestampOffset = 0; + el.currentTime = 0; + await fetchAndLoadAsync(audiosb, "bipbop/bipbop_audio", range(1, 4), ".m4s"); + ms.endOfStream(); + el.play(); + await once(el, "ended"); + is(el.currentTime, el.duration, "played to the end"); + SimpleTest.finish(); + throw ex4; // ensure we don't fallback on lines below. + }); + ok(false, "should have returned an error"); + }); + ok(false, "should have returned an error"); + } + ); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_FrameSelection.html b/dom/media/mediasource/test/test_FrameSelection.html new file mode 100644 index 0000000000..3e696841c2 --- /dev/null +++ b/dom/media/mediasource/test/test_FrameSelection.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: verify correct frames selected for given position</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + let arrayBuffer = await fetchWithXHR("seek.webm"); + let p = once(v, "loadedmetadata"); + // Append entire file covering range [0, 4]. + sb.appendBuffer(new Uint8Array(arrayBuffer)); + await p; + is(v.currentTime, 0, "currentTime has correct initial value"); + is(v.videoWidth, 320, "videoWidth has correct initial value"); + is(v.videoHeight, 240, "videoHeight has correct initial value"); + + arrayBuffer = await fetchWithXHR("seek_lowres.webm"); + // Append initialization segment. + info("Appending low-res init segment"); + p = once(sb, "updateend"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 438)); + await p; + + info("Appending low-res range [2,4]"); + // Append media segment covering range [2, 4]. + p = once(sb, "updateend"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 51003)); + await p; + + ms.endOfStream(); + + info("Seeking to t=3"); + p = Promise.all([once(v, "seeked"), once(v, "resize")]); + v.currentTime = 3; + await p; + is(v.currentTime, 3, "Video currentTime at target"); + is(v.videoWidth, 160, "videoWidth has correct low-res value"); + is(v.videoHeight, 120, "videoHeight has correct low-res value"); + + info("Seeking to t=1"); + p = Promise.all([once(v, "seeked"), once(v, "resize")]); + v.currentTime = 1; + await p; + is(v.currentTime, 1, "Video currentTime at target"); + is(v.videoWidth, 320, "videoWidth has correct high-res value"); + is(v.videoHeight, 240, "videoHeight has correct high-res value"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_FrameSelection_mp4.html b/dom/media/mediasource/test/test_FrameSelection_mp4.html new file mode 100644 index 0000000000..628b4bf0e9 --- /dev/null +++ b/dom/media/mediasource/test/test_FrameSelection_mp4.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Don't get stuck buffering for too long when we have frames to show</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +// This test loads partial video, plays and waits until playback stalls. +// It then loads only 3 frames of a video at higher resolution. + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen")); + const sb = ms.addSourceBuffer("video/mp4"); + ok(sb, "Create a SourceBuffer"); + logEvents(v); + sb.addEventListener("error", e => { + ok(false, `should not fire ${e.type} event`); + SimpleTest.finish(); + }); + await fetchAndLoad(sb, "bipbop/bipbop", ["init"], ".mp4"); + const p = once(v, "loadeddata"); + await fetchAndLoad(sb, "bipbop/bipbop", range(1, 3), ".m4s"); + await p; + is(sb.buffered.length, 1, "continuous range"); + v.play(); + // We have nothing to play, waiting will be fired. + await waitUntilTime(v, 1.5); + await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", ["init"], ".mp4"); + sb.timestampOffset = 1.601666; // End of the video track buffered - time of first video sample (0.095). + sb.appendWindowEnd = 1.796677; // Only allow room for three extra video frames (we need 3 as this video has b-frames). + await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", ["1"], ".m4s"); + ms.endOfStream(); + await Promise.all([once(ms, "sourceended"), once(v, "playing"), once(v, "ended")]); + is(v.videoWidth, 640, "has proper width"); + is(v.videoHeight, 480, "has proper height"); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_HEAAC_extradata.html b/dom/media/mediasource/test/test_HEAAC_extradata.html new file mode 100644 index 0000000000..9fbbec8d72 --- /dev/null +++ b/dom/media/mediasource/test/test_HEAAC_extradata.html @@ -0,0 +1,89 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>HE-AAC decoding test</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +const SOURCE_FILE = "whitenoise-he-aac-5s.mp4"; + +// This test checks when decoding HE-AAC using MediaSource or HTTP playback, the +// audio is decoded correctly (in particular with the SBR part). This means +// that the extradata describing the encoded AAC stream have been communicated +// correctly to the audio decoder. For this, we check that there is energy +// above 10kHz using the Web Audio API when playing white noise, which has +// maximum energy accross the audible spectrum. + +// Return the index corresponding for a particular frequency in an array +// containing frequency data from a FFT. +function binIndexForFrequency(frequency, fftSize, sampleRate) { + return (1 + Math.round((frequency * fftSize) / sampleRate)); +} + +async function checkHighFrequencyContent(element) { + const ac = new AudioContext(); + await ac.resume(); + const mediaElementSource = ac.createMediaElementSource(element); + const analyser = new AnalyserNode(ac); + + // Undo the volume scaling applied globally during test. This is fine because + // the audio isn't routed to an actual audio output device in this test, it's + // just analyzed with the Web Audio API. + const gain = new GainNode(ac); + const testVolumeScaling = + parseFloat(SpecialPowers.getCharPref("media.volume_scale")); + gain.gain.value = 1 / parseFloat(testVolumeScaling); + mediaElementSource.connect(gain).connect(analyser) + + const spectrum = new Float32Array(analyser.frequencyBinCount); + const indexFor15kHz = + binIndexForFrequency(15000, analyser.fftSize, ac.sampleRate); + // Wait a few hundreds of milliseconds + while (!element.ended) { + await once(element, "timeupdate"); + analyser.getFloatFrequencyData(spectrum); + if (spectrum[indexFor15kHz] > -50) { + ok(spectrum[indexFor15kHz] > -50, + `Energy present at 15kHz (bin index: ${indexFor15kHz}) when playing white noise encoded in HE-AAC ${spectrum[indexFor15kHz]}`); + return; + } + } + ok(false, + `No energy present at 15kHz (bin index: ${indexFor15kHz}) when playing white noise encoded in HE-AAC (last value ${spectrum[indexFor15kHz]})`); +} + +runWithMSE(async (ms, el) => { + // First check with MSE playback + el.controls = true; + await once(ms, "sourceopen"); + + const audiosb = ms.addSourceBuffer('audio/mp4; codecs="mp4a.40.5"'); + await fetchAndLoad(audiosb, SOURCE_FILE, [""], ""); + ms.endOfStream(); + el.play(); + once(el, "playing"); + + await checkHighFrequencyContent(el); + + // Redo the same test, with HTTP playback + el.src = SOURCE_FILE; + el.play(); + once(el, "playing"); + + await checkHighFrequencyContent(el); + + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek.html b/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek.html new file mode 100644 index 0000000000..dd1b252f01 --- /dev/null +++ b/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seekable attribute before end of stream</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 67833)); + + const target = 2; + + await once(v, "loadeddata"); + ok(v.readyState >= v.HAVE_CURRENT_DATA, "readyState is >= CURRENT_DATA"); + v.currentTime = target; + + await once(v, "seeking"); + is(v.readyState, v.HAVE_METADATA, "readyState is HAVE_METADATA"); + sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm"), 67833)); + await once(v, "seeked"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek_mp4.html b/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek_mp4.html new file mode 100644 index 0000000000..9b8e885cda --- /dev/null +++ b/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek_mp4.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seekable attribute before end of stream</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + const arrayBuffer = await fetchWithXHR("bipbop/bipbop2s.mp4"); + // 25819 is the offset of the first media segment's end + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 25819)); + + const target = 1.3; + + await once(v, "loadeddata"); + ok(v.readyState >= v.HAVE_CURRENT_DATA, "readyState is >= CURRENT_DATA"); + v.currentTime = target; + + await once(v, "seeking"); + is(v.readyState, v.HAVE_METADATA); + // 25819 is the offset of the first media segment's end + sb.appendBuffer(new Uint8Array(arrayBuffer, 25819)); + await once(sb, "updateend"); + ms.endOfStream(); + await once(v, "seeked"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_InputBufferIsCleared.html b/dom/media/mediasource/test/test_InputBufferIsCleared.html new file mode 100644 index 0000000000..bad9a0c558 --- /dev/null +++ b/dom/media/mediasource/test/test_InputBufferIsCleared.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: input buffer is cleared as expected (bug 1697476)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +// Test bug 1697476 is fixed. We do this by appending a number of segments with +// trailing `skip` boxes. If the bug is fixed, then the data from these appends +// will eventually be cleared from memory. If not fixed, we leak that memory. +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + await fetchAndLoad(sb, "bipbop/bipbop_video", ["init"], ".mp4"); + // Load ~1mb of media. + await fetchAndLoad(sb, "bipbop/bipbop_trailing_skip_box_video", ["1"], ".m4s"); + // Load ~1mb more media several more times. + const numberOfAppends = 5; + for (let i = 1; i < numberOfAppends; ++i) { + sb.timestampOffset = v.buffered.end(0); + await fetchAndLoad(sb, "bipbop/bipbop_trailing_skip_box_video", ["1"], ".m4s"); + } + + // Grab a memory report. We'll use this to make sure we're not accumulating + // too much data in our buffers. + const mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"] + .getService(SpecialPowers.Ci.nsIMemoryReporterManager); + + let amount = 0; + const handleReport = (aProcess, aPath, aKind, aUnits, aAmount) => { + if (aPath == "explicit/media/resources") { + amount += aAmount; + } + }; + + await new Promise(r => mgr.getReports(handleReport, null, r, null, /* anonymized = */ false)); + ok(true, "Yay didn't crash!"); + ok(amount !== undefined, "Got media resources amount"); + const sgementSize = 1023860; + // Set the limit to be equal to the total data we appended. If we're not + // clearing buffers, we'll have all the data from the appends + some other + // data, so will fail. + const limit = sgementSize * numberOfAppends - 1; + ok(amount < limit, `Should have less than ${limit} bytes of media usage. Got ${amount} bytes.`); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_LiveSeekable.html b/dom/media/mediasource/test/test_LiveSeekable.html new file mode 100644 index 0000000000..f48852f6af --- /dev/null +++ b/dom/media/mediasource/test/test_LiveSeekable.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: live seekable range</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + // Load data with a +2 offset so that we can distinguish buffered range start + // and seekable range start. + sb.timestampOffset = 2; + const p = once(v, "loadedmetadata"); + await fetchAndLoad(sb, "seek", [""], ".webm"); + await p; + ms.duration = Infinity; + sb.abort(); + is(sb.buffered.length, 1, "continuous buffered range"); + is(sb.buffered.start(0), 2, "buffered range start at timestamp offset"); + is(sb.buffered.end(0), 6.001, "buffered range end at original duration + timestamp offset"); + is(v.seekable.length, 1, "continuous seekable range"); + is(v.seekable.start(0), 0, "seekable range start at 0"); + is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end"); + + // LiveSeekableRange.start < buffered.start + ms.setLiveSeekableRange(1, 5); + is(v.seekable.length, 1, "continuous seekable range"); + is(v.seekable.start(0), 1, "seekable range start at live range start"); + is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end"); + + ms.clearLiveSeekableRange(); + is(v.seekable.length, 1, "continuous seekable range"); + is(v.seekable.start(0), 0, "seekable range start at 0"); + is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end"); + + // LiveSeekableRange.end > buffered.end + ms.setLiveSeekableRange(1, 8); + is(v.seekable.start(0), 1, "seekable range start at live range start"); + is(v.seekable.end(0), 8, "seekable range end at live range end"); + + // LiveSeekableRange.start > buffered.start + // LiveSeekableRange.end < buffered.end + ms.setLiveSeekableRange(3, 5); + is(v.seekable.start(0), sb.buffered.start(0), "seekable range start at buffered start"); + is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at live range end"); + + // LiveSeekableRange.start > buffered.end + ms.setLiveSeekableRange(8, 10); + is(v.seekable.start(0), sb.buffered.start(0), "seekable range start at buffered start"); + is(v.seekable.end(0), 10, "seekable range end at live range end"); + + // LiveSeekableRange.end < buffered.start + ms.setLiveSeekableRange(0, 2); + is(v.seekable.start(0), 0, "seekable range start at live range start"); + is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end"); + + must_throw(() => ms.setLiveSeekableRange(2, 0), + "must thow if start > end", + "TypeError"); + + must_throw(() => ms.setLiveSeekableRange(2, 0), + "must thow if start > end", + "TypeError"); + + ms.setLiveSeekableRange(0, 1e300); + is(v.seekable.start(0), 0, "seekable range start at live range start"); + is(v.seekable.end(0), 1e300, "seekable range end at specified time"); + + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_LoadedDataFired_mp4.html b/dom/media/mediasource/test/test_LoadedDataFired_mp4.html new file mode 100644 index 0000000000..476303d4fd --- /dev/null +++ b/dom/media/mediasource/test/test_LoadedDataFired_mp4.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: Check that playback only starts once we have data at time = 0</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + el.addEventListener("loadeddata", () => { + ok(el.buffered.length, "data is buffered"); + is(el.buffered.start(0), 0, "must fire loadeddata when data has been loaded"); + is(el.currentTime, 0, "must fire loadeddata at start"); + }); + el.addEventListener("playing", () => { + ok(el.buffered.length, "data is buffered"); + is(el.buffered.start(0), 0, "must fire playing when data has been loaded"); + ok(el.currentTime >= 0, "must have started playback"); + }); + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + let p = once(el, "loadedmetadata"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await p; + videosb.appendWindowStart = 2; + videosb.appendWindowEnd = 4; + is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA"); + // Load [2.4, 3.968344). 2.4 as it's the first keyframe after 2s and + // 3.968344 as the last frame ends after 4s. + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 8), ".m4s"); + is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA"); + // test that appendWindowEnd did its job. + ok(el.buffered.start(0) >= 2, "no data can be found prior appendWindowStart"); + ok(el.buffered.end(el.buffered.length - 1) <= 4, "no data can be found beyond appendWindowEnd"); + el.play(); + await once(el, "play"); + videosb.appendWindowStart = 0; + p = once(el, "playing"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 8), ".m4s"); + await p; + ok(true, "playing"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_LoadedMetadataFired.html b/dom/media/mediasource/test/test_LoadedMetadataFired.html new file mode 100644 index 0000000000..68030dbe2f --- /dev/null +++ b/dom/media/mediasource/test/test_LoadedMetadataFired.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append initialization only</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm"), 0, 318)); + v.play(); + await once(v, "loadedmetadata"); + ok(true, "Got loadedmetadata event"); + is(v.videoWidth, 320, "videoWidth has correct initial value"); + is(v.videoHeight, 240, "videoHeight has correct initial value"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_LoadedMetadataFired_mp4.html b/dom/media/mediasource/test/test_LoadedMetadataFired_mp4.html new file mode 100644 index 0000000000..0934907578 --- /dev/null +++ b/dom/media/mediasource/test/test_LoadedMetadataFired_mp4.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append initialization only</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("bipbop/bipbop2s.mp4"), 0, 1395)); + v.play(); + await once(v, "loadedmetadata"); + ok(true, "Got loadedmetadata event"); + is(v.videoWidth, 400, "videoWidth has correct initial value"); + is(v.videoHeight, 300, "videoHeight has correct initial value"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_MediaSource.html b/dom/media/mediasource/test/test_MediaSource.html new file mode 100644 index 0000000000..9bdaa0d30b --- /dev/null +++ b/dom/media/mediasource/test/test_MediaSource.html @@ -0,0 +1,92 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + SimpleTest.doesThrow(() => new SourceBuffer, "new SourceBuffer should fail"); + SimpleTest.doesThrow(() => new SourceBufferList, "new SourceBufferList direct should fail"); + + ok(ms instanceof EventTarget, "MediaSource must be an EventTarget"); + is(ms.readyState, "closed", "New MediaSource must be in closed state"); + + // Wrapper creation, tests for leaks. + SpecialPowers.wrap(ms); + + // Set an expando to force wrapper creation, tests for leaks. + ms.foo = null; + + ok(URL.createObjectURL(ms), "Create an objectURL from the MediaSource"); + + let loadedmetadataCount = 0; + let updatestartCount = 0; + let updateendCount = 0; + let updateCount = 0; + + ok(MediaSource.isTypeSupported("video/webm; codecs=vp8"), "VP8 MSE is always supported"); + ok(MediaSource.isTypeSupported("audio/webm"), "Audio MSE is always supported"); + + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + is(ms.readyState, "open", "MediaSource must be in open state after sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + ok(sb, "Create a SourceBuffer"); + is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length"); + is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer"); + is(ms.activeSourceBuffers.length, 0, "MediaSource.activeSourceBuffers is expected length"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm"))); + is(sb.updating, true, "SourceBuffer.updating is expected value after appendBuffer"); + + sb.addEventListener("update", () => { + is(sb.updating, false, "SourceBuffer.updating is expected value in update event"); + updateCount++; + /* Ensure that we endOfStream on the first update event only as endOfStream can + raise more if the duration of the last buffered range and the intial duration + differ. See bug 1065207 */ + if (updateCount == 1) { + ms.endOfStream(); + } + }); + + sb.addEventListener("updatestart", () => updatestartCount++); + + sb.addEventListener("updateend", () => { + is(ms.activeSourceBuffers[0], sb, "SourceBuffer in active list matches our SourceBuffer"); + is(sb.updating, false, "SourceBuffer.updating is expected value in updateend event"); + updateendCount++; + v.play(); + }); + + ms.addEventListener("sourceended", () => { + ok(true, "Receive a sourceended event"); + is(ms.readyState, "ended", "MediaSource must be in ended state after sourceended"); + }); + + v.addEventListener("loadedmetadata", () => loadedmetadataCount++); + + await once(v, "ended"); + // XXX: Duration should be exactly 4.0, see bug 1065207. + ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration"); + ok(Math.abs(v.currentTime - 4) <= 0.002, "Video has played to end"); + // XXX: 2 update events can be received dueto duration differences, see bug 1065207. + ok(updateCount == 1 || updateCount == 2, "update event received"); + ok(updateendCount == 1 || updateendCount == 2, "updateend event received"); + ok(updatestartCount == 1 || updatestartCount == 2, "updatestart event received"); + is(loadedmetadataCount, 1, "loadedmetadata event received"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_MediaSource_capture_gc.html b/dom/media/mediasource/test/test_MediaSource_capture_gc.html new file mode 100644 index 0000000000..d986a6f9ac --- /dev/null +++ b/dom/media/mediasource/test/test_MediaSource_capture_gc.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test garbage collection of captured stream, when playing a MediaSource</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="mediasource.js"></script> +</head> +<pre id="test"> +<script class="testbody" type="text/javascript"> +function forceGC() { + SpecialPowers.gc(); + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); +} + +SimpleTest.waitForExplicitFinish(); + +window.onload = async function() { +// Create an infinite source using a MediaSource +let el = document.createElement("audio"); +const ms = new MediaSource(); +el.src = URL.createObjectURL(ms); +await once(ms, "sourceopen"); +const sb = ms.addSourceBuffer("video/mp4"); +await fetchAndLoad(sb, "bipbop/bipbop_audio", ["init"], ".mp4"); +await fetchAndLoad(sb, "bipbop/bipbop_audio", range(1, 11), ".m4s"); +setInterval(async function() { + sb.timestampOffset = sb.buffered.end(sb.buffered.length - 1); + await fetchAndLoad(sb, "bipbop/bipbop_audio", range(1, 11), ".m4s"); +}, 8000); +el.play(); + +// Analyze the media element output. +const ac = new AudioContext; +const analyzer = ac.createAnalyser(); + +// bug 1703603 +const stream = el.mozCaptureStreamUntilEnded(); +const mss = ac.createMediaStreamSource(stream); +const gain = ac.createGain(); +// compensate mochitest volume scaling, but don't connect to the AudioContext's +// destination to avoid noise during the test +gain.gain.value = 90; +mss.connect(gain).connect(analyzer); + + +// Drop the media element reference: it is supposed to be kept alive by the +// AudioContext via the `MediaStream`. +el = null; + +// check whether the media element is still playing using the analyzer, spam the +// GC to ensure all refs are kept. +const buf = new Float32Array(analyzer.frequencyBinCount); +const startTime = Date.now(); +function checkNonSilent() { + analyzer.getFloatFrequencyData(buf); + forceGC(); + // Wait a good 20 seconds. + if (Date.now() - startTime < 2000) { + requestAnimationFrame(checkNonSilent); + } else { + ok(true, "All objects were kept alive."); + SimpleTest.finish(); + } +} +checkNonSilent(); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_MediaSource_disabled.html b/dom/media/mediasource/test/test_MediaSource_disabled.html new file mode 100644 index 0000000000..e14f493e0f --- /dev/null +++ b/dom/media/mediasource/test/test_MediaSource_disabled.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: disabling via pref</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() { + ok(!window.MediaSource && !window.SourceBuffer && !window.SourceBufferList, + "MediaSource should be hidden behind a pref"); + SimpleTest.doesThrow(() => new MediaSource, + "MediaSource should be hidden behind a pref"); + SimpleTest.finish(); +} + +SpecialPowers.pushPrefEnv({"set": + [ + ["media.mediasource.enabled", false], + ], +}, test); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_MediaSource_flac_mp4.html b/dom/media/mediasource/test/test_MediaSource_flac_mp4.html new file mode 100644 index 0000000000..9cc159e467 --- /dev/null +++ b/dom/media/mediasource/test/test_MediaSource_flac_mp4.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Can seek to last frame</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + is(ms.readyState, "open", "MediaSource must be in open state after sourceopen"); + const sb = ms.addSourceBuffer("audio/mp4; codecs=\"flac\""); + ok(sb, "Create a SourceBuffer"); + + await fetchAndLoad(sb, "flac/IS", [""], ".mp4"); + await fetchAndLoad(sb, "flac/0000", range(1, 3), ".m4s"); + el.play(); + ms.endOfStream(); + await once(el, "ended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_MediaSource_memory_reporting.html b/dom/media/mediasource/test/test_MediaSource_memory_reporting.html new file mode 100644 index 0000000000..70c720effd --- /dev/null +++ b/dom/media/mediasource/test/test_MediaSource_memory_reporting.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: memory reporting</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + // Load a webm video and play it. + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + await fetchAndLoad(sb, "seek", [""], ".webm"); + const p = once(v, "ended"); + ms.endOfStream(); + v.play(); + await p; + + // Test that memory reporting works once we've played a video. + // Grab a memory report. + const mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"] + .getService(SpecialPowers.Ci.nsIMemoryReporterManager); + + let amount; + const handleReport = (aProcess, aPath, aKind, aUnits, aAmount) => { + if (aPath == "explicit/media/resources") { + amount = (amount || 0) + aAmount; + } + }; + + await new Promise(r => mgr.getReports(handleReport, null, r, null, /* anonymized = */ false)); + ok(true, "Yay didn't crash!"); + ok(amount !== undefined, "Got media resources amount"); + ok(amount > 0, "Non-zero amount reported for media resources"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_MediaSource_mp4.html b/dom/media/mediasource/test/test_MediaSource_mp4.html new file mode 100644 index 0000000000..2ab79f37f3 --- /dev/null +++ b/dom/media/mediasource/test/test_MediaSource_mp4.html @@ -0,0 +1,90 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + SimpleTest.doesThrow(() => new SourceBuffer, "new SourceBuffer should fail"); + SimpleTest.doesThrow(() => new SourceBufferList, "new SourceBufferList direct should fail"); + + ok(ms instanceof EventTarget, "MediaSource must be an EventTarget"); + is(ms.readyState, "closed", "New MediaSource must be in closed state"); + + // Wrapper creation, tests for leaks. + SpecialPowers.wrap(ms); + + // Set an expando to force wrapper creation, tests for leaks. + ms.foo = null; + + ok(URL.createObjectURL(ms), "Create an objectURL from the MediaSource"); + + let loadedmetadataCount = 0; + let updatestartCount = 0; + let updateendCount = 0; + let updateCount = 0; + + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + is(ms.readyState, "open", "MediaSource must be in open state after sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + ok(sb, "Create a SourceBuffer"); + is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length"); + is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer"); + is(ms.activeSourceBuffers.length, 0, "MediaSource.activeSourceBuffers is expected length"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("bipbop/bipbop2s.mp4"))); + is(sb.updating, true, "SourceBuffer.updating is expected value after appendBuffer"); + + sb.addEventListener("update", () => { + is(sb.updating, false, "SourceBuffer.updating is expected value in update event"); + updateCount++; + /* Ensure that we endOfStream on the first update event only as endOfStream can + raise more if the duration of the last buffered range and the intial duration + differ. See bug 1065207 */ + if (updateCount == 1) { + ms.endOfStream(); + } + }); + + sb.addEventListener("updatestart", () => updatestartCount++); + + sb.addEventListener("updateend", () => { + is(ms.activeSourceBuffers[0], sb, "SourceBuffer in active list matches our SourceBuffer"); + is(sb.updating, false, "SourceBuffer.updating is expected value in updateend event"); + updateendCount++; + v.play(); + }); + + ms.addEventListener("sourceended", () => { + ok(true, "Receive a sourceended event"); + is(ms.readyState, "ended", "MediaSource must be in ended state after sourceended"); + }); + + v.addEventListener("loadedmetadata", () => loadedmetadataCount++); + + await once(v, "ended"); + // The bipbop video doesn't start at 0. The old MSE code adjust the + // timestamps and ignore the audio track. The new one doesn't. + isfuzzy(v.duration, 1.696, 0.166, "Video has correct duration"); + isfuzzy(v.currentTime, 1.696, 0.166, "Video has correct duration"); + // XXX: 2 update events can be received dueto duration differences, see bug 1065207. + ok(updateCount == 1 || updateCount == 2, "update event received"); + ok(updateendCount == 1 || updateendCount == 2, "updateend event received"); + ok(updatestartCount == 1 || updatestartCount == 2, "updatestart event received"); + is(loadedmetadataCount, 1, "loadedmetadata event received"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_MultipleInitSegments.html b/dom/media/mediasource/test/test_MultipleInitSegments.html new file mode 100644 index 0000000000..f4c91c08c5 --- /dev/null +++ b/dom/media/mediasource/test/test_MultipleInitSegments.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Append buffer with multiple init segments</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + const seek_lowres = await fetchWithXHR("seek_lowres.webm"); + const seek = await fetchWithXHR("seek.webm"); + const data = [ + [seek_lowres, 0, 438], // lowres init segment + [seek_lowres, 438, 25950], // lowres media segment 0-1 + [seek, 0, 318], // init segment + [seek, 46712, 67833], // media segment 0.8-1.201 + ]; + const length = data.map(d => d[2] - d[1]).reduce((a, b) => a + b, 0); + const arrayBuffer = new Uint8Array(length); + let pos = 0; + for (const d of data) { + const buffer = new Uint8Array(d[0], d[1], d[2] - d[1]); + arrayBuffer.set(buffer, pos); + pos += buffer.byteLength; + } + await loadSegment(sb, arrayBuffer); + // Since we are passing multiple segments in one buffer, + // the first durationchange event from parsing the init + // segment will be fired before updateend. + const p = once(v, "durationchange"); + ms.endOfStream(); + await p; + ok(v.duration, 1.201); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_MultipleInitSegments_mp4.html b/dom/media/mediasource/test/test_MultipleInitSegments_mp4.html new file mode 100644 index 0000000000..47c115677d --- /dev/null +++ b/dom/media/mediasource/test/test_MultipleInitSegments_mp4.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Append buffer with multiple init segments</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + const init = new Uint8Array(await fetchWithXHR("bipbop/bipbop_videoinit.mp4")); + const segment1 = new Uint8Array(await fetchWithXHR("bipbop/bipbop_video1.m4s")); + const segment2 = new Uint8Array(await fetchWithXHR("bipbop/bipbop_video2.m4s")); + const data = [init, segment1, init, segment2]; + const length = data.map(d => d.byteLength).reduce((a, b) => a + b, 0); + const arrayBuffer = new Uint8Array(length); + let pos = 0; + for (const buffer of data) { + arrayBuffer.set(buffer, pos); + pos += buffer.byteLength; + } + await loadSegment(sb, arrayBuffer); + // Since we are passing multiple segments in one buffer, + // the first durationchange event from parsing the init + // segment will be fired before updateend. + const p = once(v, "durationchange"); + ms.endOfStream(); + await p; + ok(v.duration, 1.601666); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_NoAudioLoopBackData.html b/dom/media/mediasource/test/test_NoAudioLoopBackData.html new file mode 100644 index 0000000000..7de7209b74 --- /dev/null +++ b/dom/media/mediasource/test/test_NoAudioLoopBackData.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: loop-back data not available yet (shorter audio)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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 check whether a looping video can loop back successfully + * when it has a shorter audio track than its video track. When reaching EOS for + * the shorter track, there is no loop-back data at the start position (they are + * not appended yet) Even that, we should still be able to loop back but the + * looping would become non-seamless in this situation. + */ +SimpleTest.waitForExplicitFinish(); + +runWithMSE(async (ms, el) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + + // Here we create a shorter audio than video. + info(`create different length source buffers`); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 8), ".m4s"); + audiosb.appendWindowEnd = videosb.buffered.end(0) - 0.2; + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(5, 8), ".m4s"); + ms.endOfStream(); + await Promise.all([once(el, "durationchange"), once(ms, "sourceended")]); + info(`audio=[${audiosb.buffered.start(0)}-${audiosb.buffered.end(0)}], video=[${videosb.buffered.start(0)}-${videosb.buffered.end(0)}]`); + ok(true, `endOfStream completed, buffer=[${el.buffered.start(0)}, ${el.buffered.end(0)}]`); + ok(videosb.buffered.end(0) > audiosb.buffered.end(0), `video should be longer than audio`); + + info(`seek to the position where buffered data exists`); + el.loop = true; + el.controls = true; + el.currentTime = el.buffered.start(0); + await el.play(); + + info(`video should trigger seeking when reaching to the end`); + let seekingCount = 0, seekedCount = 0; + el.addEventListener("seeking", () => { + is(++seekingCount, 1, "should only receive seeking once!"); + }); + el.addEventListener("seeked", () => { + is(++seekedCount, 1, "should only receive seeked once!"); + }); + await once(el, "seeking"); + + info(`trim old data before append new data`); + let p = Promise.all([once(videosb, "updateend"), once(audiosb, "updateend")]); + videosb.remove(videosb.buffered.start(0), videosb.buffered.end(0)); + audiosb.remove(audiosb.buffered.start(0), audiosb.buffered.end(0)); + await p; + + info(`append new data`); + const seekedPromise = once(el, "seeked"); + p = Promise.all([once(videosb, "updateend"), once(audiosb, "updateend")]); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 2), ".m4s"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 2), ".m4s"); + await p; + info(`audio=[${audiosb.buffered.start(0)}-${audiosb.buffered.end(0)}], video=[${videosb.buffered.start(0)}-${videosb.buffered.end(0)}]`); + + info(`now we should be able to finish seeking to the start position`); + await seekedPromise; + + SimpleTest.finish(SimpleTest); +}); + +</script> +</body> +</html> diff --git a/dom/media/mediasource/test/test_NoAudioLoopBackData_Muted.html b/dom/media/mediasource/test/test_NoAudioLoopBackData_Muted.html new file mode 100644 index 0000000000..14cdf34bc6 --- /dev/null +++ b/dom/media/mediasource/test/test_NoAudioLoopBackData_Muted.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: loop-back data not available yet (shorter MUTED audio)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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 check whether a looping video can loop back successfully + * when it has a shorter MUTED audio track than its video track. When reaching + * EOS for the shorter track, there is no loop-back data at the start position + * (they are not appended yet) Even that, we should still be able to loop back + * but the looping would become non-seamless in this situation. + */ +SimpleTest.waitForExplicitFinish(); + +runWithMSE(async (ms, el) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + + // Here we create a shorter audio than video. + info(`create different length source buffers`); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 8), ".m4s"); + audiosb.appendWindowEnd = videosb.buffered.end(0) - 0.2; + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(5, 8), ".m4s"); + ms.endOfStream(); + await Promise.all([once(el, "durationchange"), once(ms, "sourceended")]); + info(`audio=[${audiosb.buffered.start(0)}-${audiosb.buffered.end(0)}], video=[${videosb.buffered.start(0)}-${videosb.buffered.end(0)}]`); + ok(true, `endOfStream completed, buffer=[${el.buffered.start(0)}, ${el.buffered.end(0)}]`); + ok(videosb.buffered.end(0) > audiosb.buffered.end(0), `video should be longer than audio`); + + info(`seek to the position where buffered data exists`); + el.muted = true; + el.loop = true; + el.controls = true; + el.currentTime = el.buffered.start(0); + await el.play(); + + info(`video should trigger seeking when reaching to the end`); + let seekingCount = 0, seekedCount = 0; + el.addEventListener("seeking", () => { + is(++seekingCount, 1, "should only receive seeking once!"); + }); + el.addEventListener("seeked", () => { + is(++seekedCount, 1, "should only receive seeked once!"); + }); + await once(el, "seeking"); + + info(`trim old data before append new data`); + let p = Promise.all([once(videosb, "updateend"), once(audiosb, "updateend")]); + videosb.remove(videosb.buffered.start(0), videosb.buffered.end(0)); + audiosb.remove(audiosb.buffered.start(0), audiosb.buffered.end(0)); + await p; + + info(`append new data`); + const seekedPromise = once(el, "seeked"); + p = Promise.all([once(videosb, "updateend"), once(audiosb, "updateend")]); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 2), ".m4s"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 2), ".m4s"); + await p; + info(`audio=[${audiosb.buffered.start(0)}-${audiosb.buffered.end(0)}], video=[${videosb.buffered.start(0)}-${videosb.buffered.end(0)}]`); + + info(`now we should be able to finish seeking to the start position`); + await seekedPromise; + + SimpleTest.finish(SimpleTest); +}); + +</script> +</body> +</html> diff --git a/dom/media/mediasource/test/test_NoVideoLoopBackData.html b/dom/media/mediasource/test/test_NoVideoLoopBackData.html new file mode 100644 index 0000000000..407b2ecb42 --- /dev/null +++ b/dom/media/mediasource/test/test_NoVideoLoopBackData.html @@ -0,0 +1,81 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: loop-back data not available yet (shorter video)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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 check whether a looping video can loop back successfully + * when it has a shorter video track than its audio track. When reaching EOS for + * the shorter track, there is no loop-back data at the start position (they are + * not appended yet) Even that, we should still be able to loop back but the + * looping would become non-seamless in this situation. + */ +SimpleTest.waitForExplicitFinish(); + +runWithMSE(async (ms, el) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + + // Here we create a way shorter video than audio because audio decoding is + // very fast. If two track only have small diffence in length, audio track + // would still reach to the end first. But in this test, we want to test + // reaching video EOS first. + info(`create different length source buffers`); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(5, 8), ".m4s"); + videosb.appendWindowEnd = audiosb.buffered.end(0) - 2.5; + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 8), ".m4s"); + ms.endOfStream(); + await Promise.all([once(el, "durationchange"), once(ms, "sourceended")]); + info(`audio=[${audiosb.buffered.start(0)}-${audiosb.buffered.end(0)}], video=[${videosb.buffered.start(0)}-${videosb.buffered.end(0)}]`); + ok(true, `endOfStream completed, buffer=[${el.buffered.start(0)}, ${el.buffered.end(0)}]`); + ok(audiosb.buffered.end(0) > videosb.buffered.end(0), `audio should be longer than video`); + + info(`seek to the position where buffered data exists`); + el.loop = true; + el.controls = true; + el.currentTime = el.buffered.start(0); + await el.play(); + + info(`video should trigger seeking when reaching to the end`); + let seekingCount = 0, seekedCount = 0; + el.addEventListener("seeking", () => { + is(++seekingCount, 1, "should only receive seeking once!"); + }); + el.addEventListener("seeked", () => { + is(++seekedCount, 1, "should only receive seeked once!"); + }); + await once(el, "seeking"); + + info(`trim old data before append new data`); + let p = Promise.all([once(videosb, "updateend"), once(audiosb, "updateend")]); + videosb.remove(videosb.buffered.start(0), videosb.buffered.end(0)); + audiosb.remove(audiosb.buffered.start(0), audiosb.buffered.end(0)); + await p; + + info(`append new data`); + const seekedPromise = once(el, "seeked"); + p = Promise.all([once(videosb, "updateend"), once(audiosb, "updateend")]); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 2), ".m4s"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 2), ".m4s"); + await p; + info(`audio=[${audiosb.buffered.start(0)}-${audiosb.buffered.end(0)}], video=[${videosb.buffered.start(0)}-${videosb.buffered.end(0)}]`); + + info(`now we should be able to finish seeking to the start position`); + await seekedPromise; + + SimpleTest.finish(SimpleTest); +}); + +</script> +</body> +</html> diff --git a/dom/media/mediasource/test/test_OnEvents.html b/dom/media/mediasource/test/test_OnEvents.html new file mode 100644 index 0000000000..ae0f348ebe --- /dev/null +++ b/dom/media/mediasource/test/test_OnEvents.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: live seekable range</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + const receiveEvent = e => v["got" + e] = true; + + const msevents = ["onsourceopen", "onsourceended"]; + msevents.forEach(e => ms[e] = () => receiveEvent(e)); + + const sblistevents = ["onaddsourcebuffer", "onremovesourcebuffer"]; + sblistevents.forEach(e => ms.sourceBuffers[e] = () => receiveEvent(e)); + + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const sbevents = ["onupdatestart", "onupdate", "onupdateend", "onabort"]; + sbevents.forEach(e => sb[e] = () => receiveEvent(e)); + + await fetchAndLoad(sb, "seek", [""], ".webm"); + sb.appendBuffer(await fetchWithXHR("seek.webm")); + ms.removeSourceBuffer(sb); // will fire abort and removesourcebuffer + ms.endOfStream(); // will fire sourceended + await once(ms, "sourceended"); + [...msevents, ...sbevents, ...sblistevents].forEach(e => ok(v["got" + e], "got " + e)); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_PlayEvents.html b/dom/media/mediasource/test/test_PlayEvents.html new file mode 100644 index 0000000000..82ccaa42b5 --- /dev/null +++ b/dom/media/mediasource/test/test_PlayEvents.html @@ -0,0 +1,115 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +// This test checks that readyState is properly set and the appropriate events are being fired accordingly: +// 1. Load 1.6s of data and ensure that canplay event is fired. +// 2. Load data to have a complete buffered range from 0 to duration and ensure that canplaythrough is fired. +// 3. Seek to an area with no buffered data, and ensure that readyState goes back to HAVE_METADATA +// 4. Load 1.6s of data at the seek position and ensure that canplay is fired and that readyState is now HAVE_FUTURE_DATA +// 5. Start playing video and check that once it reaches a position with no data, readyState goes back to HAVE_CURRENT_DATA and waiting event is fired. +// 6. Add 1.6s of data once video element fired waiting, that canplay is fired once readyState is HAVE_FUTURE_DATA. +// 7. Finally load data to the end and ensure that canplaythrough is fired and that readyState is now HAVE_ENOUGH_DATA + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + logEvents(el); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + el.addEventListener("error", e => { + ok(false, `should not fire ${e.type} event`); + SimpleTest.finish(); + }); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + let p = once(el, "loadedmetadata"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await p; + ok(true, "got loadedmetadata event"); + p = Promise.all([once(el, "loadeddata"), once(el, "canplay")]); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s"); + await p; + ok(true, "got canplay event"); + // set element duration to 3.203333s. We do so in order to guarantee that + // the end of the buffered range will be equal to duration, causing + // canplaythrough to be fired later. + ms.duration = 3.203333; + await once(el, "durationchange"); + ok(true, "got durationchange event"); + // Load [0.801666, 3.203333] + p = once(el, "canplaythrough"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s"); + await p; + ok(true, "got canplaythrough event"); + // set element duration to 9.203333s, this value is set to coincide with + // data added later (we now have an empty range from 6s to 9.203333s). + ms.duration = 9.203333; + await once(el, "durationchange"); + ok(true, "got durationchange event"); + // An arbitrary value, so we are guaranteed to be in a range with no data. + el.currentTime = 6; + videosb.timestampOffset = 6; + ok(el.seeking, "seeking started"); + await once(el, "seeking"); + ok(true, "got seeking event"); + is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA"); + // Load [6+0, 6+1.601666) + p = Promise.all([once(el, "seeked"), once(el, "canplay")]); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s"); + await p; + ok(true, "got seeked and canplay event"); + is(el.currentTime, 6, "seeked to 6s"); + is(el.readyState, el.HAVE_FUTURE_DATA, "readyState is HAVE_FUTURE_DATA"); + // Load [6+1.60166, 6+3.203333] + p = once(el, "canplaythrough"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s"); + await p; + ok(true, "got canplaythrough event"); + // set element duration to 19.805s, this value is set to coincide with + // data added later (we now have an empty range from 15 to 19.805). + ms.duration = 19.805; + await once(el, "durationchange"); + ok(true, "got durationchange event"); + el.currentTime = 15; + videosb.timestampOffset = 15; + ok(el.seeking, "seeking started"); + await once(el, "seeking"); + ok(true, "got seeking event"); + // Load [15+0, 15+1.601666) + p = once(el, "seeked"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s"); + await p; + ok(true, "got seeked event"); + // Load [15+1.60166, 15+3.203333] + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s"); + ok(true, "data loaded"); + // Playback we play for a little while then stall. + p = Promise.all([once(el, "playing"), once(el, "waiting")]); + el.play(); + await p; + ok(true, "got playing and waiting event"); + // Playback has stalled, readyState is back to HAVE_CURRENT_DATA. + is(el.readyState, el.HAVE_CURRENT_DATA, "readyState is HAVE_CURRENT_DATA"); + // Load [15+3.203333, 15+4.805) + // Our final buffered range will now be [0, 3.203333)[6, 9.203333)[15, 19.805) + p = Promise.all([once(el, "playing"), once(el, "canplay"), once(el, "canplaythrough")]); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 7), ".m4s"); + await p; + ok(true, "got playing, canplay and canplaythrough event"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_PlayEventsAutoPlaying.html b/dom/media/mediasource/test/test_PlayEventsAutoPlaying.html new file mode 100644 index 0000000000..3e395c799d --- /dev/null +++ b/dom/media/mediasource/test/test_PlayEventsAutoPlaying.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +// This test checks that readyState is properly set and the appropriate events are being fired accordingly: +// 1. Ensure that play/playing aren't fired before any media data been added. +// 2. Load 1.6s of data and ensure that canplay, play and playing events are fired. + +runWithMSE(async (ms, el) => { + el.controls = true; + el.autoplay = true; + const eventCounts = { play: 0, playing: 0 }; + await once(ms, "sourceopen"); + logEvents(el); + ok(true, "Receive a sourceopen event"); + + const forbiddenEvents = e => { + ok(el.readyState >= el.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]++; + }; + el.addEventListener("play", forbiddenEvents); + el.addEventListener("playing", forbiddenEvents); + + const videosb = ms.addSourceBuffer("video/mp4"); + el.addEventListener("error", e => { + ok(false, `should not fire ${e.type} event`); + SimpleTest.finish(); + }); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + let p = once(el, "loadedmetadata"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await p; + ok(true, "got loadedmetadata event"); + // We're only adding 1.6s worth of data, not enough for readyState to change to HAVE_ENOUGH_DATA + // So we end the media source so that all the playable data is available. + p = Promise.all(["loadeddata", "canplay", "play", "playing", "ended"].map(e => once(el, e))); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s"); + ms.endOfStream(); + await p; + ok(true, "got all required event"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_PlayEventsAutoPlaying2.html b/dom/media/mediasource/test/test_PlayEventsAutoPlaying2.html new file mode 100644 index 0000000000..8845a26ac4 --- /dev/null +++ b/dom/media/mediasource/test/test_PlayEventsAutoPlaying2.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +// This test checks that readyState is properly set and the appropriate events are being fired accordingly: +// 1. Ensure that play/playing aren't fired before any media data been added. +// 2. Load more than 10s of data and ensure that canplay, play and playing events are fired. + +runWithMSE(async (ms, el) => { + el.controls = true; + el.autoplay = true; + const eventCounts = { play: 0, playing: 0 }; + await once(ms, "sourceopen"); + logEvents(el); + ok(true, "Receive a sourceopen event"); + + const forbiddenEvents = e => { + ok(el.readyState >= el.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]++; + }; + el.addEventListener("play", forbiddenEvents); + el.addEventListener("playing", forbiddenEvents); + + const videosb = ms.addSourceBuffer("video/mp4"); + el.addEventListener("error", e => { + ok(false, `should not fire ${e.type} event`); + SimpleTest.finish(); + }); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + let p = once(el, "loadedmetadata"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await p; + ok(true, "got loadedmetadata event"); + // We shift the timestamps slightly to create a small gaps at the start. + // one that should normally be ignored. + videosb.timestampOffset = 0.1; + p = Promise.all(["loadeddata", "canplay", "play", "playing"].map(e => once(el, e))); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 14), ".m4s"); + await p; + ok(true, "got all required event"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_RemoveSourceBuffer.html b/dom/media/mediasource/test/test_RemoveSourceBuffer.html new file mode 100644 index 0000000000..11c6a51deb --- /dev/null +++ b/dom/media/mediasource/test/test_RemoveSourceBuffer.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: check buffered status after removed all source buffer</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"><script class="testbody" type="text/javascript"> + +const videoURL = "seek.webm"; + +SimpleTest.waitForExplicitFinish(); + +runWithMSE(async function(ms, el) { + info("- wait for sourceopen -"); + await once(ms, "sourceopen"); + + info("- wait for fetching data -"); + const arrayBuffer = await fetchWithXHR(videoURL); + + info("- create source buffer and append data -"); + const sourceBuffer = ms.addSourceBuffer("video/webm"); + sourceBuffer.appendBuffer(arrayBuffer); + await once(sourceBuffer, "updateend"); + is(ms.sourceBuffers.length, 1, + "the length of source buffers list is 1."); + is(ms.activeSourceBuffers.length, 1, + "the length of active source buffers list is 1."); + ok(ms.duration != 0, "duration is not 0."); + is(el.buffered.length, 1, "buffered range is 1."); + + info("- remove source buffer from media source -"); + ms.removeSourceBuffer(sourceBuffer); + await once(ms.sourceBuffers, "removesourcebuffer"); + is(ms.sourceBuffers.length, 0, "source buffers list is empty."); + is(ms.activeSourceBuffers.length, 0, "active source buffers list is empty."); + ok(ms.duration != 0, "duration is not 0."); + is(el.buffered.length, 0, + "buffered range is empty since we don't have any source buffer."); + + info("- call endOfStream -"); + ms.endOfStream(); + is(ms.duration, 0, "duraton is 0 since we don't have any source buffer."); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_Resolution_change_should_not_cause_video_freeze.html b/dom/media/mediasource/test/test_Resolution_change_should_not_cause_video_freeze.html new file mode 100644 index 0000000000..640b53441e --- /dev/null +++ b/dom/media/mediasource/test/test_Resolution_change_should_not_cause_video_freeze.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: video resolution changes during playback should not cause video freeze (Bug 1718709)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer('video/mp4'); + sb.appendBuffer(new Uint8Array(await fetchWithXHR("bug1718709_low_res.mp4"))); + ok(true, "appended low resolution video"); + sb.appendBuffer(new Uint8Array(await fetchWithXHR("bug1718709_high_res.mp4"))); + ok(true, "appended high resolution video"); + + info(`start from the position which is near to the place where resolution changes`); + v.currentTime = 13; + ok(await v.play().then(_=>true,_=>false), "video started playing"); + + // When video resolution changes, it should not cause video freeze so we check + // its painted frame amount regularly to see if we stop updating video frames. + let lastPaintedFramesAmount = v.mozPaintedFrames; + const intervalHandle = setInterval(_=>{ + ok(lastPaintedFramesAmount < v.mozPaintedFrames, + `painted frames keeps growing from ${lastPaintedFramesAmount} to ${v.mozPaintedFrames}`); + lastPaintedFramesAmount = v.mozPaintedFrames; + }, 1000); + + // As we didn't append full video, so we will receive `waiting` event later + // which indicates that we can stop testing because we've finished playing + // the high resolution part. + await new Promise(r => { + v.onwaiting = _ => { + clearInterval(intervalHandle); + r(); + } + }); + SimpleTest.finish(); +}); + +</script> +</body> +</html> diff --git a/dom/media/mediasource/test/test_ResumeAfterClearing_mp4.html b/dom/media/mediasource/test/test_ResumeAfterClearing_mp4.html new file mode 100644 index 0000000000..40e512ba12 --- /dev/null +++ b/dom/media/mediasource/test/test_ResumeAfterClearing_mp4.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Don't get stuck buffering for too long when we have frames to show</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen")); + const sb = ms.addSourceBuffer("video/mp4"); + ok(sb, "Create a SourceBuffer"); + sb.addEventListener("error", e => { + ok(false, "Got Error: " + e); + SimpleTest.finish(); + }); + await fetchAndLoad(sb, "bipbop/bipbop", ["init"], ".mp4"); + let p = once(v, "loadeddata"); + await fetchAndLoad(sb, "bipbop/bipbop", range(1, 3), ".m4s"); + await p; + // clear the entire sourcebuffer. + sb.remove(0, 5); + await once(sb, "updateend"); + v.play(); + // We have nothing to play, waiting will be fired. + await once(v, "waiting"); + p = once(v, "playing"); + await fetchAndLoad(sb, "bipbop/bipbop", range(1, 4), ".m4s"); + await p; + ms.endOfStream(); + await Promise.all([once(ms, "sourceended"), once(v, "ended")]); + SimpleTest.finish(SimpleTest); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekNoData_mp4.html b/dom/media/mediasource/test/test_SeekNoData_mp4.html new file mode 100644 index 0000000000..1ea64f3fa4 --- /dev/null +++ b/dom/media/mediasource/test/test_SeekNoData_mp4.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + const videosb = ms.addSourceBuffer("video/mp4"); + el.addEventListener("error", e => { + ok(false, `should not fire ${e.type} event`); + SimpleTest.finish(); + }); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + must_not_throw(() => el.currentTime = 3, "setting currentTime is valid"); + is(el.currentTime, 3, "currentTime is default playback start position"); + is(el.seeking, false, "seek not started with HAVE_NOTHING"); + await Promise.all([ + fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"), + fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"), + once(el, "loadedmetadata"), + ]); + const p = once(el, "seeking"); + el.play(); + el.currentTime = 5; + is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA"); + is(el.seeking, true, "seek not started with HAVE_METADATA"); + is(el.currentTime, 5, "currentTime is seek position"); + await p; + ok(true, "Got seeking event"); + await Promise.all([ + once(el, "seeked"), + fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(5, 9), ".m4s"), + fetchAndLoad(videosb, "bipbop/bipbop_video", range(6, 10), ".m4s"), + ]); + ok(true, "Got seeked event"); + ok(el.currentTime >= 5, "Time >= 5"); + ms.endOfStream(); + await once(el, "ended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekToEnd_mp4.html b/dom/media/mediasource/test/test_SeekToEnd_mp4.html new file mode 100644 index 0000000000..0405cb875f --- /dev/null +++ b/dom/media/mediasource/test/test_SeekToEnd_mp4.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seeking to end of data with data gap.</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 6), ".m4s"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + is(videosb.buffered.length, 1, "continuous buffered range"); + // Ensure we have at least 2s less audio than video. + audiosb.appendWindowEnd = videosb.buffered.end(0) - 2; + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 6), ".m4s"); + ms.endOfStream(); + await Promise.all([once(el, "durationchange"), once(ms, "sourceended")]); + ok(true, "endOfStream completed"); + // Seek to the middle of the gap where audio is missing. As we are in readyState = ended + // seeking must complete. + el.currentTime = videosb.buffered.end(0) / 2 + audiosb.buffered.end(0) / 2; + ok(el.currentTime - audiosb.buffered.end(0) >= 1, "gap is big enough"); + is(el.buffered.length, 1, "continuous buffered range"); + is(el.buffered.end(0), videosb.buffered.end(0), + "buffered range end is aligned with longest track"); + ok(el.seeking, "element is now seeking"); + ok(el.currentTime >= el.buffered.start(0) && el.currentTime <= el.buffered.end(0), + "seeking time is in buffered range"); + ok(el.currentTime > audiosb.buffered.end(0), + "seeking point is not buffered in audio track"); + await once(el, "seeked"); + ok(true, "we have successfully seeked"); + // Now ensure that we can play to the end, even though we are missing data in one track. + el.play(); + await once(el, "ended"); + SimpleTest.finish(SimpleTest); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekToLastFrame_mp4.html b/dom/media/mediasource/test/test_SeekToLastFrame_mp4.html new file mode 100644 index 0000000000..edbfdff0a0 --- /dev/null +++ b/dom/media/mediasource/test/test_SeekToLastFrame_mp4.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Can seek to last frame</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const sb = ms.addSourceBuffer("video/mp4"); + await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", ["init"], ".mp4"); + await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", range(1, 3), ".m4s"); + el.play(); + // let seek to the last audio frame. + el.currentTime = 1.532517; + await once(el, "seeked"); + ok(true, "seek completed"); + ms.endOfStream(); + await once(el, "ended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekTwice_mp4.html b/dom/media/mediasource/test/test_SeekTwice_mp4.html new file mode 100644 index 0000000000..50ff32b1cd --- /dev/null +++ b/dom/media/mediasource/test/test_SeekTwice_mp4.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + const videosb = ms.addSourceBuffer("video/mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(6, 12), ".m4s"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 6), ".m4s"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(7, 14), ".m4s"); + let p = once(el, "seeking"); + el.play(); + el.currentTime = 4.5; // Seek to a gap in the video + await p; + ok(true, "Got seeking event"); + p = once(el, "seeked"); + el.currentTime = 6; // Seek past the gap. + await p; + ok(true, "Got seeked event"); + ok(el.currentTime >= 6, "Time >= 6"); + ms.endOfStream(); + await once(el, "ended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStream.html b/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStream.html new file mode 100644 index 0000000000..c65a4aff7e --- /dev/null +++ b/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStream.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seekable attribute after end of stream</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + info("- append first buffer -"); + sb.appendBuffer(new Uint8Array(arrayBuffer)); + + info("- wait for metadata -"); + await once(v, "loadedmetadata"); + + info("- wait for updateend -"); + await once(sb, "updateend"); + + info("- check seekable -"); + const target = 2; + ok(v.seekable.length, "Resource is seekable"); + is(v.seekable.start(0), 0, "Seekable's start point is correct"); + is(v.seekable.end(0), ms.duration, "Seekable's end point is correct"); + ok(v.seekable.length && + target >= v.seekable.start(0) && + target < v.seekable.end(0), "Target is within seekable range"); + + info("- call end of stream -"); + ms.endOfStream(); + await once(ms, "sourceended"); + + info("- check seekable -"); + ok(v.seekable.length, "Resource is seekable"); + is(v.seekable.start(0), 0, "Seekable's start point is correct"); + is(v.seekable.end(0), ms.duration, "Seekable's end point is correct"); + ok(v.seekable.length && + target >= v.seekable.start(0) && + target < v.seekable.end(0), "Target is within seekable range"); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStreamSplit.html b/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStreamSplit.html new file mode 100644 index 0000000000..bed2af8d48 --- /dev/null +++ b/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStreamSplit.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seekable attribute after end of stream with split appendBuffer</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + info("- append first buffer -"); + // 25523 is the offset of the first media segment's end + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 25523)); + + info("- wait for metadata -"); + await once(v, "loadedmetadata"); + + info("- wait for updateend -"); + await once(sb, "updateend"); + + info("- append second buffer -"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 25523)); + await once(sb, "updateend"); + + info("- check seekable -"); + const target = 2; + ok(v.seekable.length, "Resource is seekable"); + is(v.seekable.start(0), 0, "Seekable's start point is correct"); + is(v.seekable.end(0), ms.duration, "Seekable's end point is correct"); + ok(v.seekable.length && + target >= v.seekable.start(0) && + target < v.seekable.end(0), "Target is within seekable range"); + + info("- call end of stream -"); + ms.endOfStream(); + await once(ms, "sourceended"); + + info("- check seekable -"); + ok(v.seekable.length, "Resource is seekable"); + is(v.seekable.start(0), 0, "Seekable's start point is correct"); + is(v.seekable.end(0), ms.duration, "Seekable's end point is correct"); + ok(v.seekable.length && + target >= v.seekable.start(0) && + target < v.seekable.end(0), "Target is within seekable range"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStreamSplit_mp4.html b/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStreamSplit_mp4.html new file mode 100644 index 0000000000..00b5f9a832 --- /dev/null +++ b/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStreamSplit_mp4.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seekable attribute after end of stream with split appendBuffer</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + const arrayBuffer = await fetchWithXHR("bipbop/bipbop2s.mp4"); + info("- append first buffer -"); + // 25819 is the offset of the first media segment's end + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 25819)); + + info("- wait for metadata -"); + await once(v, "loadedmetadata"); + + info("- wait for updateend -"); + await once(sb, "updateend"); + + info("- append second buffer -"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 25819)); + await once(sb, "updateend"); + + info("- check seekable -"); + const target = 1.3; + ok(v.seekable.length, "Resource is seekable"); + is(v.seekable.start(0), 0, "Seekable's start point is correct"); + is(v.seekable.end(0), ms.duration, "Seekable's end point is correct"); + ok(v.seekable.length && + target >= v.seekable.start(0) && + target < v.seekable.end(0), "Target is within seekable range"); + + info("- call end of stream -"); + ms.endOfStream(); + await once(ms, "sourceended"); + + info("- check seekable -"); + ok(v.seekable.length, "Resource is seekable"); + is(v.seekable.start(0), 0, "Seekable's start point is correct"); + is(v.seekable.end(0), ms.duration, "Seekable's end point is correct"); + ok(v.seekable.length && + target >= v.seekable.start(0) && + target < v.seekable.end(0), "Target is within seekable range"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStream_mp4.html b/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStream_mp4.html new file mode 100644 index 0000000000..c8e53833fb --- /dev/null +++ b/dom/media/mediasource/test/test_SeekableBeforeAndAfterEndOfStream_mp4.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: seekable attribute after end of stream</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + const arrayBuffer = await fetchWithXHR("bipbop/bipbop2s.mp4"); + info("- append buffer -"); + sb.appendBuffer(new Uint8Array(arrayBuffer)); + + info("- wait for metadata -"); + await once(v, "loadedmetadata"); + + info("- wait for updateend -"); + await once(sb, "updateend"); + + info("- check seekable -"); + const target = 1.3; + ok(v.seekable.length, "Resource is seekable"); + is(v.seekable.start(0), 0, "Seekable's start point is correct"); + is(v.seekable.end(0), ms.duration, "Seekable's end point is correct"); + ok(v.seekable.length && + target >= v.seekable.start(0) && + target < v.seekable.end(0), "Target is within seekable range"); + + info("- call end of stream -"); + ms.endOfStream(); + await once(ms, "sourceended"); + + info("- check seekable -"); + ok(v.seekable.length, "Resource is seekable"); + is(v.seekable.start(0), 0, "Seekable's start point is correct"); + is(v.seekable.end(0), ms.duration, "Seekable's end point is correct"); + ok(v.seekable.length && + target >= v.seekable.start(0) && + target < v.seekable.end(0), "Target is within seekable range"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SeekedEvent_mp4.html b/dom/media/mediasource/test/test_SeekedEvent_mp4.html new file mode 100644 index 0000000000..70401f1eb1 --- /dev/null +++ b/dom/media/mediasource/test/test_SeekedEvent_mp4.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: Check that seeked event is fired prior loadeddata</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + const events = ["seeked", "loadeddata", "playing"]; + let eventCount = 0; + events.forEach(type => el.addEventListener(type, + () => is(events[eventCount++], type, "events must come in order"))); + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING"); + let p = once(el, "loadedmetadata"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await p; + el.play(); + videosb.timestampOffset = 2; + is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA"); + // Load [2, 3.606). + p = once(el, "play"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["1"], ".m4s"); + await p; + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["2"], ".m4s"); + // TODO: readyState should be at least HAVE_CURRENTDATA, see bug 1367993. + ok(el.readyState >= el.HAVE_METADATA, "readyState is HAVE_METADATA"); + el.currentTime = 2; + await Promise.all([once(el, "seeked"), once(el, "playing")]); + ok(true, "completed seek"); + is(eventCount, events.length, "Received expected number of events"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_Sequence_mp4.html b/dom/media/mediasource/test/test_Sequence_mp4.html new file mode 100644 index 0000000000..5af7fe5a0b --- /dev/null +++ b/dom/media/mediasource/test/test_Sequence_mp4.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: Don't get stuck buffering for too long when we have frames to show</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen")); + const sb = ms.addSourceBuffer("video/mp4"); + ok(sb, "Create a SourceBuffer"); + sb.addEventListener("error", e => { + ok(false, "Got Error: " + e); + SimpleTest.finish(); + }); + sb.mode = "sequence"; + + await fetchAndLoad(sb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(sb, "bipbop/bipbop_video", ["5"], ".m4s"); + await fetchAndLoad(sb, "bipbop/bipbop_video", ["2"], ".m4s"); + is(v.buffered.length, 1, "Continuous buffered range"); + is(v.buffered.start(0), 0, "Buffered range starts at 0"); + ok(sb.timestampOffset >= 0, "SourceBuffer.timestampOffset set to allow continuous range"); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SetModeThrows.html b/dom/media/mediasource/test/test_SetModeThrows.html new file mode 100644 index 0000000000..c715854b41 --- /dev/null +++ b/dom/media/mediasource/test/test_SetModeThrows.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append initialization</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +// MSE supports setting mode now. make sure it does not throw. +runWithMSE(function(ms, v) { + ms.addEventListener("sourceopen", () => { + const sb = ms.addSourceBuffer("video/webm"); + + sb.mode = "segments"; + ok("true", "Setting to segments does not throw"); + try { + sb.mode = "sequence"; + ok("true", "Setting to sequence does not throw"); + } catch (e) { ok(false, "Should not throw setting mode to sequence: " + e); } + + SimpleTest.finish(); + }); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SplitAppend.html b/dom/media/mediasource/test/test_SplitAppend.html new file mode 100644 index 0000000000..a4be5de282 --- /dev/null +++ b/dom/media/mediasource/test/test_SplitAppend.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append initialization and media segment separately</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318)); + v.play(); + await once(sb, "updateend"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 318)); + await once(sb, "updateend"); + ms.endOfStream(); + await once(v, "ended"); + // XXX: Duration should be exactly 4.0, see bug 1065207. + ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration"); + ok(Math.abs(v.currentTime - 4) <= 0.002, "Video has played to end"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SplitAppendDelay.html b/dom/media/mediasource/test/test_SplitAppendDelay.html new file mode 100644 index 0000000000..40183c3db0 --- /dev/null +++ b/dom/media/mediasource/test/test_SplitAppendDelay.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append segments with delay</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); +SimpleTest.requestFlakyTimeout("untriaged"); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const arrayBuffer = await fetchWithXHR("seek.webm"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318)); + v.play(); + await once(sb, "updateend"); + await wait(1000); + sb.appendBuffer(new Uint8Array(arrayBuffer, 318)); + await once(sb, "updateend"); + ms.endOfStream(); + await once(v, "ended"); + // XXX: Duration should be exactly 4.0, see bug 1065207. + ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration"); + ok(Math.abs(v.currentTime - 4) <= 0.002, "Video has played to end"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SplitAppendDelay_mp4.html b/dom/media/mediasource/test/test_SplitAppendDelay_mp4.html new file mode 100644 index 0000000000..c072a526cf --- /dev/null +++ b/dom/media/mediasource/test/test_SplitAppendDelay_mp4.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append segments with delay</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); +SimpleTest.requestFlakyTimeout("untriaged"); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + const arrayBuffer = await fetchWithXHR("bipbop/bipbop2s.mp4"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 1395)); + v.play(); + await once(sb, "updateend"); + await wait(1000); + sb.appendBuffer(new Uint8Array(arrayBuffer, 1395)); + await once(sb, "updateend"); + ms.endOfStream(); + await once(v, "ended"); + // The bipbop video doesn't start at 0. The old MSE code adjust the + // timestamps and ignore the audio track. The new one doesn't. + isfuzzy(v.duration, 1.696, 0.166, "Video has correct duration"); + isfuzzy(v.currentTime, 1.696, 0.166, "Video has played to end"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_SplitAppend_mp4.html b/dom/media/mediasource/test/test_SplitAppend_mp4.html new file mode 100644 index 0000000000..308fa9837d --- /dev/null +++ b/dom/media/mediasource/test/test_SplitAppend_mp4.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: append initialization and media segment separately</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + const arrayBuffer = await fetchWithXHR("bipbop/bipbop2s.mp4"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 1395)); + v.play(); + await once(sb, "updateend"); + sb.appendBuffer(new Uint8Array(arrayBuffer, 1395)); + await once(sb, "updateend"); + ms.endOfStream(); + + await once(v, "ended"); + // The bipbop video doesn't start at 0. The old MSE code adjust the + // timestamps and ignore the audio track. The new one doesn't. + isfuzzy(v.duration, 1.696, 0.166, "Video has correct duration"); + isfuzzy(v.currentTime, 1.696, 0.166, "Video has played to end"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_Threshold_mp4.html b/dom/media/mediasource/test/test_Threshold_mp4.html new file mode 100644 index 0000000000..c46883c93d --- /dev/null +++ b/dom/media/mediasource/test/test_Threshold_mp4.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: data gap detection</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + const threshold = 0.5; // gap threshold in seconds. + const fuzz = 0.000001; // fuzz when comparing double. + + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const videosb = ms.addSourceBuffer("video/mp4"); + const vchunks = [{start: 0, end: 3.203333}, { start: 3.203333, end: 6.406666}]; + + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s"); + // We will insert a gap of threshold + videosb.timestampOffset = threshold; + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s"); + // HTMLMediaElement fires 'waiting' if somebody invokes |play()| before the MDSM + // has notified it of available data. Make sure that we get 'playing' before + // we starting waiting for 'waiting'. + info("Invoking play()"); + let p = once(el, "playing"); + el.play(); + await p; + await once(el, "waiting"); + // We're waiting for data after the start of the last frame. + // 0.033333 is the duration of the last frame. + ok((el.currentTime >= vchunks[1].end - 0.033333 + threshold - fuzz && + el.currentTime <= vchunks[1].end + threshold + fuzz), + `skipped the gap properly: ${el.currentTime} ${vchunks[1].end + threshold}`); + is(el.buffered.length, 2, "buffered range has right length"); + // Now we test that seeking will succeed despite the gap. + el.currentTime = el.buffered.end(0) + (threshold / 2); + await once(el, "seeked"); + // Now we test that we don't pass the gap. + // Clean up our sourcebuffer by removing all data. + videosb.timestampOffset = 0; + videosb.remove(0, Infinity); + el.currentTime = 0; + el.pause(); + await once(videosb, "updateend"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s"); + // We will insert a gap of threshold + 1ms + videosb.timestampOffset = threshold + 1 / 1000; + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s"); + info("Invoking play()"); + p = once(el, "playing"); + el.play(); + await p; + await once(el, "waiting"); + // We're waiting for data after the start of the last frame. + // 0.033333 is the duration of the last frame. + ok((el.currentTime >= vchunks[0].end - 0.033333 - fuzz && + el.currentTime <= vchunks[0].end + fuzz), + `stopped at the gap properly: ${el.currentTime} ${vchunks[0].end}`); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_TimestampOffset_mp4.html b/dom/media/mediasource/test/test_TimestampOffset_mp4.html new file mode 100644 index 0000000000..bd08e0f36e --- /dev/null +++ b/dom/media/mediasource/test/test_TimestampOffset_mp4.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: basic functionality</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + const eps = 0.01; + + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + const videosb = ms.addSourceBuffer("video/mp4"); + // We divide the video into 3 chunks: + // chunk 0: segments 1-4 + // chunk 1: segments 5-8 + // chunk 2: segments 9-13 + // We then fill the timeline so that it seamlessly plays the chunks in order 0, 2, 1. + const vchunks = [{start: 0, end: 3.2033}, + { start: 3.2033, end: 6.4066}, + { start: 6.4066, end: 10.01}]; + const firstvoffset = vchunks[2].end - vchunks[2].start; // Duration of chunk 2 + const secondvoffset = -(vchunks[1].end - vchunks[1].start); // -(Duration of chunk 1) + + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s"); + is(videosb.buffered.length, 1, "No discontinuity"); + isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "Chunk start"); + isfuzzy(videosb.buffered.end(0), vchunks[0].end, eps, "Chunk end"); + videosb.timestampOffset = firstvoffset; + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s"); + is(videosb.buffered.length, 2, "One discontinuity"); + isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "First Chunk start"); + isfuzzy(videosb.buffered.end(0), vchunks[0].end, eps, "First chunk end"); + isfuzzy(videosb.buffered.start(1), vchunks[1].start + firstvoffset, eps, "Second chunk start"); + isfuzzy(videosb.buffered.end(1), vchunks[1].end + firstvoffset, eps, "Second chunk end"); + videosb.timestampOffset = secondvoffset; + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(9, 14), ".m4s"); + is(videosb.buffered.length, 1, "No discontinuity (end)"); + isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "Chunk start"); + isfuzzy(videosb.buffered.end(0), vchunks[2].end, eps, "Chunk end"); + audiosb.timestampOffset = 3; + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 12), ".m4s"); + is(audiosb.buffered.length, 1, "No audio discontinuity"); + isfuzzy(audiosb.buffered.start(0), 3, eps, "Audio starts at 3"); + + // Trim the rest of the audio. + audiosb.remove(videosb.buffered.end(0), Infinity); + videosb.remove(videosb.buffered.end(0), Infinity); + if (audiosb.updating) { + await once(audiosb, "updateend"); + } + if (videosb.updating) { + await once(videosb, "updateend"); + } + info("waiting for play to complete"); + el.play(); + el.currentTime = el.buffered.start(0); + ms.endOfStream(); + await Promise.all([once(el, "ended"), once(el, "seeked")]); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_TruncatedDuration.html b/dom/media/mediasource/test/test_TruncatedDuration.html new file mode 100644 index 0000000000..c80e40ac98 --- /dev/null +++ b/dom/media/mediasource/test/test_TruncatedDuration.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: truncating the media seeks to end of media and update buffered range</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// This test append data to a mediasource and then seek to half the duration +// of the video. +// We then shorten the video to 1/3rd of its original size by modifying the +// mediasource.duration attribute. +// We ensure that the buffered range immediately reflect the truncation +// and that we've seeked to the new end of the media as per W3C spec and +// video.currentTime got updated. + +SimpleTest.waitForExplicitFinish(); + +const round = n => Math.round(n * 1000) / 1000; + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm"))); + await once(sb, "updateend"); + v.currentTime = v.duration / 2; + is(v.currentTime, v.duration / 2, "current time was updated"); + ok(v.seeking, "seeking is true"); + await once(v, "seeked"); + const duration = round(v.duration / 3); + is(sb.updating, false, "sourcebuffer isn't updating"); + sb.remove(duration, Infinity); + await once(sb, "updateend"); + ms.duration = duration; + // frames aren't truncated, so duration may be slightly more. + isfuzzy(v.duration, duration, 1 / 30, "element duration was updated"); + sb.abort(); // this shouldn't abort updating the duration (bug 1130826). + ok(v.seeking, "seeking is true"); + // test playback position was updated (bug 1130839). + is(v.currentTime, v.duration, "current time was updated"); + is(sb.buffered.length, 1, "One buffered range"); + // Truncated mediasource duration will cause the video element to seek. + await once(v, "seeking"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_TruncatedDuration_mp4.html b/dom/media/mediasource/test/test_TruncatedDuration_mp4.html new file mode 100644 index 0000000000..2f37150fd3 --- /dev/null +++ b/dom/media/mediasource/test/test_TruncatedDuration_mp4.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: truncating the media seeks to end of media and update buffered range</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// This test append data to a mediasource and then seek to half the duration +// of the video. +// We then shorten the video to 1/3rd of its original size. +// We ensure that the buffered range immediately reflect the truncation +// and that we've seeked to the new end of the media as per W3C spec and +// video.currentTime got updated. + +SimpleTest.waitForExplicitFinish(); + +const round = n => Math.round(n * 1000) / 1000; + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/mp4"); + + sb.appendBuffer(new Uint8Array(await fetchWithXHR("bipbop/bipbop2s.mp4"))); + await once(sb, "updateend"); + // mp4 metadata states 10s when we only have 1.6s worth of video. + sb.remove(sb.buffered.end(0), Infinity); + await once(sb, "updateend"); + ms.duration = sb.buffered.end(0); + is(v.duration, ms.duration, "current time updated with mediasource duration"); + v.currentTime = v.duration / 2; + is(v.currentTime, v.duration / 2, "current time was updated"); + ok(v.seeking, "seeking is true"); + await once(v, "seeked"); + const duration = round(v.duration / 3); + is(sb.updating, false, "sourcebuffer isn't updating"); + sb.remove(duration, Infinity); + await once(sb, "updateend"); + ms.duration = duration; + // frames aren't truncated, so duration may be slightly more. + isfuzzy(v.duration, duration, 1 / 30, "element duration was updated"); + sb.abort(); // this shouldn't abort updating the duration (bug 1130826). + ok(v.seeking, "seeking is true"); + // test playback position was updated (bug 1130839). + is(v.currentTime, v.duration, "current time was updated"); + is(sb.buffered.length, 1, "One buffered range"); + // Truncated mediasource duration will cause the video element to seek. + await once(v, "seeking"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_WMFUnmatchedAudioDataTime.html b/dom/media/mediasource/test/test_WMFUnmatchedAudioDataTime.html new file mode 100644 index 0000000000..7c03214c7b --- /dev/null +++ b/dom/media/mediasource/test/test_WMFUnmatchedAudioDataTime.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: audio output time doesn't match the input time on WMF</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer('audio/mp4;codecs=" mp4a.40.2"'); + sb.appendBuffer(new Uint8Array(await fetchWithXHR("wmf_mismatchedaudiotime.mp4"))); + ok(true, "appended data"); + + info(`if error doesn't occur, we should be able to receive 'seeked', otherwise 'error' would be dispatched`); + v.currentTime = 22.05; + ok(await Promise.race([ + once(v, "seeked").then(_ => true), + once(v, "error").then(_ => false), + ]), "finished seeking without any error"); + ok(!v.error, "should not get any error"); + SimpleTest.finish(); +}); + +</script> +</body> +</html> diff --git a/dom/media/mediasource/test/test_WaitingOnMissingData.html b/dom/media/mediasource/test/test_WaitingOnMissingData.html new file mode 100644 index 0000000000..b1ad41bb37 --- /dev/null +++ b/dom/media/mediasource/test/test_WaitingOnMissingData.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: |waiting| event when source data is missing</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const sb = ms.addSourceBuffer("video/webm"); + sb.addEventListener("error", e => { + ok(false, "Got Error: " + e); + SimpleTest.finish(); + }); + const arrayBuffer = await fetchWithXHR("seek.webm"); + await loadSegment(sb, new Uint8Array(arrayBuffer, 0, 318)); + await loadSegment(sb, new Uint8Array(arrayBuffer, 318, 25223 - 318)); + await loadSegment(sb, new Uint8Array(arrayBuffer, 25223, 46712 - 25223)); + /* Note - Missing |46712, 67833 - 46712| segment here */ + await loadSegment(sb, new Uint8Array(arrayBuffer, 67833, 88966 - 67833)); + await loadSegment(sb, new Uint8Array(arrayBuffer, 88966)); + // HTMLMediaElement fires "waiting" if somebody invokes |play()| before the MDSM + // has notified it of available data. Make sure that we get "playing" before + // we starting waiting for "waiting". + info("Invoking play()"); + let p = once(el, "playing"); + el.play(); + await p; + ok(true, "Video playing. It should play for a bit, then fire 'waiting'"); + p = once(el, "waiting"); + el.play(); + await p; + // currentTime is based on the current video frame, so if the audio ends just before + // the next video frame, currentTime can be up to 1 frame's worth earlier than + // min(audioEnd, videoEnd). + // 0.0465 is the length of the last audio frame. + ok(el.currentTime >= (sb.buffered.end(0) - 0.0465), + `Got a waiting event at ${el.currentTime}`); + info("Loading more data"); + p = once(el, "ended"); + await loadSegment(sb, new Uint8Array(arrayBuffer, 46712, 67833 - 46712)); + ms.endOfStream(); + await p; + // These fuzz factors are bigger than they should be. We should investigate + // and fix them in bug 1137574. + isfuzzy(el.duration, 4.001, 0.1, "Video has correct duration: " + el.duration); + isfuzzy(el.currentTime, el.duration, 0.1, "Video has correct currentTime."); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_WaitingOnMissingDataEnded_mp4.html b/dom/media/mediasource/test/test_WaitingOnMissingDataEnded_mp4.html new file mode 100644 index 0000000000..8ca61eae7e --- /dev/null +++ b/dom/media/mediasource/test/test_WaitingOnMissingDataEnded_mp4.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: |waiting| event when source data is missing</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + el.addEventListener("ended", () => { + ok(false, "ended should never fire"); + SimpleTest.finish(); + }); + const videosb = ms.addSourceBuffer("video/mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(6, 8), ".m4s"); + is(el.buffered.length, 2, "discontinuous buffered range"); + ms.endOfStream(); + await Promise.all([once(el, "durationchange"), once(ms, "sourceended")]); + // HTMLMediaElement fires "waiting" if somebody invokes |play()| before the MDSM + // has notified it of available data. Make sure that we get "playing" before + // we starting waiting for "waiting". + info("Invoking play()"); + el.play(); + await once(el, "playing"); + ok(true, "Video playing. It should play for a bit, then fire 'waiting'"); + await once(el, "waiting"); + // waiting is fired when we start to play the last frame. + // 0.033334 is the duration of the last frame, + 0.000001 of fuzz. + // the next video frame, currentTime can be up to 1 frame's worth earlier than end of video. + isfuzzy(el.currentTime, videosb.buffered.end(0), 0.033334, "waiting was fired on gap"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_WaitingOnMissingData_mp4.html b/dom/media/mediasource/test/test_WaitingOnMissingData_mp4.html new file mode 100644 index 0000000000..f6768754e7 --- /dev/null +++ b/dom/media/mediasource/test/test_WaitingOnMissingData_mp4.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: |waiting| event when source data is missing</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + const videosb = ms.addSourceBuffer("video/mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(6, 12), ".m4s"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 6), ".m4s"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(7, 14), ".m4s"); + // HTMLMediaElement fires "waiting" if somebody invokes |play()| before the MDSM + // has notified it of available data. Make sure that we get "playing" before + // we starting waiting for "waiting". + info("Invoking play()"); + let p = once(el, "playing"); + el.play(); + await p; + ok(true, "Video playing. It should play for a bit, then fire 'waiting'"); + p = once(el, "waiting"); + el.play(); + await p; + // currentTime is based on the current video frame, so if the audio ends just before + // the next video frame, currentTime can be up to 1 frame's worth earlier than + // min(audioEnd, videoEnd). + // 0.0465 is the length of the last audio frame. + ok(el.currentTime >= (Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 0.0465), + `Got a waiting event at ${el.currentTime}`); + info("Loading more data"); + p = once(el, "ended"); + await Promise.all([ + fetchAndLoad(audiosb, "bipbop/bipbop_audio", [5], ".m4s"), + fetchAndLoad(videosb, "bipbop/bipbop_video", [6], ".m4s"), + ]); + ms.endOfStream(); + await p; + // These fuzz factors are bigger than they should be. We should investigate + // and fix them in bug 1137574. + isfuzzy(el.duration, 10.1, 0.1, "Video has correct duration: " + el.duration); + isfuzzy(el.currentTime, el.duration, 0.1, "Video has correct currentTime."); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_WaitingToEndedTransition_mp4.html b/dom/media/mediasource/test/test_WaitingToEndedTransition_mp4.html new file mode 100644 index 0000000000..9c3fc73161 --- /dev/null +++ b/dom/media/mediasource/test/test_WaitingToEndedTransition_mp4.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=windows-1252"> + <title>MSE: |waiting| event when source data is missing</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + const videosb = ms.addSourceBuffer("video/mp4"); + // ensure tracks end at approximately the same time to ensure ended event is + // always fired (bug 1233639). + audiosb.appendWindowEnd = 3.9; + videosb.appendWindowEnd = 3.9; + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", ["init"], ".mp4"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", ["init"], ".mp4"); + await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s"); + await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 6), ".m4s"); + // HTMLMediaElement fires "waiting" if somebody invokes |play()| before the MDSM + // has notified it of available data. Make sure that we get "playing" before + // we starting waiting for "waiting". + info("Invoking play()"); + let p = once(el, "playing"); + el.play(); + await p; + ok(true, "Video playing. It should play for a bit, then fire 'waiting'"); + await once(el, "waiting"); + p = once(el, "ended"); + ms.endOfStream(); + await p; + // Following bug 1524890, we now implement fully step 8 of the coded frame + // processing algorithm + // http://w3c.github.io/media-source/index.html#sourcebuffer-coded-frame-processing + // As such, duration is exactly the value of videosb.appendWindowEnd + is(el.duration, videosb.appendWindowEnd, "Video has correct duration: " + el.duration); + is(el.currentTime, el.duration, "Video has correct currentTime."); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_WebMTagsBeforeCluster.html b/dom/media/mediasource/test/test_WebMTagsBeforeCluster.html new file mode 100644 index 0000000000..d1d45173cd --- /dev/null +++ b/dom/media/mediasource/test/test_WebMTagsBeforeCluster.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: WebM tags element before cluster element</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +addMSEPrefs(["media.mediasource.webm.enabled", true]); + +runWithMSE(async (ms, v) => { + await once(ms, "sourceopen"); + const sb = ms.addSourceBuffer("video/webm"); + + const arrayBuffer = await fetchWithXHR("tags_before_cluster.webm"); + info("- append buffer -"); + sb.appendBuffer(new Uint8Array(arrayBuffer)); + + info("- wait for metadata -"); + await once(v, "loadedmetadata"); + + info("- wait for updateend -"); + await once(sb, "updateend"); + + info("- call end of stream -"); + ms.endOfStream(); + await once(ms, "sourceended"); + + info("- check buffered range -"); + is(sb.buffered.length, 1, "buffered range is not empty."); + + info("- video is playing -"); + v.play(); + await once(v, "timeupdate"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/test_trackidchange_mp4.html b/dom/media/mediasource/test/test_trackidchange_mp4.html new file mode 100644 index 0000000000..fdbeece3cd --- /dev/null +++ b/dom/media/mediasource/test/test_trackidchange_mp4.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>MSE: test append of audio with similar init segments that have different track ids</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mediasource.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(); + +runWithMSE(async (ms, el) => { + el.controls = true; + await once(ms, "sourceopen"); + ok(true, "Receive a sourceopen event"); + const audiosb = ms.addSourceBuffer("audio/mp4"); + await fetchAndLoad(audiosb, "init-trackid2", [''], ".mp4"); + await fetchAndLoad(audiosb, "segment-2.0001", [''], ".m4s"); + await fetchAndLoad(audiosb, "init-trackid3", [''], ".mp4"); + await fetchAndLoad(audiosb, "segment-3.0002", [''], ".m4s"); + is(el.buffered.length, 1, "data is buffered"); + is(el.buffered.end(0), 8, "all data got appended"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/mediasource/test/whitenoise-he-aac-5s.mp4 b/dom/media/mediasource/test/whitenoise-he-aac-5s.mp4 Binary files differnew file mode 100644 index 0000000000..db648b8229 --- /dev/null +++ b/dom/media/mediasource/test/whitenoise-he-aac-5s.mp4 diff --git a/dom/media/mediasource/test/wmf_mismatchedaudiotime.mp4 b/dom/media/mediasource/test/wmf_mismatchedaudiotime.mp4 Binary files differnew file mode 100644 index 0000000000..9e179bd326 --- /dev/null +++ b/dom/media/mediasource/test/wmf_mismatchedaudiotime.mp4 |