Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/MediaFormatReader.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(MediaFormatReader_h_)
8
#define MediaFormatReader_h_
9
10
#include "mozilla/Atomics.h"
11
#include "mozilla/Maybe.h"
12
#include "mozilla/Mutex.h"
13
#include "mozilla/StateMirroring.h"
14
#include "mozilla/StaticPrefs.h"
15
#include "mozilla/TaskQueue.h"
16
17
#include "FrameStatistics.h"
18
#include "MediaEventSource.h"
19
#include "MediaDataDemuxer.h"
20
#include "MediaMetadataManager.h"
21
#include "MediaPromiseDefs.h"
22
#include "nsAutoPtr.h"
23
#include "PDMFactory.h"
24
#include "SeekTarget.h"
25
26
namespace mozilla {
27
28
class CDMProxy;
29
class GMPCrashHelper;
30
class MediaResource;
31
class VideoFrameContainer;
32
33
struct WaitForDataRejectValue
34
{
35
  enum Reason
36
  {
37
    SHUTDOWN,
38
    CANCELED
39
  };
40
41
  WaitForDataRejectValue(MediaData::Type aType, Reason aReason)
42
    : mType(aType)
43
    , mReason(aReason)
44
0
  {
45
0
  }
46
  MediaData::Type mType;
47
  Reason mReason;
48
};
49
50
struct SeekRejectValue
51
{
52
  MOZ_IMPLICIT SeekRejectValue(const MediaResult& aError)
53
    : mType(MediaData::NULL_DATA)
54
    , mError(aError)
55
0
  {
56
0
  }
57
  MOZ_IMPLICIT SeekRejectValue(nsresult aResult)
58
    : mType(MediaData::NULL_DATA)
59
    , mError(aResult)
60
0
  {
61
0
  }
62
  SeekRejectValue(MediaData::Type aType, const MediaResult& aError)
63
    : mType(aType)
64
    , mError(aError)
65
0
  {
66
0
  }
67
  MediaData::Type mType;
68
  MediaResult mError;
69
};
70
71
struct MetadataHolder
72
{
73
  UniquePtr<MediaInfo> mInfo;
74
  UniquePtr<MetadataTags> mTags;
75
};
76
77
typedef void* MediaDecoderOwnerID;
78
79
struct MOZ_STACK_CLASS MediaFormatReaderInit
80
{
81
  MediaResource* mResource = nullptr;
82
  VideoFrameContainer* mVideoFrameContainer = nullptr;
83
  FrameStatistics* mFrameStats = nullptr;
84
  already_AddRefed<layers::KnowsCompositor> mKnowsCompositor;
85
  already_AddRefed<GMPCrashHelper> mCrashHelper;
86
  // Used in bug 1393399 for temporary telemetry.
87
  MediaDecoderOwnerID mMediaDecoderOwnerID = nullptr;
88
};
89
90
DDLoggedTypeDeclName(MediaFormatReader);
91
92
class MediaFormatReader final
93
  : public DecoderDoctorLifeLogger<MediaFormatReader>
94
{
95
  static const bool IsExclusive = true;
96
  typedef TrackInfo::TrackType TrackType;
97
  typedef MozPromise<bool, MediaResult, IsExclusive> NotifyDataArrivedPromise;
98
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaFormatReader)
99
100
public:
101
  using TrackSet = EnumSet<TrackInfo::TrackType>;
102
  using MetadataPromise = MozPromise<MetadataHolder, MediaResult, IsExclusive>;
103
104
  template<typename Type>
105
  using DataPromise = MozPromise<RefPtr<Type>, MediaResult, IsExclusive>;
106
  using AudioDataPromise = DataPromise<AudioData>;
107
  using VideoDataPromise = DataPromise<VideoData>;
108
109
  using SeekPromise = MozPromise<media::TimeUnit, SeekRejectValue, IsExclusive>;
110
111
  // Note that, conceptually, WaitForData makes sense in a non-exclusive sense.
112
  // But in the current architecture it's only ever used exclusively (by MDSM),
113
  // so we mark it that way to verify our assumptions. If you have a use-case
114
  // for multiple WaitForData consumers, feel free to flip the exclusivity here.
115
  using WaitForDataPromise =
116
    MozPromise<MediaData::Type, WaitForDataRejectValue, IsExclusive>;
117
118
  MediaFormatReader(MediaFormatReaderInit& aInit, MediaDataDemuxer* aDemuxer);
119
120
  // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
121
  // on failure.
122
  nsresult Init();
123
124
  size_t SizeOfVideoQueueInFrames();
125
  size_t SizeOfAudioQueueInFrames();
126
127
  // Requests one video sample from the reader.
128
  RefPtr<VideoDataPromise> RequestVideoData(
129
    const media::TimeUnit& aTimeThreshold);
130
131
  // Requests one audio sample from the reader.
132
  //
133
  // The decode should be performed asynchronously, and the promise should
134
  // be resolved when it is complete.
135
  RefPtr<AudioDataPromise> RequestAudioData();
136
137
  // The default implementation of AsyncReadMetadata is implemented in terms of
138
  // synchronous ReadMetadata() calls. Implementations may also
139
  // override AsyncReadMetadata to create a more proper async implementation.
140
  RefPtr<MetadataPromise> AsyncReadMetadata();
141
142
  // Fills aInfo with the latest cached data required to present the media,
143
  // ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
144
  void ReadUpdatedMetadata(MediaInfo* aInfo);
145
146
  RefPtr<SeekPromise> Seek(const SeekTarget& aTarget);
147
148
  // Called once new data has been cached by the MediaResource.
149
  // mBuffered should be recalculated and updated accordingly.
150
  void NotifyDataArrived();
151
152
protected:
153
  // Recomputes mBuffered.
154
  void UpdateBuffered();
155
156
public:
157
  // Called by MDSM in dormant state to release resources allocated by this
158
  // reader. The reader can resume decoding by calling Seek() to a specific
159
  // position.
160
  void ReleaseResources();
161
162
0
  bool OnTaskQueue() const { return OwnerThread()->IsCurrentThreadIn(); }
163
164
  // Resets all state related to decoding, emptying all buffers etc.
165
  // Cancels all pending Request*Data() request callbacks, rejects any
166
  // outstanding seek promises, and flushes the decode pipeline. The
167
  // decoder must not call any of the callbacks for outstanding
168
  // Request*Data() calls after this is called. Calls to Request*Data()
169
  // made after this should be processed as usual.
170
  //
171
  // Normally this call preceedes a Seek() call, or shutdown.
172
  //
173
  // aParam is a set of TrackInfo::TrackType enums specifying which
174
  // queues need to be reset, defaulting to both audio and video tracks.
175
  nsresult ResetDecode(TrackSet aTracks);
176
177
  // Destroys the decoding state. The reader cannot be made usable again.
178
  // This is different from ReleaseMediaResources() as it is irreversable,
179
  // whereas ReleaseMediaResources() is.  Must be called on the decode
180
  // thread.
181
  RefPtr<ShutdownPromise> Shutdown();
182
183
  // Returns true if this decoder reader uses hardware accelerated video
184
  // decoding.
185
  bool VideoIsHardwareAccelerated() const;
186
187
  // By default, the state machine polls the reader once per second when it's
188
  // in buffering mode. Some readers support a promise-based mechanism by which
189
  // they notify the state machine when the data arrives.
190
0
  bool IsWaitForDataSupported() const { return true; }
191
192
  RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType);
