| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 #include "core/dom/ActiveDOMObject.h" | |
| 30 #include "core/events/GenericEventQueue.h" | |
| 31 #include "core/html/HTMLElement.h" | |
| 32 #include "platform/PODIntervalTree.h" | |
| 33 #include "platform/Supplementable.h" | |
| 34 #include "platform/graphics/media/MediaPlayer.h" | |
| 35 #include "public/platform/WebMediaPlayerClient.h" | |
| 36 #include "public/platform/WebMimeRegistry.h" | |
| 37 | |
| 38 namespace blink { | |
| 39 class WebLayer; | |
| 40 } | |
| 41 | |
| 42 namespace blink { | |
| 43 | |
| 44 class ContentType; | |
| 45 class Event; | |
| 46 class ExceptionState; | |
| 47 class HTMLSourceElement; | |
| 48 class KURL; | |
| 49 class MediaError; | |
| 50 class HTMLMediaSource; | |
| 51 class TimeRanges; | |
| 52 class URLRegistry; | |
| 53 | |
| 54 // FIXME: The inheritance from MediaPlayerClient here should be private inherita
nce. | |
| 55 // But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so
it | |
| 56 // no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement. | |
| 57 | |
| 58 class HTMLMediaElement : public HTMLElement, public Supplementable<HTMLMediaElem
ent>, public MediaPlayerClient, public ActiveDOMObject | |
| 59 { | |
| 60 DEFINE_WRAPPERTYPEINFO(); | |
| 61 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLMediaElement); | |
| 62 public: | |
| 63 static blink::WebMimeRegistry::SupportsType supportsType(const ContentType&,
const String& keySystem = String()); | |
| 64 | |
| 65 // Do not use player(). | |
| 66 // FIXME: Replace all uses with webMediaPlayer() and remove this API. | |
| 67 MediaPlayer* player() const { return m_player.get(); } | |
| 68 blink::WebMediaPlayer* webMediaPlayer() const { return m_player ? m_player->
webMediaPlayer() : 0; } | |
| 69 | |
| 70 virtual bool hasVideo() const { return false; } | |
| 71 bool hasAudio() const; | |
| 72 | |
| 73 bool supportsSave() const; | |
| 74 | |
| 75 blink::WebLayer* platformLayer() const; | |
| 76 | |
| 77 enum DelayedActionType { | |
| 78 LoadMediaResource = 1 << 0, | |
| 79 }; | |
| 80 void scheduleDelayedAction(DelayedActionType); | |
| 81 | |
| 82 bool isActive() const { return m_active; } | |
| 83 | |
| 84 // error state | |
| 85 PassRefPtr<MediaError> error() const; | |
| 86 | |
| 87 // network state | |
| 88 void setSrc(const AtomicString&); | |
| 89 const KURL& currentSrc() const { return m_currentSrc; } | |
| 90 | |
| 91 enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO
_SOURCE }; | |
| 92 NetworkState networkState() const; | |
| 93 | |
| 94 String preload() const; | |
| 95 void setPreload(const AtomicString&); | |
| 96 | |
| 97 PassRefPtr<TimeRanges> buffered() const; | |
| 98 void load(); | |
| 99 String canPlayType(const String& mimeType, const String& keySystem = String(
)) const; | |
| 100 | |
| 101 // ready state | |
| 102 enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTUR
E_DATA, HAVE_ENOUGH_DATA }; | |
| 103 ReadyState readyState() const; | |
| 104 bool seeking() const; | |
| 105 | |
| 106 // playback state | |
| 107 double currentTime() const; | |
| 108 void setCurrentTime(double, ExceptionState&); | |
| 109 double duration() const; | |
| 110 bool paused() const; | |
| 111 double defaultPlaybackRate() const; | |
| 112 void setDefaultPlaybackRate(double); | |
| 113 double playbackRate() const; | |
| 114 void setPlaybackRate(double); | |
| 115 void updatePlaybackRate(); | |
| 116 PassRefPtr<TimeRanges> played(); | |
| 117 PassRefPtr<TimeRanges> seekable() const; | |
| 118 bool ended() const; | |
| 119 bool autoplay() const; | |
| 120 bool loop() const; | |
| 121 void setLoop(bool b); | |
| 122 void play(); | |
| 123 void pause(); | |
| 124 | |
| 125 // media source extensions | |
| 126 void closeMediaSource(); | |
| 127 void durationChanged(double duration, bool requestSeek); | |
| 128 | |
| 129 double volume() const; | |
| 130 void setVolume(double, ExceptionState&); | |
| 131 bool muted() const; | |
| 132 void setMuted(bool); | |
| 133 | |
| 134 // play/pause toggling that uses the media controller if present. togglePlay
StateWillPlay() is | |
| 135 // true if togglePlayState() will call play() or unpause() on the media elem
ent or controller. | |
| 136 bool togglePlayStateWillPlay() const; | |
| 137 void togglePlayState(); | |
| 138 | |
| 139 virtual KURL mediaPlayerPosterURL() override { return KURL(); } | |
| 140 | |
| 141 // EventTarget function. | |
| 142 // Both Node (via HTMLElement) and ActiveDOMObject define this method, which | |
| 143 // causes an ambiguity error at compile time. This class's constructor | |
| 144 // ensures that both implementations return document, so return the result | |
| 145 // of one of them here. | |
| 146 using HTMLElement::executionContext; | |
| 147 | |
| 148 bool isFullscreen() const; | |
| 149 void enterFullscreen(); | |
| 150 void exitFullscreen(); | |
| 151 | |
| 152 void sourceWasRemoved(HTMLSourceElement*); | |
| 153 void sourceWasAdded(HTMLSourceElement*); | |
| 154 | |
| 155 bool isPlaying() const { return m_playing; } | |
| 156 | |
| 157 // ActiveDOMObject functions. | |
| 158 virtual bool hasPendingActivity() const override final; | |
| 159 virtual void contextDestroyed() override final; | |
| 160 | |
| 161 enum InvalidURLAction { DoNothing, Complain }; | |
| 162 bool isSafeToLoadURL(const KURL&, InvalidURLAction); | |
| 163 | |
| 164 void scheduleEvent(PassRefPtr<Event>); | |
| 165 | |
| 166 // Returns the "effective media volume" value as specified in the HTML5 spec
. | |
| 167 double effectiveMediaVolume() const; | |
| 168 | |
| 169 #if ENABLE(OILPAN) | |
| 170 bool isFinalizing() const { return m_isFinalizing; } | |
| 171 | |
| 172 // Oilpan: finalization of the media element is observable from its | |
| 173 // attached MediaSource; it entering a closed state. | |
| 174 // | |
| 175 // Express that by having the MediaSource keep a weak reference | |
| 176 // to the media element and signal that it wants to be notified | |
| 177 // of destruction if it survives a GC, but the media element | |
| 178 // doesn't. | |
| 179 void setCloseMediaSourceWhenFinalizing(); | |
| 180 #endif | |
| 181 | |
| 182 protected: | |
| 183 HTMLMediaElement(const QualifiedName&, Document&); | |
| 184 virtual ~HTMLMediaElement(); | |
| 185 | |
| 186 virtual void parseAttribute(const QualifiedName&, const AtomicString&) overr
ide; | |
| 187 virtual void finishParsingChildren() override final; | |
| 188 virtual bool isURLAttribute(const Attribute&) const override; | |
| 189 virtual void attach(const AttachContext& = AttachContext()) override; | |
| 190 | |
| 191 virtual void didMoveToNewDocument(Document& oldDocument) override; | |
| 192 | |
| 193 enum DisplayMode { Unknown, Poster, PosterWaitingForVideo, Video }; | |
| 194 DisplayMode displayMode() const { return m_displayMode; } | |
| 195 virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; } | |
| 196 | |
| 197 private: | |
| 198 void createMediaPlayer(); | |
| 199 | |
| 200 virtual bool isMouseFocusable() const override final; | |
| 201 virtual bool rendererIsNeeded(const RenderStyle&) override; | |
| 202 virtual RenderObject* createRenderer(RenderStyle*) override; | |
| 203 virtual InsertionNotificationRequest insertedInto(ContainerNode*) override f
inal; | |
| 204 virtual void didNotifySubtreeInsertionsToDocument() override; | |
| 205 virtual void removedFrom(ContainerNode*) override final; | |
| 206 virtual void didRecalcStyle(StyleRecalcChange) override final; | |
| 207 | |
| 208 virtual void defaultEventHandler(Event*) override final; | |
| 209 | |
| 210 // ActiveDOMObject functions. | |
| 211 virtual void stop() override final; | |
| 212 | |
| 213 virtual void updateDisplayState() { } | |
| 214 | |
| 215 void setReadyState(ReadyState); | |
| 216 void setNetworkState(blink::WebMediaPlayer::NetworkState); | |
| 217 | |
| 218 virtual void mediaPlayerNetworkStateChanged() override final; | |
| 219 virtual void mediaPlayerReadyStateChanged() override final; | |
| 220 virtual void mediaPlayerTimeChanged() override final; | |
| 221 virtual void mediaPlayerDurationChanged() override final; | |
| 222 virtual void mediaPlayerPlaybackStateChanged() override final; | |
| 223 virtual void mediaPlayerRequestFullscreen() override final; | |
| 224 virtual void mediaPlayerRequestSeek(double) override final; | |
| 225 virtual void mediaPlayerRepaint() override final; | |
| 226 virtual void mediaPlayerSizeChanged() override final; | |
| 227 virtual void mediaPlayerSetWebLayer(blink::WebLayer*) override final; | |
| 228 virtual void mediaPlayerMediaSourceOpened(blink::WebMediaSource*) override f
inal; | |
| 229 | |
| 230 void loadTimerFired(Timer<HTMLMediaElement>*); | |
| 231 void progressEventTimerFired(Timer<HTMLMediaElement>*); | |
| 232 void playbackProgressTimerFired(Timer<HTMLMediaElement>*); | |
| 233 void startPlaybackProgressTimer(); | |
| 234 void startProgressEventTimer(); | |
| 235 void stopPeriodicTimers(); | |
| 236 | |
| 237 void seek(double time, ExceptionState&); | |
| 238 void finishSeek(); | |
| 239 void checkIfSeekNeeded(); | |
| 240 void addPlayedRange(double start, double end); | |
| 241 | |
| 242 void scheduleTimeupdateEvent(bool periodicEvent); | |
| 243 void scheduleEvent(const AtomicString& eventName); // FIXME: Rename to sched
uleNamedEvent for clarity. | |
| 244 | |
| 245 // loading | |
| 246 void prepareForLoad(); | |
| 247 void loadInternal(); | |
| 248 void selectMediaResource(); | |
| 249 void loadResource(const KURL&, ContentType&, const String& keySystem); | |
| 250 void startPlayerLoad(); | |
| 251 void setPlayerPreload(); | |
| 252 blink::WebMediaPlayer::LoadType loadType() const; | |
| 253 void scheduleNextSourceChild(); | |
| 254 void loadNextSourceChild(); | |
| 255 void userCancelledLoad(); | |
| 256 void clearMediaPlayer(int flags); | |
| 257 void clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | |
| 258 bool havePotentialSourceChild(); | |
| 259 void noneSupported(); | |
| 260 void mediaEngineError(PassRefPtr<MediaError>); | |
| 261 void cancelPendingEventsAndCallbacks(); | |
| 262 void waitForSourceChange(); | |
| 263 void prepareToPlay(); | |
| 264 | |
| 265 KURL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction
); | |
| 266 | |
| 267 void mediaLoadingFailed(blink::WebMediaPlayer::NetworkState); | |
| 268 | |
| 269 // deferred loading (preload=none) | |
| 270 bool loadIsDeferred() const; | |
| 271 void deferLoad(); | |
| 272 void cancelDeferredLoad(); | |
| 273 void startDeferredLoad(); | |
| 274 void executeDeferredLoad(); | |
| 275 void deferredLoadTimerFired(Timer<HTMLMediaElement>*); | |
| 276 | |
| 277 // This does not check user gesture restrictions. | |
| 278 void playInternal(); | |
| 279 | |
| 280 void allowVideoRendering(); | |
| 281 | |
| 282 void updateVolume(); | |
| 283 void updatePlayState(); | |
| 284 bool potentiallyPlaying() const; | |
| 285 bool endedPlayback() const; | |
| 286 bool stoppedDueToErrors() const; | |
| 287 bool couldPlayIfEnoughData() const; | |
| 288 | |
| 289 // Pauses playback without changing any states or generating events | |
| 290 void setPausedInternal(bool); | |
| 291 | |
| 292 void setShouldDelayLoadEvent(bool); | |
| 293 void invalidateCachedTime(); | |
| 294 void refreshCachedTime() const; | |
| 295 | |
| 296 void prepareMediaFragmentURI(); | |
| 297 void applyMediaFragmentURI(); | |
| 298 | |
| 299 virtual void* preDispatchEventHandler(Event*) override final; | |
| 300 | |
| 301 void changeNetworkStateFromLoadingToIdle(); | |
| 302 | |
| 303 const AtomicString& mediaGroup() const; | |
| 304 void setMediaGroup(const AtomicString&); | |
| 305 bool isBlocked() const; | |
| 306 bool isAutoplaying() const { return m_autoplaying; } | |
| 307 | |
| 308 blink::WebMediaPlayer::CORSMode corsMode() const; | |
| 309 | |
| 310 // Returns the "direction of playback" value as specified in the HTML5 spec. | |
| 311 enum DirectionOfPlayback { Backward, Forward }; | |
| 312 DirectionOfPlayback directionOfPlayback() const; | |
| 313 | |
| 314 // Returns the "effective playback rate" value as specified in the HTML5 spe
c. | |
| 315 double effectivePlaybackRate() const; | |
| 316 | |
| 317 Timer<HTMLMediaElement> m_loadTimer; | |
| 318 Timer<HTMLMediaElement> m_progressEventTimer; | |
| 319 Timer<HTMLMediaElement> m_playbackProgressTimer; | |
| 320 RefPtr<TimeRanges> m_playedTimeRanges; | |
| 321 OwnPtr<GenericEventQueue> m_asyncEventQueue; | |
| 322 | |
| 323 double m_playbackRate; | |
| 324 double m_defaultPlaybackRate; | |
| 325 NetworkState m_networkState; | |
| 326 ReadyState m_readyState; | |
| 327 ReadyState m_readyStateMaximum; | |
| 328 KURL m_currentSrc; | |
| 329 | |
| 330 RefPtr<MediaError> m_error; | |
| 331 | |
| 332 double m_volume; | |
| 333 double m_lastSeekTime; | |
| 334 | |
| 335 double m_previousProgressTime; | |
| 336 | |
| 337 // Cached duration to suppress duplicate events if duration unchanged. | |
| 338 double m_duration; | |
| 339 | |
| 340 // The last time a timeupdate event was sent (wall clock). | |
| 341 double m_lastTimeUpdateEventWallTime; | |
| 342 | |
| 343 // The last time a timeupdate event was sent in movie time. | |
| 344 double m_lastTimeUpdateEventMovieTime; | |
| 345 | |
| 346 // Loading state. | |
| 347 enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElem
ent }; | |
| 348 LoadState m_loadState; | |
| 349 RefPtr<HTMLSourceElement> m_currentSourceNode; | |
| 350 RefPtr<Node> m_nextChildNodeToConsider; | |
| 351 | |
| 352 // "Deferred loading" state (for preload=none). | |
| 353 enum DeferredLoadState { | |
| 354 // The load is not deferred. | |
| 355 NotDeferred, | |
| 356 // The load is deferred, and waiting for the task to set the | |
| 357 // delaying-the-load-event flag (to false). | |
| 358 WaitingForStopDelayingLoadEventTask, | |
| 359 // The load is the deferred, and waiting for a triggering event. | |
| 360 WaitingForTrigger, | |
| 361 // The load is deferred, and waiting for the task to set the | |
| 362 // delaying-the-load-event flag, after which the load will be executed. | |
| 363 ExecuteOnStopDelayingLoadEventTask | |
| 364 }; | |
| 365 DeferredLoadState m_deferredLoadState; | |
| 366 Timer<HTMLMediaElement> m_deferredLoadTimer; | |
| 367 | |
| 368 OwnPtr<MediaPlayer> m_player; | |
| 369 blink::WebLayer* m_webLayer; | |
| 370 | |
| 371 MediaPlayer::Preload m_preload; | |
| 372 | |
| 373 DisplayMode m_displayMode; | |
| 374 | |
| 375 RefPtr<HTMLMediaSource> m_mediaSource; | |
| 376 | |
| 377 // Cached time value. Only valid when ready state is HAVE_METADATA or | |
| 378 // higher, otherwise the current time is assumed to be zero. | |
| 379 mutable double m_cachedTime; | |
| 380 | |
| 381 double m_fragmentStartTime; | |
| 382 double m_fragmentEndTime; | |
| 383 | |
| 384 typedef unsigned PendingActionFlags; | |
| 385 PendingActionFlags m_pendingActionFlags; | |
| 386 | |
| 387 // FIXME: MediaElement has way too many state bits. | |
| 388 bool m_userGestureRequiredForPlay : 1; | |
| 389 bool m_playing : 1; | |
| 390 bool m_shouldDelayLoadEvent : 1; | |
| 391 bool m_haveFiredLoadedData : 1; | |
| 392 bool m_active : 1; | |
| 393 bool m_autoplaying : 1; | |
| 394 bool m_muted : 1; | |
| 395 bool m_paused : 1; | |
| 396 bool m_seeking : 1; | |
| 397 | |
| 398 // data has not been loaded since sending a "stalled" event | |
| 399 bool m_sentStalledEvent : 1; | |
| 400 | |
| 401 // time has not changed since sending an "ended" event | |
| 402 bool m_sentEndEvent : 1; | |
| 403 | |
| 404 bool m_pausedInternal : 1; | |
| 405 | |
| 406 bool m_closedCaptionsVisible : 1; | |
| 407 | |
| 408 bool m_completelyLoaded : 1; | |
| 409 bool m_havePreparedToPlay : 1; | |
| 410 bool m_delayingLoadForPreloadNone : 1; | |
| 411 | |
| 412 bool m_processingPreferenceChange : 1; | |
| 413 #if ENABLE(OILPAN) | |
| 414 bool m_isFinalizing : 1; | |
| 415 bool m_closeMediaSourceWhenFinalizing : 1; | |
| 416 #endif | |
| 417 | |
| 418 static URLRegistry* s_mediaStreamRegistry; | |
| 419 }; | |
| 420 | |
| 421 #ifndef NDEBUG | |
| 422 // Template specializations required by PodIntervalTree in debug mode. | |
| 423 template <> | |
| 424 struct ValueToString<double> { | |
| 425 static String string(const double value) | |
| 426 { | |
| 427 return String::number(value); | |
| 428 } | |
| 429 }; | |
| 430 #endif | |
| 431 | |
| 432 // FIXME(sky): Remove this. | |
| 433 inline bool isHTMLMediaElement(const HTMLElement& element) | |
| 434 { | |
| 435 return false; | |
| 436 } | |
| 437 | |
| 438 DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement); | |
| 439 | |
| 440 } // namespace blink | |
| 441 | |
| 442 #endif // HTMLMediaElement_h | |
| OLD | NEW |