459bd3a1e8ff7dce7855ee1479da0db854b3faaf
[WebKit-https.git] / Source / WebCore / html / HTMLMediaElement.h
1 /*
2  * Copyright (C) 2007-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(VIDEO)
29
30 #include "ActiveDOMObject.h"
31 #include "GenericEventQueue.h"
32 #include "GenericTaskQueue.h"
33 #include "HTMLElement.h"
34 #include "HTMLMediaElementEnums.h"
35 #include "MediaCanStartListener.h"
36 #include "MediaControllerInterface.h"
37 #include "MediaElementSession.h"
38 #include "MediaProducer.h"
39 #include "UserInterfaceLayoutDirection.h"
40
41 #if ENABLE(VIDEO_TRACK)
42 #include "AudioTrack.h"
43 #include "CaptionUserPreferences.h"
44 #include "PODIntervalTree.h"
45 #include "TextTrack.h"
46 #include "TextTrackCue.h"
47 #include "VTTCue.h"
48 #include "VideoTrack.h"
49 #endif
50
51 #ifndef NDEBUG
52 #include <wtf/StringPrintStream.h>
53 #endif
54
55 namespace WebCore {
56
57 class AudioSourceProvider;
58 class AudioTrackList;
59 class AudioTrackPrivate;
60 class DOMError;
61 class DeferredPromise;
62 class DisplaySleepDisabler;
63 class Event;
64 class HTMLSourceElement;
65 class HTMLTrackElement;
66 class InbandTextTrackPrivate;
67 class MediaController;
68 class MediaControls;
69 class MediaControlsHost;
70 class MediaElementAudioSourceNode;
71 class MediaError;
72 class MediaKeys;
73 class MediaPlayer;
74 class MediaSession;
75 class MediaSource;
76 class MediaStream;
77 class RenderMedia;
78 class ScriptExecutionContext;
79 class SourceBuffer;
80 class TextTrackList;
81 class TimeRanges;
82 class VideoPlaybackQuality;
83 class VideoTrackList;
84 class VideoTrackPrivate;
85 class WebKitMediaKeys;
86
87 template<typename> class DOMPromise;
88
89 #if ENABLE(VIDEO_TRACK)
90 using CueIntervalTree = PODIntervalTree<MediaTime, TextTrackCue*>;
91 using CueInterval = CueIntervalTree::IntervalType;
92 using CueList = Vector<CueInterval>;
93 #endif
94
95 class HTMLMediaElement
96     : public HTMLElement
97     , public ActiveDOMObject
98     , public MediaControllerInterface
99     , public MediaPlayerSupportsTypeClient
100     , public PlatformMediaSessionClient
101     , private MediaCanStartListener
102     , private MediaPlayerClient
103     , private MediaProducer
104 #if ENABLE(VIDEO_TRACK)
105     , private AudioTrackClient
106     , private TextTrackClient
107     , private VideoTrackClient
108 #endif
109 {
110 public:
111     MediaPlayer* player() const { return m_player.get(); }
112
113     virtual bool isVideo() const { return false; }
114     bool hasVideo() const override { return false; }
115     bool hasAudio() const override;
116
117     static HashSet<HTMLMediaElement*>& allMediaElements();
118
119     static HTMLMediaElement* bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose);
120
121     void rewind(double timeDelta);
122     WEBCORE_EXPORT void returnToRealtime() override;
123
124     // Eventually overloaded in HTMLVideoElement
125     bool supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) const override { return false; };
126
127     bool supportsScanning() const override;
128
129     bool canSaveMediaData() const;
130
131     bool doesHaveAttribute(const AtomicString&, AtomicString* value = nullptr) const override;
132
133     WEBCORE_EXPORT PlatformMedia platformMedia() const;
134     PlatformLayer* platformLayer() const;
135     bool isVideoLayerInline();
136     void setPreparedToReturnVideoLayerToInline(bool);
137     void waitForPreparedForInlineThen(std::function<void()> completionHandler = [] { });
138 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
139     void setVideoFullscreenLayer(PlatformLayer*, std::function<void()> completionHandler = [] { });
140     PlatformLayer* videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); }
141     void setVideoFullscreenFrame(FloatRect);
142     void setVideoFullscreenGravity(MediaPlayerEnums::VideoGravity);
143     MediaPlayerEnums::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; }
144 #endif
145
146     using HTMLMediaElementEnums::DelayedActionType;
147     void scheduleDelayedAction(DelayedActionType);
148     void scheduleResolvePendingPlayPromises();
149     void rejectPendingPlayPromises(DOMError&);
150     void resolvePendingPlayPromises();
151     void scheduleNotifyAboutPlaying();
152     void notifyAboutPlaying();
153     
154     MediaPlayerEnums::MovieLoadType movieLoadType() const;
155     
156     bool inActiveDocument() const { return m_inActiveDocument; }
157
158     const Document* hostingDocument() const override { return &document(); }
159
160 // DOM API
161 // error state
162     WEBCORE_EXPORT MediaError* error() const;
163
164     void setSrc(const String&);
165     const URL& currentSrc() const { return m_currentSrc; }
166
167 #if ENABLE(MEDIA_STREAM)
168     MediaStream* srcObject() const { return m_mediaStreamSrcObject.get(); }
169     void setSrcObject(ScriptExecutionContext&, MediaStream*);
170 #endif
171
172     WEBCORE_EXPORT void setCrossOrigin(const AtomicString&);
173     WEBCORE_EXPORT String crossOrigin() const;
174
175 // network state
176     using HTMLMediaElementEnums::NetworkState;
177     WEBCORE_EXPORT NetworkState networkState() const;
178
179     WEBCORE_EXPORT String preload() const;
180     WEBCORE_EXPORT void setPreload(const String&);
181
182     Ref<TimeRanges> buffered() const override;
183     WEBCORE_EXPORT void load();
184     WEBCORE_EXPORT String canPlayType(const String& mimeType) const;
185
186 // ready state
187     using HTMLMediaElementEnums::ReadyState;
188     ReadyState readyState() const override;
189     WEBCORE_EXPORT bool seeking() const;
190
191 // playback state
192     WEBCORE_EXPORT double currentTime() const override;
193     void setCurrentTime(double) override;
194     double currentTimeForBindings() const { return currentTime(); }
195     WEBCORE_EXPORT ExceptionOr<void> setCurrentTimeForBindings(double);
196     WEBCORE_EXPORT double getStartDate() const;
197     WEBCORE_EXPORT double duration() const override;
198     WEBCORE_EXPORT bool paused() const override;
199     double defaultPlaybackRate() const override;
200     void setDefaultPlaybackRate(double) override;
201     WEBCORE_EXPORT double playbackRate() const override;
202     void setPlaybackRate(double) override;
203
204 // MediaTime versions of playback state
205     MediaTime currentMediaTime() const;
206     void setCurrentTime(const MediaTime&);
207     MediaTime durationMediaTime() const;
208     WEBCORE_EXPORT void fastSeek(const MediaTime&);
209
210     void updatePlaybackRate();
211     WEBCORE_EXPORT bool webkitPreservesPitch() const;
212     WEBCORE_EXPORT void setWebkitPreservesPitch(bool);
213     Ref<TimeRanges> played() override;
214     Ref<TimeRanges> seekable() const override;
215     WEBCORE_EXPORT bool ended() const;
216     bool autoplay() const;
217     bool isAutoplaying() const { return m_autoplaying; }
218     bool loop() const;
219     void setLoop(bool b);
220
221     void play(DOMPromise<void>&&);
222
223     WEBCORE_EXPORT void play() override;
224     WEBCORE_EXPORT void pause() override;
225     void setShouldBufferData(bool) override;
226     WEBCORE_EXPORT void fastSeek(double);
227     double minFastReverseRate() const;
228     double maxFastForwardRate() const;
229
230     void purgeBufferedDataIfPossible();
231
232 // captions
233     WEBCORE_EXPORT bool webkitHasClosedCaptions() const;
234     WEBCORE_EXPORT bool webkitClosedCaptionsVisible() const;
235     WEBCORE_EXPORT void setWebkitClosedCaptionsVisible(bool);
236
237     bool elementIsHidden() const override { return m_elementIsHidden; }
238
239 #if ENABLE(MEDIA_STATISTICS)
240 // Statistics
241     unsigned webkitAudioDecodedByteCount() const;
242     unsigned webkitVideoDecodedByteCount() const;
243 #endif
244
245 #if ENABLE(MEDIA_SOURCE)
246 //  Media Source.
247     void detachMediaSource();
248     void incrementDroppedFrameCount() { ++m_droppedVideoFrames; }
249     size_t maximumSourceBufferSize(const SourceBuffer&) const;
250 #endif
251
252 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
253     WebKitMediaKeys* webkitKeys() const { return m_mediaKeys.get(); }
254     void webkitSetMediaKeys(WebKitMediaKeys*);
255
256     void keyAdded();
257 #endif
258
259 #if ENABLE(ENCRYPTED_MEDIA)
260     MediaKeys* mediaKeys() const;
261
262     void setMediaKeys(MediaKeys*, Ref<DeferredPromise>&&);
263 #endif
264
265 // controls
266     WEBCORE_EXPORT bool controls() const;
267     WEBCORE_EXPORT void setControls(bool);
268     WEBCORE_EXPORT double volume() const override;
269     ExceptionOr<void> setVolume(double) override;
270     WEBCORE_EXPORT bool muted() const override;
271     WEBCORE_EXPORT void setMuted(bool) override;
272
273     WEBCORE_EXPORT void togglePlayState();
274     WEBCORE_EXPORT void beginScrubbing() override;
275     WEBCORE_EXPORT void endScrubbing() override;
276
277     void beginScanning(ScanDirection) override;
278     void endScanning() override;
279     double nextScanRate();
280
281     WEBCORE_EXPORT bool canPlay() const override;
282
283     double percentLoaded() const;
284
285 #if ENABLE(VIDEO_TRACK)
286     ExceptionOr<TextTrack&> addTextTrack(const String& kind, const String& label, const String& language);
287
288     AudioTrackList& audioTracks();
289     TextTrackList& textTracks();
290     VideoTrackList& videoTracks();
291
292     CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
293
294     void addAudioTrack(Ref<AudioTrack>&&);
295     void addTextTrack(Ref<TextTrack>&&);
296     void addVideoTrack(Ref<VideoTrack>&&);
297     void removeAudioTrack(AudioTrack&);
298     void removeTextTrack(TextTrack&, bool scheduleEvent = true);
299     void removeVideoTrack(VideoTrack&);
300     void forgetResourceSpecificTracks();
301     void closeCaptionTracksChanged();
302     void notifyMediaPlayerOfTextTrackChanges();
303
304     virtual void didAddTextTrack(HTMLTrackElement&);
305     virtual void didRemoveTextTrack(HTMLTrackElement&);
306
307     void mediaPlayerDidAddAudioTrack(AudioTrackPrivate&) final;
308     void mediaPlayerDidAddTextTrack(InbandTextTrackPrivate&) final;
309     void mediaPlayerDidAddVideoTrack(VideoTrackPrivate&) final;
310     void mediaPlayerDidRemoveAudioTrack(AudioTrackPrivate&) final;
311     void mediaPlayerDidRemoveTextTrack(InbandTextTrackPrivate&) final;
312     void mediaPlayerDidRemoveVideoTrack(VideoTrackPrivate&) final;
313
314 #if ENABLE(AVF_CAPTIONS)
315     Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources() final;
316 #endif
317
318     struct TrackGroup;
319     void configureTextTrackGroupForLanguage(const TrackGroup&) const;
320     void configureTextTracks();
321     void configureTextTrackGroup(const TrackGroup&);
322
323     void setSelectedTextTrack(TextTrack*);
324
325     bool textTracksAreReady() const;
326     using HTMLMediaElementEnums::TextTrackVisibilityCheckType;
327     void configureTextTrackDisplay(TextTrackVisibilityCheckType checkType = CheckTextTrackVisibility);
328     void updateTextTrackDisplay();
329
330     // AudioTrackClient
331     void audioTrackEnabledChanged(AudioTrack&) final;
332
333     void textTrackReadyStateChanged(TextTrack*);
334
335     // TextTrackClient
336     void textTrackKindChanged(TextTrack&) override;
337     void textTrackModeChanged(TextTrack&) override;
338     void textTrackAddCues(TextTrack&, const TextTrackCueList&) override;
339     void textTrackRemoveCues(TextTrack&, const TextTrackCueList&) override;
340     void textTrackAddCue(TextTrack&, TextTrackCue&) override;
341     void textTrackRemoveCue(TextTrack&, TextTrackCue&) override;
342
343     // VideoTrackClient
344     void videoTrackSelectedChanged(VideoTrack&) final;
345
346     bool requiresTextTrackRepresentation() const;
347     void setTextTrackRepresentation(TextTrackRepresentation*);
348     void syncTextTrackBounds();
349 #endif
350
351 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
352     void webkitShowPlaybackTargetPicker();
353     bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
354     bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
355
356     void wirelessRoutesAvailableDidChange() override;
357     bool canPlayToWirelessPlaybackTarget() const override;
358     bool isPlayingToWirelessPlaybackTarget() const override;
359     void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
360     void setShouldPlayToPlaybackTarget(bool) override;
361 #endif
362     bool webkitCurrentPlaybackTargetIsWireless() const;
363
364     // EventTarget function.
365     // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
366     // causes an ambiguity error at compile time. This class's constructor
367     // ensures that both implementations return document, so return the result
368     // of one of them here.
369     using HTMLElement::scriptExecutionContext;
370
371     bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
372     
373     WEBCORE_EXPORT bool isFullscreen() const override;
374     bool isStandardFullscreen() const;
375     void toggleStandardFullscreenState();
376
377     using MediaPlayerEnums::VideoFullscreenMode;
378     VideoFullscreenMode fullscreenMode() const { return m_videoFullscreenMode; }
379     virtual void fullscreenModeChanged(VideoFullscreenMode);
380
381     void enterFullscreen(VideoFullscreenMode);
382     void enterFullscreen() override;
383     WEBCORE_EXPORT void exitFullscreen();
384
385     bool hasClosedCaptions() const override;
386     bool closedCaptionsVisible() const override;
387     void setClosedCaptionsVisible(bool) override;
388
389     MediaControls* mediaControls() const;
390
391     void sourceWasRemoved(HTMLSourceElement*);
392     void sourceWasAdded(HTMLSourceElement*);
393
394     void privateBrowsingStateDidChange() override;
395
396     // Media cache management.
397     WEBCORE_EXPORT static void setMediaCacheDirectory(const String&);
398     WEBCORE_EXPORT static const String& mediaCacheDirectory();
399     WEBCORE_EXPORT static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&);
400     WEBCORE_EXPORT static void clearMediaCache(const String&, std::chrono::system_clock::time_point modifiedSince = { });
401     WEBCORE_EXPORT static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&);
402     static void resetMediaEngines();
403
404     bool isPlaying() const { return m_playing; }
405
406     bool hasPendingActivity() const override;
407
408 #if ENABLE(WEB_AUDIO)
409     MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
410     void setAudioSourceNode(MediaElementAudioSourceNode*);
411
412     AudioSourceProvider* audioSourceProvider();
413 #endif
414
415     using HTMLMediaElementEnums::InvalidURLAction;
416     bool isSafeToLoadURL(const URL&, InvalidURLAction);
417
418     const String& mediaGroup() const;
419     void setMediaGroup(const String&);
420
421     MediaController* controller() const;
422     void setController(RefPtr<MediaController>&&);
423
424     MediaController* controllerForBindings() const { return controller(); }
425     void setControllerForBindings(MediaController*);
426
427     void enteredOrExitedFullscreen() { configureMediaControls(); }
428
429     unsigned long long fileSize() const;
430
431     void mediaLoadingFailed(MediaPlayerEnums::NetworkState);
432     void mediaLoadingFailedFatally(MediaPlayerEnums::NetworkState);
433
434 #if ENABLE(MEDIA_SESSION)
435     WEBCORE_EXPORT double playerVolume() const;
436
437     const String& kind() const { return m_kind; }
438     void setKind(const String& kind) { m_kind = kind; }
439
440     MediaSession* session() const;
441     void setSession(MediaSession*);
442
443     void setShouldDuck(bool);
444
445     static HTMLMediaElement* elementWithID(uint64_t);
446     uint64_t elementID() const { return m_elementID; }
447 #endif
448
449 #if ENABLE(MEDIA_SOURCE)
450     RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality();
451 #endif
452
453     MediaPlayerEnums::Preload preloadValue() const { return m_preload; }
454     MediaElementSession& mediaSession() const { return *m_mediaSession; }
455
456 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
457     void pageScaleFactorChanged();
458     void userInterfaceLayoutDirectionChanged();
459     WEBCORE_EXPORT String getCurrentMediaControlsStatus();
460
461     MediaControlsHost* mediaControlsHost() { return m_mediaControlsHost.get(); }
462 #endif
463
464     bool isDisablingSleep() const { return m_sleepDisabler.get(); }
465
466     double maxBufferedTime() const;
467
468     MediaProducer::MediaStateFlags mediaState() const override;
469
470     void layoutSizeChanged();
471     void visibilityDidChange();
472
473     void allowsMediaDocumentInlinePlaybackChanged();
474     void updateShouldPlay();
475
476     RenderMedia* renderer() const;
477
478     void resetPlaybackSessionState();
479     bool isVisibleInViewport() const;
480     bool hasEverNotifiedAboutPlaying() const;
481     void setShouldDelayLoadEvent(bool);
482
483     bool hasEverHadAudio() const { return m_hasEverHadAudio; }
484     bool hasEverHadVideo() const { return m_hasEverHadVideo; }
485
486     double playbackStartedTime() const { return m_playbackStartedTime; }
487
488 protected:
489     HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
490     virtual ~HTMLMediaElement();
491
492     void parseAttribute(const QualifiedName&, const AtomicString&) override;
493     void finishParsingChildren() override;
494     bool isURLAttribute(const Attribute&) const override;
495     void willAttachRenderers() override;
496     void didAttachRenderers() override;
497     void willDetachRenderers() override;
498     void didDetachRenderers() override;
499
500     void didMoveToNewDocument(Document& oldDocument) override;
501
502     enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
503     DisplayMode displayMode() const { return m_displayMode; }
504     virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
505     
506     bool isMediaElement() const final { return true; }
507
508 #if ENABLE(VIDEO_TRACK)
509     bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0 || !m_textTracks || !m_cueTree.size(); }
510     void beginIgnoringTrackDisplayUpdateRequests();
511     void endIgnoringTrackDisplayUpdateRequests();
512 #endif
513
514     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
515
516 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
517     bool mediaControlsDependOnPageScaleFactor() const { return m_mediaControlsDependOnPageScaleFactor; }
518     void setMediaControlsDependOnPageScaleFactor(bool);
519     void updateMediaControlsAfterPresentationModeChange();
520 #endif
521
522     void scheduleEvent(const AtomicString& eventName);
523
524 private:
525     void createMediaPlayer();
526
527     bool alwaysCreateUserAgentShadowRoot() const override { return true; }
528
529     bool supportsFocus() const override;
530     bool isMouseFocusable() const override;
531     bool rendererIsNeeded(const RenderStyle&) override;
532     bool childShouldCreateRenderer(const Node&) const override;
533     InsertionNotificationRequest insertedInto(ContainerNode&) override;
534     void finishedInsertingSubtree() override;
535     void removedFrom(ContainerNode&) override;
536     void didRecalcStyle(Style::Change) override;
537
538     void willBecomeFullscreenElement() override;
539     void didBecomeFullscreenElement() override;
540     void willStopBeingFullscreenElement() override;
541
542     // ActiveDOMObject API.
543     const char* activeDOMObjectName() const override;
544     bool canSuspendForDocumentSuspension() const override;
545     void suspend(ReasonForSuspension) override;
546     void resume() override;
547     void stop() override;
548     void stopWithoutDestroyingMediaPlayer();
549     void contextDestroyed() override;
550     
551     void mediaVolumeDidChange() override;
552
553     void visibilityStateChanged() override;
554
555     virtual void updateDisplayState() { }
556     
557     void setReadyState(MediaPlayerEnums::ReadyState);
558     void setNetworkState(MediaPlayerEnums::NetworkState);
559
560     double effectivePlaybackRate() const;
561     double requestedPlaybackRate() const;
562
563     void mediaPlayerNetworkStateChanged(MediaPlayer*) override;
564     void mediaPlayerReadyStateChanged(MediaPlayer*) override;
565     void mediaPlayerTimeChanged(MediaPlayer*) override;
566     void mediaPlayerVolumeChanged(MediaPlayer*) override;
567     void mediaPlayerMuteChanged(MediaPlayer*) override;
568     void mediaPlayerDurationChanged(MediaPlayer*) override;
569     void mediaPlayerRateChanged(MediaPlayer*) override;
570     void mediaPlayerPlaybackStateChanged(MediaPlayer*) override;
571     void mediaPlayerSawUnsupportedTracks(MediaPlayer*) override;
572     void mediaPlayerResourceNotSupported(MediaPlayer*) override;
573     void mediaPlayerRepaint(MediaPlayer*) override;
574     void mediaPlayerSizeChanged(MediaPlayer*) override;
575     bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) override;
576     void mediaPlayerRenderingModeChanged(MediaPlayer*) override;
577     bool mediaPlayerAcceleratedCompositingEnabled() override;
578     void mediaPlayerEngineUpdated(MediaPlayer*) override;
579     void mediaEngineWasUpdated();
580
581     void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override;
582     void mediaPlayerCharacteristicChanged(MediaPlayer*) override;
583
584 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
585     RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String& keyId) const override;
586     bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override;
587     String mediaPlayerMediaKeysStorageDirectory() const override;
588 #endif
589     
590 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
591     void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;
592     void enqueuePlaybackTargetAvailabilityChangedEvent();
593
594     using EventTarget::dispatchEvent;
595     bool dispatchEvent(Event&) override;
596 #endif
597
598 #if ENABLE(MEDIA_SESSION)
599     void setSessionInternal(MediaSession&);
600 #endif
601
602     String mediaPlayerReferrer() const override;
603     String mediaPlayerUserAgent() const override;
604
605     bool mediaPlayerNeedsSiteSpecificHacks() const override;
606     String mediaPlayerDocumentHost() const override;
607
608     void mediaPlayerEnterFullscreen() override;
609     void mediaPlayerExitFullscreen() override;
610     bool mediaPlayerIsFullscreen() const override;
611     bool mediaPlayerIsFullscreenPermitted() const override;
612     bool mediaPlayerIsVideo() const override;
613     LayoutRect mediaPlayerContentBoxRect() const override;
614     float mediaPlayerContentsScale() const override;
615     void mediaPlayerSetSize(const IntSize&) override;
616     void mediaPlayerPause() override;
617     void mediaPlayerPlay() override;
618     bool mediaPlayerPlatformVolumeConfigurationRequired() const override;
619     bool mediaPlayerIsPaused() const override;
620     bool mediaPlayerIsLooping() const override;
621     CachedResourceLoader* mediaPlayerCachedResourceLoader() override;
622     RefPtr<PlatformMediaResourceLoader> mediaPlayerCreateResourceLoader() override;
623     bool mediaPlayerShouldUsePersistentCache() const override;
624     const String& mediaPlayerMediaCacheDirectory() const override;
625
626 #if PLATFORM(WIN) && USE(AVFOUNDATION)
627     GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const override;
628 #endif
629
630     void mediaPlayerActiveSourceBuffersChanged(const MediaPlayer*) override;
631
632     bool mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge&) override;
633     void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command, nullptr); }
634     String sourceApplicationIdentifier() const override;
635     String mediaPlayerSourceApplicationIdentifier() const override { return sourceApplicationIdentifier(); }
636     Vector<String> mediaPlayerPreferredAudioCharacteristics() const override;
637
638 #if PLATFORM(IOS)
639     String mediaPlayerNetworkInterfaceName() const override;
640     bool mediaPlayerGetRawCookies(const URL&, Vector<Cookie>&) const override;
641 #endif
642
643     bool mediaPlayerIsInMediaDocument() const final;
644     void mediaPlayerEngineFailedToLoad() const final;
645
646     double mediaPlayerRequestedPlaybackRate() const final;
647     VideoFullscreenMode mediaPlayerFullscreenMode() const final { return fullscreenMode(); }
648     bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep(); }
649
650 #if USE(GSTREAMER)
651     void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) final;
652 #endif
653
654     void pendingActionTimerFired();
655     void progressEventTimerFired();
656     void playbackProgressTimerFired();
657     void scanTimerFired();
658     void seekTask();
659     void startPlaybackProgressTimer();
660     void startProgressEventTimer();
661     void stopPeriodicTimers();
662
663     void seek(const MediaTime&);
664     void seekInternal(const MediaTime&);
665     void seekWithTolerance(const MediaTime&, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance, bool fromDOM);
666     void finishSeek();
667     void clearSeeking();
668     void addPlayedRange(const MediaTime& start, const MediaTime& end);
669     
670     void scheduleTimeupdateEvent(bool periodicEvent);
671     virtual void scheduleResizeEvent() { }
672     virtual void scheduleResizeEventIfSizeChanged() { }
673
674     void selectMediaResource();
675     void loadResource(const URL&, ContentType&, const String& keySystem);
676     void scheduleNextSourceChild();
677     void loadNextSourceChild();
678     void userCancelledLoad();
679     void clearMediaPlayer(DelayedActionType flags);
680     bool havePotentialSourceChild();
681     void noneSupported();
682     void cancelPendingEventsAndCallbacks();
683     void waitForSourceChange();
684     void prepareToPlay();
685
686     URL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction);
687
688 #if ENABLE(VIDEO_TRACK)
689     void updateActiveTextTrackCues(const MediaTime&);
690     HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
691
692     enum ReconfigureMode {
693         Immediately,
694         AfterDelay,
695     };
696     void markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMode);
697     void captionPreferencesChanged() override;
698 #endif
699
700     // These "internal" functions do not check user gesture restrictions.
701     void loadInternal();
702     bool playInternal();
703     void pauseInternal();
704
705     void prepareForLoad();
706     void allowVideoRendering();
707
708     bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
709     void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
710     void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
711
712     enum class UpdateState { Asynchronously, Synchronously };
713
714     void updatePlayState(UpdateState updateState = UpdateState::Synchronously);
715     void updateVolume();
716     void setPlaying(bool);
717     bool potentiallyPlaying() const;
718     bool endedPlayback() const;
719     bool stoppedDueToErrors() const;
720     bool pausedForUserInteraction() const;
721     bool couldPlayIfEnoughData() const;
722     SuccessOr<MediaPlaybackDenialReason> canTransitionFromAutoplayToPlay() const;
723
724     MediaTime minTimeSeekable() const;
725     MediaTime maxTimeSeekable() const;
726
727     // Pauses playback without changing any states or generating events
728     void setPausedInternal(bool);
729
730     void setPlaybackRateInternal(double);
731
732     void mediaCanStart(Document&) final;
733
734     void invalidateCachedTime() const;
735     void refreshCachedTime() const;
736
737     bool hasMediaControls() const;
738     bool createMediaControls();
739     void configureMediaControls();
740
741     void prepareMediaFragmentURI();
742     void applyMediaFragmentURI();
743
744     void changeNetworkStateFromLoadingToIdle();
745
746     void removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions);
747
748     void updateMediaController();
749     bool isBlocked() const;
750     bool isBlockedOnMediaController() const;
751     bool hasCurrentSrc() const override { return !m_currentSrc.isEmpty(); }
752     bool isLiveStream() const override { return movieLoadType() == MediaPlayerEnums::LiveStream; }
753
754     void updateSleepDisabling();
755     bool shouldDisableSleep() const;
756
757 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
758     void didAddUserAgentShadowRoot(ShadowRoot*) override;
759     DOMWrapperWorld& ensureIsolatedWorld();
760     bool ensureMediaControlsInjectedScript();
761 #endif
762
763     PlatformMediaSession::MediaType mediaType() const override;
764     PlatformMediaSession::MediaType presentationType() const override;
765     PlatformMediaSession::DisplayType displayType() const override;
766     PlatformMediaSession::CharacteristicsFlags characteristics() const final;
767
768     void suspendPlayback() override;
769     void resumeAutoplaying() override;
770     void mayResumePlayback(bool shouldResume) override;
771     String mediaSessionTitle() const override;
772     double mediaSessionDuration() const override { return duration(); }
773     double mediaSessionCurrentTime() const override { return currentTime(); }
774     bool canReceiveRemoteControlCommands() const override { return true; }
775     void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override;
776     bool supportsSeeking() const override;
777     bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override;
778     bool shouldOverrideBackgroundLoadingRestriction() const override;
779     bool canProduceAudio() const final;
780
781     void pageMutedStateDidChange() override;
782
783     bool effectiveMuted() const;
784
785     void registerWithDocument(Document&);
786     void unregisterWithDocument(Document&);
787
788     void updateCaptionContainer();
789     void ensureMediaControlsShadowRoot();
790
791 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
792     void prepareForDocumentSuspension() final;
793     void resumeFromDocumentSuspension() final;
794
795     void updateMediaState(UpdateState updateState = UpdateState::Synchronously);
796     bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; }
797 #endif
798
799     bool isVideoTooSmallForInlinePlayback();
800     void isVisibleInViewportChanged() final;
801     void updateShouldAutoplay();
802
803     void pauseAfterDetachedTask();
804     void updatePlaybackControlsManager();
805     void scheduleUpdatePlaybackControlsManager();
806     void playbackControlsManagerBehaviorRestrictionsTimerFired();
807
808     void updateRenderer();
809
810     void updatePageScaleFactorJSProperty();
811     void updateUsesLTRUserInterfaceLayoutDirectionJSProperty();
812     void setControllerJSProperty(const char*, JSC::JSValue);
813
814     void addBehaviorRestrictionsOnEndIfNecessary();
815     void handleSeekToPlaybackPosition(double);
816     void seekToPlaybackPositionEndedTimerFired();
817
818     Timer m_pendingActionTimer;
819     Timer m_progressEventTimer;
820     Timer m_playbackProgressTimer;
821     Timer m_scanTimer;
822     Timer m_playbackControlsManagerBehaviorRestrictionsTimer;
823     Timer m_seekToPlaybackPositionEndedTimer;
824     GenericTaskQueue<Timer> m_seekTaskQueue;
825     GenericTaskQueue<Timer> m_resizeTaskQueue;
826     GenericTaskQueue<Timer> m_shadowDOMTaskQueue;
827     GenericTaskQueue<Timer> m_promiseTaskQueue;
828     GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue;
829     GenericTaskQueue<Timer> m_updatePlaybackControlsManagerQueue;
830     GenericTaskQueue<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue;
831     RefPtr<TimeRanges> m_playedTimeRanges;
832     GenericEventQueue m_asyncEventQueue;
833
834     Vector<DOMPromise<void>> m_pendingPlayPromises;
835
836     double m_requestedPlaybackRate { 1 };
837     double m_reportedPlaybackRate { 1 };
838     double m_defaultPlaybackRate { 1 };
839     bool m_webkitPreservesPitch { true };
840     NetworkState m_networkState { NETWORK_EMPTY };
841     ReadyState m_readyState { HAVE_NOTHING };
842     ReadyState m_readyStateMaximum { HAVE_NOTHING };
843     URL m_currentSrc;
844
845     RefPtr<MediaError> m_error;
846
847     struct PendingSeek {
848         PendingSeek(const MediaTime& now, const MediaTime& targetTime, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance)
849             : now(now)
850             , targetTime(targetTime)
851             , negativeTolerance(negativeTolerance)
852             , positiveTolerance(positiveTolerance)
853         {
854         }
855         MediaTime now;
856         MediaTime targetTime;
857         MediaTime negativeTolerance;
858         MediaTime positiveTolerance;
859     };
860     std::unique_ptr<PendingSeek> m_pendingSeek;
861     SeekType m_pendingSeekType { NoSeek };
862
863     double m_volume { 1 };
864     bool m_volumeInitialized { false };
865     MediaTime m_lastSeekTime;
866     
867     double m_previousProgressTime { std::numeric_limits<double>::max() };
868     double m_playbackStartedTime { 0 };
869
870     // The last time a timeupdate event was sent (based on monotonic clock).
871     double m_clockTimeAtLastUpdateEvent { 0 };
872
873     // The last time a timeupdate event was sent in movie time.
874     MediaTime m_lastTimeUpdateEventMovieTime;
875     
876     // Loading state.
877     enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
878     LoadState m_loadState { WaitingForSource };
879     RefPtr<HTMLSourceElement> m_currentSourceNode;
880     RefPtr<Node> m_nextChildNodeToConsider;
881
882     VideoFullscreenMode m_videoFullscreenMode { VideoFullscreenModeNone };
883     bool m_preparedForInline;
884     std::function<void()> m_preparedForInlineCompletionHandler;
885
886 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
887     RetainPtr<PlatformLayer> m_videoFullscreenLayer;
888     FloatRect m_videoFullscreenFrame;
889     MediaPlayerEnums::VideoGravity m_videoFullscreenGravity { MediaPlayer::VideoGravityResizeAspect };
890 #endif
891
892     RefPtr<MediaPlayer> m_player;
893
894     MediaPlayerEnums::Preload m_preload { MediaPlayer::Auto };
895
896     DisplayMode m_displayMode { Unknown };
897
898     // Counter incremented while processing a callback from the media player, so we can avoid
899     // calling the media engine recursively.
900     int m_processingMediaPlayerCallback { 0 };
901
902 #if ENABLE(MEDIA_SESSION)
903     String m_kind;
904     RefPtr<MediaSession> m_session;
905     bool m_shouldDuck { false };
906     uint64_t m_elementID;
907 #endif
908
909 #if ENABLE(MEDIA_SOURCE)
910     RefPtr<MediaSource> m_mediaSource;
911     unsigned m_droppedVideoFrames { 0 };
912 #endif
913
914     mutable MediaTime m_cachedTime;
915     mutable double m_clockTimeAtLastCachedTimeUpdate { 0 };
916     mutable double m_minimumClockTimeToUpdateCachedTime { 0 };
917
918     MediaTime m_fragmentStartTime;
919     MediaTime m_fragmentEndTime;
920
921     using PendingActionFlags = unsigned;
922     PendingActionFlags m_pendingActionFlags { 0 };
923
924     enum ActionAfterScanType { Nothing, Play, Pause };
925     ActionAfterScanType m_actionAfterScan { Nothing };
926
927     enum ScanType { Seek, Scan };
928     ScanType m_scanType { Scan };
929     ScanDirection m_scanDirection { Forward };
930
931     bool m_firstTimePlaying : 1;
932     bool m_playing : 1;
933     bool m_isWaitingUntilMediaCanStart : 1;
934     bool m_shouldDelayLoadEvent : 1;
935     bool m_haveFiredLoadedData : 1;
936     bool m_inActiveDocument : 1;
937     bool m_autoplaying : 1;
938     bool m_muted : 1;
939     bool m_explicitlyMuted : 1;
940     bool m_initiallyMuted : 1;
941     bool m_paused : 1;
942     bool m_seeking : 1;
943
944     // data has not been loaded since sending a "stalled" event
945     bool m_sentStalledEvent : 1;
946
947     // time has not changed since sending an "ended" event
948     bool m_sentEndEvent : 1;
949
950     bool m_pausedInternal : 1;
951
952     // Not all media engines provide enough information about a file to be able to
953     // support progress events so setting m_sendProgressEvents disables them 
954     bool m_sendProgressEvents : 1;
955
956     bool m_closedCaptionsVisible : 1;
957     bool m_webkitLegacyClosedCaptionOverride : 1;
958     bool m_completelyLoaded : 1;
959     bool m_havePreparedToPlay : 1;
960     bool m_parsingInProgress : 1;
961     bool m_elementIsHidden : 1;
962     bool m_creatingControls : 1;
963     bool m_receivedLayoutSizeChanged : 1;
964     bool m_hasEverNotifiedAboutPlaying : 1;
965     bool m_preventedFromPlayingWithoutUserGesture : 1;
966
967     bool m_hasEverHadAudio : 1;
968     bool m_hasEverHadVideo : 1;
969
970 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
971     bool m_mediaControlsDependOnPageScaleFactor : 1;
972     bool m_haveSetUpCaptionContainer : 1;
973 #endif
974
975     bool m_isScrubbingRemotely : 1;
976
977 #if ENABLE(VIDEO_TRACK)
978     bool m_tracksAreReady : 1;
979     bool m_haveVisibleTextTrack : 1;
980     bool m_processingPreferenceChange : 1;
981
982     String m_subtitleTrackLanguage;
983     MediaTime m_lastTextTrackUpdateTime { -1, 1 };
984
985     CaptionUserPreferences::CaptionDisplayMode m_captionDisplayMode { CaptionUserPreferences::Automatic };
986
987     RefPtr<AudioTrackList> m_audioTracks;
988     RefPtr<TextTrackList> m_textTracks;
989     RefPtr<VideoTrackList> m_videoTracks;
990     Vector<RefPtr<TextTrack>> m_textTracksWhenResourceSelectionBegan;
991
992     CueIntervalTree m_cueTree;
993
994     CueList m_currentlyActiveCues;
995     int m_ignoreTrackDisplayUpdate { 0 };
996
997     bool m_requireCaptionPreferencesChangedCallbacks { false };
998 #endif
999
1000 #if ENABLE(WEB_AUDIO)
1001     // This is a weak reference, since m_audioSourceNode holds a reference to us.
1002     // The value is set just after the MediaElementAudioSourceNode is created.
1003     // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
1004     MediaElementAudioSourceNode* m_audioSourceNode { nullptr };
1005 #endif
1006
1007     String m_mediaGroup;
1008     friend class MediaController;
1009     RefPtr<MediaController> m_mediaController;
1010
1011     std::unique_ptr<DisplaySleepDisabler> m_sleepDisabler;
1012
1013     friend class TrackDisplayUpdateScope;
1014
1015 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
1016     RefPtr<WebKitMediaKeys> m_mediaKeys;
1017 #endif
1018
1019     std::unique_ptr<MediaElementSession> m_mediaSession;
1020     size_t m_reportedExtraMemoryCost { 0 };
1021
1022 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1023     friend class MediaControlsHost;
1024     RefPtr<MediaControlsHost> m_mediaControlsHost;
1025     RefPtr<DOMWrapperWorld> m_isolatedWorld;
1026 #endif
1027
1028 #if ENABLE(MEDIA_STREAM)
1029     RefPtr<MediaStream> m_mediaStreamSrcObject;
1030     bool m_settingMediaStreamSrcObject { false };
1031 #endif
1032
1033 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
1034     MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
1035     bool m_hasPlaybackTargetAvailabilityListeners { false };
1036     bool m_failedToPlayToWirelessTarget { false };
1037     bool m_isPlayingToWirelessTarget { false };
1038 #endif
1039 };
1040
1041 #if ENABLE(VIDEO_TRACK) && !defined(NDEBUG)
1042
1043 // Template specialization required by PodIntervalTree in debug mode.
1044 template <> struct ValueToString<TextTrackCue*> {
1045     static String string(TextTrackCue* const& cue)
1046     {
1047         String text;
1048         if (cue->isRenderable())
1049             text = toVTTCue(cue)->text();
1050         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());
1051     }
1052 };
1053
1054 #endif
1055
1056 #ifndef NDEBUG
1057
1058 template<> struct ValueToString<MediaTime> {
1059     static String string(const MediaTime& time)
1060     {
1061         return toString(time);
1062     }
1063 };
1064
1065 #endif
1066
1067 } // namespace WebCore
1068
1069 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLMediaElement)
1070     static bool isType(const WebCore::Element& element) { return element.isMediaElement(); }
1071     static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
1072 SPECIALIZE_TYPE_TRAITS_END()
1073
1074 #endif