| <!DOCTYPE html> |
| <html> |
| <title>MediaSource-in-Worker looped playback test case with worker termination at various places</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <body> |
| <script> |
| |
| function terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_remaining) { |
| if (timeouts_remaining <= 0) { |
| worker.terminate(); |
| test.step_timeout(() => { test.done(); }, 0); |
| } else { |
| test.step_timeout(() => { |
| terminateWorkerAfterMultipleSetTimeouts(test, worker, --timeouts_remaining); |
| }, 0); |
| } |
| } |
| |
| function startWorkerAndTerminateWorker(test, when_to_start_timeouts, timeouts_to_await) { |
| // Fail fast if MSE-in-Workers is not supported. |
| assert_true(MediaSource.hasOwnProperty("canConstructInDedicatedWorker"), "MediaSource hasOwnProperty 'canConstructInDedicatedWorker'"); |
| assert_true(MediaSource.canConstructInDedicatedWorker, "MediaSource.canConstructInDedicatedWorker"); |
| |
| const worker = new Worker("mediasource-worker-util.js"); |
| worker.onerror = test.unreached_func("worker error"); |
| |
| const video = document.createElement("video"); |
| document.body.appendChild(video); |
| video.onerror = test.unreached_func("video element error"); |
| |
| if (when_to_start_timeouts == "after first ended event") { |
| video.addEventListener("ended", test.step_func(() => { |
| terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_to_await); |
| video.currentTime = 0; |
| video.loop = true; |
| }), { once : true }); |
| } else { |
| video.loop = true; |
| } |
| |
| if (when_to_start_timeouts == "before setting src") { |
| terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_to_await); |
| } |
| |
| worker.onmessage = test.step_func(e => { |
| if (e.data.substr(0,6) == "Error:") { |
| assert_unreached("Worker error: " + e.data); |
| } else { |
| const url = e.data |
| assert_true(url.match(/^blob:.+/) != null); |
| video.src = url; |
| if (when_to_start_timeouts == "after setting src") { |
| terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_to_await); |
| } |
| video.play().catch(error => { |
| // Only rejections due to MEDIA_ERR_SRC_NOT_SUPPORTED are expected to possibly |
| // occur, except if we expect to reach at least 1 'ended' event. |
| assert_not_equals(when_to_start_timeouts, "after first ended event"); |
| assert_true(video.error != null); |
| assert_equals(video.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
| // Do not rethrow. Instead, wait for the step_timeouts to finish the test. |
| }); |
| } |
| }); |
| } |
| |
| [ "before setting src", "after setting src", "after first ended event" ].forEach(when => { |
| for (let timeouts = 0; timeouts < 10; ++timeouts) { |
| async_test(test => { startWorkerAndTerminateWorker(test, when, timeouts); }, |
| "Test worker MediaSource termination after at least " + timeouts + |
| " main thread setTimeouts, starting counting " + when); |
| } |
| }); |
| |
| </script> |
| </body> |
| </html> |