diff -r 000000000000 -r 4f2f89ce4247 WebCore/html/HTMLMediaElement.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebCore/html/HTMLMediaElement.h Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,375 @@ +/* + * 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 "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 { +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 const KURL poster() const { return KURL(); } + + 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 error() const; + +// network state + KURL src() const; + 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 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 played(); + PassRefPtr 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); + +// 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(); + + IntRect screenRect(); + + 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& names, Vector& values); + virtual void finishParsingChildren(); + void createMediaPlayerProxy(); +#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; + +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(); + +private: + virtual bool checkDTD(const Node* newChild); + 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*); + + float getTimeOffsetAttribute(const QualifiedName&, float valueOnError) const; + void setTimeOffsetAttribute(const QualifiedName&, float value); + + virtual void documentWillBecomeInactive(); + virtual void documentDidBecomeActive(); + virtual void mediaVolumeDidChange(); + virtual void updatePosterImage() { } + + 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 mediaPlayerSawUnsupportedTracks(MediaPlayer*); + virtual void mediaPlayerRepaint(MediaPlayer*); + virtual void mediaPlayerSizeChanged(MediaPlayer*); +#if USE(ACCELERATED_COMPOSITING) + virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*); + virtual void mediaPlayerRenderingModeChanged(MediaPlayer*); +#endif + + void loadTimerFired(Timer*); + void asyncEventTimerFired(Timer*); + void progressEventTimerFired(Timer*); + void playbackProgressTimerFired(Timer*); + 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 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(); + + 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(); + + // 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 m_loadTimer; + Timer m_asyncEventTimer; + Timer m_progressEventTimer; + Timer m_playbackProgressTimer; + Vector > m_pendingEvents; + RefPtr m_playedTimeRanges; + + float m_playbackRate; + float m_defaultPlaybackRate; + bool m_webkitPreservesPitch; + NetworkState m_networkState; + ReadyState m_readyState; + ReadyState m_readyStateMaximum; + String m_currentSrc; + + RefPtr 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; + + OwnPtr m_player; +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + RefPtr m_proxyWidget; +#endif + + BehaviorRestrictions m_restrictions; + + MediaPlayer::Preload m_preload; + + bool m_playing; + + // Counter incremented while processing a callback from the media player, so we can avoid + // calling the media engine recursively. + int m_processingMediaPlayerCallback; + + bool m_isWaitingUntilMediaCanStart; + + bool m_processingLoad : 1; + bool m_delayingTheLoadEvent : 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