193
194
  // The MediaDecoderStateMachine uses various heuristics that assume that
195
  // raw media data is arriving sequentially from a network channel. This
196
  // makes sense in the <video src="foo"> case, but not for more advanced use
197
  // cases like MSE.
198
0
  bool UseBufferingHeuristics() const { return mTrackDemuxersMayBlock; }
199
200
  RefPtr<SetCDMPromise> SetCDMProxy(CDMProxy* aProxy);
201
202
  // Returns a string describing the state of the decoder data.
203
  // Used for debugging purposes.
204
  void GetMozDebugReaderData(nsACString& aString);
205
206
  // Switch the video decoder to NullDecoderModule. It might takes effective
207
  // since a few samples later depends on how much demuxed samples are already
208
  // queued in the original video decoder.
209
  void SetVideoNullDecode(bool aIsNullDecode);
210
211
  void UpdateCompositor(already_AddRefed<layers::KnowsCompositor>);
212
213
  void UpdateDuration(const media::TimeUnit& aDuration)
214
0
  {
215
0
    MOZ_ASSERT(OnTaskQueue());
216
0
    UpdateBuffered();
217
0
  }
218
219
  AbstractCanonical<media::TimeIntervals>* CanonicalBuffered()
220
0
  {
221
0
    return &mBuffered;
222
0
  }
223
224
0
  TaskQueue* OwnerThread() const { return mTaskQueue; }
225
226
0
  TimedMetadataEventSource& TimedMetadataEvent() { return mTimedMetadataEvent; }
