Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[visionOS] Changing video.src while in video fullscreen results in black video #28394

Conversation

jernoble
Copy link
Contributor

@jernoble jernoble commented May 10, 2024

159e1c8

[visionOS] Changing video.src while in video fullscreen results in black video
https://bugs.webkit.org/show_bug.cgi?id=274002
rdar://125926759

Reviewed by Andy Estes.

A FigVideoTarget can only be used with one renderer at a time, and once a target has been created from an XPC
endpoint, it cannot be re-used to create another FigVideoTarget. The combination of these requirements means
that once a FigVideoTarget has been created for a given HTMLMediaElement, it must be cached and re-used for
subsequent MediaPlayers created by that HTMLMediaElement.

To allow the WebCore/platform layer to identify the owner of a MediaPlayer (typically a HTMLMediaElement, but
in WebKit this will be a RemoteMediaPlayerProxy), add a new MediaPlayerClientIdentifier and make the existing
HTMLMediaElementIdentifier an alias for that new identifier.

Add a utility class/namespace to convert XPC endpoints to a FigVideoTarget, and add a new PlatformVideoTarget
type to wrap FigVideoTarget.

Add methods to MediaPlayer to allow MediaPlayerPrivates to query for an existing PlatformVideoTarget. Rename
MediaPlayer setVideoEndpoint() methods to setVideoTarget().

Add a cache of PlatformVideoTargets (and endpoints, and MediaPlayerIdentifiers) in RemoteMediaPlayerManagerProxy.
Having the cache exist on this object means that it will automatically be cleared when the associated WebContent
process exits.

Add new messaging from the UIProcess to explicitly clear cached PlatformVideoTargets when the video interface
in the UIProcess is closed.

* Source/WebCore/Headers.cmake:
* Source/WebCore/SourcesCocoa.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/html/HTMLMediaElement.h:
* Source/WebCore/html/HTMLMediaElementIdentifier.h:
* Source/WebCore/platform/VideoReceiverEndpoint.h:
* Source/WebCore/platform/graphics/MediaPlayer.h:
(WebCore::MediaPlayerClient::mediaPlayerVideoTarget const):
(WebCore::MediaPlayerClient::mediaPlayerClientIdentifier const):
* Source/WebCore/platform/graphics/MediaPlayerClientIdentifier.h: Copied from Source/WebCore/html/HTMLMediaElementIdentifier.h.
* Source/WebCore/platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::setVideoTarget):
(WebCore::MediaPlayerPrivateInterface::setVideoReceiverEndpoint): Deleted.
* Source/WebCore/platform/graphics/VideoTarget.h: Copied from Source/WebCore/platform/VideoReceiverEndpoint.h.
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC):
(WebCore::MediaPlayerPrivateAVFoundationObjC::cancelLoad):
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoTarget):
(WebCore::MediaPlayerPrivateAVFoundationObjC::isInFullscreenOrPictureInPictureChanged):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoReceiverEndpoint): Deleted.
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::MediaPlayerPrivateMediaSourceAVFObjC):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::destroyVideoRenderer):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setVideoTarget):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setVideoReceiverEndpoint): Deleted.
* Source/WebCore/platform/graphics/cocoa/MediaPlayerCocoa.mm:
(WebCore::MediaPlayer::setVideoTarget):
(WebCore::MediaPlayer::setVideoReceiverEndpoint): Deleted.
* Source/WebCore/platform/graphics/cocoa/VideoTargetFactory.h: Copied from Source/WebCore/platform/VideoReceiverEndpoint.h.
* Source/WebCore/platform/graphics/cocoa/VideoTargetFactory.mm: Copied from Source/WebCore/platform/VideoReceiverEndpoint.h.
(WebCore::VideoTargetFactory::createTargetFromEndpoint):
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp:
(WebKit::RemoteMediaPlayerManagerProxy::createMediaPlayer):
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.h:
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.messages.in:
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.cpp:
(WebKit::RemoteMediaPlayerProxy::create):
(WebKit::RemoteMediaPlayerProxy::RemoteMediaPlayerProxy):
(WebKit::RemoteMediaPlayerProxy::mediaPlayerVideoTarget const):
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.h:
* Source/WebKit/GPUProcess/media/cocoa/RemoteMediaPlayerManagerProxyCocoa.mm: Added.
(WebKit::RemoteMediaPlayerManagerProxy::videoTargetForMediaElementIdentifier):
(WebKit::RemoteMediaPlayerManagerProxy::handleVideoReceiverEndpointMessage):
* Source/WebKit/Platform/ios/VideoReceiverEndpointMessage.h:
(WebKit::VideoReceiverEndpointMessage::mediaElementIdentifier const):
* Source/WebKit/Platform/ios/VideoReceiverEndpointMessage.mm:
(WebKit::VideoReceiverEndpointMessage::VideoReceiverEndpointMessage):
(WebKit::VideoReceiverEndpointMessage::decode):
(WebKit::VideoReceiverEndpointMessage::encode const):
* Source/WebKit/Scripts/webkit/messages.py:
(serialized_identifiers):
* Source/WebKit/Shared/EntryPointUtilities/Cocoa/XPCService/XPCEndpointMessages.mm:
(WebKit::handleVideoReceiverEndpointMessage):
* Source/WebKit/Shared/WTFArgumentCoders.serialization.in:
* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
* Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:
(WebKit::PlaybackSessionModelContext::~PlaybackSessionModelContext):
(WebKit::PlaybackSessionModelContext::setVideoReceiverEndpoint):
(WebKit::PlaybackSessionManagerProxy::setVideoReceiverEndpoint):
(WebKit::PlaybackSessionManagerProxy::uncacheVideoReceiverEndpoint):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Source/WebKit/WebProcess/GPU/media/RemoteMediaPlayerManager.cpp:
(WebKit::RemoteMediaPlayerManager::createRemoteMediaPlayer):

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

