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