227
228
  // Notified by the OggDemuxer during playback when chained ogg is detected.
229
0
  MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; }
230
231
  TimedMetadataEventProducer& TimedMetadataProducer()
232
0
  {
233
0
    return mTimedMetadataEvent;
234
0
  }
235
236
  MediaEventProducer<void>& MediaNotSeekableProducer()
237
0
  {
238
0
    return mOnMediaNotSeekable;
239
0
  }
240
241
  // Notified if the reader can't decode a sample due to a missing decryption
242
  // key.
243
  MediaEventSource<TrackInfo::TrackType>& OnTrackWaitingForKey()
244
0
  {
245
0
    return mOnTrackWaitingForKey;
246
0
  }
247
248
  MediaEventProducer<TrackInfo::TrackType>& OnTrackWaitingForKeyProducer()
249
0
  {
250
0
    return mOnTrackWaitingForKey;
251
0
  }
252
253
  MediaEventSource<nsTArray<uint8_t>, nsString>& OnEncrypted()
254
0
  {
255
0
    return mOnEncrypted;
256
0
  }
257
258
0
  MediaEventSource<void>& OnWaitingForKey() { return mOnWaitingForKey; }
259
260
0
  MediaEventSource<MediaResult>& OnDecodeWarning() { return mOnDecodeWarning; }
261
262
private:
263
  ~MediaFormatReader();
264
265
0
  bool HasVideo() const { return mVideo.mTrackDemuxer; }
266
0
  bool HasAudio() const { return mAudio.mTrackDemuxer; }
267
268
  bool IsWaitingOnCDMResource();
269
270
  bool InitDemuxer();
271
  // Notify the track demuxers that new data has been received.
272
  void NotifyTrackDemuxers();
273
  void ReturnOutput(MediaData* aData, TrackType aTrack);
274
275
  // Enqueues a task to call Update(aTrack) on the decoder task queue.
276
  // Lock for corresponding track must be held.
277
  void ScheduleUpdate(TrackType aTrack);
278
  void Update(TrackType aTrack);
279
  // Handle actions should more data be received.
280
  // Returns true if no more action is required.
281
  bool UpdateReceivedNewData(TrackType aTrack);
282
  // Called when new samples need to be demuxed.
283
  void RequestDemuxSamples(TrackType aTrack);
284
  // Handle demuxed samples by the input behavior.
285
  void HandleDemuxedSamples(TrackType aTrack,
286
                            FrameStatistics::AutoNotifyDecoded& aA);
287
  // Decode any pending already demuxed samples.
288
  void DecodeDemuxedSamples(TrackType aTrack,
289
                            MediaRawData* aSample);
290
291
  struct InternalSeekTarget
292
  {
293
    InternalSeekTarget(const media::TimeInterval& aTime, bool aDropTarget)
294
      : mTime(aTime)
295
      , mDropTarget(aDropTarget)
296
      , mWaiting(false)
297
      , mHasSeeked(false)
298
0
    {
299
0
    }
300
301
0
    media::TimeUnit Time() const { return mTime.mStart; }
302
0
    media::TimeUnit EndTime() const { return mTime.mEnd; }
303
    bool Contains(const media::TimeUnit& aTime) const
304
0
    {
305
0
      return mTime.Contains(aTime);
306
0
    }
307
308
    media::TimeInterval mTime;
309
    bool mDropTarget;
310
    bool mWaiting;
311
    bool mHasSeeked;
312
  };
313
314
  // Perform an internal seek to aTime. If aDropTarget is true then
315
  // the first sample past the target will be dropped.
316
  void InternalSeek(TrackType aTrack, const InternalSeekTarget& aTarget);
317
318
  // Drain the current decoder.
319
  void DrainDecoder(TrackType aTrack);
320
  void NotifyNewOutput(TrackType aTrack,
321
                       const MediaDataDecoder::DecodedData& aResults);
322
  void NotifyError(TrackType aTrack, const MediaResult& aError);
323
  void NotifyWaitingForData(TrackType aTrack);
324
  void NotifyWaitingForKey(TrackType aTrack);
325
  void NotifyEndOfStream(TrackType aTrack);
326
327
  void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
328
329
  // Initializes mLayersBackendType if possible.
330
  void InitLayersBackendType();
331
332
  void Reset(TrackType aTrack);
333
  void DropDecodedSamples(TrackType aTrack);
334
335
  bool ShouldSkip(media::TimeUnit aTimeThreshold);
336
337
  void SetVideoDecodeThreshold();
