summaryrefslogtreecommitdiffstats
path: root/dom/media/MediaDataDemuxer.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/MediaDataDemuxer.h')
-rw-r--r--dom/media/MediaDataDemuxer.h213
1 files changed, 213 insertions, 0 deletions
diff --git a/dom/media/MediaDataDemuxer.h b/dom/media/MediaDataDemuxer.h
new file mode 100644
index 0000000000..79ef5f5f0a
--- /dev/null
+++ b/dom/media/MediaDataDemuxer.h
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if !defined(MediaDataDemuxer_h)
+# define MediaDataDemuxer_h
+
+# include "DecoderDoctorLogger.h"
+# include "mozilla/MozPromise.h"
+# include "mozilla/UniquePtr.h"
+
+# include "MediaData.h"
+# include "MediaInfo.h"
+# include "MediaResult.h"
+# include "TimeUnits.h"
+# include "nsISupportsImpl.h"
+# include "mozilla/RefPtr.h"
+# include "nsTArray.h"
+
+namespace mozilla {
+
+class MediaTrackDemuxer;
+class TrackMetadataHolder;
+
+DDLoggedTypeDeclName(MediaDataDemuxer);
+DDLoggedTypeName(MediaTrackDemuxer);
+
+// Allows reading the media data: to retrieve the metadata and demux samples.
+// MediaDataDemuxer isn't designed to be thread safe.
+// When used by the MediaFormatDecoder, care is taken to ensure that the demuxer
+// will never be called from more than one thread at once.
+class MediaDataDemuxer : public DecoderDoctorLifeLogger<MediaDataDemuxer> {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDemuxer)
+
+ typedef MozPromise<MediaResult, MediaResult, /* IsExclusive = */ false>
+ InitPromise;
+
+ // Initializes the demuxer. Other methods cannot be called unless
+ // initialization has completed and succeeded.
+ // Typically a demuxer will wait to parse the metadata before resolving the
+ // promise. The promise must not be resolved until sufficient data is
+ // supplied. For example, an incomplete metadata would cause the promise to be
+ // rejected should no more data be coming, while the demuxer would wait
+ // otherwise.
+ virtual RefPtr<InitPromise> Init() = 0;
+
+ // Returns the number of tracks of aType type available. A value of
+ // 0 indicates that no such type is available.
+ virtual uint32_t GetNumberTracks(TrackInfo::TrackType aType) const = 0;
+
+ // Returns the MediaTrackDemuxer associated with aTrackNumber aType track.
+ // aTrackNumber is not to be confused with the Track ID.
+ // aTrackNumber must be constrained between 0 and GetNumberTracks(aType) - 1
+ // The actual Track ID is to be retrieved by calling
+ // MediaTrackDemuxer::TrackInfo.
+ virtual already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
+ TrackInfo::TrackType aType, uint32_t aTrackNumber) = 0;
+
+ // Returns true if the underlying resource allows seeking.
+ virtual bool IsSeekable() const = 0;
+
+ // Returns true if the underlying resource can only seek within buffered
+ // ranges.
+ virtual bool IsSeekableOnlyInBufferedRanges() const { return false; }
+
+ // Returns the media's crypto information, or nullptr if media isn't
+ // encrypted.
+ virtual UniquePtr<EncryptionInfo> GetCrypto() { return nullptr; }
+
+ // Notifies the demuxer that the underlying resource has received more data
+ // since the demuxer was initialized.
+ // The demuxer can use this mechanism to inform all track demuxers that new
+ // data is available and to refresh its buffered range.
+ virtual void NotifyDataArrived() {}
+
+ // Notifies the demuxer that the underlying resource has had data removed
+ // since the demuxer was initialized.
+ // The demuxer can use this mechanism to inform all track demuxers to update
+ // its buffered range.
+ // This will be called should the demuxer be used with MediaSource.
+ virtual void NotifyDataRemoved() {}
+
+ // Indicate to MediaFormatReader if it should compute the start time
+ // of the demuxed data. If true (default) the first sample returned will be
+ // used as reference time base.
+ virtual bool ShouldComputeStartTime() const { return true; }
+
+ protected:
+ virtual ~MediaDataDemuxer() = default;
+};
+
+class MediaTrackDemuxer : public DecoderDoctorLifeLogger<MediaTrackDemuxer> {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTrackDemuxer)
+
+ class SamplesHolder {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SamplesHolder)
+
+ void AppendSample(RefPtr<MediaRawData>& aSample) {
+ MOZ_DIAGNOSTIC_ASSERT(aSample->HasValidTime());
+ mSamples.AppendElement(aSample);
+ }
+
+ const nsTArray<RefPtr<MediaRawData>>& GetSamples() const {
+ return mSamples;
+ }
+
+ // This method is only used to do the move semantic for mSamples, do not
+ // append any element to the samples we returns. We should always append new
+ // sample to mSamples via `AppendSample()`.
+ nsTArray<RefPtr<MediaRawData>>& GetMovableSamples() { return mSamples; }
+
+ private:
+ ~SamplesHolder() = default;
+ nsTArray<RefPtr<MediaRawData>> mSamples;
+ };
+
+ class SkipFailureHolder {
+ public:
+ SkipFailureHolder(const MediaResult& aFailure, uint32_t aSkipped)
+ : mFailure(aFailure), mSkipped(aSkipped) {}
+ MediaResult mFailure;
+ uint32_t mSkipped;
+ };
+
+ typedef MozPromise<media::TimeUnit, MediaResult, /* IsExclusive = */ true>
+ SeekPromise;
+ typedef MozPromise<RefPtr<SamplesHolder>, MediaResult,
+ /* IsExclusive = */ true>
+ SamplesPromise;
+ typedef MozPromise<uint32_t, SkipFailureHolder, /* IsExclusive = */ true>
+ SkipAccessPointPromise;
+
+ // Returns the TrackInfo (a.k.a Track Description) for this track.
+ // The TrackInfo returned will be:
+ // TrackInfo::kVideoTrack -> VideoInfo.
+ // TrackInfo::kAudioTrack -> AudioInfo.
+ // respectively.
+ virtual UniquePtr<TrackInfo> GetInfo() const = 0;
+
+ // Seeks to aTime. Upon success, SeekPromise will be resolved with the
+ // actual time seeked to. Typically the random access point time
+ virtual RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) = 0;
+
+ // Returns the next aNumSamples sample(s) available.
+ // If only a lesser amount of samples is available, only those will be
+ // returned.
+ // A aNumSamples value of -1 indicates to return all remaining samples.
+ // A video sample is typically made of a single video frame while an audio
+ // sample will contains multiple audio frames.
+ virtual RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) = 0;
+
+ // Returns true if a call to GetSamples() may block while waiting on the
+ // underlying resource to return the data.
+ // This is used by the MediaFormatReader to determine if buffering heuristics
+ // should be used.
+ virtual bool GetSamplesMayBlock() const { return true; }
+
+ // Cancel all pending actions (Seek, GetSamples) and reset current state
+ // All pending promises are to be rejected with CANCEL.
+ // The next call to GetSamples would return the first sample available in the
+ // track.
+ virtual void Reset() = 0;
+
+ // Returns timestamp of next random access point or an error if the demuxer
+ // can't report this.
+ virtual nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ // Returns timestamp of previous random access point or an error if the
+ // demuxer can't report this.
+ virtual nsresult GetPreviousRandomAccessPoint(media::TimeUnit* aTime) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ // Skip frames until the next Random Access Point located after
+ // aTimeThreshold.
+ // The first frame returned by the next call to GetSamples() will be the
+ // first random access point found after aTimeThreshold.
+ // Upon success, returns the number of frames skipped.
+ virtual RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
+ const media::TimeUnit& aTimeThreshold) = 0;
+
+ // Gets the resource's offset used for the last Seek() or GetSample().
+ // A negative value indicates that this functionality isn't supported.
+ virtual int64_t GetResourceOffset() const { return -1; }
+
+ virtual TrackInfo::TrackType GetType() const { return GetInfo()->GetType(); }
+
+ virtual media::TimeIntervals GetBuffered() = 0;
+
+ // By default, it is assumed that the entire resource can be evicted once
+ // all samples have been demuxed.
+ virtual int64_t GetEvictionOffset(const media::TimeUnit& aTime) {
+ return INT64_MAX;
+ }
+
+ // If the MediaTrackDemuxer and MediaDataDemuxer hold cross references.
+ // BreakCycles must be overridden.
+ virtual void BreakCycles() {}
+
+ protected:
+ virtual ~MediaTrackDemuxer() = default;
+};
+
+} // namespace mozilla
+
+#endif // MediaDataDemuxer_h