Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / html / HTMLMediaElement.h
blob6c159a797114bf6765081cb5e57734c57cc59b1e
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_dom_HTMLMediaElement_h
7 #define mozilla_dom_HTMLMediaElement_h
9 #include "nsGenericHTMLElement.h"
10 #include "AudioChannelService.h"
11 #include "MediaEventSource.h"
12 #include "SeekTarget.h"
13 #include "MediaDecoderOwner.h"
14 #include "MediaElementEventRunners.h"
15 #include "MediaPlaybackDelayPolicy.h"
16 #include "MediaPromiseDefs.h"
17 #include "TelemetryProbesReporter.h"
18 #include "nsCycleCollectionParticipant.h"
19 #include "Visibility.h"
20 #include "mozilla/CORSMode.h"
21 #include "DecoderTraits.h"
22 #include "mozilla/Attributes.h"
23 #include "mozilla/StateWatching.h"
24 #include "mozilla/WeakPtr.h"
25 #include "mozilla/dom/DecoderDoctorNotificationBinding.h"
26 #include "mozilla/dom/HTMLMediaElementBinding.h"
27 #include "mozilla/dom/MediaDebugInfoBinding.h"
28 #include "mozilla/dom/MediaKeys.h"
29 #include "mozilla/dom/TextTrackManager.h"
30 #include "nsGkAtoms.h"
31 #include "PrincipalChangeObserver.h"
32 #include "nsStubMutationObserver.h"
33 #include "MediaSegment.h" // for PrincipalHandle, GraphTime
35 #include <utility>
37 // X.h on Linux #defines CurrentTime as 0L, so we have to #undef it here.
38 #ifdef CurrentTime
39 # undef CurrentTime
40 #endif
42 // Define to output information on decoding and painting framerate
43 /* #define DEBUG_FRAME_RATE 1 */
45 using nsMediaNetworkState = uint16_t;
46 using nsMediaReadyState = uint16_t;
47 using SuspendTypes = uint32_t;
48 using AudibleChangedReasons = uint32_t;
50 class nsIStreamListener;
52 namespace mozilla {
53 class AbstractThread;
54 class ChannelMediaDecoder;
55 class DecoderDoctorDiagnostics;
56 class DOMMediaStream;
57 class ErrorResult;
58 class FirstFrameVideoOutput;
59 class MediaResource;
60 class MediaDecoder;
61 class MediaInputPort;
62 class MediaTrack;
63 class MediaTrackGraph;
64 class MediaStreamWindowCapturer;
65 struct SharedDummyTrack;
66 class VideoFrameContainer;
67 class VideoOutput;
68 namespace dom {
69 class HTMLSourceElement;
70 class MediaKeys;
71 class TextTrack;
72 class TimeRanges;
73 class WakeLock;
74 class MediaStreamTrack;
75 class MediaStreamTrackSource;
76 class MediaTrack;
77 class VideoStreamTrack;
78 } // namespace dom
79 } // namespace mozilla
81 class AudioDeviceInfo;
82 class nsIChannel;
83 class nsIHttpChannel;
84 class nsILoadGroup;
85 class nsIRunnable;
86 class nsISerialEventTarget;
87 class nsITimer;
88 class nsRange;
90 namespace mozilla::dom {
92 // Number of milliseconds between timeupdate events as defined by spec
93 #define TIMEUPDATE_MS 250
95 class MediaError;
96 class MediaSource;
97 class PlayPromise;
98 class Promise;
99 class TextTrackList;
100 class AudioTrackList;
101 class VideoTrackList;
103 enum class StreamCaptureType : uint8_t { CAPTURE_ALL_TRACKS, CAPTURE_AUDIO };
105 enum class StreamCaptureBehavior : uint8_t {
106 CONTINUE_WHEN_ENDED,
107 FINISH_WHEN_ENDED
110 class HTMLMediaElement : public nsGenericHTMLElement,
111 public MediaDecoderOwner,
112 public PrincipalChangeObserver<MediaStreamTrack>,
113 public SupportsWeakPtr,
114 public nsStubMutationObserver,
115 public TelemetryProbesReporterOwner {
116 public:
117 using TimeStamp = mozilla::TimeStamp;
118 using ImageContainer = mozilla::layers::ImageContainer;
119 using VideoFrameContainer = mozilla::VideoFrameContainer;
120 using MediaResource = mozilla::MediaResource;
121 using MediaDecoderOwner = mozilla::MediaDecoderOwner;
122 using MetadataTags = mozilla::MetadataTags;
124 // Helper struct to keep track of the MediaStreams returned by
125 // mozCaptureStream(). For each OutputMediaStream, dom::MediaTracks get
126 // captured into MediaStreamTracks which get added to
127 // OutputMediaStream::mStream.
128 struct OutputMediaStream {
129 OutputMediaStream(RefPtr<DOMMediaStream> aStream, bool aCapturingAudioOnly,
130 bool aFinishWhenEnded);
131 ~OutputMediaStream();
133 RefPtr<DOMMediaStream> mStream;
134 nsTArray<RefPtr<MediaStreamTrack>> mLiveTracks;
135 const bool mCapturingAudioOnly;
136 const bool mFinishWhenEnded;
137 // If mFinishWhenEnded is true, this is the URI of the first resource
138 // mStream got tracks for.
139 nsCOMPtr<nsIURI> mFinishWhenEndedLoadingSrc;
140 // If mFinishWhenEnded is true, this is the first MediaStream mStream got
141 // tracks for.
142 RefPtr<DOMMediaStream> mFinishWhenEndedAttrStream;
143 // If mFinishWhenEnded is true, this is the MediaSource being played.
144 RefPtr<MediaSource> mFinishWhenEndedMediaSource;
147 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
149 CORSMode GetCORSMode() { return mCORSMode; }
151 explicit HTMLMediaElement(
152 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
153 void Init();
155 // `eMandatory`: `timeupdate` occurs according to the spec requirement.
156 // Eg.
157 // https://html.spec.whatwg.org/multipage/media.html#seeking:event-media-timeupdate
158 // `ePeriodic` : `timeupdate` occurs regularly and should follow the rule
159 // of not dispatching that event within 250 ms. Eg.
160 // https://html.spec.whatwg.org/multipage/media.html#offsets-into-the-media-resource:event-media-timeupdate
161 enum class TimeupdateType : bool {
162 eMandatory = false,
163 ePeriodic = true,
166 // This is used for event runner creation. Currently only timeupdate needs
167 // that, but it can be used to extend for other events in the future if
168 // necessary.
169 enum class EventFlag : uint8_t {
170 eNone = 0,
171 eMandatory = 1,
175 * This is used when the browser is constructing a video element to play
176 * a channel that we've already started loading. The src attribute and
177 * <source> children are ignored.
178 * @param aChannel the channel to use
179 * @param aListener returns a stream listener that should receive
180 * notifications for the stream
182 nsresult LoadWithChannel(nsIChannel* aChannel, nsIStreamListener** aListener);
184 // nsISupports
185 NS_DECL_ISUPPORTS_INHERITED
186 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLMediaElement,
187 nsGenericHTMLElement)
188 NS_IMPL_FROMNODE_HELPER(HTMLMediaElement,
189 IsAnyOfHTMLElements(nsGkAtoms::video,
190 nsGkAtoms::audio))
192 NS_DECL_ADDSIZEOFEXCLUDINGTHIS
194 // EventTarget
195 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
197 void NodeInfoChanged(Document* aOldDoc) override;
199 virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
200 const nsAString& aValue,
201 nsIPrincipal* aMaybeScriptedPrincipal,
202 nsAttrValue& aResult) override;
204 virtual nsresult BindToTree(BindContext&, nsINode& aParent) override;
205 virtual void UnbindFromTree(UnbindContext&) override;
206 virtual void DoneCreatingElement() override;
208 virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
209 int32_t* aTabIndex) override;
210 virtual int32_t TabIndexDefault() override;
212 // Called by the video decoder object, on the main thread,
213 // when it has read the metadata containing video dimensions,
214 // etc.
215 virtual void MetadataLoaded(const MediaInfo* aInfo,
216 UniquePtr<const MetadataTags> aTags) final;
218 // Called by the decoder object, on the main thread,
219 // when it has read the first frame of the video or audio.
220 void FirstFrameLoaded() final;
222 // Called by the video decoder object, on the main thread,
223 // when the resource has a network error during loading.
224 void NetworkError(const MediaResult& aError) final;
226 // Called by the video decoder object, on the main thread, when the
227 // resource has a decode error during metadata loading or decoding.
228 void DecodeError(const MediaResult& aError) final;
230 // Called by the decoder object, on the main thread, when the
231 // resource has a decode issue during metadata loading or decoding, but can
232 // continue decoding.
233 void DecodeWarning(const MediaResult& aError) final;
235 // Return true if error attribute is not null.
236 bool HasError() const final;
238 // Called by the video decoder object, on the main thread, when the
239 // resource load has been cancelled.
240 void LoadAborted() final;
242 // Called by the video decoder object, on the main thread,
243 // when the video playback has ended.
244 void PlaybackEnded() final;
246 // Called by the video decoder object, on the main thread,
247 // when the resource has started seeking.
248 void SeekStarted() final;
250 // Called by the video decoder object, on the main thread,
251 // when the resource has completed seeking.
252 void SeekCompleted() final;
254 // Called by the video decoder object, on the main thread,
255 // when the resource has aborted seeking.
256 void SeekAborted() final;
258 // Called by the media stream, on the main thread, when the download
259 // has been suspended by the cache or because the element itself
260 // asked the decoder to suspend the download.
261 void DownloadSuspended() final;
263 // Called by the media stream, on the main thread, when the download
264 // has been resumed by the cache or because the element itself
265 // asked the decoder to resumed the download.
266 void DownloadResumed();
268 // Called to indicate the download is progressing.
269 void DownloadProgressed() final;
271 // Called by the media decoder to indicate whether the media cache has
272 // suspended the channel.
273 void NotifySuspendedByCache(bool aSuspendedByCache) final;
275 // Return true if the media element is actually invisible to users.
276 bool IsActuallyInvisible() const override;
278 // Return true if the element is in the view port.
279 bool IsInViewPort() const;
281 // Called by the media decoder and the video frame to get the
282 // ImageContainer containing the video data.
283 VideoFrameContainer* GetVideoFrameContainer() final;
284 layers::ImageContainer* GetImageContainer();
287 * Call this to reevaluate whether we should start/stop due to our owner
288 * document being active, inactive, visible or hidden.
290 void NotifyOwnerDocumentActivityChanged();
292 // Called when the media element enters or leaves the fullscreen.
293 void NotifyFullScreenChanged();
295 bool IsInFullScreen() const;
297 // From PrincipalChangeObserver<MediaStreamTrack>.
298 void PrincipalChanged(MediaStreamTrack* aTrack) override;
300 void UpdateSrcStreamVideoPrincipal(const PrincipalHandle& aPrincipalHandle);
302 // Called after the MediaStream we're playing rendered a frame to aContainer
303 // with a different principalHandle than the previous frame.
304 void PrincipalHandleChangedForVideoFrameContainer(
305 VideoFrameContainer* aContainer,
306 const PrincipalHandle& aNewPrincipalHandle) override;
308 // Dispatch events
309 void DispatchAsyncEvent(const nsAString& aName) final;
310 void DispatchAsyncEvent(RefPtr<nsMediaEventRunner> aRunner);
312 // Triggers a recomputation of readyState.
313 void UpdateReadyState() override {
314 mWatchManager.ManualNotify(&HTMLMediaElement::UpdateReadyStateInternal);
317 // Dispatch events that were raised while in the bfcache
318 nsresult DispatchPendingMediaEvents();
320 // Return true if we can activate autoplay assuming enough data has arrived.
321 // https://html.spec.whatwg.org/multipage/media.html#eligible-for-autoplay
322 bool IsEligibleForAutoplay();
324 // Notify that state has changed that might cause an autoplay element to
325 // start playing.
326 // If the element is 'autoplay' and is ready to play back (not paused,
327 // autoplay pref enabled, etc), it should start playing back.
328 void CheckAutoplayDataReady();
330 void RunAutoplay();
332 // Check if the media element had crossorigin set when loading started
333 bool ShouldCheckAllowOrigin();
335 // Returns true if the currently loaded resource is CORS same-origin with
336 // respect to the document.
337 bool IsCORSSameOrigin();
339 // Is the media element potentially playing as defined by the HTML 5
340 // specification.
341 // http://www.whatwg.org/specs/web-apps/current-work/#potentially-playing
342 bool IsPotentiallyPlaying() const;
344 // Has playback ended as defined by the HTML 5 specification.
345 // http://www.whatwg.org/specs/web-apps/current-work/#ended
346 bool IsPlaybackEnded() const;
348 // principal of the currently playing resource. Anything accessing the
349 // contents of this element must have a principal that subsumes this
350 // principal. Returns null if nothing is playing.
351 already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
353 // Return true if the loading of this resource required cross-origin
354 // redirects.
355 bool HadCrossOriginRedirects();
357 bool ShouldResistFingerprinting(RFPTarget aTarget) const override;
359 // Principal of the currently playing video resource. Anything accessing the
360 // image container of this element must have a principal that subsumes this
361 // principal. If there are no live video tracks but content has been rendered
362 // to the image container, we return the last video principal we had. Should
363 // the image container be empty with no live video tracks, we return nullptr.
364 already_AddRefed<nsIPrincipal> GetCurrentVideoPrincipal();
366 // called to notify that the principal of the decoder's media resource has
367 // changed.
368 void NotifyDecoderPrincipalChanged() final;
370 void GetEMEInfo(dom::EMEDebugInfo& aInfo);
372 // Update the visual size of the media. Called from the decoder on the
373 // main thread when/if the size changes.
374 virtual void UpdateMediaSize(const nsIntSize& aSize);
376 void Invalidate(ImageSizeChanged aImageSizeChanged,
377 const Maybe<nsIntSize>& aNewIntrinsicSize,
378 ForceInvalidate aForceInvalidate) override;
380 // Returns the CanPlayStatus indicating if we can handle the
381 // full MIME type including the optional codecs parameter.
382 static CanPlayStatus GetCanPlay(const nsAString& aType,
383 DecoderDoctorDiagnostics* aDiagnostics);
386 * Called when a child source element is added to this media element. This
387 * may queue a task to run the select resource algorithm if appropriate.
389 void NotifyAddedSource();
392 * Called when there's been an error fetching the resource. This decides
393 * whether it's appropriate to fire an error event.
395 void NotifyLoadError(const nsACString& aErrorDetails = nsCString());
398 * Called by one of our associated MediaTrackLists (audio/video) when a
399 * MediaTrack is added.
401 void NotifyMediaTrackAdded(dom::MediaTrack* aTrack);
404 * Called by one of our associated MediaTrackLists (audio/video) when a
405 * MediaTrack is removed.
407 void NotifyMediaTrackRemoved(dom::MediaTrack* aTrack);
410 * Called by one of our associated MediaTrackLists (audio/video) when an
411 * AudioTrack is enabled or a VideoTrack is selected.
413 void NotifyMediaTrackEnabled(dom::MediaTrack* aTrack);
416 * Called by one of our associated MediaTrackLists (audio/video) when an
417 * AudioTrack is disabled or a VideoTrack is unselected.
419 void NotifyMediaTrackDisabled(dom::MediaTrack* aTrack);
422 * Returns the current load ID. Asynchronous events store the ID that was
423 * current when they were enqueued, and if it has changed when they come to
424 * fire, they consider themselves cancelled, and don't fire.
426 uint32_t GetCurrentLoadID() const { return mCurrentLoadID; }
429 * Returns the load group for this media element's owner document.
430 * XXX XBL2 issue.
432 already_AddRefed<nsILoadGroup> GetDocumentLoadGroup();
435 * Returns true if the media has played or completed a seek.
436 * Used by video frame to determine whether to paint the poster.
438 bool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; }
440 nsresult CopyInnerTo(Element* aDest);
443 * Sets the Accept header on the HTTP channel to the required
444 * video or audio MIME types.
446 virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) = 0;
449 * Sets the required request headers on the HTTP channel for
450 * video or audio requests.
452 void SetRequestHeaders(nsIHttpChannel* aChannel);
455 * Asynchronously awaits a stable state, whereupon aRunnable runs on the main
456 * thread. This adds an event which run aRunnable to the appshell's list of
457 * sections synchronous the next time control returns to the event loop.
459 void RunInStableState(nsIRunnable* aRunnable);
462 * Fires a timeupdate event. If aPeriodic is true, the event will only
463 * be fired if we've not fired a timeupdate event (for any reason) in the
464 * last 250ms, as required by the spec when the current time is periodically
465 * increasing during playback.
467 void FireTimeUpdate(TimeupdateType aType);
469 void MaybeQueueTimeupdateEvent() final {
470 FireTimeUpdate(TimeupdateType::ePeriodic);
473 const TimeStamp& LastTimeupdateDispatchTime() const;
474 void UpdateLastTimeupdateDispatchTime();
476 // WebIDL
478 MediaError* GetError() const;
480 void GetSrc(nsAString& aSrc) { GetURIAttr(nsGkAtoms::src, nullptr, aSrc); }
481 void SetSrc(const nsAString& aSrc, ErrorResult& aError) {
482 SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
484 void SetSrc(const nsAString& aSrc, nsIPrincipal* aTriggeringPrincipal,
485 ErrorResult& aError) {
486 SetHTMLAttr(nsGkAtoms::src, aSrc, aTriggeringPrincipal, aError);
489 void GetCurrentSrc(nsAString& aCurrentSrc);
491 void GetCrossOrigin(nsAString& aResult) {
492 // Null for both missing and invalid defaults is ok, since we
493 // always parse to an enum value, so we don't need an invalid
494 // default, and we _want_ the missing default to be null.
495 GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult);
497 void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError) {
498 SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
501 uint16_t NetworkState() const { return mNetworkState; }
503 void NotifyXPCOMShutdown() final;
505 // Called by media decoder when the audible state changed or when input is
506 // a media stream.
507 void SetAudibleState(bool aAudible) final;
509 // Notify agent when the MediaElement changes its audible state.
510 void NotifyAudioPlaybackChanged(AudibleChangedReasons aReason);
512 void GetPreload(nsAString& aValue) {
513 if (mSrcAttrStream) {
514 nsGkAtoms::none->ToString(aValue);
515 return;
517 GetEnumAttr(nsGkAtoms::preload, nullptr, aValue);
519 void SetPreload(const nsAString& aValue, ErrorResult& aRv) {
520 if (mSrcAttrStream) {
521 return;
523 SetHTMLAttr(nsGkAtoms::preload, aValue, aRv);
526 already_AddRefed<TimeRanges> Buffered() const;
528 void Load();
530 void CanPlayType(const nsAString& aType, nsAString& aResult);
532 uint16_t ReadyState() const { return mReadyState; }
534 bool Seeking() const;
536 double CurrentTime() const;
538 void SetCurrentTime(double aCurrentTime, ErrorResult& aRv);
539 void SetCurrentTime(double aCurrentTime) {
540 SetCurrentTime(aCurrentTime, IgnoreErrors());
543 void FastSeek(double aTime, ErrorResult& aRv);
545 already_AddRefed<Promise> SeekToNextFrame(ErrorResult& aRv);
547 double Duration() const;
549 bool HasAudio() const { return mMediaInfo.HasAudio(); }
551 virtual bool IsVideo() const { return false; }
553 bool HasVideo() const { return mMediaInfo.HasVideo(); }
555 bool IsEncrypted() const override { return mIsEncrypted; }
557 #ifdef MOZ_WMF_CDM
558 bool IsUsingWMFCDM() const override;
559 #endif
561 bool Paused() const { return mPaused; }
563 double DefaultPlaybackRate() const {
564 if (mSrcAttrStream) {
565 return 1.0;
567 return mDefaultPlaybackRate;
570 void SetDefaultPlaybackRate(double aDefaultPlaybackRate, ErrorResult& aRv);
572 double PlaybackRate() const {
573 if (mSrcAttrStream) {
574 return 1.0;
576 return mPlaybackRate;
579 void SetPlaybackRate(double aPlaybackRate, ErrorResult& aRv);
581 already_AddRefed<TimeRanges> Played();
583 already_AddRefed<TimeRanges> Seekable() const;
585 bool Ended();
587 bool Autoplay() const { return GetBoolAttr(nsGkAtoms::autoplay); }
589 void SetAutoplay(bool aValue, ErrorResult& aRv) {
590 SetHTMLBoolAttr(nsGkAtoms::autoplay, aValue, aRv);
593 bool Loop() const { return GetBoolAttr(nsGkAtoms::loop); }
595 void SetLoop(bool aValue, ErrorResult& aRv) {
596 SetHTMLBoolAttr(nsGkAtoms::loop, aValue, aRv);
599 already_AddRefed<Promise> Play(ErrorResult& aRv);
600 void Play() {
601 IgnoredErrorResult dummy;
602 RefPtr<Promise> toBeIgnored = Play(dummy);
605 void Pause(ErrorResult& aRv);
606 void Pause() { Pause(IgnoreErrors()); }
608 bool Controls() const { return GetBoolAttr(nsGkAtoms::controls); }
610 void SetControls(bool aValue, ErrorResult& aRv) {
611 SetHTMLBoolAttr(nsGkAtoms::controls, aValue, aRv);
614 double Volume() const { return mVolume; }
616 void SetVolume(double aVolume, ErrorResult& aRv);
618 bool Muted() const { return mMuted & MUTED_BY_CONTENT; }
619 void SetMuted(bool aMuted);
621 bool DefaultMuted() const { return GetBoolAttr(nsGkAtoms::muted); }
623 void SetDefaultMuted(bool aMuted, ErrorResult& aRv) {
624 SetHTMLBoolAttr(nsGkAtoms::muted, aMuted, aRv);
627 bool MozAllowCasting() const { return mAllowCasting; }
629 void SetMozAllowCasting(bool aShow) { mAllowCasting = aShow; }
631 bool MozIsCasting() const { return mIsCasting; }
633 void SetMozIsCasting(bool aShow) { mIsCasting = aShow; }
635 // Returns whether a call to Play() would be rejected with NotAllowedError.
636 // This assumes "worst case" for unknowns. So if prompting for permission is
637 // enabled and no permission is stored, this behaves as if the user would
638 // opt to block.
639 bool AllowedToPlay() const;
641 already_AddRefed<MediaSource> GetMozMediaSourceObject() const;
643 // Returns a promise which will be resolved after collecting debugging
644 // data from decoder/reader/MDSM. Used for debugging purposes.
645 already_AddRefed<Promise> MozRequestDebugInfo(ErrorResult& aRv);
647 // Enables DecoderDoctorLogger logging. Used for debugging purposes.
648 static void MozEnableDebugLog(const GlobalObject&);
650 // Returns a promise which will be resolved after collecting debugging
651 // log associated with this element. Used for debugging purposes.
652 already_AddRefed<Promise> MozRequestDebugLog(ErrorResult& aRv);
654 // For use by mochitests. Enabling pref "media.test.video-suspend"
655 void SetVisible(bool aVisible);
657 // For use by mochitests. Enabling pref "media.test.video-suspend"
658 bool HasSuspendTaint() const;
660 // For use by mochitests.
661 bool IsVideoDecodingSuspended() const;
663 // These functions return accumulated time, which are used for the telemetry
664 // usage. Return -1 for error.
665 double TotalVideoPlayTime() const;
666 double TotalVideoHDRPlayTime() const;
667 double VisiblePlayTime() const;
668 double InvisiblePlayTime() const;
669 double VideoDecodeSuspendedTime() const;
670 double TotalAudioPlayTime() const;
671 double AudiblePlayTime() const;
672 double InaudiblePlayTime() const;
673 double MutedPlayTime() const;
675 // Test methods for decoder doctor.
676 void SetFormatDiagnosticsReportForMimeType(const nsAString& aMimeType,
677 DecoderDoctorReportType aType);
678 void SetDecodeError(const nsAString& aError, ErrorResult& aRv);
679 void SetAudioSinkFailedStartup();
681 // Synchronously, return the next video frame and mark the element unable to
682 // participate in decode suspending.
684 // This function is synchronous for cases where decoding has been suspended
685 // and JS needs a frame to use in, eg., nsLayoutUtils::SurfaceFromElement()
686 // via drawImage().
687 already_AddRefed<layers::Image> GetCurrentImage();
689 already_AddRefed<DOMMediaStream> GetSrcObject() const;
690 void SetSrcObject(DOMMediaStream& aValue);
691 void SetSrcObject(DOMMediaStream* aValue);
693 bool PreservesPitch() const { return mPreservesPitch; }
694 void SetPreservesPitch(bool aPreservesPitch);
696 MediaKeys* GetMediaKeys() const;
698 already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
699 ErrorResult& aRv);
701 mozilla::dom::EventHandlerNonNull* GetOnencrypted();
702 void SetOnencrypted(mozilla::dom::EventHandlerNonNull* aCallback);
704 mozilla::dom::EventHandlerNonNull* GetOnwaitingforkey();
705 void SetOnwaitingforkey(mozilla::dom::EventHandlerNonNull* aCallback);
707 void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
708 const nsAString& aInitDataType) override;
710 bool IsEventAttributeNameInternal(nsAtom* aName) override;
712 bool ContainsRestrictedContent() const;
714 void NotifyWaitingForKey() override;
716 already_AddRefed<DOMMediaStream> CaptureAudio(ErrorResult& aRv,
717 MediaTrackGraph* aGraph);
719 already_AddRefed<DOMMediaStream> MozCaptureStream(ErrorResult& aRv);
721 already_AddRefed<DOMMediaStream> MozCaptureStreamUntilEnded(ErrorResult& aRv);
723 bool MozAudioCaptured() const { return mAudioCaptured; }
725 void MozGetMetadata(JSContext* aCx, JS::MutableHandle<JSObject*> aResult,
726 ErrorResult& aRv);
728 double MozFragmentEnd();
730 AudioTrackList* AudioTracks();
732 VideoTrackList* VideoTracks();
734 TextTrackList* GetTextTracks();
736 already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
737 const nsAString& aLabel,
738 const nsAString& aLanguage);
740 void AddTextTrack(TextTrack* aTextTrack) {
741 GetOrCreateTextTrackManager()->AddTextTrack(aTextTrack);
744 void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly = false) {
745 if (mTextTrackManager) {
746 mTextTrackManager->RemoveTextTrack(aTextTrack, aPendingListOnly);
750 void NotifyCueAdded(TextTrackCue& aCue) {
751 if (mTextTrackManager) {
752 mTextTrackManager->NotifyCueAdded(aCue);
755 void NotifyCueRemoved(TextTrackCue& aCue) {
756 if (mTextTrackManager) {
757 mTextTrackManager->NotifyCueRemoved(aCue);
760 void NotifyCueUpdated(TextTrackCue* aCue) {
761 if (mTextTrackManager) {
762 mTextTrackManager->NotifyCueUpdated(aCue);
766 void NotifyCueDisplayStatesChanged();
768 bool IsBlessed() const { return mIsBlessed; }
770 // A method to check whether we are currently playing.
771 bool IsCurrentlyPlaying() const;
773 // Returns true if the media element is being destroyed. Used in
774 // dormancy checks to prevent dormant processing for an element
775 // that will soon be gone.
776 bool IsBeingDestroyed();
778 virtual void OnVisibilityChange(Visibility aNewVisibility);
780 // Begin testing only methods
781 float ComputedVolume() const;
782 bool ComputedMuted() const;
784 // Return true if the media has been suspended media due to an inactive
785 // document or prohibiting by the docshell.
786 bool IsSuspendedByInactiveDocOrDocShell() const;
787 // End testing only methods
789 void SetMediaInfo(const MediaInfo& aInfo);
790 MediaInfo GetMediaInfo() const override;
792 // Gives access to the decoder's frame statistics, if present.
793 FrameStatistics* GetFrameStatistics() const override;
795 void DispatchAsyncTestingEvent(const nsAString& aName) override;
797 AbstractThread* AbstractMainThread() const final;
799 // Log the usage of a {visible / invisible} video element as
800 // the source of {drawImage(), createPattern(), createImageBitmap() and
801 // captureStream()} APIs. This function can be used to collect telemetries for
802 // bug 1352007.
803 enum class CallerAPI {
804 DRAW_IMAGE,
805 CREATE_PATTERN,
806 CREATE_IMAGEBITMAP,
807 CAPTURE_STREAM,
808 CREATE_VIDEOFRAME,
810 void LogVisibility(CallerAPI aAPI);
812 Document* GetDocument() const override;
814 already_AddRefed<GMPCrashHelper> CreateGMPCrashHelper() override;
816 // Set the sink id (of the output device) that the audio will play. If aSinkId
817 // is empty the default device will be set.
818 already_AddRefed<Promise> SetSinkId(const nsAString& aSinkId,
819 ErrorResult& aRv);
820 // Get the sink id of the device that audio is being played. Initial value is
821 // empty and the default device is being used.
822 void GetSinkId(nsString& aSinkId) const {
823 MOZ_ASSERT(NS_IsMainThread());
824 aSinkId = mSink.first;
827 // This is used to notify MediaElementAudioSourceNode that media element is
828 // allowed to play when media element is used as a source for web audio, so
829 // that we can start AudioContext if it was not allowed to start.
830 RefPtr<GenericNonExclusivePromise> GetAllowedToPlayPromise();
832 bool GetShowPosterFlag() const { return mShowPoster; }
834 bool IsAudible() const;
836 // Return key system in use if we have one, otherwise return nothing.
837 Maybe<nsAutoString> GetKeySystem() const override;
839 protected:
840 virtual ~HTMLMediaElement();
842 class AudioChannelAgentCallback;
843 class ChannelLoader;
844 class ErrorSink;
845 class MediaElementTrackSource;
846 class MediaLoadListener;
847 class MediaStreamRenderer;
848 class MediaStreamTrackListener;
849 class ShutdownObserver;
850 class TitleChangeObserver;
851 class MediaControlKeyListener;
853 MediaDecoderOwner::NextFrameStatus NextFrameStatus();
855 void SetDecoder(MediaDecoder* aDecoder);
857 void PlayInternal(bool aHandlingUserInput);
859 // See spec, https://html.spec.whatwg.org/#internal-pause-steps
860 void PauseInternal();
862 /** Use this method to change the mReadyState member, so required
863 * events can be fired.
865 void ChangeReadyState(nsMediaReadyState aState);
868 * Use this method to change the mNetworkState member, so required
869 * actions will be taken during the transition.
871 void ChangeNetworkState(nsMediaNetworkState aState);
874 * The MediaElement will be responsible for creating and releasing the audio
875 * wakelock depending on the playing and audible state.
877 virtual void WakeLockRelease();
878 virtual void UpdateWakeLock();
880 void CreateAudioWakeLockIfNeeded();
881 void ReleaseAudioWakeLockIfExists();
882 RefPtr<WakeLock> mWakeLock;
885 * Logs a warning message to the web console to report various failures.
886 * aMsg is the localized message identifier, aParams is the parameters to
887 * be substituted into the localized message, and aParamCount is the number
888 * of parameters in aParams.
890 void ReportLoadError(const char* aMsg, const nsTArray<nsString>& aParams =
891 nsTArray<nsString>());
894 * Log message to web console.
896 void ReportToConsole(
897 uint32_t aErrorFlags, const char* aMsg,
898 const nsTArray<nsString>& aParams = nsTArray<nsString>()) const;
901 * Changes mHasPlayedOrSeeked to aValue. If mHasPlayedOrSeeked changes
902 * we'll force a reflow so that the video frame gets reflowed to reflect
903 * the poster hiding or showing immediately.
905 void SetPlayedOrSeeked(bool aValue);
908 * Initialize the media element for playback of aStream
910 void SetupSrcMediaStreamPlayback(DOMMediaStream* aStream);
912 * Stop playback on mSrcStream.
914 void EndSrcMediaStreamPlayback();
916 * Ensure we're playing mSrcStream if and only if we're not paused.
918 enum { REMOVING_SRC_STREAM = 0x1 };
919 void UpdateSrcMediaStreamPlaying(uint32_t aFlags = 0);
922 * Ensure currentTime progresses if and only if we're potentially playing
923 * mSrcStream. Called by the watch manager while we're playing mSrcStream, and
924 * one of the inputs to the potentially playing algorithm changes.
926 void UpdateSrcStreamPotentiallyPlaying();
929 * mSrcStream's graph's CurrentTime() has been updated. It might be time to
930 * fire "timeupdate".
932 void UpdateSrcStreamTime();
935 * Called after a tail dispatch when playback of mSrcStream ended, to comply
936 * with the spec where we must start reporting true for the ended attribute
937 * after the event loop returns to step 1. A MediaStream could otherwise be
938 * manipulated to end a HTMLMediaElement synchronously.
940 void UpdateSrcStreamReportPlaybackEnded();
943 * Called by our DOMMediaStream::TrackListener when a new MediaStreamTrack has
944 * been added to the playback stream of |mSrcStream|.
946 void NotifyMediaStreamTrackAdded(const RefPtr<MediaStreamTrack>& aTrack);
949 * Called by our DOMMediaStream::TrackListener when a MediaStreamTrack in
950 * |mSrcStream|'s playback stream has ended.
952 void NotifyMediaStreamTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack);
955 * Convenience method to get in a single list all enabled AudioTracks and, if
956 * this is a video element, the selected VideoTrack.
958 void GetAllEnabledMediaTracks(nsTArray<RefPtr<MediaTrack>>& aTracks);
961 * Enables or disables all tracks forwarded from mSrcStream to all
962 * OutputMediaStreams. We do this for muting the tracks when pausing,
963 * and unmuting when playing the media element again.
965 void SetCapturedOutputStreamsEnabled(bool aEnabled);
968 * Returns true if output tracks should be muted, based on the state of this
969 * media element.
971 enum class OutputMuteState { Muted, Unmuted };
972 OutputMuteState OutputTracksMuted();
975 * Sets the muted state of all output track sources. They are muted when we're
976 * paused and unmuted otherwise.
978 void UpdateOutputTracksMuting();
981 * Create a new MediaStreamTrack for the TrackSource corresponding to aTrack
982 * and add it to the DOMMediaStream in aOutputStream. This automatically sets
983 * the output track to enabled or disabled depending on our current playing
984 * state.
986 enum class AddTrackMode { ASYNC, SYNC };
987 void AddOutputTrackSourceToOutputStream(
988 MediaElementTrackSource* aSource, OutputMediaStream& aOutputStream,
989 AddTrackMode aMode = AddTrackMode::ASYNC);
992 * Creates output track sources when this media element is captured, tracks
993 * exist, playback is not ended and readyState is >= HAVE_METADATA.
995 void UpdateOutputTrackSources();
998 * Returns an DOMMediaStream containing the played contents of this
999 * element. When aBehavior is FINISH_WHEN_ENDED, when this element ends
1000 * playback we will finish the stream and not play any more into it. When
1001 * aType is CONTINUE_WHEN_ENDED, ending playback does not finish the stream.
1002 * The stream will never finish.
1004 * When aType is CAPTURE_AUDIO, we stop playout of audio and instead route it
1005 * to the DOMMediaStream. Volume and mute state will be applied to the audio
1006 * reaching the stream. No video tracks will be captured in this case.
1008 * aGraph may be null if the stream's tracks do not need to use a
1009 * specific graph.
1011 already_AddRefed<DOMMediaStream> CaptureStreamInternal(
1012 StreamCaptureBehavior aFinishBehavior,
1013 StreamCaptureType aStreamCaptureType, MediaTrackGraph* aGraph);
1016 * Initialize a decoder as a clone of an existing decoder in another
1017 * element.
1018 * mLoadingSrc must already be set.
1020 nsresult InitializeDecoderAsClone(ChannelMediaDecoder* aOriginal);
1023 * Call Load() and FinishDecoderSetup() on the decoder. It also handle
1024 * resource cloning if DecoderType is ChannelMediaDecoder.
1026 template <typename DecoderType, typename... LoadArgs>
1027 nsresult SetupDecoder(DecoderType* aDecoder, LoadArgs&&... aArgs);
1030 * Initialize a decoder to load the given channel. The decoder's stream
1031 * listener is returned via aListener.
1032 * mLoadingSrc must already be set.
1034 nsresult InitializeDecoderForChannel(nsIChannel* aChannel,
1035 nsIStreamListener** aListener);
1038 * Finish setting up the decoder after Load() has been called on it.
1039 * Called by InitializeDecoderForChannel/InitializeDecoderAsClone.
1041 nsresult FinishDecoderSetup(MediaDecoder* aDecoder);
1044 * Call this after setting up mLoadingSrc and mDecoder.
1046 void AddMediaElementToURITable();
1048 * Call this before modifying mLoadingSrc.
1050 void RemoveMediaElementFromURITable();
1052 * Call this to find a media element with the same NodePrincipal and
1053 * mLoadingSrc set to aURI, and with a decoder on which Load() has been
1054 * called.
1056 HTMLMediaElement* LookupMediaElementURITable(nsIURI* aURI);
1059 * Shutdown and clear mDecoder and maintain associated invariants.
1061 void ShutdownDecoder();
1063 * Execute the initial steps of the load algorithm that ensure existing
1064 * loads are aborted, the element is emptied, and a new load ID is
1065 * created.
1067 void AbortExistingLoads();
1070 * This is the dedicated media source failure steps.
1071 * Called when all potential resources are exhausted. Changes network
1072 * state to NETWORK_NO_SOURCE, and sends error event with code
1073 * MEDIA_ERR_SRC_NOT_SUPPORTED.
1075 void NoSupportedMediaSourceError(
1076 const nsACString& aErrorDetails = nsCString());
1079 * Per spec, Failed with elements: Queue a task, using the DOM manipulation
1080 * task source, to fire a simple event named error at the candidate element.
1081 * So dispatch |QueueLoadFromSourceTask| to main thread to make sure the task
1082 * will be executed later than loadstart event.
1084 void DealWithFailedElement(nsIContent* aSourceElement);
1087 * Attempts to load resources from the <source> children. This is a
1088 * substep of the resource selection algorithm. Do not call this directly,
1089 * call QueueLoadFromSourceTask() instead.
1091 void LoadFromSourceChildren();
1094 * Asynchronously awaits a stable state, and then causes
1095 * LoadFromSourceChildren() to be called on the main threads' event loop.
1097 void QueueLoadFromSourceTask();
1100 * Runs the media resource selection algorithm.
1102 void SelectResource();
1105 * A wrapper function that allows us to cleanly reset flags after a call
1106 * to SelectResource()
1108 void SelectResourceWrapper();
1111 * Asynchronously awaits a stable state, and then causes SelectResource()
1112 * to be run on the main thread's event loop.
1114 void QueueSelectResourceTask();
1117 * When loading a new source on an existing media element, make sure to reset
1118 * everything that is accessible using the media element API.
1120 void ResetState();
1123 * The resource-fetch algorithm step of the load algorithm.
1125 MediaResult LoadResource();
1128 * Selects the next <source> child from which to load a resource. Called
1129 * during the resource selection algorithm. Stores the return value in
1130 * mSourceLoadCandidate before returning.
1132 HTMLSourceElement* GetNextSource();
1135 * Changes mDelayingLoadEvent, and will call BlockOnLoad()/UnblockOnLoad()
1136 * on the owning document, so it can delay the load event firing.
1138 void ChangeDelayLoadStatus(bool aDelay);
1141 * If we suspended downloading after the first frame, unsuspend now.
1143 void StopSuspendingAfterFirstFrame();
1146 * Called when our channel is redirected to another channel.
1147 * Updates our mChannel reference to aNewChannel.
1149 nsresult OnChannelRedirect(nsIChannel* aChannel, nsIChannel* aNewChannel,
1150 uint32_t aFlags);
1153 * Call this to reevaluate whether we should be holding a self-reference.
1155 void AddRemoveSelfReference();
1158 * Called when "xpcom-shutdown" event is received.
1160 void NotifyShutdownEvent();
1163 * Possible values of the 'preload' attribute.
1165 enum PreloadAttrValue : uint8_t {
1166 PRELOAD_ATTR_EMPTY, // set to ""
1167 PRELOAD_ATTR_NONE, // set to "none"
1168 PRELOAD_ATTR_METADATA, // set to "metadata"
1169 PRELOAD_ATTR_AUTO // set to "auto"
1173 * The preloading action to perform. These dictate how we react to the
1174 * preload attribute. See mPreloadAction.
1176 enum PreloadAction {
1177 PRELOAD_UNDEFINED = 0, // not determined - used only for initialization
1178 PRELOAD_NONE = 1, // do not preload
1179 PRELOAD_METADATA = 2, // preload only the metadata (and first frame)
1180 PRELOAD_ENOUGH = 3 // preload enough data to allow uninterrupted
1181 // playback
1185 * The guts of Load(). Load() acts as a wrapper around this which sets
1186 * mIsDoingExplicitLoad to true so that when script calls 'load()'
1187 * preload-none will be automatically upgraded to preload-metadata.
1189 void DoLoad();
1192 * Suspends the load of mLoadingSrc, so that it can be resumed later
1193 * by ResumeLoad(). This is called when we have a media with a 'preload'
1194 * attribute value of 'none', during the resource selection algorithm.
1196 void SuspendLoad();
1199 * Resumes a previously suspended load (suspended by SuspendLoad(uri)).
1200 * Will continue running the resource selection algorithm.
1201 * Sets mPreloadAction to aAction.
1203 void ResumeLoad(PreloadAction aAction);
1206 * Handle a change to the preload attribute. Should be called whenever the
1207 * value (or presence) of the preload attribute changes. The change in
1208 * attribute value may cause a change in the mPreloadAction of this
1209 * element. If there is a change then this method will initiate any
1210 * behaviour that is necessary to implement the action.
1212 void UpdatePreloadAction();
1215 * Fire progress events if needed according to the time and byte constraints
1216 * outlined in the specification. aHaveNewProgress is true if progress has
1217 * just been detected. Otherwise the method is called as a result of the
1218 * progress timer.
1220 void CheckProgress(bool aHaveNewProgress);
1221 static void ProgressTimerCallback(nsITimer* aTimer, void* aClosure);
1223 * Start timer to update download progress.
1225 void StartProgressTimer();
1227 * Start sending progress and/or stalled events.
1229 void StartProgress();
1231 * Stop progress information timer and events.
1233 void StopProgress();
1236 * Dispatches an error event to a child source element.
1238 void DispatchAsyncSourceError(nsIContent* aSourceElement);
1241 * Resets the media element for an error condition as per aErrorCode.
1242 * aErrorCode must be one of WebIDL HTMLMediaElement error codes.
1244 void Error(uint16_t aErrorCode,
1245 const nsACString& aErrorDetails = nsCString());
1248 * Returns the URL spec of the currentSrc.
1250 void GetCurrentSpec(nsCString& aString);
1253 * Process any media fragment entries in the URI
1255 void ProcessMediaFragmentURI();
1258 * Mute or unmute the audio and change the value that the |muted| map.
1260 void SetMutedInternal(uint32_t aMuted);
1262 * Update the volume of the output audio stream to match the element's
1263 * current mMuted/mVolume/mAudioChannelFaded state.
1265 void SetVolumeInternal();
1268 * Suspend or resume element playback and resource download. When we suspend
1269 * playback, event delivery would also be suspended (and events queued) until
1270 * the element is resumed.
1272 void SuspendOrResumeElement(bool aSuspendElement);
1274 // Get the HTMLMediaElement object if the decoder is being used from an
1275 // HTML media element, and null otherwise.
1276 HTMLMediaElement* GetMediaElement() final { return this; }
1278 // Return true if decoding should be paused
1279 bool GetPaused() final { return Paused(); }
1281 // Seeks to aTime seconds. aSeekType can be Exact to seek to exactly the
1282 // seek target, or PrevSyncPoint if a quicker but less precise seek is
1283 // desired, and we'll seek to the sync point (keyframe and/or start of the
1284 // next block of audio samples) preceeding seek target.
1285 void Seek(double aTime, SeekTarget::Type aSeekType, ErrorResult& aRv);
1287 // Update the audio channel playing state
1288 void UpdateAudioChannelPlayingState();
1290 // Adds to the element's list of pending text tracks each text track
1291 // in the element's list of text tracks whose text track mode is not disabled
1292 // and whose text track readiness state is loading.
1293 void PopulatePendingTextTrackList();
1295 // Gets a reference to the MediaElement's TextTrackManager. If the
1296 // MediaElement doesn't yet have one then it will create it.
1297 TextTrackManager* GetOrCreateTextTrackManager();
1299 // Recomputes ready state and fires events as necessary based on current
1300 // state.
1301 void UpdateReadyStateInternal();
1303 // Create or destroy the captured stream.
1304 void AudioCaptureTrackChange(bool aCapture);
1306 // If the network state is empty and then we would trigger DoLoad().
1307 void MaybeDoLoad();
1309 // Anything we need to check after played success and not related with spec.
1310 void UpdateCustomPolicyAfterPlayed();
1312 // Returns a StreamCaptureType populated with the right bits, depending on the
1313 // tracks this HTMLMediaElement has.
1314 StreamCaptureType CaptureTypeForElement();
1316 // True if this element can be captured, false otherwise.
1317 bool CanBeCaptured(StreamCaptureType aCaptureType);
1319 using nsGenericHTMLElement::DispatchEvent;
1320 // For nsAsyncEventRunner.
1321 nsresult DispatchEvent(const nsAString& aName);
1323 already_AddRefed<nsMediaEventRunner> GetEventRunner(
1324 const nsAString& aName, EventFlag aFlag = EventFlag::eNone);
1326 // This method moves the mPendingPlayPromises into a temperate object. So the
1327 // mPendingPlayPromises is cleared after this method call.
1328 nsTArray<RefPtr<PlayPromise>> TakePendingPlayPromises();
1330 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
1331 // and queues a task to resolve them.
1332 void AsyncResolvePendingPlayPromises();
1334 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
1335 // and queues a task to reject them.
1336 void AsyncRejectPendingPlayPromises(nsresult aError);
1338 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
1339 // and queues a task to resolve them also to dispatch a "playing" event.
1340 void NotifyAboutPlaying();
1342 already_AddRefed<Promise> CreateDOMPromise(ErrorResult& aRv) const;
1344 // Pass information for deciding the video decode mode to decoder.
1345 void NotifyDecoderActivityChanges() const;
1347 // Constructs an AudioTrack in mAudioTrackList if aInfo reports that audio is
1348 // available, and a VideoTrack in mVideoTrackList if aInfo reports that video
1349 // is available.
1350 void ConstructMediaTracks(const MediaInfo* aInfo);
1352 // Removes all MediaTracks from mAudioTrackList and mVideoTrackList and fires
1353 // "removetrack" on the lists accordingly.
1354 // Note that by spec, this should not fire "removetrack". However, it appears
1355 // other user agents do, per
1356 // https://wpt.fyi/results/media-source/mediasource-avtracks.html.
1357 void RemoveMediaTracks();
1359 // Mark the decoder owned by the element as tainted so that the
1360 // suspend-video-decoder is disabled.
1361 void MarkAsTainted();
1363 virtual void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
1364 const nsAttrValue* aValue,
1365 const nsAttrValue* aOldValue,
1366 nsIPrincipal* aMaybeScriptedPrincipal,
1367 bool aNotify) override;
1368 virtual void OnAttrSetButNotChanged(int32_t aNamespaceID, nsAtom* aName,
1369 const nsAttrValueOrString& aValue,
1370 bool aNotify) override;
1372 bool DetachExistingMediaKeys();
1373 bool TryRemoveMediaKeysAssociation();
1374 void RemoveMediaKeys();
1375 bool AttachNewMediaKeys();
1376 bool TryMakeAssociationWithCDM(CDMProxy* aProxy);
1377 void MakeAssociationWithCDMResolved();
1378 void SetCDMProxyFailure(const MediaResult& aResult);
1379 void ResetSetMediaKeysTempVariables();
1381 void PauseIfShouldNotBePlaying();
1383 WatchManager<HTMLMediaElement> mWatchManager;
1385 // When the play is not allowed, dispatch related events which are used for
1386 // testing or changing control UI.
1387 void DispatchEventsWhenPlayWasNotAllowed();
1389 // When the doc is blocked permanantly, we would dispatch event to notify
1390 // front-end side to show blocking icon.
1391 void MaybeNotifyAutoplayBlocked();
1393 // Dispatch event for video control when video gets blocked in order to show
1394 // the click-to-play icon.
1395 void DispatchBlockEventForVideoControl();
1397 // When playing state change, we have to notify MediaControl in the chrome
1398 // process in order to keep its playing state correct.
1399 void NotifyMediaControlPlaybackStateChanged();
1401 // Clear the timer when we want to continue listening to the media control
1402 // key events.
1403 void ClearStopMediaControlTimerIfNeeded();
1405 // Sets a secondary renderer for mSrcStream, so this media element can be
1406 // rendered in Picture-in-Picture mode when playing a MediaStream. A null
1407 // aContainer will unset the secondary renderer. aFirstFrameOutput allows
1408 // for injecting a listener of the callers choice for rendering the first
1409 // frame.
1410 void SetSecondaryMediaStreamRenderer(
1411 VideoFrameContainer* aContainer,
1412 FirstFrameVideoOutput* aFirstFrameOutput = nullptr);
1414 // This function is used to update the status of media control when the media
1415 // changes its status of being used in the Picture-in-Picture mode.
1416 void UpdateMediaControlAfterPictureInPictureModeChanged();
1418 // The current decoder. Load() has been called on this decoder.
1419 // At most one of mDecoder and mSrcStream can be non-null.
1420 RefPtr<MediaDecoder> mDecoder;
1422 // A reference to the VideoFrameContainer which contains the current frame
1423 // of video to display.
1424 RefPtr<VideoFrameContainer> mVideoFrameContainer;
1426 // Holds a reference to the MediaStream that has been set in the src
1427 // attribute.
1428 RefPtr<DOMMediaStream> mSrcAttrStream;
1430 // Holds the triggering principal for the src attribute.
1431 nsCOMPtr<nsIPrincipal> mSrcAttrTriggeringPrincipal;
1433 // Holds a reference to the MediaStream that we're actually playing.
1434 // At most one of mDecoder and mSrcStream can be non-null.
1435 RefPtr<DOMMediaStream> mSrcStream;
1437 // The MediaStreamRenderer handles rendering of our selected video track, and
1438 // enabled audio tracks, while mSrcStream is set.
1439 RefPtr<MediaStreamRenderer> mMediaStreamRenderer;
1441 // The secondary MediaStreamRenderer handles rendering of our selected video
1442 // track to a secondary VideoFrameContainer, while mSrcStream is set.
1443 RefPtr<MediaStreamRenderer> mSecondaryMediaStreamRenderer;
1445 // True once PlaybackEnded() is called and we're playing a MediaStream.
1446 // Reset to false if we start playing mSrcStream again.
1447 Watchable<bool> mSrcStreamPlaybackEnded = {
1448 false, "HTMLMediaElement::mSrcStreamPlaybackEnded"};
1450 // Mirrors mSrcStreamPlaybackEnded after a tail dispatch when set to true,
1451 // but may be be forced to false directly. To accomodate when an application
1452 // ends playback synchronously by manipulating mSrcStream or its tracks,
1453 // e.g., through MediaStream.removeTrack(), or MediaStreamTrack.stop().
1454 bool mSrcStreamReportPlaybackEnded = false;
1456 // Holds a reference to the stream connecting this stream to the window
1457 // capture sink.
1458 RefPtr<MediaStreamWindowCapturer> mStreamWindowCapturer;
1460 // Holds references to the DOM wrappers for the MediaStreams that we're
1461 // writing to.
1462 nsTArray<OutputMediaStream> mOutputStreams;
1464 // Mapping for output tracks, from dom::MediaTrack ids to the
1465 // MediaElementTrackSource that represents the source of all corresponding
1466 // MediaStreamTracks captured from this element.
1467 nsRefPtrHashtable<nsStringHashKey, MediaElementTrackSource>
1468 mOutputTrackSources;
1470 // The currently selected video stream track.
1471 RefPtr<VideoStreamTrack> mSelectedVideoStreamTrack;
1473 const RefPtr<ShutdownObserver> mShutdownObserver;
1475 const RefPtr<TitleChangeObserver> mTitleChangeObserver;
1477 // Holds a reference to the MediaSource, if any, referenced by the src
1478 // attribute on the media element.
1479 RefPtr<MediaSource> mSrcMediaSource;
1481 // Holds a reference to the MediaSource supplying data for playback. This
1482 // may either match mSrcMediaSource or come from Source element children.
1483 // This is set when and only when mLoadingSrc corresponds to an object url
1484 // that resolved to a MediaSource.
1485 RefPtr<MediaSource> mMediaSource;
1487 RefPtr<ChannelLoader> mChannelLoader;
1489 // Points to the child source elements, used to iterate through the children
1490 // when selecting a resource to load. This is the previous sibling of the
1491 // child considered the current 'candidate' in:
1492 // https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm
1494 // mSourcePointer == nullptr, we will next try to load |GetFirstChild()|.
1495 // mSourcePointer == GetLastChild(), we've exhausted all sources, waiting
1496 // for new elements to be appended.
1497 nsCOMPtr<nsIContent> mSourcePointer;
1499 // Points to the document whose load we're blocking. This is the document
1500 // we're bound to when loading starts.
1501 nsCOMPtr<Document> mLoadBlockedDoc;
1503 // This is used to help us block/resume the event delivery.
1504 class EventBlocker;
1505 RefPtr<EventBlocker> mEventBlocker;
1507 // Media loading flags. See:
1508 // http://www.whatwg.org/specs/web-apps/current-work/#video)
1509 nsMediaNetworkState mNetworkState = HTMLMediaElement_Binding::NETWORK_EMPTY;
1510 Watchable<nsMediaReadyState> mReadyState = {
1511 HTMLMediaElement_Binding::HAVE_NOTHING, "HTMLMediaElement::mReadyState"};
1513 enum LoadAlgorithmState {
1514 // No load algorithm instance is waiting for a source to be added to the
1515 // media in order to continue loading.
1516 NOT_WAITING,
1517 // We've run the load algorithm, and we tried all source children of the
1518 // media element, and failed to load any successfully. We're waiting for
1519 // another source element to be added to the media element, and will try
1520 // to load any such element when its added.
1521 WAITING_FOR_SOURCE
1524 // The current media load ID. This is incremented every time we start a
1525 // new load. Async events note the ID when they're first sent, and only fire
1526 // if the ID is unchanged when they come to fire.
1527 uint32_t mCurrentLoadID = 0;
1529 // Denotes the waiting state of a load algorithm instance. When the load
1530 // algorithm is waiting for a source element child to be added, this is set
1531 // to WAITING_FOR_SOURCE, otherwise it's NOT_WAITING.
1532 LoadAlgorithmState mLoadWaitStatus = NOT_WAITING;
1534 // Current audio volume
1535 double mVolume = 1.0;
1537 // True if the audio track is not silent.
1538 bool mIsAudioTrackAudible = false;
1540 enum MutedReasons {
1541 MUTED_BY_CONTENT = 0x01,
1542 MUTED_BY_INVALID_PLAYBACK_RATE = 0x02,
1543 MUTED_BY_AUDIO_CHANNEL = 0x04,
1544 MUTED_BY_AUDIO_TRACK = 0x08
1547 uint32_t mMuted = 0;
1549 UniquePtr<const MetadataTags> mTags;
1551 // URI of the resource we're attempting to load. This stores the value we
1552 // return in the currentSrc attribute. Use GetCurrentSrc() to access the
1553 // currentSrc attribute.
1554 // This is always the original URL we're trying to load --- before
1555 // redirects etc.
1556 nsCOMPtr<nsIURI> mLoadingSrc;
1558 // The triggering principal for the current source.
1559 nsCOMPtr<nsIPrincipal> mLoadingSrcTriggeringPrincipal;
1561 // Stores the current preload action for this element. Initially set to
1562 // PRELOAD_UNDEFINED, its value is changed by calling
1563 // UpdatePreloadAction().
1564 PreloadAction mPreloadAction = PRELOAD_UNDEFINED;
1566 // Time that the last timeupdate event was queued. Read/Write from the
1567 // main thread only.
1568 TimeStamp mQueueTimeUpdateRunnerTime;
1570 // Time that the last timeupdate event was fired. Read/Write from the
1571 // main thread only.
1572 TimeStamp mLastTimeUpdateDispatchTime;
1574 // Time that the last progress event was fired. Read/Write from the
1575 // main thread only.
1576 TimeStamp mProgressTime;
1578 // Time that data was last read from the media resource. Used for
1579 // computing if the download has stalled and to rate limit progress events
1580 // when data is arriving slower than PROGRESS_MS.
1581 // Read/Write from the main thread only.
1582 TimeStamp mDataTime;
1584 // Media 'currentTime' value when the last timeupdate event was queued.
1585 // Read/Write from the main thread only.
1586 double mLastCurrentTime = 0.0;
1588 // Logical start time of the media resource in seconds as obtained
1589 // from any media fragments. A negative value indicates that no
1590 // fragment time has been set. Read/Write from the main thread only.
1591 double mFragmentStart = -1.0;
1593 // Logical end time of the media resource in seconds as obtained
1594 // from any media fragments. A negative value indicates that no
1595 // fragment time has been set. Read/Write from the main thread only.
1596 double mFragmentEnd = -1.0;
1598 // The defaultPlaybackRate attribute gives the desired speed at which the
1599 // media resource is to play, as a multiple of its intrinsic speed.
1600 double mDefaultPlaybackRate = 1.0;
1602 // The playbackRate attribute gives the speed at which the media resource
1603 // plays, as a multiple of its intrinsic speed. If it is not equal to the
1604 // defaultPlaybackRate, then the implication is that the user is using a
1605 // feature such as fast forward or slow motion playback.
1606 double mPlaybackRate = 1.0;
1608 // True if pitch correction is applied when playbackRate is set to a
1609 // non-intrinsic value.
1610 bool mPreservesPitch = true;
1612 // Reference to the source element last returned by GetNextSource().
1613 // This is the child source element which we're trying to load from.
1614 nsCOMPtr<nsIContent> mSourceLoadCandidate;
1616 // Range of time played.
1617 RefPtr<TimeRanges> mPlayed;
1619 // Timer used for updating progress events.
1620 nsCOMPtr<nsITimer> mProgressTimer;
1622 // Encrypted Media Extension media keys.
1623 RefPtr<MediaKeys> mMediaKeys;
1624 RefPtr<MediaKeys> mIncomingMediaKeys;
1625 // The dom promise is used for HTMLMediaElement::SetMediaKeys.
1626 RefPtr<DetailedPromise> mSetMediaKeysDOMPromise;
1627 // Used to indicate if the MediaKeys attaching operation is on-going or not.
1628 bool mAttachingMediaKey = false;
1629 MozPromiseRequestHolder<SetCDMPromise> mSetCDMRequest;
1631 // Stores the time at the start of the current 'played' range.
1632 double mCurrentPlayRangeStart = 1.0;
1634 // True if loadeddata has been fired.
1635 bool mLoadedDataFired = false;
1637 // One of the factors determines whether a media element with 'autoplay'
1638 // attribute is allowed to start playing.
1639 // https://html.spec.whatwg.org/multipage/media.html#can-autoplay-flag
1640 bool mCanAutoplayFlag = true;
1642 // Playback of the video is paused either due to calling the
1643 // 'Pause' method, or playback not yet having started.
1644 Watchable<bool> mPaused = {true, "HTMLMediaElement::mPaused"};
1646 // The following two fields are here for the private storage of the builtin
1647 // video controls, and control 'casting' of the video to external devices
1648 // (TVs, projectors etc.)
1649 // True if casting is currently allowed
1650 bool mAllowCasting = false;
1651 // True if currently casting this video
1652 bool mIsCasting = false;
1654 // Set while there are some OutputMediaStreams this media element's enabled
1655 // and selected tracks are captured into. When set, all tracks are captured
1656 // into the graph of this dummy track.
1657 // NB: This is a SharedDummyTrack to allow non-default graphs (AudioContexts
1658 // with an explicit sampleRate defined) to capture this element. When
1659 // cross-graph tracks are supported, this can become a bool.
1660 Watchable<RefPtr<SharedDummyTrack>> mTracksCaptured;
1662 // True if the sound is being captured.
1663 bool mAudioCaptured = false;
1665 // If TRUE then the media element was actively playing before the currently
1666 // in progress seeking. If FALSE then the media element is either not seeking
1667 // or was not actively playing before the current seek. Used to decide whether
1668 // to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
1669 bool mPlayingBeforeSeek = false;
1671 // True if this element is suspended because the document is inactive or the
1672 // inactive docshell is not allowing media to play.
1673 bool mSuspendedByInactiveDocOrDocshell = false;
1675 // True if we're running the "load()" method.
1676 bool mIsRunningLoadMethod = false;
1678 // True if we're running or waiting to run queued tasks due to an explicit
1679 // call to "load()".
1680 bool mIsDoingExplicitLoad = false;
1682 // True if we're loading the resource from the child source elements.
1683 bool mIsLoadingFromSourceChildren = false;
1685 // True if we're delaying the "load" event. They are delayed until either
1686 // an error occurs, or the first frame is loaded.
1687 bool mDelayingLoadEvent = false;
1689 // True when we've got a task queued to call SelectResource(),
1690 // or while we're running SelectResource().
1691 bool mIsRunningSelectResource = false;
1693 // True when we already have select resource call queued
1694 bool mHaveQueuedSelectResource = false;
1696 // True if we suspended the decoder because we were paused,
1697 // preloading metadata is enabled, autoplay was not enabled, and we loaded
1698 // the first frame.
1699 bool mSuspendedAfterFirstFrame = false;
1701 // True if we are allowed to suspend the decoder because we were paused,
1702 // preloading metdata was enabled, autoplay was not enabled, and we loaded
1703 // the first frame.
1704 bool mAllowSuspendAfterFirstFrame = true;
1706 // True if we've played or completed a seek. We use this to determine
1707 // when the poster frame should be shown.
1708 bool mHasPlayedOrSeeked = false;
1710 // True if we've added a reference to ourselves to keep the element
1711 // alive while no-one is referencing it but the element may still fire
1712 // events of its own accord.
1713 bool mHasSelfReference = false;
1715 // True if we've received a notification that the engine is shutting
1716 // down.
1717 bool mShuttingDown = false;
1719 // True if we've suspended a load in the resource selection algorithm
1720 // due to loading a preload:none media. When true, the resource we'll
1721 // load when the user initiates either playback or an explicit load is
1722 // stored in mPreloadURI.
1723 bool mSuspendedForPreloadNone = false;
1725 // True if we've connected mSrcStream to the media element output.
1726 bool mSrcStreamIsPlaying = false;
1728 // True if we should set nsIClassOfService::UrgentStart to the channel to
1729 // get the response ASAP for better user responsiveness.
1730 bool mUseUrgentStartForChannel = false;
1732 // The CORS mode when loading the media element
1733 CORSMode mCORSMode = CORS_NONE;
1735 // Info about the played media.
1736 MediaInfo mMediaInfo;
1738 // True if the media has encryption information.
1739 bool mIsEncrypted = false;
1741 enum WaitingForKeyState {
1742 NOT_WAITING_FOR_KEY = 0,
1743 WAITING_FOR_KEY = 1,
1744 WAITING_FOR_KEY_DISPATCHED = 2
1747 // True when the CDM cannot decrypt the current block due to lacking a key.
1748 // Note: the "waitingforkey" event is not dispatched until all decoded data
1749 // has been rendered.
1750 WaitingForKeyState mWaitingForKey = NOT_WAITING_FOR_KEY;
1752 // Listens for waitingForKey events from the owned decoder.
1753 MediaEventListener mWaitingForKeyListener;
1755 // Init Data that needs to be sent in 'encrypted' events in MetadataLoaded().
1756 EncryptionInfo mPendingEncryptedInitData;
1758 // True if the media's channel's download has been suspended.
1759 Watchable<bool> mDownloadSuspendedByCache = {
1760 false, "HTMLMediaElement::mDownloadSuspendedByCache"};
1762 // Disable the video playback by track selection. This flag might not be
1763 // enough if we ever expand the ability of supporting multi-tracks video
1764 // playback.
1765 bool mDisableVideo = false;
1767 RefPtr<TextTrackManager> mTextTrackManager;
1769 RefPtr<AudioTrackList> mAudioTrackList;
1771 RefPtr<VideoTrackList> mVideoTrackList;
1773 RefPtr<MediaStreamTrackListener> mMediaStreamTrackListener;
1775 // The principal guarding mVideoFrameContainer access when playing a
1776 // MediaStream.
1777 nsCOMPtr<nsIPrincipal> mSrcStreamVideoPrincipal;
1779 // True if the autoplay media was blocked because it hadn't loaded metadata
1780 // yet.
1781 bool mBlockedAsWithoutMetadata = false;
1783 // This promise is used to notify MediaElementAudioSourceNode that media
1784 // element is allowed to play when MediaElement is used as a source for web
1785 // audio.
1786 MozPromiseHolder<GenericNonExclusivePromise> mAllowedToPlayPromise;
1788 // True if media has ever been blocked for autoplay, it's used to notify front
1789 // end to show the correct blocking icon when the document goes back from
1790 // bfcache.
1791 bool mHasEverBeenBlockedForAutoplay = false;
1793 // True if we have dispatched a task for text track changed, will be unset
1794 // when we starts processing text track changed.
1795 // https://html.spec.whatwg.org/multipage/media.html#pending-text-track-change-notification-flag
1796 bool mPendingTextTrackChanged = false;
1798 public:
1799 // This function will be called whenever a text track that is in a media
1800 // element's list of text tracks has its text track mode change value
1801 void NotifyTextTrackModeChanged();
1803 private:
1804 friend class nsMediaEventRunner;
1805 friend class nsResolveOrRejectPendingPlayPromisesRunner;
1807 already_AddRefed<PlayPromise> CreatePlayPromise(ErrorResult& aRv) const;
1809 virtual void MaybeBeginCloningVisually(){};
1811 uint32_t GetPreloadDefault() const;
1812 uint32_t GetPreloadDefaultAuto() const;
1815 * This function is called by AfterSetAttr and OnAttrSetButNotChanged.
1816 * It will not be called if the value is being unset.
1818 * @param aNamespaceID the namespace of the attr being set
1819 * @param aName the localname of the attribute being set
1820 * @param aNotify Whether we plan to notify document observers.
1822 void AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName, bool aNotify);
1824 // True if Init() has been called after construction
1825 bool mInitialized = false;
1827 // True if user has called load(), seek() or element has started playing
1828 // before. It's *only* use for `click-to-play` blocking autoplay policy.
1829 // In addition, we would reset this once media aborts current load.
1830 bool mIsBlessed = false;
1832 // True if the first frame has been successfully loaded.
1833 Watchable<bool> mFirstFrameLoaded = {false,
1834 "HTMLMediaElement::mFirstFrameLoaded"};
1836 // Media elements also have a default playback start position, which must
1837 // initially be set to zero seconds. This time is used to allow the element to
1838 // be seeked even before the media is loaded.
1839 double mDefaultPlaybackStartPosition = 0.0;
1841 // True if media element has been marked as 'tainted' and can't
1842 // participate in video decoder suspending.
1843 bool mHasSuspendTaint = false;
1845 // True if media element has been forced into being considered 'hidden'.
1846 // For use by mochitests. Enabling pref "media.test.video-suspend"
1847 bool mForcedHidden = false;
1849 Visibility mVisibilityState = Visibility::Untracked;
1851 UniquePtr<ErrorSink> mErrorSink;
1853 // This wrapper will handle all audio channel related stuffs, eg. the
1854 // operations of tab audio indicator, Fennec's media control. Note:
1855 // mAudioChannelWrapper might be null after GC happened.
1856 RefPtr<AudioChannelAgentCallback> mAudioChannelWrapper;
1858 // A list of pending play promises. The elements are pushed during the play()
1859 // method call and are resolved/rejected during further playback steps.
1860 nsTArray<RefPtr<PlayPromise>> mPendingPlayPromises;
1862 // A list of already-dispatched but not yet run
1863 // nsResolveOrRejectPendingPlayPromisesRunners.
1864 // Runners whose Run() method is called remove themselves from this list.
1865 // We keep track of these because the load algorithm resolves/rejects all
1866 // already-dispatched pending play promises.
1867 nsTArray<nsResolveOrRejectPendingPlayPromisesRunner*>
1868 mPendingPlayPromisesRunners;
1870 // A pending seek promise which is created at Seek() method call and is
1871 // resolved/rejected at AsyncResolveSeekDOMPromiseIfExists()/
1872 // AsyncRejectSeekDOMPromiseIfExists() methods.
1873 RefPtr<dom::Promise> mSeekDOMPromise;
1875 // Return true if the docshell is inactive and explicitly wants to stop media
1876 // playing in that shell.
1877 bool ShouldBeSuspendedByInactiveDocShell() const;
1879 // For debugging bug 1407148.
1880 void AssertReadyStateIsNothing();
1882 // Contains the unique id of the sink device and the device info.
1883 // The initial value is ("", nullptr) and the default output device is used.
1884 // It can contain an invalid id and info if the device has been
1885 // unplugged. It can be set to ("", nullptr). It follows the spec attribute:
1886 // https://w3c.github.io/mediacapture-output/#htmlmediaelement-extensions
1887 // Read/Write from the main thread only.
1888 std::pair<nsString, RefPtr<AudioDeviceInfo>> mSink;
1890 // This flag is used to control when the user agent is to show a poster frame
1891 // for a video element instead of showing the video contents.
1892 // https://html.spec.whatwg.org/multipage/media.html#show-poster-flag
1893 bool mShowPoster;
1895 // We may delay starting playback of a media for an unvisited tab until it's
1896 // going to foreground. We would create ResumeDelayedMediaPlaybackAgent to
1897 // handle related operations at the time whenever delaying media playback is
1898 // needed.
1899 void CreateResumeDelayedMediaPlaybackAgentIfNeeded();
1900 void ClearResumeDelayedMediaPlaybackAgentIfNeeded();
1901 RefPtr<ResumeDelayedPlaybackAgent> mResumeDelayedPlaybackAgent;
1902 MozPromiseRequestHolder<ResumeDelayedPlaybackAgent::ResumePromise>
1903 mResumePlaybackRequest;
1905 // Return true if we have already a decoder or a src stream and don't have any
1906 // error.
1907 bool IsPlayable() const;
1909 // Return true if the media qualifies for being controlled by media control
1910 // keys.
1911 bool ShouldStartMediaControlKeyListener() const;
1913 // Start the listener if media fits the requirement of being able to be
1914 // controlled be media control keys.
1915 void StartMediaControlKeyListenerIfNeeded();
1917 // It's used to listen media control key, by which we would play or pause
1918 // media element.
1919 RefPtr<MediaControlKeyListener> mMediaControlKeyListener;
1921 // Method to update audio stream name
1922 void UpdateStreamName();
1924 // Return true if the media element is being used in picture in picture mode.
1925 bool IsBeingUsedInPictureInPictureMode() const;
1927 // Return true if we should queue a 'timeupdate' event runner to main thread.
1928 bool ShouldQueueTimeupdateAsyncTask(TimeupdateType aType) const;
1930 #ifdef MOZ_WMF_CDM
1931 // It's used to record telemetry probe for WMFCDM playback.
1932 bool mIsUsingWMFCDM = false;
1933 #endif
1936 // Check if the context is chrome or has the debugger or tabs permission
1937 bool HasDebuggerOrTabsPrivilege(JSContext* aCx, JSObject* aObj);
1939 } // namespace mozilla::dom
1941 #endif // mozilla_dom_HTMLMediaElement_h