b2c885f

Misc iOS, tvOS & watchOS macOS Linux Windows
❌ πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ§ͺ api-wpe
βœ… πŸ§ͺ webkitpy ❌ πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 ⏳ πŸ›  wpe-skia
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ›  gtk
βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress βœ… πŸ§ͺ api-gtk
βœ… πŸ›  πŸ§ͺ merge βœ… πŸ›  watch
βœ… πŸ›  watch-sim

@jernoble jernoble self-assigned this May 10, 2024
@jernoble jernoble added the Media Bugs related to the HTML 5 Media elements. label May 10, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 10, 2024
@jernoble jernoble removed the merging-blocked Applied to prevent a change from being merged label May 10, 2024
@jernoble jernoble force-pushed the eng/visionOS-Changing-video-src-while-in-video-fullscreen-results-in-black-video branch from 62e72d3 to 696c9d8 Compare May 10, 2024 17:19
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 10, 2024
@jernoble jernoble removed the merging-blocked Applied to prevent a change from being merged label May 10, 2024
@jernoble jernoble force-pushed the eng/visionOS-Changing-video-src-while-in-video-fullscreen-results-in-black-video branch from 696c9d8 to 415dbd7 Compare May 10, 2024 18:36
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 10, 2024
@jernoble jernoble requested a review from a team May 10, 2024 19:00
@jernoble jernoble removed the merging-blocked Applied to prevent a change from being merged label May 10, 2024
@jernoble jernoble force-pushed the eng/visionOS-Changing-video-src-while-in-video-fullscreen-results-in-black-video branch from 415dbd7 to 951e03e Compare May 10, 2024 19:00
@jernoble jernoble force-pushed the eng/visionOS-Changing-video-src-while-in-video-fullscreen-results-in-black-video branch from 951e03e to 8a20ec3 Compare May 10, 2024 19:17

#if ENABLE(LINEAR_MEDIA_PLAYER)

#include <pal/cocoa/MediaToolboxSoftLink.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/include/import/


#include "VideoReceiverEndpointMessage.h"
#include <WebCore/MediaPlayerPrivate.h>
#include <WebCore/VideoTargetFactory.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/include/import/

return;
}

// An cached entry implies a MediaPlayer has already been given this endpoint.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: "An cached"