338
339
  size_t SizeOfQueue(TrackType aTrack);
340
341
  RefPtr<PDMFactory> mPlatform;
342
  RefPtr<PDMFactory> mEncryptedPlatform;
343
344
  enum class DrainState
345
  {
346
    None,
347
    DrainRequested,
348
    Draining,
349
    PartialDrainPending,
350
    DrainCompleted,
351
    DrainAborted,
352
  };
353
354
  class SharedShutdownPromiseHolder : public MozPromiseHolder<ShutdownPromise>
355
  {
356
    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedShutdownPromiseHolder)
357
  private:
358
0
    ~SharedShutdownPromiseHolder() { }
359
  };
360
361
  struct DecoderData
362
  {
363
    DecoderData(MediaFormatReader* aOwner,
364
                MediaData::Type aType,
365
                uint32_t aNumOfMaxError)
366
      : mOwner(aOwner)
367
      , mType(aType)
368
      , mMutex("DecoderData")
369
      , mDescription("shutdown")
370
      , mUpdateScheduled(false)
371
      , mDemuxEOS(false)
372
      , mWaitingForData(false)
373
      , mWaitingForKey(false)
374
      , mReceivedNewData(false)
375
      , mFlushing(false)
376
      , mFlushed(true)
377
      , mDrainState(DrainState::None)
378
      , mNumOfConsecutiveError(0)
379
      , mMaxConsecutiveError(aNumOfMaxError)
380
      , mFirstFrameTime(Some(media::TimeUnit::Zero()))
381
      , mNumSamplesInput(0)
382
      , mNumSamplesOutput(0)
383
      , mNumSamplesOutputTotal(0)
384
      , mNumSamplesSkippedTotal(0)
385
      , mSizeOfQueue(0)
386
      , mIsHardwareAccelerated(false)
387
      , mLastStreamSourceID(UINT32_MAX)
388
      , mIsNullDecode(false)
389
0
    {
390
0
      DecoderDoctorLogger::LogConstruction("MediaFormatReader::DecoderData",
391
0
                                           this);
392
0
    }
393
394
    ~DecoderData()
395
0
    {
396
0
      DecoderDoctorLogger::LogDestruction("MediaFormatReader::DecoderData",
397
0
                                          this);
398
0
    }
399
400
    MediaFormatReader* mOwner;
401
    // Disambiguate Audio vs Video.
402
    MediaData::Type mType;
403
    RefPtr<MediaTrackDemuxer> mTrackDemuxer;
404
    // TaskQueue on which decoder can choose to decode.
405
    // Only non-null up until the decoder is created.
406
    RefPtr<TaskQueue> mTaskQueue;
407
408
    // Mutex protecting mDescription and mDecoder.
409
    Mutex mMutex;
410
    // The platform decoder.
411
    RefPtr<MediaDataDecoder> mDecoder;
412
    nsCString mDescription;
413
    void ShutdownDecoder();
414
415
    // Only accessed from reader's task queue.
416
    bool mUpdateScheduled;
417
    bool mDemuxEOS;
418
    bool mWaitingForData;
419
    bool mWaitingForKey;
420
    bool mReceivedNewData;
421
422
    // Pending seek.
423
    MozPromiseRequestHolder<MediaTrackDemuxer::SeekPromise> mSeekRequest;
424
425
    // Queued demux samples waiting to be decoded.
426
    nsTArray<RefPtr<MediaRawData>> mQueuedSamples;
427
    MozPromiseRequestHolder<MediaTrackDemuxer::SamplesPromise> mDemuxRequest;
428
    // A WaitingPromise is pending if the demuxer is waiting for data or
429
    // if the decoder is waiting for a key.
430
    MozPromiseHolder<WaitForDataPromise> mWaitingPromise;
431
    bool HasWaitingPromise() const
432
0
    {
433
0
      MOZ_ASSERT(mOwner->OnTaskQueue());
434
0
      return !mWaitingPromise.IsEmpty();
435
0
    }
436
437
    bool IsWaitingForData() const
438
0
    {
439
0
      MOZ_ASSERT(mOwner->OnTaskQueue());
440
0
      return mWaitingForData;
441
0
    }
442
443
    bool IsWaitingForKey() const
444
0
    {
445
0
      MOZ_ASSERT(mOwner->OnTaskQueue());
446
0
      return mWaitingForKey && mDecodeRequest.Exists();
447
0
    }
448
449
    // MediaDataDecoder handler's variables.
450
    MozPromiseRequestHolder<MediaDataDecoder::DecodePromise> mDecodeRequest;
451
    bool mFlushing; // True if flush is in action.
452
    // Set to true if the last operation run on the decoder was a flush.
453
    bool mFlushed;
454
    RefPtr<SharedShutdownPromiseHolder> mShutdownPromise;
455
456
    MozPromiseRequestHolder<MediaDataDecoder::DecodePromise> mDrainRequest;
457
    DrainState mDrainState;
458
    bool HasPendingDrain() const
459
0
    {
460
0
      return mDrainState != DrainState::None;
461
0
    }
462
    bool HasCompletedDrain() const
463
0
    {
464
0
      return mDrainState == DrainState::DrainCompleted ||
465
0
             mDrainState == DrainState::DrainAborted;
466
0
    }
467
    void RequestDrain()
468
0
    {
469
0
        MOZ_RELEASE_ASSERT(mDrainState == DrainState::None);
470
0
        mDrainState = DrainState::DrainRequested;
471
0
    }
472
473
    uint32_t mNumOfConsecutiveError;
474
    uint32_t mMaxConsecutiveError;
475
    // Set when we haven't yet decoded the first frame.
476
    // Cleared once the first frame has been decoded.
477
    // This is used to determine, upon error, if we should try again to decode
478
    // the frame, or skip to the next keyframe.
479
    Maybe<media::TimeUnit> mFirstFrameTime;
480
481
    Maybe<MediaResult> mError;
482
    bool HasFatalError() const
483
0
    {
484
0
      if (!mError.isSome()) {
485
0
        return false;
486
0
      }
487
0
      if (mError.ref() == NS_ERROR_DOM_MEDIA_DECODE_ERR) {
488
0
        // Allow decode errors to be non-fatal, but give up
489
0
        // if we have too many, or if warnings should be treated as errors.
490
0
        return mNumOfConsecutiveError > mMaxConsecutiveError ||
491
0
               StaticPrefs::MediaPlaybackWarningsAsErrors();
492
0
      } else if (mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER) {
493
0
        // If the caller asked for a new decoder we shouldn't treat
494
0
        // it as fatal.
495
0
        return false;
496
0
      } else {
497
0
        // All other error types are fatal
498
0
        return true;
499
0
      }
500
0
    }
501
502
    // If set, all decoded samples prior mTimeThreshold will be dropped.
503
    // Used for internal seeking when a change of stream is detected or when
504
    // encountering data discontinuity.
505
    Maybe<InternalSeekTarget> mTimeThreshold;
506
    // Time of last decoded sample returned.
507
    Maybe<media::TimeInterval> mLastDecodedSampleTime;
508
509
    // Decoded samples returned my mDecoder awaiting being returned to
510
    // state machine upon request.
511
    nsTArray<RefPtr<MediaData>> mOutput;
512
    uint64_t mNumSamplesInput;
513
    uint64_t mNumSamplesOutput;
514
    uint64_t mNumSamplesOutputTotal;
515
    uint64_t mNumSamplesSkippedTotal;
516
517
    // These get overridden in the templated concrete class.
518
    // Indicate if we have a pending promise for decoded frame.
519
    // Rejecting the promise will stop the reader from decoding ahead.
520
    virtual bool HasPromise() const = 0;
521
    virtual void RejectPromise(const MediaResult& aError,
522
                               const char* aMethodName) = 0;
523
524
    // Clear track demuxer related data.
525
    void ResetDemuxer()
526
0
    {
527
0
      mDemuxRequest.DisconnectIfExists();
528
0
      mSeekRequest.DisconnectIfExists();
529
0
      mTrackDemuxer->Reset();
530
0
      mQueuedSamples.Clear();
531
0
    }
532
533
    // Flush the decoder if present and reset decoding related data.
534
    // Following a flush, the decoder is ready to accept any new data.
535
    void Flush();
536
537
    bool CancelWaitingForKey()
538
0
    {
539
0
      if (!mWaitingForKey) {
540
0
        return false;
541
0
      }
542
0
      mWaitingForKey = false;
543
0
      if (IsWaitingForData() || !HasWaitingPromise()) {
544
0
        return false;
545
0
      }
546
0
      mWaitingPromise.Resolve(mType, __func__);
547
0
      return true;
548
0
    }
549
550
    // Reset the state of the DecoderData, clearing all queued frames
551
    // (pending demuxed and decoded).
552
    // The track demuxer is *not* reset.
553
    void ResetState()
554
0
    {
555
0
      MOZ_ASSERT(mOwner->OnTaskQueue());
556
0
      mDemuxEOS = false;
557
0
      mWaitingForData = false;
558
0
      mQueuedSamples.Clear();
559
0
      mDecodeRequest.DisconnectIfExists();
560
0
      mDrainRequest.DisconnectIfExists();
561
0
      mDrainState = DrainState::None;
562
0
      CancelWaitingForKey();
563
0
      mTimeThreshold.reset();
564
0
      mLastDecodedSampleTime.reset();
565
0
      mOutput.Clear();
566
0
      mNumSamplesInput = 0;
567
0
      mNumSamplesOutput = 0;
568
0
      mSizeOfQueue = 0;
569
0
      mNextStreamSourceID.reset();
570
0
      if (!HasFatalError()) {
571
0
        mError.reset();
572
0
      }
573
0
    }
574
575
    bool HasInternalSeekPending() const
576
0
    {
577
0
      return mTimeThreshold && !mTimeThreshold.ref().mHasSeeked;
578
0
    }
579
580
    // Return the current TrackInfo in the stream. If the stream content never
581
    // changed since AsyncReadMetadata was called then the TrackInfo used is
582
    // mOriginalInfo, other it will be mInfo. The later case is only ever true
583
    // with MSE or the WebMDemuxer.
584
    const TrackInfo* GetCurrentInfo() const
585
0
    {
586
0
      if (mInfo) {
587
0
        return *mInfo;
588
0
      }
589
0
      return mOriginalInfo.get();
590
0
    }
591
    bool IsEncrypted() const
592
0
    {
593
0
      return GetCurrentInfo()->mCrypto.mValid;
594
0
    }
595
596
    // Used by the MDSM for logging purposes.
597
    Atomic<size_t> mSizeOfQueue;
598
    // Used by the MDSM to determine if video decoding is hardware accelerated.
599
    // This value is updated after a frame is successfully decoded.
600
    Atomic<bool> mIsHardwareAccelerated;
601
    // Sample format monitoring.
602
    uint32_t mLastStreamSourceID;
603
    Maybe<uint32_t> mNextStreamSourceID;
604
    media::TimeIntervals mTimeRanges;
605
    Maybe<media::TimeUnit> mLastTimeRangesEnd;
606
    // TrackInfo as first discovered during ReadMetadata.
607
    UniquePtr<TrackInfo> mOriginalInfo;
608
    RefPtr<TrackInfoSharedPtr> mInfo;
609
    Maybe<media::TimeUnit> mFirstDemuxedSampleTime;
610
    // Use NullDecoderModule or not.
611
    bool mIsNullDecode;
612
613
    class
614
    {
615
    public:
616
0
      float Mean() const { return mMean; }
617
618
      void Update(const media::TimeUnit& aValue)
619
0
      {
620
0
        if (aValue == media::TimeUnit::Zero()) {
621
0
          return;
622
0
        }
623
0
        mMean += (1.0f / aValue.ToSeconds() - mMean) / ++mCount;
624
0
      }
625
626
      void Reset()
627
0
      {
628
0
        mMean = 0;
629
0
        mCount = 0;
630
0
      }
631
632
    private:
633
      float mMean = 0;
634
      uint64_t mCount = 0;
635
    } mMeanRate;
636
  };
