• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 COMPUTER, 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 COMPUTER, 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 #ifndef HTMLMediaElement_h
27 #define HTMLMediaElement_h
28 
29 #include "core/dom/ActiveDOMObject.h"
30 #include "core/events/GenericEventQueue.h"
31 #include "core/html/HTMLElement.h"
32 #include "core/html/MediaControllerInterface.h"
33 #include "core/html/track/TextTrack.h"
34 #include "core/html/track/TextTrackCue.h"
35 #include "core/html/track/vtt/VTTCue.h"
36 #include "platform/PODIntervalTree.h"
37 #include "platform/graphics/media/MediaPlayer.h"
38 #include "public/platform/WebMimeRegistry.h"
39 
40 namespace blink {
41 class WebInbandTextTrack;
42 class WebLayer;
43 }
44 
45 namespace WebCore {
46 
47 #if ENABLE(WEB_AUDIO)
48 class AudioSourceProvider;
49 class MediaElementAudioSourceNode;
50 #endif
51 class ContentType;
52 class Event;
53 class ExceptionState;
54 class HTMLSourceElement;
55 class HTMLTrackElement;
56 class KURL;
57 class MediaController;
58 class MediaControls;
59 class MediaError;
60 class MediaKeys;
61 class HTMLMediaSource;
62 class TextTrackList;
63 class TimeRanges;
64 
65 typedef PODIntervalTree<double, TextTrackCue*> CueIntervalTree;
66 typedef CueIntervalTree::IntervalType CueInterval;
67 typedef Vector<CueInterval> CueList;
68 
69 // FIXME: The inheritance from MediaPlayerClient here should be private inheritance.
70 // But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
71 // no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
72 
73 class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, public ActiveDOMObject, public MediaControllerInterface
74     , private TextTrackClient
75 {
76 public:
77     static blink::WebMimeRegistry::SupportsType supportsType(const ContentType&, const String& keySystem = String());
78 
player()79     MediaPlayer* player() const { return m_player.get(); }
80 
81     virtual bool isVideo() const = 0;
hasVideo()82     virtual bool hasVideo() const OVERRIDE { return false; }
83     virtual bool hasAudio() const OVERRIDE;
84 
85     // Eventually overloaded in HTMLVideoElement
supportsFullscreen()86     virtual bool supportsFullscreen() const OVERRIDE { return false; };
87 
88     bool supportsSave() const;
89 
90     blink::WebLayer* platformLayer() const;
91 
92     enum DelayedActionType {
93         LoadMediaResource = 1 << 0,
94         LoadTextTrackResource = 1 << 1,
95         TextTrackChangesNotification = 1 << 2
96     };
97     void scheduleDelayedAction(DelayedActionType);
98 
isActive()99     bool isActive() const { return m_active; }
100 
101     // error state
102     PassRefPtr<MediaError> error() const;
103 
104     // network state
105     void setSrc(const AtomicString&);
currentSrc()106     const KURL& currentSrc() const { return m_currentSrc; }
107 
108     enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
109     NetworkState networkState() const;
110 
111     String preload() const;
112     void setPreload(const String&);
113 
114     PassRefPtr<TimeRanges> buffered() const;
115     void load();
116     String canPlayType(const String& mimeType, const String& keySystem = String(), const KURL& = KURL()) const;
117 
118     // ready state
119     ReadyState readyState() const;
120     bool seeking() const;
121 
122     // playback state
123     double currentTime() const;
124     void setCurrentTime(double, ExceptionState&);
125     double duration() const;
126     bool paused() const;
127     double defaultPlaybackRate() const;
128     void setDefaultPlaybackRate(double);
129     double playbackRate() const;
130     void setPlaybackRate(double);
131     void updatePlaybackRate();
132     PassRefPtr<TimeRanges> played();
133     PassRefPtr<TimeRanges> seekable() const;
134     bool ended() const;
135     bool autoplay() const;
136     bool loop() const;
137     void setLoop(bool b);
138     void play();
139     void pause();
140 
141     // statistics
142     unsigned webkitAudioDecodedByteCount() const;
143     unsigned webkitVideoDecodedByteCount() const;
144 
145     // media source extensions
146     void closeMediaSource();
147     void durationChanged(double duration);
148 
149     // encrypted media extensions
150     void webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState&);
151     void webkitGenerateKeyRequest(const String& keySystem, ExceptionState&);
152     void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState&);
153     void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionState&);
154     void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionState&);
155 
156     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyadded);
157     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyerror);
158     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeymessage);
159     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitneedkey);
160 
mediaKeys()161     MediaKeys* mediaKeys() const { return m_mediaKeys.get(); }
162     void setMediaKeys(MediaKeys*);
163 
164     // controls
165     bool controls() const;
166     void setControls(bool);
167     double volume() const;
168     void setVolume(double, ExceptionState&);
169     bool muted() const;
170     void setMuted(bool);
171 
172     void togglePlayState();
173     void beginScrubbing();
174     void endScrubbing();
175 
176     bool canPlay() const;
177 
178     double percentLoaded() const;
179 
180     PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, const String& language, ExceptionState&);
addTextTrack(const String & kind,const String & label,ExceptionState & exceptionState)181     PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, ExceptionState& exceptionState) { return addTextTrack(kind, label, emptyString(), exceptionState); }
addTextTrack(const String & kind,ExceptionState & exceptionState)182     PassRefPtr<TextTrack> addTextTrack(const String& kind, ExceptionState& exceptionState) { return addTextTrack(kind, emptyString(), emptyString(), exceptionState); }
183 
184     TextTrackList* textTracks();
currentlyActiveCues()185     CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
186 
187     void addTrack(TextTrack*);
188     void removeTrack(TextTrack*);
189     void removeAllInbandTracks();
190     void closeCaptionTracksChanged();
191     void notifyMediaPlayerOfTextTrackChanges();
192 
193     void didAddTrack(HTMLTrackElement*);
194     void didRemoveTrack(HTMLTrackElement*);
195 
196     virtual void mediaPlayerDidAddTrack(blink::WebInbandTextTrack*) OVERRIDE;
197     virtual void mediaPlayerDidRemoveTrack(blink::WebInbandTextTrack*) OVERRIDE;
198 
199     struct TrackGroup {
200         enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other };
201 
TrackGroupTrackGroup202         TrackGroup(GroupKind kind)
203             : visibleTrack(0)
204             , defaultTrack(0)
205             , kind(kind)
206             , hasSrcLang(false)
207         {
208         }
209 
210         Vector<RefPtr<TextTrack> > tracks;
211         RefPtr<TextTrack> visibleTrack;
212         RefPtr<TextTrack> defaultTrack;
213         GroupKind kind;
214         bool hasSrcLang;
215     };
216 
217     void configureTextTrackGroupForLanguage(const TrackGroup&) const;
218     void configureTextTracks();
219     void configureTextTrackGroup(const TrackGroup&);
220 
221     bool textTracksAreReady() const;
222     enum VisibilityChangeAssumption {
223         AssumeNoVisibleChange,
224         AssumeVisibleChange
225     };
226     void configureTextTrackDisplay(VisibilityChangeAssumption);
227     void updateTextTrackDisplay();
228     void textTrackReadyStateChanged(TextTrack*);
229 
230     // TextTrackClient
231     virtual void textTrackKindChanged(TextTrack*) OVERRIDE;
232     virtual void textTrackModeChanged(TextTrack*) OVERRIDE;
233     virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
234     virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
235     virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
236     virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
237 
238     // EventTarget function.
239     // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
240     // causes an ambiguity error at compile time. This class's constructor
241     // ensures that both implementations return document, so return the result
242     // of one of them here.
executionContext()243     virtual ExecutionContext* executionContext() const OVERRIDE { return HTMLElement::executionContext(); }
244 
hasSingleSecurityOrigin()245     bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
246 
247     bool isFullscreen() const;
248     void enterFullscreen();
249     void exitFullscreen();
250 
251     bool hasClosedCaptions() const;
252     bool closedCaptionsVisible() const;
253     void setClosedCaptionsVisible(bool);
254 
255     MediaControls* mediaControls() const;
256 
257     void sourceWasRemoved(HTMLSourceElement*);
258     void sourceWasAdded(HTMLSourceElement*);
259 
isPlaying()260     bool isPlaying() const { return m_playing; }
261 
262     // ActiveDOMObject functions.
263     virtual bool hasPendingActivity() const OVERRIDE;
264     virtual void contextDestroyed() OVERRIDE;
265 
266 #if ENABLE(WEB_AUDIO)
audioSourceNode()267     MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
268     void setAudioSourceNode(MediaElementAudioSourceNode*);
269 
270     AudioSourceProvider* audioSourceProvider();
271 #endif
272 
273     enum InvalidURLAction { DoNothing, Complain };
274     bool isSafeToLoadURL(const KURL&, InvalidURLAction);
275 
276     MediaController* controller() const;
277     void setController(PassRefPtr<MediaController>); // Resets the MediaGroup and sets the MediaController.
278 
279 protected:
280     HTMLMediaElement(const QualifiedName&, Document&, bool);
281     virtual ~HTMLMediaElement();
282 
283     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
284     virtual void finishParsingChildren() OVERRIDE;
285     virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
286     virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
287 
288     virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
289 
290     enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
displayMode()291     DisplayMode displayMode() const { return m_displayMode; }
setDisplayMode(DisplayMode mode)292     virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
293 
isMediaElement()294     virtual bool isMediaElement() const OVERRIDE { return true; }
295 
296     void setControllerInternal(PassRefPtr<MediaController>);
297 
298     // Restrictions to change default behaviors.
299     enum BehaviorRestrictionFlags {
300         NoRestrictions = 0,
301         RequireUserGestureForLoadRestriction = 1 << 0,
302         RequireUserGestureForRateChangeRestriction = 1 << 1,
303         RequireUserGestureForFullscreenRestriction = 1 << 2,
304         RequirePageConsentToLoadMediaRestriction = 1 << 3,
305     };
306     typedef unsigned BehaviorRestrictions;
307 
userGestureRequiredForLoad()308     bool userGestureRequiredForLoad() const { return m_restrictions & RequireUserGestureForLoadRestriction; }
userGestureRequiredForRateChange()309     bool userGestureRequiredForRateChange() const { return m_restrictions & RequireUserGestureForRateChangeRestriction; }
userGestureRequiredForFullscreen()310     bool userGestureRequiredForFullscreen() const { return m_restrictions & RequireUserGestureForFullscreenRestriction; }
pageConsentRequiredForLoad()311     bool pageConsentRequiredForLoad() const { return m_restrictions & RequirePageConsentToLoadMediaRestriction; }
312 
addBehaviorRestriction(BehaviorRestrictions restriction)313     void addBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions |= restriction; }
removeBehaviorRestriction(BehaviorRestrictions restriction)314     void removeBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions &= ~restriction; }
315 
ignoreTrackDisplayUpdateRequests()316     bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0; }
317     void beginIgnoringTrackDisplayUpdateRequests();
318     void endIgnoringTrackDisplayUpdateRequests();
319 
320 private:
321     void createMediaPlayer();
322 
alwaysCreateUserAgentShadowRoot()323     virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE { return true; }
areAuthorShadowsAllowed()324     virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
325 
326     virtual bool hasCustomFocusLogic() const OVERRIDE;
327     virtual bool supportsFocus() const OVERRIDE;
328     virtual bool isMouseFocusable() const OVERRIDE;
329     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
330     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
331     virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
332     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
333     virtual void removedFrom(ContainerNode*) OVERRIDE;
334     virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
335 
336     virtual void didBecomeFullscreenElement() OVERRIDE;
337     virtual void willStopBeingFullscreenElement() OVERRIDE;
338     virtual bool isInteractiveContent() const OVERRIDE;
339 
340     // ActiveDOMObject functions.
341     virtual void stop() OVERRIDE;
342 
updateDisplayState()343     virtual void updateDisplayState() { }
344 
345     void setReadyState(MediaPlayer::ReadyState);
346     void setNetworkState(MediaPlayer::NetworkState);
347 
348     virtual void mediaPlayerNetworkStateChanged() OVERRIDE;
349     virtual void mediaPlayerReadyStateChanged() OVERRIDE;
350     virtual void mediaPlayerTimeChanged() OVERRIDE;
351     virtual void mediaPlayerDurationChanged() OVERRIDE;
352     virtual void mediaPlayerPlaybackStateChanged() OVERRIDE;
353     virtual void mediaPlayerRequestFullscreen() OVERRIDE;
354     virtual void mediaPlayerRequestSeek(double) OVERRIDE;
355     virtual void mediaPlayerRepaint() OVERRIDE;
356     virtual void mediaPlayerSizeChanged() OVERRIDE;
357 
358     virtual void mediaPlayerKeyAdded(const String& keySystem, const String& sessionId) OVERRIDE;
359     virtual void mediaPlayerKeyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode) OVERRIDE;
360     virtual void mediaPlayerKeyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL) OVERRIDE;
361     virtual bool mediaPlayerKeyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) OVERRIDE;
362     virtual bool mediaPlayerKeyNeeded(Uint8Array*) OVERRIDE;
363 
364     virtual CORSMode mediaPlayerCORSMode() const OVERRIDE;
365 
366     virtual void mediaPlayerSetWebLayer(blink::WebLayer*) OVERRIDE;
367     virtual void mediaPlayerSetOpaque(bool) OVERRIDE;
368 
369     void loadTimerFired(Timer<HTMLMediaElement>*);
370     void progressEventTimerFired(Timer<HTMLMediaElement>*);
371     void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
372     void startPlaybackProgressTimer();
373     void startProgressEventTimer();
374     void stopPeriodicTimers();
375 
376     void seek(double time, ExceptionState&);
377     void finishSeek();
378     void checkIfSeekNeeded();
379     void addPlayedRange(double start, double end);
380 
381     void scheduleTimeupdateEvent(bool periodicEvent);
382     void scheduleEvent(const AtomicString& eventName);
383 
384     // loading
385     void selectMediaResource();
386     void loadResource(const KURL&, ContentType&, const String& keySystem);
387     void scheduleNextSourceChild();
388     void loadNextSourceChild();
389     void userCancelledLoad();
390     void clearMediaPlayer(int flags);
391     void clearMediaPlayerAndAudioSourceProviderClient();
392     bool havePotentialSourceChild();
393     void noneSupported();
394     void mediaEngineError(PassRefPtr<MediaError> err);
395     void cancelPendingEventsAndCallbacks();
396     void waitForSourceChange();
397     void prepareToPlay();
398 
399     KURL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction);
400 
401     void mediaLoadingFailed(MediaPlayer::NetworkState);
402 
403     void updateActiveTextTrackCues(double);
404     HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
405 
406     void markCaptionAndSubtitleTracksAsUnconfigured();
407 
408     // These "internal" functions do not check user gesture restrictions.
409     void loadInternal();
410     void playInternal();
411     void pauseInternal();
412 
413     void prepareForLoad();
414     void allowVideoRendering();
415 
416     void updateVolume();
417     void updatePlayState();
418     bool potentiallyPlaying() const;
419     bool endedPlayback() const;
420     bool stoppedDueToErrors() const;
421     bool pausedForUserInteraction() const;
422     bool couldPlayIfEnoughData() const;
423 
424     // Pauses playback without changing any states or generating events
425     void setPausedInternal(bool);
426 
427     void setPlaybackRateInternal(double);
428 
429     void setShouldDelayLoadEvent(bool);
430     void invalidateCachedTime();
431     void refreshCachedTime() const;
432 
433     bool hasMediaControls() const;
434     bool createMediaControls();
435     void configureMediaControls();
436 
437     void prepareMediaFragmentURI();
438     void applyMediaFragmentURI();
439 
440     virtual void* preDispatchEventHandler(Event*) OVERRIDE;
441 
442     void changeNetworkStateFromLoadingToIdle();
443 
444     void removeBehaviorsRestrictionsAfterFirstUserGesture();
445 
446     const AtomicString& mediaGroup() const;
447     void setMediaGroup(const AtomicString&);
448     void updateMediaController();
449     bool isBlocked() const;
450     bool isBlockedOnMediaController() const;
hasCurrentSrc()451     bool hasCurrentSrc() const { return !m_currentSrc.isEmpty(); }
isAutoplaying()452     bool isAutoplaying() const { return m_autoplaying; }
453 
454     Timer<HTMLMediaElement> m_loadTimer;
455     Timer<HTMLMediaElement> m_progressEventTimer;
456     Timer<HTMLMediaElement> m_playbackProgressTimer;
457     RefPtr<TimeRanges> m_playedTimeRanges;
458     OwnPtr<GenericEventQueue> m_asyncEventQueue;
459 
460     double m_playbackRate;
461     double m_defaultPlaybackRate;
462     NetworkState m_networkState;
463     ReadyState m_readyState;
464     ReadyState m_readyStateMaximum;
465     KURL m_currentSrc;
466 
467     RefPtr<MediaError> m_error;
468 
469     double m_volume;
470     double m_lastSeekTime;
471 
472     unsigned m_previousProgress;
473     double m_previousProgressTime;
474 
475     // Cached duration to suppress duplicate events if duration unchanged.
476     double m_duration;
477 
478     // The last time a timeupdate event was sent (wall clock).
479     double m_lastTimeUpdateEventWallTime;
480 
481     // The last time a timeupdate event was sent in movie time.
482     double m_lastTimeUpdateEventMovieTime;
483 
484     // Loading state.
485     enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
486     LoadState m_loadState;
487     RefPtr<HTMLSourceElement> m_currentSourceNode;
488     RefPtr<Node> m_nextChildNodeToConsider;
489 
490     OwnPtr<MediaPlayer> m_player;
491     blink::WebLayer* m_webLayer;
492     bool m_opaque;
493 
494     BehaviorRestrictions m_restrictions;
495 
496     MediaPlayer::Preload m_preload;
497 
498     DisplayMode m_displayMode;
499 
500     RefPtr<HTMLMediaSource> m_mediaSource;
501 
502     mutable double m_cachedTime;
503     mutable double m_cachedTimeWallClockUpdateTime;
504     mutable double m_minimumWallClockTimeToCacheMediaTime;
505 
506     double m_fragmentStartTime;
507     double m_fragmentEndTime;
508 
509     typedef unsigned PendingActionFlags;
510     PendingActionFlags m_pendingActionFlags;
511 
512     // FIXME: MediaElement has way too many state bits.
513     bool m_playing : 1;
514     bool m_shouldDelayLoadEvent : 1;
515     bool m_haveFiredLoadedData : 1;
516     bool m_active : 1;
517     bool m_autoplaying : 1;
518     bool m_muted : 1;
519     bool m_paused : 1;
520     bool m_seeking : 1;
521 
522     // data has not been loaded since sending a "stalled" event
523     bool m_sentStalledEvent : 1;
524 
525     // time has not changed since sending an "ended" event
526     bool m_sentEndEvent : 1;
527 
528     bool m_pausedInternal : 1;
529 
530     bool m_closedCaptionsVisible : 1;
531 
532     bool m_loadInitiatedByUserGesture : 1;
533     bool m_completelyLoaded : 1;
534     bool m_havePreparedToPlay : 1;
535     bool m_parsingInProgress : 1;
536 
537     bool m_tracksAreReady : 1;
538     bool m_haveVisibleTextTrack : 1;
539     bool m_processingPreferenceChange : 1;
540     double m_lastTextTrackUpdateTime;
541 
542     RefPtr<TextTrackList> m_textTracks;
543     Vector<RefPtr<TextTrack> > m_textTracksWhenResourceSelectionBegan;
544 
545     CueIntervalTree m_cueTree;
546 
547     CueList m_currentlyActiveCues;
548     int m_ignoreTrackDisplayUpdate;
549 
550 #if ENABLE(WEB_AUDIO)
551     // This is a weak reference, since m_audioSourceNode holds a reference to us.
552     // The value is set just after the MediaElementAudioSourceNode is created.
553     // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
554     MediaElementAudioSourceNode* m_audioSourceNode;
555 #endif
556 
557     friend class MediaController;
558     RefPtr<MediaController> m_mediaController;
559 
560     friend class TrackDisplayUpdateScope;
561 
562     RefPtr<MediaKeys> m_mediaKeys;
563 };
564 
565 #ifndef NDEBUG
566 // Template specializations required by PodIntervalTree in debug mode.
567 template <>
568 struct ValueToString<double> {
569     static String string(const double value)
570     {
571         return String::number(value);
572     }
573 };
574 
575 template <>
576 struct ValueToString<TextTrackCue*> {
577     static String string(TextTrackCue* const& cue)
578     {
579         return cue->toString();
580     }
581 };
582 #endif
583 
584 inline bool isHTMLMediaElement(Node* node)
585 {
586     return node && node->isElementNode() && toElement(node)->isMediaElement();
587 }
588 
589 inline bool isHTMLMediaElement(const Node& node)
590 {
591     return node.isElementNode() && toElement(node).isMediaElement();
592 }
593 
594 DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement);
595 
596 } //namespace
597 
598 #endif
599