2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef HTMLMediaElement_h
27 #define HTMLMediaElement_h
31 #include "HTMLElement.h"
32 #include "MediaPlayer.h"
35 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
36 #include "MediaPlayerProxy.h"
42 class HTMLSourceElement
;
47 class HTMLMediaElement
: public HTMLElement
, public MediaPlayerClient
{
49 HTMLMediaElement(const QualifiedName
&, Document
*);
50 virtual ~HTMLMediaElement();
52 bool checkDTD(const Node
* newChild
);
54 void attributeChanged(Attribute
*, bool preserveDecls
);
55 void parseMappedAttribute(MappedAttribute
*);
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
);
64 MediaPlayer
* player() const { return m_player
.get(); }
66 virtual bool isVideo() const { return false; }
67 virtual bool hasVideo() const { return false; }
68 virtual bool hasAudio() const;
70 void rewind(float timeDelta
);
71 void returnToRealtime();
73 // Eventually overloaded in HTMLVideoElement
74 virtual bool supportsFullscreen() const { return false; };
75 virtual bool supportsSave() const;
77 PlatformMedia
platformMedia() const;
81 virtual void defaultEventHandler(Event
*);
83 // Pauses playback without changing any states or generating events
84 void setPausedInternal(bool);
86 MediaPlayer::MovieLoadType
movieLoadType() const;
88 bool inActiveDocument() const { return m_inActiveDocument
; }
92 PassRefPtr
<MediaError
> error() const;
96 void setSrc(const String
&);
97 String
currentSrc() const;
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);
104 PassRefPtr
<TimeRanges
> buffered() const;
105 void load(ExceptionCode
&);
106 String
canPlayType(const String
& mimeType
) const;
109 enum ReadyState
{ HAVE_NOTHING
, HAVE_METADATA
, HAVE_CURRENT_DATA
, HAVE_FUTURE_DATA
, HAVE_ENOUGH_DATA
};
110 ReadyState
readyState() const;
111 bool seeking() const;
114 float currentTime() const;
115 void setCurrentTime(float, ExceptionCode
&);
116 float startTime() const;
117 float duration() 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;
128 bool autoplay() const;
129 void setAutoplay(bool b
);
131 void setLoop(bool b
);
136 void webkitEnterFullScreen(ExceptionCode
&);
137 void webkitExitFullScreen();
138 bool webkitSupportsFullscreen();
139 bool webkitDisplayingFullscreen();
142 bool webkitHasClosedCaptions() const;
143 bool webkitClosedCaptionsVisible() const;
144 void setWebkitClosedCaptionsVisible(bool);
147 bool controls() const;
148 void setControls(bool);
149 float volume() const;
150 void setVolume(float, ExceptionCode
&);
153 void togglePlayState();
154 void beginScrubbing();
157 const IntRect
screenRect();
159 bool canPlay() const;
161 float percentLoaded() const;
163 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
164 void setNeedWidgetUpdate(bool needWidgetUpdate
) { m_needWidgetUpdate
= needWidgetUpdate
; }
165 void deliverNotification(MediaPlayerProxyNotificationType notification
);
166 void setMediaPlayerProxy(WebMediaPlayerProxy
* proxy
);
168 virtual void finishParsingChildren();
171 bool hasSingleSecurityOrigin() const { return !m_player
|| m_player
->hasSingleSecurityOrigin(); }
173 void enterFullscreen();
174 void exitFullscreen();
176 bool hasClosedCaptions() const;
177 bool closedCaptionsVisible() const;
178 void setClosedCaptionsVisible(bool);
181 float getTimeOffsetAttribute(const QualifiedName
&, float valueOnError
) const;
182 void setTimeOffsetAttribute(const QualifiedName
&, float value
);
184 virtual void documentWillBecomeInactive();
185 virtual void documentDidBecomeActive();
186 virtual void mediaVolumeDidChange();
188 void setReadyState(MediaPlayer::ReadyState
);
189 void setNetworkState(MediaPlayer::NetworkState
);
191 private: // MediaPlayerClient
192 virtual void mediaPlayerNetworkStateChanged(MediaPlayer
*);
193 virtual void mediaPlayerReadyStateChanged(MediaPlayer
*);
194 virtual void mediaPlayerTimeChanged(MediaPlayer
*);
195 virtual void mediaPlayerVolumeChanged(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
*);
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();
215 void seek(float time
, ExceptionCode
&);
217 void checkIfSeekNeeded();
218 void addPlayedRange(float start
, float end
);
220 void scheduleTimeupdateEvent(bool periodicEvent
);
221 void scheduleEvent(const AtomicString
& eventName
);
222 void enqueueEvent(RefPtr
<Event
> event
);
225 void selectMediaResource();
226 void loadResource(const KURL
&, ContentType
&);
227 void scheduleNextSourceChild();
228 void loadNextSourceChild();
229 void userCancelledLoad();
230 bool havePotentialSourceChild();
231 void noneSupported();
232 void mediaEngineError(PassRefPtr
<MediaError
> err
);
233 void cancelPendingEventsAndCallbacks();
235 enum InvalidSourceAction
{ DoNothing
, Complain
};
236 bool isSafeToLoadURL(const KURL
&, InvalidSourceAction
);
237 KURL
selectNextSourceChild(ContentType
*, InvalidSourceAction
);
239 // These "internal" functions do not check user gesture restrictions.
242 void pauseInternal();
244 void prepareForLoad();
246 bool processingUserGesture() const;
247 bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback
> 0; }
248 void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback
; }
249 void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback
); --m_processingMediaPlayerCallback
; }
252 void updatePlayState();
253 bool potentiallyPlaying() const;
254 bool endedPlayback() const;
255 bool stoppedDueToErrors() const;
256 bool pausedForUserInteraction() const;
257 bool couldPlayIfEnoughData() const;
259 float minTimeSeekable() const;
260 float maxTimeSeekable() const;
262 // Restrictions to change default behaviors. This is a effectively a compile time choice at the moment
263 // because there are no accessor methods.
264 enum BehaviorRestrictions
{
266 RequireUserGestureForLoadRestriction
= 1 << 0,
267 RequireUserGestureForRateChangeRestriction
= 1 << 1,
271 Timer
<HTMLMediaElement
> m_loadTimer
;
272 Timer
<HTMLMediaElement
> m_asyncEventTimer
;
273 Timer
<HTMLMediaElement
> m_progressEventTimer
;
274 Timer
<HTMLMediaElement
> m_playbackProgressTimer
;
275 Vector
<RefPtr
<Event
> > m_pendingEvents
;
276 RefPtr
<TimeRanges
> m_playedTimeRanges
;
278 float m_playbackRate
;
279 float m_defaultPlaybackRate
;
280 bool m_webkitPreservesPitch
;
281 NetworkState m_networkState
;
282 ReadyState m_readyState
;
285 RefPtr
<MediaError
> m_error
;
288 float m_lastSeekTime
;
290 unsigned m_previousProgress
;
291 double m_previousProgressTime
;
293 // the last time a timeupdate event was sent (wall clock)
294 double m_lastTimeUpdateEventWallTime
;
296 // the last time a timeupdate event was sent in movie time
297 float m_lastTimeUpdateEventMovieTime
;
300 enum LoadState
{ WaitingForSource
, LoadingFromSrcAttr
, LoadingFromSourceElement
};
301 LoadState m_loadState
;
302 HTMLSourceElement
*m_currentSourceNode
;
304 OwnPtr
<MediaPlayer
> m_player
;
306 BehaviorRestrictions m_restrictions
;
310 // counter incremented while processing a callback from the media player, so we can avoid
311 // calling the media engine recursively
312 int m_processingMediaPlayerCallback
;
314 bool m_processingLoad
: 1;
315 bool m_delayingTheLoadEvent
: 1;
316 bool m_haveFiredLoadedData
: 1;
317 bool m_inActiveDocument
: 1;
318 bool m_autoplaying
: 1;
323 // data has not been loaded since sending a "stalled" event
324 bool m_sentStalledEvent
: 1;
326 // time has not changed since sending an "ended" event
327 bool m_sentEndEvent
: 1;
329 bool m_pausedInternal
: 1;
331 // Not all media engines provide enough information about a file to be able to
332 // support progress events so setting m_sendProgressEvents disables them
333 bool m_sendProgressEvents
: 1;
335 bool m_isFullscreen
: 1;
336 bool m_closedCaptionsVisible
: 1;
338 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
339 bool m_needWidgetUpdate
: 1;