637
638
  template <typename Type>
639
  class DecoderDataWithPromise : public DecoderData
640
  {
641
  public:
642
    DecoderDataWithPromise(MediaFormatReader* aOwner,
643
                           MediaData::Type aType,
644
                           uint32_t aNumOfMaxError)
645
      : DecoderData(aOwner, aType, aNumOfMaxError)
646
      , mHasPromise(false)
647
0
    {
648
0
      DecoderDoctorLogger::LogConstructionAndBase(
649
0
        "MediaFormatReader::DecoderDataWithPromise",
650
0
        this,
651
0
        "MediaFormatReader::DecoderData",
652
0
        static_cast<const MediaFormatReader::DecoderData*>(this));
653
0
    }
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::AudioData>::DecoderDataWithPromise(mozilla::MediaFormatReader*, mozilla::MediaData::Type, unsigned int)
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::VideoData>::DecoderDataWithPromise(mozilla::MediaFormatReader*, mozilla::MediaData::Type, unsigned int)
654
655
    ~DecoderDataWithPromise()
656
0
    {
657
0
      DecoderDoctorLogger::LogDestruction(
658
0
        "MediaFormatReader::DecoderDataWithPromise", this);
659
0
    }
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::AudioData>::~DecoderDataWithPromise()
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::VideoData>::~DecoderDataWithPromise()
660
661
    bool HasPromise() const override
662
0
    {
663
0
      return mHasPromise;
664
0
    }
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::AudioData>::HasPromise() const
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::VideoData>::HasPromise() const
665
666
    RefPtr<DataPromise<Type>> EnsurePromise(const char* aMethodName)
667
0
    {
668
0
      MOZ_ASSERT(mOwner->OnTaskQueue());
669
0
      mHasPromise = true;
670
0
      return mPromise.Ensure(aMethodName);
671
0
    }
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::VideoData>::EnsurePromise(char const*)
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::AudioData>::EnsurePromise(char const*)
672
673
    void ResolvePromise(Type* aData, const char* aMethodName)
674
0
    {
675
0
      MOZ_ASSERT(mOwner->OnTaskQueue());
676
0
      mPromise.Resolve(aData, aMethodName);
677
0
      mHasPromise = false;
678
0
    }
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::AudioData>::ResolvePromise(mozilla::AudioData*, char const*)
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::VideoData>::ResolvePromise(mozilla::VideoData*, char const*)
679
680
    void RejectPromise(const MediaResult& aError,
681
                       const char* aMethodName) override
682
0
    {
683
0
      MOZ_ASSERT(mOwner->OnTaskQueue());
684
0
      mPromise.Reject(aError, aMethodName);
685
0
      mHasPromise = false;
686
0
    }
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::AudioData>::RejectPromise(mozilla::MediaResult const&, char const*)
Unexecuted instantiation: mozilla::MediaFormatReader::DecoderDataWithPromise<mozilla::VideoData>::RejectPromise(mozilla::MediaResult const&, char const*)
687
688
  private:
689
    MozPromiseHolder<DataPromise<Type>> mPromise;
690
    Atomic<bool> mHasPromise;
691
  };
