Skip to content

Commit

Permalink
Cherry-pick c0a2b30. rdar://124079735
Browse files Browse the repository at this point in the history
    <audio> and <video> loadeddata events not fired on page load
    https://bugs.webkit.org/show_bug.cgi?id=270837
    rdar://124079735

    Reviewed by Eric Carlson.

    The HTMLMediaElement would call MediaPlayer::prepareToPlay() on the first MediaPlayerPrivate
    created which may not be the one we end up using.
    The code assumed that as soon as a MediaPlayer was created, we could call prepareToPlay on
    it which in the case of the MediaPlayerPrivateAVFobjC would start loading the content.
    Since we enabled the WebM player, the assumption no longer applied, multiple players could
    be used until we find one that can play the content.
    If the GPU process was enabled, the behaviour was racy as the GPUP's MediaPlayer
    may not have been created yet.

    The site would set a HTMLMediaElement's source to a mp3 file, without using an explicit
    extension nor having the server provide the mime-type. As such, we have to try in
    succession all MediaPlayerPrivate until we can find one that can load the content.
    We cache the call to prepareToPlay() and re-issue it on all new MediaPlayerPrivate once
    created.

    Added test.

    * LayoutTests/http/tests/media/audio-load-loadeddata-expected.txt: Added.
    * LayoutTests/http/tests/media/audio-load-loadeddata.html: Added.
    * LayoutTests/platform/ios/TestExpectations: All media tests are disabled on iOS, force this one to run.
    * Source/WebCore/platform/graphics/MediaPlayer.cpp:
    (WebCore::MediaPlayer::loadWithNextMediaEngine):
    (WebCore::MediaPlayer::prepareToPlay):
    * Source/WebCore/platform/graphics/MediaPlayer.h:
    * Source/WebCore/platform/graphics/MediaPlayerPrivate.h:
    (WebCore::MediaPlayerPrivateInterface::prepareForPlayback):
    * Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.cpp:
    (WebKit::RemoteMediaPlayerProxy::prepareForPlayback):
    * Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.h:
    * Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.messages.in:
    * Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.cpp:
    (WebKit::MediaPlayerPrivateRemote::prepareForPlayback):
    * Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.h:

    Canonical link: https://commits.webkit.org/275997@main

Canonical link: https://commits.webkit.org/272448.891@safari-7618-branch
  • Loading branch information
jyavenard authored and Dan Robson committed Apr 9, 2024
1 parent 5f1654c commit 2d5d49a
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

RUN(video.muted = true)
RUN(video.src = '/media/resources/load-video.py?type=audio/mpeg&name=sound_5.mp3')
RUN(video.load())
EVENT(loadeddata)
END OF TEST

23 changes: 23 additions & 0 deletions LayoutTests/http/tests/media/audio-load-loadeddata.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>audio-load-loadeddata</title>
<script src=../../media-resources/video-test.js></script>

<script>
function runTest()
{
video = document.getElementsByTagName('audio')[0];
waitFor(video, 'loadeddata').then(() => endTest());
run("video.muted = true");
run(`video.src = '/media/resources/load-video.py?type=audio/mpeg&name=sound_5.mp3'`);
run("video.load()");
}
</script>
</head>

<body onload="runTest()">
<audio controls muted></audio>
</body>
</html>

1 change: 1 addition & 0 deletions LayoutTests/platform/ios/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ imported/w3c/web-platform-tests/pointerlock [ Skip ]
http/tests/media
imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements
http/tests/cache/disk-cache/disk-cache-media-small.html
http/tests/media/audio-load-loadeddata.html [ Pass ]

