• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008, 2009, 2010 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 #if ENABLE(VIDEO)
30 
31 #include "HTMLElement.h"
32 #include "ActiveDOMObject.h"
33 #include "MediaCanStartListener.h"
34 #include "MediaPlayer.h"
35 
36 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
37 #include "MediaPlayerProxy.h"
38 #endif
39 
40 namespace WebCore {
41 
42 class Event;
43 class HTMLSourceElement;
44 class MediaControls;
45 class MediaError;
46 class KURL;
47 class TimeRanges;
48 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
49 class Widget;
50 #endif
51 
52 // FIXME: The inheritance from MediaPlayerClient here should be private inheritance.
53 // But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
54 // no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
55 
56 class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, private MediaCanStartListener, private ActiveDOMObject {
57 public:
player()58     MediaPlayer* player() const { return m_player.get(); }
59 
60     virtual bool isVideo() const = 0;
hasVideo()61     virtual bool hasVideo() const { return false; }
62     virtual bool hasAudio() const;
63 
64     void rewind(float timeDelta);
65     void returnToRealtime();
66 
67     // Eventually overloaded in HTMLVideoElement
supportsFullscreen()68     virtual bool supportsFullscreen() const { return false; };
69 
70     virtual bool supportsSave() const;
71 
72     PlatformMedia platformMedia() const;
73 #if USE(ACCELERATED_COMPOSITING)
74     PlatformLayer* platformLayer() const;
75 #endif
76 
77     void scheduleLoad();
78 
79     MediaPlayer::MovieLoadType movieLoadType() const;
80 
inActiveDocument()81     bool inActiveDocument() const { return m_inActiveDocument; }
82 
83 // DOM API
84 // error state
85     PassRefPtr<MediaError> error() const;
86 
87 // network state
88     void setSrc(const String&);
89     String currentSrc() const;
90 
91     enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
92     NetworkState networkState() const;
93 
94     String preload() const;
95     void setPreload(const String&);
96 
97     PassRefPtr<TimeRanges> buffered() const;
98     void load(bool isUserGesture, ExceptionCode&);
99     String canPlayType(const String& mimeType) const;
100 
101 // ready state
102     enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
103     ReadyState readyState() const;
104     bool seeking() const;
105 
106 // playback state
107     float currentTime() const;
108     void setCurrentTime(float, ExceptionCode&);
109     float startTime() const;
110     float duration() const;
111     bool paused() const;
112     float defaultPlaybackRate() const;
113     void setDefaultPlaybackRate(float);
114     float playbackRate() const;
115     void setPlaybackRate(float);
116     bool webkitPreservesPitch() const;
117     void setWebkitPreservesPitch(bool);
118     PassRefPtr<TimeRanges> played();
119     PassRefPtr<TimeRanges> seekable() const;
120     bool ended() const;
121     bool autoplay() const;
122     void setAutoplay(bool b);
123     bool loop() const;
124     void setLoop(bool b);
125     void play(bool isUserGesture);
126     void pause(bool isUserGesture);
127 
128 // captions
129     bool webkitHasClosedCaptions() const;
130     bool webkitClosedCaptionsVisible() const;
131     void setWebkitClosedCaptionsVisible(bool);
132 
133 #if ENABLE(MEDIA_STATISTICS)
134 // Statistics
135     unsigned webkitAudioDecodedByteCount() const;
136     unsigned webkitVideoDecodedByteCount() const;
137 #endif
138 
139 // controls
140     bool controls() const;
141     void setControls(bool);
142     float volume() const;
143     void setVolume(float, ExceptionCode&);
144     bool muted() const;
145     void setMuted(bool);
146     void togglePlayState();
147     void beginScrubbing();
148     void endScrubbing();
149 
150     bool canPlay() const;
151 
152     float percentLoaded() const;
153 
154 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
155     void allocateMediaPlayerIfNecessary();
setNeedWidgetUpdate(bool needWidgetUpdate)156     void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
157     void deliverNotification(MediaPlayerProxyNotificationType notification);
158     void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
159     void getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values);
160     virtual void finishParsingChildren();
161     void createMediaPlayerProxy();
162     void updateWidget(PluginCreationOption);
163 #endif
164 
hasSingleSecurityOrigin()165     bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
166 
167     bool isFullscreen() const;
168     void enterFullscreen();
169     void exitFullscreen();
170 
171     bool hasClosedCaptions() const;
172     bool closedCaptionsVisible() const;
173     void setClosedCaptionsVisible(bool);
174 
175     MediaControls* mediaControls();
176 
177     bool processingUserGesture() const;
178 
179     void sourceWillBeRemoved(HTMLSourceElement*);
180     void sourceWasAdded(HTMLSourceElement*);
181 
182     void privateBrowsingStateDidChange();
183 
184     // Restrictions to change default behaviors.
185     enum BehaviorRestrictionFlags {
186         NoRestrictions = 0,
187         RequireUserGestureForLoadRestriction = 1 << 0,
188         RequireUserGestureForRateChangeRestriction = 1 << 1,
189         RequireUserGestureForFullScreenRestriction = 1 << 2
190     };
191     typedef unsigned BehaviorRestrictions;
192 
requireUserGestureForLoad()193     bool requireUserGestureForLoad() const { return m_restrictions & RequireUserGestureForLoadRestriction; }
requireUserGestureForRateChange()194     bool requireUserGestureForRateChange() const { return m_restrictions & RequireUserGestureForRateChangeRestriction; }
requireUserGestureForFullScreen()195     bool requireUserGestureForFullScreen() const { return m_restrictions & RequireUserGestureForFullScreenRestriction; }
196 
setBehaviorRestrictions(BehaviorRestrictions restrictions)197     void setBehaviorRestrictions(BehaviorRestrictions restrictions) { m_restrictions = restrictions; }
198 
199     // Media cache management.
200     static void getSitesInMediaCache(Vector<String>&);
201     static void clearMediaCache();
202     static void clearMediaCacheForSite(const String&);
203 
204 protected:
205     HTMLMediaElement(const QualifiedName&, Document*);
206     virtual ~HTMLMediaElement();
207 
208     virtual void parseMappedAttribute(Attribute*);
209     virtual bool isURLAttribute(Attribute*) const;
210     virtual void attach();
211 
212     virtual void willMoveToNewOwnerDocument();
213     virtual void didMoveToNewOwnerDocument();
214 
215     enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
displayMode()216     DisplayMode displayMode() const { return m_displayMode; }
setDisplayMode(DisplayMode mode)217     virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
218 
219 private:
220     virtual void attributeChanged(Attribute*, bool preserveDecls);
221     virtual bool rendererIsNeeded(RenderStyle*);
222     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
223     virtual void insertedIntoDocument();
224     virtual void removedFromDocument();
225     virtual void recalcStyle(StyleChange);
226 
227     virtual void defaultEventHandler(Event*);
228 
229     // ActiveDOMObject functions.
230     virtual bool canSuspend() const;
231     virtual void suspend(ReasonForSuspension);
232     virtual void resume();
233     virtual void stop();
234     virtual bool hasPendingActivity() const;
235 
236     virtual void mediaVolumeDidChange();
237 
updateDisplayState()238     virtual void updateDisplayState() { }
239 
240     void setReadyState(MediaPlayer::ReadyState);
241     void setNetworkState(MediaPlayer::NetworkState);
242 
243     virtual Document* mediaPlayerOwningDocument();
244     virtual void mediaPlayerNetworkStateChanged(MediaPlayer*);
245     virtual void mediaPlayerReadyStateChanged(MediaPlayer*);
246     virtual void mediaPlayerTimeChanged(MediaPlayer*);
247     virtual void mediaPlayerVolumeChanged(MediaPlayer*);
248     virtual void mediaPlayerMuteChanged(MediaPlayer*);
249     virtual void mediaPlayerDurationChanged(MediaPlayer*);
250     virtual void mediaPlayerRateChanged(MediaPlayer*);
251     virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*);
252     virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
253     virtual void mediaPlayerRepaint(MediaPlayer*);
254     virtual void mediaPlayerSizeChanged(MediaPlayer*);
255 #if USE(ACCELERATED_COMPOSITING)
256     virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*);
257     virtual void mediaPlayerRenderingModeChanged(MediaPlayer*);
258 #endif
259     virtual void mediaPlayerEngineUpdated(MediaPlayer*);
260     virtual void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*);
261 
262     void loadTimerFired(Timer<HTMLMediaElement>*);
263     void asyncEventTimerFired(Timer<HTMLMediaElement>*);
264     void progressEventTimerFired(Timer<HTMLMediaElement>*);
265     void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
266     void startPlaybackProgressTimer();
267     void startProgressEventTimer();
268     void stopPeriodicTimers();
269 
270     void seek(float time, ExceptionCode&);
271     void finishSeek();
272     void checkIfSeekNeeded();
273     void addPlayedRange(float start, float end);
274 
275     void scheduleTimeupdateEvent(bool periodicEvent);
276     void scheduleEvent(const AtomicString& eventName);
277 
278     // loading
279     void selectMediaResource();
280     void loadResource(const KURL&, ContentType&);
281     void scheduleNextSourceChild();
282     void loadNextSourceChild();
283     void userCancelledLoad();
284     bool havePotentialSourceChild();
285     void noneSupported();
286     void mediaEngineError(PassRefPtr<MediaError> err);
287     void cancelPendingEventsAndCallbacks();
288     void waitForSourceChange();
289 
290     enum InvalidSourceAction { DoNothing, Complain };
291     bool isSafeToLoadURL(const KURL&, InvalidSourceAction);
292     KURL selectNextSourceChild(ContentType*, InvalidSourceAction);
293 
294     // These "internal" functions do not check user gesture restrictions.
295     void loadInternal();
296     void playInternal();
297     void pauseInternal();
298 
299     void prepareForLoad();
300     void allowVideoRendering();
301 
processingMediaPlayerCallback()302     bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
beginProcessingMediaPlayerCallback()303     void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
endProcessingMediaPlayerCallback()304     void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
305 
306     void updateVolume();
307     void updatePlayState();
308     bool potentiallyPlaying() const;
309     bool endedPlayback() const;
310     bool stoppedDueToErrors() const;
311     bool pausedForUserInteraction() const;
312     bool couldPlayIfEnoughData() const;
313 
314     float minTimeSeekable() const;
315     float maxTimeSeekable() const;
316 
317     // Pauses playback without changing any states or generating events
318     void setPausedInternal(bool);
319 
320     virtual void mediaCanStart();
321 
322     void setShouldDelayLoadEvent(bool);
323 
324     void invalidateCachedTime();
325     void refreshCachedTime() const;
326 
327     bool hasMediaControls();
328     bool createMediaControls();
329 
330     virtual void* preDispatchEventHandler(Event*);
331 
332     Timer<HTMLMediaElement> m_loadTimer;
333     Timer<HTMLMediaElement> m_asyncEventTimer;
334     Timer<HTMLMediaElement> m_progressEventTimer;
335     Timer<HTMLMediaElement> m_playbackProgressTimer;
336     Vector<RefPtr<Event> > m_pendingEvents;
337     RefPtr<TimeRanges> m_playedTimeRanges;
338 
339     float m_playbackRate;
340     float m_defaultPlaybackRate;
341     bool m_webkitPreservesPitch;
342     NetworkState m_networkState;
343     ReadyState m_readyState;
344     ReadyState m_readyStateMaximum;
345     String m_currentSrc;
346 
347     RefPtr<MediaError> m_error;
348 
349     float m_volume;
350     float m_lastSeekTime;
351 
352     unsigned m_previousProgress;
353     double m_previousProgressTime;
354 
355     // the last time a timeupdate event was sent (wall clock)
356     double m_lastTimeUpdateEventWallTime;
357 
358     // the last time a timeupdate event was sent in movie time
359     float m_lastTimeUpdateEventMovieTime;
360 
361     // loading state
362     enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
363     LoadState m_loadState;
364     HTMLSourceElement* m_currentSourceNode;
365     Node* m_nextChildNodeToConsider;
sourceChildEndOfListValue()366     Node* sourceChildEndOfListValue() { return static_cast<Node*>(this); }
367 
368     OwnPtr<MediaPlayer> m_player;
369 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
370     RefPtr<Widget> m_proxyWidget;
371 #endif
372 
373     BehaviorRestrictions m_restrictions;
374 
375     MediaPlayer::Preload m_preload;
376 
377     DisplayMode m_displayMode;
378 
379     // Counter incremented while processing a callback from the media player, so we can avoid
380     // calling the media engine recursively.
381     int m_processingMediaPlayerCallback;
382 
383     mutable float m_cachedTime;
384     mutable double m_cachedTimeWallClockUpdateTime;
385     mutable double m_minimumWallClockTimeToCacheMediaTime;
386 
387     bool m_playing : 1;
388     bool m_isWaitingUntilMediaCanStart : 1;
389     bool m_shouldDelayLoadEvent : 1;
390     bool m_haveFiredLoadedData : 1;
391     bool m_inActiveDocument : 1;
392     bool m_autoplaying : 1;
393     bool m_muted : 1;
394     bool m_paused : 1;
395     bool m_seeking : 1;
396 
397     // data has not been loaded since sending a "stalled" event
398     bool m_sentStalledEvent : 1;
399 
400     // time has not changed since sending an "ended" event
401     bool m_sentEndEvent : 1;
402 
403     bool m_pausedInternal : 1;
404 
405     // Not all media engines provide enough information about a file to be able to
406     // support progress events so setting m_sendProgressEvents disables them
407     bool m_sendProgressEvents : 1;
408 
409     bool m_isFullscreen : 1;
410     bool m_closedCaptionsVisible : 1;
411     bool m_mouseOver : 1;
412 
413 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
414     bool m_needWidgetUpdate : 1;
415 #endif
416 
417     bool m_dispatchingCanPlayEvent : 1;
418     bool m_loadInitiatedByUserGesture : 1;
419     bool m_completelyLoaded : 1;
420 
421 #if PLATFORM(ANDROID)
422     double m_lastTouch;
423     // When user gesture invoke load, play or pause, this turns to be true.
424     // After this becomes true, we ignore the user gesture requirement for play
425     // and pause.
426     bool m_userGestureInitiated;
427 #endif
428 };
429 
430 } //namespace
431 
432 #endif
433 #endif
434