692
693
  // Decode task queue.
694
  RefPtr<TaskQueue> mTaskQueue;
695
696
  DecoderDataWithPromise<AudioData> mAudio;
697
  DecoderDataWithPromise<VideoData> mVideo;
698
699
  // Returns true when the decoder for this track needs input.
700
  bool NeedInput(DecoderData& aDecoder);
701
702
  DecoderData& GetDecoderData(TrackType aTrack);
703
704
  // Demuxer objects.
705
  class DemuxerProxy;
706
  UniquePtr<DemuxerProxy> mDemuxer;
707
  bool mDemuxerInitDone;
708
  void OnDemuxerInitDone(const MediaResult& aResult);
709
  void OnDemuxerInitFailed(const MediaResult& aError);
710
  MozPromiseRequestHolder<MediaDataDemuxer::InitPromise> mDemuxerInitRequest;
711
  MozPromiseRequestHolder<NotifyDataArrivedPromise> mNotifyDataArrivedPromise;
712
  bool mPendingNotifyDataArrived;
713
  void OnDemuxFailed(TrackType aTrack, const MediaResult &aError);
714
715
  void DoDemuxVideo();
716
  void OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
717
  void OnVideoDemuxFailed(const MediaResult& aError)
718
0
  {
719
0
    OnDemuxFailed(TrackType::kVideoTrack, aError);
720
0
  }
