Bug 1554951 [wpt PR 17043] - wake-lock: Fix invalid types test in wakelock-type.https...
[gecko.git] / dom / html / HTMLMediaElement.h
blob22f2a3a888869e2d8c7169a70026b76389f7ec1a
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 "nsAutoPtr.h"
10 #include "nsGenericHTMLElement.h"
11 #include "MediaEventSource.h"
12 #include "SeekTarget.h"
13 #include "MediaDecoderOwner.h"
14 #include "MediaPromiseDefs.h"
15 #include "nsCycleCollectionParticipant.h"
16 #include "nsIObserver.h"
17 #include "mozilla/CORSMode.h"
18 #include "DecoderTraits.h"
19 #include "nsIAudioChannelAgent.h"
20 #include "mozilla/Attributes.h"
21 #include "mozilla/StateWatching.h"
22 #include "mozilla/WeakPtr.h"
23 #include "mozilla/dom/HTMLMediaElementBinding.h"
24 #include "mozilla/dom/MediaDebugInfoBinding.h"
25 #include "mozilla/dom/MediaKeys.h"
26 #include "mozilla/dom/TextTrackManager.h"
27 #include "nsGkAtoms.h"
28 #include "PrincipalChangeObserver.h"
29 #include "nsStubMutationObserver.h"
30 #include "MediaSegment.h" // for PrincipalHandle, GraphTime
32 // X.h on Linux #defines CurrentTime as 0L, so we have to #undef it here.
33 #ifdef CurrentTime
34 # undef CurrentTime
35 #endif
37 // Define to output information on decoding and painting framerate
38 /* #define DEBUG_FRAME_RATE 1 */
40 typedef uint16_t nsMediaNetworkState;
41 typedef uint16_t nsMediaReadyState;
42 typedef uint32_t SuspendTypes;
43 typedef uint32_t AudibleChangedReasons;
44 typedef uint8_t AudibleState;
46 namespace mozilla {
47 class AbstractThread;
48 class ChannelMediaDecoder;
49 class DecoderDoctorDiagnostics;
50 class DOMMediaStream;
51 class ErrorResult;
52 class MediaResource;
53 class MediaDecoder;
54 class MediaInputPort;
55 class MediaStream;
56 class MediaStreamGraph;
57 class VideoFrameContainer;
58 namespace dom {
59 class MediaKeys;
60 class TextTrack;
61 class TimeRanges;
62 class WakeLock;
63 class MediaTrack;
64 class MediaStreamTrack;
65 class VideoStreamTrack;
66 } // namespace dom
67 } // namespace mozilla
69 class AudioDeviceInfo;
70 class nsIChannel;
71 class nsIHttpChannel;
72 class nsILoadGroup;
73 class nsIRunnable;
74 class nsISerialEventTarget;
75 class nsITimer;
76 class nsRange;
78 namespace mozilla {
79 namespace dom {
81 // Number of milliseconds between timeupdate events as defined by spec
82 #define TIMEUPDATE_MS 250
84 class MediaError;
85 class MediaSource;
86 class PlayPromise;
87 class Promise;
88 class TextTrackList;
89 class AudioTrackList;
90 class VideoTrackList;
92 enum class StreamCaptureType : uint8_t { CAPTURE_ALL_TRACKS, CAPTURE_AUDIO };
94 enum class StreamCaptureBehavior : uint8_t {
95 CONTINUE_WHEN_ENDED,
96 FINISH_WHEN_ENDED
99 class HTMLMediaElement : public nsGenericHTMLElement,
100 public MediaDecoderOwner,
101 public PrincipalChangeObserver<DOMMediaStream>,
102 public SupportsWeakPtr<HTMLMediaElement>,
103 public nsStubMutationObserver {
104 public:
105 typedef mozilla::TimeStamp TimeStamp;
106 typedef mozilla::layers::ImageContainer ImageContainer;
107 typedef mozilla::VideoFrameContainer VideoFrameContainer;
108 typedef mozilla::MediaStream MediaStream;
109 typedef mozilla::MediaResource MediaResource;
110 typedef mozilla::MediaDecoderOwner MediaDecoderOwner;
111 typedef mozilla::MetadataTags MetadataTags;
113 MOZ_DECLARE_WEAKREFERENCE_TYPENAME(HTMLMediaElement)
114 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
116 CORSMode GetCORSMode() { return mCORSMode; }
118 explicit HTMLMediaElement(
119 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
120 void Init();
122 void ReportCanPlayTelemetry();
125 * This is used when the browser is constructing a video element to play
126 * a channel that we've already started loading. The src attribute and
127 * <source> children are ignored.
128 * @param aChannel the channel to use
129 * @param aListener returns a stream listener that should receive
130 * notifications for the stream
132 nsresult LoadWithChannel(nsIChannel* aChannel, nsIStreamListener** aListener);
134 // nsISupports
135 NS_DECL_ISUPPORTS_INHERITED
136 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLMediaElement,
137 nsGenericHTMLElement)
138 NS_IMPL_FROMNODE_HELPER(HTMLMediaElement,
139 IsAnyOfHTMLElements(nsGkAtoms::video,
140 nsGkAtoms::audio))
142 // EventTarget
143 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
145 virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
146 const nsAString& aValue,
147 nsIPrincipal* aMaybeScriptedPrincipal,
148 nsAttrValue& aResult) override;
150 virtual nsresult BindToTree(BindContext&, nsINode& aParent) override;
151 virtual void UnbindFromTree(bool aNullParent = true) override;
152 virtual void DoneCreatingElement() override;
154 virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
155 int32_t* aTabIndex) override;
156 virtual int32_t TabIndexDefault() override;
158 // Called by the video decoder object, on the main thread,
159 // when it has read the metadata containing video dimensions,
160 // etc.
161 virtual void MetadataLoaded(const MediaInfo* aInfo,
162 UniquePtr<const MetadataTags> aTags) final;
164 // Called by the decoder object, on the main thread,
165 // when it has read the first frame of the video or audio.
166 void FirstFrameLoaded() final;
168 // Called by the video decoder object, on the main thread,
169 // when the resource has a network error during loading.
170 void NetworkError(const MediaResult& aError) final;
172 // Called by the video decoder object, on the main thread, when the
173 // resource has a decode error during metadata loading or decoding.
174 void DecodeError(const MediaResult& aError) final;
176 // Called by the decoder object, on the main thread, when the
177 // resource has a decode issue during metadata loading or decoding, but can
178 // continue decoding.
179 void DecodeWarning(const MediaResult& aError) final;
181 // Return true if error attribute is not null.
182 bool HasError() const final;
184 // Called by the video decoder object, on the main thread, when the
185 // resource load has been cancelled.
186 void LoadAborted() final;
188 // Called by the video decoder object, on the main thread,
189 // when the video playback has ended.
190 void PlaybackEnded() final;
192 // Called by the video decoder object, on the main thread,
193 // when the resource has started seeking.
194 void SeekStarted() final;
196 // Called by the video decoder object, on the main thread,
197 // when the resource has completed seeking.
198 void SeekCompleted() final;
200 // Called by the media stream, on the main thread, when the download
201 // has been suspended by the cache or because the element itself
202 // asked the decoder to suspend the download.
203 void DownloadSuspended() final;
205 // Called by the media stream, on the main thread, when the download
206 // has been resumed by the cache or because the element itself
207 // asked the decoder to resumed the download.
208 void DownloadResumed();
210 // Called to indicate the download is progressing.
211 void DownloadProgressed() final;
213 // Called by the media decoder to indicate whether the media cache has
214 // suspended the channel.
215 void NotifySuspendedByCache(bool aSuspendedByCache) final;
217 bool IsActive() const;
219 bool IsHidden() const;
221 // Called by the media decoder and the video frame to get the
222 // ImageContainer containing the video data.
223 VideoFrameContainer* GetVideoFrameContainer() final;
224 layers::ImageContainer* GetImageContainer();
227 * Call this to reevaluate whether we should start/stop due to our owner
228 * document being active, inactive, visible or hidden.
230 void NotifyOwnerDocumentActivityChanged();
232 // From PrincipalChangeObserver<DOMMediaStream>.
233 void PrincipalChanged(DOMMediaStream* aStream) override;
235 void UpdateSrcStreamVideoPrincipal(const PrincipalHandle& aPrincipalHandle);
237 // Called after the MediaStream we're playing rendered a frame to aContainer
238 // with a different principalHandle than the previous frame.
239 void PrincipalHandleChangedForVideoFrameContainer(
240 VideoFrameContainer* aContainer,
241 const PrincipalHandle& aNewPrincipalHandle) override;
243 // Dispatch events
244 void DispatchAsyncEvent(const nsAString& aName) final;
246 // Triggers a recomputation of readyState.
247 void UpdateReadyState() override { UpdateReadyStateInternal(); }
249 // Dispatch events that were raised while in the bfcache
250 nsresult DispatchPendingMediaEvents();
252 // Return true if we can activate autoplay assuming enough data has arrived.
253 bool CanActivateAutoplay();
255 // Notify that state has changed that might cause an autoplay element to
256 // start playing.
257 // If the element is 'autoplay' and is ready to play back (not paused,
258 // autoplay pref enabled, etc), it should start playing back.
259 void CheckAutoplayDataReady();
261 // Check if the media element had crossorigin set when loading started
262 bool ShouldCheckAllowOrigin();
264 // Returns true if the currently loaded resource is CORS same-origin with
265 // respect to the document.
266 bool IsCORSSameOrigin();
268 // Is the media element potentially playing as defined by the HTML 5
269 // specification.
270 // http://www.whatwg.org/specs/web-apps/current-work/#potentially-playing
271 bool IsPotentiallyPlaying() const;
273 // Has playback ended as defined by the HTML 5 specification.
274 // http://www.whatwg.org/specs/web-apps/current-work/#ended
275 bool IsPlaybackEnded() const;
277 // principal of the currently playing resource. Anything accessing the
278 // contents of this element must have a principal that subsumes this
279 // principal. Returns null if nothing is playing.
280 already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
282 // Return true if the loading of this resource required cross-origin
283 // redirects.
284 bool HadCrossOriginRedirects();
286 // Principal of the currently playing video resource. Anything accessing the
287 // image container of this element must have a principal that subsumes this
288 // principal. If there are no live video tracks but content has been rendered
289 // to the image container, we return the last video principal we had. Should
290 // the image container be empty with no live video tracks, we return nullptr.
291 already_AddRefed<nsIPrincipal> GetCurrentVideoPrincipal();
293 // called to notify that the principal of the decoder's media resource has
294 // changed.
295 void NotifyDecoderPrincipalChanged() final;
297 void GetEMEInfo(dom::EMEDebugInfo& aInfo);
299 class StreamCaptureTrackSource;
301 // Update the visual size of the media. Called from the decoder on the
302 // main thread when/if the size changes.
303 virtual void UpdateMediaSize(const nsIntSize& aSize);
304 // Like UpdateMediaSize, but only updates the size if no size has yet
305 // been set.
306 void UpdateInitialMediaSize(const nsIntSize& aSize);
308 void Invalidate(bool aImageSizeChanged, Maybe<nsIntSize>& aNewIntrinsicSize,
309 bool aForceInvalidate) override;
311 // Returns the CanPlayStatus indicating if we can handle the
312 // full MIME type including the optional codecs parameter.
313 static CanPlayStatus GetCanPlay(const nsAString& aType,
314 DecoderDoctorDiagnostics* aDiagnostics);
317 * Called when a child source element is added to this media element. This
318 * may queue a task to run the select resource algorithm if appropriate.
320 void NotifyAddedSource();
323 * Called when there's been an error fetching the resource. This decides
324 * whether it's appropriate to fire an error event.
326 void NotifyLoadError(const nsACString& aErrorDetails = nsCString());
329 * Called by one of our associated MediaTrackLists (audio/video) when an
330 * AudioTrack is enabled or a VideoTrack is selected.
332 void NotifyMediaTrackEnabled(MediaTrack* aTrack);
335 * Called by one of our associated MediaTrackLists (audio/video) when an
336 * AudioTrack is disabled or a VideoTrack is unselected.
338 void NotifyMediaTrackDisabled(MediaTrack* aTrack);
341 * Called when a captured MediaStreamTrack is stopped so we can clean up its
342 * MediaInputPort.
344 void NotifyOutputTrackStopped(DOMMediaStream* aOwningStream,
345 TrackID aDestinationTrackID);
348 * Returns the current load ID. Asynchronous events store the ID that was
349 * current when they were enqueued, and if it has changed when they come to
350 * fire, they consider themselves cancelled, and don't fire.
352 uint32_t GetCurrentLoadID() { return mCurrentLoadID; }
355 * Returns the load group for this media element's owner document.
356 * XXX XBL2 issue.
358 already_AddRefed<nsILoadGroup> GetDocumentLoadGroup();
361 * Returns true if the media has played or completed a seek.
362 * Used by video frame to determine whether to paint the poster.
364 bool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; }
366 nsresult CopyInnerTo(Element* aDest);
369 * Sets the Accept header on the HTTP channel to the required
370 * video or audio MIME types.
372 virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) = 0;
375 * Sets the required request headers on the HTTP channel for
376 * video or audio requests.
378 void SetRequestHeaders(nsIHttpChannel* aChannel);
381 * Asynchronously awaits a stable state, whereupon aRunnable runs on the main
382 * thread. This adds an event which run aRunnable to the appshell's list of
383 * sections synchronous the next time control returns to the event loop.
385 void RunInStableState(nsIRunnable* aRunnable);
388 * Fires a timeupdate event. If aPeriodic is true, the event will only
389 * be fired if we've not fired a timeupdate event (for any reason) in the
390 * last 250ms, as required by the spec when the current time is periodically
391 * increasing during playback.
393 void FireTimeUpdate(bool aPeriodic) final;
396 * This will return null if mSrcStream is null, or if mSrcStream is not
397 * null but its GetPlaybackStream() returns null --- which can happen during
398 * cycle collection unlinking!
400 MediaStream* GetSrcMediaStream() const;
402 // WebIDL
404 MediaError* GetError() const;
406 void GetSrc(nsAString& aSrc) { GetURIAttr(nsGkAtoms::src, nullptr, aSrc); }
407 void SetSrc(const nsAString& aSrc, ErrorResult& aError) {
408 SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
410 void SetSrc(const nsAString& aSrc, nsIPrincipal* aTriggeringPrincipal,
411 ErrorResult& aError) {
412 SetHTMLAttr(nsGkAtoms::src, aSrc, aTriggeringPrincipal, aError);
415 void GetCurrentSrc(nsAString& aCurrentSrc);
417 void GetCrossOrigin(nsAString& aResult) {
418 // Null for both missing and invalid defaults is ok, since we
419 // always parse to an enum value, so we don't need an invalid
420 // default, and we _want_ the missing default to be null.
421 GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult);
423 void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError) {
424 SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
427 uint16_t NetworkState() const { return mNetworkState; }
429 void NotifyXPCOMShutdown() final;
431 // Called by media decoder when the audible state changed or when input is
432 // a media stream.
433 void SetAudibleState(bool aAudible) final;
435 // Notify agent when the MediaElement changes its audible state.
436 void NotifyAudioPlaybackChanged(AudibleChangedReasons aReason);
438 void GetPreload(nsAString& aValue) {
439 if (mSrcAttrStream) {
440 nsGkAtoms::none->ToString(aValue);
441 return;
443 GetEnumAttr(nsGkAtoms::preload, nullptr, aValue);
445 void SetPreload(const nsAString& aValue, ErrorResult& aRv) {
446 if (mSrcAttrStream) {
447 return;
449 SetHTMLAttr(nsGkAtoms::preload, aValue, aRv);
452 already_AddRefed<TimeRanges> Buffered() const;
454 void Load();
456 void CanPlayType(const nsAString& aType, nsAString& aResult);
458 uint16_t ReadyState() const { return mReadyState; }
460 bool Seeking() const;
462 double CurrentTime() const;
464 void SetCurrentTime(double aCurrentTime, ErrorResult& aRv);
465 void SetCurrentTime(double aCurrentTime) {
466 SetCurrentTime(aCurrentTime, IgnoreErrors());
469 void FastSeek(double aTime, ErrorResult& aRv);
471 already_AddRefed<Promise> SeekToNextFrame(ErrorResult& aRv);
473 double Duration() const;
475 bool HasAudio() const { return mMediaInfo.HasAudio(); }
477 virtual bool IsVideo() const { return false; }
479 bool HasVideo() const { return mMediaInfo.HasVideo(); }
481 bool IsEncrypted() const { return mIsEncrypted; }
483 bool Paused() const { return mPaused; }
485 double DefaultPlaybackRate() const {
486 if (mSrcAttrStream) {
487 return 1.0;
489 return mDefaultPlaybackRate;
492 void SetDefaultPlaybackRate(double aDefaultPlaybackRate, ErrorResult& aRv);
494 double PlaybackRate() const {
495 if (mSrcAttrStream) {
496 return 1.0;
498 return mPlaybackRate;
501 void SetPlaybackRate(double aPlaybackRate, ErrorResult& aRv);
503 already_AddRefed<TimeRanges> Played();
505 already_AddRefed<TimeRanges> Seekable() const;
507 bool Ended();
509 bool Autoplay() const { return GetBoolAttr(nsGkAtoms::autoplay); }
511 void SetAutoplay(bool aValue, ErrorResult& aRv) {
512 SetHTMLBoolAttr(nsGkAtoms::autoplay, aValue, aRv);
515 bool Loop() const { return GetBoolAttr(nsGkAtoms::loop); }
517 void SetLoop(bool aValue, ErrorResult& aRv) {
518 SetHTMLBoolAttr(nsGkAtoms::loop, aValue, aRv);
521 already_AddRefed<Promise> Play(ErrorResult& aRv);
523 void Pause(ErrorResult& aRv);
524 void Pause() { Pause(IgnoreErrors()); }
526 bool Controls() const { return GetBoolAttr(nsGkAtoms::controls); }
528 void SetControls(bool aValue, ErrorResult& aRv) {
529 SetHTMLBoolAttr(nsGkAtoms::controls, aValue, aRv);
532 double Volume() const { return mVolume; }
534 void SetVolume(double aVolume, ErrorResult& aRv);
536 bool Muted() const { return mMuted & MUTED_BY_CONTENT; }
537 void SetMuted(bool aMuted);
539 bool DefaultMuted() const { return GetBoolAttr(nsGkAtoms::muted); }
541 void SetDefaultMuted(bool aMuted, ErrorResult& aRv) {
542 SetHTMLBoolAttr(nsGkAtoms::muted, aMuted, aRv);
545 bool MozAllowCasting() const { return mAllowCasting; }
547 void SetMozAllowCasting(bool aShow) { mAllowCasting = aShow; }
549 bool MozIsCasting() const { return mIsCasting; }
551 void SetMozIsCasting(bool aShow) { mIsCasting = aShow; }
553 // Returns whether a call to Play() would be rejected with NotAllowedError.
554 // This assumes "worst case" for unknowns. So if prompting for permission is
555 // enabled and no permission is stored, this behaves as if the user would
556 // opt to block.
557 bool AllowedToPlay() const;
559 already_AddRefed<MediaSource> GetMozMediaSourceObject() const;
561 // Returns a promise which will be resolved after collecting debugging
562 // data from decoder/reader/MDSM. Used for debugging purposes.
563 already_AddRefed<Promise> MozRequestDebugInfo(ErrorResult& aRv);
565 // Enables DecoderDoctorLogger logging. Used for debugging purposes.
566 static void MozEnableDebugLog(const GlobalObject&);
568 // Returns a promise which will be resolved after collecting debugging
569 // log associated with this element. Used for debugging purposes.
570 already_AddRefed<Promise> MozRequestDebugLog(ErrorResult& aRv);
572 // For use by mochitests. Enabling pref "media.test.video-suspend"
573 void SetVisible(bool aVisible);
575 // For use by mochitests. Enabling pref "media.test.video-suspend"
576 bool HasSuspendTaint() const;
578 // For use by mochitests.
579 bool IsVideoDecodingSuspended() const;
581 // For use by mochitests only.
582 bool IsVisible() const;
584 // Synchronously, return the next video frame and mark the element unable to
585 // participate in decode suspending.
587 // This function is synchronous for cases where decoding has been suspended
588 // and JS needs a frame to use in, eg., nsLayoutUtils::SurfaceFromElement()
589 // via drawImage().
590 already_AddRefed<layers::Image> GetCurrentImage();
592 already_AddRefed<DOMMediaStream> GetSrcObject() const;
593 void SetSrcObject(DOMMediaStream& aValue);
594 void SetSrcObject(DOMMediaStream* aValue);
596 bool MozPreservesPitch() const { return mPreservesPitch; }
597 void SetMozPreservesPitch(bool aPreservesPitch);
599 MediaKeys* GetMediaKeys() const;
601 already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
602 ErrorResult& aRv);
604 mozilla::dom::EventHandlerNonNull* GetOnencrypted();
605 void SetOnencrypted(mozilla::dom::EventHandlerNonNull* aCallback);
607 mozilla::dom::EventHandlerNonNull* GetOnwaitingforkey();
608 void SetOnwaitingforkey(mozilla::dom::EventHandlerNonNull* aCallback);
610 void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
611 const nsAString& aInitDataType) override;
613 bool IsEventAttributeNameInternal(nsAtom* aName) override;
615 // Returns the principal of the "top level" document; the origin displayed
616 // in the URL bar of the browser window.
617 already_AddRefed<nsIPrincipal> GetTopLevelPrincipal();
619 bool ContainsRestrictedContent();
621 void NotifyWaitingForKey() override;
623 already_AddRefed<DOMMediaStream> CaptureAudio(ErrorResult& aRv,
624 MediaStreamGraph* aGraph);
626 already_AddRefed<DOMMediaStream> MozCaptureStream(ErrorResult& aRv);
628 already_AddRefed<DOMMediaStream> MozCaptureStreamUntilEnded(ErrorResult& aRv);
630 bool MozAudioCaptured() const { return mAudioCaptured; }
632 void MozGetMetadata(JSContext* aCx, JS::MutableHandle<JSObject*> aResult,
633 ErrorResult& aRv);
635 double MozFragmentEnd();
637 AudioTrackList* AudioTracks();
639 VideoTrackList* VideoTracks();
641 TextTrackList* GetTextTracks();
643 already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
644 const nsAString& aLabel,
645 const nsAString& aLanguage);
647 void AddTextTrack(TextTrack* aTextTrack) {
648 GetOrCreateTextTrackManager()->AddTextTrack(aTextTrack);
651 void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly = false) {
652 if (mTextTrackManager) {
653 mTextTrackManager->RemoveTextTrack(aTextTrack, aPendingListOnly);
657 void NotifyCueAdded(TextTrackCue& aCue) {
658 if (mTextTrackManager) {
659 mTextTrackManager->NotifyCueAdded(aCue);
662 void NotifyCueRemoved(TextTrackCue& aCue) {
663 if (mTextTrackManager) {
664 mTextTrackManager->NotifyCueRemoved(aCue);
667 void NotifyCueUpdated(TextTrackCue* aCue) {
668 if (mTextTrackManager) {
669 mTextTrackManager->NotifyCueUpdated(aCue);
673 void NotifyCueDisplayStatesChanged();
675 bool IsBlessed() const { return mIsBlessed; }
677 // A method to check whether we are currently playing.
678 bool IsCurrentlyPlaying() const;
680 // Returns true if the media element is being destroyed. Used in
681 // dormancy checks to prevent dormant processing for an element
682 // that will soon be gone.
683 bool IsBeingDestroyed();
685 void OnVisibilityChange(Visibility aNewVisibility);
687 // These are used for testing only
688 float ComputedVolume() const;
689 bool ComputedMuted() const;
690 nsSuspendedTypes ComputedSuspended() const;
692 void SetMediaInfo(const MediaInfo& aInfo);
694 AbstractThread* AbstractMainThread() const final;
696 // Telemetry: to record the usage of a {visible / invisible} video element as
697 // the source of {drawImage(), createPattern(), createImageBitmap() and
698 // captureStream()} APIs.
699 enum class CallerAPI {
700 DRAW_IMAGE,
701 CREATE_PATTERN,
702 CREATE_IMAGEBITMAP,
703 CAPTURE_STREAM,
705 void MarkAsContentSource(CallerAPI aAPI);
707 Document* GetDocument() const override;
709 void ConstructMediaTracks(const MediaInfo* aInfo) override;
711 void RemoveMediaTracks() override;
713 already_AddRefed<GMPCrashHelper> CreateGMPCrashHelper() override;
715 // The promise resolving/rejection is queued as a "micro-task" which will be
716 // handled immediately after the current JS task and before any pending JS
717 // tasks.
718 // At the time we are going to resolve/reject a promise, the "seeking" event
719 // task should already be queued but might yet be processed, so we queue one
720 // more task to file the promise resolving/rejection micro-tasks
721 // asynchronously to make sure that the micro-tasks are processed after the
722 // "seeking" event task.
723 void AsyncResolveSeekDOMPromiseIfExists() override;
724 void AsyncRejectSeekDOMPromiseIfExists() override;
726 nsISerialEventTarget* MainThreadEventTarget() {
727 return mMainThreadEventTarget;
730 // Set the sink id (of the output device) that the audio will play. If aSinkId
731 // is empty the default device will be set.
732 already_AddRefed<Promise> SetSinkId(const nsAString& aSinkId,
733 ErrorResult& aRv);
734 // Get the sink id of the device that audio is being played. Initial value is
735 // empty and the default device is being used.
736 void GetSinkId(nsString& aSinkId) {
737 MOZ_ASSERT(NS_IsMainThread());
738 aSinkId = mSink.first();
741 // This is used to notify MediaElementAudioSourceNode that media element is
742 // allowed to play when media element is used as a source for web audio, so
743 // that we can start AudioContext if it was not allowed to start.
744 RefPtr<GenericNonExclusivePromise> GetAllowedToPlayPromise();
746 bool GetShowPosterFlag() const { return mShowPoster; }
748 protected:
749 virtual ~HTMLMediaElement();
751 class AudioChannelAgentCallback;
752 class ChannelLoader;
753 class ErrorSink;
754 class MediaLoadListener;
755 class MediaStreamTrackListener;
756 class FirstFrameListener;
757 class ShutdownObserver;
759 MediaDecoderOwner::NextFrameStatus NextFrameStatus();
761 void SetDecoder(MediaDecoder* aDecoder);
763 // Holds references to the DOM wrappers for the MediaStreams that we're
764 // writing to.
765 struct OutputMediaStream {
766 OutputMediaStream();
767 ~OutputMediaStream();
769 RefPtr<DOMMediaStream> mStream;
770 TrackID mNextAvailableTrackID;
771 bool mFinishWhenEnded;
772 bool mCapturingAudioOnly;
773 bool mCapturingDecoder;
774 bool mCapturingMediaStream;
776 // The following members are keeping state for a captured MediaStream.
777 nsTArray<Pair<nsString, RefPtr<MediaInputPort>>> mTrackPorts;
780 void PlayInternal(bool aHandlingUserInput);
782 /** Use this method to change the mReadyState member, so required
783 * events can be fired.
785 void ChangeReadyState(nsMediaReadyState aState);
788 * Use this method to change the mNetworkState member, so required
789 * actions will be taken during the transition.
791 void ChangeNetworkState(nsMediaNetworkState aState);
794 * The MediaElement will be responsible for creating and releasing the audio
795 * wakelock depending on the playing and audible state.
797 virtual void WakeLockRelease();
798 virtual void UpdateWakeLock();
800 void CreateAudioWakeLockIfNeeded();
801 void ReleaseAudioWakeLockIfExists();
802 RefPtr<WakeLock> mWakeLock;
805 * Logs a warning message to the web console to report various failures.
806 * aMsg is the localized message identifier, aParams is the parameters to
807 * be substituted into the localized message, and aParamCount is the number
808 * of parameters in aParams.
810 void ReportLoadError(const char* aMsg, const nsTArray<nsString>& aParams =
811 nsTArray<nsString>());
814 * Log message to web console.
816 void ReportToConsole(
817 uint32_t aErrorFlags, const char* aMsg,
818 const nsTArray<nsString>& aParams = nsTArray<nsString>()) const;
821 * Changes mHasPlayedOrSeeked to aValue. If mHasPlayedOrSeeked changes
822 * we'll force a reflow so that the video frame gets reflowed to reflect
823 * the poster hiding or showing immediately.
825 void SetPlayedOrSeeked(bool aValue);
828 * Initialize the media element for playback of aStream
830 void SetupSrcMediaStreamPlayback(DOMMediaStream* aStream);
832 * Stop playback on mSrcStream.
834 void EndSrcMediaStreamPlayback();
836 * Ensure we're playing mSrcStream if and only if we're not paused.
838 enum { REMOVING_SRC_STREAM = 0x1 };
839 void UpdateSrcMediaStreamPlaying(uint32_t aFlags = 0);
842 * mSrcStream's graph's CurrentTime() has been updated. It might be time to
843 * fire "timeupdate".
845 void UpdateSrcStreamTime();
848 * Called by our DOMMediaStream::TrackListener when a new MediaStreamTrack has
849 * been added to the playback stream of |mSrcStream|.
851 void NotifyMediaStreamTrackAdded(const RefPtr<MediaStreamTrack>& aTrack);
854 * Called by our DOMMediaStream::TrackListener when a MediaStreamTrack in
855 * |mSrcStream|'s playback stream has ended.
857 void NotifyMediaStreamTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack);
860 * Enables or disables all tracks forwarded from mSrcStream to all
861 * OutputMediaStreams. We do this for muting the tracks when pausing,
862 * and unmuting when playing the media element again.
864 * If mSrcStream is unset, this does nothing.
866 void SetCapturedOutputStreamsEnabled(bool aEnabled);
869 * Create a new MediaStreamTrack for aTrack and add it to the DOMMediaStream
870 * in aOutputStream. This automatically sets the output track to enabled or
871 * disabled depending on our current playing state.
873 void AddCaptureMediaTrackToOutputStream(MediaTrack* aTrack,
874 OutputMediaStream& aOutputStream,
875 bool aAsyncAddtrack = true);
878 * Returns an DOMMediaStream containing the played contents of this
879 * element. When aBehavior is FINISH_WHEN_ENDED, when this element ends
880 * playback we will finish the stream and not play any more into it. When
881 * aType is CONTINUE_WHEN_ENDED, ending playback does not finish the stream.
882 * The stream will never finish.
884 * When aType is CAPTURE_AUDIO, we stop playout of audio and instead route it
885 * to the DOMMediaStream. Volume and mute state will be applied to the audio
886 * reaching the stream. No video tracks will be captured in this case.
888 already_AddRefed<DOMMediaStream> CaptureStreamInternal(
889 StreamCaptureBehavior aBehavior, StreamCaptureType aType,
890 MediaStreamGraph* aGraph);
893 * Initialize a decoder as a clone of an existing decoder in another
894 * element.
895 * mLoadingSrc must already be set.
897 nsresult InitializeDecoderAsClone(ChannelMediaDecoder* aOriginal);
900 * Call Load() and FinishDecoderSetup() on the decoder. It also handle
901 * resource cloning if DecoderType is ChannelMediaDecoder.
903 template <typename DecoderType, typename... LoadArgs>
904 nsresult SetupDecoder(DecoderType* aDecoder, LoadArgs&&... aArgs);
907 * Initialize a decoder to load the given channel. The decoder's stream
908 * listener is returned via aListener.
909 * mLoadingSrc must already be set.
911 nsresult InitializeDecoderForChannel(nsIChannel* aChannel,
912 nsIStreamListener** aListener);
915 * Finish setting up the decoder after Load() has been called on it.
916 * Called by InitializeDecoderForChannel/InitializeDecoderAsClone.
918 nsresult FinishDecoderSetup(MediaDecoder* aDecoder);
921 * Call this after setting up mLoadingSrc and mDecoder.
923 void AddMediaElementToURITable();
925 * Call this before modifying mLoadingSrc.
927 void RemoveMediaElementFromURITable();
929 * Call this to find a media element with the same NodePrincipal and
930 * mLoadingSrc set to aURI, and with a decoder on which Load() has been
931 * called.
933 HTMLMediaElement* LookupMediaElementURITable(nsIURI* aURI);
936 * Shutdown and clear mDecoder and maintain associated invariants.
938 void ShutdownDecoder();
940 * Execute the initial steps of the load algorithm that ensure existing
941 * loads are aborted, the element is emptied, and a new load ID is
942 * created.
944 void AbortExistingLoads();
947 * This is the dedicated media source failure steps.
948 * Called when all potential resources are exhausted. Changes network
949 * state to NETWORK_NO_SOURCE, and sends error event with code
950 * MEDIA_ERR_SRC_NOT_SUPPORTED.
952 void NoSupportedMediaSourceError(
953 const nsACString& aErrorDetails = nsCString());
956 * Per spec, Failed with elements: Queue a task, using the DOM manipulation
957 * task source, to fire a simple event named error at the candidate element.
958 * So dispatch |QueueLoadFromSourceTask| to main thread to make sure the task
959 * will be executed later than loadstart event.
961 void DealWithFailedElement(nsIContent* aSourceElement);
964 * Attempts to load resources from the <source> children. This is a
965 * substep of the resource selection algorithm. Do not call this directly,
966 * call QueueLoadFromSourceTask() instead.
968 void LoadFromSourceChildren();
971 * Asynchronously awaits a stable state, and then causes
972 * LoadFromSourceChildren() to be called on the main threads' event loop.
974 void QueueLoadFromSourceTask();
977 * Runs the media resource selection algorithm.
979 void SelectResource();
982 * A wrapper function that allows us to cleanly reset flags after a call
983 * to SelectResource()
985 void SelectResourceWrapper();
988 * Asynchronously awaits a stable state, and then causes SelectResource()
989 * to be run on the main thread's event loop.
991 void QueueSelectResourceTask();
994 * When loading a new source on an existing media element, make sure to reset
995 * everything that is accessible using the media element API.
997 void ResetState();
1000 * The resource-fetch algorithm step of the load algorithm.
1002 MediaResult LoadResource();
1005 * Selects the next <source> child from which to load a resource. Called
1006 * during the resource selection algorithm. Stores the return value in
1007 * mSourceLoadCandidate before returning.
1009 Element* GetNextSource();
1012 * Changes mDelayingLoadEvent, and will call BlockOnLoad()/UnblockOnLoad()
1013 * on the owning document, so it can delay the load event firing.
1015 void ChangeDelayLoadStatus(bool aDelay);
1018 * If we suspended downloading after the first frame, unsuspend now.
1020 void StopSuspendingAfterFirstFrame();
1023 * Called when our channel is redirected to another channel.
1024 * Updates our mChannel reference to aNewChannel.
1026 nsresult OnChannelRedirect(nsIChannel* aChannel, nsIChannel* aNewChannel,
1027 uint32_t aFlags);
1030 * Call this to reevaluate whether we should be holding a self-reference.
1032 void AddRemoveSelfReference();
1035 * Called when "xpcom-shutdown" event is received.
1037 void NotifyShutdownEvent();
1040 * Possible values of the 'preload' attribute.
1042 enum PreloadAttrValue : uint8_t {
1043 PRELOAD_ATTR_EMPTY, // set to ""
1044 PRELOAD_ATTR_NONE, // set to "none"
1045 PRELOAD_ATTR_METADATA, // set to "metadata"
1046 PRELOAD_ATTR_AUTO // set to "auto"
1050 * The preloading action to perform. These dictate how we react to the
1051 * preload attribute. See mPreloadAction.
1053 enum PreloadAction {
1054 PRELOAD_UNDEFINED = 0, // not determined - used only for initialization
1055 PRELOAD_NONE = 1, // do not preload
1056 PRELOAD_METADATA = 2, // preload only the metadata (and first frame)
1057 PRELOAD_ENOUGH = 3 // preload enough data to allow uninterrupted
1058 // playback
1062 * The guts of Load(). Load() acts as a wrapper around this which sets
1063 * mIsDoingExplicitLoad to true so that when script calls 'load()'
1064 * preload-none will be automatically upgraded to preload-metadata.
1066 void DoLoad();
1069 * Suspends the load of mLoadingSrc, so that it can be resumed later
1070 * by ResumeLoad(). This is called when we have a media with a 'preload'
1071 * attribute value of 'none', during the resource selection algorithm.
1073 void SuspendLoad();
1076 * Resumes a previously suspended load (suspended by SuspendLoad(uri)).
1077 * Will continue running the resource selection algorithm.
1078 * Sets mPreloadAction to aAction.
1080 void ResumeLoad(PreloadAction aAction);
1083 * Handle a change to the preload attribute. Should be called whenever the
1084 * value (or presence) of the preload attribute changes. The change in
1085 * attribute value may cause a change in the mPreloadAction of this
1086 * element. If there is a change then this method will initiate any
1087 * behaviour that is necessary to implement the action.
1089 void UpdatePreloadAction();
1092 * Fire progress events if needed according to the time and byte constraints
1093 * outlined in the specification. aHaveNewProgress is true if progress has
1094 * just been detected. Otherwise the method is called as a result of the
1095 * progress timer.
1097 void CheckProgress(bool aHaveNewProgress);
1098 static void ProgressTimerCallback(nsITimer* aTimer, void* aClosure);
1100 * Start timer to update download progress.
1102 void StartProgressTimer();
1104 * Start sending progress and/or stalled events.
1106 void StartProgress();
1108 * Stop progress information timer and events.
1110 void StopProgress();
1113 * Dispatches an error event to a child source element.
1115 void DispatchAsyncSourceError(nsIContent* aSourceElement);
1118 * Resets the media element for an error condition as per aErrorCode.
1119 * aErrorCode must be one of WebIDL HTMLMediaElement error codes.
1121 void Error(uint16_t aErrorCode,
1122 const nsACString& aErrorDetails = nsCString());
1125 * Returns the URL spec of the currentSrc.
1127 void GetCurrentSpec(nsCString& aString);
1130 * Process any media fragment entries in the URI
1132 void ProcessMediaFragmentURI();
1135 * Mute or unmute the audio and change the value that the |muted| map.
1137 void SetMutedInternal(uint32_t aMuted);
1139 * Update the volume of the output audio stream to match the element's
1140 * current mMuted/mVolume/mAudioChannelFaded state.
1142 void SetVolumeInternal();
1145 * Suspend (if aPauseForInactiveDocument) or resume element playback and
1146 * resource download. If aSuspendEvents is true, event delivery is
1147 * suspended (and events queued) until the element is resumed.
1149 void SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents);
1151 // Get the HTMLMediaElement object if the decoder is being used from an
1152 // HTML media element, and null otherwise.
1153 HTMLMediaElement* GetMediaElement() final { return this; }
1155 // Return true if decoding should be paused
1156 bool GetPaused() final { return Paused(); }
1159 * Video has been playing while hidden and, if feature was enabled, would
1160 * trigger suspending decoder.
1161 * Used to track hidden-video-decode-suspend telemetry.
1163 static void VideoDecodeSuspendTimerCallback(nsITimer* aTimer, void* aClosure);
1165 * Video is now both: playing and hidden.
1166 * Used to track hidden-video telemetry.
1168 void HiddenVideoStart();
1170 * Video is not playing anymore and/or has become visible.
1171 * Used to track hidden-video telemetry.
1173 void HiddenVideoStop();
1175 void ReportTelemetry();
1177 // Seeks to aTime seconds. aSeekType can be Exact to seek to exactly the
1178 // seek target, or PrevSyncPoint if a quicker but less precise seek is
1179 // desired, and we'll seek to the sync point (keyframe and/or start of the
1180 // next block of audio samples) preceeding seek target.
1181 already_AddRefed<Promise> Seek(double aTime, SeekTarget::Type aSeekType,
1182 ErrorResult& aRv);
1184 // Update the audio channel playing state
1185 void UpdateAudioChannelPlayingState(bool aForcePlaying = false);
1187 // Adds to the element's list of pending text tracks each text track
1188 // in the element's list of text tracks whose text track mode is not disabled
1189 // and whose text track readiness state is loading.
1190 void PopulatePendingTextTrackList();
1192 // Gets a reference to the MediaElement's TextTrackManager. If the
1193 // MediaElement doesn't yet have one then it will create it.
1194 TextTrackManager* GetOrCreateTextTrackManager();
1196 // Recomputes ready state and fires events as necessary based on current
1197 // state.
1198 void UpdateReadyStateInternal();
1200 // Determine if the element should be paused because of suspend conditions.
1201 bool ShouldElementBePaused();
1203 // Create or destroy the captured stream.
1204 void AudioCaptureStreamChange(bool aCapture);
1206 // A method to check whether the media element is allowed to start playback.
1207 bool AudioChannelAgentBlockedPlay();
1209 // If the network state is empty and then we would trigger DoLoad().
1210 void MaybeDoLoad();
1212 // Anything we need to check after played success and not related with spec.
1213 void UpdateCustomPolicyAfterPlayed();
1215 // Returns a StreamCaptureType populated with the right bits, depending on the
1216 // tracks this HTMLMediaElement has.
1217 StreamCaptureType CaptureTypeForElement();
1219 // True if this element can be captured, false otherwise.
1220 bool CanBeCaptured(StreamCaptureType aCaptureType);
1222 class nsAsyncEventRunner;
1223 class nsNotifyAboutPlayingRunner;
1224 class nsResolveOrRejectPendingPlayPromisesRunner;
1225 using nsGenericHTMLElement::DispatchEvent;
1226 // For nsAsyncEventRunner.
1227 nsresult DispatchEvent(const nsAString& aName);
1229 // This method moves the mPendingPlayPromises into a temperate object. So the
1230 // mPendingPlayPromises is cleared after this method call.
1231 nsTArray<RefPtr<PlayPromise>> TakePendingPlayPromises();
1233 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
1234 // and queues a task to resolve them.
1235 void AsyncResolvePendingPlayPromises();
1237 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
1238 // and queues a task to reject them.
1239 void AsyncRejectPendingPlayPromises(nsresult aError);
1241 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
1242 // and queues a task to resolve them also to dispatch a "playing" event.
1243 void NotifyAboutPlaying();
1245 already_AddRefed<Promise> CreateDOMPromise(ErrorResult& aRv) const;
1247 // Pass information for deciding the video decode mode to decoder.
1248 void NotifyDecoderActivityChanges() const;
1250 // Mark the decoder owned by the element as tainted so that the
1251 // suspend-video-decoder is disabled.
1252 void MarkAsTainted();
1254 virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
1255 const nsAttrValue* aValue,
1256 const nsAttrValue* aOldValue,
1257 nsIPrincipal* aMaybeScriptedPrincipal,
1258 bool aNotify) override;
1259 virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsAtom* aName,
1260 const nsAttrValueOrString& aValue,
1261 bool aNotify) override;
1263 bool DetachExistingMediaKeys();
1264 bool TryRemoveMediaKeysAssociation();
1265 void RemoveMediaKeys();
1266 bool AttachNewMediaKeys();
1267 bool TryMakeAssociationWithCDM(CDMProxy* aProxy);
1268 void MakeAssociationWithCDMResolved();
1269 void SetCDMProxyFailure(const MediaResult& aResult);
1270 void ResetSetMediaKeysTempVariables();
1272 void PauseIfShouldNotBePlaying();
1274 WatchManager<HTMLMediaElement> mWatchManager;
1276 // If the media element's tab has never been in the foreground, this
1277 // registers as with the AudioChannelAgent to notify us when the tab
1278 // is put in the foreground, whereupon we will begin playback.
1279 bool AudioChannelAgentDelayingPlayback();
1281 // Update the silence range of the audio track when the audible status of
1282 // silent audio track changes or seeking to the new position where the audio
1283 // track is silent.
1284 void UpdateAudioTrackSilenceRange(bool aAudible);
1286 // When silent audio track becomes audible or seeking to new place, we would
1287 // end the current silence range and accumulate it to the total silence
1288 // proportion of audio track and update current silence range.
1289 void AccumulateAudioTrackSilence();
1291 // True when the media element's audio track is containing silence now.
1292 bool IsAudioTrackCurrentlySilent() const;
1294 // Calculate the audio track silence proportion and then report the telemetry
1295 // result. we would report the result when decoder is destroyed.
1296 void ReportAudioTrackSilenceProportionTelemetry();
1298 // When the play is not allowed, dispatch related events which are used for
1299 // testing or changing control UI.
1300 void DispatchEventsWhenPlayWasNotAllowed();
1302 // The current decoder. Load() has been called on this decoder.
1303 // At most one of mDecoder and mSrcStream can be non-null.
1304 RefPtr<MediaDecoder> mDecoder;
1306 // The DocGroup-specific nsISerialEventTarget of this HTML element on the main
1307 // thread.
1308 nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
1310 // The DocGroup-specific AbstractThread::MainThread() of this HTML element.
1311 RefPtr<AbstractThread> mAbstractMainThread;
1313 // A reference to the VideoFrameContainer which contains the current frame
1314 // of video to display.
1315 RefPtr<VideoFrameContainer> mVideoFrameContainer;
1317 // Holds a reference to the DOM wrapper for the MediaStream that has been
1318 // set in the src attribute.
1319 RefPtr<DOMMediaStream> mSrcAttrStream;
1321 // Holds the triggering principal for the src attribute.
1322 nsCOMPtr<nsIPrincipal> mSrcAttrTriggeringPrincipal;
1324 // Holds a reference to the DOM wrapper for the MediaStream that we're
1325 // actually playing.
1326 // At most one of mDecoder and mSrcStream can be non-null.
1327 RefPtr<DOMMediaStream> mSrcStream;
1329 // True once mSrcStream's initial set of tracks are known.
1330 bool mSrcStreamTracksAvailable = false;
1332 // While mPaused is true and mSrcStream is set, this is the value to use for
1333 // CurrentTime(). Otherwise this is Nothing.
1334 Maybe<GraphTime> mSrcStreamPausedGraphTime;
1336 // The offset in GraphTime at which this media element started playing the
1337 // playback stream of mSrcStream.
1338 GraphTime mSrcStreamGraphTimeOffset = 0;
1340 // True once PlaybackEnded() is called and we're playing a MediaStream.
1341 // Reset to false if we start playing mSrcStream again.
1342 bool mSrcStreamPlaybackEnded = false;
1344 // Holds a reference to the stream connecting this stream to the capture sink.
1345 RefPtr<MediaInputPort> mCaptureStreamPort;
1347 // Holds references to the DOM wrappers for the MediaStreams that we're
1348 // writing to.
1349 nsTArray<OutputMediaStream> mOutputStreams;
1351 // The next track id to use for a captured MediaDecoder.
1352 TrackID mNextAvailableMediaDecoderOutputTrackID = 1;
1354 // Holds a reference to the first-frame-getting track listener attached to
1355 // mSelectedVideoStreamTrack.
1356 RefPtr<FirstFrameListener> mFirstFrameListener;
1357 // The currently selected video stream track.
1358 RefPtr<VideoStreamTrack> mSelectedVideoStreamTrack;
1360 const RefPtr<ShutdownObserver> mShutdownObserver;
1362 // Holds a reference to the MediaSource, if any, referenced by the src
1363 // attribute on the media element.
1364 RefPtr<MediaSource> mSrcMediaSource;
1366 // Holds a reference to the MediaSource supplying data for playback. This
1367 // may either match mSrcMediaSource or come from Source element children.
1368 // This is set when and only when mLoadingSrc corresponds to an object url
1369 // that resolved to a MediaSource.
1370 RefPtr<MediaSource> mMediaSource;
1372 RefPtr<ChannelLoader> mChannelLoader;
1374 // Points to the child source elements, used to iterate through the children
1375 // when selecting a resource to load. This is the previous sibling of the
1376 // child considered the current 'candidate' in:
1377 // https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm
1379 // mSourcePointer == nullptr, we will next try to load |GetFirstChild()|.
1380 // mSourcePointer == GetLastChild(), we've exhausted all sources, waiting
1381 // for new elements to be appended.
1382 nsCOMPtr<nsIContent> mSourcePointer;
1384 // Points to the document whose load we're blocking. This is the document
1385 // we're bound to when loading starts.
1386 nsCOMPtr<Document> mLoadBlockedDoc;
1388 // Contains names of events that have been raised while in the bfcache.
1389 // These events get re-dispatched when the bfcache is exited.
1390 nsTArray<nsString> mPendingEvents;
1392 // Media loading flags. See:
1393 // http://www.whatwg.org/specs/web-apps/current-work/#video)
1394 nsMediaNetworkState mNetworkState = HTMLMediaElement_Binding::NETWORK_EMPTY;
1395 nsMediaReadyState mReadyState = HTMLMediaElement_Binding::HAVE_NOTHING;
1397 enum LoadAlgorithmState {
1398 // No load algorithm instance is waiting for a source to be added to the
1399 // media in order to continue loading.
1400 NOT_WAITING,
1401 // We've run the load algorithm, and we tried all source children of the
1402 // media element, and failed to load any successfully. We're waiting for
1403 // another source element to be added to the media element, and will try
1404 // to load any such element when its added.
1405 WAITING_FOR_SOURCE
1408 // The current media load ID. This is incremented every time we start a
1409 // new load. Async events note the ID when they're first sent, and only fire
1410 // if the ID is unchanged when they come to fire.
1411 uint32_t mCurrentLoadID = 0;
1413 // Denotes the waiting state of a load algorithm instance. When the load
1414 // algorithm is waiting for a source element child to be added, this is set
1415 // to WAITING_FOR_SOURCE, otherwise it's NOT_WAITING.
1416 LoadAlgorithmState mLoadWaitStatus = NOT_WAITING;
1418 // Current audio volume
1419 double mVolume = 1.0;
1421 // True if the audio track is not silent.
1422 bool mIsAudioTrackAudible = false;
1424 // Used to mark the start of the silence range of audio track.
1425 double mAudioTrackSilenceStartedTime = 0.0;
1427 // Save all the silence ranges, all ranges would be normalized. That means
1428 // intervals won't overlap or touch each other.
1429 media::TimeIntervals mSilenceTimeRanges;
1431 // True if we have calculated silence range before SeekEnd(). This attribute
1432 // would be reset after seeking completed.
1433 bool mHasAccumulatedSilenceRangeBeforeSeekEnd = false;
1435 enum MutedReasons {
1436 MUTED_BY_CONTENT = 0x01,
1437 MUTED_BY_INVALID_PLAYBACK_RATE = 0x02,
1438 MUTED_BY_AUDIO_CHANNEL = 0x04,
1439 MUTED_BY_AUDIO_TRACK = 0x08
1442 uint32_t mMuted = 0;
1444 UniquePtr<const MetadataTags> mTags;
1446 // URI of the resource we're attempting to load. This stores the value we
1447 // return in the currentSrc attribute. Use GetCurrentSrc() to access the
1448 // currentSrc attribute.
1449 // This is always the original URL we're trying to load --- before
1450 // redirects etc.
1451 nsCOMPtr<nsIURI> mLoadingSrc;
1453 // The triggering principal for the current source.
1454 nsCOMPtr<nsIPrincipal> mLoadingSrcTriggeringPrincipal;
1456 // Stores the current preload action for this element. Initially set to
1457 // PRELOAD_UNDEFINED, its value is changed by calling
1458 // UpdatePreloadAction().
1459 PreloadAction mPreloadAction = PRELOAD_UNDEFINED;
1461 // Time that the last timeupdate event was fired. Read/Write from the
1462 // main thread only.
1463 TimeStamp mTimeUpdateTime;
1465 // Time that the last progress event was fired. Read/Write from the
1466 // main thread only.
1467 TimeStamp mProgressTime;
1469 // Time that data was last read from the media resource. Used for
1470 // computing if the download has stalled and to rate limit progress events
1471 // when data is arriving slower than PROGRESS_MS.
1472 // Read/Write from the main thread only.
1473 TimeStamp mDataTime;
1475 // Media 'currentTime' value when the last timeupdate event occurred.
1476 // Read/Write from the main thread only.
1477 double mLastCurrentTime = 0.0;
1479 // Logical start time of the media resource in seconds as obtained
1480 // from any media fragments. A negative value indicates that no
1481 // fragment time has been set. Read/Write from the main thread only.
1482 double mFragmentStart = -1.0;
1484 // Logical end time of the media resource in seconds as obtained
1485 // from any media fragments. A negative value indicates that no
1486 // fragment time has been set. Read/Write from the main thread only.
1487 double mFragmentEnd = -1.0;
1489 // The defaultPlaybackRate attribute gives the desired speed at which the
1490 // media resource is to play, as a multiple of its intrinsic speed.
1491 double mDefaultPlaybackRate = 1.0;
1493 // The playbackRate attribute gives the speed at which the media resource
1494 // plays, as a multiple of its intrinsic speed. If it is not equal to the
1495 // defaultPlaybackRate, then the implication is that the user is using a
1496 // feature such as fast forward or slow motion playback.
1497 double mPlaybackRate = 1.0;
1499 // True if pitch correction is applied when playbackRate is set to a
1500 // non-intrinsic value.
1501 bool mPreservesPitch = true;
1503 // Reference to the source element last returned by GetNextSource().
1504 // This is the child source element which we're trying to load from.
1505 nsCOMPtr<nsIContent> mSourceLoadCandidate;
1507 // Range of time played.
1508 RefPtr<TimeRanges> mPlayed;
1510 // Timer used for updating progress events.
1511 nsCOMPtr<nsITimer> mProgressTimer;
1513 // Timer used to simulate video-suspend.
1514 nsCOMPtr<nsITimer> mVideoDecodeSuspendTimer;
1516 // Encrypted Media Extension media keys.
1517 RefPtr<MediaKeys> mMediaKeys;
1518 RefPtr<MediaKeys> mIncomingMediaKeys;
1519 // The dom promise is used for HTMLMediaElement::SetMediaKeys.
1520 RefPtr<DetailedPromise> mSetMediaKeysDOMPromise;
1521 // Used to indicate if the MediaKeys attaching operation is on-going or not.
1522 bool mAttachingMediaKey = false;
1523 MozPromiseRequestHolder<SetCDMPromise> mSetCDMRequest;
1525 // Stores the time at the start of the current 'played' range.
1526 double mCurrentPlayRangeStart = 1.0;
1528 // True if loadeddata has been fired.
1529 bool mLoadedDataFired = false;
1531 // Indicates whether current playback is a result of user action
1532 // (ie. calling of the Play method), or automatic playback due to
1533 // the 'autoplay' attribute being set. A true value indicates the
1534 // latter case.
1535 // The 'autoplay' HTML attribute indicates that the video should
1536 // start playing when loaded. The 'autoplay' attribute of the object
1537 // is a mirror of the HTML attribute. These are different from this
1538 // 'mAutoplaying' flag, which indicates whether the current playback
1539 // is a result of the autoplay attribute.
1540 bool mAutoplaying = true;
1542 // Playback of the video is paused either due to calling the
1543 // 'Pause' method, or playback not yet having started.
1544 Watchable<bool> mPaused;
1546 // The following two fields are here for the private storage of the builtin
1547 // video controls, and control 'casting' of the video to external devices
1548 // (TVs, projectors etc.)
1549 // True if casting is currently allowed
1550 bool mAllowCasting = false;
1551 // True if currently casting this video
1552 bool mIsCasting = false;
1554 // True if the sound is being captured.
1555 bool mAudioCaptured = false;
1557 // If TRUE then the media element was actively playing before the currently
1558 // in progress seeking. If FALSE then the media element is either not seeking
1559 // or was not actively playing before the current seek. Used to decide whether
1560 // to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
1561 bool mPlayingBeforeSeek = false;
1563 // True iff this element is paused because the document is inactive or has
1564 // been suspended by the audio channel service.
1565 bool mPausedForInactiveDocumentOrChannel = false;
1567 // True iff event delivery is suspended (mPausedForInactiveDocumentOrChannel
1568 // must also be true).
1569 bool mEventDeliveryPaused = false;
1571 // True if we're running the "load()" method.
1572 bool mIsRunningLoadMethod = false;
1574 // True if we're running or waiting to run queued tasks due to an explicit
1575 // call to "load()".
1576 bool mIsDoingExplicitLoad = false;
1578 // True if we're loading the resource from the child source elements.
1579 bool mIsLoadingFromSourceChildren = false;
1581 // True if we're delaying the "load" event. They are delayed until either
1582 // an error occurs, or the first frame is loaded.
1583 bool mDelayingLoadEvent = false;
1585 // True when we've got a task queued to call SelectResource(),
1586 // or while we're running SelectResource().
1587 bool mIsRunningSelectResource = false;
1589 // True when we already have select resource call queued
1590 bool mHaveQueuedSelectResource = false;
1592 // True if we suspended the decoder because we were paused,
1593 // preloading metadata is enabled, autoplay was not enabled, and we loaded
1594 // the first frame.
1595 bool mSuspendedAfterFirstFrame = false;
1597 // True if we are allowed to suspend the decoder because we were paused,
1598 // preloading metdata was enabled, autoplay was not enabled, and we loaded
1599 // the first frame.
1600 bool mAllowSuspendAfterFirstFrame = true;
1602 // True if we've played or completed a seek. We use this to determine
1603 // when the poster frame should be shown.
1604 bool mHasPlayedOrSeeked = false;
1606 // True if we've added a reference to ourselves to keep the element
1607 // alive while no-one is referencing it but the element may still fire
1608 // events of its own accord.
1609 bool mHasSelfReference = false;
1611 // True if we've received a notification that the engine is shutting
1612 // down.
1613 bool mShuttingDown = false;
1615 // True if we've suspended a load in the resource selection algorithm
1616 // due to loading a preload:none media. When true, the resource we'll
1617 // load when the user initiates either playback or an explicit load is
1618 // stored in mPreloadURI.
1619 bool mSuspendedForPreloadNone = false;
1621 // True if we've connected mSrcStream to the media element output.
1622 bool mSrcStreamIsPlaying = false;
1624 // True if we should set nsIClassOfService::UrgentStart to the channel to
1625 // get the response ASAP for better user responsiveness.
1626 bool mUseUrgentStartForChannel = false;
1628 // The CORS mode when loading the media element
1629 CORSMode mCORSMode = CORS_NONE;
1631 // Info about the played media.
1632 MediaInfo mMediaInfo;
1634 // True if the media has encryption information.
1635 bool mIsEncrypted = false;
1637 enum WaitingForKeyState {
1638 NOT_WAITING_FOR_KEY = 0,
1639 WAITING_FOR_KEY = 1,
1640 WAITING_FOR_KEY_DISPATCHED = 2
1643 // True when the CDM cannot decrypt the current block due to lacking a key.
1644 // Note: the "waitingforkey" event is not dispatched until all decoded data
1645 // has been rendered.
1646 WaitingForKeyState mWaitingForKey = NOT_WAITING_FOR_KEY;
1648 // Listens for waitingForKey events from the owned decoder.
1649 MediaEventListener mWaitingForKeyListener;
1651 // Init Data that needs to be sent in 'encrypted' events in MetadataLoaded().
1652 EncryptionInfo mPendingEncryptedInitData;
1654 // True if the media's channel's download has been suspended.
1655 bool mDownloadSuspendedByCache = false;
1657 // Disable the video playback by track selection. This flag might not be
1658 // enough if we ever expand the ability of supporting multi-tracks video
1659 // playback.
1660 bool mDisableVideo = false;
1662 RefPtr<TextTrackManager> mTextTrackManager;
1664 RefPtr<AudioTrackList> mAudioTrackList;
1666 RefPtr<VideoTrackList> mVideoTrackList;
1668 UniquePtr<MediaStreamTrackListener> mMediaStreamTrackListener;
1670 // The principal guarding mVideoFrameContainer access when playing a
1671 // MediaStream.
1672 nsCOMPtr<nsIPrincipal> mSrcStreamVideoPrincipal;
1674 // True if UnbindFromTree() is called on the element.
1675 // Note this flag is false when the element is in a phase after creation and
1676 // before attaching to the DOM tree.
1677 bool mUnboundFromTree = false;
1679 // True if the autoplay media was blocked because it hadn't loaded metadata
1680 // yet.
1681 bool mBlockedAsWithoutMetadata = false;
1683 // This promise is used to notify MediaElementAudioSourceNode that media
1684 // element is allowed to play when MediaElement is used as a source for web
1685 // audio.
1686 MozPromiseHolder<GenericNonExclusivePromise> mAllowedToPlayPromise;
1688 // True if media has ever been blocked for autoplay, it's used to notify front
1689 // end to show the correct blocking icon when the document goes back from
1690 // bfcache.
1691 bool mHasEverBeenBlockedForAutoplay = false;
1693 // True if we have dispatched a task for text track changed, will be unset
1694 // when we starts processing text track changed.
1695 // https://html.spec.whatwg.org/multipage/media.html#pending-text-track-change-notification-flag
1696 bool mPendingTextTrackChanged = false;
1698 public:
1699 // This function will be called whenever a text track that is in a media
1700 // element's list of text tracks has its text track mode change value
1701 void NotifyTextTrackModeChanged();
1703 public:
1704 // Helper class to measure times for playback telemetry stats
1705 class TimeDurationAccumulator {
1706 public:
1707 TimeDurationAccumulator() : mCount(0) {}
1708 void Start() {
1709 if (IsStarted()) {
1710 return;
1712 mStartTime = TimeStamp::Now();
1714 void Pause() {
1715 if (!IsStarted()) {
1716 return;
1718 mSum += (TimeStamp::Now() - mStartTime);
1719 mCount++;
1720 mStartTime = TimeStamp();
1722 bool IsStarted() const { return !mStartTime.IsNull(); }
1723 double Total() const {
1724 if (!IsStarted()) {
1725 return mSum.ToSeconds();
1727 // Add current running time until now, but keep it running.
1728 return (mSum + (TimeStamp::Now() - mStartTime)).ToSeconds();
1730 uint32_t Count() const {
1731 if (!IsStarted()) {
1732 return mCount;
1734 // Count current run in this report, without increasing the stored count.
1735 return mCount + 1;
1737 void Reset() {
1738 mStartTime = TimeStamp();
1739 mSum = TimeDuration();
1740 mCount = 0;
1743 private:
1744 TimeStamp mStartTime;
1745 TimeDuration mSum;
1746 uint32_t mCount;
1749 private:
1750 already_AddRefed<PlayPromise> CreatePlayPromise(ErrorResult& aRv) const;
1752 void UpdateHadAudibleAutoplayState();
1754 virtual void MaybeBeginCloningVisually(){};
1756 uint32_t GetPreloadDefault() const;
1757 uint32_t GetPreloadDefaultAuto() const;
1760 * This function is called by AfterSetAttr and OnAttrSetButNotChanged.
1761 * It will not be called if the value is being unset.
1763 * @param aNamespaceID the namespace of the attr being set
1764 * @param aName the localname of the attribute being set
1765 * @param aNotify Whether we plan to notify document observers.
1767 void AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName, bool aNotify);
1769 // Total time a video has spent playing.
1770 TimeDurationAccumulator mPlayTime;
1772 // Total time a video has spent playing while hidden.
1773 TimeDurationAccumulator mHiddenPlayTime;
1775 // Total time a video has (or would have) spent in video-decode-suspend mode.
1776 TimeDurationAccumulator mVideoDecodeSuspendTime;
1778 // Total time a video has spent playing on the current load, it would be reset
1779 // when media aborts the current load; be paused when the docuemt enters the
1780 // bf-cache and be resumed when the docuemt leaves the bf-cache.
1781 TimeDurationAccumulator mCurrentLoadPlayTime;
1783 // True if media has ever been blocked by autoplay policy before.
1784 bool mHasPlayEverBeenBlocked = false;
1786 // Report the Telemetry about whether media played over the specific time
1787 // threshold.
1788 void ReportPlayedTimeAfterBlockedTelemetry();
1790 // True if Init() has been called after construction
1791 bool mInitialized = false;
1793 // True if user has called load(), seek() or element has started playing
1794 // before. It's *only* use for checking autoplay policy
1795 bool mIsBlessed = false;
1797 // True if the first frame has been successfully loaded.
1798 bool mFirstFrameLoaded = false;
1800 // Media elements also have a default playback start position, which must
1801 // initially be set to zero seconds. This time is used to allow the element to
1802 // be seeked even before the media is loaded.
1803 double mDefaultPlaybackStartPosition = 0.0;
1805 // True if media element has been marked as 'tainted' and can't
1806 // participate in video decoder suspending.
1807 bool mHasSuspendTaint = false;
1809 // True if media element has been forced into being considered 'hidden'.
1810 // For use by mochitests. Enabling pref "media.test.video-suspend"
1811 bool mForcedHidden = false;
1813 // True if audio tracks and video tracks are constructed and added into the
1814 // track list, false if all tracks are removed from the track list.
1815 bool mMediaTracksConstructed = false;
1817 Visibility mVisibilityState = Visibility::Untracked;
1819 UniquePtr<ErrorSink> mErrorSink;
1821 // This wrapper will handle all audio channel related stuffs, eg. the
1822 // operations of tab audio indicator, Fennec's media control. Note:
1823 // mAudioChannelWrapper might be null after GC happened.
1824 RefPtr<AudioChannelAgentCallback> mAudioChannelWrapper;
1826 // A list of pending play promises. The elements are pushed during the play()
1827 // method call and are resolved/rejected during further playback steps.
1828 nsTArray<RefPtr<PlayPromise>> mPendingPlayPromises;
1830 // A list of already-dispatched but not yet run
1831 // nsResolveOrRejectPendingPlayPromisesRunners.
1832 // Runners whose Run() method is called remove themselves from this list.
1833 // We keep track of these because the load algorithm resolves/rejects all
1834 // already-dispatched pending play promises.
1835 nsTArray<nsResolveOrRejectPendingPlayPromisesRunner*>
1836 mPendingPlayPromisesRunners;
1838 // A pending seek promise which is created at Seek() method call and is
1839 // resolved/rejected at AsyncResolveSeekDOMPromiseIfExists()/
1840 // AsyncRejectSeekDOMPromiseIfExists() methods.
1841 RefPtr<dom::Promise> mSeekDOMPromise;
1843 // For debugging bug 1407148.
1844 void AssertReadyStateIsNothing();
1846 // Contains the unique id of the sink device and the device info.
1847 // The initial value is ("", nullptr) and the default output device is used.
1848 // It can contain an invalid id and info if the device has been
1849 // unplugged. It can be set to ("", nullptr). It follows the spec attribute:
1850 // https://w3c.github.io/mediacapture-output/#htmlmediaelement-extensions
1851 // Read/Write from the main thread only.
1852 Pair<nsString, RefPtr<AudioDeviceInfo>> mSink;
1854 // This flag is used to control when the user agent is to show a poster frame
1855 // for a video element instead of showing the video contents.
1856 // https://html.spec.whatwg.org/multipage/media.html#show-poster-flag
1857 bool mShowPoster;
1860 // Check if the context is chrome or has the debugger or tabs permission
1861 bool HasDebuggerOrTabsPrivilege(JSContext* aCx, JSObject* aObj);
1863 } // namespace dom
1864 } // namespace mozilla
1866 #endif // mozilla_dom_HTMLMediaElement_h