Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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(MediaDataDemuxer_h)
8 : #define MediaDataDemuxer_h
9 :
10 : #include "mozilla/MozPromise.h"
11 : #include "mozilla/UniquePtr.h"
12 :
13 : #include "MediaData.h"
14 : #include "MediaInfo.h"
15 : #include "MediaResult.h"
16 : #include "TimeUnits.h"
17 : #include "nsISupportsImpl.h"
18 : #include "mozilla/RefPtr.h"
19 : #include "nsTArray.h"
20 :
21 : namespace mozilla {
22 :
23 : class MediaTrackDemuxer;
24 : class TrackMetadataHolder;
25 :
26 : // Allows reading the media data: to retrieve the metadata and demux samples.
27 : // MediaDataDemuxer isn't designed to be thread safe.
28 : // When used by the MediaFormatDecoder, care is taken to ensure that the demuxer
29 : // will never be called from more than one thread at once.
30 0 : class MediaDataDemuxer
31 : {
32 : public:
33 0 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDemuxer)
34 :
35 : typedef
36 : MozPromise<MediaResult, MediaResult, /* IsExclusive = */ true> InitPromise;
37 :
38 : // Initializes the demuxer. Other methods cannot be called unless
39 : // initialization has completed and succeeded.
40 : // Typically a demuxer will wait to parse the metadata before resolving the
41 : // promise. The promise must not be resolved until sufficient data is
42 : // supplied. For example, an incomplete metadata would cause the promise to be
43 : // rejected should no more data be coming, while the demuxer would wait
44 : // otherwise.
45 : virtual RefPtr<InitPromise> Init() = 0;
46 :
47 : // Returns true if a aType track type is available.
48 : virtual bool HasTrackType(TrackInfo::TrackType aType) const = 0;
49 :
50 : // Returns the number of tracks of aType type available. A value of
51 : // 0 indicates that no such type is available.
52 : virtual uint32_t GetNumberTracks(TrackInfo::TrackType aType) const = 0;
53 :
54 : // Returns the MediaTrackDemuxer associated with aTrackNumber aType track.
55 : // aTrackNumber is not to be confused with the Track ID.
56 : // aTrackNumber must be constrained between 0 and GetNumberTracks(aType) - 1
57 : // The actual Track ID is to be retrieved by calling
58 : // MediaTrackDemuxer::TrackInfo.
59 : virtual already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
60 : TrackInfo::TrackType aType, uint32_t aTrackNumber) = 0;
61 :
62 : // Returns true if the underlying resource allows seeking.
63 : virtual bool IsSeekable() const = 0;
64 :
65 : // Returns true if the underlying resource can only seek within buffered
66 : // ranges.
67 0 : virtual bool IsSeekableOnlyInBufferedRanges() const { return false; }
68 :
69 : // Returns the media's crypto information, or nullptr if media isn't
70 : // encrypted.
71 0 : virtual UniquePtr<EncryptionInfo> GetCrypto()
72 : {
73 0 : return nullptr;
74 : }
75 :
76 : // Notifies the demuxer that the underlying resource has received more data
77 : // since the demuxer was initialized.
78 : // The demuxer can use this mechanism to inform all track demuxers that new
79 : // data is available and to refresh its buffered range.
80 0 : virtual void NotifyDataArrived() { }
81 :
82 : // Notifies the demuxer that the underlying resource has had data removed
83 : // since the demuxer was initialized.
84 : // The demuxer can use this mechanism to inform all track demuxers to update
85 : // its buffered range.
86 : // This will be called should the demuxer be used with MediaSourceResource.
87 0 : virtual void NotifyDataRemoved() { }
88 :
89 : // Indicate to MediaFormatReader if it should compute the start time
90 : // of the demuxed data. If true (default) the first sample returned will be
91 : // used as reference time base.
92 0 : virtual bool ShouldComputeStartTime() const { return true; }
93 :
94 : protected:
95 0 : virtual ~MediaDataDemuxer()
96 0 : {
97 0 : }
98 : };
99 :
100 0 : class MediaTrackDemuxer
101 : {
102 : public:
103 0 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTrackDemuxer)
104 :
105 0 : class SamplesHolder
106 : {
107 : public:
108 0 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SamplesHolder)
109 : nsTArray<RefPtr<MediaRawData>> mSamples;
110 : private:
111 0 : ~SamplesHolder() { }
112 : };
113 :
114 0 : class SkipFailureHolder
115 : {
116 : public:
117 0 : SkipFailureHolder(const MediaResult& aFailure, uint32_t aSkipped)
118 0 : : mFailure(aFailure)
119 0 : , mSkipped(aSkipped)
120 0 : {}
121 : MediaResult mFailure;
122 : uint32_t mSkipped;
123 : };
124 :
125 : typedef MozPromise<media::TimeUnit, MediaResult, /* IsExclusive = */ true>
126 : SeekPromise;
127 : typedef MozPromise<RefPtr<SamplesHolder>, MediaResult,
128 : /* IsExclusive = */ true>
129 : SamplesPromise;
130 : typedef MozPromise<uint32_t, SkipFailureHolder, /* IsExclusive = */ true>
131 : SkipAccessPointPromise;
132 :
133 : // Returns the TrackInfo (a.k.a Track Description) for this track.
134 : // The TrackInfo returned will be:
135 : // TrackInfo::kVideoTrack -> VideoInfo.
136 : // TrackInfo::kAudioTrack -> AudioInfo.
137 : // respectively.
138 : virtual UniquePtr<TrackInfo> GetInfo() const = 0;
139 :
140 : // Seeks to aTime. Upon success, SeekPromise will be resolved with the
141 : // actual time seeked to. Typically the random access point time
142 : virtual RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) = 0;
143 :
144 : // Returns the next aNumSamples sample(s) available.
145 : // If only a lesser amount of samples is available, only those will be
146 : // returned.
147 : // A aNumSamples value of -1 indicates to return all remaining samples.
148 : // A video sample is typically made of a single video frame while an audio
149 : // sample will contains multiple audio frames.
150 : virtual RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) = 0;
151 :
152 : // Returns true if a call to GetSamples() may block while waiting on the
153 : // underlying resource to return the data.
154 : // This is used by the MediaFormatReader to determine if buffering heuristics
155 : // should be used.
156 0 : virtual bool GetSamplesMayBlock() const
157 : {
158 0 : return true;
159 : }
160 :
161 : // Cancel all pending actions (Seek, GetSamples) and reset current state
162 : // All pending promises are to be rejected with CANCEL.
163 : // The next call to GetSamples would return the first sample available in the
164 : // track.
165 : virtual void Reset() = 0;
166 :
167 : // Returns timestamp of next random access point or an error if the demuxer
168 : // can't report this.
169 0 : virtual nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime)
170 : {
171 0 : return NS_ERROR_NOT_IMPLEMENTED;
172 : }
173 :
174 : // Returns timestamp of previous random access point or an error if the
175 : // demuxer can't report this.
176 0 : virtual nsresult GetPreviousRandomAccessPoint(media::TimeUnit* aTime)
177 : {
178 0 : return NS_ERROR_NOT_IMPLEMENTED;
179 : }
180 :
181 : // Skip frames until the next Random Access Point located after
182 : // aTimeThreshold.
183 : // The first frame returned by the next call to GetSamples() will be the
184 : // first random access point found after aTimeThreshold.
185 : // Upon success, returns the number of frames skipped.
186 : virtual RefPtr<SkipAccessPointPromise>
187 : SkipToNextRandomAccessPoint(const media::TimeUnit& aTimeThreshold) = 0;
188 :
189 : // Gets the resource's offset used for the last Seek() or GetSample().
190 : // A negative value indicates that this functionality isn't supported.
191 0 : virtual int64_t GetResourceOffset() const
192 : {
193 0 : return -1;
194 : }
195 :
196 0 : virtual TrackInfo::TrackType GetType() const
197 : {
198 0 : return GetInfo()->GetType();
199 : }
200 :
201 : virtual media::TimeIntervals GetBuffered() = 0;
202 :
203 : // By default, it is assumed that the entire resource can be evicted once
204 : // all samples have been demuxed.
205 0 : virtual int64_t GetEvictionOffset(const media::TimeUnit& aTime)
206 : {
207 0 : return INT64_MAX;
208 : }
209 :
210 : // If the MediaTrackDemuxer and MediaDataDemuxer hold cross references.
211 : // BreakCycles must be overridden.
212 0 : virtual void BreakCycles()
213 : {
214 0 : }
215 :
216 : protected:
217 0 : virtual ~MediaTrackDemuxer() { }
218 : };
219 :
220 : } // namespace mozilla
221 :
222 : #endif // MediaDataDemuxer_h
|