721
722
  void DoDemuxAudio();
723
  void OnAudioDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
724
  void OnAudioDemuxFailed(const MediaResult& aError)
725
0
  {
726
0
    OnDemuxFailed(TrackType::kAudioTrack, aError);
727
0
  }
728
729
  void SkipVideoDemuxToNextKeyFrame(media::TimeUnit aTimeThreshold);
730
  MozPromiseRequestHolder<MediaTrackDemuxer::SkipAccessPointPromise> mSkipRequest;
731
  void VideoSkipReset(uint32_t aSkipped);
732
  void OnVideoSkipCompleted(uint32_t aSkipped);
733
  void OnVideoSkipFailed(MediaTrackDemuxer::SkipFailureHolder aFailure);
734
735
  // The last number of decoded output frames that we've reported to
736
  // MediaDecoder::NotifyDecoded(). We diff the number of output video
737
  // frames every time that DecodeVideoData() is called, and report the
738
  // delta there.
739
  uint64_t mLastReportedNumDecodedFrames;
740
741
  // Timestamp of the previous decoded keyframe, in microseconds.
742
  int64_t mPreviousDecodedKeyframeTime_us;
743
  // Default mLastDecodedKeyframeTime_us value, must be bigger than anything.
744
  static const int64_t sNoPreviousDecodedKeyframe = INT64_MAX;