# No touch events
fast/events/touch [ Skip ]
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/platform/graphics/MediaPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ void MediaPlayer::loadWithNextMediaEngine(const MediaPlayerFactory* current)
if (m_shouldContinueAfterKeyNeeded)
m_private->setShouldContinueAfterKeyNeeded(m_shouldContinueAfterKeyNeeded);
#endif
m_private->prepareForPlayback(m_privateBrowsing, m_preload, m_preservesPitch, m_shouldPrepareToRender);
m_private->prepareForPlayback(m_privateBrowsing, m_preload, m_preservesPitch, m_shouldPrepareToPlay, m_shouldPrepareToRender);
}
}

Expand Down Expand Up @@ -705,6 +705,7 @@ void MediaPlayer::prepareToPlay()
{
Ref<MediaPlayer> protectedThis(*this);

m_shouldPrepareToPlay = true;
m_private->prepareToPlay();
}

Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/platform/graphics/MediaPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ class WEBCORE_EXPORT MediaPlayer : public MediaPlayerEnums, public ThreadSafeRef
bool m_muted { false };
bool m_preservesPitch { true };
bool m_privateBrowsing { false };
bool m_shouldPrepareToPlay { false };
bool m_shouldPrepareToRender { false };
bool m_contentMIMETypeWasInferredFromExtension { false };
bool m_initializingMediaEngine { false };
Expand Down
6 changes: 4 additions & 2 deletions Source/WebCore/platform/graphics/MediaPlayerPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ class MediaPlayerPrivateInterface {
#endif
virtual void cancelLoad() = 0;

virtual void prepareForPlayback(bool privateMode, MediaPlayer::Preload preload, bool preservesPitch, bool prepare)
virtual void prepareForPlayback(bool privateMode, MediaPlayer::Preload preload, bool preservesPitch, bool prepareToPlay, bool prepareToRender)
{
setPrivateBrowsingMode(privateMode);
setPreload(preload);
setPreservesPitch(preservesPitch);
if (prepare)
if (prepareToPlay)
this->prepareToPlay();
if (prepareToRender)
prepareForRendering();
}

Expand Down
4 changes: 3 additions & 1 deletion Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,14 +197,16 @@ void RemoteMediaPlayerProxy::cancelLoad()
m_player->cancelLoad();
}

