diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/html/HTMLMediaElement.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/html/HTMLMediaElement.h')
-rw-r--r-- | Source/WebCore/html/HTMLMediaElement.h | 1080 |
1 files changed, 648 insertions, 432 deletions
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h index 07faa23cc..d8f5bb1bd 100644 --- a/Source/WebCore/html/HTMLMediaElement.h +++ b/Source/WebCore/html/HTMLMediaElement.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2007-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -23,23 +23,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HTMLMediaElement_h -#define HTMLMediaElement_h +#pragma once #if ENABLE(VIDEO) -#include "HTMLElement.h" + #include "ActiveDOMObject.h" #include "GenericEventQueue.h" -#include "HTMLMediaSession.h" +#include "GenericTaskQueue.h" +#include "HTMLElement.h" +#include "HTMLMediaElementEnums.h" #include "MediaCanStartListener.h" #include "MediaControllerInterface.h" -#include "MediaPlayer.h" - -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) -#include "HTMLFrameOwnerElement.h" -#include "HTMLPlugInImageElement.h" -#include "MediaPlayerProxy.h" -#endif +#include "MediaElementSession.h" +#include "MediaProducer.h" +#include "UserInterfaceLayoutDirection.h" #if ENABLE(VIDEO_TRACK) #include "AudioTrack.h" @@ -47,162 +44,205 @@ #include "PODIntervalTree.h" #include "TextTrack.h" #include "TextTrackCue.h" +#include "VTTCue.h" #include "VideoTrack.h" #endif -#if ENABLE(MEDIA_STREAM) -#include "MediaStream.h" +#ifndef NDEBUG +#include <wtf/StringPrintStream.h> #endif - namespace WebCore { -#if ENABLE(WEB_AUDIO) class AudioSourceProvider; -class MediaElementAudioSourceNode; -#endif +class AudioTrackList; +class AudioTrackPrivate; +class Blob; +class DOMError; +class DeferredPromise; +class DisplaySleepDisabler; class Event; class HTMLSourceElement; class HTMLTrackElement; -class URL; +class InbandTextTrackPrivate; class MediaController; class MediaControls; class MediaControlsHost; +class MediaElementAudioSourceNode; class MediaError; -class PageActivityAssertionToken; -class TimeRanges; -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) -class Widget; -#endif -#if PLATFORM(MAC) -class DisplaySleepDisabler; -#endif -#if ENABLE(ENCRYPTED_MEDIA_V2) class MediaKeys; -#endif -#if ENABLE(MEDIA_SOURCE) -class VideoPlaybackQuality; -#endif - -#if ENABLE(VIDEO_TRACK) -class AudioTrackList; -class AudioTrackPrivate; -class InbandTextTrackPrivate; +class MediaPlayer; +class MediaSession; +class MediaSource; +class MediaStream; +class RenderMedia; +class ScriptExecutionContext; +class SourceBuffer; class TextTrackList; +class TimeRanges; +class VideoPlaybackQuality; class VideoTrackList; class VideoTrackPrivate; +class WebKitMediaKeys; + +template<typename> class DOMPromise; -typedef PODIntervalTree<double, TextTrackCue*> CueIntervalTree; -typedef CueIntervalTree::IntervalType CueInterval; -typedef Vector<CueInterval> CueList; +#if ENABLE(VIDEO_TRACK) +using CueIntervalTree = PODIntervalTree<MediaTime, TextTrackCue*>; +using CueInterval = CueIntervalTree::IntervalType; +using CueList = Vector<CueInterval>; #endif +using MediaProvider = std::optional<Variant< +#if ENABLE(MEDIA_STREAM) + RefPtr<MediaStream>, +#endif +#if ENABLE(MEDIA_SOURCE) + RefPtr<MediaSource>, +#endif + RefPtr<Blob>>>; + class HTMLMediaElement -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) - : public HTMLFrameOwnerElement -#else : public HTMLElement -#endif - , private MediaPlayerClient, public MediaPlayerSupportsTypeClient, private MediaCanStartListener, public ActiveDOMObject, public MediaControllerInterface , public MediaSessionClient + , public ActiveDOMObject + , public MediaControllerInterface + , public MediaPlayerSupportsTypeClient + , public PlatformMediaSessionClient + , private MediaCanStartListener + , private MediaPlayerClient + , private MediaProducer #if ENABLE(VIDEO_TRACK) , private AudioTrackClient , private TextTrackClient , private VideoTrackClient #endif -#if USE(PLATFORM_TEXT_TRACK_MENU) - , public PlatformTextTrackMenuClient -#endif { public: MediaPlayer* player() const { return m_player.get(); } virtual bool isVideo() const { return false; } - virtual bool hasVideo() const override { return false; } - virtual bool hasAudio() const override; + bool hasVideo() const override { return false; } + bool hasAudio() const override; + + static HashSet<HTMLMediaElement*>& allMediaElements(); + + static HTMLMediaElement* bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose); void rewind(double timeDelta); - virtual void returnToRealtime() override; + WEBCORE_EXPORT void returnToRealtime() override; // Eventually overloaded in HTMLVideoElement - virtual bool supportsFullscreen() const override { return false; }; + bool supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) const override { return false; }; - virtual bool supportsSave() const; - virtual bool supportsScanning() const override; - - PlatformMedia platformMedia() const; -#if USE(ACCELERATED_COMPOSITING) + bool supportsScanning() const override; + + bool canSaveMediaData() const; + + bool doesHaveAttribute(const AtomicString&, AtomicString* value = nullptr) const override; + + WEBCORE_EXPORT PlatformMedia platformMedia() const; PlatformLayer* platformLayer() const; -#if PLATFORM(IOS) - PlatformLayer* borrowPlatformLayer(); - void returnPlatformLayer(PlatformLayer*); -#endif + bool isVideoLayerInline(); + void setPreparedToReturnVideoLayerToInline(bool); + void waitForPreparedForInlineThen(std::function<void()> completionHandler = [] { }); +#if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) + void setVideoFullscreenLayer(PlatformLayer*, std::function<void()> completionHandler = [] { }); + PlatformLayer* videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); } + void setVideoFullscreenFrame(FloatRect); + void setVideoFullscreenGravity(MediaPlayerEnums::VideoGravity); + MediaPlayerEnums::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; } #endif - enum DelayedActionType { - LoadMediaResource = 1 << 0, - ConfigureTextTracks = 1 << 1, - TextTrackChangesNotification = 1 << 2, - ConfigureTextTrackDisplay = 1 << 3, - }; + using HTMLMediaElementEnums::DelayedActionType; void scheduleDelayedAction(DelayedActionType); + void scheduleResolvePendingPlayPromises(); + void rejectPendingPlayPromises(DOMError&); + void resolvePendingPlayPromises(); + void scheduleNotifyAboutPlaying(); + void notifyAboutPlaying(); - MediaPlayer::MovieLoadType movieLoadType() const; + MediaPlayerEnums::MovieLoadType movieLoadType() const; bool inActiveDocument() const { return m_inActiveDocument; } - + + const Document* hostingDocument() const override { return &document(); } + // DOM API // error state - PassRefPtr<MediaError> error() const; + WEBCORE_EXPORT MediaError* error() const; void setSrc(const String&); const URL& currentSrc() const { return m_currentSrc; } -#if ENABLE(MEDIA_STREAM) - MediaStream* srcObject() const { return m_mediaStreamSrcObject.get(); } - void setSrcObject(MediaStream*); -#endif + const MediaProvider& srcObject() const { return m_mediaProvider; } + void setSrcObject(MediaProvider&&); + + WEBCORE_EXPORT void setCrossOrigin(const AtomicString&); + WEBCORE_EXPORT String crossOrigin() const; // network state - enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE }; - NetworkState networkState() const; + using HTMLMediaElementEnums::NetworkState; + WEBCORE_EXPORT NetworkState networkState() const; - String preload() const; - void setPreload(const String&); + WEBCORE_EXPORT String preload() const; + WEBCORE_EXPORT void setPreload(const String&); - virtual PassRefPtr<TimeRanges> buffered() const override; - void load(); - String canPlayType(const String& mimeType, const String& keySystem = String(), const URL& = URL()) const; + Ref<TimeRanges> buffered() const override; + WEBCORE_EXPORT void load(); + WEBCORE_EXPORT String canPlayType(const String& mimeType) const; // ready state - virtual ReadyState readyState() const override; - bool seeking() const; + using HTMLMediaElementEnums::ReadyState; + ReadyState readyState() const override; + WEBCORE_EXPORT bool seeking() const; // playback state - virtual double currentTime() const override; - virtual void setCurrentTime(double) override; - virtual double duration() const override; - virtual bool paused() const override; - virtual double defaultPlaybackRate() const override; - virtual void setDefaultPlaybackRate(double) override; - virtual double playbackRate() const override; - virtual void setPlaybackRate(double) override; + WEBCORE_EXPORT double currentTime() const override; + void setCurrentTime(double) override; + double currentTimeForBindings() const { return currentTime(); } + WEBCORE_EXPORT ExceptionOr<void> setCurrentTimeForBindings(double); + WEBCORE_EXPORT double getStartDate() const; + WEBCORE_EXPORT double duration() const override; + WEBCORE_EXPORT bool paused() const override; + double defaultPlaybackRate() const override; + void setDefaultPlaybackRate(double) override; + WEBCORE_EXPORT double playbackRate() const override; + void setPlaybackRate(double) override; + +// MediaTime versions of playback state + MediaTime currentMediaTime() const; + void setCurrentTime(const MediaTime&); + MediaTime durationMediaTime() const; + WEBCORE_EXPORT void fastSeek(const MediaTime&); + void updatePlaybackRate(); - bool webkitPreservesPitch() const; - void setWebkitPreservesPitch(bool); - virtual PassRefPtr<TimeRanges> played() override; - virtual PassRefPtr<TimeRanges> seekable() const override; - bool ended() const; + WEBCORE_EXPORT bool webkitPreservesPitch() const; + WEBCORE_EXPORT void setWebkitPreservesPitch(bool); + Ref<TimeRanges> played() override; + Ref<TimeRanges> seekable() const override; + WEBCORE_EXPORT bool ended() const; bool autoplay() const; - bool loop() const; + bool isAutoplaying() const { return m_autoplaying; } + bool loop() const; void setLoop(bool b); - virtual void play() override; - virtual void pause() override; - void fastSeek(double); + + void play(DOMPromise<void>&&); + + WEBCORE_EXPORT void play() override; + WEBCORE_EXPORT void pause() override; + void setShouldBufferData(bool) override; + WEBCORE_EXPORT void fastSeek(double); + double minFastReverseRate() const; + double maxFastForwardRate() const; + + void purgeBufferedDataIfPossible(); // captions - bool webkitHasClosedCaptions() const; - bool webkitClosedCaptionsVisible() const; - void setWebkitClosedCaptionsVisible(bool); + WEBCORE_EXPORT bool webkitHasClosedCaptions() const; + WEBCORE_EXPORT bool webkitClosedCaptionsVisible() const; + WEBCORE_EXPORT void setWebkitClosedCaptionsVisible(bool); + + bool elementIsHidden() const override { return m_elementIsHidden; } #if ENABLE(MEDIA_STATISTICS) // Statistics @@ -212,101 +252,78 @@ public: #if ENABLE(MEDIA_SOURCE) // Media Source. - void closeMediaSource(); + void detachMediaSource(); void incrementDroppedFrameCount() { ++m_droppedVideoFrames; } + size_t maximumSourceBufferSize(const SourceBuffer&) const; #endif -#if ENABLE(ENCRYPTED_MEDIA) - void webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionCode&); - void webkitGenerateKeyRequest(const String& keySystem, ExceptionCode&); - void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionCode&); - void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionCode&); - void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionCode&); +#if ENABLE(LEGACY_ENCRYPTED_MEDIA) + WebKitMediaKeys* webkitKeys() const { return m_webKitMediaKeys.get(); } + void webkitSetMediaKeys(WebKitMediaKeys*); - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyadded); - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyerror); - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeymessage); -#endif -#if ENABLE(ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA_V2) - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitneedkey); + void keyAdded(); #endif -#if ENABLE(ENCRYPTED_MEDIA_V2) - MediaKeys* keys() const { return m_mediaKeys.get(); } - void setMediaKeys(MediaKeys*); +#if ENABLE(ENCRYPTED_MEDIA) + MediaKeys* mediaKeys() const; + + void setMediaKeys(MediaKeys*, Ref<DeferredPromise>&&); #endif // controls - bool controls() const; - void setControls(bool); - virtual double volume() const override; - virtual void setVolume(double, ExceptionCode&) override; - virtual bool muted() const override; - virtual void setMuted(bool) override; - - void togglePlayState(); - virtual void beginScrubbing() override; - virtual void endScrubbing() override; - - virtual bool canPlay() const override; + WEBCORE_EXPORT bool controls() const; + WEBCORE_EXPORT void setControls(bool); + WEBCORE_EXPORT double volume() const override; + ExceptionOr<void> setVolume(double) override; + WEBCORE_EXPORT bool muted() const override; + WEBCORE_EXPORT void setMuted(bool) override; + + WEBCORE_EXPORT void togglePlayState(); + WEBCORE_EXPORT void beginScrubbing() override; + WEBCORE_EXPORT void endScrubbing() override; + + void beginScanning(ScanDirection) override; + void endScanning() override; + double nextScanRate(); + + WEBCORE_EXPORT bool canPlay() const override; double percentLoaded() const; #if ENABLE(VIDEO_TRACK) - PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, const String& language, ExceptionCode&); - PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, ExceptionCode& ec) { return addTextTrack(kind, label, emptyString(), ec); } - PassRefPtr<TextTrack> addTextTrack(const String& kind, ExceptionCode& ec) { return addTextTrack(kind, emptyString(), emptyString(), ec); } + ExceptionOr<TextTrack&> addTextTrack(const String& kind, const String& label, const String& language); - AudioTrackList* audioTracks(); - TextTrackList* textTracks(); - VideoTrackList* videoTracks(); + AudioTrackList& audioTracks(); + TextTrackList& textTracks(); + VideoTrackList& videoTracks(); CueList currentlyActiveCues() const { return m_currentlyActiveCues; } - void addAudioTrack(PassRefPtr<AudioTrack>); - void addTextTrack(PassRefPtr<TextTrack>); - void addVideoTrack(PassRefPtr<VideoTrack>); - void removeAudioTrack(AudioTrack*); - void removeTextTrack(TextTrack*); - void removeVideoTrack(VideoTrack*); - void removeAllInbandTracks(); + void addAudioTrack(Ref<AudioTrack>&&); + void addTextTrack(Ref<TextTrack>&&); + void addVideoTrack(Ref<VideoTrack>&&); + void removeAudioTrack(AudioTrack&); + void removeTextTrack(TextTrack&, bool scheduleEvent = true); + void removeVideoTrack(VideoTrack&); + void forgetResourceSpecificTracks(); void closeCaptionTracksChanged(); void notifyMediaPlayerOfTextTrackChanges(); - virtual void didAddTextTrack(HTMLTrackElement*); - virtual void didRemoveTextTrack(HTMLTrackElement*); + virtual void didAddTextTrack(HTMLTrackElement&); + virtual void didRemoveTextTrack(HTMLTrackElement&); - virtual void mediaPlayerDidAddAudioTrack(PassRefPtr<AudioTrackPrivate>) override; - virtual void mediaPlayerDidAddTextTrack(PassRefPtr<InbandTextTrackPrivate>) override; - virtual void mediaPlayerDidAddVideoTrack(PassRefPtr<VideoTrackPrivate>) override; - virtual void mediaPlayerDidRemoveAudioTrack(PassRefPtr<AudioTrackPrivate>) override; - virtual void mediaPlayerDidRemoveTextTrack(PassRefPtr<InbandTextTrackPrivate>) override; - virtual void mediaPlayerDidRemoveVideoTrack(PassRefPtr<VideoTrackPrivate>) override; + void mediaPlayerDidAddAudioTrack(AudioTrackPrivate&) final; + void mediaPlayerDidAddTextTrack(InbandTextTrackPrivate&) final; + void mediaPlayerDidAddVideoTrack(VideoTrackPrivate&) final; + void mediaPlayerDidRemoveAudioTrack(AudioTrackPrivate&) final; + void mediaPlayerDidRemoveTextTrack(InbandTextTrackPrivate&) final; + void mediaPlayerDidRemoveVideoTrack(VideoTrackPrivate&) final; -#if USE(PLATFORM_TEXT_TRACK_MENU) - virtual void setSelectedTextTrack(PassRefPtr<PlatformTextTrack>) override; - virtual Vector<RefPtr<PlatformTextTrack>> platformTextTracks() override; - PlatformTextTrackMenuInterface* platformTextTrackMenu(); +#if ENABLE(AVF_CAPTIONS) + Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources() final; #endif - struct TrackGroup { - enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other }; - - TrackGroup(GroupKind kind) - : visibleTrack(0) - , defaultTrack(0) - , kind(kind) - , hasSrcLang(false) - { - } - - Vector<RefPtr<TextTrack>> tracks; - RefPtr<TextTrack> visibleTrack; - RefPtr<TextTrack> defaultTrack; - GroupKind kind; - bool hasSrcLang; - }; - + struct TrackGroup; void configureTextTrackGroupForLanguage(const TrackGroup&) const; void configureTextTracks(); void configureTextTrackGroup(const TrackGroup&); @@ -314,49 +331,43 @@ public: void setSelectedTextTrack(TextTrack*); bool textTracksAreReady() const; - enum TextTrackVisibilityCheckType { CheckTextTrackVisibility, AssumeTextTrackVisibilityChanged }; + using HTMLMediaElementEnums::TextTrackVisibilityCheckType; void configureTextTrackDisplay(TextTrackVisibilityCheckType checkType = CheckTextTrackVisibility); void updateTextTrackDisplay(); // AudioTrackClient - virtual void audioTrackEnabledChanged(AudioTrack*) override; + void audioTrackEnabledChanged(AudioTrack&) final; + + void textTrackReadyStateChanged(TextTrack*); // TextTrackClient - virtual void textTrackReadyStateChanged(TextTrack*); - virtual void textTrackKindChanged(TextTrack*) override; - virtual void textTrackModeChanged(TextTrack*) override; - virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) override; - virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) override; - virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) override; - virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) override; + void textTrackKindChanged(TextTrack&) override; + void textTrackModeChanged(TextTrack&) override; + void textTrackAddCues(TextTrack&, const TextTrackCueList&) override; + void textTrackRemoveCues(TextTrack&, const TextTrackCueList&) override; + void textTrackAddCue(TextTrack&, TextTrackCue&) override; + void textTrackRemoveCue(TextTrack&, TextTrackCue&) override; // VideoTrackClient - virtual void videoTrackSelectedChanged(VideoTrack*) override; + void videoTrackSelectedChanged(VideoTrack&) final; bool requiresTextTrackRepresentation() const; void setTextTrackRepresentation(TextTrackRepresentation*); + void syncTextTrackBounds(); #endif -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) - void ensureMediaPlayer(); - void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; } - void deliverNotification(MediaPlayerProxyNotificationType notification); - void setMediaPlayerProxy(WebMediaPlayerProxy* proxy); - void getPluginProxyParams(URL& url, Vector<String>& names, Vector<String>& values); - void createMediaPlayerProxy(); - void updateWidget(PluginCreationOption); -#endif - -#if ENABLE(IOS_AIRPLAY) +#if ENABLE(WIRELESS_PLAYBACK_TARGET) void webkitShowPlaybackTargetPicker(); - bool webkitCurrentPlaybackTargetIsWireless() const; - - virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override; - virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override; - - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitcurrentplaybacktargetiswirelesschanged); - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitplaybacktargetavailabilitychanged); + bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override; + bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override; + + void wirelessRoutesAvailableDidChange() override; + bool canPlayToWirelessPlaybackTarget() const override; + bool isPlayingToWirelessPlaybackTarget() const override; + void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override; + void setShouldPlayToPlaybackTarget(bool) override; #endif + bool webkitCurrentPlaybackTargetIsWireless() const; // EventTarget function. // Both Node (via HTMLElement) and ActiveDOMObject define this method, which @@ -367,31 +378,40 @@ public: bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); } - virtual bool isFullscreen() const override; - void toggleFullscreenState(); - virtual void enterFullscreen() override; - void exitFullscreen(); + WEBCORE_EXPORT bool isFullscreen() const override; + bool isStandardFullscreen() const; + void toggleStandardFullscreenState(); + + using MediaPlayerEnums::VideoFullscreenMode; + VideoFullscreenMode fullscreenMode() const { return m_videoFullscreenMode; } + virtual void fullscreenModeChanged(VideoFullscreenMode); + + void enterFullscreen(VideoFullscreenMode); + void enterFullscreen() override; + WEBCORE_EXPORT void exitFullscreen(); - virtual bool hasClosedCaptions() const override; - virtual bool closedCaptionsVisible() const override; - virtual void setClosedCaptionsVisible(bool) override; + bool hasClosedCaptions() const override; + bool closedCaptionsVisible() const override; + void setClosedCaptionsVisible(bool) override; MediaControls* mediaControls() const; void sourceWasRemoved(HTMLSourceElement*); void sourceWasAdded(HTMLSourceElement*); - virtual void privateBrowsingStateDidChange() override; + void privateBrowsingStateDidChange() override; // Media cache management. - static void getSitesInMediaCache(Vector<String>&); - static void clearMediaCache(); - static void clearMediaCacheForSite(const String&); + WEBCORE_EXPORT static void setMediaCacheDirectory(const String&); + WEBCORE_EXPORT static const String& mediaCacheDirectory(); + WEBCORE_EXPORT static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&); + WEBCORE_EXPORT static void clearMediaCache(const String&, std::chrono::system_clock::time_point modifiedSince = { }); + WEBCORE_EXPORT static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&); static void resetMediaEngines(); bool isPlaying() const { return m_playing; } - virtual bool hasPendingActivity() const override; + bool hasPendingActivity() const override; #if ENABLE(WEB_AUDIO) MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; } @@ -400,53 +420,100 @@ public: AudioSourceProvider* audioSourceProvider(); #endif - enum InvalidURLAction { DoNothing, Complain }; + using HTMLMediaElementEnums::InvalidURLAction; bool isSafeToLoadURL(const URL&, InvalidURLAction); const String& mediaGroup() const; void setMediaGroup(const String&); MediaController* controller() const; - void setController(PassRefPtr<MediaController>); + void setController(RefPtr<MediaController>&&); -#if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override; -#endif + MediaController* controllerForBindings() const { return controller(); } + void setControllerForBindings(MediaController*); void enteredOrExitedFullscreen() { configureMediaControls(); } -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) - bool shouldUseVideoPluginProxy() const; -#endif - unsigned long long fileSize() const; - void mediaLoadingFailed(MediaPlayer::NetworkState); - void mediaLoadingFailedFatally(MediaPlayer::NetworkState); + void mediaLoadingFailed(MediaPlayerEnums::NetworkState); + void mediaLoadingFailedFatally(MediaPlayerEnums::NetworkState); + +#if ENABLE(MEDIA_SESSION) + WEBCORE_EXPORT double playerVolume() const; + + const String& kind() const { return m_kind; } + void setKind(const String& kind) { m_kind = kind; } + + MediaSession* session() const; + void setSession(MediaSession*); + + void setShouldDuck(bool); + + static HTMLMediaElement* elementWithID(uint64_t); + uint64_t elementID() const { return m_elementID; } +#endif #if ENABLE(MEDIA_SOURCE) RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality(); #endif - MediaPlayer::Preload preloadValue() const { return m_preload; } + MediaPlayerEnums::Preload preloadValue() const { return m_preload; } + MediaElementSession& mediaSession() const { return *m_mediaSession; } + +#if ENABLE(MEDIA_CONTROLS_SCRIPT) + void pageScaleFactorChanged(); + void userInterfaceLayoutDirectionChanged(); + WEBCORE_EXPORT String getCurrentMediaControlsStatus(); + + MediaControlsHost* mediaControlsHost() { return m_mediaControlsHost.get(); } +#endif + + bool isDisablingSleep() const { return m_sleepDisabler.get(); } + + double maxBufferedTime() const; + + MediaProducer::MediaStateFlags mediaState() const override; + + void layoutSizeChanged(); + void visibilityDidChange(); + + void allowsMediaDocumentInlinePlaybackChanged(); + void updateShouldPlay(); + + RenderMedia* renderer() const; + + void resetPlaybackSessionState(); + bool isVisibleInViewport() const; + bool hasEverNotifiedAboutPlaying() const; + void setShouldDelayLoadEvent(bool); + + bool hasEverHadAudio() const { return m_hasEverHadAudio; } + bool hasEverHadVideo() const { return m_hasEverHadVideo; } + + double playbackStartedTime() const { return m_playbackStartedTime; } + + bool isTemporarilyAllowingInlinePlaybackAfterFullscreen() const {return m_temporarilyAllowingInlinePlaybackAfterFullscreen; } protected: - HTMLMediaElement(const QualifiedName&, Document&, bool); + HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser); virtual ~HTMLMediaElement(); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void finishParsingChildren() override; - virtual bool isURLAttribute(const Attribute&) const override; - virtual void willAttachRenderers() override; - virtual void didAttachRenderers() override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void finishParsingChildren() override; + bool isURLAttribute(const Attribute&) const override; + void willAttachRenderers() override; + void didAttachRenderers() override; + void willDetachRenderers() override; + void didDetachRenderers() override; - virtual void didMoveToNewDocument(Document* oldDocument) override; + void didMoveToNewDocument(Document& oldDocument) override; enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video }; DisplayMode displayMode() const { return m_displayMode; } virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; } - virtual bool isMediaElement() const override { return true; } + bool isMediaElement() const final { return true; } #if ENABLE(VIDEO_TRACK) bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0 || !m_textTracks || !m_cueTree.size(); } @@ -454,138 +521,172 @@ protected: void endIgnoringTrackDisplayUpdateRequests(); #endif - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; - HTMLMediaSession& mediaSession() const { return *m_mediaSession; } +#if ENABLE(MEDIA_CONTROLS_SCRIPT) + bool mediaControlsDependOnPageScaleFactor() const { return m_mediaControlsDependOnPageScaleFactor; } + void setMediaControlsDependOnPageScaleFactor(bool); + void updateMediaControlsAfterPresentationModeChange(); +#endif + + void scheduleEvent(const AtomicString& eventName); private: void createMediaPlayer(); - virtual bool alwaysCreateUserAgentShadowRoot() const override { return true; } - virtual bool areAuthorShadowsAllowed() const override { return false; } - - virtual bool hasCustomFocusLogic() const override; - virtual bool supportsFocus() const override; - virtual bool isMouseFocusable() const override; - virtual bool rendererIsNeeded(const RenderStyle&) override; - virtual bool childShouldCreateRenderer(const Node&) const override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - virtual void didRecalcStyle(Style::Change) override; - - virtual void defaultEventHandler(Event*) override; - - virtual void didBecomeFullscreenElement() override; - virtual void willStopBeingFullscreenElement() override; - - // ActiveDOMObject functions. - virtual bool canSuspend() const override; - virtual void suspend(ReasonForSuspension) override; - virtual void resume() override; - virtual void stop() override; + bool alwaysCreateUserAgentShadowRoot() const override { return true; } + + bool supportsFocus() const override; + bool isMouseFocusable() const override; + bool rendererIsNeeded(const RenderStyle&) override; + bool childShouldCreateRenderer(const Node&) const override; + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void finishedInsertingSubtree() override; + void removedFrom(ContainerNode&) override; + void didRecalcStyle(Style::Change) override; + + void willBecomeFullscreenElement() override; + void didBecomeFullscreenElement() override; + void willStopBeingFullscreenElement() override; + + // ActiveDOMObject API. + const char* activeDOMObjectName() const override; + bool canSuspendForDocumentSuspension() const override; + void suspend(ReasonForSuspension) override; + void resume() override; + void stop() override; + void stopWithoutDestroyingMediaPlayer(); + void contextDestroyed() override; - virtual void mediaVolumeDidChange() override; + void mediaVolumeDidChange() override; -#if ENABLE(PAGE_VISIBILITY_API) - virtual void visibilityStateChanged() override; -#endif + void visibilityStateChanged() override; virtual void updateDisplayState() { } - void setReadyState(MediaPlayer::ReadyState); - void setNetworkState(MediaPlayer::NetworkState); - - virtual Document* mediaPlayerOwningDocument() override; - virtual void mediaPlayerNetworkStateChanged(MediaPlayer*) override; - virtual void mediaPlayerReadyStateChanged(MediaPlayer*) override; - virtual void mediaPlayerTimeChanged(MediaPlayer*) override; - virtual void mediaPlayerVolumeChanged(MediaPlayer*) override; - virtual void mediaPlayerMuteChanged(MediaPlayer*) override; - virtual void mediaPlayerDurationChanged(MediaPlayer*) override; - virtual void mediaPlayerRateChanged(MediaPlayer*) override; - virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*) override; - virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*) override; - virtual void mediaPlayerResourceNotSupported(MediaPlayer*) override; - virtual void mediaPlayerRepaint(MediaPlayer*) override; - virtual void mediaPlayerSizeChanged(MediaPlayer*) override; -#if USE(ACCELERATED_COMPOSITING) - virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) override; - virtual void mediaPlayerRenderingModeChanged(MediaPlayer*) override; -#endif - virtual void mediaPlayerEngineUpdated(MediaPlayer*) override; + void setReadyState(MediaPlayerEnums::ReadyState); + void setNetworkState(MediaPlayerEnums::NetworkState); + + double effectivePlaybackRate() const; + double requestedPlaybackRate() const; + + void mediaPlayerNetworkStateChanged(MediaPlayer*) override; + void mediaPlayerReadyStateChanged(MediaPlayer*) override; + void mediaPlayerTimeChanged(MediaPlayer*) override; + void mediaPlayerVolumeChanged(MediaPlayer*) override; + void mediaPlayerMuteChanged(MediaPlayer*) override; + void mediaPlayerDurationChanged(MediaPlayer*) override; + void mediaPlayerRateChanged(MediaPlayer*) override; + void mediaPlayerPlaybackStateChanged(MediaPlayer*) override; + void mediaPlayerSawUnsupportedTracks(MediaPlayer*) override; + void mediaPlayerResourceNotSupported(MediaPlayer*) override; + void mediaPlayerRepaint(MediaPlayer*) override; + void mediaPlayerSizeChanged(MediaPlayer*) override; + bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) override; + void mediaPlayerRenderingModeChanged(MediaPlayer*) override; + bool mediaPlayerAcceleratedCompositingEnabled() override; + void mediaPlayerEngineUpdated(MediaPlayer*) override; + void mediaEngineWasUpdated(); + + void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override; + void mediaPlayerCharacteristicChanged(MediaPlayer*) override; + +#if ENABLE(LEGACY_ENCRYPTED_MEDIA) + RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String& keyId) const override; + bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override; + String mediaPlayerMediaKeysStorageDirectory() const override; +#endif - virtual void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override; - virtual void mediaPlayerCharacteristicChanged(MediaPlayer*) override; +#if ENABLE(WIRELESS_PLAYBACK_TARGET) + void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override; + void enqueuePlaybackTargetAvailabilityChangedEvent(); -#if ENABLE(ENCRYPTED_MEDIA) - virtual void mediaPlayerKeyAdded(MediaPlayer*, const String& keySystem, const String& sessionId) override; - virtual void mediaPlayerKeyError(MediaPlayer*, const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode) override; - virtual void mediaPlayerKeyMessage(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const URL& defaultURL) override; - virtual bool mediaPlayerKeyNeeded(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) override; + using EventTarget::dispatchEvent; + bool dispatchEvent(Event&) override; #endif -#if ENABLE(ENCRYPTED_MEDIA_V2) - virtual bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override; +#if ENABLE(MEDIA_SESSION) + void setSessionInternal(MediaSession&); #endif -#if ENABLE(IOS_AIRPLAY) - virtual void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override; - virtual void mediaPlayerPlaybackTargetAvailabilityChanged(MediaPlayer*) override; - void enqueuePlaybackTargetAvailabilityChangedEvent(); + String mediaPlayerReferrer() const override; + String mediaPlayerUserAgent() const override; + + bool mediaPlayerNeedsSiteSpecificHacks() const override; + String mediaPlayerDocumentHost() const override; + + void mediaPlayerEnterFullscreen() override; + void mediaPlayerExitFullscreen() override; + bool mediaPlayerIsFullscreen() const override; + bool mediaPlayerIsFullscreenPermitted() const override; + bool mediaPlayerIsVideo() const override; + LayoutRect mediaPlayerContentBoxRect() const override; + float mediaPlayerContentsScale() const override; + void mediaPlayerSetSize(const IntSize&) override; + void mediaPlayerPause() override; + void mediaPlayerPlay() override; + bool mediaPlayerPlatformVolumeConfigurationRequired() const override; + bool mediaPlayerIsPaused() const override; + bool mediaPlayerIsLooping() const override; + CachedResourceLoader* mediaPlayerCachedResourceLoader() override; + RefPtr<PlatformMediaResourceLoader> mediaPlayerCreateResourceLoader() override; + bool mediaPlayerShouldUsePersistentCache() const override; + const String& mediaPlayerMediaCacheDirectory() const override; + +#if PLATFORM(WIN) && USE(AVFOUNDATION) + GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const override; #endif - virtual String mediaPlayerReferrer() const override; - virtual String mediaPlayerUserAgent() const override; - virtual CORSMode mediaPlayerCORSMode() const override; - - virtual bool mediaPlayerNeedsSiteSpecificHacks() const override; - virtual String mediaPlayerDocumentHost() const override; - - virtual void mediaPlayerEnterFullscreen() override; - virtual void mediaPlayerExitFullscreen() override; - virtual bool mediaPlayerIsFullscreen() const override; - virtual bool mediaPlayerIsFullscreenPermitted() const override; - virtual bool mediaPlayerIsVideo() const override; - virtual LayoutRect mediaPlayerContentBoxRect() const override; - virtual void mediaPlayerSetSize(const IntSize&) override; - virtual void mediaPlayerPause() override; - virtual void mediaPlayerPlay() override; - virtual bool mediaPlayerPlatformVolumeConfigurationRequired() const override; - virtual bool mediaPlayerIsPaused() const override; - virtual bool mediaPlayerIsLooping() const override; - virtual HostWindow* mediaPlayerHostWindow() override; - virtual IntRect mediaPlayerWindowClipRect() override; - virtual CachedResourceLoader* mediaPlayerCachedResourceLoader() override; + void mediaPlayerActiveSourceBuffersChanged(const MediaPlayer*) override; -#if PLATFORM(WIN) && USE(AVFOUNDATION) - virtual GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const override; + bool mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge&) override; + void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command, nullptr); } + String sourceApplicationIdentifier() const override; + String mediaPlayerSourceApplicationIdentifier() const override { return sourceApplicationIdentifier(); } + Vector<String> mediaPlayerPreferredAudioCharacteristics() const override; + +#if PLATFORM(IOS) + String mediaPlayerNetworkInterfaceName() const override; + bool mediaPlayerGetRawCookies(const URL&, Vector<Cookie>&) const override; #endif - virtual bool mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge&) override; + bool mediaPlayerIsInMediaDocument() const final; + void mediaPlayerEngineFailedToLoad() const final; + + double mediaPlayerRequestedPlaybackRate() const final; + VideoFullscreenMode mediaPlayerFullscreenMode() const final { return fullscreenMode(); } + bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep(); } - void loadTimerFired(Timer<HTMLMediaElement>&); - void progressEventTimerFired(Timer<HTMLMediaElement>&); - void playbackProgressTimerFired(Timer<HTMLMediaElement>&); +#if USE(GSTREAMER) + void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) final; +#endif + + void pendingActionTimerFired(); + void progressEventTimerFired(); + void playbackProgressTimerFired(); + void scanTimerFired(); + void seekTask(); void startPlaybackProgressTimer(); void startProgressEventTimer(); void stopPeriodicTimers(); - void seek(double time); - void seekWithTolerance(double time, double negativeTolerance, double positiveTolerance); + void seek(const MediaTime&); + void seekInternal(const MediaTime&); + void seekWithTolerance(const MediaTime&, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance, bool fromDOM); void finishSeek(); - void checkIfSeekNeeded(); - void addPlayedRange(double start, double end); + void clearSeeking(); + void addPlayedRange(const MediaTime& start, const MediaTime& end); void scheduleTimeupdateEvent(bool periodicEvent); - void scheduleEvent(const AtomicString& eventName); - - // loading + virtual void scheduleResizeEvent() { } + virtual void scheduleResizeEventIfSizeChanged() { } + void selectMediaResource(); void loadResource(const URL&, ContentType&, const String& keySystem); void scheduleNextSourceChild(); void loadNextSourceChild(); void userCancelledLoad(); - void clearMediaPlayer(int flags); + void clearMediaPlayer(DelayedActionType flags); bool havePotentialSourceChild(); void noneSupported(); void cancelPendingEventsAndCallbacks(); @@ -595,7 +696,7 @@ private: URL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction); #if ENABLE(VIDEO_TRACK) - void updateActiveTextTrackCues(double); + void updateActiveTextTrackCues(const MediaTime&); HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const; enum ReconfigureMode { @@ -603,12 +704,11 @@ private: AfterDelay, }; void markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMode); - virtual void captionPreferencesChanged() override; + void captionPreferencesChanged() override; #endif // These "internal" functions do not check user gesture restrictions. - void loadInternal(); - void playInternal(); + bool playInternal(); void pauseInternal(); void prepareForLoad(); @@ -618,30 +718,29 @@ private: void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; } void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; } + enum class UpdateState { Asynchronously, Synchronously }; + + void updatePlayState(UpdateState updateState = UpdateState::Synchronously); void updateVolume(); - void updatePlayState(); + void setPlaying(bool); bool potentiallyPlaying() const; bool endedPlayback() const; bool stoppedDueToErrors() const; bool pausedForUserInteraction() const; bool couldPlayIfEnoughData() const; + SuccessOr<MediaPlaybackDenialReason> canTransitionFromAutoplayToPlay() const; - double minTimeSeekable() const; - double maxTimeSeekable() const; - -#if PLATFORM(IOS) - bool parseMediaPlayerAttribute(const QualifiedName&, const AtomicString&); -#endif + MediaTime minTimeSeekable() const; + MediaTime maxTimeSeekable() const; // Pauses playback without changing any states or generating events void setPausedInternal(bool); void setPlaybackRateInternal(double); - virtual void mediaCanStart() override; + void mediaCanStart(Document&) final; - void setShouldDelayLoadEvent(bool); - void invalidateCachedTime(); + void invalidateCachedTime() const; void refreshCachedTime() const; bool hasMediaControls() const; @@ -653,95 +752,195 @@ private: void changeNetworkStateFromLoadingToIdle(); - void removeBehaviorsRestrictionsAfterFirstUserGesture(); + void removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions); void updateMediaController(); bool isBlocked() const; bool isBlockedOnMediaController() const; - virtual bool hasCurrentSrc() const override { return !m_currentSrc.isEmpty(); } - virtual bool isLiveStream() const override { return movieLoadType() == MediaPlayer::LiveStream; } - bool isAutoplaying() const { return m_autoplaying; } + bool hasCurrentSrc() const override { return !m_currentSrc.isEmpty(); } + bool isLiveStream() const override { return movieLoadType() == MediaPlayerEnums::LiveStream; } void updateSleepDisabling(); -#if PLATFORM(MAC) bool shouldDisableSleep() const; -#endif #if ENABLE(MEDIA_CONTROLS_SCRIPT) - virtual void didAddUserAgentShadowRoot(ShadowRoot*) override; + void didAddUserAgentShadowRoot(ShadowRoot*) override; DOMWrapperWorld& ensureIsolatedWorld(); bool ensureMediaControlsInjectedScript(); #endif - virtual MediaSession::MediaType mediaType() const override; + PlatformMediaSession::MediaType mediaType() const override; + PlatformMediaSession::MediaType presentationType() const override; + PlatformMediaSession::DisplayType displayType() const override; + PlatformMediaSession::CharacteristicsFlags characteristics() const final; + + void suspendPlayback() override; + void resumeAutoplaying() override; + void mayResumePlayback(bool shouldResume) override; + String mediaSessionTitle() const override; + double mediaSessionDuration() const override { return duration(); } + double mediaSessionCurrentTime() const override { return currentTime(); } + bool canReceiveRemoteControlCommands() const override { return true; } + void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override; + bool supportsSeeking() const override; + bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override; + bool shouldOverrideBackgroundLoadingRestriction() const override; + bool canProduceAudio() const final; + + void pageMutedStateDidChange() override; + + bool effectiveMuted() const; + + void registerWithDocument(Document&); + void unregisterWithDocument(Document&); + + void updateCaptionContainer(); + void ensureMediaControlsShadowRoot(); - virtual void beginInterruption() override; - virtual void endInterruption(MediaSession::EndInterruptionFlags) override; - virtual void pausePlayback() override; +#if ENABLE(WIRELESS_PLAYBACK_TARGET) + void prepareForDocumentSuspension() final; + void resumeFromDocumentSuspension() final; - Timer<HTMLMediaElement> m_loadTimer; - Timer<HTMLMediaElement> m_progressEventTimer; - Timer<HTMLMediaElement> m_playbackProgressTimer; + void updateMediaState(UpdateState updateState = UpdateState::Synchronously); + bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; } +#endif + + bool isVideoTooSmallForInlinePlayback(); + void isVisibleInViewportChanged() final; + void updateShouldAutoplay(); + + void pauseAfterDetachedTask(); + void updatePlaybackControlsManager(); + void scheduleUpdatePlaybackControlsManager(); + void playbackControlsManagerBehaviorRestrictionsTimerFired(); + + void updateRenderer(); + + void updatePageScaleFactorJSProperty(); + void updateUsesLTRUserInterfaceLayoutDirectionJSProperty(); + void setControllerJSProperty(const char*, JSC::JSValue); + + void addBehaviorRestrictionsOnEndIfNecessary(); + void handleSeekToPlaybackPosition(double); + void seekToPlaybackPositionEndedTimerFired(); + + Timer m_pendingActionTimer; + Timer m_progressEventTimer; + Timer m_playbackProgressTimer; + Timer m_scanTimer; + Timer m_playbackControlsManagerBehaviorRestrictionsTimer; + Timer m_seekToPlaybackPositionEndedTimer; + GenericTaskQueue<Timer> m_seekTaskQueue; + GenericTaskQueue<Timer> m_resizeTaskQueue; + GenericTaskQueue<Timer> m_shadowDOMTaskQueue; + GenericTaskQueue<Timer> m_promiseTaskQueue; + GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue; + GenericTaskQueue<Timer> m_updatePlaybackControlsManagerQueue; + GenericTaskQueue<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue; + GenericTaskQueue<Timer> m_resourceSelectionTaskQueue; RefPtr<TimeRanges> m_playedTimeRanges; GenericEventQueue m_asyncEventQueue; - double m_playbackRate; - double m_defaultPlaybackRate; - bool m_webkitPreservesPitch; - NetworkState m_networkState; - ReadyState m_readyState; - ReadyState m_readyStateMaximum; + Vector<DOMPromise<void>> m_pendingPlayPromises; + + double m_requestedPlaybackRate { 1 }; + double m_reportedPlaybackRate { 1 }; + double m_defaultPlaybackRate { 1 }; + bool m_webkitPreservesPitch { true }; + NetworkState m_networkState { NETWORK_EMPTY }; + ReadyState m_readyState { HAVE_NOTHING }; + ReadyState m_readyStateMaximum { HAVE_NOTHING }; URL m_currentSrc; RefPtr<MediaError> m_error; - double m_volume; - bool m_volumeInitialized; - double m_lastSeekTime; + struct PendingSeek { + PendingSeek(const MediaTime& now, const MediaTime& targetTime, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance) + : now(now) + , targetTime(targetTime) + , negativeTolerance(negativeTolerance) + , positiveTolerance(positiveTolerance) + { + } + MediaTime now; + MediaTime targetTime; + MediaTime negativeTolerance; + MediaTime positiveTolerance; + }; + std::unique_ptr<PendingSeek> m_pendingSeek; + SeekType m_pendingSeekType { NoSeek }; + + double m_volume { 1 }; + bool m_volumeInitialized { false }; + MediaTime m_lastSeekTime; - unsigned m_previousProgress; - double m_previousProgressTime; + double m_previousProgressTime { std::numeric_limits<double>::max() }; + double m_playbackStartedTime { 0 }; // The last time a timeupdate event was sent (based on monotonic clock). - double m_clockTimeAtLastUpdateEvent; + double m_clockTimeAtLastUpdateEvent { 0 }; // The last time a timeupdate event was sent in movie time. - double m_lastTimeUpdateEventMovieTime; + MediaTime m_lastTimeUpdateEventMovieTime; // Loading state. enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement }; - LoadState m_loadState; + LoadState m_loadState { WaitingForSource }; RefPtr<HTMLSourceElement> m_currentSourceNode; RefPtr<Node> m_nextChildNodeToConsider; - OwnPtr<MediaPlayer> m_player; -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) - RefPtr<Widget> m_proxyWidget; + VideoFullscreenMode m_videoFullscreenMode { VideoFullscreenModeNone }; + bool m_preparedForInline; + std::function<void()> m_preparedForInlineCompletionHandler; + + bool m_temporarilyAllowingInlinePlaybackAfterFullscreen { false }; + +#if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) + RetainPtr<PlatformLayer> m_videoFullscreenLayer; + FloatRect m_videoFullscreenFrame; + MediaPlayerEnums::VideoGravity m_videoFullscreenGravity { MediaPlayer::VideoGravityResizeAspect }; #endif - MediaPlayer::Preload m_preload; + RefPtr<MediaPlayer> m_player; - DisplayMode m_displayMode; + MediaPlayerEnums::Preload m_preload { MediaPlayer::Auto }; + + DisplayMode m_displayMode { Unknown }; // Counter incremented while processing a callback from the media player, so we can avoid // calling the media engine recursively. - int m_processingMediaPlayerCallback; + int m_processingMediaPlayerCallback { 0 }; + +#if ENABLE(MEDIA_SESSION) + String m_kind; + RefPtr<MediaSession> m_session; + bool m_shouldDuck { false }; + uint64_t m_elementID; +#endif #if ENABLE(MEDIA_SOURCE) - RefPtr<HTMLMediaSource> m_mediaSource; - unsigned long m_droppedVideoFrames; + RefPtr<MediaSource> m_mediaSource; + unsigned m_droppedVideoFrames { 0 }; #endif - mutable double m_cachedTime; - mutable double m_clockTimeAtLastCachedTimeUpdate; - mutable double m_minimumClockTimeToUpdateCachedTime; + mutable MediaTime m_cachedTime; + mutable double m_clockTimeAtLastCachedTimeUpdate { 0 }; + mutable double m_minimumClockTimeToUpdateCachedTime { 0 }; - double m_fragmentStartTime; - double m_fragmentEndTime; + MediaTime m_fragmentStartTime; + MediaTime m_fragmentEndTime; - typedef unsigned PendingActionFlags; - PendingActionFlags m_pendingActionFlags; + using PendingActionFlags = unsigned; + PendingActionFlags m_pendingActionFlags { 0 }; + enum ActionAfterScanType { Nothing, Play, Pause }; + ActionAfterScanType m_actionAfterScan { Nothing }; + + enum ScanType { Seek, Scan }; + ScanType m_scanType { Scan }; + ScanDirection m_scanDirection { Forward }; + + bool m_firstTimePlaying : 1; bool m_playing : 1; bool m_isWaitingUntilMediaCanStart : 1; bool m_shouldDelayLoadEvent : 1; @@ -750,6 +949,7 @@ private: bool m_autoplaying : 1; bool m_muted : 1; bool m_explicitlyMuted : 1; + bool m_initiallyMuted : 1; bool m_paused : 1; bool m_seeking : 1; @@ -765,27 +965,26 @@ private: // support progress events so setting m_sendProgressEvents disables them bool m_sendProgressEvents : 1; - bool m_isFullscreen : 1; bool m_closedCaptionsVisible : 1; bool m_webkitLegacyClosedCaptionOverride : 1; - -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) - bool m_needWidgetUpdate : 1; -#endif - bool m_completelyLoaded : 1; bool m_havePreparedToPlay : 1; bool m_parsingInProgress : 1; -#if ENABLE(PAGE_VISIBILITY_API) - bool m_isDisplaySleepDisablingSuspended : 1; -#endif + bool m_elementIsHidden : 1; + bool m_creatingControls : 1; + bool m_receivedLayoutSizeChanged : 1; + bool m_hasEverNotifiedAboutPlaying : 1; + bool m_preventedFromPlayingWithoutUserGesture : 1; -#if PLATFORM(IOS) - bool m_requestingPlay : 1; - bool m_platformLayerBorrowed : 1; + bool m_hasEverHadAudio : 1; + bool m_hasEverHadVideo : 1; + +#if ENABLE(MEDIA_CONTROLS_SCRIPT) + bool m_mediaControlsDependOnPageScaleFactor : 1; + bool m_haveSetUpCaptionContainer : 1; #endif - bool m_resumePlaybackAfterInterruption : 1; + bool m_isScrubbingRemotely : 1; #if ENABLE(VIDEO_TRACK) bool m_tracksAreReady : 1; @@ -793,9 +992,9 @@ private: bool m_processingPreferenceChange : 1; String m_subtitleTrackLanguage; - float m_lastTextTrackUpdateTime; + MediaTime m_lastTextTrackUpdateTime { -1, 1 }; - CaptionUserPreferences::CaptionDisplayMode m_captionDisplayMode; + CaptionUserPreferences::CaptionDisplayMode m_captionDisplayMode { CaptionUserPreferences::Automatic }; RefPtr<AudioTrackList> m_audioTracks; RefPtr<TextTrackList> m_textTracks; @@ -805,69 +1004,86 @@ private: CueIntervalTree m_cueTree; CueList m_currentlyActiveCues; - int m_ignoreTrackDisplayUpdate; + int m_ignoreTrackDisplayUpdate { 0 }; + + bool m_requireCaptionPreferencesChangedCallbacks { false }; #endif #if ENABLE(WEB_AUDIO) // This is a weak reference, since m_audioSourceNode holds a reference to us. // The value is set just after the MediaElementAudioSourceNode is created. // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode(). - MediaElementAudioSourceNode* m_audioSourceNode; + MediaElementAudioSourceNode* m_audioSourceNode { nullptr }; #endif String m_mediaGroup; friend class MediaController; RefPtr<MediaController> m_mediaController; -#if PLATFORM(MAC) - OwnPtr<DisplaySleepDisabler> m_sleepDisabler; -#endif + std::unique_ptr<DisplaySleepDisabler> m_sleepDisabler; friend class TrackDisplayUpdateScope; -#if ENABLE(ENCRYPTED_MEDIA_V2) - RefPtr<MediaKeys> m_mediaKeys; -#endif + RefPtr<Blob> m_blob; + MediaProvider m_mediaProvider; -#if USE(PLATFORM_TEXT_TRACK_MENU) - RefPtr<PlatformTextTrackMenuInterface> m_platformMenu; +#if ENABLE(LEGACY_ENCRYPTED_MEDIA) + RefPtr<WebKitMediaKeys> m_webKitMediaKeys; #endif - std::unique_ptr<HTMLMediaSession> m_mediaSession; - std::unique_ptr<PageActivityAssertionToken> m_activityToken; - size_t m_reportedExtraMemoryCost; + std::unique_ptr<MediaElementSession> m_mediaSession; + size_t m_reportedExtraMemoryCost { 0 }; #if ENABLE(MEDIA_CONTROLS_SCRIPT) + friend class MediaControlsHost; RefPtr<MediaControlsHost> m_mediaControlsHost; RefPtr<DOMWrapperWorld> m_isolatedWorld; #endif #if ENABLE(MEDIA_STREAM) RefPtr<MediaStream> m_mediaStreamSrcObject; + bool m_settingMediaStreamSrcObject { false }; +#endif + +#if ENABLE(WIRELESS_PLAYBACK_TARGET) + MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying }; + bool m_hasPlaybackTargetAvailabilityListeners { false }; + bool m_failedToPlayToWirelessTarget { false }; + bool m_isPlayingToWirelessTarget { false }; #endif }; -#if ENABLE(VIDEO_TRACK) -#ifndef NDEBUG +#if ENABLE(VIDEO_TRACK) && !defined(NDEBUG) + // Template specialization required by PodIntervalTree in debug mode. -template <> -struct ValueToString<TextTrackCue*> { +template <> struct ValueToString<TextTrackCue*> { static String string(TextTrackCue* const& cue) { - return String::format("%p id=%s interval=%f-->%f cue=%s)", cue, cue->id().utf8().data(), cue->startTime(), cue->endTime(), cue->text().utf8().data()); + String text; + if (cue->isRenderable()) + text = toVTTCue(cue)->text(); + return String::format("%p id=%s interval=%s-->%s cue=%s)", cue, cue->id().utf8().data(), toString(cue->startTime()).utf8().data(), toString(cue->endTime()).utf8().data(), text.utf8().data()); } }; -#endif -#endif -void isHTMLMediaElement(const HTMLMediaElement&); // Catch unnecessary runtime check of type known at compile time. -inline bool isHTMLMediaElement(const Element& element) { return element.isMediaElement(); } -inline bool isHTMLMediaElement(const Node& node) { return node.isElementNode() && toElement(node).isMediaElement(); } -template <> inline bool isElementOfType<const HTMLMediaElement>(const Element& element) { return element.isMediaElement(); } +#endif -NODE_TYPE_CASTS(HTMLMediaElement) +#ifndef NDEBUG -} //namespace +template<> struct ValueToString<MediaTime> { + static String string(const MediaTime& time) + { + return toString(time); + } +}; #endif + +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLMediaElement) + static bool isType(const WebCore::Element& element) { return element.isMediaElement(); } + static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); } +SPECIALIZE_TYPE_TRAITS_END() + #endif |