summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html/HTMLMediaElement.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/HTMLMediaElement.h')
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h401
1 files changed, 401 insertions, 0 deletions
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
new file mode 100644
index 0000000..9778fd4
--- /dev/null
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLMediaElement_h
+#define HTMLMediaElement_h
+
+#if ENABLE(VIDEO)
+
+#include "HTMLElement.h"
+#include "ActiveDOMObject.h"
+#include "MediaCanStartListener.h"
+#include "MediaPlayer.h"
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "MediaPlayerProxy.h"
+#endif
+
+namespace WebCore {
+
+class Event;
+class HTMLSourceElement;
+class MediaError;
+class KURL;
+class TimeRanges;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+class Widget;
+#endif
+
+// FIXME: The inheritance from MediaPlayerClient here should be private inheritance.
+// But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
+// no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
+
+class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, private MediaCanStartListener, private ActiveDOMObject {
+public:
+ MediaPlayer* player() const { return m_player.get(); }
+
+ virtual bool isVideo() const = 0;
+ virtual bool hasVideo() const { return false; }
+ virtual bool hasAudio() const;
+
+ void rewind(float timeDelta);
+ void returnToRealtime();
+
+ // Eventually overloaded in HTMLVideoElement
+ virtual bool supportsFullscreen() const { return false; };
+
+ virtual bool supportsSave() const;
+
+ PlatformMedia platformMedia() const;
+#if USE(ACCELERATED_COMPOSITING)
+ PlatformLayer* platformLayer() const;
+#endif
+
+ void scheduleLoad();
+
+ MediaPlayer::MovieLoadType movieLoadType() const;
+
+ bool inActiveDocument() const { return m_inActiveDocument; }
+
+// DOM API
+// error state
+ PassRefPtr<MediaError> error() const;
+
+// network state
+ void setSrc(const String&);
+ String currentSrc() const;
+
+ enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
+ NetworkState networkState() const;
+
+ String preload() const;
+ void setPreload(const String&);
+
+ PassRefPtr<TimeRanges> buffered() const;
+ void load(bool isUserGesture, ExceptionCode&);
+ String canPlayType(const String& mimeType) const;
+
+// ready state
+ enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
+ ReadyState readyState() const;
+ bool seeking() const;
+
+// playback state
+ float currentTime() const;
+ void setCurrentTime(float, ExceptionCode&);
+ float startTime() const;
+ float duration() const;
+ bool paused() const;
+ float defaultPlaybackRate() const;
+ void setDefaultPlaybackRate(float);
+ float playbackRate() const;
+ void setPlaybackRate(float);
+ bool webkitPreservesPitch() const;
+ void setWebkitPreservesPitch(bool);
+ PassRefPtr<TimeRanges> played();
+ PassRefPtr<TimeRanges> seekable() const;
+ bool ended() const;
+ bool autoplay() const;
+ void setAutoplay(bool b);
+ bool loop() const;
+ void setLoop(bool b);
+ void play(bool isUserGesture);
+ void pause(bool isUserGesture);
+
+// captions
+ bool webkitHasClosedCaptions() const;
+ bool webkitClosedCaptionsVisible() const;
+ void setWebkitClosedCaptionsVisible(bool);
+
+#if ENABLE(MEDIA_STATISTICS)
+// Statistics
+ unsigned long webkitAudioBytesDecoded() const;
+ unsigned long webkitVideoBytesDecoded() const;
+#endif
+
+// controls
+ bool controls() const;
+ void setControls(bool);
+ float volume() const;
+ void setVolume(float, ExceptionCode&);
+ bool muted() const;
+ void setMuted(bool);
+ void togglePlayState();
+ void beginScrubbing();
+ void endScrubbing();
+
+ bool canPlay() const;
+
+ float percentLoaded() const;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ void allocateMediaPlayerIfNecessary();
+ void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
+ void deliverNotification(MediaPlayerProxyNotificationType notification);
+ void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
+ void getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values);
+ virtual void finishParsingChildren();
+ void createMediaPlayerProxy();
+ void updateWidget(PluginCreationOption);
+#endif
+
+ bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
+
+ bool isFullscreen() const { return m_isFullscreen; }
+ void enterFullscreen();
+ void exitFullscreen();
+
+ bool hasClosedCaptions() const;
+ bool closedCaptionsVisible() const;
+ void setClosedCaptionsVisible(bool);
+
+ bool processingUserGesture() const;
+
+ void sourceWillBeRemoved(HTMLSourceElement*);
+ void sourceWasAdded(HTMLSourceElement*);
+
+protected:
+ HTMLMediaElement(const QualifiedName&, Document*);
+ virtual ~HTMLMediaElement();
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual void attach();
+
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
+
+ enum DisplayMode { Unknown, None, Poster, Video };
+ DisplayMode displayMode() const { return m_displayMode; }
+ virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
+
+private:
+ virtual void attributeChanged(Attribute*, bool preserveDecls);
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void recalcStyle(StyleChange);
+
+ virtual void defaultEventHandler(Event*);
+
+ // ActiveDOMObject functions.
+ virtual bool canSuspend() const;
+ virtual void suspend(ReasonForSuspension);
+ virtual void resume();
+ virtual void stop();
+ virtual bool hasPendingActivity() const;
+
+ virtual void mediaVolumeDidChange();
+
+ virtual void updateDisplayState() { }
+
+ void setReadyState(MediaPlayer::ReadyState);
+ void setNetworkState(MediaPlayer::NetworkState);
+
+ virtual Document* mediaPlayerOwningDocument();
+ virtual void mediaPlayerNetworkStateChanged(MediaPlayer*);
+ virtual void mediaPlayerReadyStateChanged(MediaPlayer*);
+ virtual void mediaPlayerTimeChanged(MediaPlayer*);
+ virtual void mediaPlayerVolumeChanged(MediaPlayer*);
+ virtual void mediaPlayerMuteChanged(MediaPlayer*);
+ virtual void mediaPlayerDurationChanged(MediaPlayer*);
+ virtual void mediaPlayerRateChanged(MediaPlayer*);
+ virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*);
+ virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
+ virtual void mediaPlayerRepaint(MediaPlayer*);
+ virtual void mediaPlayerSizeChanged(MediaPlayer*);
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*);
+ virtual void mediaPlayerRenderingModeChanged(MediaPlayer*);
+#endif
+ virtual void mediaPlayerEngineUpdated(MediaPlayer*);
+
+ void loadTimerFired(Timer<HTMLMediaElement>*);
+ void asyncEventTimerFired(Timer<HTMLMediaElement>*);
+ void progressEventTimerFired(Timer<HTMLMediaElement>*);
+ void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
+ void startPlaybackProgressTimer();
+ void startProgressEventTimer();
+ void stopPeriodicTimers();
+
+ void seek(float time, ExceptionCode&);
+ void finishSeek();
+ void checkIfSeekNeeded();
+ void addPlayedRange(float start, float end);
+
+ void scheduleTimeupdateEvent(bool periodicEvent);
+ void scheduleEvent(const AtomicString& eventName);
+
+ // loading
+ void selectMediaResource();
+ void loadResource(const KURL&, ContentType&);
+ void scheduleNextSourceChild();
+ void loadNextSourceChild();
+ void userCancelledLoad();
+ bool havePotentialSourceChild();
+ void noneSupported();
+ void mediaEngineError(PassRefPtr<MediaError> err);
+ void cancelPendingEventsAndCallbacks();
+ void waitForSourceChange();
+
+ enum InvalidSourceAction { DoNothing, Complain };
+ bool isSafeToLoadURL(const KURL&, InvalidSourceAction);
+ KURL selectNextSourceChild(ContentType*, InvalidSourceAction);
+
+ // These "internal" functions do not check user gesture restrictions.
+ void loadInternal();
+ void playInternal();
+ void pauseInternal();
+
+ void prepareForLoad();
+ void allowVideoRendering();
+
+ bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
+ void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
+ void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
+
+ void updateVolume();
+ void updatePlayState();
+ bool potentiallyPlaying() const;
+ bool endedPlayback() const;
+ bool stoppedDueToErrors() const;
+ bool pausedForUserInteraction() const;
+ bool couldPlayIfEnoughData() const;
+
+ float minTimeSeekable() const;
+ float maxTimeSeekable() const;
+
+ // Pauses playback without changing any states or generating events
+ void setPausedInternal(bool);
+
+ virtual void mediaCanStart();
+
+ void setShouldDelayLoadEvent(bool);
+
+ void invalidateCachedTime();
+ void refreshCachedTime() const;
+
+ // Restrictions to change default behaviors. This is effectively a compile time choice at the moment
+ // because there are no accessor functions.
+ enum BehaviorRestrictions {
+ NoRestrictions = 0,
+ RequireUserGestureForLoadRestriction = 1 << 0,
+ RequireUserGestureForRateChangeRestriction = 1 << 1,
+ };
+
+ Timer<HTMLMediaElement> m_loadTimer;
+ Timer<HTMLMediaElement> m_asyncEventTimer;
+ Timer<HTMLMediaElement> m_progressEventTimer;
+ Timer<HTMLMediaElement> m_playbackProgressTimer;
+ Vector<RefPtr<Event> > m_pendingEvents;
+ RefPtr<TimeRanges> m_playedTimeRanges;
+
+ float m_playbackRate;
+ float m_defaultPlaybackRate;
+ bool m_webkitPreservesPitch;
+ NetworkState m_networkState;
+ ReadyState m_readyState;
+ ReadyState m_readyStateMaximum;
+ String m_currentSrc;
+
+ RefPtr<MediaError> m_error;
+
+ float m_volume;
+ float m_lastSeekTime;
+
+ unsigned m_previousProgress;
+ double m_previousProgressTime;
+
+ // the last time a timeupdate event was sent (wall clock)
+ double m_lastTimeUpdateEventWallTime;
+
+ // the last time a timeupdate event was sent in movie time
+ float m_lastTimeUpdateEventMovieTime;
+
+ // loading state
+ enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
+ LoadState m_loadState;
+ HTMLSourceElement* m_currentSourceNode;
+ Node* m_nextChildNodeToConsider;
+ Node* sourceChildEndOfListValue() { return static_cast<Node*>(this); }
+
+ OwnPtr<MediaPlayer> m_player;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ RefPtr<Widget> m_proxyWidget;
+#endif
+
+ BehaviorRestrictions m_restrictions;
+
+ MediaPlayer::Preload m_preload;
+
+ DisplayMode m_displayMode;
+
+ // Counter incremented while processing a callback from the media player, so we can avoid
+ // calling the media engine recursively.
+ int m_processingMediaPlayerCallback;
+
+ mutable float m_cachedTime;
+ mutable double m_cachedTimeWallClockUpdateTime;
+ mutable double m_minimumWallClockTimeToCacheMediaTime;
+
+ bool m_playing : 1;
+ bool m_isWaitingUntilMediaCanStart : 1;
+ bool m_shouldDelayLoadEvent : 1;
+ bool m_haveFiredLoadedData : 1;
+ bool m_inActiveDocument : 1;
+ bool m_autoplaying : 1;
+ bool m_muted : 1;
+ bool m_paused : 1;
+ bool m_seeking : 1;
+
+ // data has not been loaded since sending a "stalled" event
+ bool m_sentStalledEvent : 1;
+
+ // time has not changed since sending an "ended" event
+ bool m_sentEndEvent : 1;
+
+ bool m_pausedInternal : 1;
+
+ // Not all media engines provide enough information about a file to be able to
+ // support progress events so setting m_sendProgressEvents disables them
+ bool m_sendProgressEvents : 1;
+
+ bool m_isFullscreen : 1;
+ bool m_closedCaptionsVisible : 1;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ bool m_needWidgetUpdate : 1;
+#endif
+
+ bool m_dispatchingCanPlayEvent : 1;
+ bool m_loadInitiatedByUserGesture : 1;
+ bool m_completelyLoaded : 1;
+};
+
+} //namespace
+
+#endif
+#endif