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