Coverage Report

Created: 2018-09-25 14:53

/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