| /* |
| * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_ |
| |
| #include <memory> |
| |
| #include "base/optional.h" |
| #include "base/time/time.h" |
| #include "base/timer/elapsed_timer.h" |
| #include "media/mojo/mojom/media_player.mojom-blink.h" |
| #include "third_party/blink/public/common/media/display_type.h" |
| #include "third_party/blink/public/platform/web_media_player_client.h" |
| #include "third_party/blink/public/platform/webaudiosourceprovider_impl.h" |
| #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" |
| #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" |
| #include "third_party/blink/renderer/core/core_export.h" |
| #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h" |
| #include "third_party/blink/renderer/core/html/html_element.h" |
| #include "third_party/blink/renderer/core/html/media/media_controls.h" |
| #include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h" |
| #include "third_party/blink/renderer/platform/audio/audio_source_provider.h" |
| #include "third_party/blink/renderer/platform/bindings/exception_state.h" |
| #include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h" |
| #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h" |
| #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h" |
| #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_set.h" |
| #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" |
| #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" |
| #include "third_party/blink/renderer/platform/supplementable.h" |
| #include "third_party/blink/renderer/platform/timer.h" |
| #include "third_party/blink/renderer/platform/weborigin/kurl.h" |
| #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" |
| |
| namespace cc { |
| class Layer; |
| } |
| |
| namespace media { |
| enum class MediaContentType; |
| } // namespace media |
| |
| namespace blink { |
| |
| class AudioSourceProviderClient; |
| class AudioTrack; |
| class AudioTrackList; |
| class AutoplayPolicy; |
| class ContentType; |
| class CueTimeline; |
| class Event; |
| class EventQueue; |
| class ExceptionState; |
| class HTMLMediaElementControlsList; |
| class HTMLSourceElement; |
| class HTMLTrackElement; |
| class MediaError; |
| class MediaSourceAttachment; |
| class MediaSourceTracer; |
| class MediaStreamDescriptor; |
| class ScriptPromiseResolver; |
| class ScriptState; |
| class TextTrack; |
| class TextTrackContainer; |
| class TextTrackList; |
| class TimeRanges; |
| class VideoTrack; |
| class VideoTrackList; |
| class WebInbandTextTrack; |
| class WebRemotePlaybackClient; |
| |
| class CORE_EXPORT HTMLMediaElement |
| : public HTMLElement, |
| public Supplementable<HTMLMediaElement>, |
| public ActiveScriptWrappable<HTMLMediaElement>, |
| public ExecutionContextLifecycleStateObserver, |
| public media::mojom::blink::MediaPlayer, |
| private WebMediaPlayerClient { |
| DEFINE_WRAPPERTYPEINFO(); |
| USING_PRE_FINALIZER(HTMLMediaElement, Dispose); |
| |
| public: |
| // Limits the range of media playback rate. |
| static constexpr double kMinPlaybackRate = 0.0625; |
| static constexpr double kMaxPlaybackRate = 16.0; |
| |
| bool IsMediaElement() const override { return true; } |
| |
| static MIMETypeRegistry::SupportsType GetSupportsType(const ContentType&); |
| |
| enum class RecordMetricsBehavior { kDoNotRecord, kDoRecord }; |
| |
| static bool IsHLSURL(const KURL&); |
| |
| // If HTMLMediaElement is using MediaTracks (either placeholder or provided |
| // by the page). |
| static bool MediaTracksEnabledInternally(); |
| |
| // Notify the HTMLMediaElement that the media controls settings have changed |
| // for the given document. |
| static void OnMediaControlsEnabledChange(Document*); |
| |
| // Binds |pending_receiver| and adds it to |media_player_receiver_set_|. Also |
| // called from other Blink classes (e.g. PictureInPictureControllerImpl). |
| void BindMediaPlayerReceiver( |
| mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayer> |
| pending_receiver); |
| |
| void Trace(Visitor*) const override; |
| |
| WebMediaPlayer* GetWebMediaPlayer() const { return web_media_player_.get(); } |
| |
| // Returns true if the loaded media has a video track. |
| // Note that even an audio element can have video track in cases such as |
| // <audio src="video.webm">, in which case this function will return true. |
| bool HasVideo() const; |
| // Returns true if loaded media has an audio track. |
| bool HasAudio() const; |
| |
| bool SupportsSave() const; |
| |
| bool SupportsLoop() const; |
| |
| cc::Layer* CcLayer() const; |
| |
| enum DelayedActionType { |
| kLoadMediaResource = 1 << 0, |
| kLoadTextTrackResource = 1 << 1 |
| }; |
| void ScheduleTextTrackResourceLoad(); |
| |
| bool HasRemoteRoutes() const; |
| |
| // error state |
| MediaError* error() const; |
| |
| // network state |
| void SetSrc(const AtomicString&); |
| const KURL& currentSrc() const { return current_src_; } |
| |
| // Return the URL to be used for downloading the media. |
| const KURL& downloadURL() const { |
| // If we didn't get a redirected URL from the player, then use the original. |
| if (current_src_after_redirects_.IsNull() || |
| current_src_after_redirects_.IsEmpty()) { |
| return currentSrc(); |
| } |
| return current_src_after_redirects_; |
| } |
| |
| void SetSrcObject(MediaStreamDescriptor*); |
| MediaStreamDescriptor* GetSrcObject() const { return src_object_.Get(); } |
| |
| enum NetworkState { |
| kNetworkEmpty, |
| kNetworkIdle, |
| kNetworkLoading, |
| kNetworkNoSource |
| }; |
| NetworkState getNetworkState() const; |
| |
| String preload() const; |
| void setPreload(const AtomicString&); |
| WebMediaPlayer::Preload PreloadType() const; |
| String EffectivePreload() const; |
| WebMediaPlayer::Preload EffectivePreloadType() const; |
| |
| WebTimeRanges BufferedInternal() const; |
| TimeRanges* buffered() const; |
| void load(); |
| String canPlayType(ExecutionContext* context, const String& mime_type) const; |
| |
| // ready state |
| enum ReadyState { |
| kHaveNothing, |
| kHaveMetadata, |
| kHaveCurrentData, |
| kHaveFutureData, |
| kHaveEnoughData |
| }; |
| ReadyState getReadyState() const; |
| bool seeking() const; |
| |
| // playback state |
| double currentTime() const; |
| void setCurrentTime(double); |
| double duration() const; |
| bool paused() const; |
| double defaultPlaybackRate() const; |
| void setDefaultPlaybackRate(double); |
| double playbackRate() const; |
| void setPlaybackRate(double, ExceptionState& = ASSERT_NO_EXCEPTION); |
| TimeRanges* played(); |
| WebTimeRanges SeekableInternal() const; |
| TimeRanges* seekable() const; |
| bool ended() const; |
| bool Autoplay() const; |
| bool Loop() const; |
| void SetLoop(bool); |
| ScriptPromise playForBindings(ScriptState*); |
| base::Optional<DOMExceptionCode> Play(); |
| void pause(); |
| double latencyHint() const; |
| void setLatencyHint(double); |
| bool preservesPitch() const; |
| void setPreservesPitch(bool); |
| void FlingingStarted(); |
| void FlingingStopped(); |
| |
| // statistics |
| uint64_t webkitAudioDecodedByteCount() const; |
| uint64_t webkitVideoDecodedByteCount() const; |
| |
| // media source extensions |
| void CloseMediaSource(); |
| void DurationChanged(double duration, bool request_seek); |
| |
| // controls |
| bool ShouldShowControls( |
| const RecordMetricsBehavior = RecordMetricsBehavior::kDoNotRecord) const; |
| DOMTokenList* controlsList() const; |
| HTMLMediaElementControlsList* ControlsListInternal() const; |
| double volume() const; |
| void setVolume(double, ExceptionState& = ASSERT_NO_EXCEPTION); |
| bool muted() const; |
| void setMuted(bool); |
| virtual bool SupportsPictureInPicture() const { return false; } |
| |
| void TogglePlayState(); |
| |
| AudioTrackList& audioTracks(); |
| void AudioTrackChanged(AudioTrack*); |
| |
| VideoTrackList& videoTracks(); |
| void SelectedVideoTrackChanged(VideoTrack*); |
| |
| TextTrack* addTextTrack(const AtomicString& kind, |
| const AtomicString& label, |
| const AtomicString& language, |
| ExceptionState&); |
| |
| TextTrackList* textTracks(); |
| CueTimeline& GetCueTimeline(); |
| |
| // Implements the "forget the media element's media-resource-specific tracks" |
| // algorithm in the HTML5 spec. |
| void ForgetResourceSpecificTracks(); |
| |
| void DidAddTrackElement(HTMLTrackElement*); |
| void DidRemoveTrackElement(HTMLTrackElement*); |
| |
| void HonorUserPreferencesForAutomaticTextTrackSelection(); |
| |
| bool TextTracksAreReady() const; |
| void ConfigureTextTrackDisplay(); |
| void UpdateTextTrackDisplay(); |
| double LastSeekTime() const { return last_seek_time_; } |
| void TextTrackReadyStateChanged(TextTrack*); |
| |
| void TextTrackModeChanged(TextTrack*); |
| void DisableAutomaticTextTrackSelection(); |
| |
| // EventTarget function. |
| // Both Node (via HTMLElement) and ExecutionContextLifecycleStateObserver |
| // define this method, which causes an ambiguity error at compile time. This |
| // class's constructor ensures that both implementations return document, so |
| // return the result of one of them here. |
| using HTMLElement::GetExecutionContext; |
| |
| bool IsFullscreen() const; |
| virtual bool UsesOverlayFullscreenVideo() const { return false; } |
| |
| bool HasClosedCaptions() const; |
| bool TextTracksVisible() const; |
| |
| static void SetTextTrackKindUserPreferenceForAllMediaElements(Document*); |
| void AutomaticTrackSelectionForUpdatedUserPreference(); |
| |
| // Returns the MediaControls, or null if they have not been added yet. |
| // Note that this can be non-null even if there is no controls attribute. |
| MediaControls* GetMediaControls() const; |
| |
| // Notifies the media element that the media controls became visible, so |
| // that text track layout may be updated to avoid overlapping them. |
| void MediaControlsDidBecomeVisible(); |
| |
| void SourceWasRemoved(HTMLSourceElement*); |
| void SourceWasAdded(HTMLSourceElement*); |
| |
| // ScriptWrappable functions. |
| bool HasPendingActivity() const override; |
| |
| AudioSourceProviderClient* AudioSourceNode() { return audio_source_node_; } |
| void SetAudioSourceNode(AudioSourceProviderClient*); |
| |
| AudioSourceProvider& GetAudioSourceProvider() { |
| return audio_source_provider_; |
| } |
| |
| enum InvalidURLAction { kDoNothing, kComplain }; |
| bool IsSafeToLoadURL(const KURL&, InvalidURLAction); |
| |
| // Checks to see if current media data is CORS-same-origin. |
| bool IsMediaDataCorsSameOrigin() const; |
| |
| void ScheduleEvent(Event*); |
| |
| // Returns the "effective media volume" value as specified in the HTML5 spec. |
| double EffectiveMediaVolume() const; |
| |
| // Predicates also used when dispatching wrapper creation (cf. |
| // [SpecialWrapFor] IDL attribute usage.) |
| virtual bool IsHTMLAudioElement() const { return false; } |
| virtual bool IsHTMLVideoElement() const { return false; } |
| |
| void VideoWillBeDrawnToCanvas() const; |
| |
| const WebRemotePlaybackClient* RemotePlaybackClient() const { |
| return remote_playback_client_; |
| } |
| |
| const AutoplayPolicy& GetAutoplayPolicy() const { return *autoplay_policy_; } |
| |
| WebMediaPlayer::LoadType GetLoadType() const; |
| |
| bool HasMediaSource() const { return media_source_attachment_.get(); } |
| |
| // Return true if element is paused and won't resume automatically if it |
| // becomes visible again. |
| bool PausedWhenVisible() const; |
| |
| void DidAudioOutputSinkChanged(const String& hashed_device_id); |
| |
| void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); } |
| |
| // Required by tests set mock receivers to check that messages are delivered. |
| void AddMediaPlayerObserverForTesting( |
| mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerObserver> |
| observer); |
| |
| bool IsShowPosterFlagSet() const { return show_poster_flag_; } |
| |
| protected: |
| // Assert the correct order of the children in shadow dom when DCHECK is on. |
| static void AssertShadowRootChildren(ShadowRoot&); |
| |
| HTMLMediaElement(const QualifiedName&, Document&); |
| ~HTMLMediaElement() override; |
| void Dispose(); |
| |
| // Returns a constant reference to the HeapMojoAssociatedRemoteSet holding all |
| // the bound remotes for the media::mojom::blink::MediaPlayerObserver |
| // interface. Needed to allow sending messages directly from |
| // HTMLMediaElement's subclasses. |
| const HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>& |
| GetMediaPlayerObserverRemoteSet() { |
| return media_player_observer_remote_set_; |
| } |
| |
| void ParseAttribute(const AttributeModificationParams&) override; |
| void FinishParsingChildren() final; |
| bool IsURLAttribute(const Attribute&) const override; |
| void AttachLayoutTree(AttachContext&) override; |
| void ParserDidSetAttributes() override; |
| void CloneNonAttributePropertiesFrom(const Element&, |
| CloneChildrenFlag) override; |
| |
| InsertionNotificationRequest InsertedInto(ContainerNode&) override; |
| void RemovedFrom(ContainerNode&) override; |
| |
| // Return true if media is cross origin from the current document |
| // and has not passed a cors check, meaning that we should return |
| // as little information as possible about it. |
| bool MediaShouldBeOpaque() const; |
| |
| void DidMoveToNewDocument(Document& old_document) override; |
| virtual KURL PosterImageURL() const { return KURL(); } |
| |
| // Called after the creation of |web_media_player_|. |
| virtual void OnWebMediaPlayerCreated() {} |
| virtual void OnWebMediaPlayerCleared() {} |
| |
| void UpdateLayoutObject(); |
| |
| private: |
| // Friend class for testing. |
| friend class ContextMenuControllerTest; |
| friend class HTMLMediaElementTest; |
| friend class PictureInPictureControllerTest; |
| friend class VideoWakeLockTest; |
| |
| bool HasPendingActivityInternal() const; |
| |
| void ResetMediaPlayerAndMediaSource(); |
| |
| bool AlwaysCreateUserAgentShadowRoot() const final { return true; } |
| bool AreAuthorShadowsAllowed() const final { return false; } |
| |
| bool SupportsFocus() const final; |
| bool IsMouseFocusable() const final; |
| bool LayoutObjectIsNeeded(const ComputedStyle&) const override; |
| LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; |
| void DidNotifySubtreeInsertionsToDocument() override; |
| void DidRecalcStyle(const StyleRecalcChange) final; |
| |
| bool CanStartSelection() const override { return false; } |
| |
| bool IsInteractiveContent() const final; |
| |
| // ExecutionContextLifecycleStateObserver functions. |
| void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override; |
| void ContextDestroyed() override; |
| |
| virtual void OnPlay() {} |
| virtual void OnLoadStarted() {} |
| virtual void OnLoadFinished() {} |
| |
| void SetShowPosterFlag(bool value); |
| |
| void SetReadyState(ReadyState); |
| void SetNetworkState(WebMediaPlayer::NetworkState); |
| |
| // WebMediaPlayerClient implementation. |
| void NetworkStateChanged() final; |
| void ReadyStateChanged() final; |
| void TimeChanged() final; |
| void Repaint() final; |
| void DurationChanged() final; |
| void SizeChanged() final; |
| |
| void SetCcLayer(cc::Layer*) final; |
| WebMediaPlayer::TrackId AddAudioTrack(const WebString&, |
| WebMediaPlayerClient::AudioTrackKind, |
| const WebString&, |
| const WebString&, |
| bool) final; |
| void RemoveAudioTrack(WebMediaPlayer::TrackId) final; |
| WebMediaPlayer::TrackId AddVideoTrack(const WebString&, |
| WebMediaPlayerClient::VideoTrackKind, |
| const WebString&, |
| const WebString&, |
| bool) final; |
| void RemoveVideoTrack(WebMediaPlayer::TrackId) final; |
| void AddTextTrack(WebInbandTextTrack*) final; |
| void RemoveTextTrack(WebInbandTextTrack*) final; |
| void MediaSourceOpened(WebMediaSource*) final; |
| void RemotePlaybackCompatibilityChanged(const WebURL&, |
| bool is_compatible) final; |
| void OnBecamePersistentVideo(bool) override {} |
| bool HasSelectedVideoTrack() final; |
| WebMediaPlayer::TrackId GetSelectedVideoTrackId() final; |
| bool WasAlwaysMuted() final; |
| bool HasNativeControls() final; |
| bool IsAudioElement() final; |
| DisplayType GetDisplayType() const override; |
| WebRemotePlaybackClient* RemotePlaybackClient() final { |
| return remote_playback_client_; |
| } |
| std::vector<TextTrackMetadata> GetTextTrackMetadata() override; |
| gfx::ColorSpace TargetColorSpace() override; |
| bool WasAutoplayInitiated() override; |
| bool IsInAutoPIP() const override { return false; } |
| void ResumePlayback() final; |
| void PausePlayback() final; |
| void DidPlayerStartPlaying() override; |
| void DidPlayerPaused(bool stream_ended) override; |
| void DidPlayerMutedStatusChange(bool muted) override; |
| void DidMediaMetadataChange( |
| bool has_audio, |
| bool has_video, |
| media::MediaContentType media_content_type) override; |
| void DidPlayerMediaPositionStateChange(double playback_rate, |
| base::TimeDelta duration, |
| base::TimeDelta position) override; |
| void DidDisableAudioOutputSinkChanges() override; |
| void DidPlayerSizeChange(const gfx::Size& size) override; |
| void DidBufferUnderflow() override; |
| void DidSeek() override; |
| |
| // Returns a reference to the mojo remote for the MediaPlayerHost interface, |
| // requesting it first from the BrowserInterfaceBroker if needed. It is an |
| // error to call this method before having access to the document's frame. |
| media::mojom::blink::MediaPlayerHost& GetMediaPlayerHostRemote(); |
| |
| // media::mojom::MediaPlayer implementation. |
| void AddMediaPlayerObserver( |
| mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerObserver> |
| observer) override; |
| void RequestPlay() override; |
| void RequestPause(bool triggered_by_user) override; |
| void RequestSeekForward(base::TimeDelta seek_time) override; |
| void RequestSeekBackward(base::TimeDelta seek_time) override; |
| void RequestEnterPictureInPicture() override {} |
| void RequestExitPictureInPicture() override {} |
| void SetAudioSinkId(const String&) override; |
| |
| void LoadTimerFired(TimerBase*); |
| void ProgressEventTimerFired(TimerBase*); |
| void PlaybackProgressTimerFired(TimerBase*); |
| void ScheduleTimeupdateEvent(bool periodic_event); |
| void StartPlaybackProgressTimer(); |
| void StartProgressEventTimer(); |
| void StopPeriodicTimers(); |
| |
| void Seek(double time); |
| void FinishSeek(); |
| void AddPlayedRange(double start, double end); |
| |
| // FIXME: Rename to scheduleNamedEvent for clarity. |
| void ScheduleEvent(const AtomicString& event_name); |
| |
| // loading |
| void InvokeLoadAlgorithm(); |
| void InvokeResourceSelectionAlgorithm(); |
| void LoadInternal(); |
| void SelectMediaResource(); |
| void LoadResource(const WebMediaPlayerSource&, const String& content_type); |
| void StartPlayerLoad(); |
| void SetPlayerPreload(); |
| void ScheduleNextSourceChild(); |
| void LoadSourceFromObject(); |
| void LoadSourceFromAttribute(); |
| void LoadNextSourceChild(); |
| void ClearMediaPlayer(); |
| void ClearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
| bool HavePotentialSourceChild(); |
| void NoneSupported(const String&); |
| void MediaEngineError(MediaError*); |
| void CancelPendingEventsAndCallbacks(); |
| void WaitForSourceChange(); |
| void SetIgnorePreloadNone(); |
| |
| KURL SelectNextSourceChild(String* content_type, InvalidURLAction); |
| |
| void MediaLoadingFailed(WebMediaPlayer::NetworkState, const String&); |
| |
| // deferred loading (preload=none) |
| bool LoadIsDeferred() const; |
| void DeferLoad(); |
| void CancelDeferredLoad(); |
| void StartDeferredLoad(); |
| void ExecuteDeferredLoad(); |
| void DeferredLoadTimerFired(TimerBase*); |
| |
| void MarkCaptionAndSubtitleTracksAsUnconfigured(); |
| |
| // This does not check user gesture restrictions. |
| void PlayInternal(); |
| |
| // This does not stop autoplay visibility observation. |
| void PauseInternal(); |
| |
| void UpdatePlayState(); |
| bool PotentiallyPlaying() const; |
| bool StoppedDueToErrors() const; |
| bool CouldPlayIfEnoughData() const override; |
| |
| // Generally the presence of the loop attribute should be considered to mean |
| // playback has not "ended", as "ended" and "looping" are mutually exclusive. |
| // See |
| // https://html.spec.whatwg.org/C/#ended-playback |
| enum class LoopCondition { kIncluded, kIgnored }; |
| bool EndedPlayback(LoopCondition = LoopCondition::kIncluded) const; |
| |
| void SetShouldDelayLoadEvent(bool); |
| |
| double EarliestPossiblePosition() const; |
| double CurrentPlaybackPosition() const; |
| double OfficialPlaybackPosition() const; |
| void SetOfficialPlaybackPosition(double) const; |
| void RequireOfficialPlaybackPositionUpdate() const; |
| |
| void EnsureMediaControls(); |
| void UpdateControlsVisibility(); |
| |
| TextTrackContainer& EnsureTextTrackContainer(); |
| |
| void ChangeNetworkStateFromLoadingToIdle(); |
| |
| WebMediaPlayer::CorsMode CorsMode() const; |
| |
| // Returns the "direction of playback" value as specified in the HTML5 spec. |
| enum DirectionOfPlayback { kBackward, kForward }; |
| DirectionOfPlayback GetDirectionOfPlayback() const; |
| |
| // Creates placeholder AudioTrack and/or VideoTrack objects when |
| // WebMediaPlayer objects advertise they have audio and/or video, but don't |
| // explicitly signal them via addAudioTrack() and addVideoTrack(). |
| // FIXME: Remove this once all WebMediaPlayer implementations properly report |
| // their track info. |
| void CreatePlaceholderTracksIfNecessary(); |
| |
| void SetNetworkState(NetworkState); |
| |
| void AudioTracksTimerFired(TimerBase*); |
| |
| void ScheduleResolvePlayPromises(); |
| void ScheduleRejectPlayPromises(DOMExceptionCode); |
| void ScheduleNotifyPlaying(); |
| void ResolveScheduledPlayPromises(); |
| void RejectScheduledPlayPromises(); |
| void RejectPlayPromises(DOMExceptionCode, const String&); |
| void RejectPlayPromisesInternal(DOMExceptionCode, const String&); |
| |
| void OnRemovedFromDocumentTimerFired(TimerBase*); |
| |
| void SetError(MediaError* error); |
| void ReportCurrentTimeToMediaSource(); |
| |
| Features GetFeatures() override; |
| |
| HeapTaskRunnerTimer<HTMLMediaElement> load_timer_; |
| HeapTaskRunnerTimer<HTMLMediaElement> progress_event_timer_; |
| HeapTaskRunnerTimer<HTMLMediaElement> playback_progress_timer_; |
| HeapTaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_; |
| HeapTaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_; |
| |
| Member<TimeRanges> played_time_ranges_; |
| Member<EventQueue> async_event_queue_; |
| |
| double playback_rate_; |
| double default_playback_rate_; |
| NetworkState network_state_; |
| ReadyState ready_state_; |
| ReadyState ready_state_maximum_; |
| KURL current_src_; |
| KURL current_src_after_redirects_; |
| Member<MediaStreamDescriptor> src_object_; |
| |
| // To prevent potential regression when extended by the MSE API, do not set |
| // |error_| outside of constructor and SetError(). |
| Member<MediaError> error_; |
| |
| double volume_; |
| double last_seek_time_; |
| |
| base::Optional<base::ElapsedTimer> previous_progress_time_; |
| |
| // Cached duration to suppress duplicate events if duration unchanged. |
| double duration_; |
| |
| // The last time a timeupdate event was sent in movie time. |
| double last_time_update_event_media_time_; |
| |
| // The default playback start position. |
| double default_playback_start_position_; |
| |
| // Loading state. |
| enum LoadState { |
| kWaitingForSource, |
| kLoadingFromSrcObject, |
| kLoadingFromSrcAttr, |
| kLoadingFromSourceElement |
| }; |
| LoadState load_state_; |
| Member<HTMLSourceElement> current_source_node_; |
| Member<Node> next_child_node_to_consider_; |
| |
| // "Deferred loading" state (for preload=none). |
| enum DeferredLoadState { |
| // The load is not deferred. |
| kNotDeferred, |
| // The load is deferred, and waiting for the task to set the |
| // delaying-the-load-event flag (to false). |
| kWaitingForStopDelayingLoadEventTask, |
| // The load is the deferred, and waiting for a triggering event. |
| kWaitingForTrigger, |
| // The load is deferred, and waiting for the task to set the |
| // delaying-the-load-event flag, after which the load will be executed. |
| kExecuteOnStopDelayingLoadEventTask |
| }; |
| DeferredLoadState deferred_load_state_; |
| HeapTaskRunnerTimer<HTMLMediaElement> deferred_load_timer_; |
| |
| std::unique_ptr<WebMediaPlayer> web_media_player_; |
| cc::Layer* cc_layer_; |
| |
| // These two fields must be carefully set and reset: the actual derived type |
| // of the attachment (same-thread vs cross-thread, for instance) must be the |
| // same semantic as the actual derived type of the tracer. Further, if there |
| // is no attachment, then there must be no tracer that's tracking an active |
| // attachment. Note that some kinds of attachments do not require a tracer; |
| // see MediaSourceAttachment::StartAttachingToMediaElement() for details. |
| scoped_refptr<MediaSourceAttachment> media_source_attachment_; |
| Member<MediaSourceTracer> media_source_tracer_; |
| |
| // Stores "official playback position", updated periodically from "current |
| // playback position". Official playback position should not change while |
| // scripts are running. See setOfficialPlaybackPosition(). |
| mutable double official_playback_position_; |
| mutable bool official_playback_position_needs_update_; |
| |
| double fragment_end_time_; |
| |
| typedef unsigned PendingActionFlags; |
| PendingActionFlags pending_action_flags_; |
| |
| // FIXME: HTMLMediaElement has way too many state bits. |
| bool playing_ : 1; |
| bool should_delay_load_event_ : 1; |
| bool have_fired_loaded_data_ : 1; |
| bool can_autoplay_ : 1; |
| bool muted_ : 1; |
| bool paused_ : 1; |
| bool seeking_ : 1; |
| bool paused_by_context_paused_ : 1; |
| bool show_poster_flag_ : 1; |
| |
| // data has not been loaded since sending a "stalled" event |
| bool sent_stalled_event_ : 1; |
| |
| bool ignore_preload_none_ : 1; |
| |
| bool text_tracks_visible_ : 1; |
| bool should_perform_automatic_track_selection_ : 1; |
| |
| bool tracks_are_ready_ : 1; |
| bool processing_preference_change_ : 1; |
| |
| bool was_always_muted_ : 1; |
| |
| // Whether or not |web_media_player_| should apply pitch adjustments at |
| // playback raters other than 1.0. |
| bool preserves_pitch_ = true; |
| |
| // Keeps track of when the player seek event was sent to the browser process. |
| base::TimeTicks last_seek_update_time_; |
| |
| Member<AudioTrackList> audio_tracks_; |
| Member<VideoTrackList> video_tracks_; |
| Member<TextTrackList> text_tracks_; |
| HeapVector<Member<TextTrack>> text_tracks_when_resource_selection_began_; |
| |
| Member<CueTimeline> cue_timeline_; |
| |
| HeapVector<Member<ScriptPromiseResolver>> play_promise_resolvers_; |
| TaskHandle play_promise_resolve_task_handle_; |
| TaskHandle play_promise_reject_task_handle_; |
| HeapVector<Member<ScriptPromiseResolver>> play_promise_resolve_list_; |
| HeapVector<Member<ScriptPromiseResolver>> play_promise_reject_list_; |
| DOMExceptionCode play_promise_error_code_; |
| |
| // HTMLMediaElement and its MediaElementAudioSourceNode in case it is provided |
| // die together. |
| Member<AudioSourceProviderClient> audio_source_node_; |
| |
| // AudioClientImpl wraps an AudioSourceProviderClient. |
| // When the audio format is known, Chromium calls setFormat(). |
| class AudioClientImpl final : public GarbageCollected<AudioClientImpl>, |
| public WebAudioSourceProviderClient { |
| public: |
| explicit AudioClientImpl(AudioSourceProviderClient* client) |
| : client_(client) {} |
| |
| ~AudioClientImpl() override = default; |
| |
| // WebAudioSourceProviderClient |
| void SetFormat(uint32_t number_of_channels, float sample_rate) override; |
| |
| void Trace(Visitor*) const; |
| |
| private: |
| Member<AudioSourceProviderClient> client_; |
| }; |
| |
| // AudioSourceProviderImpl wraps a WebAudioSourceProvider. |
| // provideInput() calls into Chromium to get a rendered audio stream. |
| class AudioSourceProviderImpl final : public AudioSourceProvider { |
| DISALLOW_NEW(); |
| |
| public: |
| AudioSourceProviderImpl() = default; |
| ~AudioSourceProviderImpl() override = default; |
| |
| // Wraps the given WebAudioSourceProvider. |
| void Wrap(scoped_refptr<WebAudioSourceProviderImpl>); |
| |
| // AudioSourceProvider |
| void SetClient(AudioSourceProviderClient*) override; |
| void ProvideInput(AudioBus*, uint32_t frames_to_process) override; |
| |
| void Trace(Visitor*) const; |
| |
| private: |
| scoped_refptr<WebAudioSourceProviderImpl> web_audio_source_provider_; |
| Member<AudioClientImpl> client_; |
| Mutex provide_input_lock; |
| }; |
| |
| AudioSourceProviderImpl audio_source_provider_; |
| |
| friend class AutoplayPolicy; |
| friend class AutoplayUmaHelperTest; |
| friend class Internals; |
| friend class TrackDisplayUpdateScope; |
| friend class MediaControlsImplTest; |
| friend class HTMLMediaElementTest; |
| friend class HTMLMediaElementEventListenersTest; |
| friend class HTMLVideoElement; |
| friend class MediaControlInputElementTest; |
| friend class MediaControlsOrientationLockDelegateTest; |
| friend class MediaControlsRotateToFullscreenDelegateTest; |
| friend class MediaControlLoadingPanelElementTest; |
| friend class ContextMenuControllerTest; |
| friend class HTMLVideoElementTest; |
| |
| Member<AutoplayPolicy> autoplay_policy_; |
| |
| WebRemotePlaybackClient* remote_playback_client_; |
| |
| Member<MediaControls> media_controls_; |
| Member<HTMLMediaElementControlsList> controls_list_; |
| |
| Member<IntersectionObserver> lazy_load_intersection_observer_; |
| |
| HeapMojoAssociatedRemote<media::mojom::blink::MediaPlayerHost> |
| media_player_host_remote_; |
| |
| // Multiple objects outside of the renderer process can register as observers, |
| // so we need to store the remotes in a set here. |
| HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver> |
| media_player_observer_remote_set_; |
| |
| // A receiver set is needed here as there will be different objects in the |
| // browser communicating with this object. This is done this way to avoid |
| // routing everything through a single class (e.g. RFHI) and to keep this |
| // logic contained inside MediaPlayer-related classes. |
| HeapMojoAssociatedReceiverSet<media::mojom::blink::MediaPlayer, |
| HTMLMediaElement> |
| media_player_receiver_set_; |
| }; |
| |
| template <> |
| inline bool IsElementOfType<const HTMLMediaElement>(const Node& node) { |
| return IsA<HTMLMediaElement>(node); |
| } |
| template <> |
| struct DowncastTraits<HTMLMediaElement> { |
| static bool AllowFrom(const Node& node) { |
| auto* html_element = DynamicTo<HTMLElement>(node); |
| return html_element && AllowFrom(*html_element); |
| } |
| static bool AllowFrom(const HTMLElement& html_element) { |
| return IsA<HTMLAudioElement>(html_element) || |
| IsA<HTMLVideoElement>(html_element); |
| } |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_ |