/work/obj-fuzz/dist/include/MediaDecoder.h
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #if !defined(MediaDecoder_h_) |
8 | | #define MediaDecoder_h_ |
9 | | |
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 "MediaStreamGraph.h" |
20 | | #include "SeekTarget.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 "nsAutoPtr.h" |
29 | | #include "nsCOMPtr.h" |
30 | | #include "nsIObserver.h" |
31 | | #include "nsISupports.h" |
32 | | #include "nsITimer.h" |
33 | | |
34 | | class nsIPrincipal; |
35 | | |
36 | | namespace mozilla { |
37 | | |
38 | | class AbstractThread; |
39 | | class FrameStatistics; |
40 | | class VideoFrameContainer; |
41 | | class MediaFormatReader; |
42 | | class MediaDecoderStateMachine; |
43 | | struct MediaPlaybackEvent; |
44 | | |
45 | | enum class Visibility : uint8_t; |
46 | | |
47 | | // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to |
48 | | // GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation. |
49 | | #ifdef GetCurrentTime |
50 | | #undef GetCurrentTime |
51 | | #endif |
52 | | |
53 | | struct MOZ_STACK_CLASS MediaDecoderInit |
54 | | { |
55 | | MediaDecoderOwner* const mOwner; |
56 | | const double mVolume; |
57 | | const bool mPreservesPitch; |
58 | | const double mPlaybackRate; |
59 | | const bool mMinimizePreroll; |
60 | | const bool mHasSuspendTaint; |
61 | | const bool mLooping; |
62 | | const MediaContainerType mContainerType; |
63 | | |
64 | | MediaDecoderInit(MediaDecoderOwner* aOwner, |
65 | | double aVolume, |
66 | | bool aPreservesPitch, |
67 | | double aPlaybackRate, |
68 | | bool aMinimizePreroll, |
69 | | bool aHasSuspendTaint, |
70 | | bool aLooping, |
71 | | const MediaContainerType& aContainerType) |
72 | | : mOwner(aOwner) |
73 | | , mVolume(aVolume) |
74 | | , mPreservesPitch(aPreservesPitch) |
75 | | , mPlaybackRate(aPlaybackRate) |
76 | | , mMinimizePreroll(aMinimizePreroll) |
77 | | , mHasSuspendTaint(aHasSuspendTaint) |
78 | | , mLooping(aLooping) |
79 | | , mContainerType(aContainerType) |
80 | 0 | { |
81 | 0 | } |
82 | | }; |
83 | | |
84 | | DDLoggedTypeDeclName(MediaDecoder); |
85 | | |
86 | | class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> |
87 | | { |
88 | | public: |
89 | | typedef MozPromise<bool /* aIgnored */, bool /* aIgnored */, |
90 | | /* IsExclusive = */ true> |
91 | | SeekPromise; |
92 | | |
93 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoder) |
94 | | |
95 | | // Enumeration for the valid play states (see mPlayState) |
96 | | enum PlayState |
97 | | { |
98 | | PLAY_STATE_START, |
99 | | PLAY_STATE_LOADING, |
100 | | PLAY_STATE_PAUSED, |
101 | | PLAY_STATE_PLAYING, |
102 | | PLAY_STATE_ENDED, |
103 | | PLAY_STATE_SHUTDOWN |
104 | | }; |
105 | | |
106 | | // Must be called exactly once, on the main thread, during startup. |
107 | | static void InitStatics(); |
108 | | |
109 | | explicit MediaDecoder(MediaDecoderInit& aInit); |
110 | | |
111 | | // Returns the container content type of the resource. |
112 | | // Safe to call from any thread. |
113 | 0 | const MediaContainerType& ContainerType() const { return mContainerType; } |
114 | | |
115 | | // Cleanup internal data structures. Must be called on the main |
116 | | // thread by the owning object before that object disposes of this object. |
117 | | virtual void Shutdown(); |
118 | | |
119 | | // Notified by the shutdown manager that XPCOM shutdown has begun. |
120 | | // The decoder should notify its owner to drop the reference to the decoder |
121 | | // to prevent further calls into the decoder. |
122 | | void NotifyXPCOMShutdown(); |
123 | | |
124 | | // Called if the media file encounters a network error. |
125 | | void NetworkError(const MediaResult& aError); |
126 | | |
127 | | // Return the principal of the current URI being played or downloaded. |
128 | | virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() = 0; |
129 | | |
130 | | // Return the time position in the video stream being |
131 | | // played measured in seconds. |
132 | | virtual double GetCurrentTime(); |
133 | | |
134 | | // Seek to the time position in (seconds) from the start of the video. |
135 | | // If aDoFastSeek is true, we'll seek to the sync point/keyframe preceeding |
136 | | // the seek target. |
137 | | void Seek(double aTime, SeekTarget::Type aSeekType); |
138 | | |
139 | | // Initialize state machine and schedule it. |
140 | | nsresult InitializeStateMachine(); |
141 | | |
142 | | // Start playback of a video. 'Load' must have previously been |
143 | | // called. |
144 | | virtual void Play(); |
145 | | |
146 | | // Notify activity of the decoder owner is changed. |
147 | | virtual void NotifyOwnerActivityChanged(bool aIsDocumentVisible, |
148 | | Visibility aElementVisibility, |
149 | | bool aIsElementInTree); |
150 | | |
151 | | // Pause video playback. |
152 | | virtual void Pause(); |
153 | | // Adjust the speed of the playback, optionally with pitch correction, |
154 | | void SetVolume(double aVolume); |
155 | | |
156 | | void SetPlaybackRate(double aPlaybackRate); |
157 | | void SetPreservesPitch(bool aPreservesPitch); |
158 | | void SetLooping(bool aLooping); |
159 | | |
160 | | bool GetMinimizePreroll() const { return mMinimizePreroll; } |
161 | | |
162 | | // All MediaStream-related data is protected by mReentrantMonitor. |
163 | | // We have at most one DecodedStreamData per MediaDecoder. Its stream |
164 | | // is used as the input for each ProcessedMediaStream created by calls to |
165 | | // captureStream(UntilEnded). Seeking creates a new source stream, as does |
166 | | // replaying after the input as ended. In the latter case, the new source is |
167 | | // not connected to streams created by captureStreamUntilEnded. |
168 | | |
169 | | // Add an output stream. All decoder output will be sent to the stream. |
170 | | // The stream is initially blocked. The decoder is responsible for unblocking |
171 | | // it while it is playing back. |
172 | | virtual void AddOutputStream(ProcessedMediaStream* aStream, |
173 | | TrackID aNextAvailableTrackID, |
174 | | bool aFinishWhenEnded); |
175 | | // Remove an output stream added with AddOutputStream. |
176 | | virtual void RemoveOutputStream(MediaStream* aStream); |
177 | | // The next TrackID that can be used without risk of a collision. |
178 | | virtual TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const; |
179 | | |
180 | | // Return the duration of the video in seconds. |
181 | | virtual double GetDuration(); |
182 | | |
183 | | // Return true if the stream is infinite. |
184 | | bool IsInfinite() const; |
185 | | |
186 | | // Return true if we are currently seeking in the media resource. |
187 | | // Call on the main thread only. |
188 | | bool IsSeeking() const; |
189 | | |
190 | | // Return true if the decoder has reached the end of playback. |
191 | | bool IsEnded() const; |
192 | | |
193 | | // True if we are playing a MediaSource object. |
194 | | virtual bool IsMSE() const { return false; } |
195 | | |
196 | | // Return true if the MediaDecoderOwner's error attribute is not null. |
197 | | // Must be called before Shutdown(). |
198 | | bool OwnerHasError() const; |
199 | | |
200 | | // Returns true if this media supports random seeking. False for example with |
201 | | // chained ogg files. |
202 | | bool IsMediaSeekable(); |
203 | | // Returns true if seeking is supported on a transport level (e.g. the server |
204 | | // supports range requests, we are playing a file, etc.). |
205 | | virtual bool IsTransportSeekable() = 0; |
206 | | |
207 | | // Return the time ranges that can be seeked into. |
208 | | virtual media::TimeIntervals GetSeekable(); |
209 | | |
210 | | // Set the end time of the media resource. When playback reaches |
211 | | // this point the media pauses. aTime is in seconds. |
212 | | virtual void SetFragmentEndTime(double aTime); |
213 | | |
214 | | // Invalidate the frame. |
215 | | void Invalidate(); |
216 | | void InvalidateWithFlags(uint32_t aFlags); |
217 | | |
218 | | // Suspend any media downloads that are in progress. Called by the |
219 | | // media element when it is sent to the bfcache, or when we need |
220 | | // to throttle the download. Call on the main thread only. This can |
221 | | // be called multiple times, there's an internal "suspend count". |
222 | | virtual void Suspend() {} |
223 | | |
224 | | // Resume any media downloads that have been suspended. Called by the |
225 | | // media element when it is restored from the bfcache, or when we need |
226 | | // to stop throttling the download. Call on the main thread only. |
227 | | // The download will only actually resume once as many Resume calls |
228 | | // have been made as Suspend calls. |
229 | | virtual void Resume() {} |
230 | | |
231 | | // Moves any existing channel loads into or out of background. Background |
232 | | // loads don't block the load event. This is called when we stop or restart |
233 | | // delaying the load event. This also determines whether any new loads |
234 | | // initiated (for example to seek) will be in the background. This calls |
235 | | // SetLoadInBackground() on mResource. |
236 | | virtual void SetLoadInBackground(bool aLoadInBackground) {} |
237 | | |
238 | | MediaDecoderStateMachine* GetStateMachine() const; |
239 | | void SetStateMachine(MediaDecoderStateMachine* aStateMachine); |
240 | | |
241 | | // Constructs the time ranges representing what segments of the media |
242 | | // are buffered and playable. |
243 | | virtual media::TimeIntervals GetBuffered(); |
244 | | |
245 | | // Returns the size, in bytes, of the heap memory used by the currently |
246 | | // queued decoded video and audio data. |
247 | | size_t SizeOfVideoQueue(); |
248 | | size_t SizeOfAudioQueue(); |
249 | | |
250 | | // Helper struct for accumulating resource sizes that need to be measured |
251 | | // asynchronously. Once all references are dropped the callback will be |
252 | | // invoked. |
253 | | struct ResourceSizes |
254 | | { |
255 | | typedef MozPromise<size_t, size_t, true> SizeOfPromise; |
256 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ResourceSizes) |
257 | | explicit ResourceSizes(MallocSizeOf aMallocSizeOf) |
258 | | : mMallocSizeOf(aMallocSizeOf) |
259 | | , mByteSize(0) |
260 | | , mCallback() |
261 | | { |
262 | | } |
263 | | |
264 | | mozilla::MallocSizeOf mMallocSizeOf; |
265 | | mozilla::Atomic<size_t> mByteSize; |
266 | | |
267 | | RefPtr<SizeOfPromise> Promise() |
268 | | { |
269 | | return mCallback.Ensure(__func__); |
270 | | } |
271 | | |
272 | | private: |
273 | | ~ResourceSizes() |
274 | | { |
275 | | mCallback.ResolveIfExists(mByteSize, __func__); |
276 | | } |
277 | | |
278 | | MozPromiseHolder<SizeOfPromise> mCallback; |
279 | | }; |
280 | | |
281 | | virtual void AddSizeOfResources(ResourceSizes* aSizes) = 0; |
282 | | |
283 | | VideoFrameContainer* GetVideoFrameContainer() |
284 | | { |
285 | | return mVideoFrameContainer; |
286 | | } |
287 | | |
288 | | layers::ImageContainer* GetImageContainer(); |
289 | | |
290 | | // Fire timeupdate events if needed according to the time constraints |
291 | | // outlined in the specification. |
292 | | void FireTimeUpdate(); |
293 | | |
294 | | // Returns true if we can play the entire media through without stopping |
295 | | // to buffer, given the current download and playback rates. |
296 | | bool CanPlayThrough(); |
297 | | |
298 | | // Called from HTMLMediaElement when owner document activity changes |
299 | | virtual void SetElementVisibility(bool aIsDocumentVisible, |
300 | | Visibility aElementVisibility, |
301 | | bool aIsElementInTree); |
302 | | |
303 | | // Force override the visible state to hidden. |
304 | | // Called from HTMLMediaElement when testing of video decode suspend from mochitests. |
305 | | void SetForcedHidden(bool aForcedHidden); |
306 | | |
307 | | // Mark the decoder as tainted, meaning suspend-video-decoder is disabled. |
308 | | void SetSuspendTaint(bool aTaint); |
309 | | |
310 | | // Returns true if the decoder can't participate in suspend-video-decoder. |
311 | | bool HasSuspendTaint() const; |
312 | | |
313 | | void UpdateVideoDecodeMode(); |
314 | | |
315 | | void SetIsBackgroundVideoDecodingAllowed(bool aAllowed); |
316 | | |
317 | | /****** |
318 | | * The following methods must only be called on the main |
319 | | * thread. |
320 | | ******/ |
321 | | |
322 | | // Change to a new play state. This updates the mState variable and |
323 | | // notifies any thread blocking on this object's monitor of the |
324 | | // change. Call on the main thread only. |
325 | | virtual void ChangeState(PlayState aState); |
326 | | |
327 | | // Called when the video has completed playing. |
328 | | // Call on the main thread only. |
329 | | void PlaybackEnded(); |
330 | | |
331 | | void OnSeekRejected(); |
332 | | void OnSeekResolved(); |
333 | | |
334 | | // Seeking has started. Inform the element on the main thread. |
335 | | void SeekingStarted(); |
336 | | |
337 | | void UpdateLogicalPositionInternal(); |
338 | | void UpdateLogicalPosition() |
339 | | { |
340 | | MOZ_ASSERT(NS_IsMainThread()); |
341 | | MOZ_DIAGNOSTIC_ASSERT(!IsShutdown()); |
342 | | // Per spec, offical position remains stable during pause and seek. |
343 | | if (mPlayState == PLAY_STATE_PAUSED || IsSeeking()) { |
344 | | return; |
345 | | } |
346 | | UpdateLogicalPositionInternal(); |
347 | | } |
348 | | |
349 | | // Find the end of the cached data starting at the current decoder |
350 | | // position. |
351 | | int64_t GetDownloadPosition(); |
352 | | |
353 | | // Notifies the element that decoding has failed. |
354 | | void DecodeError(const MediaResult& aError); |
355 | | |
356 | | // Indicate whether the media is same-origin with the element. |
357 | | void UpdateSameOriginStatus(bool aSameOrigin); |
358 | | |
359 | | MediaDecoderOwner* GetOwner() const; |
360 | | |
361 | | AbstractThread* AbstractMainThread() const |
362 | | { |
363 | | return mAbstractMainThread; |
364 | | } |
365 | | |
366 | | RefPtr<SetCDMPromise> SetCDMProxy(CDMProxy* aProxy); |
367 | | |
368 | | void EnsureTelemetryReported(); |
369 | | |
370 | | static bool IsOggEnabled(); |
371 | | static bool IsOpusEnabled(); |
372 | | static bool IsWaveEnabled(); |
373 | | static bool IsWebMEnabled(); |
374 | | |
375 | | #ifdef MOZ_WMF |
376 | | static bool IsWMFEnabled(); |
377 | | #endif |
378 | | |
379 | | // Return the frame decode/paint related statistics. |
380 | | FrameStatistics& GetFrameStatistics() { return *mFrameStats; } |
381 | | |
382 | | void UpdateReadyState() |
383 | | { |
384 | | MOZ_ASSERT(NS_IsMainThread()); |
385 | | MOZ_DIAGNOSTIC_ASSERT(!IsShutdown()); |
386 | | GetOwner()->UpdateReadyState(); |
387 | | } |
388 | | |
389 | | MediaDecoderOwner::NextFrameStatus NextFrameStatus() const |
390 | 0 | { |
391 | 0 | return mNextFrameStatus; |
392 | 0 | } |
393 | | |
394 | | virtual MediaDecoderOwner::NextFrameStatus NextFrameBufferedStatus(); |
395 | | |
396 | | // Returns a string describing the state of the media player internal |
397 | | // data. Used for debugging purposes. |
398 | | virtual void GetMozDebugReaderData(nsACString& aString); |
399 | | |
400 | | RefPtr<GenericPromise> DumpDebugInfo(); |
401 | | |
402 | | using DebugInfoPromise = MozPromise<nsCString, bool, true>; |
403 | | RefPtr<DebugInfoPromise> RequestDebugInfo(); |
404 | | |
405 | | protected: |
406 | | virtual ~MediaDecoder(); |
407 | | |
408 | | // Called when the first audio and/or video from the media file has been loaded |
409 | | // by the state machine. Call on the main thread only. |
410 | | virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo, |
411 | | MediaDecoderEventVisibility aEventVisibility); |
412 | | |
413 | | void SetStateMachineParameters(); |
414 | | |
415 | | bool IsShutdown() const; |
416 | | |
417 | | // Called to notify the decoder that the duration has changed. |
418 | | virtual void DurationChanged(); |
419 | | |
420 | | // State-watching manager. |
421 | | WatchManager<MediaDecoder> mWatchManager; |
422 | | |
423 | 0 | double ExplicitDuration() { return mExplicitDuration.ref(); } |
424 | | |
425 | | void SetExplicitDuration(double aValue) |
426 | 0 | { |
427 | 0 | MOZ_DIAGNOSTIC_ASSERT(!IsShutdown()); |
428 | 0 | mExplicitDuration = Some(aValue); |
429 | 0 |
|
430 | 0 | // We Invoke DurationChanged explicitly, rather than using a watcher, so |
431 | 0 | // that it takes effect immediately, rather than at the end of the current task. |
432 | 0 | DurationChanged(); |
433 | 0 | } |
434 | | |
435 | | virtual void OnPlaybackEvent(MediaPlaybackEvent&& aEvent); |
436 | | |
437 | | // Called when the metadata from the media file has been loaded by the |
438 | | // state machine. Call on the main thread only. |
439 | | virtual void MetadataLoaded(UniquePtr<MediaInfo> aInfo, |
440 | | UniquePtr<MetadataTags> aTags, |
441 | | MediaDecoderEventVisibility aEventVisibility); |
442 | | |
443 | | /****** |
444 | | * The following members should be accessed with the decoder lock held. |
445 | | ******/ |
446 | | |
447 | | // The logical playback position of the media resource in units of |
448 | | // seconds. This corresponds to the "official position" in HTML5. Note that |
449 | | // we need to store this as a double, rather than an int64_t (like |
450 | | // mCurrentPosition), so that |v.currentTime = foo; v.currentTime == foo| |
451 | | // returns true without being affected by rounding errors. |
452 | | double mLogicalPosition; |
453 | | |
454 | | // The current playback position of the underlying playback infrastructure. |
455 | | // This corresponds to the "current position" in HTML5. |
456 | | // We allow omx subclasses to substitute an alternative current position for |
457 | | // usage with the audio offload player. |
458 | | virtual media::TimeUnit CurrentPosition() |
459 | | { |
460 | | return mCurrentPosition.Ref(); |
461 | | } |
462 | | |
463 | | already_AddRefed<layers::KnowsCompositor> GetCompositor(); |
464 | | |
465 | | // Official duration of the media resource as observed by script. |
466 | | double mDuration; |
467 | | |
468 | | /****** |
469 | | * The following member variables can be accessed from any thread. |
470 | | ******/ |
471 | | |
472 | | RefPtr<MediaFormatReader> mReader; |
473 | | |
474 | | // Amount of buffered data ahead of current time required to consider that |
475 | | // the next frame is available. |
476 | | // An arbitrary value of 250ms is used. |
477 | | static constexpr auto DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED = |
478 | | media::TimeUnit::FromMicroseconds(250000); |
479 | | |
480 | | virtual nsCString GetDebugInfo(); |
481 | | |
482 | | private: |
483 | | // Called when the owner's activity changed. |
484 | | void NotifyCompositor(); |
485 | | |
486 | | void OnPlaybackErrorEvent(const MediaResult& aError); |
487 | | |
488 | | void OnDecoderDoctorEvent(DecoderDoctorEvent aEvent); |
489 | | |
490 | | void OnMediaNotSeekable() |
491 | | { |
492 | | mMediaSeekable = false; |
493 | | } |
494 | | |
495 | | void OnNextFrameStatus(MediaDecoderOwner::NextFrameStatus); |
496 | | |
497 | | void FinishShutdown(); |
498 | | |
499 | | void ConnectMirrors(MediaDecoderStateMachine* aObject); |
500 | | void DisconnectMirrors(); |
501 | | |
502 | | virtual bool CanPlayThroughImpl() = 0; |
503 | | |
504 | | // The state machine object for handling the decoding. It is safe to |
505 | | // call methods of this object from other threads. Its internal data |
506 | | // is synchronised on a monitor. The lifetime of this object is |
507 | | // after mPlayState is LOADING and before mPlayState is SHUTDOWN. It |
508 | | // is safe to access it during this period. |
509 | | // |
510 | | // Explicitly prievate to force access via accessors. |
511 | | RefPtr<MediaDecoderStateMachine> mDecoderStateMachine; |
512 | | |
513 | | protected: |
514 | | void NotifyReaderDataArrived(); |
515 | | void DiscardOngoingSeekIfExists(); |
516 | | virtual void CallSeek(const SeekTarget& aTarget); |
517 | | |
518 | | // Called by MediaResource when the principal of the resource has |
519 | | // changed. Called on main thread only. |
520 | | virtual void NotifyPrincipalChanged(); |
521 | | |
522 | | MozPromiseRequestHolder<SeekPromise> mSeekRequest; |
523 | | |
524 | | const char* PlayStateStr(); |
525 | | |
526 | | void OnMetadataUpdate(TimedMetadata&& aMetadata); |
527 | | |
528 | | // This should only ever be accessed from the main thread. |
529 | | // It is set in the constructor and cleared in Shutdown when the element goes |
530 | | // away. The decoder does not add a reference the element. |
531 | | MediaDecoderOwner* mOwner; |
532 | | |
533 | | // The AbstractThread from mOwner. |
534 | | const RefPtr<AbstractThread> mAbstractMainThread; |
535 | | |
536 | | // Counters related to decode and presentation of frames. |
537 | | const RefPtr<FrameStatistics> mFrameStats; |
538 | | |
539 | | RefPtr<VideoFrameContainer> mVideoFrameContainer; |
540 | | |
541 | | // True if the decoder has been directed to minimize its preroll before |
542 | | // playback starts. After the first time playback starts, we don't attempt |
543 | | // to minimize preroll, as we assume the user is likely to keep playing, |
544 | | // or play the media again. |
545 | | const bool mMinimizePreroll; |
546 | | |
547 | | // True if we've already fired metadataloaded. |
548 | | bool mFiredMetadataLoaded; |
549 | | |
550 | | // True if the media is seekable (i.e. supports random access). |
551 | | bool mMediaSeekable = true; |
552 | | |
553 | | // True if the media is only seekable within its buffered ranges |
554 | | // like WebMs with no cues. |
555 | | bool mMediaSeekableOnlyInBufferedRanges = false; |
556 | | |
557 | | // Stores media info, including info of audio tracks and video tracks, should |
558 | | // only be accessed from main thread. |
559 | | nsAutoPtr<MediaInfo> mInfo; |
560 | | |
561 | | // Tracks the visibility status of owner element's document. |
562 | | bool mIsDocumentVisible; |
563 | | |
564 | | // Tracks the visibility status of owner element. |
565 | | Visibility mElementVisibility; |
566 | | |
567 | | // Tracks the owner is in-tree or not. |
568 | | bool mIsElementInTree; |
569 | | |
570 | | // If true, forces the decoder to be considered hidden. |
571 | | bool mForcedHidden; |
572 | | |
573 | | // True if the decoder has a suspend taint - meaning suspend-video-decoder is |
574 | | // disabled. |
575 | | bool mHasSuspendTaint; |
576 | | |
577 | | MediaDecoderOwner::NextFrameStatus mNextFrameStatus = |
578 | | MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE; |
579 | | |
580 | | // A listener to receive metadata updates from MDSM. |
581 | | MediaEventListener mTimedMetadataListener; |
582 | | |
583 | | MediaEventListener mMetadataLoadedListener; |
584 | | MediaEventListener mFirstFrameLoadedListener; |
585 | | |
586 | | MediaEventListener mOnPlaybackEvent; |
587 | | MediaEventListener mOnPlaybackErrorEvent; |
588 | | MediaEventListener mOnDecoderDoctorEvent; |
589 | | MediaEventListener mOnMediaNotSeekable; |
590 | | MediaEventListener mOnEncrypted; |
591 | | MediaEventListener mOnWaitingForKey; |
592 | | MediaEventListener mOnDecodeWarning; |
593 | | MediaEventListener mOnNextFrameStatus; |
594 | | |
595 | | protected: |
596 | | // PlaybackRate and pitch preservation status we should start at. |
597 | | double mPlaybackRate; |
598 | | |
599 | | // Buffered range, mirrored from the reader. |
600 | | Mirror<media::TimeIntervals> mBuffered; |
601 | | |
602 | | // NB: Don't use mCurrentPosition directly, but rather CurrentPosition(). |
603 | | Mirror<media::TimeUnit> mCurrentPosition; |
604 | | |
605 | | // Duration of the media resource according to the state machine. |
606 | | Mirror<media::NullableTimeUnit> mStateMachineDuration; |
607 | | |
608 | | // Used to distinguish whether the audio is producing sound. |
609 | | Mirror<bool> mIsAudioDataAudible; |
610 | | |
611 | | // Volume of playback. 0.0 = muted. 1.0 = full volume. |
612 | | Canonical<double> mVolume; |
613 | | |
614 | | Canonical<bool> mPreservesPitch; |
615 | | |
616 | | Canonical<bool> mLooping; |
617 | | |
618 | | // Media duration set explicitly by JS. At present, this is only ever present |
619 | | // for MSE. |
620 | | Maybe<double> mExplicitDuration; |
621 | | |
622 | | // Set to one of the valid play states. |
623 | | // This can only be changed on the main thread while holding the decoder |
624 | | // monitor. Thus, it can be safely read while holding the decoder monitor |
625 | | // OR on the main thread. |
626 | | Canonical<PlayState> mPlayState; |
627 | | |
628 | | // This can only be changed on the main thread. |
629 | | PlayState mNextState = PLAY_STATE_PAUSED; |
630 | | |
631 | | // True if the decoder is seeking. |
632 | | Canonical<bool> mLogicallySeeking; |
633 | | |
634 | | // True if the media is same-origin with the element. Data can only be |
635 | | // passed to MediaStreams when this is true. |
636 | | Canonical<bool> mSameOriginMedia; |
637 | | |
638 | | // An identifier for the principal of the media. Used to track when |
639 | | // main-thread induced principal changes get reflected on MSG thread. |
640 | | Canonical<PrincipalHandle> mMediaPrincipalHandle; |
641 | | |
642 | | // We can allow video decoding in background when we match some special |
643 | | // conditions, eg. when the cursor is hovering over the tab. This observer is |
644 | | // used to listen the related events. |
645 | | RefPtr<BackgroundVideoDecodingPermissionObserver> mVideoDecodingOberver; |
646 | | |
647 | | // True if we want to resume video decoding even the media element is in the |
648 | | // background. |
649 | | bool mIsBackgroundVideoDecodingAllowed; |
650 | | |
651 | | public: |
652 | | AbstractCanonical<double>* CanonicalVolume() { return &mVolume; } |
653 | | AbstractCanonical<bool>* CanonicalPreservesPitch() |
654 | | { |
655 | | return &mPreservesPitch; |
656 | | } |
657 | | AbstractCanonical<bool>* CanonicalLooping() |
658 | | { |
659 | | return &mLooping; |
660 | | } |
661 | | AbstractCanonical<PlayState>* CanonicalPlayState() { return &mPlayState; } |
662 | | AbstractCanonical<bool>* CanonicalLogicallySeeking() |
663 | 0 | { |
664 | 0 | return &mLogicallySeeking; |
665 | 0 | } |
666 | | AbstractCanonical<bool>* CanonicalSameOriginMedia() |
667 | | { |
668 | | return &mSameOriginMedia; |
669 | | } |
670 | | AbstractCanonical<PrincipalHandle>* CanonicalMediaPrincipalHandle() |
671 | | { |
672 | | return &mMediaPrincipalHandle; |
673 | | } |
674 | | |
675 | | private: |
676 | | // Notify owner when the audible state changed |
677 | | void NotifyAudibleStateChanged(); |
678 | | |
679 | | bool mTelemetryReported; |
680 | | const MediaContainerType mContainerType; |
681 | | bool mCanPlayThrough = false; |
682 | | }; |
683 | | |
684 | | } // namespace mozilla |
685 | | |
686 | | #endif |