745
746
  RefPtr<layers::KnowsCompositor> mKnowsCompositor;
747
748
  // Metadata objects
749
  // True if we've read the streams' metadata.
750
  bool mInitDone;
751
  MozPromiseHolder<MetadataPromise> mMetadataPromise;
752
  bool IsEncrypted() const;
753
754
  // Set to true if any of our track buffers may be blocking.
755
  bool mTrackDemuxersMayBlock;
756
757
  // Seeking objects.
758
  void SetSeekTarget(const SeekTarget& aTarget);
759
0
  bool IsSeeking() const { return mPendingSeekTime.isSome(); }
760
  bool IsVideoSeeking() const
761
0
  {
762
0
    return IsSeeking() && mOriginalSeekTarget.IsVideoOnly();
763
0
  }
764
  void ScheduleSeek();
765
  void AttemptSeek();
766
  void OnSeekFailed(TrackType aTrack, const MediaResult& aError);
767
  void DoVideoSeek();
768
  void OnVideoSeekCompleted(media::TimeUnit aTime);
769
  void OnVideoSeekFailed(const MediaResult& aError);
770
  bool mSeekScheduled;
771
772
  void DoAudioSeek();
773
  void OnAudioSeekCompleted(media::TimeUnit aTime);
774
  void OnAudioSeekFailed(const MediaResult& aError);
775
  // The SeekTarget that was last given to Seek()
776
  SeekTarget mOriginalSeekTarget;
777
  // Temporary seek information while we wait for the data
778
  Maybe<media::TimeUnit> mFallbackSeekTime;
779
  Maybe<media::TimeUnit> mPendingSeekTime;
780
  MozPromiseHolder<SeekPromise> mSeekPromise;
781
782
  RefPtr<VideoFrameContainer> mVideoFrameContainer;
783
  layers::ImageContainer* GetImageContainer();
784
785
  RefPtr<CDMProxy> mCDMProxy;
786
787
  RefPtr<GMPCrashHelper> mCrashHelper;
788
789
  void SetNullDecode(TrackType aTrack, bool aIsNullDecode);
790
791
  class DecoderFactory;
792
  UniquePtr<DecoderFactory> mDecoderFactory;
793
794
  class ShutdownPromisePool;
795
  UniquePtr<ShutdownPromisePool> mShutdownPromisePool;
796
797
  MediaEventListener mOnTrackWaitingForKeyListener;
798
799
  void OnFirstDemuxCompleted(TrackInfo::TrackType aType,
800
                             RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
801
802
  void OnFirstDemuxFailed(TrackInfo::TrackType aType, const MediaResult& aError);
803
804
  void MaybeResolveMetadataPromise();
805
806
  // Stores presentation info required for playback.
807
  MediaInfo mInfo;
808
809
  UniquePtr<MetadataTags> mTags;
810
811
  // A flag indicating if the start time is known or not.
812
  bool mHasStartTime = false;
813
814
  void ShutdownDecoder(TrackType aTrack);
815
  RefPtr<ShutdownPromise> TearDownDecoders();
816
817
  bool mShutdown = false;
818
819
  // Buffered range.
820
  Canonical<media::TimeIntervals> mBuffered;
821
822
  // Used to send TimedMetadata to the listener.
823
  TimedMetadataEventProducer mTimedMetadataEvent;
824
825
  // Notify if this media is not seekable.
826
  MediaEventProducer<void> mOnMediaNotSeekable;
827
828
  // Notify if we are waiting for a decryption key.
829
  MediaEventProducer<TrackInfo::TrackType> mOnTrackWaitingForKey;
830
831
  MediaEventProducer<nsTArray<uint8_t>, nsString> mOnEncrypted;
832
833
  MediaEventProducer<void> mOnWaitingForKey;
834
835
  MediaEventProducer<MediaResult> mOnDecodeWarning;
836
837
  RefPtr<FrameStatistics> mFrameStats;
838
839
  // Used in bug 1393399 for telemetry.
840
  const MediaDecoderOwnerID mMediaDecoderOwnerID;
841
842
  bool ResolveSetCDMPromiseIfDone(TrackType aTrack);
843
  void PrepareToSetCDMForTrack(TrackType aTrack);
844
  MozPromiseHolder<SetCDMPromise> mSetCDMPromise;
845
  TrackSet mSetCDMForTracks{};
846
  bool IsDecoderWaitingForCDM(TrackType aTrack);
847
};
848
849
} // namespace mozilla
850
851
#endif