• 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 "MediaPlayer.h"
33 #include "Timer.h"
34 
35 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
36 #include "MediaPlayerProxy.h"
37 #endif
38 
39 namespace WebCore {
40 
41 class Event;
42 class HTMLSourceElement;
43 class MediaError;
44 class KURL;
45 class TimeRanges;
46 
47 class HTMLMediaElement : public HTMLElement, public MediaPlayerClient {
48 public:
49     HTMLMediaElement(const QualifiedName&, Document*);
50     virtual ~HTMLMediaElement();
51 
52     bool checkDTD(const Node* newChild);
53 
54     void attributeChanged(Attribute*, bool preserveDecls);
55     void parseMappedAttribute(MappedAttribute *);
56 
57     virtual bool rendererIsNeeded(RenderStyle*);
58     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
59     virtual void insertedIntoDocument();
60     virtual void removedFromDocument();
61     virtual void attach();
62     virtual void recalcStyle(StyleChange);
63 
player()64     MediaPlayer* player() const { return m_player.get(); }
65 
isVideo()66     virtual bool isVideo() const { return false; }
hasVideo()67     virtual bool hasVideo() const { return false; }
68     virtual bool hasAudio() const;
69 
70     void rewind(float timeDelta);
71     void returnToRealtime();
72 
73     // Eventually overloaded in HTMLVideoElement
supportsFullscreen()74     virtual bool supportsFullscreen() const { return false; };
75     virtual bool supportsSave() const;
76 
77     PlatformMedia platformMedia() const;
78 
79     void scheduleLoad();
80 
81     virtual void defaultEventHandler(Event*);
82 
83     // Pauses playback without changing any states or generating events
84     void setPausedInternal(bool);
85 
86     MediaPlayer::MovieLoadType movieLoadType() const;
87 
inActiveDocument()88     bool inActiveDocument() const { return m_inActiveDocument; }
89 
90 // DOM API
91 // error state
92     PassRefPtr<MediaError> error() const;
93 
94 // network state
95     KURL src() const;
96     void setSrc(const String&);
97     String currentSrc() const;
98 
99     enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_LOADED, NETWORK_NO_SOURCE };
100     NetworkState networkState() const;
101     bool autobuffer() const;
102     void setAutobuffer(bool);
103 
104     PassRefPtr<TimeRanges> buffered() const;
105     void load(bool isUserGesture, ExceptionCode&);
106     String canPlayType(const String& mimeType) const;
107 
108 // ready state
109     enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
110     ReadyState readyState() const;
111     bool seeking() const;
112 
113 // playback state
114     float currentTime() const;
115     void setCurrentTime(float, ExceptionCode&);
116     float startTime() const;
117     float duration() const;
118     bool paused() const;
119     float defaultPlaybackRate() const;
120     void setDefaultPlaybackRate(float);
121     float playbackRate() const;
122     void setPlaybackRate(float);
123     bool webkitPreservesPitch() const;
124     void setWebkitPreservesPitch(bool);
125     PassRefPtr<TimeRanges> played();
126     PassRefPtr<TimeRanges> seekable() const;
127     bool ended() const;
128     bool autoplay() const;
129     void setAutoplay(bool b);
130     bool loop() const;
131     void setLoop(bool b);
132     void play(bool isUserGesture);
133     void pause(bool isUserGesture);
134 
135 // captions
136     bool webkitHasClosedCaptions() const;
137     bool webkitClosedCaptionsVisible() const;
138     void setWebkitClosedCaptionsVisible(bool);
139 
140 // controls
141     bool controls() const;
142     void setControls(bool);
143     float volume() const;
144     void setVolume(float, ExceptionCode&);
145     bool muted() const;
146     void setMuted(bool);
147     void togglePlayState();
148     void beginScrubbing();
149     void endScrubbing();
150 
151     const IntRect screenRect();
152 
153     bool canPlay() const;
154 
155     float percentLoaded() const;
156 
157 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
setNeedWidgetUpdate(bool needWidgetUpdate)158     void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
159     void deliverNotification(MediaPlayerProxyNotificationType notification);
160     void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
161     String initialURL();
162     virtual void finishParsingChildren();
163 #endif
164 
hasSingleSecurityOrigin()165     bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
166 
167     void enterFullscreen();
168     void exitFullscreen();
169 
170     bool hasClosedCaptions() const;
171     bool closedCaptionsVisible() const;
172     void setClosedCaptionsVisible(bool);
173 
174     bool processingUserGesture() const;
175 
176 protected:
177     float getTimeOffsetAttribute(const QualifiedName&, float valueOnError) const;
178     void setTimeOffsetAttribute(const QualifiedName&, float value);
179 
180     virtual void documentWillBecomeInactive();
181     virtual void documentDidBecomeActive();
182     virtual void mediaVolumeDidChange();
183 
184     void setReadyState(MediaPlayer::ReadyState);
185     void setNetworkState(MediaPlayer::NetworkState);
186 
187     virtual void willMoveToNewOwnerDocument();
188     virtual void didMoveToNewOwnerDocument();
189 
190 private: // MediaPlayerClient
191     virtual void mediaPlayerNetworkStateChanged(MediaPlayer*);
192     virtual void mediaPlayerReadyStateChanged(MediaPlayer*);
193     virtual void mediaPlayerTimeChanged(MediaPlayer*);
194     virtual void mediaPlayerVolumeChanged(MediaPlayer*);
195     virtual void mediaPlayerMuteChanged(MediaPlayer*);
196     virtual void mediaPlayerDurationChanged(MediaPlayer*);
197     virtual void mediaPlayerRateChanged(MediaPlayer*);
198     virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
199     virtual void mediaPlayerRepaint(MediaPlayer*);
200     virtual void mediaPlayerSizeChanged(MediaPlayer*);
201 #if USE(ACCELERATED_COMPOSITING)
202     virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*);
203     virtual GraphicsLayer* mediaPlayerGraphicsLayer(MediaPlayer*);
204 #endif
205 
206 private:
207     void loadTimerFired(Timer<HTMLMediaElement>*);
208     void asyncEventTimerFired(Timer<HTMLMediaElement>*);
209     void progressEventTimerFired(Timer<HTMLMediaElement>*);
210     void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
211     void startPlaybackProgressTimer();
212     void startProgressEventTimer();
213     void stopPeriodicTimers();
214 
215     void seek(float time, ExceptionCode&);
216     void finishSeek();
217     void checkIfSeekNeeded();
218     void addPlayedRange(float start, float end);
219 
220     void scheduleTimeupdateEvent(bool periodicEvent);
221     void scheduleEvent(const AtomicString& eventName);
222 
223     // loading
224     void selectMediaResource();
225     void loadResource(const KURL&, ContentType&);
226     void scheduleNextSourceChild();
227     void loadNextSourceChild();
228     void userCancelledLoad();
229     bool havePotentialSourceChild();
230     void noneSupported();
231     void mediaEngineError(PassRefPtr<MediaError> err);
232     void cancelPendingEventsAndCallbacks();
233     void waitForSourceChange();
234 
235     enum InvalidSourceAction { DoNothing, Complain };
236     bool isSafeToLoadURL(const KURL&, InvalidSourceAction);
237     KURL selectNextSourceChild(ContentType*, InvalidSourceAction);
238 
239     // These "internal" functions do not check user gesture restrictions.
240     void loadInternal();
241     void playInternal();
242     void pauseInternal();
243 
244     void prepareForLoad();
245 
processingMediaPlayerCallback()246     bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
beginProcessingMediaPlayerCallback()247     void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
endProcessingMediaPlayerCallback()248     void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
249 
250     void updateVolume();
251     void updatePlayState();
252     bool potentiallyPlaying() const;
253     bool endedPlayback() const;
254     bool stoppedDueToErrors() const;
255     bool pausedForUserInteraction() const;
256     bool couldPlayIfEnoughData() const;
257 
258     float minTimeSeekable() const;
259     float maxTimeSeekable() const;
260 
261     // Restrictions to change default behaviors. This is a effectively a compile time choice at the moment
262     //  because there are no accessor methods.
263     enum BehaviorRestrictions {
264         NoRestrictions = 0,
265         RequireUserGestureForLoadRestriction = 1 << 0,
266         RequireUserGestureForRateChangeRestriction = 1 << 1,
267     };
268 
269 protected:
270     Timer<HTMLMediaElement> m_loadTimer;
271     Timer<HTMLMediaElement> m_asyncEventTimer;
272     Timer<HTMLMediaElement> m_progressEventTimer;
273     Timer<HTMLMediaElement> m_playbackProgressTimer;
274     Vector<RefPtr<Event> > m_pendingEvents;
275     RefPtr<TimeRanges> m_playedTimeRanges;
276 
277     float m_playbackRate;
278     float m_defaultPlaybackRate;
279     bool m_webkitPreservesPitch;
280     NetworkState m_networkState;
281     ReadyState m_readyState;
282     String m_currentSrc;
283 
284     RefPtr<MediaError> m_error;
285 
286     float m_volume;
287     float m_lastSeekTime;
288 
289     unsigned m_previousProgress;
290     double m_previousProgressTime;
291 
292     // the last time a timeupdate event was sent (wall clock)
293     double m_lastTimeUpdateEventWallTime;
294 
295     // the last time a timeupdate event was sent in movie time
296     float m_lastTimeUpdateEventMovieTime;
297 
298     // loading state
299     enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
300     LoadState m_loadState;
301     HTMLSourceElement *m_currentSourceNode;
302 
303     OwnPtr<MediaPlayer> m_player;
304 
305     BehaviorRestrictions m_restrictions;
306 
307     bool m_playing;
308 
309     // counter incremented while processing a callback from the media player, so we can avoid
310     //  calling the media engine recursively
311     int m_processingMediaPlayerCallback;
312 
313     bool m_processingLoad : 1;
314     bool m_delayingTheLoadEvent : 1;
315     bool m_haveFiredLoadedData : 1;
316     bool m_inActiveDocument : 1;
317     bool m_autoplaying : 1;
318     bool m_muted : 1;
319     bool m_paused : 1;
320     bool m_seeking : 1;
321 
322     // data has not been loaded since sending a "stalled" event
323     bool m_sentStalledEvent : 1;
324 
325     // time has not changed since sending an "ended" event
326     bool m_sentEndEvent : 1;
327 
328     bool m_pausedInternal : 1;
329 
330     // Not all media engines provide enough information about a file to be able to
331     // support progress events so setting m_sendProgressEvents disables them
332     bool m_sendProgressEvents : 1;
333 
334     bool m_isFullscreen : 1;
335     bool m_closedCaptionsVisible : 1;
336 
337 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
338     bool m_needWidgetUpdate : 1;
339 #endif
340 };
341 
342 } //namespace
343 
344 #endif
345 #endif
346