1 /* 2 * Copyright (C) 2007, 2008, 2009, 2010 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 PlatformMedia platformMedia() const; 78 79 void scheduleLoad(); 80 81 virtual void defaultEventHandler(Event*); 82 83 // Pauses playback without changing any states or generating events 84 void setPausedInternal(bool); 85 86 MediaPlayer::MovieLoadType movieLoadType() const; 87 88 bool inActiveDocument() const { return m_inActiveDocument; } 89 90 // DOM API 91 // error state 92 PassRefPtr<MediaError> error() const; 93 94 // network state 95 KURL src() const; 96 void setSrc(const String&); 97 String currentSrc() const; 98 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); 103 104 PassRefPtr<TimeRanges> buffered() const; 105 void load(bool isUserGesture, ExceptionCode&); 106 String canPlayType(const String& mimeType) const; 107 108 // ready state 109 enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA }; 110 ReadyState readyState() const; 111 bool seeking() const; 112 113 // playback state 114 float currentTime() const; 115 void setCurrentTime(float, ExceptionCode&); 116 float startTime() const; 117 float duration() const; 118 bool paused() 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; 127 bool ended() const; 128 bool autoplay() const; 129 void setAutoplay(bool b); 130 bool loop() const; 131 void setLoop(bool b); 132 void play(bool isUserGesture); 133 void pause(bool isUserGesture); 134 135 // captions 136 bool webkitHasClosedCaptions() const; 137 bool webkitClosedCaptionsVisible() const; 138 void setWebkitClosedCaptionsVisible(bool); 139 140 // controls 141 bool controls() const; 142 void setControls(bool); 143 float volume() const; 144 void setVolume(float, ExceptionCode&); 145 bool muted() const; 146 void setMuted(bool); 147 void togglePlayState(); 148 void beginScrubbing(); 149 void endScrubbing(); 150 151 const IntRect screenRect(); 152 153 bool canPlay() const; 154 155 float percentLoaded() const; 156 157 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 158 void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; } 159 void deliverNotification(MediaPlayerProxyNotificationType notification); 160 void setMediaPlayerProxy(WebMediaPlayerProxy* proxy); 161 String initialURL(); 162 virtual void finishParsingChildren(); 163 #endif 164 165 bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); } 166 167 void enterFullscreen(); 168 void exitFullscreen(); 169 170 bool hasClosedCaptions() const; 171 bool closedCaptionsVisible() const; 172 void setClosedCaptionsVisible(bool); 173 174 bool processingUserGesture() const; 175 176 protected: 177 float getTimeOffsetAttribute(const QualifiedName&, float valueOnError) const; 178 void setTimeOffsetAttribute(const QualifiedName&, float value); 179 180 virtual void documentWillBecomeInactive(); 181 virtual void documentDidBecomeActive(); 182 virtual void mediaVolumeDidChange(); 183 184 void setReadyState(MediaPlayer::ReadyState); 185 void setNetworkState(MediaPlayer::NetworkState); 186 187 virtual void willMoveToNewOwnerDocument(); 188 virtual void didMoveToNewOwnerDocument(); 189 190 private: // MediaPlayerClient 191 virtual void mediaPlayerNetworkStateChanged(MediaPlayer*); 192 virtual void mediaPlayerReadyStateChanged(MediaPlayer*); 193 virtual void mediaPlayerTimeChanged(MediaPlayer*); 194 virtual void mediaPlayerVolumeChanged(MediaPlayer*); 195 virtual void mediaPlayerMuteChanged(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*); 204 #endif 205 206 private: 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(); 214 215 void seek(float time, ExceptionCode&); 216 void finishSeek(); 217 void checkIfSeekNeeded(); 218 void addPlayedRange(float start, float end); 219 220 void scheduleTimeupdateEvent(bool periodicEvent); 221 void scheduleEvent(const AtomicString& eventName); 222 223 // loading 224 void selectMediaResource(); 225 void loadResource(const KURL&, ContentType&); 226 void scheduleNextSourceChild(); 227 void loadNextSourceChild(); 228 void userCancelledLoad(); 229 bool havePotentialSourceChild(); 230 void noneSupported(); 231 void mediaEngineError(PassRefPtr<MediaError> err); 232 void cancelPendingEventsAndCallbacks(); 233 void waitForSourceChange(); 234 235 enum InvalidSourceAction { DoNothing, Complain }; 236 bool isSafeToLoadURL(const KURL&, InvalidSourceAction); 237 KURL selectNextSourceChild(ContentType*, InvalidSourceAction); 238 239 // These "internal" functions do not check user gesture restrictions. 240 void loadInternal(); 241 void playInternal(); 242 void pauseInternal(); 243 244 void prepareForLoad(); 245 246 bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; } 247 void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; } 248 void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; } 249 250 void updateVolume(); 251 void updatePlayState(); 252 bool potentiallyPlaying() const; 253 bool endedPlayback() const; 254 bool stoppedDueToErrors() const; 255 bool pausedForUserInteraction() const; 256 bool couldPlayIfEnoughData() const; 257 258 float minTimeSeekable() const; 259 float maxTimeSeekable() const; 260 261 // Restrictions to change default behaviors. This is a effectively a compile time choice at the moment 262 // because there are no accessor methods. 263 enum BehaviorRestrictions { 264 NoRestrictions = 0, 265 RequireUserGestureForLoadRestriction = 1 << 0, 266 RequireUserGestureForRateChangeRestriction = 1 << 1, 267 }; 268 269 protected: 270 Timer<HTMLMediaElement> m_loadTimer; 271 Timer<HTMLMediaElement> m_asyncEventTimer; 272 Timer<HTMLMediaElement> m_progressEventTimer; 273 Timer<HTMLMediaElement> m_playbackProgressTimer; 274 Vector<RefPtr<Event> > m_pendingEvents; 275 RefPtr<TimeRanges> m_playedTimeRanges; 276 277 float m_playbackRate; 278 float m_defaultPlaybackRate; 279 bool m_webkitPreservesPitch; 280 NetworkState m_networkState; 281 ReadyState m_readyState; 282 String m_currentSrc; 283 284 RefPtr<MediaError> m_error; 285 286 float m_volume; 287 float m_lastSeekTime; 288 289 unsigned m_previousProgress; 290 double m_previousProgressTime; 291 292 // the last time a timeupdate event was sent (wall clock) 293 double m_lastTimeUpdateEventWallTime; 294 295 // the last time a timeupdate event was sent in movie time 296 float m_lastTimeUpdateEventMovieTime; 297 298 // loading state 299 enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement }; 300 LoadState m_loadState; 301 HTMLSourceElement *m_currentSourceNode; 302 303 OwnPtr<MediaPlayer> m_player; 304 305 BehaviorRestrictions m_restrictions; 306 307 bool m_playing; 308 309 // counter incremented while processing a callback from the media player, so we can avoid 310 // calling the media engine recursively 311 int m_processingMediaPlayerCallback; 312 313 bool m_processingLoad : 1; 314 bool m_delayingTheLoadEvent : 1; 315 bool m_haveFiredLoadedData : 1; 316 bool m_inActiveDocument : 1; 317 bool m_autoplaying : 1; 318 bool m_muted : 1; 319 bool m_paused : 1; 320 bool m_seeking : 1; 321 322 // data has not been loaded since sending a "stalled" event 323 bool m_sentStalledEvent : 1; 324 325 // time has not changed since sending an "ended" event 326 bool m_sentEndEvent : 1; 327 328 bool m_pausedInternal : 1; 329 330 // Not all media engines provide enough information about a file to be able to 331 // support progress events so setting m_sendProgressEvents disables them 332 bool m_sendProgressEvents : 1; 333 334 bool m_isFullscreen : 1; 335 bool m_closedCaptionsVisible : 1; 336 337 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 338 bool m_needWidgetUpdate : 1; 339 #endif 340 }; 341 342 } //namespace 343 344 #endif 345 #endif 346