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