void RemoteMediaPlayerProxy::prepareForPlayback(bool privateMode, WebCore::MediaPlayerEnums::Preload preload, bool preservesPitch, WebCore::MediaPlayerEnums::PitchCorrectionAlgorithm pitchCorrectionAlgorithm, bool prepareForRendering, WebCore::IntSize presentationSize, float videoContentScale, WebCore::DynamicRangeMode preferredDynamicRangeMode)
void RemoteMediaPlayerProxy::prepareForPlayback(bool privateMode, WebCore::MediaPlayerEnums::Preload preload, bool preservesPitch, WebCore::MediaPlayerEnums::PitchCorrectionAlgorithm pitchCorrectionAlgorithm, bool prepareToPlay, bool prepareForRendering, WebCore::IntSize presentationSize, float videoContentScale, WebCore::DynamicRangeMode preferredDynamicRangeMode)
{
m_player->setPrivateBrowsingMode(privateMode);
m_player->setPreload(preload);
m_player->setPreservesPitch(preservesPitch);
m_player->setPitchCorrectionAlgorithm(pitchCorrectionAlgorithm);
m_player->setPreferredDynamicRangeMode(preferredDynamicRangeMode);
m_player->setPresentationSize(presentationSize);
if (prepareToPlay)
m_player->prepareToPlay();
if (prepareForRendering)
m_player->prepareForRendering();
m_videoContentScale = videoContentScale;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class RemoteMediaPlayerProxy final

void getConfiguration(RemoteMediaPlayerConfiguration&);

void prepareForPlayback(bool privateMode, WebCore::MediaPlayerEnums::Preload, bool preservesPitch, WebCore::MediaPlayerEnums::PitchCorrectionAlgorithm, bool prepareForRendering, WebCore::IntSize presentationSize, float videoContentScale, WebCore::DynamicRangeMode);
void prepareForPlayback(bool privateMode, WebCore::MediaPlayerEnums::Preload, bool preservesPitch, WebCore::MediaPlayerEnums::PitchCorrectionAlgorithm, bool prepareToPlay, bool prepareForRendering, WebCore::IntSize presentationSize, float videoContentScale, WebCore::DynamicRangeMode);
void prepareForRendering();

void load(URL&&, std::optional<SandboxExtension::Handle>&&, const WebCore::ContentType&, const String&, bool, CompletionHandler<void(RemoteMediaPlayerConfiguration&&)>&&);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#if ENABLE(GPU_PROCESS) && ENABLE(VIDEO)

messages -> RemoteMediaPlayerProxy {
PrepareForPlayback(bool privateMode, enum:uint8_t WebCore::MediaPlayerEnums::Preload preload, bool preservesPitch, WebCore::MediaPlayerEnums::PitchCorrectionAlgorithm pitchCorrectionAlgorithm, bool prepareForRendering, WebCore::IntSize presentationSize, float videoContentScale, enum:uint8_t WebCore::DynamicRangeMode mode)
PrepareForPlayback(bool privateMode, enum:uint8_t WebCore::MediaPlayerEnums::Preload preload, bool preservesPitch, WebCore::MediaPlayerEnums::PitchCorrectionAlgorithm pitchCorrectionAlgorithm, bool prepareToPlay, bool prepareForRendering, WebCore::IntSize presentationSize, float videoContentScale, enum:uint8_t WebCore::DynamicRangeMode mode)

Load(URL url, std::optional<WebKit::SandboxExtension::Handle> sandboxExtension, WebCore::ContentType contentType, String keySystem, bool requiresRemotePlayback) -> (struct WebKit::RemoteMediaPlayerConfiguration playerConfiguration)
#if ENABLE(MEDIA_SOURCE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ MediaPlayerPrivateRemote::~MediaPlayerPrivateRemote()
request({ });
}

void MediaPlayerPrivateRemote::prepareForPlayback(bool privateMode, MediaPlayer::Preload preload, bool preservesPitch, bool prepare)
void MediaPlayerPrivateRemote::prepareForPlayback(bool privateMode, MediaPlayer::Preload preload, bool preservesPitch, bool prepareToPlay, bool prepareToRender)
{
auto player = m_player.get();
if (!player)
Expand All @@ -158,7 +158,7 @@ void MediaPlayerPrivateRemote::prepareForPlayback(bool privateMode, MediaPlayer:
auto presentationSize = player->presentationSize();
auto pitchCorrectionAlgorithm = player->pitchCorrectionAlgorithm();

connection().send(Messages::RemoteMediaPlayerProxy::PrepareForPlayback(privateMode, preload, preservesPitch, pitchCorrectionAlgorithm, prepare, presentationSize, scale, preferredDynamicRangeMode), m_id);
connection().send(Messages::RemoteMediaPlayerProxy::PrepareForPlayback(privateMode, preload, preservesPitch, pitchCorrectionAlgorithm, prepareToPlay, prepareToRender, presentationSize, scale, preferredDynamicRangeMode), m_id);
}

void MediaPlayerPrivateRemote::load(const URL& url, const ContentType& contentType, const String& keySystem)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ class MediaPlayerPrivateRemote final
#endif

void load(const URL&, const WebCore::ContentType&, const String&) final;
void prepareForPlayback(bool privateMode, WebCore::MediaPlayer::Preload, bool preservesPitch, bool prepare) final;
void prepareForPlayback(bool privateMode, WebCore::MediaPlayer::Preload, bool preservesPitch, bool prepareToPlay, bool prepareToRender) final;

#if ENABLE(MEDIA_SOURCE)
void load(const URL&, const WebCore::ContentType&, WebCore::MediaSourcePrivateClient&) final;
Expand Down

0 comments on commit 2d5d49a

Please sign in to comment.