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