mediasource-worker-play-terminate-worker.html (3569B)
1 <!DOCTYPE html> 2 <html> 3 <title>MediaSource-in-Worker looped playback test case with worker termination at various places</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="mediasource-message-util.js"></script> 7 <body> 8 <script> 9 10 function terminateWorkerAfterMultipleSetTimeouts(video, test, worker, timeouts_remaining) { 11 if (timeouts_remaining <= 0) { 12 // Terminating the worker may introduce errors in the video element we don't care about. 13 video.onerror = null; 14 worker.terminate(); 15 test.step_timeout(() => { test.done(); }, 0); 16 } else { 17 test.step_timeout(() => { 18 terminateWorkerAfterMultipleSetTimeouts(video, test, worker, --timeouts_remaining); 19 }, 0); 20 } 21 } 22 23 function startWorkerAndTerminateWorker(test, when_to_start_timeouts, timeouts_to_await) { 24 // Fail fast if MSE-in-Workers is not supported. 25 assert_true(MediaSource.hasOwnProperty("canConstructInDedicatedWorker"), "MediaSource hasOwnProperty 'canConstructInDedicatedWorker'"); 26 assert_true(MediaSource.canConstructInDedicatedWorker, "MediaSource.canConstructInDedicatedWorker"); 27 28 const worker = new Worker("mediasource-worker-play-terminate-worker.js"); 29 worker.onerror = test.unreached_func("worker error"); 30 31 const video = document.createElement("video"); 32 document.body.appendChild(video); 33 video.onerror = _ => { 34 assert_unreached( 35 `video element error: \"${video.error.message}\": ${video.error.code}`); 36 } 37 38 if (when_to_start_timeouts == "after first ended event") { 39 video.addEventListener("ended", test.step_func(() => { 40 terminateWorkerAfterMultipleSetTimeouts(video, test, worker, timeouts_to_await); 41 video.currentTime = 0; 42 video.loop = true; 43 }), { once : true }); 44 } else { 45 video.loop = true; 46 } 47 48 if (when_to_start_timeouts == "before setting srcObject") { 49 terminateWorkerAfterMultipleSetTimeouts(video, test, worker, timeouts_to_await); 50 } 51 52 worker.onmessage = test.step_func(e => { 53 let subject = e.data.subject; 54 assert_true(subject != undefined, "message must have a subject field"); 55 switch (subject) { 56 case messageSubject.ERROR: 57 assert_unreached("Worker error: " + e.data.info); 58 break; 59 case messageSubject.HANDLE: 60 const handle = e.data.info; 61 video.srcObject = handle; 62 if (when_to_start_timeouts == "after setting srcObject") { 63 terminateWorkerAfterMultipleSetTimeouts(video, test, worker, timeouts_to_await); 64 } 65 video.play().catch(error => { 66 // Only rejections due to MEDIA_ERR_SRC_NOT_SUPPORTED are expected to possibly 67 // occur, except if we expect to reach at least 1 'ended' event. 68 assert_not_equals(when_to_start_timeouts, "after first ended event"); 69 assert_true(video.error != null); 70 assert_equals(video.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); 71 // Do not rethrow. Instead, wait for the step_timeouts to finish the test. 72 }); 73 break; 74 default: 75 assert_unreached("Unexpected message subject: " + subject); 76 } 77 }); 78 } 79 80 [ "before setting srcObject", "after setting srcObject", "after first ended event" ].forEach(when => { 81 for (let timeouts = 0; timeouts < 10; ++timeouts) { 82 async_test(test => { startWorkerAndTerminateWorker(test, when, timeouts); }, 83 "Test worker MediaSource termination after at least " + timeouts + 84 " main thread setTimeouts, starting counting " + when); 85 } 86 }); 87 88 </script> 89 </body> 90 </html>