aa8d5f72a9aaa9d5c60725e8a579c9f654c239a7
[WebKit.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();
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     void addPlayedRange(float start, float end);
197     
198     void scheduleTimeupdateEvent(bool periodicEvent);
199     void scheduleProgressEvent(const AtomicString& eventName);
200     void scheduleEvent(const AtomicString& eventName);
201     void enqueueEvent(RefPtr<Event> event);
202     
203     // loading
204     void selectMediaResource();
205     void loadResource(const KURL&, ContentType&);
206     void scheduleNextSourceChild();
207     void loadNextSourceChild();
208     void userCancelledLoad();
209     bool havePotentialSourceChild();
210     void noneSupported();
211     void mediaEngineError(PassRefPtr<MediaError> err);
212     void cancelPendingEventsAndCallbacks();
213
214     enum InvalidSourceAction { DoNothing, Complain };
215     bool isSafeToLoadURL(const KURL&, InvalidSourceAction);
216     KURL selectNextSourceChild(ContentType*, InvalidSourceAction);
217
218     // These "internal" functions do not check user gesture restrictions.
219     void loadInternal();
220     void playInternal();
221     void pauseInternal();
222
223     void prepareForLoad();
224     
225     bool processingUserGesture() const;
226     bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
227     void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
228     void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
229
230     void updateVolume();
231     void updatePlayState();
232     bool potentiallyPlaying() const;
233     bool endedPlayback() const;
234     bool stoppedDueToErrors() const;
235     bool pausedForUserInteraction() const;
236
237     float minTimeSeekable() const;
238     float maxTimeSeekable() const;
239
240     // Restrictions to change default behaviors. This is a effectively a compile time choice at the moment
241     //  because there are no accessor methods.
242     enum BehaviorRestrictions {
243         NoRestrictions = 0,
244         RequireUserGestureForLoadRestriction = 1 << 0,
245         RequireUserGestureForRateChangeRestriction = 1 << 1,
246     };
247
248 protected:
249     Timer<HTMLMediaElement> m_loadTimer;
250     Timer<HTMLMediaElement> m_asyncEventTimer;
251     Timer<HTMLMediaElement> m_progressEventTimer;
252     Timer<HTMLMediaElement> m_playbackProgressTimer;
253     Vector<RefPtr<Event> > m_pendingEvents;
254     RefPtr<TimeRanges> m_playedTimeRanges;
255     
256     float m_playbackRate;
257     float m_defaultPlaybackRate;
258     bool m_webkitPreservesPitch;
259     NetworkState m_networkState;
260     ReadyState m_readyState;
261     String m_currentSrc;
262     
263     RefPtr<MediaError> m_error;
264
265     float m_volume;
266     float m_lastSeekTime;
267     
268     unsigned m_previousProgress;
269     double m_previousProgressTime;
270
271     // the last time a timeupdate event was sent (wall clock)
272     double m_lastTimeUpdateEventWallTime;
273
274     // the last time a timeupdate event was sent in movie time
275     float m_lastTimeUpdateEventMovieTime;
276     
277     // loading state
278     enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
279     LoadState m_loadState;
280     HTMLSourceElement *m_currentSourceNode;
281     
282     OwnPtr<MediaPlayer> m_player;
283
284     BehaviorRestrictions m_restrictions;
285
286     bool m_playing;
287
288     // counter incremented while processing a callback from the media player, so we can avoid
289     //  calling the media engine recursively
290     int m_processingMediaPlayerCallback;
291
292     bool m_processingLoad : 1;
293     bool m_delayingTheLoadEvent : 1;
294     bool m_haveFiredLoadedData : 1;
295     bool m_inActiveDocument : 1;
296     bool m_autoplaying : 1;
297     bool m_muted : 1;
298     bool m_paused : 1;
299     bool m_seeking : 1;
300
301     // data has not been loaded since sending a "stalled" event
302     bool m_sentStalledEvent : 1;
303
304     // time has not changed since sending an "ended" event
305     bool m_sentEndEvent : 1;
306
307     bool m_pausedInternal : 1;
308
309     // Not all media engines provide enough information about a file to be able to
310     // support progress events so setting m_sendProgressEvents disables them 
311     bool m_sendProgressEvents : 1;
312
313 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
314     bool m_needWidgetUpdate : 1;
315 #endif
316 };
317
318 } //namespace
319
320 #endif
321 #endif