// If nothing has actually changed, bail.
if (cachedPlayerIdentifier == endpointMessage.playerIdentifier()
&& cachedEndpoint.get() == endpointMessage.endpoint().get())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check seems harmless, but I don't think it's possible for cachedEndpoint to ever equal endpointMessage.endpoint() since there will be a new instance of an xpc_object_t each time endpointMessage is deserialized.

&& cachedEndpoint.get() == endpointMessage.endpoint().get())
return;

RefPtr cachedPlayer = this->mediaPlayer(cachedPlayerIdentifier);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: no need for this->

cachedPlayer->setVideoTarget(nullptr);
}

// Then set the new endpoint, which may have changed, on the specified MediaPlayer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Then set the new target, which may have changed, ...

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 10, 2024
@jernoble jernoble removed the merging-blocked Applied to prevent a change from being merged label May 10, 2024
@jernoble jernoble force-pushed the eng/visionOS-Changing-video-src-while-in-video-fullscreen-results-in-black-video branch from 8a20ec3 to ba8d535 Compare May 10, 2024 20:18
@jernoble jernoble force-pushed the eng/visionOS-Changing-video-src-while-in-video-fullscreen-results-in-black-video branch from ba8d535 to 87ef343 Compare May 10, 2024 23:10
@jernoble jernoble added merge-queue Applied to send a pull request to merge-queue and removed merge-queue Applied to send a pull request to merge-queue labels May 13, 2024
@jernoble jernoble force-pushed the eng/visionOS-Changing-video-src-while-in-video-fullscreen-results-in-black-video branch from 87ef343 to b2c885f Compare May 13, 2024 15:37
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 13, 2024
@jernoble jernoble added merge-queue Applied to send a pull request to merge-queue and removed merging-blocked Applied to prevent a change from being merged labels May 13, 2024
…ack video

https://bugs.webkit.org/show_bug.cgi?id=274002
rdar://125926759

Reviewed by Andy Estes.

A FigVideoTarget can only be used with one renderer at a time, and once a target has been created from an XPC
endpoint, it cannot be re-used to create another FigVideoTarget. The combination of these requirements means
that once a FigVideoTarget has been created for a given HTMLMediaElement, it must be cached and re-used for
subsequent MediaPlayers created by that HTMLMediaElement.

To allow the WebCore/platform layer to identify the owner of a MediaPlayer (typically a HTMLMediaElement, but
in WebKit this will be a RemoteMediaPlayerProxy), add a new MediaPlayerClientIdentifier and make the existing
HTMLMediaElementIdentifier an alias for that new identifier.

Add a utility class/namespace to convert XPC endpoints to a FigVideoTarget, and add a new PlatformVideoTarget
type to wrap FigVideoTarget.

Add methods to MediaPlayer to allow MediaPlayerPrivates to query for an existing PlatformVideoTarget. Rename
MediaPlayer setVideoEndpoint() methods to setVideoTarget().

Add a cache of PlatformVideoTargets (and endpoints, and MediaPlayerIdentifiers) in RemoteMediaPlayerManagerProxy.
Having the cache exist on this object means that it will automatically be cleared when the associated WebContent
process exits.

Add new messaging from the UIProcess to explicitly clear cached PlatformVideoTargets when the video interface
in the UIProcess is closed.

