Skip to content

Commit

Permalink
[MSE] ManagedMediaSource isn't usable in a DedicatedWorker
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=270891
rdar://124499286

Reviewed by Youenn Fablet.

The HTMLMediaElement was never attached to the MediaSource (or ManagedMediaSource) running
in the dedicated worker.
While this didn't prevent MediaSource to work, it would have caused the ManagedMediaSource
to never move to the `Open` readyState as the MMS need to check the HTMLMediaElement if
an AirPlay alternative is present.
The MediaSourceHandle uses the ensureOnDispatcher utility to dispatch to the MediaSource
dispatcher, which will not run the function should MediaSource::isClosed() return true.
We need to force the function to run when we attach the HTMLMediaElement which in turn
will move the readyState to `open`.

Added test.

* LayoutTests/media/media-source/worker/media-managedmse-worker-expected.txt: Added.
* LayoutTests/media/media-source/worker/media-managedmse-worker.html: Added.
* LayoutTests/media/media-source/worker/worker.js: Added.
(logToMain):
(onmessage):
* LayoutTests/platform/glib/TestExpectations:
* Source/WebCore/Modules/mediasource/MediaSourceHandle.cpp:
(WebCore::MediaSourceHandle::ensureOnDispatcher const):
* Source/WebCore/Modules/mediasource/MediaSourceHandle.h:
* Source/WebCore/Modules/mediasource/MediaSourceInterfaceWorker.cpp:
(WebCore::MediaSourceInterfaceWorker::attachToElement):

Canonical link: https://commits.webkit.org/276140@main
  • Loading branch information
jyavenard committed Mar 15, 2024
1 parent 2773206 commit 321003e
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

RUN(video.disableRemotePlayback = true)
received handle message: [object MediaSourceHandle] OK
info message from worker: sourceopen event received OK
END OF TEST

34 changes: 34 additions & 0 deletions LayoutTests/media/media-source/worker/media-managedmse-worker.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html> <!-- webkit-test-runner [ ManagedMediaSourceEnabled=true MediaSourceEnabled=true ] -->
<html>
<head>
<title>managedmediasource in worker</title>
<script src="../../../media/video-test.js"></script>
<script>
window.addEventListener('load', async event => {
findMediaElement();

const worker = new Worker('worker.js');
worker.onmessage = msg => {
switch (msg.data.topic) {
case 'handle':
logResult(true, 'received handle message: ' + msg.data.arg);
video.srcObject = msg.data.arg;
break;
case 'info':
logResult(true, 'info message from worker: ' + msg.data.arg);
endTest();
break;
default:
logResult(false, 'error: Unrecognized topic in message from worker');
break;
}
};
run('video.disableRemotePlayback = true');
worker.postMessage({ });
});
</script>
</head>
<body>
<video controls></video>
</body>
</html>
16 changes: 16 additions & 0 deletions LayoutTests/media/media-source/worker/worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function logToMain(msg) {
postMessage({topic: 'info', arg: msg});
}

onmessage = (e) => {
const ms = new ManagedMediaSource();
const handle = ms.handle;

ms.onsourceopen = () => {
logToMain("sourceopen event received");
};
// Transfer the MediaSourceHandle to the main thread for use in attaching to
// the main thread media element that will play the content being buffered
// here in the worker.
postMessage({topic: 'handle', arg: handle}, [handle]);
};
3 changes: 3 additions & 0 deletions LayoutTests/platform/glib/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,9 @@ media/media-source/media-managedmse-memorypressure.html [ Timeout ]
media/media-source/media-managedmse-memorypressure-inactive.html [ Timeout ]
media/media-source/media-managedmse-eviction.html [ Timeout ]

# No MSE in a worker on glib platforms for now (requires GPU process).
media/media-source/worker/media-managedmse-worker.html [ Timeout ]

webkit.org/b/211995 fast/images/animated-image-mp4.html [ Failure Timeout ]

webkit.org/b/214038 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/track/track-element/track-cues-cuechange.html [ Missing Failure ]
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/Modules/mediasource/MediaSourceHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ bool MediaSourceHandle::isManaged() const
return m_private->m_isManaged;
}

void MediaSourceHandle::ensureOnDispatcher(MediaSourceHandle::TaskType&& task) const
void MediaSourceHandle::ensureOnDispatcher(MediaSourceHandle::TaskType&& task, bool forceRun) const
{
m_private->dispatch(WTFMove(task));
m_private->dispatch(WTFMove(task), forceRun);
}

Ref<DetachedMediaSourceHandle> MediaSourceHandle::detach()
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/mediasource/MediaSourceHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class MediaSourceHandle
bool isManaged() const;

using TaskType = Function<void(MediaSource&)>;
void ensureOnDispatcher(TaskType&&) const;
void ensureOnDispatcher(TaskType&&, bool forceRun = false) const;

RefPtr<MediaSourcePrivateClient> mediaSourcePrivateClient() const;
RefPtr<MediaSourcePrivate> mediaSourcePrivate() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ bool MediaSourceInterfaceWorker::attachToElement(WeakPtr<HTMLMediaElement>&& ele
if (m_handle->hasEverBeenAssignedAsSrcObject())
return false;
m_handle->setHasEverBeenAssignedAsSrcObject();
bool forceRun = true;
m_handle->ensureOnDispatcher([element = WTFMove(element)](MediaSource& mediaSource) mutable {
mediaSource.attachToElement(WTFMove(element));
});
}, forceRun);
return true;
}

Expand Down

0 comments on commit 321003e

Please sign in to comment.