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 8 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 34 35 #include <utility> 36 37 // X.h on Linux #defines CurrentTime as 0L, so we have to #undef it here. 38 #ifdef CurrentTime 39 # undef CurrentTime 40 #endif 41 42 // Define to output information on decoding and painting framerate 43 /* #define DEBUG_FRAME_RATE 1 */ 44 45 using nsMediaNetworkState = uint16_t; 46 using nsMediaReadyState = uint16_t; 47 using SuspendTypes = uint32_t; 48 using AudibleChangedReasons = uint32_t; 49 50 class nsIStreamListener; 51 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 MediaKeys; 70 class TextTrack; 71 class TimeRanges; 72 class WakeLock; 73 class MediaStreamTrack; 74 class MediaStreamTrackSource; 75 class MediaTrack; 76 class VideoStreamTrack; 77 } // namespace dom 78 } // namespace mozilla 79 80 class AudioDeviceInfo; 81 class nsIChannel; 82 class nsIHttpChannel; 83 class nsILoadGroup; 84 class nsIRunnable; 85 class nsISerialEventTarget; 86 class nsITimer; 87 class nsRange; 88 89 namespace mozilla { 90 namespace dom { 91 92 // Number of milliseconds between timeupdate events as defined by spec 93 #define TIMEUPDATE_MS 250 94 95 class MediaError; 96 class MediaSource; 97 class PlayPromise; 98 class Promise; 99 class TextTrackList; 100 class AudioTrackList; 101 class VideoTrackList; 102 103 enum class StreamCaptureType : uint8_t { CAPTURE_ALL_TRACKS, CAPTURE_AUDIO }; 104 105 enum class StreamCaptureBehavior : uint8_t { 106 CONTINUE_WHEN_ENDED, 107 FINISH_WHEN_ENDED 108 }; 109 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; 123 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(); 132 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; 145 }; 146 147 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED 148 GetCORSMode()149 CORSMode GetCORSMode() { return mCORSMode; } 150 151 explicit HTMLMediaElement( 152 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo); 153 void Init(); 154 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, 164 }; 165 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, 172 }; 173 174 /** 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 181 */ 182 nsresult LoadWithChannel(nsIChannel* aChannel, nsIStreamListener** aListener); 183 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)) 191 192 NS_DECL_ADDSIZEOFEXCLUDINGTHIS 193 194 // EventTarget 195 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override; 196 197 void NodeInfoChanged(Document* aOldDoc) override; 198 199 virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, 200 const nsAString& aValue, 201 nsIPrincipal* aMaybeScriptedPrincipal, 202 nsAttrValue& aResult) override; 203 204 virtual nsresult BindToTree(BindContext&, nsINode& aParent) override; 205 virtual void UnbindFromTree(bool aNullParent = true) override; 206 virtual void DoneCreatingElement() override; 207 208 virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable, 209 int32_t* aTabIndex) override; 210 virtual int32_t TabIndexDefault() override; 211 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; 217 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; 221 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; 225 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; 229 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; 234 235 // Return true if error attribute is not null. 236 bool HasError() const final; 237 238 // Called by the video decoder object, on the main thread, when the 239 // resource load has been cancelled. 240 void LoadAborted() final; 241 242 // Called by the video decoder object, on the main thread, 243 // when the video playback has ended. 244 void PlaybackEnded() final; 245 246 // Called by the video decoder object, on the main thread, 247 // when the resource has started seeking. 248 void SeekStarted() final; 249 250 // Called by the video decoder object, on the main thread, 251 // when the resource has completed seeking. 252 void SeekCompleted() final; 253 254 // Called by the video decoder object, on the main thread, 255 // when the resource has aborted seeking. 256 void SeekAborted() final; 257 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; 262 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(); 267 268 // Called to indicate the download is progressing. 269 void DownloadProgressed() final; 270 271 // Called by the media decoder to indicate whether the media cache has 272 // suspended the channel. 273 void NotifySuspendedByCache(bool aSuspendedByCache) final; 274 275 // Return true if the media element is actually invisible to users. 276 bool IsActuallyInvisible() const override; 277 278 // Return true if the element is in the view port. 279 bool IsInViewPort() const; 280 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(); 285 286 /** 287 * Call this to reevaluate whether we should start/stop due to our owner 288 * document being active, inactive, visible or hidden. 289 */ 290 void NotifyOwnerDocumentActivityChanged(); 291 292 // Called when the media element enters or leaves the fullscreen. 293 void NotifyFullScreenChanged(); 294 295 bool IsInFullScreen() const; 296 297 // From PrincipalChangeObserver<MediaStreamTrack>. 298 void PrincipalChanged(MediaStreamTrack* aTrack) override; 299 300 void UpdateSrcStreamVideoPrincipal(const PrincipalHandle& aPrincipalHandle); 301 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; 307 308 // Dispatch events 309 void DispatchAsyncEvent(const nsAString& aName) final; 310 void DispatchAsyncEvent(RefPtr<nsMediaEventRunner> aRunner); 311 312 // Triggers a recomputation of readyState. UpdateReadyState()313 void UpdateReadyState() override { 314 mWatchManager.ManualNotify(&HTMLMediaElement::UpdateReadyStateInternal); 315 } 316 317 // Dispatch events that were raised while in the bfcache 318 nsresult DispatchPendingMediaEvents(); 319 320 // Return true if we can activate autoplay assuming enough data has arrived. 321 bool CanActivateAutoplay(); 322 323 // Notify that state has changed that might cause an autoplay element to 324 // start playing. 325 // If the element is 'autoplay' and is ready to play back (not paused, 326 // autoplay pref enabled, etc), it should start playing back. 327 void CheckAutoplayDataReady(); 328 329 // Check if the media element had crossorigin set when loading started 330 bool ShouldCheckAllowOrigin(); 331 332 // Returns true if the currently loaded resource is CORS same-origin with 333 // respect to the document. 334 bool IsCORSSameOrigin(); 335 336 // Is the media element potentially playing as defined by the HTML 5 337 // specification. 338 // http://www.whatwg.org/specs/web-apps/current-work/#potentially-playing 339 bool IsPotentiallyPlaying() const; 340 341 // Has playback ended as defined by the HTML 5 specification. 342 // http://www.whatwg.org/specs/web-apps/current-work/#ended 343 bool IsPlaybackEnded() const; 344 345 // principal of the currently playing resource. Anything accessing the 346 // contents of this element must have a principal that subsumes this 347 // principal. Returns null if nothing is playing. 348 already_AddRefed<nsIPrincipal> GetCurrentPrincipal(); 349 350 // Return true if the loading of this resource required cross-origin 351 // redirects. 352 bool HadCrossOriginRedirects(); 353 354 // Principal of the currently playing video resource. Anything accessing the 355 // image container of this element must have a principal that subsumes this 356 // principal. If there are no live video tracks but content has been rendered 357 // to the image container, we return the last video principal we had. Should 358 // the image container be empty with no live video tracks, we return nullptr. 359 already_AddRefed<nsIPrincipal> GetCurrentVideoPrincipal(); 360 361 // called to notify that the principal of the decoder's media resource has 362 // changed. 363 void NotifyDecoderPrincipalChanged() final; 364 365 void GetEMEInfo(dom::EMEDebugInfo& aInfo); 366 367 // Update the visual size of the media. Called from the decoder on the 368 // main thread when/if the size changes. 369 virtual void UpdateMediaSize(const nsIntSize& aSize); 370 // Like UpdateMediaSize, but only updates the size if no size has yet 371 // been set. 372 void UpdateInitialMediaSize(const nsIntSize& aSize); 373 374 void Invalidate(bool aImageSizeChanged, Maybe<nsIntSize>& aNewIntrinsicSize, 375 bool aForceInvalidate) override; 376 377 // Returns the CanPlayStatus indicating if we can handle the 378 // full MIME type including the optional codecs parameter. 379 static CanPlayStatus GetCanPlay(const nsAString& aType, 380 DecoderDoctorDiagnostics* aDiagnostics); 381 382 /** 383 * Called when a child source element is added to this media element. This 384 * may queue a task to run the select resource algorithm if appropriate. 385 */ 386 void NotifyAddedSource(); 387 388 /** 389 * Called when there's been an error fetching the resource. This decides 390 * whether it's appropriate to fire an error event. 391 */ 392 void NotifyLoadError(const nsACString& aErrorDetails = nsCString()); 393 394 /** 395 * Called by one of our associated MediaTrackLists (audio/video) when a 396 * MediaTrack is added. 397 */ 398 void NotifyMediaTrackAdded(dom::MediaTrack* aTrack); 399 400 /** 401 * Called by one of our associated MediaTrackLists (audio/video) when a 402 * MediaTrack is removed. 403 */ 404 void NotifyMediaTrackRemoved(dom::MediaTrack* aTrack); 405 406 /** 407 * Called by one of our associated MediaTrackLists (audio/video) when an 408 * AudioTrack is enabled or a VideoTrack is selected. 409 */ 410 void NotifyMediaTrackEnabled(dom::MediaTrack* aTrack); 411 412 /** 413 * Called by one of our associated MediaTrackLists (audio/video) when an 414 * AudioTrack is disabled or a VideoTrack is unselected. 415 */ 416 void NotifyMediaTrackDisabled(dom::MediaTrack* aTrack); 417 418 /** 419 * Returns the current load ID. Asynchronous events store the ID that was 420 * current when they were enqueued, and if it has changed when they come to 421 * fire, they consider themselves cancelled, and don't fire. 422 */ GetCurrentLoadID()423 uint32_t GetCurrentLoadID() { return mCurrentLoadID; } 424 425 /** 426 * Returns the load group for this media element's owner document. 427 * XXX XBL2 issue. 428 */ 429 already_AddRefed<nsILoadGroup> GetDocumentLoadGroup(); 430 431 /** 432 * Returns true if the media has played or completed a seek. 433 * Used by video frame to determine whether to paint the poster. 434 */ GetPlayedOrSeeked()435 bool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; } 436 437 nsresult CopyInnerTo(Element* aDest); 438 439 /** 440 * Sets the Accept header on the HTTP channel to the required 441 * video or audio MIME types. 442 */ 443 virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) = 0; 444 445 /** 446 * Sets the required request headers on the HTTP channel for 447 * video or audio requests. 448 */ 449 void SetRequestHeaders(nsIHttpChannel* aChannel); 450 451 /** 452 * Asynchronously awaits a stable state, whereupon aRunnable runs on the main 453 * thread. This adds an event which run aRunnable to the appshell's list of 454 * sections synchronous the next time control returns to the event loop. 455 */ 456 void RunInStableState(nsIRunnable* aRunnable); 457 458 /** 459 * Fires a timeupdate event. If aPeriodic is true, the event will only 460 * be fired if we've not fired a timeupdate event (for any reason) in the 461 * last 250ms, as required by the spec when the current time is periodically 462 * increasing during playback. 463 */ 464 void FireTimeUpdate(TimeupdateType aType); 465 MaybeQueueTimeupdateEvent()466 void MaybeQueueTimeupdateEvent() final { 467 FireTimeUpdate(TimeupdateType::ePeriodic); 468 } 469 470 const TimeStamp& LastTimeupdateDispatchTime() const; 471 void UpdateLastTimeupdateDispatchTime(); 472 473 // WebIDL 474 475 MediaError* GetError() const; 476 GetSrc(nsAString & aSrc)477 void GetSrc(nsAString& aSrc) { GetURIAttr(nsGkAtoms::src, nullptr, aSrc); } SetSrc(const nsAString & aSrc,ErrorResult & aError)478 void SetSrc(const nsAString& aSrc, ErrorResult& aError) { 479 SetHTMLAttr(nsGkAtoms::src, aSrc, aError); 480 } SetSrc(const nsAString & aSrc,nsIPrincipal * aTriggeringPrincipal,ErrorResult & aError)481 void SetSrc(const nsAString& aSrc, nsIPrincipal* aTriggeringPrincipal, 482 ErrorResult& aError) { 483 SetHTMLAttr(nsGkAtoms::src, aSrc, aTriggeringPrincipal, aError); 484 } 485 486 void GetCurrentSrc(nsAString& aCurrentSrc); 487 GetCrossOrigin(nsAString & aResult)488 void GetCrossOrigin(nsAString& aResult) { 489 // Null for both missing and invalid defaults is ok, since we 490 // always parse to an enum value, so we don't need an invalid 491 // default, and we _want_ the missing default to be null. 492 GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult); 493 } SetCrossOrigin(const nsAString & aCrossOrigin,ErrorResult & aError)494 void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError) { 495 SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError); 496 } 497 NetworkState()498 uint16_t NetworkState() const { return mNetworkState; } 499 500 void NotifyXPCOMShutdown() final; 501 502 // Called by media decoder when the audible state changed or when input is 503 // a media stream. 504 void SetAudibleState(bool aAudible) final; 505 506 // Notify agent when the MediaElement changes its audible state. 507 void NotifyAudioPlaybackChanged(AudibleChangedReasons aReason); 508 GetPreload(nsAString & aValue)509 void GetPreload(nsAString& aValue) { 510 if (mSrcAttrStream) { 511 nsGkAtoms::none->ToString(aValue); 512 return; 513 } 514 GetEnumAttr(nsGkAtoms::preload, nullptr, aValue); 515 } SetPreload(const nsAString & aValue,ErrorResult & aRv)516 void SetPreload(const nsAString& aValue, ErrorResult& aRv) { 517 if (mSrcAttrStream) { 518 return; 519 } 520 SetHTMLAttr(nsGkAtoms::preload, aValue, aRv); 521 } 522 523 already_AddRefed<TimeRanges> Buffered() const; 524 525 void Load(); 526 527 void CanPlayType(const nsAString& aType, nsAString& aResult); 528 ReadyState()529 uint16_t ReadyState() const { return mReadyState; } 530 531 bool Seeking() const; 532 533 double CurrentTime() const; 534 535 void SetCurrentTime(double aCurrentTime, ErrorResult& aRv); SetCurrentTime(double aCurrentTime)536 void SetCurrentTime(double aCurrentTime) { 537 SetCurrentTime(aCurrentTime, IgnoreErrors()); 538 } 539 540 void FastSeek(double aTime, ErrorResult& aRv); 541 542 already_AddRefed<Promise> SeekToNextFrame(ErrorResult& aRv); 543 544 double Duration() const; 545 HasAudio()546 bool HasAudio() const { return mMediaInfo.HasAudio(); } 547 IsVideo()548 virtual bool IsVideo() const { return false; } 549 HasVideo()550 bool HasVideo() const { return mMediaInfo.HasVideo(); } 551 IsEncrypted()552 bool IsEncrypted() const override { return mIsEncrypted; } 553 Paused()554 bool Paused() const { return mPaused; } 555 DefaultPlaybackRate()556 double DefaultPlaybackRate() const { 557 if (mSrcAttrStream) { 558 return 1.0; 559 } 560 return mDefaultPlaybackRate; 561 } 562 563 void SetDefaultPlaybackRate(double aDefaultPlaybackRate, ErrorResult& aRv); 564 PlaybackRate()565 double PlaybackRate() const { 566 if (mSrcAttrStream) { 567 return 1.0; 568 } 569 return mPlaybackRate; 570 } 571 572 void SetPlaybackRate(double aPlaybackRate, ErrorResult& aRv); 573 574 already_AddRefed<TimeRanges> Played(); 575 576 already_AddRefed<TimeRanges> Seekable() const; 577 578 bool Ended(); 579 Autoplay()580 bool Autoplay() const { return GetBoolAttr(nsGkAtoms::autoplay); } 581 SetAutoplay(bool aValue,ErrorResult & aRv)582 void SetAutoplay(bool aValue, ErrorResult& aRv) { 583 SetHTMLBoolAttr(nsGkAtoms::autoplay, aValue, aRv); 584 } 585 Loop()586 bool Loop() const { return GetBoolAttr(nsGkAtoms::loop); } 587 SetLoop(bool aValue,ErrorResult & aRv)588 void SetLoop(bool aValue, ErrorResult& aRv) { 589 SetHTMLBoolAttr(nsGkAtoms::loop, aValue, aRv); 590 } 591 592 already_AddRefed<Promise> Play(ErrorResult& aRv); Play()593 void Play() { 594 IgnoredErrorResult dummy; 595 RefPtr<Promise> toBeIgnored = Play(dummy); 596 } 597 598 void Pause(ErrorResult& aRv); Pause()599 void Pause() { Pause(IgnoreErrors()); } 600 Controls()601 bool Controls() const { return GetBoolAttr(nsGkAtoms::controls); } 602 SetControls(bool aValue,ErrorResult & aRv)603 void SetControls(bool aValue, ErrorResult& aRv) { 604 SetHTMLBoolAttr(nsGkAtoms::controls, aValue, aRv); 605 } 606 Volume()607 double Volume() const { return mVolume; } 608 609 void SetVolume(double aVolume, ErrorResult& aRv); 610 Muted()611 bool Muted() const { return mMuted & MUTED_BY_CONTENT; } 612 void SetMuted(bool aMuted); 613 DefaultMuted()614 bool DefaultMuted() const { return GetBoolAttr(nsGkAtoms::muted); } 615 SetDefaultMuted(bool aMuted,ErrorResult & aRv)616 void SetDefaultMuted(bool aMuted, ErrorResult& aRv) { 617 SetHTMLBoolAttr(nsGkAtoms::muted, aMuted, aRv); 618 } 619 MozAllowCasting()620 bool MozAllowCasting() const { return mAllowCasting; } 621 SetMozAllowCasting(bool aShow)622 void SetMozAllowCasting(bool aShow) { mAllowCasting = aShow; } 623 MozIsCasting()624 bool MozIsCasting() const { return mIsCasting; } 625 SetMozIsCasting(bool aShow)626 void SetMozIsCasting(bool aShow) { mIsCasting = aShow; } 627 628 // Returns whether a call to Play() would be rejected with NotAllowedError. 629 // This assumes "worst case" for unknowns. So if prompting for permission is 630 // enabled and no permission is stored, this behaves as if the user would 631 // opt to block. 632 bool AllowedToPlay() const; 633 634 already_AddRefed<MediaSource> GetMozMediaSourceObject() const; 635 636 // Returns a promise which will be resolved after collecting debugging 637 // data from decoder/reader/MDSM. Used for debugging purposes. 638 already_AddRefed<Promise> MozRequestDebugInfo(ErrorResult& aRv); 639 640 // Enables DecoderDoctorLogger logging. Used for debugging purposes. 641 static void MozEnableDebugLog(const GlobalObject&); 642 643 // Returns a promise which will be resolved after collecting debugging 644 // log associated with this element. Used for debugging purposes. 645 already_AddRefed<Promise> MozRequestDebugLog(ErrorResult& aRv); 646 647 // For use by mochitests. Enabling pref "media.test.video-suspend" 648 void SetVisible(bool aVisible); 649 650 // For use by mochitests. Enabling pref "media.test.video-suspend" 651 bool HasSuspendTaint() const; 652 653 // For use by mochitests. 654 bool IsVideoDecodingSuspended() const; 655 656 // These functions return accumulated time, which are used for the telemetry 657 // usage. Return -1 for error. 658 double TotalVideoPlayTime() const; 659 double VisiblePlayTime() const; 660 double InvisiblePlayTime() const; 661 double VideoDecodeSuspendedTime() const; 662 double TotalAudioPlayTime() const; 663 double AudiblePlayTime() const; 664 double InaudiblePlayTime() const; 665 double MutedPlayTime() const; 666 667 // Test methods for decoder doctor. 668 void SetFormatDiagnosticsReportForMimeType(const nsAString& aMimeType, 669 DecoderDoctorReportType aType); 670 void SetDecodeError(const nsAString& aError, ErrorResult& aRv); 671 void SetAudioSinkFailedStartup(); 672 673 // Synchronously, return the next video frame and mark the element unable to 674 // participate in decode suspending. 675 // 676 // This function is synchronous for cases where decoding has been suspended 677 // and JS needs a frame to use in, eg., nsLayoutUtils::SurfaceFromElement() 678 // via drawImage(). 679 already_AddRefed<layers::Image> GetCurrentImage(); 680 681 already_AddRefed<DOMMediaStream> GetSrcObject() const; 682 void SetSrcObject(DOMMediaStream& aValue); 683 void SetSrcObject(DOMMediaStream* aValue); 684 MozPreservesPitch()685 bool MozPreservesPitch() const { return mPreservesPitch; } 686 void SetMozPreservesPitch(bool aPreservesPitch); 687 688 MediaKeys* GetMediaKeys() const; 689 690 already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys, 691 ErrorResult& aRv); 692 693 mozilla::dom::EventHandlerNonNull* GetOnencrypted(); 694 void SetOnencrypted(mozilla::dom::EventHandlerNonNull* aCallback); 695 696 mozilla::dom::EventHandlerNonNull* GetOnwaitingforkey(); 697 void SetOnwaitingforkey(mozilla::dom::EventHandlerNonNull* aCallback); 698 699 void DispatchEncrypted(const nsTArray<uint8_t>& aInitData, 700 const nsAString& aInitDataType) override; 701 702 bool IsEventAttributeNameInternal(nsAtom* aName) override; 703 704 bool ContainsRestrictedContent(); 705 706 void NotifyWaitingForKey() override; 707 708 already_AddRefed<DOMMediaStream> CaptureAudio(ErrorResult& aRv, 709 MediaTrackGraph* aGraph); 710 711 already_AddRefed<DOMMediaStream> MozCaptureStream(ErrorResult& aRv); 712 713 already_AddRefed<DOMMediaStream> MozCaptureStreamUntilEnded(ErrorResult& aRv); 714 MozAudioCaptured()715 bool MozAudioCaptured() const { return mAudioCaptured; } 716 717 void MozGetMetadata(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, 718 ErrorResult& aRv); 719 720 double MozFragmentEnd(); 721 722 AudioTrackList* AudioTracks(); 723 724 VideoTrackList* VideoTracks(); 725 726 TextTrackList* GetTextTracks(); 727 728 already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind, 729 const nsAString& aLabel, 730 const nsAString& aLanguage); 731 AddTextTrack(TextTrack * aTextTrack)732 void AddTextTrack(TextTrack* aTextTrack) { 733 GetOrCreateTextTrackManager()->AddTextTrack(aTextTrack); 734 } 735 736 void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly = false) { 737 if (mTextTrackManager) { 738 mTextTrackManager->RemoveTextTrack(aTextTrack, aPendingListOnly); 739 } 740 } 741 NotifyCueAdded(TextTrackCue & aCue)742 void NotifyCueAdded(TextTrackCue& aCue) { 743 if (mTextTrackManager) { 744 mTextTrackManager->NotifyCueAdded(aCue); 745 } 746 } NotifyCueRemoved(TextTrackCue & aCue)747 void NotifyCueRemoved(TextTrackCue& aCue) { 748 if (mTextTrackManager) { 749 mTextTrackManager->NotifyCueRemoved(aCue); 750 } 751 } NotifyCueUpdated(TextTrackCue * aCue)752 void NotifyCueUpdated(TextTrackCue* aCue) { 753 if (mTextTrackManager) { 754 mTextTrackManager->NotifyCueUpdated(aCue); 755 } 756 } 757 758 void NotifyCueDisplayStatesChanged(); 759 IsBlessed()760 bool IsBlessed() const { return mIsBlessed; } 761 762 // A method to check whether we are currently playing. 763 bool IsCurrentlyPlaying() const; 764 765 // Returns true if the media element is being destroyed. Used in 766 // dormancy checks to prevent dormant processing for an element 767 // that will soon be gone. 768 bool IsBeingDestroyed(); 769 770 void OnVisibilityChange(Visibility aNewVisibility); 771 772 // Begin testing only methods 773 float ComputedVolume() const; 774 bool ComputedMuted() const; 775 776 // Return true if the media has been suspended media due to an inactive 777 // document or prohibiting by the docshell. 778 bool IsSuspendedByInactiveDocOrDocShell() const; 779 // End testing only methods 780 781 void SetMediaInfo(const MediaInfo& aInfo); 782 MediaInfo GetMediaInfo() const override; 783 784 // Gives access to the decoder's frame statistics, if present. 785 FrameStatistics* GetFrameStatistics() const override; 786 787 void DispatchAsyncTestingEvent(const nsAString& aName) override; 788 789 AbstractThread* AbstractMainThread() const final; 790 791 // Telemetry: to record the usage of a {visible / invisible} video element as 792 // the source of {drawImage(), createPattern(), createImageBitmap() and 793 // captureStream()} APIs. 794 enum class CallerAPI { 795 DRAW_IMAGE, 796 CREATE_PATTERN, 797 CREATE_IMAGEBITMAP, 798 CAPTURE_STREAM, 799 }; 800 void MarkAsContentSource(CallerAPI aAPI); 801 802 Document* GetDocument() const override; 803 804 already_AddRefed<GMPCrashHelper> CreateGMPCrashHelper() override; 805 MainThreadEventTarget()806 nsISerialEventTarget* MainThreadEventTarget() { 807 return mMainThreadEventTarget; 808 } 809 810 // Set the sink id (of the output device) that the audio will play. If aSinkId 811 // is empty the default device will be set. 812 already_AddRefed<Promise> SetSinkId(const nsAString& aSinkId, 813 ErrorResult& aRv); 814 // Get the sink id of the device that audio is being played. Initial value is 815 // empty and the default device is being used. GetSinkId(nsString & aSinkId)816 void GetSinkId(nsString& aSinkId) { 817 MOZ_ASSERT(NS_IsMainThread()); 818 aSinkId = mSink.first; 819 } 820 821 // This is used to notify MediaElementAudioSourceNode that media element is 822 // allowed to play when media element is used as a source for web audio, so 823 // that we can start AudioContext if it was not allowed to start. 824 RefPtr<GenericNonExclusivePromise> GetAllowedToPlayPromise(); 825 GetShowPosterFlag()826 bool GetShowPosterFlag() const { return mShowPoster; } 827 828 bool IsAudible() const; 829 830 // Return key system in use if we have one, otherwise return nothing. 831 Maybe<nsAutoString> GetKeySystem() const override; 832 833 protected: 834 virtual ~HTMLMediaElement(); 835 836 class AudioChannelAgentCallback; 837 class ChannelLoader; 838 class ErrorSink; 839 class MediaElementTrackSource; 840 class MediaLoadListener; 841 class MediaStreamRenderer; 842 class MediaStreamTrackListener; 843 class ShutdownObserver; 844 class TitleChangeObserver; 845 class MediaControlKeyListener; 846 847 MediaDecoderOwner::NextFrameStatus NextFrameStatus(); 848 849 void SetDecoder(MediaDecoder* aDecoder); 850 851 void PlayInternal(bool aHandlingUserInput); 852 853 // See spec, https://html.spec.whatwg.org/#internal-pause-steps 854 void PauseInternal(); 855 856 /** Use this method to change the mReadyState member, so required 857 * events can be fired. 858 */ 859 void ChangeReadyState(nsMediaReadyState aState); 860 861 /** 862 * Use this method to change the mNetworkState member, so required 863 * actions will be taken during the transition. 864 */ 865 void ChangeNetworkState(nsMediaNetworkState aState); 866 867 /** 868 * The MediaElement will be responsible for creating and releasing the audio 869 * wakelock depending on the playing and audible state. 870 */ 871 virtual void WakeLockRelease(); 872 virtual void UpdateWakeLock(); 873 874 void CreateAudioWakeLockIfNeeded(); 875 void ReleaseAudioWakeLockIfExists(); 876 RefPtr<WakeLock> mWakeLock; 877 878 /** 879 * Logs a warning message to the web console to report various failures. 880 * aMsg is the localized message identifier, aParams is the parameters to 881 * be substituted into the localized message, and aParamCount is the number 882 * of parameters in aParams. 883 */ 884 void ReportLoadError(const char* aMsg, const nsTArray<nsString>& aParams = 885 nsTArray<nsString>()); 886 887 /** 888 * Log message to web console. 889 */ 890 void ReportToConsole( 891 uint32_t aErrorFlags, const char* aMsg, 892 const nsTArray<nsString>& aParams = nsTArray<nsString>()) const; 893 894 /** 895 * Changes mHasPlayedOrSeeked to aValue. If mHasPlayedOrSeeked changes 896 * we'll force a reflow so that the video frame gets reflowed to reflect 897 * the poster hiding or showing immediately. 898 */ 899 void SetPlayedOrSeeked(bool aValue); 900 901 /** 902 * Initialize the media element for playback of aStream 903 */ 904 void SetupSrcMediaStreamPlayback(DOMMediaStream* aStream); 905 /** 906 * Stop playback on mSrcStream. 907 */ 908 void EndSrcMediaStreamPlayback(); 909 /** 910 * Ensure we're playing mSrcStream if and only if we're not paused. 911 */ 912 enum { REMOVING_SRC_STREAM = 0x1 }; 913 void UpdateSrcMediaStreamPlaying(uint32_t aFlags = 0); 914 915 /** 916 * Ensure currentTime progresses if and only if we're potentially playing 917 * mSrcStream. Called by the watch manager while we're playing mSrcStream, and 918 * one of the inputs to the potentially playing algorithm changes. 919 */ 920 void UpdateSrcStreamPotentiallyPlaying(); 921 922 /** 923 * mSrcStream's graph's CurrentTime() has been updated. It might be time to 924 * fire "timeupdate". 925 */ 926 void UpdateSrcStreamTime(); 927 928 /** 929 * Called after a tail dispatch when playback of mSrcStream ended, to comply 930 * with the spec where we must start reporting true for the ended attribute 931 * after the event loop returns to step 1. A MediaStream could otherwise be 932 * manipulated to end a HTMLMediaElement synchronously. 933 */ 934 void UpdateSrcStreamReportPlaybackEnded(); 935 936 /** 937 * Called by our DOMMediaStream::TrackListener when a new MediaStreamTrack has 938 * been added to the playback stream of |mSrcStream|. 939 */ 940 void NotifyMediaStreamTrackAdded(const RefPtr<MediaStreamTrack>& aTrack); 941 942 /** 943 * Called by our DOMMediaStream::TrackListener when a MediaStreamTrack in 944 * |mSrcStream|'s playback stream has ended. 945 */ 946 void NotifyMediaStreamTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack); 947 948 /** 949 * Convenience method to get in a single list all enabled AudioTracks and, if 950 * this is a video element, the selected VideoTrack. 951 */ 952 void GetAllEnabledMediaTracks(nsTArray<RefPtr<MediaTrack>>& aTracks); 953 954 /** 955 * Enables or disables all tracks forwarded from mSrcStream to all 956 * OutputMediaStreams. We do this for muting the tracks when pausing, 957 * and unmuting when playing the media element again. 958 */ 959 void SetCapturedOutputStreamsEnabled(bool aEnabled); 960 961 /** 962 * Returns true if output tracks should be muted, based on the state of this 963 * media element. 964 */ 965 enum class OutputMuteState { Muted, Unmuted }; 966 OutputMuteState OutputTracksMuted(); 967 968 /** 969 * Sets the muted state of all output track sources. They are muted when we're 970 * paused and unmuted otherwise. 971 */ 972 void UpdateOutputTracksMuting(); 973 974 /** 975 * Create a new MediaStreamTrack for the TrackSource corresponding to aTrack 976 * and add it to the DOMMediaStream in aOutputStream. This automatically sets 977 * the output track to enabled or disabled depending on our current playing 978 * state. 979 */ 980 enum class AddTrackMode { ASYNC, SYNC }; 981 void AddOutputTrackSourceToOutputStream( 982 MediaElementTrackSource* aSource, OutputMediaStream& aOutputStream, 983 AddTrackMode aMode = AddTrackMode::ASYNC); 984 985 /** 986 * Creates output track sources when this media element is captured, tracks 987 * exist, playback is not ended and readyState is >= HAVE_METADATA. 988 */ 989 void UpdateOutputTrackSources(); 990 991 /** 992 * Returns an DOMMediaStream containing the played contents of this 993 * element. When aBehavior is FINISH_WHEN_ENDED, when this element ends 994 * playback we will finish the stream and not play any more into it. When 995 * aType is CONTINUE_WHEN_ENDED, ending playback does not finish the stream. 996 * The stream will never finish. 997 * 998 * When aType is CAPTURE_AUDIO, we stop playout of audio and instead route it 999 * to the DOMMediaStream. Volume and mute state will be applied to the audio 1000 * reaching the stream. No video tracks will be captured in this case. 1001 */ 1002 already_AddRefed<DOMMediaStream> CaptureStreamInternal( 1003 StreamCaptureBehavior aFinishBehavior, 1004 StreamCaptureType aStreamCaptureType, MediaTrackGraph* aGraph); 1005 1006 /** 1007 * Initialize a decoder as a clone of an existing decoder in another 1008 * element. 1009 * mLoadingSrc must already be set. 1010 */ 1011 nsresult InitializeDecoderAsClone(ChannelMediaDecoder* aOriginal); 1012 1013 /** 1014 * Call Load() and FinishDecoderSetup() on the decoder. It also handle 1015 * resource cloning if DecoderType is ChannelMediaDecoder. 1016 */ 1017 template <typename DecoderType, typename... LoadArgs> 1018 nsresult SetupDecoder(DecoderType* aDecoder, LoadArgs&&... aArgs); 1019 1020 /** 1021 * Initialize a decoder to load the given channel. The decoder's stream 1022 * listener is returned via aListener. 1023 * mLoadingSrc must already be set. 1024 */ 1025 nsresult InitializeDecoderForChannel(nsIChannel* aChannel, 1026 nsIStreamListener** aListener); 1027 1028 /** 1029 * Finish setting up the decoder after Load() has been called on it. 1030 * Called by InitializeDecoderForChannel/InitializeDecoderAsClone. 1031 */ 1032 nsresult FinishDecoderSetup(MediaDecoder* aDecoder); 1033 1034 /** 1035 * Call this after setting up mLoadingSrc and mDecoder. 1036 */ 1037 void AddMediaElementToURITable(); 1038 /** 1039 * Call this before modifying mLoadingSrc. 1040 */ 1041 void RemoveMediaElementFromURITable(); 1042 /** 1043 * Call this to find a media element with the same NodePrincipal and 1044 * mLoadingSrc set to aURI, and with a decoder on which Load() has been 1045 * called. 1046 */ 1047 HTMLMediaElement* LookupMediaElementURITable(nsIURI* aURI); 1048 1049 /** 1050 * Shutdown and clear mDecoder and maintain associated invariants. 1051 */ 1052 void ShutdownDecoder(); 1053 /** 1054 * Execute the initial steps of the load algorithm that ensure existing 1055 * loads are aborted, the element is emptied, and a new load ID is 1056 * created. 1057 */ 1058 void AbortExistingLoads(); 1059 1060 /** 1061 * This is the dedicated media source failure steps. 1062 * Called when all potential resources are exhausted. Changes network 1063 * state to NETWORK_NO_SOURCE, and sends error event with code 1064 * MEDIA_ERR_SRC_NOT_SUPPORTED. 1065 */ 1066 void NoSupportedMediaSourceError( 1067 const nsACString& aErrorDetails = nsCString()); 1068 1069 /** 1070 * Per spec, Failed with elements: Queue a task, using the DOM manipulation 1071 * task source, to fire a simple event named error at the candidate element. 1072 * So dispatch |QueueLoadFromSourceTask| to main thread to make sure the task 1073 * will be executed later than loadstart event. 1074 */ 1075 void DealWithFailedElement(nsIContent* aSourceElement); 1076 1077 /** 1078 * Attempts to load resources from the <source> children. This is a 1079 * substep of the resource selection algorithm. Do not call this directly, 1080 * call QueueLoadFromSourceTask() instead. 1081 */ 1082 void LoadFromSourceChildren(); 1083 1084 /** 1085 * Asynchronously awaits a stable state, and then causes 1086 * LoadFromSourceChildren() to be called on the main threads' event loop. 1087 */ 1088 void QueueLoadFromSourceTask(); 1089 1090 /** 1091 * Runs the media resource selection algorithm. 1092 */ 1093 void SelectResource(); 1094 1095 /** 1096 * A wrapper function that allows us to cleanly reset flags after a call 1097 * to SelectResource() 1098 */ 1099 void SelectResourceWrapper(); 1100 1101 /** 1102 * Asynchronously awaits a stable state, and then causes SelectResource() 1103 * to be run on the main thread's event loop. 1104 */ 1105 void QueueSelectResourceTask(); 1106 1107 /** 1108 * When loading a new source on an existing media element, make sure to reset 1109 * everything that is accessible using the media element API. 1110 */ 1111 void ResetState(); 1112 1113 /** 1114 * The resource-fetch algorithm step of the load algorithm. 1115 */ 1116 MediaResult LoadResource(); 1117 1118 /** 1119 * Selects the next <source> child from which to load a resource. Called 1120 * during the resource selection algorithm. Stores the return value in 1121 * mSourceLoadCandidate before returning. 1122 */ 1123 Element* GetNextSource(); 1124 1125 /** 1126 * Changes mDelayingLoadEvent, and will call BlockOnLoad()/UnblockOnLoad() 1127 * on the owning document, so it can delay the load event firing. 1128 */ 1129 void ChangeDelayLoadStatus(bool aDelay); 1130 1131 /** 1132 * If we suspended downloading after the first frame, unsuspend now. 1133 */ 1134 void StopSuspendingAfterFirstFrame(); 1135 1136 /** 1137 * Called when our channel is redirected to another channel. 1138 * Updates our mChannel reference to aNewChannel. 1139 */ 1140 nsresult OnChannelRedirect(nsIChannel* aChannel, nsIChannel* aNewChannel, 1141 uint32_t aFlags); 1142 1143 /** 1144 * Call this to reevaluate whether we should be holding a self-reference. 1145 */ 1146 void AddRemoveSelfReference(); 1147 1148 /** 1149 * Called when "xpcom-shutdown" event is received. 1150 */ 1151 void NotifyShutdownEvent(); 1152 1153 /** 1154 * Possible values of the 'preload' attribute. 1155 */ 1156 enum PreloadAttrValue : uint8_t { 1157 PRELOAD_ATTR_EMPTY, // set to "" 1158 PRELOAD_ATTR_NONE, // set to "none" 1159 PRELOAD_ATTR_METADATA, // set to "metadata" 1160 PRELOAD_ATTR_AUTO // set to "auto" 1161 }; 1162 1163 /** 1164 * The preloading action to perform. These dictate how we react to the 1165 * preload attribute. See mPreloadAction. 1166 */ 1167 enum PreloadAction { 1168 PRELOAD_UNDEFINED = 0, // not determined - used only for initialization 1169 PRELOAD_NONE = 1, // do not preload 1170 PRELOAD_METADATA = 2, // preload only the metadata (and first frame) 1171 PRELOAD_ENOUGH = 3 // preload enough data to allow uninterrupted 1172 // playback 1173 }; 1174 1175 /** 1176 * The guts of Load(). Load() acts as a wrapper around this which sets 1177 * mIsDoingExplicitLoad to true so that when script calls 'load()' 1178 * preload-none will be automatically upgraded to preload-metadata. 1179 */ 1180 void DoLoad(); 1181 1182 /** 1183 * Suspends the load of mLoadingSrc, so that it can be resumed later 1184 * by ResumeLoad(). This is called when we have a media with a 'preload' 1185 * attribute value of 'none', during the resource selection algorithm. 1186 */ 1187 void SuspendLoad(); 1188 1189 /** 1190 * Resumes a previously suspended load (suspended by SuspendLoad(uri)). 1191 * Will continue running the resource selection algorithm. 1192 * Sets mPreloadAction to aAction. 1193 */ 1194 void ResumeLoad(PreloadAction aAction); 1195 1196 /** 1197 * Handle a change to the preload attribute. Should be called whenever the 1198 * value (or presence) of the preload attribute changes. The change in 1199 * attribute value may cause a change in the mPreloadAction of this 1200 * element. If there is a change then this method will initiate any 1201 * behaviour that is necessary to implement the action. 1202 */ 1203 void UpdatePreloadAction(); 1204 1205 /** 1206 * Fire progress events if needed according to the time and byte constraints 1207 * outlined in the specification. aHaveNewProgress is true if progress has 1208 * just been detected. Otherwise the method is called as a result of the 1209 * progress timer. 1210 */ 1211 void CheckProgress(bool aHaveNewProgress); 1212 static void ProgressTimerCallback(nsITimer* aTimer, void* aClosure); 1213 /** 1214 * Start timer to update download progress. 1215 */ 1216 void StartProgressTimer(); 1217 /** 1218 * Start sending progress and/or stalled events. 1219 */ 1220 void StartProgress(); 1221 /** 1222 * Stop progress information timer and events. 1223 */ 1224 void StopProgress(); 1225 1226 /** 1227 * Dispatches an error event to a child source element. 1228 */ 1229 void DispatchAsyncSourceError(nsIContent* aSourceElement); 1230 1231 /** 1232 * Resets the media element for an error condition as per aErrorCode. 1233 * aErrorCode must be one of WebIDL HTMLMediaElement error codes. 1234 */ 1235 void Error(uint16_t aErrorCode, 1236 const nsACString& aErrorDetails = nsCString()); 1237 1238 /** 1239 * Returns the URL spec of the currentSrc. 1240 **/ 1241 void GetCurrentSpec(nsCString& aString); 1242 1243 /** 1244 * Process any media fragment entries in the URI 1245 */ 1246 void ProcessMediaFragmentURI(); 1247 1248 /** 1249 * Mute or unmute the audio and change the value that the |muted| map. 1250 */ 1251 void SetMutedInternal(uint32_t aMuted); 1252 /** 1253 * Update the volume of the output audio stream to match the element's 1254 * current mMuted/mVolume/mAudioChannelFaded state. 1255 */ 1256 void SetVolumeInternal(); 1257 1258 /** 1259 * Suspend or resume element playback and resource download. When we suspend 1260 * playback, event delivery would also be suspended (and events queued) until 1261 * the element is resumed. 1262 */ 1263 void SuspendOrResumeElement(bool aSuspendElement); 1264 1265 // Get the HTMLMediaElement object if the decoder is being used from an 1266 // HTML media element, and null otherwise. GetMediaElement()1267 HTMLMediaElement* GetMediaElement() final { return this; } 1268 1269 // Return true if decoding should be paused GetPaused()1270 bool GetPaused() final { return Paused(); } 1271 1272 // Seeks to aTime seconds. aSeekType can be Exact to seek to exactly the 1273 // seek target, or PrevSyncPoint if a quicker but less precise seek is 1274 // desired, and we'll seek to the sync point (keyframe and/or start of the 1275 // next block of audio samples) preceeding seek target. 1276 void Seek(double aTime, SeekTarget::Type aSeekType, ErrorResult& aRv); 1277 1278 // Update the audio channel playing state 1279 void UpdateAudioChannelPlayingState(); 1280 1281 // Adds to the element's list of pending text tracks each text track 1282 // in the element's list of text tracks whose text track mode is not disabled 1283 // and whose text track readiness state is loading. 1284 void PopulatePendingTextTrackList(); 1285 1286 // Gets a reference to the MediaElement's TextTrackManager. If the 1287 // MediaElement doesn't yet have one then it will create it. 1288 TextTrackManager* GetOrCreateTextTrackManager(); 1289 1290 // Recomputes ready state and fires events as necessary based on current 1291 // state. 1292 void UpdateReadyStateInternal(); 1293 1294 // Create or destroy the captured stream. 1295 void AudioCaptureTrackChange(bool aCapture); 1296 1297 // If the network state is empty and then we would trigger DoLoad(). 1298 void MaybeDoLoad(); 1299 1300 // Anything we need to check after played success and not related with spec. 1301 void UpdateCustomPolicyAfterPlayed(); 1302 1303 // Returns a StreamCaptureType populated with the right bits, depending on the 1304 // tracks this HTMLMediaElement has. 1305 StreamCaptureType CaptureTypeForElement(); 1306 1307 // True if this element can be captured, false otherwise. 1308 bool CanBeCaptured(StreamCaptureType aCaptureType); 1309 1310 using nsGenericHTMLElement::DispatchEvent; 1311 // For nsAsyncEventRunner. 1312 nsresult DispatchEvent(const nsAString& aName); 1313 1314 already_AddRefed<nsMediaEventRunner> GetEventRunner( 1315 const nsAString& aName, EventFlag aFlag = EventFlag::eNone); 1316 1317 // This method moves the mPendingPlayPromises into a temperate object. So the 1318 // mPendingPlayPromises is cleared after this method call. 1319 nsTArray<RefPtr<PlayPromise>> TakePendingPlayPromises(); 1320 1321 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises() 1322 // and queues a task to resolve them. 1323 void AsyncResolvePendingPlayPromises(); 1324 1325 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises() 1326 // and queues a task to reject them. 1327 void AsyncRejectPendingPlayPromises(nsresult aError); 1328 1329 // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises() 1330 // and queues a task to resolve them also to dispatch a "playing" event. 1331 void NotifyAboutPlaying(); 1332 1333 already_AddRefed<Promise> CreateDOMPromise(ErrorResult& aRv) const; 1334 1335 // Pass information for deciding the video decode mode to decoder. 1336 void NotifyDecoderActivityChanges() const; 1337 1338 // Constructs an AudioTrack in mAudioTrackList if aInfo reports that audio is 1339 // available, and a VideoTrack in mVideoTrackList if aInfo reports that video 1340 // is available. 1341 void ConstructMediaTracks(const MediaInfo* aInfo); 1342 1343 // Removes all MediaTracks from mAudioTrackList and mVideoTrackList and fires 1344 // "removetrack" on the lists accordingly. 1345 // Note that by spec, this should not fire "removetrack". However, it appears 1346 // other user agents do, per 1347 // https://wpt.fyi/results/media-source/mediasource-avtracks.html. 1348 void RemoveMediaTracks(); 1349 1350 // Mark the decoder owned by the element as tainted so that the 1351 // suspend-video-decoder is disabled. 1352 void MarkAsTainted(); 1353 1354 virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, 1355 const nsAttrValue* aValue, 1356 const nsAttrValue* aOldValue, 1357 nsIPrincipal* aMaybeScriptedPrincipal, 1358 bool aNotify) override; 1359 virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsAtom* aName, 1360 const nsAttrValueOrString& aValue, 1361 bool aNotify) override; 1362 1363 bool DetachExistingMediaKeys(); 1364 bool TryRemoveMediaKeysAssociation(); 1365 void RemoveMediaKeys(); 1366 bool AttachNewMediaKeys(); 1367 bool TryMakeAssociationWithCDM(CDMProxy* aProxy); 1368 void MakeAssociationWithCDMResolved(); 1369 void SetCDMProxyFailure(const MediaResult& aResult); 1370 void ResetSetMediaKeysTempVariables(); 1371 1372 void PauseIfShouldNotBePlaying(); 1373 1374 WatchManager<HTMLMediaElement> mWatchManager; 1375 1376 // When the play is not allowed, dispatch related events which are used for 1377 // testing or changing control UI. 1378 void DispatchEventsWhenPlayWasNotAllowed(); 1379 1380 // When the doc is blocked permanantly, we would dispatch event to notify 1381 // front-end side to show blocking icon. 1382 void MaybeNotifyAutoplayBlocked(); 1383 1384 // Dispatch event for video control when video gets blocked in order to show 1385 // the click-to-play icon. 1386 void DispatchBlockEventForVideoControl(); 1387 1388 // When playing state change, we have to notify MediaControl in the chrome 1389 // process in order to keep its playing state correct. 1390 void NotifyMediaControlPlaybackStateChanged(); 1391 1392 // Clear the timer when we want to continue listening to the media control 1393 // key events. 1394 void ClearStopMediaControlTimerIfNeeded(); 1395 1396 // Sets a secondary renderer for mSrcStream, so this media element can be 1397 // rendered in Picture-in-Picture mode when playing a MediaStream. A null 1398 // aContainer will unset the secondary renderer. aFirstFrameOutput allows 1399 // for injecting a listener of the callers choice for rendering the first 1400 // frame. 1401 void SetSecondaryMediaStreamRenderer( 1402 VideoFrameContainer* aContainer, 1403 FirstFrameVideoOutput* aFirstFrameOutput = nullptr); 1404 1405 // This function is used to update the status of media control when the media 1406 // changes its status of being used in the Picture-in-Picture mode. 1407 void UpdateMediaControlAfterPictureInPictureModeChanged(); 1408 1409 // The current decoder. Load() has been called on this decoder. 1410 // At most one of mDecoder and mSrcStream can be non-null. 1411 RefPtr<MediaDecoder> mDecoder; 1412 1413 // The DocGroup-specific nsISerialEventTarget of this HTML element on the main 1414 // thread. 1415 nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget; 1416 1417 // The DocGroup-specific AbstractThread::MainThread() of this HTML element. 1418 RefPtr<AbstractThread> mAbstractMainThread; 1419 1420 // A reference to the VideoFrameContainer which contains the current frame 1421 // of video to display. 1422 RefPtr<VideoFrameContainer> mVideoFrameContainer; 1423 1424 // Holds a reference to the MediaStream that has been set in the src 1425 // attribute. 1426 RefPtr<DOMMediaStream> mSrcAttrStream; 1427 1428 // Holds the triggering principal for the src attribute. 1429 nsCOMPtr<nsIPrincipal> mSrcAttrTriggeringPrincipal; 1430 1431 // Holds a reference to the MediaStream that we're actually playing. 1432 // At most one of mDecoder and mSrcStream can be non-null. 1433 RefPtr<DOMMediaStream> mSrcStream; 1434 1435 // The MediaStreamRenderer handles rendering of our selected video track, and 1436 // enabled audio tracks, while mSrcStream is set. 1437 RefPtr<MediaStreamRenderer> mMediaStreamRenderer; 1438 1439 // The secondary MediaStreamRenderer handles rendering of our selected video 1440 // track to a secondary VideoFrameContainer, while mSrcStream is set. 1441 RefPtr<MediaStreamRenderer> mSecondaryMediaStreamRenderer; 1442 1443 // True once PlaybackEnded() is called and we're playing a MediaStream. 1444 // Reset to false if we start playing mSrcStream again. 1445 Watchable<bool> mSrcStreamPlaybackEnded = { 1446 false, "HTMLMediaElement::mSrcStreamPlaybackEnded"}; 1447 1448 // Mirrors mSrcStreamPlaybackEnded after a tail dispatch when set to true, 1449 // but may be be forced to false directly. To accomodate when an application 1450 // ends playback synchronously by manipulating mSrcStream or its tracks, 1451 // e.g., through MediaStream.removeTrack(), or MediaStreamTrack.stop(). 1452 bool mSrcStreamReportPlaybackEnded = false; 1453 1454 // Holds a reference to the stream connecting this stream to the window 1455 // capture sink. 1456 UniquePtr<MediaStreamWindowCapturer> mStreamWindowCapturer; 1457 1458 // Holds references to the DOM wrappers for the MediaStreams that we're 1459 // writing to. 1460 nsTArray<OutputMediaStream> mOutputStreams; 1461 1462 // Mapping for output tracks, from dom::MediaTrack ids to the 1463 // MediaElementTrackSource that represents the source of all corresponding 1464 // MediaStreamTracks captured from this element. 1465 nsRefPtrHashtable<nsStringHashKey, MediaElementTrackSource> 1466 mOutputTrackSources; 1467 1468 // The currently selected video stream track. 1469 RefPtr<VideoStreamTrack> mSelectedVideoStreamTrack; 1470 1471 const RefPtr<ShutdownObserver> mShutdownObserver; 1472 1473 const RefPtr<TitleChangeObserver> mTitleChangeObserver; 1474 1475 // Holds a reference to the MediaSource, if any, referenced by the src 1476 // attribute on the media element. 1477 RefPtr<MediaSource> mSrcMediaSource; 1478 1479 // Holds a reference to the MediaSource supplying data for playback. This 1480 // may either match mSrcMediaSource or come from Source element children. 1481 // This is set when and only when mLoadingSrc corresponds to an object url 1482 // that resolved to a MediaSource. 1483 RefPtr<MediaSource> mMediaSource; 1484 1485 RefPtr<ChannelLoader> mChannelLoader; 1486 1487 // Points to the child source elements, used to iterate through the children 1488 // when selecting a resource to load. This is the previous sibling of the 1489 // child considered the current 'candidate' in: 1490 // https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm 1491 // 1492 // mSourcePointer == nullptr, we will next try to load |GetFirstChild()|. 1493 // mSourcePointer == GetLastChild(), we've exhausted all sources, waiting 1494 // for new elements to be appended. 1495 nsCOMPtr<nsIContent> mSourcePointer; 1496 1497 // Points to the document whose load we're blocking. This is the document 1498 // we're bound to when loading starts. 1499 nsCOMPtr<Document> mLoadBlockedDoc; 1500 1501 // This is used to help us block/resume the event delivery. 1502 class EventBlocker; 1503 RefPtr<EventBlocker> mEventBlocker; 1504 1505 // Media loading flags. See: 1506 // http://www.whatwg.org/specs/web-apps/current-work/#video) 1507 nsMediaNetworkState mNetworkState = HTMLMediaElement_Binding::NETWORK_EMPTY; 1508 Watchable<nsMediaReadyState> mReadyState = { 1509 HTMLMediaElement_Binding::HAVE_NOTHING, "HTMLMediaElement::mReadyState"}; 1510 1511 enum LoadAlgorithmState { 1512 // No load algorithm instance is waiting for a source to be added to the 1513 // media in order to continue loading. 1514 NOT_WAITING, 1515 // We've run the load algorithm, and we tried all source children of the 1516 // media element, and failed to load any successfully. We're waiting for 1517 // another source element to be added to the media element, and will try 1518 // to load any such element when its added. 1519 WAITING_FOR_SOURCE 1520 }; 1521 1522 // The current media load ID. This is incremented every time we start a 1523 // new load. Async events note the ID when they're first sent, and only fire 1524 // if the ID is unchanged when they come to fire. 1525 uint32_t mCurrentLoadID = 0; 1526 1527 // Denotes the waiting state of a load algorithm instance. When the load 1528 // algorithm is waiting for a source element child to be added, this is set 1529 // to WAITING_FOR_SOURCE, otherwise it's NOT_WAITING. 1530 LoadAlgorithmState mLoadWaitStatus = NOT_WAITING; 1531 1532 // Current audio volume 1533 double mVolume = 1.0; 1534 1535 // True if the audio track is not silent. 1536 bool mIsAudioTrackAudible = false; 1537 1538 enum MutedReasons { 1539 MUTED_BY_CONTENT = 0x01, 1540 MUTED_BY_INVALID_PLAYBACK_RATE = 0x02, 1541 MUTED_BY_AUDIO_CHANNEL = 0x04, 1542 MUTED_BY_AUDIO_TRACK = 0x08 1543 }; 1544 1545 uint32_t mMuted = 0; 1546 1547 UniquePtr<const MetadataTags> mTags; 1548 1549 // URI of the resource we're attempting to load. This stores the value we 1550 // return in the currentSrc attribute. Use GetCurrentSrc() to access the 1551 // currentSrc attribute. 1552 // This is always the original URL we're trying to load --- before 1553 // redirects etc. 1554 nsCOMPtr<nsIURI> mLoadingSrc; 1555 1556 // The triggering principal for the current source. 1557 nsCOMPtr<nsIPrincipal> mLoadingSrcTriggeringPrincipal; 1558 1559 // Stores the current preload action for this element. Initially set to 1560 // PRELOAD_UNDEFINED, its value is changed by calling 1561 // UpdatePreloadAction(). 1562 PreloadAction mPreloadAction = PRELOAD_UNDEFINED; 1563 1564 // Time that the last timeupdate event was queued. Read/Write from the 1565 // main thread only. 1566 TimeStamp mQueueTimeUpdateRunnerTime; 1567 1568 // Time that the last timeupdate event was fired. Read/Write from the 1569 // main thread only. 1570 TimeStamp mLastTimeUpdateDispatchTime; 1571 1572 // Time that the last progress event was fired. Read/Write from the 1573 // main thread only. 1574 TimeStamp mProgressTime; 1575 1576 // Time that data was last read from the media resource. Used for 1577 // computing if the download has stalled and to rate limit progress events 1578 // when data is arriving slower than PROGRESS_MS. 1579 // Read/Write from the main thread only. 1580 TimeStamp mDataTime; 1581 1582 // Media 'currentTime' value when the last timeupdate event was queued. 1583 // Read/Write from the main thread only. 1584 double mLastCurrentTime = 0.0; 1585 1586 // Logical start time of the media resource in seconds as obtained 1587 // from any media fragments. A negative value indicates that no 1588 // fragment time has been set. Read/Write from the main thread only. 1589 double mFragmentStart = -1.0; 1590 1591 // Logical end time of the media resource in seconds as obtained 1592 // from any media fragments. A negative value indicates that no 1593 // fragment time has been set. Read/Write from the main thread only. 1594 double mFragmentEnd = -1.0; 1595 1596 // The defaultPlaybackRate attribute gives the desired speed at which the 1597 // media resource is to play, as a multiple of its intrinsic speed. 1598 double mDefaultPlaybackRate = 1.0; 1599 1600 // The playbackRate attribute gives the speed at which the media resource 1601 // plays, as a multiple of its intrinsic speed. If it is not equal to the 1602 // defaultPlaybackRate, then the implication is that the user is using a 1603 // feature such as fast forward or slow motion playback. 1604 double mPlaybackRate = 1.0; 1605 1606 // True if pitch correction is applied when playbackRate is set to a 1607 // non-intrinsic value. 1608 bool mPreservesPitch = true; 1609 1610 // Reference to the source element last returned by GetNextSource(). 1611 // This is the child source element which we're trying to load from. 1612 nsCOMPtr<nsIContent> mSourceLoadCandidate; 1613 1614 // Range of time played. 1615 RefPtr<TimeRanges> mPlayed; 1616 1617 // Timer used for updating progress events. 1618 nsCOMPtr<nsITimer> mProgressTimer; 1619 1620 // Encrypted Media Extension media keys. 1621 RefPtr<MediaKeys> mMediaKeys; 1622 RefPtr<MediaKeys> mIncomingMediaKeys; 1623 // The dom promise is used for HTMLMediaElement::SetMediaKeys. 1624 RefPtr<DetailedPromise> mSetMediaKeysDOMPromise; 1625 // Used to indicate if the MediaKeys attaching operation is on-going or not. 1626 bool mAttachingMediaKey = false; 1627 MozPromiseRequestHolder<SetCDMPromise> mSetCDMRequest; 1628 1629 // Stores the time at the start of the current 'played' range. 1630 double mCurrentPlayRangeStart = 1.0; 1631 1632 // True if loadeddata has been fired. 1633 bool mLoadedDataFired = false; 1634 1635 // Indicates whether current playback is a result of user action 1636 // (ie. calling of the Play method), or automatic playback due to 1637 // the 'autoplay' attribute being set. A true value indicates the 1638 // latter case. 1639 // The 'autoplay' HTML attribute indicates that the video should 1640 // start playing when loaded. The 'autoplay' attribute of the object 1641 // is a mirror of the HTML attribute. These are different from this 1642 // 'mAutoplaying' flag, which indicates whether the current playback 1643 // is a result of the autoplay attribute. 1644 bool mAutoplaying = true; 1645 1646 // Playback of the video is paused either due to calling the 1647 // 'Pause' method, or playback not yet having started. 1648 Watchable<bool> mPaused = {true, "HTMLMediaElement::mPaused"}; 1649 1650 // The following two fields are here for the private storage of the builtin 1651 // video controls, and control 'casting' of the video to external devices 1652 // (TVs, projectors etc.) 1653 // True if casting is currently allowed 1654 bool mAllowCasting = false; 1655 // True if currently casting this video 1656 bool mIsCasting = false; 1657 1658 // Set while there are some OutputMediaStreams this media element's enabled 1659 // and selected tracks are captured into. When set, all tracks are captured 1660 // into the graph of this dummy track. 1661 // NB: This is a SharedDummyTrack to allow non-default graphs (AudioContexts 1662 // with an explicit sampleRate defined) to capture this element. When 1663 // cross-graph tracks are supported, this can become a bool. 1664 Watchable<RefPtr<SharedDummyTrack>> mTracksCaptured; 1665 1666 // True if the sound is being captured. 1667 bool mAudioCaptured = false; 1668 1669 // If TRUE then the media element was actively playing before the currently 1670 // in progress seeking. If FALSE then the media element is either not seeking 1671 // or was not actively playing before the current seek. Used to decide whether 1672 // to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification. 1673 bool mPlayingBeforeSeek = false; 1674 1675 // True if this element is suspended because the document is inactive or the 1676 // inactive docshell is not allowing media to play. 1677 bool mSuspendedByInactiveDocOrDocshell = false; 1678 1679 // True if we're running the "load()" method. 1680 bool mIsRunningLoadMethod = false; 1681 1682 // True if we're running or waiting to run queued tasks due to an explicit 1683 // call to "load()". 1684 bool mIsDoingExplicitLoad = false; 1685 1686 // True if we're loading the resource from the child source elements. 1687 bool mIsLoadingFromSourceChildren = false; 1688 1689 // True if we're delaying the "load" event. They are delayed until either 1690 // an error occurs, or the first frame is loaded. 1691 bool mDelayingLoadEvent = false; 1692 1693 // True when we've got a task queued to call SelectResource(), 1694 // or while we're running SelectResource(). 1695 bool mIsRunningSelectResource = false; 1696 1697 // True when we already have select resource call queued 1698 bool mHaveQueuedSelectResource = false; 1699 1700 // True if we suspended the decoder because we were paused, 1701 // preloading metadata is enabled, autoplay was not enabled, and we loaded 1702 // the first frame. 1703 bool mSuspendedAfterFirstFrame = false; 1704 1705 // True if we are allowed to suspend the decoder because we were paused, 1706 // preloading metdata was enabled, autoplay was not enabled, and we loaded 1707 // the first frame. 1708 bool mAllowSuspendAfterFirstFrame = true; 1709 1710 // True if we've played or completed a seek. We use this to determine 1711 // when the poster frame should be shown. 1712 bool mHasPlayedOrSeeked = false; 1713 1714 // True if we've added a reference to ourselves to keep the element 1715 // alive while no-one is referencing it but the element may still fire 1716 // events of its own accord. 1717 bool mHasSelfReference = false; 1718 1719 // True if we've received a notification that the engine is shutting 1720 // down. 1721 bool mShuttingDown = false; 1722 1723 // True if we've suspended a load in the resource selection algorithm 1724 // due to loading a preload:none media. When true, the resource we'll 1725 // load when the user initiates either playback or an explicit load is 1726 // stored in mPreloadURI. 1727 bool mSuspendedForPreloadNone = false; 1728 1729 // True if we've connected mSrcStream to the media element output. 1730 bool mSrcStreamIsPlaying = false; 1731 1732 // True if we should set nsIClassOfService::UrgentStart to the channel to 1733 // get the response ASAP for better user responsiveness. 1734 bool mUseUrgentStartForChannel = false; 1735 1736 // The CORS mode when loading the media element 1737 CORSMode mCORSMode = CORS_NONE; 1738 1739 // Info about the played media. 1740 MediaInfo mMediaInfo; 1741 1742 // True if the media has encryption information. 1743 bool mIsEncrypted = false; 1744 1745 enum WaitingForKeyState { 1746 NOT_WAITING_FOR_KEY = 0, 1747 WAITING_FOR_KEY = 1, 1748 WAITING_FOR_KEY_DISPATCHED = 2 1749 }; 1750 1751 // True when the CDM cannot decrypt the current block due to lacking a key. 1752 // Note: the "waitingforkey" event is not dispatched until all decoded data 1753 // has been rendered. 1754 WaitingForKeyState mWaitingForKey = NOT_WAITING_FOR_KEY; 1755 1756 // Listens for waitingForKey events from the owned decoder. 1757 MediaEventListener mWaitingForKeyListener; 1758 1759 // Init Data that needs to be sent in 'encrypted' events in MetadataLoaded(). 1760 EncryptionInfo mPendingEncryptedInitData; 1761 1762 // True if the media's channel's download has been suspended. 1763 Watchable<bool> mDownloadSuspendedByCache = { 1764 false, "HTMLMediaElement::mDownloadSuspendedByCache"}; 1765 1766 // Disable the video playback by track selection. This flag might not be 1767 // enough if we ever expand the ability of supporting multi-tracks video 1768 // playback. 1769 bool mDisableVideo = false; 1770 1771 RefPtr<TextTrackManager> mTextTrackManager; 1772 1773 RefPtr<AudioTrackList> mAudioTrackList; 1774 1775 RefPtr<VideoTrackList> mVideoTrackList; 1776 1777 UniquePtr<MediaStreamTrackListener> mMediaStreamTrackListener; 1778 1779 // The principal guarding mVideoFrameContainer access when playing a 1780 // MediaStream. 1781 nsCOMPtr<nsIPrincipal> mSrcStreamVideoPrincipal; 1782 1783 // True if the autoplay media was blocked because it hadn't loaded metadata 1784 // yet. 1785 bool mBlockedAsWithoutMetadata = false; 1786 1787 // This promise is used to notify MediaElementAudioSourceNode that media 1788 // element is allowed to play when MediaElement is used as a source for web 1789 // audio. 1790 MozPromiseHolder<GenericNonExclusivePromise> mAllowedToPlayPromise; 1791 1792 // True if media has ever been blocked for autoplay, it's used to notify front 1793 // end to show the correct blocking icon when the document goes back from 1794 // bfcache. 1795 bool mHasEverBeenBlockedForAutoplay = false; 1796 1797 // True if we have dispatched a task for text track changed, will be unset 1798 // when we starts processing text track changed. 1799 // https://html.spec.whatwg.org/multipage/media.html#pending-text-track-change-notification-flag 1800 bool mPendingTextTrackChanged = false; 1801 1802 public: 1803 // This function will be called whenever a text track that is in a media 1804 // element's list of text tracks has its text track mode change value 1805 void NotifyTextTrackModeChanged(); 1806 1807 private: 1808 friend class nsMediaEventRunner; 1809 friend class nsResolveOrRejectPendingPlayPromisesRunner; 1810 1811 already_AddRefed<PlayPromise> CreatePlayPromise(ErrorResult& aRv) const; 1812 MaybeBeginCloningVisually()1813 virtual void MaybeBeginCloningVisually(){}; 1814 1815 uint32_t GetPreloadDefault() const; 1816 uint32_t GetPreloadDefaultAuto() const; 1817 1818 /** 1819 * This function is called by AfterSetAttr and OnAttrSetButNotChanged. 1820 * It will not be called if the value is being unset. 1821 * 1822 * @param aNamespaceID the namespace of the attr being set 1823 * @param aName the localname of the attribute being set 1824 * @param aNotify Whether we plan to notify document observers. 1825 */ 1826 void AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName, bool aNotify); 1827 1828 // True if Init() has been called after construction 1829 bool mInitialized = false; 1830 1831 // True if user has called load(), seek() or element has started playing 1832 // before. It's *only* use for `click-to-play` blocking autoplay policy. 1833 // In addition, we would reset this once media aborts current load. 1834 bool mIsBlessed = false; 1835 1836 // True if the first frame has been successfully loaded. 1837 Watchable<bool> mFirstFrameLoaded = {false, 1838 "HTMLMediaElement::mFirstFrameLoaded"}; 1839 1840 // Media elements also have a default playback start position, which must 1841 // initially be set to zero seconds. This time is used to allow the element to 1842 // be seeked even before the media is loaded. 1843 double mDefaultPlaybackStartPosition = 0.0; 1844 1845 // True if media element has been marked as 'tainted' and can't 1846 // participate in video decoder suspending. 1847 bool mHasSuspendTaint = false; 1848 1849 // True if media element has been forced into being considered 'hidden'. 1850 // For use by mochitests. Enabling pref "media.test.video-suspend" 1851 bool mForcedHidden = false; 1852 1853 Visibility mVisibilityState = Visibility::Untracked; 1854 1855 UniquePtr<ErrorSink> mErrorSink; 1856 1857 // This wrapper will handle all audio channel related stuffs, eg. the 1858 // operations of tab audio indicator, Fennec's media control. Note: 1859 // mAudioChannelWrapper might be null after GC happened. 1860 RefPtr<AudioChannelAgentCallback> mAudioChannelWrapper; 1861 1862 // A list of pending play promises. The elements are pushed during the play() 1863 // method call and are resolved/rejected during further playback steps. 1864 nsTArray<RefPtr<PlayPromise>> mPendingPlayPromises; 1865 1866 // A list of already-dispatched but not yet run 1867 // nsResolveOrRejectPendingPlayPromisesRunners. 1868 // Runners whose Run() method is called remove themselves from this list. 1869 // We keep track of these because the load algorithm resolves/rejects all 1870 // already-dispatched pending play promises. 1871 nsTArray<nsResolveOrRejectPendingPlayPromisesRunner*> 1872 mPendingPlayPromisesRunners; 1873 1874 // A pending seek promise which is created at Seek() method call and is 1875 // resolved/rejected at AsyncResolveSeekDOMPromiseIfExists()/ 1876 // AsyncRejectSeekDOMPromiseIfExists() methods. 1877 RefPtr<dom::Promise> mSeekDOMPromise; 1878 1879 // Return true if the docshell is inactive and explicitly wants to stop media 1880 // playing in that shell. 1881 bool ShouldBeSuspendedByInactiveDocShell() const; 1882 1883 // For debugging bug 1407148. 1884 void AssertReadyStateIsNothing(); 1885 1886 // Contains the unique id of the sink device and the device info. 1887 // The initial value is ("", nullptr) and the default output device is used. 1888 // It can contain an invalid id and info if the device has been 1889 // unplugged. It can be set to ("", nullptr). It follows the spec attribute: 1890 // https://w3c.github.io/mediacapture-output/#htmlmediaelement-extensions 1891 // Read/Write from the main thread only. 1892 std::pair<nsString, RefPtr<AudioDeviceInfo>> mSink; 1893 1894 // This flag is used to control when the user agent is to show a poster frame 1895 // for a video element instead of showing the video contents. 1896 // https://html.spec.whatwg.org/multipage/media.html#show-poster-flag 1897 bool mShowPoster; 1898 1899 // We may delay starting playback of a media for an unvisited tab until it's 1900 // going to foreground. We would create ResumeDelayedMediaPlaybackAgent to 1901 // handle related operations at the time whenever delaying media playback is 1902 // needed. 1903 void CreateResumeDelayedMediaPlaybackAgentIfNeeded(); 1904 void ClearResumeDelayedMediaPlaybackAgentIfNeeded(); 1905 RefPtr<ResumeDelayedPlaybackAgent> mResumeDelayedPlaybackAgent; 1906 MozPromiseRequestHolder<ResumeDelayedPlaybackAgent::ResumePromise> 1907 mResumePlaybackRequest; 1908 1909 // Return true if we have already a decoder or a src stream and don't have any 1910 // error. 1911 bool IsPlayable() const; 1912 1913 // Return true if the media qualifies for being controlled by media control 1914 // keys. 1915 bool ShouldStartMediaControlKeyListener() const; 1916 1917 // Start the listener if media fits the requirement of being able to be 1918 // controlled be media control keys. 1919 void StartMediaControlKeyListenerIfNeeded(); 1920 1921 // It's used to listen media control key, by which we would play or pause 1922 // media element. 1923 RefPtr<MediaControlKeyListener> mMediaControlKeyListener; 1924 1925 // Method to update audio stream name 1926 void UpdateStreamName(); 1927 1928 // Return true if the media element is being used in picture in picture mode. 1929 bool IsBeingUsedInPictureInPictureMode() const; 1930 1931 // Return true if we should queue a 'timeupdate' event runner to main thread. 1932 bool ShouldQueueTimeupdateAsyncTask(TimeupdateType aType) const; 1933 }; 1934 1935 // Check if the context is chrome or has the debugger or tabs permission 1936 bool HasDebuggerOrTabsPrivilege(JSContext* aCx, JSObject* aObj); 1937 1938 } // namespace dom 1939 } // namespace mozilla 1940 1941 #endif // mozilla_dom_HTMLMediaElement_h 1942