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 bool HasMediaSource() const { return media_source_attachment_.get(); }
394 // Return true if element is paused and won't resume automatically if it
395 // becomes visible again.
396 bool PausedWhenVisible() const;
398 void DidAudioOutputSinkChanged(const String& hashed_device_id);
400 void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); }
402 // This should be called directly after creation.
403 void SetMediaPlayerHostForTesting(
404 mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerHost> host);
406 bool IsShowPosterFlagSet() const { return show_poster_flag_; }
408 // What LocalFrame should own our player? Normally, players are tied to their
409 // HTMLMediaElement's LocalFrame for metrics, network fetch, etc. This has
410 // the side-effect of requiring that a player is destroyed when the element's
411 // frame changes. That causes playback to be user-visibly interrupted,
412 // potentially for multiple seconds.
414 // In some very restricted cases, related to picture-in-picture playback, it
415 // is okay to keep the player even when the element is moved to a new
416 // document. It requires that everything is same-origin, and that lifetimes
417 // are looked after carefully so that the player does not outlive the frame
418 // that owns it. However, it permits seamless playback when transitioning to
419 // picture in picture. In this case, this function will return a different
420 // frame than our own.
422 // Note that new players can be created in this frame as well, so that a
423 // transfer back to the original opener frame when picture in picture is
424 // closed can be seamless too, even if the player was recreated for some
425 // reason while in picture in picture mode.
426 LocalFrame* LocalFrameForPlayer();
429 // Assert the correct order of the children in shadow dom when DCHECK is on.
430 static void AssertShadowRootChildren(ShadowRoot&);
432 HTMLMediaElement(const QualifiedName&, Document&);
433 ~HTMLMediaElement() override;
436 // Returns a constant reference to the HeapMojoAssociatedRemoteSet holding all
437 // the bound remotes for the media::mojom::blink::MediaPlayerObserver
438 // interface. Needed to allow sending messages directly from
439 // HTMLMediaElement's subclasses.
440 const HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>&
441 GetMediaPlayerObserverRemoteSet() {
442 return media_player_observer_remote_set_->Value();
445 void ParseAttribute(const AttributeModificationParams&) override;
446 void FinishParsingChildren() final;
447 bool IsURLAttribute(const Attribute&) const override;
448 void AttachLayoutTree(AttachContext&) override;
449 void ParserDidSetAttributes() override;
450 void CloneNonAttributePropertiesFrom(const Element&,
451 NodeCloningData&) override;
453 InsertionNotificationRequest InsertedInto(ContainerNode&) override;
454 void RemovedFrom(ContainerNode&) override;
456 // Return true if media is cross origin from the current document
457 // and has not passed a cors check, meaning that we should return
458 // as little information as possible about it.
459 bool MediaShouldBeOpaque() const;
461 void DidMoveToNewDocument(Document& old_document) override;
462 virtual KURL PosterImageURL() const { return KURL(); }
464 // Called after the creation of |web_media_player_|.
465 virtual void OnWebMediaPlayerCreated() {}
466 virtual void OnWebMediaPlayerCleared() {}
468 void UpdateLayoutObject();
471 // Friend class for testing.
472 friend class ContextMenuControllerTest;
473 friend class HTMLMediaElementTest;
474 friend class PictureInPictureControllerTestWithWidget;
475 friend class VideoWakeLockTest;
477 class SourceMetadata {
481 enum class SourceVisibility { kVisibleToApp, kInvisibleToApp };
482 SourceMetadata() = default;
483 void SetSource(const KURL& src, SourceVisibility visibility) {
485 invisible_to_app_ = visibility == SourceVisibility::kInvisibleToApp;
487 const KURL& GetSourceIfVisible() const {
488 return invisible_to_app_ ? NullURL() : src_;
490 const KURL& GetSource() const { return src_; }
495 // If true, then |current_src| is used only for internal loading and safety
496 // checks, and for logging that is not visible to apps, either. For example,
497 // when loading from a MediaSourceHandle as srcObject, this would be true.
498 bool invisible_to_app_ = false;
501 bool HasPendingActivityInternal() const;
503 void ResetMediaPlayerAndMediaSource();
505 bool AlwaysCreateUserAgentShadowRoot() const final { return true; }
506 bool AreAuthorShadowsAllowed() const final { return false; }
508 bool SupportsFocus() const final;
510 bool disallow_layout_updates_for_accessibility_only = false) const final;
511 bool IsKeyboardFocusable() const final;
512 int DefaultTabIndex() const final;
513 bool LayoutObjectIsNeeded(const DisplayStyle&) const override;
514 LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
515 void DidNotifySubtreeInsertionsToDocument() override;
516 void DidRecalcStyle(const StyleRecalcChange) final;
518 bool CanStartSelection() const override { return false; }
520 bool IsInteractiveContent() const final;
522 // ExecutionContextLifecycleStateObserver functions.
523 void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
524 void ContextDestroyed() override;
526 virtual void OnPlay() {}
527 virtual void OnLoadStarted() {}
528 virtual void OnLoadFinished() {}
530 // Handles playing of media element when audio descriptions are finished
532 void OnSpeakingCompleted();
534 void SetShowPosterFlag(bool value);
536 void SetReadyState(ReadyState);
537 void SetNetworkState(WebMediaPlayer::NetworkState);
539 // WebMediaPlayerClient implementation.
540 void NetworkStateChanged() final;
541 void ReadyStateChanged() final;
542 void TimeChanged() final;
543 void Repaint() final;
544 void DurationChanged() final;
545 void SizeChanged() final;
546 void OnFirstFrame(base::TimeTicks frame_time,
547 size_t bytes_to_first_frame) override {}
549 void SetCcLayer(cc::Layer*) final;
550 WebMediaPlayer::TrackId AddAudioTrack(const WebString&,
551 WebMediaPlayerClient::AudioTrackKind,
555 void RemoveAudioTrack(WebMediaPlayer::TrackId) final;
556 WebMediaPlayer::TrackId AddVideoTrack(const WebString&,
557 WebMediaPlayerClient::VideoTrackKind,
561 void RemoveVideoTrack(WebMediaPlayer::TrackId) final;
562 void MediaSourceOpened(WebMediaSource*) final;
563 void RemotePlaybackCompatibilityChanged(const WebURL&,
564 bool is_compatible) final;
565 bool HasSelectedVideoTrack() final;
566 WebMediaPlayer::TrackId GetSelectedVideoTrackId() final;
567 bool WasAlwaysMuted() final;
568 bool HasNativeControls() final;
569 bool IsAudioElement() final;
570 DisplayType GetDisplayType() const override;
571 WebRemotePlaybackClient* RemotePlaybackClient() final {
572 return remote_playback_client_;
574 gfx::ColorSpace TargetColorSpace() override;
575 bool WasAutoplayInitiated() override;
576 bool IsInAutoPIP() const override { return false; }
577 void ResumePlayback() final;
578 void PausePlayback(PauseReason) final;
579 void DidPlayerStartPlaying() override;
580 void DidPlayerPaused(bool stream_ended) override;
581 void DidPlayerMutedStatusChange(bool muted) override;
582 void DidMediaMetadataChange(bool has_audio,
584 media::AudioCodec audio_codec,
585 media::VideoCodec video_codec,
586 media::MediaContentType media_content_type,
587 bool is_encrypted_media) override;
588 void DidPlayerMediaPositionStateChange(double playback_rate,
589 base::TimeDelta duration,
590 base::TimeDelta position,
591 bool end_of_media) override;
592 void DidDisableAudioOutputSinkChanges() override;
593 void DidUseAudioServiceChange(bool uses_audio_service) override;
594 void DidPlayerSizeChange(const gfx::Size& size) override;
595 void OnRemotePlaybackDisabled(bool disabled) override;
596 #if defined(TIZEN_MULTIMEDIA)
597 void SuspendPlayer() override;
600 // Returns a reference to the mojo remote for the MediaPlayerHost interface,
601 // requesting it first from the BrowserInterfaceBroker if needed. It is an
602 // error to call this method before having access to the document's frame.
603 media::mojom::blink::MediaPlayerHost& GetMediaPlayerHostRemote();
605 // media::mojom::MediaPlayer implementation.
606 void RequestPlay() override;
607 void RequestPause(bool triggered_by_user) override;
608 void RequestSeekForward(base::TimeDelta seek_time) override;
609 void RequestSeekBackward(base::TimeDelta seek_time) override;
610 void RequestSeekTo(base::TimeDelta seek_time) override;
611 void RequestEnterPictureInPicture() override {}
612 void RequestMute(bool mute) override;
613 void SetVolumeMultiplier(double multiplier) override;
614 void SetPersistentState(bool persistent) override {}
615 void SetPowerExperimentState(bool enabled) override;
616 void SetAudioSinkId(const String&) override;
617 void SuspendForFrameClosed() override;
618 void RequestMediaRemoting() override {}
620 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
621 void MediaPlayerHidden() final;
622 void MediaPlayerShown() final;
625 void NotifyPlayingUrl();
628 void LoadTimerFired(TimerBase*);
629 void ProgressEventTimerFired();
630 void PlaybackProgressTimerFired();
631 void ScheduleTimeupdateEvent(bool periodic_event);
632 void StartPlaybackProgressTimer();
633 void StartProgressEventTimer();
634 void StopPeriodicTimers();
636 void Seek(double time);
638 void AddPlayedRange(double start, double end);
640 // FIXME: Rename to scheduleNamedEvent for clarity.
641 void ScheduleEvent(const AtomicString& event_name);
644 void InvokeLoadAlgorithm();
645 void InvokeResourceSelectionAlgorithm();
647 void SelectMediaResource();
648 void LoadResource(const WebMediaPlayerSource&, const String& content_type);
649 void StartPlayerLoad();
650 void SetPlayerPreload();
651 void ScheduleNextSourceChild();
652 void LoadSourceFromObject();
653 void LoadSourceFromAttribute();
654 void LoadNextSourceChild();
655 void ClearMediaPlayer();
656 void ClearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
657 bool HavePotentialSourceChild();
658 void NoneSupported(const String&);
659 void MediaEngineError(MediaError*);
660 void CancelPendingEventsAndCallbacks();
661 void WaitForSourceChange();
662 void SetIgnorePreloadNone();
664 KURL SelectNextSourceChild(String* content_type, InvalidURLAction);
666 void MediaLoadingFailed(WebMediaPlayer::NetworkState, const String&);
668 // deferred loading (preload=none)
669 bool LoadIsDeferred() const;
671 void CancelDeferredLoad();
672 void StartDeferredLoad();
673 void ExecuteDeferredLoad();
674 void DeferredLoadTimerFired(TimerBase*);
676 void MarkCaptionAndSubtitleTracksAsUnconfigured();
678 // This does not check user gesture restrictions.
681 // This does not stop autoplay visibility observation.
682 // By default, will pause the video and speech.
683 void PauseInternal(PlayPromiseError code, bool pause_speech = true);
685 // By default, will pause the video and speech.
686 void UpdatePlayState(bool pause_speech = true);
688 bool PotentiallyPlaying() const;
689 bool StoppedDueToErrors() const;
690 bool CouldPlayIfEnoughData() const override;
692 // Generally the presence of the loop attribute should be considered to mean
693 // playback has not "ended", as "ended" and "looping" are mutually exclusive.
695 // https://html.spec.whatwg.org/C/#ended-playback
696 enum class LoopCondition { kIncluded, kIgnored };
697 bool EndedPlayback(LoopCondition = LoopCondition::kIncluded) const;
699 void SetShouldDelayLoadEvent(bool);
701 double EarliestPossiblePosition() const;
702 double CurrentPlaybackPosition() const;
703 double OfficialPlaybackPosition() const;
704 void SetOfficialPlaybackPosition(double) const;
705 void RequireOfficialPlaybackPositionUpdate() const;
707 void EnsureMediaControls();
708 void UpdateControlsVisibility();
710 TextTrackContainer& EnsureTextTrackContainer();
712 void ChangeNetworkStateFromLoadingToIdle();
714 WebMediaPlayer::CorsMode CorsMode() const;
716 // Returns the "direction of playback" value as specified in the HTML5 spec.
717 enum DirectionOfPlayback { kBackward, kForward };
718 DirectionOfPlayback GetDirectionOfPlayback() const;
720 // Creates placeholder AudioTrack and/or VideoTrack objects when
721 // WebMediaPlayer objects advertise they have audio and/or video, but don't
722 // explicitly signal them via addAudioTrack() and addVideoTrack().
723 // FIXME: Remove this once all WebMediaPlayer implementations properly report
725 void CreatePlaceholderTracksIfNecessary();
727 void SetNetworkState(NetworkState, bool update_media_controls = true);
729 void AudioTracksTimerFired(TimerBase*);
731 void ScheduleResolvePlayPromises();
732 void ScheduleRejectPlayPromises(PlayPromiseError);
733 void ScheduleNotifyPlaying();
734 void ResolveScheduledPlayPromises();
735 void RejectScheduledPlayPromises();
736 void RejectPlayPromises(DOMExceptionCode, const String&);
737 void RejectPlayPromisesInternal(DOMExceptionCode, const String&);
739 void OnRemovedFromDocumentTimerFired(TimerBase*);
741 void SetError(MediaError* error);
742 void ReportCurrentTimeToMediaSource();
744 void ResetMojoState();
745 void OnRemotePlaybackMetadataChange();
747 // Determine if we should reuse the player when moving the element from
748 // |old_document| to |new_document|
749 bool ShouldReusePlayer(Document& old_document, Document& new_document) const;
751 // Adds a new MediaPlayerObserver remote that will be notified about media
752 // player events and returns a receiver that an observer implementation can
754 mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayerObserver>
755 AddMediaPlayerObserverAndPassReceiver();
757 // Timers used to schedule one-shot tasks with no delay.
758 HeapTaskRunnerTimer<HTMLMediaElement> load_timer_;
759 HeapTaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_;
760 HeapTaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_;
761 // Use a low precision timer for repeating tasks to avoid excessive Idle Wake
762 // Up frequency, especially when WebRTC is used and the page contains many
763 // HTMLMediaElements.
764 LowPrecisionTimer progress_event_timer_;
765 LowPrecisionTimer playback_progress_timer_;
767 Member<TimeRanges> played_time_ranges_;
768 Member<EventQueue> async_event_queue_;
770 double playback_rate_;
771 double default_playback_rate_;
772 NetworkState network_state_;
773 ReadyState ready_state_;
774 ReadyState ready_state_maximum_;
776 SourceMetadata current_src_;
777 KURL current_src_after_redirects_;
779 Member<MediaStreamDescriptor> src_object_stream_descriptor_;
780 Member<MediaSourceHandle> src_object_media_source_handle_;
782 // To prevent potential regression when extended by the MSE API, do not set
783 // |error_| outside of constructor and SetError().
784 Member<MediaError> error_;
787 double last_seek_time_;
789 absl::optional<base::ElapsedTimer> previous_progress_time_;
791 // Cached duration to suppress duplicate events if duration unchanged.
794 // The last time a timeupdate event was sent in movie time.
795 double last_time_update_event_media_time_;
797 // The default playback start position.
798 double default_playback_start_position_;
803 kLoadingFromSrcObject,
805 kLoadingFromSourceElement
807 LoadState load_state_;
808 Member<HTMLSourceElement> current_source_node_;
809 Member<Node> next_child_node_to_consider_;
811 // "Deferred loading" state (for preload=none).
812 enum DeferredLoadState {
813 // The load is not deferred.
815 // The load is deferred, and waiting for the task to set the
816 // delaying-the-load-event flag (to false).
817 kWaitingForStopDelayingLoadEventTask,
818 // The load is the deferred, and waiting for a triggering event.
820 // The load is deferred, and waiting for the task to set the
821 // delaying-the-load-event flag, after which the load will be executed.
822 kExecuteOnStopDelayingLoadEventTask
824 DeferredLoadState deferred_load_state_;
825 HeapTaskRunnerTimer<HTMLMediaElement> deferred_load_timer_;
827 std::unique_ptr<WebMediaPlayer> web_media_player_;
828 cc::Layer* cc_layer_;
830 // These two fields must be carefully set and reset: the actual derived type
831 // of the attachment (same-thread vs cross-thread, for instance) must be the
832 // same semantic as the actual derived type of the tracer. Further, if there
833 // is no attachment, then there must be no tracer that's tracking an active
834 // attachment. Note that some kinds of attachments do not require a tracer;
835 // see MediaSourceAttachment::StartAttachingToMediaElement() for details.
836 scoped_refptr<MediaSourceAttachment> media_source_attachment_;
837 Member<MediaSourceTracer> media_source_tracer_;
839 // Stores "official playback position", updated periodically from "current
840 // playback position". Official playback position should not change while
841 // scripts are running. See setOfficialPlaybackPosition().
842 mutable double official_playback_position_;
843 mutable bool official_playback_position_needs_update_;
845 double fragment_end_time_;
847 typedef unsigned PendingActionFlags;
848 PendingActionFlags pending_action_flags_;
850 // FIXME: HTMLMediaElement has way too many state bits.
852 bool should_delay_load_event_ : 1;
853 bool have_fired_loaded_data_ : 1;
854 bool can_autoplay_ : 1;
858 bool paused_by_context_paused_ : 1;
859 bool show_poster_flag_ : 1;
861 // data has not been loaded since sending a "stalled" event
862 bool sent_stalled_event_ : 1;
864 bool ignore_preload_none_ : 1;
866 bool text_tracks_visible_ : 1;
867 bool should_perform_automatic_track_selection_ : 1;
869 bool tracks_are_ready_ : 1;
870 bool processing_preference_change_ : 1;
872 bool was_always_muted_ : 1;
874 #if defined(TIZEN_MULTIMEDIA)
875 bool live_playback_complete_ : 1;
878 #if BUILDFLAG(IS_TIZEN_TV)
879 String content_mime_type_;
880 bool is_translated_url_ : 1;
882 // Set if the user has used the context menu to set the visibility of the
884 absl::optional<bool> user_wants_controls_visible_;
886 // Whether or not |web_media_player_| should apply pitch adjustments at
887 // playback raters other than 1.0.
888 bool preserves_pitch_ = true;
890 #if BUILDFLAG(IS_TIZEN_TV)
891 bool is_deactivate_ : 1;
894 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
895 // This is to suppress stuff set to JS. Do not use it for other purposes.
896 bool suppress_events_ : 1;
899 // Whether the player disables the Remote Playback feature.
900 bool is_remote_playback_disabled_ = false;
901 // Whether the player is rendering remotely.
902 bool is_remote_rendering_ = false;
903 // Whether the media content is encrypted.
904 bool is_encrypted_media_ = false;
905 WebString remote_device_friendly_name_;
906 media::AudioCodec audio_codec_ = media::AudioCodec::kUnknown;
907 media::VideoCodec video_codec_ = media::VideoCodec::kUnknown;
909 Member<AudioTrackList> audio_tracks_;
910 Member<VideoTrackList> video_tracks_;
911 Member<TextTrackList> text_tracks_;
912 HeapVector<Member<TextTrack>> text_tracks_when_resource_selection_began_;
914 Member<CueTimeline> cue_timeline_;
916 HeapVector<Member<ScriptPromiseResolver>> play_promise_resolvers_;
917 TaskHandle play_promise_resolve_task_handle_;
918 TaskHandle play_promise_reject_task_handle_;
919 HeapVector<Member<ScriptPromiseResolver>> play_promise_resolve_list_;
920 HeapVector<Member<ScriptPromiseResolver>> play_promise_reject_list_;
921 PlayPromiseError play_promise_error_code_;
923 // HTMLMediaElement and its MediaElementAudioSourceNode in case it is provided
925 Member<AudioSourceProviderClient> audio_source_node_;
927 // Controls browser vocalization within the media element (e.g. to speak cues,
928 // to pause utterance).
929 Member<SpeechSynthesisBase> speech_synthesis_;
931 // AudioClientImpl wraps an AudioSourceProviderClient.
932 // When the audio format is known, Chromium calls setFormat().
933 class AudioClientImpl final : public GarbageCollected<AudioClientImpl>,
934 public WebAudioSourceProviderClient {
936 explicit AudioClientImpl(AudioSourceProviderClient* client)
939 ~AudioClientImpl() override = default;
941 // WebAudioSourceProviderClient
942 void SetFormat(uint32_t number_of_channels, float sample_rate) override;
944 void Trace(Visitor*) const;
947 Member<AudioSourceProviderClient> client_;
950 // AudioSourceProviderImpl wraps a WebAudioSourceProvider.
951 // provideInput() calls into Chromium to get a rendered audio stream.
952 class AudioSourceProviderImpl final : public AudioSourceProvider {
956 AudioSourceProviderImpl() = default;
957 ~AudioSourceProviderImpl() override = default;
959 // Wraps the given WebAudioSourceProvider.
960 void Wrap(scoped_refptr<WebAudioSourceProviderImpl>);
962 // AudioSourceProvider
963 void SetClient(AudioSourceProviderClient*) override;
964 void ProvideInput(AudioBus*, int frames_to_process) override;
966 void Trace(Visitor*) const;
969 base::Lock provide_input_lock;
970 scoped_refptr<WebAudioSourceProviderImpl> web_audio_source_provider_
971 GUARDED_BY(provide_input_lock);
972 Member<AudioClientImpl> client_;
975 AudioSourceProviderImpl audio_source_provider_;
977 // Notify HTMLMediaElement when a document's ExecutionContext is destroyed.
978 // It allows us to disconnect from a previous document's frame if we were
979 // using it to support our WebMediaPlayer rather than our current frame.
980 class OpenerContextObserver final
981 : public GarbageCollected<OpenerContextObserver>,
982 public ContextLifecycleObserver {
984 // Notify `element` when our context is destroyed.
985 explicit OpenerContextObserver(HTMLMediaElement* element);
986 ~OpenerContextObserver() final;
988 void Trace(Visitor* visitor) const final;
991 void ContextDestroyed() final;
993 Member<HTMLMediaElement> element_;
996 // Clean up things that are tied to any previous frame, including the player
997 // and mojo interfaces, when we switch to a new frame.
998 void AttachToNewFrame();
1000 Member<Document> opener_document_;
1001 Member<OpenerContextObserver> opener_context_observer_;
1003 friend class AutoplayPolicy;
1004 friend class AutoplayUmaHelperTest;
1005 friend class Internals;
1006 friend class TrackDisplayUpdateScope;
1007 friend class MediaControlsImplTest;
1008 friend class HTMLMediaElementTest;
1009 friend class HTMLMediaElementEventListenersTest;
1010 friend class HTMLVideoElement;
1011 friend class MediaControlInputElementTest;
1012 friend class MediaControlsOrientationLockDelegateTest;
1013 friend class MediaControlsRotateToFullscreenDelegateTest;
1014 friend class MediaControlLoadingPanelElementTest;
1015 friend class ContextMenuControllerTest;
1016 friend class HTMLVideoElementTest;
1018 Member<AutoplayPolicy> autoplay_policy_;
1020 WebRemotePlaybackClient* remote_playback_client_;
1022 Member<MediaControls> media_controls_;
1023 Member<HTMLMediaElementControlsList> controls_list_;
1025 Member<IntersectionObserver> lazy_load_intersection_observer_;
1027 Member<DisallowNewWrapper<
1028 HeapMojoAssociatedRemote<media::mojom::blink::MediaPlayerHost>>>
1029 media_player_host_remote_;
1031 // Note: There's only ever one entry in this set.
1032 Member<DisallowNewWrapper<
1033 HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>>>
1034 media_player_observer_remote_set_;
1036 // A receiver set is needed here as there will be different objects in the
1037 // browser communicating with this object. This is done this way to avoid
1038 // routing everything through a single class (e.g. RFHI) and to keep this
1039 // logic contained inside MediaPlayer-related classes.
1040 Member<DisallowNewWrapper<
1041 HeapMojoAssociatedReceiverSet<media::mojom::blink::MediaPlayer,
1043 media_player_receiver_set_;
1047 inline bool IsElementOfType<const HTMLMediaElement>(const Node& node) {
1048 return IsA<HTMLMediaElement>(node);
1051 struct DowncastTraits<HTMLMediaElement> {
1052 static bool AllowFrom(const Node& node) {
1053 auto* html_element = DynamicTo<HTMLElement>(node);
1054 return html_element && AllowFrom(*html_element);
1056 static bool AllowFrom(const HTMLElement& html_element) {
1057 return IsA<HTMLAudioElement>(html_element) ||
1058 IsA<HTMLVideoElement>(html_element);
1062 } // namespace blink
1064 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_