no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / dom / media / MediaDecoder.h
blobf2f10a67c6326e12b525e80c6163032037abe408
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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/. */
7 #if !defined(MediaDecoder_h_)
8 # define MediaDecoder_h_
10 # include "BackgroundVideoDecodingPermissionObserver.h"
11 # include "DecoderDoctorDiagnostics.h"
12 # include "MediaContainerType.h"
13 # include "MediaDecoderOwner.h"
14 # include "MediaEventSource.h"
15 # include "MediaMetadataManager.h"
16 # include "MediaPromiseDefs.h"
17 # include "MediaResource.h"
18 # include "MediaStatistics.h"
19 # include "SeekTarget.h"
20 # include "TelemetryProbesReporter.h"
21 # include "TimeUnits.h"
22 # include "mozilla/Atomics.h"
23 # include "mozilla/CDMProxy.h"
24 # include "mozilla/MozPromise.h"
25 # include "mozilla/ReentrantMonitor.h"
26 # include "mozilla/StateMirroring.h"
27 # include "mozilla/StateWatching.h"
28 # include "mozilla/dom/MediaDebugInfoBinding.h"
29 # include "nsCOMPtr.h"
30 # include "nsIObserver.h"
31 # include "nsISupports.h"
32 # include "nsITimer.h"
34 class AudioDeviceInfo;
35 class nsIPrincipal;
37 namespace mozilla {
39 class AbstractThread;
40 class DOMMediaStream;
41 class DecoderBenchmark;
42 class ProcessedMediaTrack;
43 class FrameStatistics;
44 class VideoFrameContainer;
45 class MediaFormatReader;
46 class MediaDecoderStateMachineBase;
47 struct MediaPlaybackEvent;
48 struct SharedDummyTrack;
50 template <typename T>
51 struct DurationToType {
52 double operator()(double aDouble);
53 double operator()(const media::TimeUnit& aTimeUnit);
56 template <>
57 struct DurationToType<double> {
58 double operator()(double aDouble) { return aDouble; }
59 double operator()(const media::TimeUnit& aTimeUnit) {
60 if (aTimeUnit.IsValid()) {
61 if (aTimeUnit.IsPosInf()) {
62 return std::numeric_limits<double>::infinity();
64 if (aTimeUnit.IsNegInf()) {
65 return -std::numeric_limits<double>::infinity();
67 return aTimeUnit.ToSeconds();
69 return std::numeric_limits<double>::quiet_NaN();
73 using DurationToDouble = DurationToType<double>;
75 template <>
76 struct DurationToType<media::TimeUnit> {
77 media::TimeUnit operator()(double aDouble) {
78 return media::TimeUnit::FromSeconds(aDouble);
80 media::TimeUnit operator()(const media::TimeUnit& aTimeUnit) {
81 return aTimeUnit;
85 using DurationToTimeUnit = DurationToType<media::TimeUnit>;
87 struct MOZ_STACK_CLASS MediaDecoderInit {
88 MediaDecoderOwner* const mOwner;
89 TelemetryProbesReporterOwner* const mReporterOwner;
90 const double mVolume;
91 const bool mPreservesPitch;
92 const double mPlaybackRate;
93 const bool mMinimizePreroll;
94 const bool mHasSuspendTaint;
95 const bool mLooping;
96 const MediaContainerType mContainerType;
97 const nsAutoString mStreamName;
99 MediaDecoderInit(MediaDecoderOwner* aOwner,
100 TelemetryProbesReporterOwner* aReporterOwner, double aVolume,
101 bool aPreservesPitch, double aPlaybackRate,
102 bool aMinimizePreroll, bool aHasSuspendTaint, bool aLooping,
103 const MediaContainerType& aContainerType)
104 : mOwner(aOwner),
105 mReporterOwner(aReporterOwner),
106 mVolume(aVolume),
107 mPreservesPitch(aPreservesPitch),
108 mPlaybackRate(aPlaybackRate),
109 mMinimizePreroll(aMinimizePreroll),
110 mHasSuspendTaint(aHasSuspendTaint),
111 mLooping(aLooping),
112 mContainerType(aContainerType) {}
115 DDLoggedTypeDeclName(MediaDecoder);
117 class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
118 public:
119 typedef MozPromise<bool /* aIgnored */, bool /* aIgnored */,
120 /* IsExclusive = */ true>
121 SeekPromise;
123 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoder)
125 // Enumeration for the valid play states (see mPlayState)
126 enum PlayState {
127 PLAY_STATE_LOADING,
128 PLAY_STATE_PAUSED,
129 PLAY_STATE_PLAYING,
130 PLAY_STATE_ENDED,
131 PLAY_STATE_SHUTDOWN
134 // Must be called exactly once, on the main thread, during startup.
135 static void InitStatics();
137 explicit MediaDecoder(MediaDecoderInit& aInit);
139 // Returns the container content type of the resource.
140 // Safe to call from any thread.
141 const MediaContainerType& ContainerType() const { return mContainerType; }
143 // Cleanup internal data structures. Must be called on the main
144 // thread by the owning object before that object disposes of this object.
145 virtual void Shutdown();
147 // Notified by the shutdown manager that XPCOM shutdown has begun.
148 // The decoder should notify its owner to drop the reference to the decoder
149 // to prevent further calls into the decoder.
150 void NotifyXPCOMShutdown();
152 // Called if the media file encounters a network error.
153 void NetworkError(const MediaResult& aError);
155 // Return the principal of the current URI being played or downloaded.
156 virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() = 0;
158 // Return true if the loading of this resource required cross-origin
159 // redirects.
160 virtual bool HadCrossOriginRedirects() = 0;
162 // Return the time position in the video stream being
163 // played measured in seconds.
164 virtual double GetCurrentTime();
166 // Seek to the time position in (seconds) from the start of the video.
167 // If aDoFastSeek is true, we'll seek to the sync point/keyframe preceeding
168 // the seek target.
169 void Seek(double aTime, SeekTarget::Type aSeekType);
171 // Start playback of a video. 'Load' must have previously been
172 // called.
173 virtual void Play();
175 // Notify activity of the decoder owner is changed.
176 virtual void NotifyOwnerActivityChanged(bool aIsOwnerInvisible,
177 bool aIsOwnerConnected);
179 // Pause video playback.
180 virtual void Pause();
181 // Adjust the speed of the playback, optionally with pitch correction,
182 void SetVolume(double aVolume);
184 void SetPlaybackRate(double aPlaybackRate);
185 void SetPreservesPitch(bool aPreservesPitch);
186 void SetLooping(bool aLooping);
187 void SetStreamName(const nsAutoString& aStreamName);
189 // Set the given device as the output device.
190 RefPtr<GenericPromise> SetSink(AudioDeviceInfo* aSinkDevice);
192 bool GetMinimizePreroll() const { return mMinimizePreroll; }
194 // When we enable delay seek mode, media decoder won't actually ask MDSM to do
195 // seeking. During this period, we would store the latest seeking target and
196 // perform the seek to that target when we leave the mode. If we have any
197 // delayed seeks stored `IsSeeking()` will return true. E.g. During delay
198 // seeking mode, if we get seek target to 5s, 10s, 7s. When we stop delaying
199 // seeking, we would only seek to 7s.
200 void SetDelaySeekMode(bool aShouldDelaySeek);
202 // All MediaStream-related data is protected by mReentrantMonitor.
203 // We have at most one DecodedStreamData per MediaDecoder. Its stream
204 // is used as the input for each ProcessedMediaTrack created by calls to
205 // captureStream(UntilEnded). Seeking creates a new source stream, as does
206 // replaying after the input as ended. In the latter case, the new source is
207 // not connected to streams created by captureStreamUntilEnded.
209 enum class OutputCaptureState { Capture, Halt, None };
210 // Set the output capture state of this decoder.
211 // @param aState Capture: Output is captured into output tracks, and
212 // aDummyTrack must be provided.
213 // Halt: A capturing media sink is used, but capture is
214 // halted.
215 // None: Output is not captured.
216 // @param aDummyTrack A SharedDummyTrack the capturing media sink can use to
217 // access a MediaTrackGraph, so it can create tracks even
218 // when there are no output tracks available.
219 void SetOutputCaptureState(OutputCaptureState aState,
220 SharedDummyTrack* aDummyTrack = nullptr);
221 // Add an output track. All decoder output for the track's media type will be
222 // sent to the track.
223 // Note that only one audio track and one video track is supported by
224 // MediaDecoder at this time. Passing in more of one type, or passing in a
225 // type that metadata says we are not decoding, is an error.
226 void AddOutputTrack(RefPtr<ProcessedMediaTrack> aTrack);
227 // Remove an output track added with AddOutputTrack.
228 void RemoveOutputTrack(const RefPtr<ProcessedMediaTrack>& aTrack);
229 // Update the principal for any output tracks.
230 void SetOutputTracksPrincipal(const RefPtr<nsIPrincipal>& aPrincipal);
232 // Return the duration of the video in seconds.
233 virtual double GetDuration();
235 // Return true if the stream is infinite.
236 bool IsInfinite() const;
238 // Return true if we are currently seeking in the media resource.
239 // Call on the main thread only.
240 bool IsSeeking() const;
242 // Return true if the decoder has reached the end of playback.
243 bool IsEnded() const;
245 // True if we are playing a MediaSource object.
246 virtual bool IsMSE() const { return false; }
248 // Return true if the MediaDecoderOwner's error attribute is not null.
249 // Must be called before Shutdown().
250 bool OwnerHasError() const;
252 // Returns true if this media supports random seeking. False for example with
253 // chained ogg files.
254 bool IsMediaSeekable();
255 // Returns true if seeking is supported on a transport level (e.g. the server
256 // supports range requests, we are playing a file, etc.).
257 virtual bool IsTransportSeekable() = 0;
259 // Return the time ranges that can be seeked into, in TimeUnits.
260 virtual media::TimeIntervals GetSeekable();
261 // Return the time ranges that can be seeked into, in seconds, double
262 // precision.
263 virtual media::TimeRanges GetSeekableTimeRanges();
265 template <typename T>
266 T GetSeekableImpl();
268 // Set the end time of the media resource. When playback reaches
269 // this point the media pauses. aTime is in seconds.
270 virtual void SetFragmentEndTime(double aTime);
272 // Invalidate the frame.
273 void Invalidate();
274 void InvalidateWithFlags(uint32_t aFlags);
276 // Suspend any media downloads that are in progress. Called by the
277 // media element when it is sent to the bfcache, or when we need
278 // to throttle the download. Call on the main thread only. This can
279 // be called multiple times, there's an internal "suspend count".
280 // When it is called the internal system audio resource are cleaned up.
281 virtual void Suspend();
283 // Resume any media downloads that have been suspended. Called by the
284 // media element when it is restored from the bfcache, or when we need
285 // to stop throttling the download. Call on the main thread only.
286 // The download will only actually resume once as many Resume calls
287 // have been made as Suspend calls.
288 virtual void Resume();
290 // Moves any existing channel loads into or out of background. Background
291 // loads don't block the load event. This is called when we stop or restart
292 // delaying the load event. This also determines whether any new loads
293 // initiated (for example to seek) will be in the background. This calls
294 // SetLoadInBackground() on mResource.
295 virtual void SetLoadInBackground(bool aLoadInBackground) {}
297 MediaDecoderStateMachineBase* GetStateMachine() const;
298 void SetStateMachine(MediaDecoderStateMachineBase* aStateMachine);
300 // Constructs the time ranges representing what segments of the media
301 // are buffered and playable.
302 virtual media::TimeIntervals GetBuffered();
304 // Returns the size, in bytes, of the heap memory used by the currently
305 // queued decoded video and audio data.
306 size_t SizeOfVideoQueue();
307 size_t SizeOfAudioQueue();
309 // Helper struct for accumulating resource sizes that need to be measured
310 // asynchronously. Once all references are dropped the callback will be
311 // invoked.
312 struct ResourceSizes {
313 typedef MozPromise<size_t, size_t, true> SizeOfPromise;
314 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ResourceSizes)
315 explicit ResourceSizes(MallocSizeOf aMallocSizeOf)
316 : mMallocSizeOf(aMallocSizeOf), mByteSize(0), mCallback() {}
318 mozilla::MallocSizeOf mMallocSizeOf;
319 mozilla::Atomic<size_t> mByteSize;
321 RefPtr<SizeOfPromise> Promise() { return mCallback.Ensure(__func__); }
323 private:
324 ~ResourceSizes() { mCallback.ResolveIfExists(mByteSize, __func__); }
326 MozPromiseHolder<SizeOfPromise> mCallback;
329 virtual void AddSizeOfResources(ResourceSizes* aSizes) = 0;
331 VideoFrameContainer* GetVideoFrameContainer() { return mVideoFrameContainer; }
333 layers::ImageContainer* GetImageContainer();
335 // Returns true if we can play the entire media through without stopping
336 // to buffer, given the current download and playback rates.
337 bool CanPlayThrough();
339 // Called from HTMLMediaElement when owner document activity changes
340 virtual void SetElementVisibility(bool aIsOwnerInvisible,
341 bool aIsOwnerConnected);
343 // Force override the visible state to hidden.
344 // Called from HTMLMediaElement when testing of video decode suspend from
345 // mochitests.
346 void SetForcedHidden(bool aForcedHidden);
348 // Mark the decoder as tainted, meaning suspend-video-decoder is disabled.
349 void SetSuspendTaint(bool aTaint);
351 // Returns true if the decoder can't participate in suspend-video-decoder.
352 bool HasSuspendTaint() const;
354 void UpdateVideoDecodeMode();
356 void SetSecondaryVideoContainer(
357 const RefPtr<VideoFrameContainer>& aSecondaryVideoContainer);
359 void SetIsBackgroundVideoDecodingAllowed(bool aAllowed);
361 bool IsVideoDecodingSuspended() const;
363 // The MediaDecoderOwner of this decoder wants to resist fingerprinting.
364 bool ShouldResistFingerprinting() const {
365 return mShouldResistFingerprinting;
368 /******
369 * The following methods must only be called on the main
370 * thread.
371 ******/
373 // Change to a new play state. This updates the mState variable and
374 // notifies any thread blocking on this object's monitor of the
375 // change. Call on the main thread only.
376 virtual void ChangeState(PlayState aState);
378 // Called when the video has completed playing.
379 // Call on the main thread only.
380 void PlaybackEnded();
382 void OnSeekRejected();
383 void OnSeekResolved();
385 // Seeking has started. Inform the element on the main thread.
386 void SeekingStarted();
388 void UpdateLogicalPositionInternal();
389 void UpdateLogicalPosition() {
390 MOZ_ASSERT(NS_IsMainThread());
391 MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
392 // Per spec, offical position remains stable during pause and seek.
393 if (mPlayState == PLAY_STATE_PAUSED || IsSeeking()) {
394 return;
396 UpdateLogicalPositionInternal();
399 // Find the end of the cached data starting at the current decoder
400 // position.
401 int64_t GetDownloadPosition();
403 // Notifies the element that decoding has failed.
404 void DecodeError(const MediaResult& aError);
406 // Indicate whether the media is same-origin with the element.
407 void UpdateSameOriginStatus(bool aSameOrigin);
409 MediaDecoderOwner* GetOwner() const;
411 AbstractThread* AbstractMainThread() const { return mAbstractMainThread; }
413 RefPtr<SetCDMPromise> SetCDMProxy(CDMProxy* aProxy);
415 void EnsureTelemetryReported();
417 static bool IsOggEnabled();
418 static bool IsOpusEnabled();
419 static bool IsWaveEnabled();
420 static bool IsWebMEnabled();
422 // Return the frame decode/paint related statistics.
423 FrameStatistics& GetFrameStatistics() { return *mFrameStats; }
425 void UpdateReadyState() {
426 MOZ_ASSERT(NS_IsMainThread());
427 MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
428 GetOwner()->UpdateReadyState();
431 MediaDecoderOwner::NextFrameStatus NextFrameStatus() const {
432 return mNextFrameStatus;
435 virtual MediaDecoderOwner::NextFrameStatus NextFrameBufferedStatus();
437 RefPtr<GenericPromise> RequestDebugInfo(dom::MediaDecoderDebugInfo& aInfo);
439 void GetDebugInfo(dom::MediaDecoderDebugInfo& aInfo);
441 protected:
442 virtual ~MediaDecoder();
444 // Called when the first audio and/or video from the media file has been
445 // loaded by the state machine. Call on the main thread only.
446 virtual void FirstFrameLoaded(UniquePtr<MediaInfo> aInfo,
447 MediaDecoderEventVisibility aEventVisibility);
449 // Return error if fail to init the state machine.
450 nsresult CreateAndInitStateMachine(bool aIsLiveStream,
451 bool aDisableExternalEngine = false);
453 // Always return a state machine. If the decoder supports using external
454 // engine, `aDisableExternalEngine` can disable the external engine if needed.
455 virtual MediaDecoderStateMachineBase* CreateStateMachine(
456 bool aDisableExternalEngine) MOZ_NONNULL_RETURN = 0;
458 void SetStateMachineParameters();
460 // Disconnect any events before shutting down the state machine.
461 void DisconnectEvents();
462 RefPtr<ShutdownPromise> ShutdownStateMachine();
464 // Called when MediaDecoder shutdown is finished. Subclasses use this to clean
465 // up internal structures, and unregister potential shutdown blockers when
466 // they're done.
467 virtual void ShutdownInternal();
469 bool IsShutdown() const;
471 // Called to notify the decoder that the duration has changed.
472 virtual void DurationChanged();
474 // State-watching manager.
475 WatchManager<MediaDecoder> mWatchManager;
477 double ExplicitDuration() { return mExplicitDuration.ref(); }
479 void SetExplicitDuration(double aValue) {
480 MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
481 mExplicitDuration = Some(aValue);
483 // We Invoke DurationChanged explicitly, rather than using a watcher, so
484 // that it takes effect immediately, rather than at the end of the current
485 // task.
486 DurationChanged();
489 virtual void OnPlaybackEvent(MediaPlaybackEvent&& aEvent);
491 // Called when the metadata from the media file has been loaded by the
492 // state machine. Call on the main thread only.
493 virtual void MetadataLoaded(UniquePtr<MediaInfo> aInfo,
494 UniquePtr<MetadataTags> aTags,
495 MediaDecoderEventVisibility aEventVisibility);
497 void SetLogicalPosition(const media::TimeUnit& aNewPosition);
499 /******
500 * The following members should be accessed with the decoder lock held.
501 ******/
503 // The logical playback position of the media resource in units of
504 // seconds. This corresponds to the "official position" in HTML5. Note that
505 // we need to store this as a double, rather than an int64_t (like
506 // mCurrentPosition), so that |v.currentTime = foo; v.currentTime == foo|
507 // returns true without being affected by rounding errors.
508 double mLogicalPosition;
510 // The current playback position of the underlying playback infrastructure.
511 // This corresponds to the "current position" in HTML5.
512 // We allow omx subclasses to substitute an alternative current position for
513 // usage with the audio offload player.
514 virtual media::TimeUnit CurrentPosition() { return mCurrentPosition.Ref(); }
516 already_AddRefed<layers::KnowsCompositor> GetCompositor();
518 // Official duration of the media resource as observed by script.
519 // This can be a TimeUnit representing the exact duration found by demuxing,
520 // as a TimeUnit. This can also be a duration set explicitly by script, as a
521 // double.
522 Variant<media::TimeUnit, double> mDuration;
524 /******
525 * The following member variables can be accessed from any thread.
526 ******/
528 RefPtr<MediaFormatReader> mReader;
530 // Amount of buffered data ahead of current time required to consider that
531 // the next frame is available.
532 // An arbitrary value of 250ms is used.
533 static constexpr auto DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED =
534 media::TimeUnit::FromMicroseconds(250000);
536 private:
537 // Called when the owner's activity changed.
538 void NotifyCompositor();
540 void OnPlaybackErrorEvent(const MediaResult& aError);
542 void OnDecoderDoctorEvent(DecoderDoctorEvent aEvent);
544 void OnMediaNotSeekable() { mMediaSeekable = false; }
546 void OnNextFrameStatus(MediaDecoderOwner::NextFrameStatus);
548 void OnTrackInfoUpdated(const VideoInfo& aVideoInfo,
549 const AudioInfo& aAudioInfo);
551 void OnSecondaryVideoContainerInstalled(
552 const RefPtr<VideoFrameContainer>& aSecondaryVideoContainer);
554 void OnStoreDecoderBenchmark(const VideoInfo& aInfo);
556 void FinishShutdown();
558 void ConnectMirrors(MediaDecoderStateMachineBase* aObject);
559 void DisconnectMirrors();
561 virtual bool CanPlayThroughImpl() = 0;
563 // The state machine object for handling the decoding. It is safe to
564 // call methods of this object from other threads. Its internal data
565 // is synchronised on a monitor. The lifetime of this object is
566 // after mPlayState is LOADING and before mPlayState is SHUTDOWN. It
567 // is safe to access it during this period.
569 // Explicitly prievate to force access via accessors.
570 RefPtr<MediaDecoderStateMachineBase> mDecoderStateMachine;
572 protected:
573 void NotifyReaderDataArrived();
574 void DiscardOngoingSeekIfExists();
575 void CallSeek(const SeekTarget& aTarget);
577 // Called by MediaResource when the principal of the resource has
578 // changed. Called on main thread only.
579 virtual void NotifyPrincipalChanged();
581 MozPromiseRequestHolder<SeekPromise> mSeekRequest;
583 const char* PlayStateStr();
585 void OnMetadataUpdate(TimedMetadata&& aMetadata);
587 // This should only ever be accessed from the main thread.
588 // It is set in the constructor and cleared in Shutdown when the element goes
589 // away. The decoder does not add a reference the element.
590 MediaDecoderOwner* mOwner;
592 // The AbstractThread from mOwner.
593 const RefPtr<AbstractThread> mAbstractMainThread;
595 // Counters related to decode and presentation of frames.
596 const RefPtr<FrameStatistics> mFrameStats;
598 // Store a benchmark of the decoder based on FrameStatistics.
599 RefPtr<DecoderBenchmark> mDecoderBenchmark;
601 RefPtr<VideoFrameContainer> mVideoFrameContainer;
603 // True if the decoder has been directed to minimize its preroll before
604 // playback starts. After the first time playback starts, we don't attempt
605 // to minimize preroll, as we assume the user is likely to keep playing,
606 // or play the media again.
607 const bool mMinimizePreroll;
609 // True if we've already fired metadataloaded.
610 bool mFiredMetadataLoaded;
612 // True if the media is seekable (i.e. supports random access).
613 bool mMediaSeekable = true;
615 // True if the media is only seekable within its buffered ranges
616 // like WebMs with no cues.
617 bool mMediaSeekableOnlyInBufferedRanges = false;
619 // Stores media info, including info of audio tracks and video tracks, should
620 // only be accessed from main thread.
621 UniquePtr<MediaInfo> mInfo;
623 // True if the owner element is actually visible to users.
624 bool mIsOwnerInvisible;
626 // True if the owner element is connected to a document tree.
627 // https://dom.spec.whatwg.org/#connected
628 bool mIsOwnerConnected;
630 // If true, forces the decoder to be considered hidden.
631 bool mForcedHidden;
633 // True if the decoder has a suspend taint - meaning suspend-video-decoder is
634 // disabled.
635 bool mHasSuspendTaint;
637 // If true, the decoder should resist fingerprinting.
638 const bool mShouldResistFingerprinting;
640 MediaDecoderOwner::NextFrameStatus mNextFrameStatus =
641 MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
643 // A listener to receive metadata updates from MDSM.
644 MediaEventListener mTimedMetadataListener;
646 MediaEventListener mMetadataLoadedListener;
647 MediaEventListener mFirstFrameLoadedListener;
649 MediaEventListener mOnPlaybackEvent;
650 MediaEventListener mOnPlaybackErrorEvent;
651 MediaEventListener mOnDecoderDoctorEvent;
652 MediaEventListener mOnMediaNotSeekable;
653 MediaEventListener mOnEncrypted;
654 MediaEventListener mOnWaitingForKey;
655 MediaEventListener mOnDecodeWarning;
656 MediaEventListener mOnNextFrameStatus;
657 MediaEventListener mOnTrackInfoUpdated;
658 MediaEventListener mOnSecondaryVideoContainerInstalled;
659 MediaEventListener mOnStoreDecoderBenchmark;
661 // True if we have suspended video decoding.
662 bool mIsVideoDecodingSuspended = false;
664 protected:
665 // PlaybackRate and pitch preservation status we should start at.
666 double mPlaybackRate;
668 // True if the decoder is seeking.
669 Watchable<bool> mLogicallySeeking;
671 // Buffered range, mirrored from the reader.
672 Mirror<media::TimeIntervals> mBuffered;
674 // NB: Don't use mCurrentPosition directly, but rather CurrentPosition().
675 Mirror<media::TimeUnit> mCurrentPosition;
677 // Duration of the media resource according to the state machine.
678 Mirror<media::NullableTimeUnit> mStateMachineDuration;
680 // Used to distinguish whether the audio is producing sound.
681 Mirror<bool> mIsAudioDataAudible;
683 // Volume of playback. 0.0 = muted. 1.0 = full volume.
684 Canonical<double> mVolume;
686 Canonical<bool> mPreservesPitch;
688 Canonical<bool> mLooping;
690 Canonical<nsAutoString> mStreamName;
692 // The device used with SetSink, or nullptr if no explicit device has been
693 // set.
694 Canonical<RefPtr<AudioDeviceInfo>> mSinkDevice;
696 // Set if the decoder is sending video to a secondary container. While set we
697 // should not suspend the decoder.
698 Canonical<RefPtr<VideoFrameContainer>> mSecondaryVideoContainer;
700 // Whether this MediaDecoder's output is captured, halted or not captured.
701 // When captured, all decoded data must be played out through mOutputTracks.
702 Canonical<OutputCaptureState> mOutputCaptureState;
704 // A dummy track used to access the right MediaTrackGraph instance. Needed
705 // since there's no guarantee that output tracks are present.
706 Canonical<nsMainThreadPtrHandle<SharedDummyTrack>> mOutputDummyTrack;
708 // Tracks that, if set, will get data routed through them.
709 Canonical<CopyableTArray<RefPtr<ProcessedMediaTrack>>> mOutputTracks;
711 // PrincipalHandle to be used when feeding data into mOutputTracks.
712 Canonical<PrincipalHandle> mOutputPrincipal;
714 // Media duration set explicitly by JS. At present, this is only ever present
715 // for MSE.
716 Maybe<double> mExplicitDuration;
718 // Set to one of the valid play states.
719 // This can only be changed on the main thread while holding the decoder
720 // monitor. Thus, it can be safely read while holding the decoder monitor
721 // OR on the main thread.
722 Canonical<PlayState> mPlayState;
724 // This can only be changed on the main thread.
725 PlayState mNextState = PLAY_STATE_PAUSED;
727 // True if the media is same-origin with the element. Data can only be
728 // passed to MediaStreams when this is true.
729 bool mSameOriginMedia;
731 // We can allow video decoding in background when we match some special
732 // conditions, eg. when the cursor is hovering over the tab. This observer is
733 // used to listen the related events.
734 RefPtr<BackgroundVideoDecodingPermissionObserver> mVideoDecodingOberver;
736 // True if we want to resume video decoding even the media element is in the
737 // background.
738 bool mIsBackgroundVideoDecodingAllowed;
740 // True if we want to delay seeking, and and save the latest seeking target to
741 // resume to when we stop delaying seeking.
742 bool mShouldDelaySeek = false;
743 Maybe<SeekTarget> mDelayedSeekTarget;
745 public:
746 Canonical<double>& CanonicalVolume() { return mVolume; }
747 Canonical<bool>& CanonicalPreservesPitch() { return mPreservesPitch; }
748 Canonical<bool>& CanonicalLooping() { return mLooping; }
749 Canonical<nsAutoString>& CanonicalStreamName() { return mStreamName; }
750 Canonical<RefPtr<AudioDeviceInfo>>& CanonicalSinkDevice() {
751 return mSinkDevice;
753 Canonical<RefPtr<VideoFrameContainer>>& CanonicalSecondaryVideoContainer() {
754 return mSecondaryVideoContainer;
756 Canonical<OutputCaptureState>& CanonicalOutputCaptureState() {
757 return mOutputCaptureState;
759 Canonical<nsMainThreadPtrHandle<SharedDummyTrack>>&
760 CanonicalOutputDummyTrack() {
761 return mOutputDummyTrack;
763 Canonical<CopyableTArray<RefPtr<ProcessedMediaTrack>>>&
764 CanonicalOutputTracks() {
765 return mOutputTracks;
767 Canonical<PrincipalHandle>& CanonicalOutputPrincipal() {
768 return mOutputPrincipal;
770 Canonical<PlayState>& CanonicalPlayState() { return mPlayState; }
772 void UpdateTelemetryHelperBasedOnPlayState(PlayState aState) const;
774 TelemetryProbesReporter::Visibility OwnerVisibility() const;
776 // Those methods exist to report telemetry related metrics.
777 double GetTotalVideoPlayTimeInSeconds() const;
778 double GetTotalVideoHDRPlayTimeInSeconds() const;
779 double GetVisibleVideoPlayTimeInSeconds() const;
780 double GetInvisibleVideoPlayTimeInSeconds() const;
781 double GetVideoDecodeSuspendedTimeInSeconds() const;
782 double GetTotalAudioPlayTimeInSeconds() const;
783 double GetAudiblePlayTimeInSeconds() const;
784 double GetInaudiblePlayTimeInSeconds() const;
785 double GetMutedPlayTimeInSeconds() const;
787 private:
789 * This enum describes the reason why we need to update the logical position.
790 * ePeriodicUpdate : the position grows periodically during playback
791 * eSeamlessLoopingSeeking : the position changes due to demuxer level seek.
792 * eOther : due to normal seeking or other attributes changes, eg. playstate
794 enum class PositionUpdate {
795 ePeriodicUpdate,
796 eSeamlessLoopingSeeking,
797 eOther,
799 PositionUpdate GetPositionUpdateReason(double aPrevPos,
800 const media::TimeUnit& aCurPos) const;
802 // Notify owner when the audible state changed
803 void NotifyAudibleStateChanged();
805 void NotifyVolumeChanged();
807 bool mTelemetryReported;
808 const MediaContainerType mContainerType;
809 bool mCanPlayThrough = false;
811 UniquePtr<TelemetryProbesReporter> mTelemetryProbesReporter;
813 # ifdef MOZ_WMF_MEDIA_ENGINE
814 // True when we need to update the newly created MDSM's status to make it
815 // consistent with the previous destroyed one.
816 bool mPendingStatusUpdateForNewlyCreatedStateMachine = false;
817 # endif
820 } // namespace mozilla
822 #endif