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