* Source/WebCore/Headers.cmake:
* Source/WebCore/SourcesCocoa.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/html/HTMLMediaElement.h:
* Source/WebCore/html/HTMLMediaElementIdentifier.h:
* Source/WebCore/platform/VideoReceiverEndpoint.h:
* Source/WebCore/platform/graphics/MediaPlayer.h:
(WebCore::MediaPlayerClient::mediaPlayerVideoTarget const):
(WebCore::MediaPlayerClient::mediaPlayerClientIdentifier const):
* Source/WebCore/platform/graphics/MediaPlayerClientIdentifier.h: Copied from Source/WebCore/html/HTMLMediaElementIdentifier.h.
* Source/WebCore/platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::setVideoTarget):
(WebCore::MediaPlayerPrivateInterface::setVideoReceiverEndpoint): Deleted.
* Source/WebCore/platform/graphics/VideoTarget.h: Copied from Source/WebCore/platform/VideoReceiverEndpoint.h.
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC):
(WebCore::MediaPlayerPrivateAVFoundationObjC::cancelLoad):
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoTarget):
(WebCore::MediaPlayerPrivateAVFoundationObjC::isInFullscreenOrPictureInPictureChanged):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoReceiverEndpoint): Deleted.
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::MediaPlayerPrivateMediaSourceAVFObjC):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::destroyVideoRenderer):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setVideoTarget):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setVideoReceiverEndpoint): Deleted.
* Source/WebCore/platform/graphics/cocoa/MediaPlayerCocoa.mm:
(WebCore::MediaPlayer::setVideoTarget):
(WebCore::MediaPlayer::setVideoReceiverEndpoint): Deleted.
* Source/WebCore/platform/graphics/cocoa/VideoTargetFactory.h: Copied from Source/WebCore/platform/VideoReceiverEndpoint.h.
* Source/WebCore/platform/graphics/cocoa/VideoTargetFactory.mm: Copied from Source/WebCore/platform/VideoReceiverEndpoint.h.
(WebCore::VideoTargetFactory::createTargetFromEndpoint):
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp:
(WebKit::RemoteMediaPlayerManagerProxy::createMediaPlayer):
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.h:
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.messages.in:
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.cpp:
(WebKit::RemoteMediaPlayerProxy::create):
(WebKit::RemoteMediaPlayerProxy::RemoteMediaPlayerProxy):
(WebKit::RemoteMediaPlayerProxy::mediaPlayerVideoTarget const):
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.h:
* Source/WebKit/GPUProcess/media/cocoa/RemoteMediaPlayerManagerProxyCocoa.mm: Added.
(WebKit::RemoteMediaPlayerManagerProxy::videoTargetForMediaElementIdentifier):
(WebKit::RemoteMediaPlayerManagerProxy::handleVideoReceiverEndpointMessage):
* Source/WebKit/Platform/ios/VideoReceiverEndpointMessage.h:
(WebKit::VideoReceiverEndpointMessage::mediaElementIdentifier const):
* Source/WebKit/Platform/ios/VideoReceiverEndpointMessage.mm:
(WebKit::VideoReceiverEndpointMessage::VideoReceiverEndpointMessage):
(WebKit::VideoReceiverEndpointMessage::decode):
(WebKit::VideoReceiverEndpointMessage::encode const):
* Source/WebKit/Scripts/webkit/messages.py:
(serialized_identifiers):
* Source/WebKit/Shared/EntryPointUtilities/Cocoa/XPCService/XPCEndpointMessages.mm:
(WebKit::handleVideoReceiverEndpointMessage):
* Source/WebKit/Shared/WTFArgumentCoders.serialization.in:
* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
* Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:
(WebKit::PlaybackSessionModelContext::~PlaybackSessionModelContext):
(WebKit::PlaybackSessionModelContext::setVideoReceiverEndpoint):
(WebKit::PlaybackSessionManagerProxy::setVideoReceiverEndpoint):
(WebKit::PlaybackSessionManagerProxy::uncacheVideoReceiverEndpoint):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Source/WebKit/WebProcess/GPU/media/RemoteMediaPlayerManager.cpp:
(WebKit::RemoteMediaPlayerManager::createRemoteMediaPlayer):

Canonical link: https://commits.webkit.org/278712@main
@webkit-commit-queue webkit-commit-queue force-pushed the eng/visionOS-Changing-video-src-while-in-video-fullscreen-results-in-black-video branch from b2c885f to 159e1c8 Compare May 13, 2024 21:23
@webkit-commit-queue
Copy link
Collaborator

Committed 278712@main (159e1c8): https://commits.webkit.org/278712@main

Reviewed commits have been landed. Closing PR #28394 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 159e1c8 into WebKit:main May 13, 2024
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Media Bugs related to the HTML 5 Media elements.
Projects
None yet
5 participants