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