2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_
28 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_
32 #include "base/synchronization/lock.h"
33 #include "base/thread_annotations.h"
34 #include "base/time/time.h"
35 #include "base/timer/elapsed_timer.h"
36 #include "media/mojo/mojom/media_player.mojom-blink.h"
37 #include "third_party/abseil-cpp/absl/types/optional.h"
38 #include "third_party/abseil-cpp/absl/types/variant.h"
39 #include "third_party/blink/public/common/media/display_type.h"
40 #include "third_party/blink/public/platform/web_media_player_client.h"
41 #include "third_party/blink/public/platform/webaudiosourceprovider_impl.h"
42 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
43 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
44 #include "third_party/blink/renderer/core/core_export.h"
45 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
46 #include "third_party/blink/renderer/core/html/html_element.h"
47 #include "third_party/blink/renderer/core/html/media/media_controls.h"
48 #include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
49 #include "third_party/blink/renderer/core/speech/speech_synthesis_base.h"
50 #include "third_party/blink/renderer/platform/audio/audio_source_provider.h"
51 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
52 #include "third_party/blink/renderer/platform/heap/disallow_new_wrapper.h"
53 #include "third_party/blink/renderer/platform/heap/prefinalizer.h"
54 #include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
55 #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h"
56 #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
57 #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_set.h"
58 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
59 #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
60 #include "third_party/blink/renderer/platform/supplementable.h"
61 #include "third_party/blink/renderer/platform/timer.h"
62 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
63 #include "third_party/blink/renderer/platform/wtf/vector.h"
64 #include "third_party/webrtc_overrides/low_precision_timer.h"
71 enum class MediaContentType;
76 class AudioSourceProviderClient;
85 class HTMLMediaElementControlsList;
86 class HTMLSourceElement;
87 class HTMLTrackElement;
89 class MediaSourceAttachment;
90 class MediaSourceHandle;
91 class MediaSourceTracer;
92 class MediaStreamDescriptor;
93 class ScriptPromiseResolver;
96 class TextTrackContainer;
100 class VideoTrackList;
101 class WebRemotePlaybackClient;
103 class CORE_EXPORT HTMLMediaElement
104 : public HTMLElement,
105 public Supplementable<HTMLMediaElement>,
106 public ActiveScriptWrappable<HTMLMediaElement>,
107 public ExecutionContextLifecycleStateObserver,
108 public media::mojom::blink::MediaPlayer,
109 private WebMediaPlayerClient {
110 DEFINE_WRAPPERTYPEINFO();
111 USING_PRE_FINALIZER(HTMLMediaElement, Dispose);
114 // Limits the range of media playback rate.
115 static constexpr double kMinPlaybackRate = 0.0625;
116 static constexpr double kMaxPlaybackRate = 16.0;
118 enum class PlayPromiseError {
122 kPaused_EndOfPlayback,
123 kPaused_RemovedFromDocument,
124 kPaused_AutoplayAutoPause,
125 kPaused_BackgroundVideoOptimization,
126 kPaused_SuspendedPlayerIdleTimeout,
127 kPaused_RemotePlayStateChange,
128 kPaused_PauseRequestedByUser,
129 kPaused_PauseRequestedInternally,
132 bool IsMediaElement() const override { return true; }
134 static MIMETypeRegistry::SupportsType GetSupportsType(const ContentType&);
136 enum class RecordMetricsBehavior { kDoNotRecord, kDoRecord };
138 static bool IsHLSURL(const KURL&);
140 // Notify the HTMLMediaElement that the media controls settings have changed
141 // for the given document.
142 static void OnMediaControlsEnabledChange(Document*);
144 // Binds |pending_receiver| and adds it to |media_player_receiver_set_|. Also
145 // called from other Blink classes (e.g. PictureInPictureControllerImpl).
146 void BindMediaPlayerReceiver(
147 mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayer>
150 void Trace(Visitor*) const override;
152 WebMediaPlayer* GetWebMediaPlayer() const { return web_media_player_.get(); }
154 // Returns true if the loaded media has a video track.
155 // Note that even an audio element can have video track in cases such as
156 // <audio src="video.webm">, in which case this function will return true.
157 bool HasVideo() const;
159 // Returns true if loaded media has an audio track.
160 bool HasAudio() const;
162 // Whether the media element has encrypted audio or video streams.
163 bool IsEncrypted() const;
165 bool SupportsSave() const;
166 bool SupportsLoop() const;
168 cc::Layer* CcLayer() const;
170 enum DelayedActionType {
171 kLoadMediaResource = 1 << 0,
172 kLoadTextTrackResource = 1 << 1
174 void ScheduleTextTrackResourceLoad();
177 MediaError* error() const;
180 void SetSrc(const AtomicString&);
181 const KURL& currentSrc() const { return current_src_.GetSourceIfVisible(); }
183 // Return the URL to be used for downloading the media.
184 const KURL& downloadURL() const {
185 // If we didn't get a redirected URL from the player, then use the original.
186 if (current_src_after_redirects_.IsNull() ||
187 current_src_after_redirects_.IsEmpty()) {
190 return current_src_after_redirects_;
193 using SrcObjectVariant =
194 absl::variant<MediaStreamDescriptor*, MediaSourceHandle*>;
195 void SetSrcObjectVariant(SrcObjectVariant src_object_variant);
196 SrcObjectVariant GetSrcObjectVariant() const;
204 NetworkState getNetworkState() const;
206 String preload() const;
207 void setPreload(const AtomicString&);
208 WebMediaPlayer::Preload PreloadType() const;
209 String EffectivePreload() const;
210 WebMediaPlayer::Preload EffectivePreloadType() const;
212 WebTimeRanges BufferedInternal() const;
213 TimeRanges* buffered() const;
215 String canPlayType(const String& mime_type) const;
225 ReadyState getReadyState() const;
226 bool seeking() const;
229 double currentTime() const;
230 void setCurrentTime(double);
231 double duration() const;
233 double defaultPlaybackRate() const;
234 void setDefaultPlaybackRate(double);
235 double playbackRate() const;
236 void setPlaybackRate(double, ExceptionState& = ASSERT_NO_EXCEPTION);
237 TimeRanges* played();
238 WebTimeRanges SeekableInternal() const;
239 TimeRanges* seekable() const;
241 bool Autoplay() const;
244 ScriptPromise playForBindings(ScriptState*);
245 absl::optional<DOMExceptionCode> Play();
247 // Called when the video should pause to let audio descriptions finish.
248 void PauseToLetDescriptionFinish();
251 double latencyHint() const;
252 void setLatencyHint(double);
253 bool preservesPitch() const;
254 void setPreservesPitch(bool);
255 void FlingingStarted();
256 void FlingingStopped();
259 uint64_t webkitAudioDecodedByteCount() const;
260 uint64_t webkitVideoDecodedByteCount() const;
262 // media source extensions
263 void CloseMediaSource();
264 void DurationChanged(double duration, bool request_seek);
267 bool ShouldShowControls(
268 const RecordMetricsBehavior = RecordMetricsBehavior::kDoNotRecord) const;
269 bool ShouldShowAllControls() const;
270 DOMTokenList* controlsList() const;
271 HTMLMediaElementControlsList* ControlsListInternal() const;
272 double volume() const;
273 void setVolume(double, ExceptionState& = ASSERT_NO_EXCEPTION);
276 virtual bool SupportsPictureInPicture() const { return false; }
277 void SetUserWantsControlsVisible(bool visible);
278 bool UserWantsControlsVisible() const;
280 void TogglePlayState();
282 AudioTrackList& audioTracks();
283 void AudioTrackChanged(AudioTrack*);
285 VideoTrackList& videoTracks();
286 void SelectedVideoTrackChanged(VideoTrack*);
288 TextTrack* addTextTrack(const AtomicString& kind,
289 const AtomicString& label,
290 const AtomicString& language,
293 TextTrackList* textTracks();
294 CueTimeline& GetCueTimeline();
296 // Implements the "forget the media element's media-resource-specific tracks"
297 // algorithm in the HTML5 spec.
298 void ForgetResourceSpecificTracks();
300 void DidAddTrackElement(HTMLTrackElement*);
301 void DidRemoveTrackElement(HTMLTrackElement*);
303 void HonorUserPreferencesForAutomaticTextTrackSelection();
305 bool TextTracksAreReady() const;
306 void ConfigureTextTrackDisplay();
307 void UpdateTextTrackDisplay();
309 // Get a SpeechSynthesis interface to use for generating speech for audio
311 SpeechSynthesisBase* SpeechSynthesis();
312 double LastSeekTime() const { return last_seek_time_; }
313 void TextTrackReadyStateChanged(TextTrack*);
315 void TextTrackModeChanged(TextTrack*);
316 void DisableAutomaticTextTrackSelection();
318 // EventTarget function.
319 // Both Node (via HTMLElement) and ExecutionContextLifecycleStateObserver
320 // define this method, which causes an ambiguity error at compile time. This
321 // class's constructor ensures that both implementations return document, so
322 // return the result of one of them here.
323 using HTMLElement::GetExecutionContext;
325 bool IsFullscreen() const;
326 virtual bool UsesOverlayFullscreenVideo() const { return false; }
328 bool HasClosedCaptions() const;
329 bool TextTracksVisible() const;
331 static void SetTextTrackKindUserPreferenceForAllMediaElements(Document*);
332 void AutomaticTrackSelectionForUpdatedUserPreference();
334 // Returns the MediaControls, or null if they have not been added yet.
335 // Note that this can be non-null even if there is no controls attribute.
336 MediaControls* GetMediaControls() const;
338 // Notifies the media element that the media controls became visible, so
339 // that text track layout may be updated to avoid overlapping them.
340 void MediaControlsDidBecomeVisible();
342 void SourceWasRemoved(HTMLSourceElement*);
343 void SourceWasAdded(HTMLSourceElement*);
345 // ScriptWrappable functions.
346 bool HasPendingActivity() const override;
348 AudioSourceProviderClient* AudioSourceNode() {
349 return audio_source_node_.Get();
351 void SetAudioSourceNode(AudioSourceProviderClient*);
353 AudioSourceProvider& GetAudioSourceProvider() {
354 return audio_source_provider_;
357 enum InvalidURLAction { kDoNothing, kComplain };
358 bool IsSafeToLoadURL(const KURL&, InvalidURLAction);
360 // Checks to see if current media data is CORS-same-origin.
361 bool IsMediaDataCorsSameOrigin() const;
363 void ScheduleEvent(Event*);
365 // Returns the "effective media volume" value as specified in the HTML5 spec.
366 double EffectiveMediaVolume() const;
368 // Predicates also used when dispatching wrapper creation (cf.
369 // [SpecialWrapFor] IDL attribute usage.)
370 virtual bool IsHTMLAudioElement() const { return false; }
371 virtual bool IsHTMLVideoElement() const { return false; }
373 void VideoWillBeDrawnToCanvas() const;
375 const WebRemotePlaybackClient* RemotePlaybackClient() const {
376 return remote_playback_client_;
379 const AutoplayPolicy& GetAutoplayPolicy() const { return *autoplay_policy_; }
381 WebMediaPlayer::LoadType GetLoadType() const;
383 #if BUILDFLAG(IS_TIZEN_TV)
384 WebString GetContentMIMEType() override;
385 void RequestReload(const KURL& new_url);
386 void SetTranslatedURL(const String&) override;
387 bool IsHTMLMediaElement() const override { return true; }
388 WTF::String GetUrl() const override { return current_src_.GetSource(); }
389 void SetParentalRatingResult(bool is_pass) override;
392 #if defined(TIZEN_MULTIMEDIA)
393 void OnLivePlaybackComplete() override;
396 bool HasMediaSource() const { return media_source_attachment_.get(); }
398 // Return true if element is paused and won't resume automatically if it
399 // becomes visible again.
400 bool PausedWhenVisible() const;
402 void DidAudioOutputSinkChanged(const String& hashed_device_id);
404 void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); }
406 // This should be called directly after creation.
407 void SetMediaPlayerHostForTesting(
408 mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerHost> host);
410 bool IsShowPosterFlagSet() const { return show_poster_flag_; }
412 // What LocalFrame should own our player? Normally, players are tied to their
413 // HTMLMediaElement's LocalFrame for metrics, network fetch, etc. This has
414 // the side-effect of requiring that a player is destroyed when the element's
415 // frame changes. That causes playback to be user-visibly interrupted,
416 // potentially for multiple seconds.
418 // In some very restricted cases, related to picture-in-picture playback, it
419 // is okay to keep the player even when the element is moved to a new
420 // document. It requires that everything is same-origin, and that lifetimes
421 // are looked after carefully so that the player does not outlive the frame
422 // that owns it. However, it permits seamless playback when transitioning to
423 // picture in picture. In this case, this function will return a different
424 // frame than our own.
426 // Note that new players can be created in this frame as well, so that a
427 // transfer back to the original opener frame when picture in picture is
428 // closed can be seamless too, even if the player was recreated for some
429 // reason while in picture in picture mode.
430 LocalFrame* LocalFrameForPlayer();
433 // Assert the correct order of the children in shadow dom when DCHECK is on.
434 static void AssertShadowRootChildren(ShadowRoot&);
436 HTMLMediaElement(const QualifiedName&, Document&);
437 ~HTMLMediaElement() override;
440 // Returns a constant reference to the HeapMojoAssociatedRemoteSet holding all
441 // the bound remotes for the media::mojom::blink::MediaPlayerObserver
442 // interface. Needed to allow sending messages directly from
443 // HTMLMediaElement's subclasses.
444 const HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>&
445 GetMediaPlayerObserverRemoteSet() {
446 return media_player_observer_remote_set_->Value();
449 void ParseAttribute(const AttributeModificationParams&) override;
450 void FinishParsingChildren() final;
451 bool IsURLAttribute(const Attribute&) const override;
452 void AttachLayoutTree(AttachContext&) override;
453 void ParserDidSetAttributes() override;
454 void CloneNonAttributePropertiesFrom(const Element&,
455 NodeCloningData&) override;
457 InsertionNotificationRequest InsertedInto(ContainerNode&) override;
458 void RemovedFrom(ContainerNode&) override;
460 // Return true if media is cross origin from the current document
461 // and has not passed a cors check, meaning that we should return
462 // as little information as possible about it.
463 bool MediaShouldBeOpaque() const;
465 void DidMoveToNewDocument(Document& old_document) override;
466 virtual KURL PosterImageURL() const { return KURL(); }
468 // Called after the creation of |web_media_player_|.
469 virtual void OnWebMediaPlayerCreated() {}
470 virtual void OnWebMediaPlayerCleared() {}
472 void UpdateLayoutObject();
475 // Friend class for testing.
476 friend class ContextMenuControllerTest;
477 friend class HTMLMediaElementTest;
478 friend class PictureInPictureControllerTestWithWidget;
479 friend class VideoWakeLockTest;
481 class SourceMetadata {
485 enum class SourceVisibility { kVisibleToApp, kInvisibleToApp };
486 SourceMetadata() = default;
487 void SetSource(const KURL& src, SourceVisibility visibility) {
489 invisible_to_app_ = visibility == SourceVisibility::kInvisibleToApp;
491 const KURL& GetSourceIfVisible() const {
492 return invisible_to_app_ ? NullURL() : src_;
494 const KURL& GetSource() const { return src_; }
499 // If true, then |current_src| is used only for internal loading and safety
500 // checks, and for logging that is not visible to apps, either. For example,
501 // when loading from a MediaSourceHandle as srcObject, this would be true.
502 bool invisible_to_app_ = false;
505 bool HasPendingActivityInternal() const;
507 void ResetMediaPlayerAndMediaSource();
509 bool AlwaysCreateUserAgentShadowRoot() const final { return true; }
510 bool AreAuthorShadowsAllowed() const final { return false; }
512 bool SupportsFocus() const final;
514 bool disallow_layout_updates_for_accessibility_only = false) const final;
515 bool IsKeyboardFocusable() const final;
516 int DefaultTabIndex() const final;
517 bool LayoutObjectIsNeeded(const DisplayStyle&) const override;
518 LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
519 void DidNotifySubtreeInsertionsToDocument() override;
520 void DidRecalcStyle(const StyleRecalcChange) final;
522 bool CanStartSelection() const override { return false; }
524 bool IsInteractiveContent() const final;
526 // ExecutionContextLifecycleStateObserver functions.
527 void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
528 void ContextDestroyed() override;
530 virtual void OnPlay() {}
531 virtual void OnLoadStarted() {}
532 virtual void OnLoadFinished() {}
534 // Handles playing of media element when audio descriptions are finished
536 void OnSpeakingCompleted();
538 void SetShowPosterFlag(bool value);
540 void SetReadyState(ReadyState);
541 void SetNetworkState(WebMediaPlayer::NetworkState);
543 // WebMediaPlayerClient implementation.
544 void NetworkStateChanged() final;
545 void ReadyStateChanged() final;
546 void TimeChanged() final;
547 void Repaint() final;
548 void DurationChanged() final;
549 void SizeChanged() final;
550 void OnFirstFrame(base::TimeTicks frame_time,
551 size_t bytes_to_first_frame) override {}
553 void SetCcLayer(cc::Layer*) final;
554 WebMediaPlayer::TrackId AddAudioTrack(const WebString&,
555 WebMediaPlayerClient::AudioTrackKind,
559 void RemoveAudioTrack(WebMediaPlayer::TrackId) final;
560 WebMediaPlayer::TrackId AddVideoTrack(const WebString&,
561 WebMediaPlayerClient::VideoTrackKind,
565 void RemoveVideoTrack(WebMediaPlayer::TrackId) final;
566 void MediaSourceOpened(WebMediaSource*) final;
567 void RemotePlaybackCompatibilityChanged(const WebURL&,
568 bool is_compatible) final;
569 bool HasSelectedVideoTrack() final;
570 WebMediaPlayer::TrackId GetSelectedVideoTrackId() final;
571 bool WasAlwaysMuted() final;
572 bool HasNativeControls() final;
573 bool IsAudioElement() final;
574 DisplayType GetDisplayType() const override;
575 WebRemotePlaybackClient* RemotePlaybackClient() final {
576 return remote_playback_client_;
578 gfx::ColorSpace TargetColorSpace() override;
579 bool WasAutoplayInitiated() override;
580 bool IsInAutoPIP() const override { return false; }
581 void ResumePlayback() final;
582 void PausePlayback(PauseReason) final;
583 void DidPlayerStartPlaying() override;
584 void DidPlayerPaused(bool stream_ended) override;
585 void DidPlayerMutedStatusChange(bool muted) override;
586 void DidMediaMetadataChange(bool has_audio,
588 media::AudioCodec audio_codec,
589 media::VideoCodec video_codec,
590 media::MediaContentType media_content_type,
591 bool is_encrypted_media) override;
592 void DidPlayerMediaPositionStateChange(double playback_rate,
593 base::TimeDelta duration,
594 base::TimeDelta position,
595 bool end_of_media) override;
596 void DidDisableAudioOutputSinkChanges() override;
597 void DidUseAudioServiceChange(bool uses_audio_service) override;
598 void DidPlayerSizeChange(const gfx::Size& size) override;
599 void OnRemotePlaybackDisabled(bool disabled) override;
600 #if defined(TIZEN_MULTIMEDIA)
601 void SuspendPlayer() override;
604 // Returns a reference to the mojo remote for the MediaPlayerHost interface,
605 // requesting it first from the BrowserInterfaceBroker if needed. It is an
606 // error to call this method before having access to the document's frame.
607 media::mojom::blink::MediaPlayerHost& GetMediaPlayerHostRemote();
609 // media::mojom::MediaPlayer implementation.
610 void RequestPlay() override;
611 void RequestPause(bool triggered_by_user) override;
612 void RequestSeekForward(base::TimeDelta seek_time) override;
613 void RequestSeekBackward(base::TimeDelta seek_time) override;
614 void RequestSeekTo(base::TimeDelta seek_time) override;
615 void RequestEnterPictureInPicture() override {}
616 void RequestMute(bool mute) override;
617 void SetVolumeMultiplier(double multiplier) override;
618 void SetPersistentState(bool persistent) override {}
619 void SetPowerExperimentState(bool enabled) override;
620 void SetAudioSinkId(const String&) override;
621 void SuspendForFrameClosed() override;
622 void RequestMediaRemoting() override {}
624 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
625 void MediaPlayerHidden() final;
626 void MediaPlayerShown() final;
629 void NotifyPlayingUrl();
632 void LoadTimerFired(TimerBase*);
633 void ProgressEventTimerFired();
634 void PlaybackProgressTimerFired();
635 void ScheduleTimeupdateEvent(bool periodic_event);
636 void StartPlaybackProgressTimer();
637 void StartProgressEventTimer();
638 void StopPeriodicTimers();
640 void Seek(double time);
642 void AddPlayedRange(double start, double end);
644 // FIXME: Rename to scheduleNamedEvent for clarity.
645 void ScheduleEvent(const AtomicString& event_name);
648 void InvokeLoadAlgorithm();
649 void InvokeResourceSelectionAlgorithm();
651 void SelectMediaResource();
652 void LoadResource(const WebMediaPlayerSource&, const String& content_type);
653 void StartPlayerLoad();
654 void SetPlayerPreload();
655 void ScheduleNextSourceChild();
656 void LoadSourceFromObject();
657 void LoadSourceFromAttribute();
658 void LoadNextSourceChild();
659 void ClearMediaPlayer();
660 void ClearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
661 bool HavePotentialSourceChild();
662 void NoneSupported(const String&);
663 void MediaEngineError(MediaError*);
664 void CancelPendingEventsAndCallbacks();
665 void WaitForSourceChange();
666 void SetIgnorePreloadNone();
668 KURL SelectNextSourceChild(String* content_type, InvalidURLAction);
670 void MediaLoadingFailed(WebMediaPlayer::NetworkState, const String&);
672 // deferred loading (preload=none)
673 bool LoadIsDeferred() const;
675 void CancelDeferredLoad();
676 void StartDeferredLoad();
677 void ExecuteDeferredLoad();
678 void DeferredLoadTimerFired(TimerBase*);
680 void MarkCaptionAndSubtitleTracksAsUnconfigured();
682 // This does not check user gesture restrictions.
685 // This does not stop autoplay visibility observation.
686 // By default, will pause the video and speech.
687 void PauseInternal(PlayPromiseError code, bool pause_speech = true);
689 // By default, will pause the video and speech.
690 void UpdatePlayState(bool pause_speech = true);
692 bool PotentiallyPlaying() const;
693 bool StoppedDueToErrors() const;
694 bool CouldPlayIfEnoughData() const override;
696 // Generally the presence of the loop attribute should be considered to mean
697 // playback has not "ended", as "ended" and "looping" are mutually exclusive.
699 // https://html.spec.whatwg.org/C/#ended-playback
700 enum class LoopCondition { kIncluded, kIgnored };
701 bool EndedPlayback(LoopCondition = LoopCondition::kIncluded) const;
703 void SetShouldDelayLoadEvent(bool);
705 double EarliestPossiblePosition() const;
706 double CurrentPlaybackPosition() const;
707 double OfficialPlaybackPosition() const;
708 void SetOfficialPlaybackPosition(double) const;
709 void RequireOfficialPlaybackPositionUpdate() const;
711 void EnsureMediaControls();
712 void UpdateControlsVisibility();
714 TextTrackContainer& EnsureTextTrackContainer();
716 void ChangeNetworkStateFromLoadingToIdle();
718 WebMediaPlayer::CorsMode CorsMode() const;
720 // Returns the "direction of playback" value as specified in the HTML5 spec.
721 enum DirectionOfPlayback { kBackward, kForward };
722 DirectionOfPlayback GetDirectionOfPlayback() const;
724 // Creates placeholder AudioTrack and/or VideoTrack objects when
725 // WebMediaPlayer objects advertise they have audio and/or video, but don't
726 // explicitly signal them via addAudioTrack() and addVideoTrack().
727 // FIXME: Remove this once all WebMediaPlayer implementations properly report
729 void CreatePlaceholderTracksIfNecessary();
731 void SetNetworkState(NetworkState, bool update_media_controls = true);
733 void AudioTracksTimerFired(TimerBase*);
735 void ScheduleResolvePlayPromises();
736 void ScheduleRejectPlayPromises(PlayPromiseError);
737 void ScheduleNotifyPlaying();
738 void ResolveScheduledPlayPromises();
739 void RejectScheduledPlayPromises();
740 void RejectPlayPromises(DOMExceptionCode, const String&);
741 void RejectPlayPromisesInternal(DOMExceptionCode, const String&);
743 void OnRemovedFromDocumentTimerFired(TimerBase*);
745 void SetError(MediaError* error);
746 void ReportCurrentTimeToMediaSource();
748 void ResetMojoState();
749 void OnRemotePlaybackMetadataChange();
751 // Determine if we should reuse the player when moving the element from
752 // |old_document| to |new_document|
753 bool ShouldReusePlayer(Document& old_document, Document& new_document) const;
755 // Adds a new MediaPlayerObserver remote that will be notified about media
756 // player events and returns a receiver that an observer implementation can
758 mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayerObserver>
759 AddMediaPlayerObserverAndPassReceiver();
761 // Timers used to schedule one-shot tasks with no delay.
762 HeapTaskRunnerTimer<HTMLMediaElement> load_timer_;
763 HeapTaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_;
764 HeapTaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_;
765 // Use a low precision timer for repeating tasks to avoid excessive Idle Wake
766 // Up frequency, especially when WebRTC is used and the page contains many
767 // HTMLMediaElements.
768 LowPrecisionTimer progress_event_timer_;
769 LowPrecisionTimer playback_progress_timer_;
771 Member<TimeRanges> played_time_ranges_;
772 Member<EventQueue> async_event_queue_;
774 double playback_rate_;
775 double default_playback_rate_;
776 NetworkState network_state_;
777 ReadyState ready_state_;
778 ReadyState ready_state_maximum_;
780 SourceMetadata current_src_;
781 KURL current_src_after_redirects_;
783 Member<MediaStreamDescriptor> src_object_stream_descriptor_;
784 Member<MediaSourceHandle> src_object_media_source_handle_;
786 // To prevent potential regression when extended by the MSE API, do not set
787 // |error_| outside of constructor and SetError().
788 Member<MediaError> error_;
791 double last_seek_time_;
793 absl::optional<base::ElapsedTimer> previous_progress_time_;
795 // Cached duration to suppress duplicate events if duration unchanged.
798 // The last time a timeupdate event was sent in movie time.
799 double last_time_update_event_media_time_;
801 // The default playback start position.
802 double default_playback_start_position_;
807 kLoadingFromSrcObject,
809 kLoadingFromSourceElement
811 LoadState load_state_;
812 Member<HTMLSourceElement> current_source_node_;
813 Member<Node> next_child_node_to_consider_;
815 // "Deferred loading" state (for preload=none).
816 enum DeferredLoadState {
817 // The load is not deferred.
819 // The load is deferred, and waiting for the task to set the
820 // delaying-the-load-event flag (to false).
821 kWaitingForStopDelayingLoadEventTask,
822 // The load is the deferred, and waiting for a triggering event.
824 // The load is deferred, and waiting for the task to set the
825 // delaying-the-load-event flag, after which the load will be executed.
826 kExecuteOnStopDelayingLoadEventTask
828 DeferredLoadState deferred_load_state_;
829 HeapTaskRunnerTimer<HTMLMediaElement> deferred_load_timer_;
831 std::unique_ptr<WebMediaPlayer> web_media_player_;
832 cc::Layer* cc_layer_;
834 // These two fields must be carefully set and reset: the actual derived type
835 // of the attachment (same-thread vs cross-thread, for instance) must be the
836 // same semantic as the actual derived type of the tracer. Further, if there
837 // is no attachment, then there must be no tracer that's tracking an active
838 // attachment. Note that some kinds of attachments do not require a tracer;
839 // see MediaSourceAttachment::StartAttachingToMediaElement() for details.
840 scoped_refptr<MediaSourceAttachment> media_source_attachment_;
841 Member<MediaSourceTracer> media_source_tracer_;
843 // Stores "official playback position", updated periodically from "current
844 // playback position". Official playback position should not change while
845 // scripts are running. See setOfficialPlaybackPosition().
846 mutable double official_playback_position_;
847 mutable bool official_playback_position_needs_update_;
849 double fragment_end_time_;
851 typedef unsigned PendingActionFlags;
852 PendingActionFlags pending_action_flags_;
854 // FIXME: HTMLMediaElement has way too many state bits.
856 bool should_delay_load_event_ : 1;
857 bool have_fired_loaded_data_ : 1;
858 bool can_autoplay_ : 1;
862 bool paused_by_context_paused_ : 1;
863 bool show_poster_flag_ : 1;
865 // data has not been loaded since sending a "stalled" event
866 bool sent_stalled_event_ : 1;
868 bool ignore_preload_none_ : 1;
870 bool text_tracks_visible_ : 1;
871 bool should_perform_automatic_track_selection_ : 1;
873 bool tracks_are_ready_ : 1;
874 bool processing_preference_change_ : 1;
876 bool was_always_muted_ : 1;
878 #if defined(TIZEN_MULTIMEDIA)
879 bool live_playback_complete_ : 1;
882 #if BUILDFLAG(IS_TIZEN_TV)
883 String content_mime_type_;
884 bool is_translated_url_ : 1;
886 // Set if the user has used the context menu to set the visibility of the
888 absl::optional<bool> user_wants_controls_visible_;
890 // Whether or not |web_media_player_| should apply pitch adjustments at
891 // playback raters other than 1.0.
892 bool preserves_pitch_ = true;
894 #if BUILDFLAG(IS_TIZEN_TV)
895 bool is_deactivate_ : 1;
898 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
899 // This is to suppress stuff set to JS. Do not use it for other purposes.
900 bool suppress_events_ : 1;
903 // Whether the player disables the Remote Playback feature.
904 bool is_remote_playback_disabled_ = false;
905 // Whether the player is rendering remotely.
906 bool is_remote_rendering_ = false;
907 // Whether the media content is encrypted.
908 bool is_encrypted_media_ = false;
909 WebString remote_device_friendly_name_;
910 media::AudioCodec audio_codec_ = media::AudioCodec::kUnknown;
911 media::VideoCodec video_codec_ = media::VideoCodec::kUnknown;
913 Member<AudioTrackList> audio_tracks_;
914 Member<VideoTrackList> video_tracks_;
915 Member<TextTrackList> text_tracks_;
916 HeapVector<Member<TextTrack>> text_tracks_when_resource_selection_began_;
918 Member<CueTimeline> cue_timeline_;
920 HeapVector<Member<ScriptPromiseResolver>> play_promise_resolvers_;
921 TaskHandle play_promise_resolve_task_handle_;
922 TaskHandle play_promise_reject_task_handle_;
923 HeapVector<Member<ScriptPromiseResolver>> play_promise_resolve_list_;
924 HeapVector<Member<ScriptPromiseResolver>> play_promise_reject_list_;
925 PlayPromiseError play_promise_error_code_;
927 // HTMLMediaElement and its MediaElementAudioSourceNode in case it is provided
929 Member<AudioSourceProviderClient> audio_source_node_;
931 // Controls browser vocalization within the media element (e.g. to speak cues,
932 // to pause utterance).
933 Member<SpeechSynthesisBase> speech_synthesis_;
935 // AudioClientImpl wraps an AudioSourceProviderClient.
936 // When the audio format is known, Chromium calls setFormat().
937 class AudioClientImpl final : public GarbageCollected<AudioClientImpl>,
938 public WebAudioSourceProviderClient {
940 explicit AudioClientImpl(AudioSourceProviderClient* client)
943 ~AudioClientImpl() override = default;
945 // WebAudioSourceProviderClient
946 void SetFormat(uint32_t number_of_channels, float sample_rate) override;
948 void Trace(Visitor*) const;
951 Member<AudioSourceProviderClient> client_;
954 // AudioSourceProviderImpl wraps a WebAudioSourceProvider.
955 // provideInput() calls into Chromium to get a rendered audio stream.
956 class AudioSourceProviderImpl final : public AudioSourceProvider {
960 AudioSourceProviderImpl() = default;
961 ~AudioSourceProviderImpl() override = default;
963 // Wraps the given WebAudioSourceProvider.
964 void Wrap(scoped_refptr<WebAudioSourceProviderImpl>);
966 // AudioSourceProvider
967 void SetClient(AudioSourceProviderClient*) override;
968 void ProvideInput(AudioBus*, int frames_to_process) override;
970 void Trace(Visitor*) const;
973 base::Lock provide_input_lock;
974 scoped_refptr<WebAudioSourceProviderImpl> web_audio_source_provider_
975 GUARDED_BY(provide_input_lock);
976 Member<AudioClientImpl> client_;
979 AudioSourceProviderImpl audio_source_provider_;
981 // Notify HTMLMediaElement when a document's ExecutionContext is destroyed.
982 // It allows us to disconnect from a previous document's frame if we were
983 // using it to support our WebMediaPlayer rather than our current frame.
984 class OpenerContextObserver final
985 : public GarbageCollected<OpenerContextObserver>,
986 public ContextLifecycleObserver {
988 // Notify `element` when our context is destroyed.
989 explicit OpenerContextObserver(HTMLMediaElement* element);
990 ~OpenerContextObserver() final;
992 void Trace(Visitor* visitor) const final;
995 void ContextDestroyed() final;
997 Member<HTMLMediaElement> element_;
1000 // Clean up things that are tied to any previous frame, including the player
1001 // and mojo interfaces, when we switch to a new frame.
1002 void AttachToNewFrame();
1004 Member<Document> opener_document_;
1005 Member<OpenerContextObserver> opener_context_observer_;
1007 friend class AutoplayPolicy;
1008 friend class AutoplayUmaHelperTest;
1009 friend class Internals;
1010 friend class TrackDisplayUpdateScope;
1011 friend class MediaControlsImplTest;
1012 friend class HTMLMediaElementTest;
1013 friend class HTMLMediaElementEventListenersTest;
1014 friend class HTMLVideoElement;
1015 friend class MediaControlInputElementTest;
1016 friend class MediaControlsOrientationLockDelegateTest;
1017 friend class MediaControlsRotateToFullscreenDelegateTest;
1018 friend class MediaControlLoadingPanelElementTest;
1019 friend class ContextMenuControllerTest;
1020 friend class HTMLVideoElementTest;
1022 Member<AutoplayPolicy> autoplay_policy_;
1024 WebRemotePlaybackClient* remote_playback_client_;
1026 Member<MediaControls> media_controls_;
1027 Member<HTMLMediaElementControlsList> controls_list_;
1029 Member<IntersectionObserver> lazy_load_intersection_observer_;
1031 Member<DisallowNewWrapper<
1032 HeapMojoAssociatedRemote<media::mojom::blink::MediaPlayerHost>>>
1033 media_player_host_remote_;
1035 // Note: There's only ever one entry in this set.
1036 Member<DisallowNewWrapper<
1037 HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>>>
1038 media_player_observer_remote_set_;
1040 // A receiver set is needed here as there will be different objects in the
1041 // browser communicating with this object. This is done this way to avoid
1042 // routing everything through a single class (e.g. RFHI) and to keep this
1043 // logic contained inside MediaPlayer-related classes.
1044 Member<DisallowNewWrapper<
1045 HeapMojoAssociatedReceiverSet<media::mojom::blink::MediaPlayer,
1047 media_player_receiver_set_;
1051 inline bool IsElementOfType<const HTMLMediaElement>(const Node& node) {
1052 return IsA<HTMLMediaElement>(node);
1055 struct DowncastTraits<HTMLMediaElement> {
1056 static bool AllowFrom(const Node& node) {
1057 auto* html_element = DynamicTo<HTMLElement>(node);
1058 return html_element && AllowFrom(*html_element);
1060 static bool AllowFrom(const HTMLElement& html_element) {
1061 return IsA<HTMLAudioElement>(html_element) ||
1062 IsA<HTMLVideoElement>(html_element);
1066 } // namespace blink
1068 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_