Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #ifndef MP3_DEMUXER_H_
6 : #define MP3_DEMUXER_H_
7 :
8 : #include "MediaDataDemuxer.h"
9 : #include "MediaResource.h"
10 : #include "MP3FrameParser.h"
11 :
12 : namespace mozilla {
13 :
14 : class MP3TrackDemuxer;
15 :
16 0 : class MP3Demuxer : public MediaDataDemuxer
17 : {
18 : public:
19 : // MediaDataDemuxer interface.
20 : explicit MP3Demuxer(MediaResource* aSource);
21 : RefPtr<InitPromise> Init() override;
22 : bool HasTrackType(TrackInfo::TrackType aType) const override;
23 : uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
24 : already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
25 : TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
26 : bool IsSeekable() const override;
27 : void NotifyDataArrived() override;
28 : void NotifyDataRemoved() override;
29 :
30 : private:
31 : // Synchronous initialization.
32 : bool InitInternal();
33 :
34 : RefPtr<MediaResource> mSource;
35 : RefPtr<MP3TrackDemuxer> mTrackDemuxer;
36 : };
37 :
38 : // The MP3 demuxer used to extract MPEG frames and side information out of
39 : // MPEG streams.
40 : class MP3TrackDemuxer : public MediaTrackDemuxer
41 : {
42 : public:
43 : // Constructor, expecting a valid media resource.
44 : explicit MP3TrackDemuxer(MediaResource* aSource);
45 :
46 : // Initializes the track demuxer by reading the first frame for meta data.
47 : // Returns initialization success state.
48 : bool Init();
49 :
50 : // Returns the total stream length if known, -1 otherwise.
51 : int64_t StreamLength() const;
52 :
53 : // Returns the estimated stream duration, or a 0-duration if unknown.
54 : media::TimeUnit Duration() const;
55 :
56 : // Returns the estimated duration up to the given frame number,
57 : // or a 0-duration if unknown.
58 : media::TimeUnit Duration(int64_t aNumFrames) const;
59 :
60 : // Returns the estimated current seek position time.
61 : media::TimeUnit SeekPosition() const;
62 :
63 : const FrameParser::Frame& LastFrame() const;
64 : RefPtr<MediaRawData> DemuxSample();
65 :
66 : const ID3Parser::ID3Header& ID3Header() const;
67 : const FrameParser::VBRHeader& VBRInfo() const;
68 :
69 : // MediaTrackDemuxer interface.
70 : UniquePtr<TrackInfo> GetInfo() const override;
71 : RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override;
72 : RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override;
73 : void Reset() override;
74 : RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
75 : const media::TimeUnit& aTimeThreshold) override;
76 : int64_t GetResourceOffset() const override;
77 : media::TimeIntervals GetBuffered() override;
78 :
79 : private:
80 : // Destructor.
81 0 : ~MP3TrackDemuxer() {}
82 :
83 : // Fast approximate seeking to given time.
84 : media::TimeUnit FastSeek(const media::TimeUnit& aTime);
85 :
86 : // Seeks by scanning the stream up to the given time for more accurate results.
87 : media::TimeUnit ScanUntil(const media::TimeUnit& aTime);
88 :
89 : // Finds the first valid frame and returns its byte range if found
90 : // or a null-byte range otherwise.
91 : MediaByteRange FindFirstFrame();
92 :
93 : // Finds the next valid frame and returns its byte range if found
94 : // or a null-byte range otherwise.
95 : MediaByteRange FindNextFrame();
96 :
97 : // Skips the next frame given the provided byte range.
98 : bool SkipNextFrame(const MediaByteRange& aRange);
99 :
100 : // Returns the next MPEG frame, if available.
101 : already_AddRefed<MediaRawData> GetNextFrame(const MediaByteRange& aRange);
102 :
103 : // Updates post-read meta data.
104 : void UpdateState(const MediaByteRange& aRange);
105 :
106 : // Returns the estimated offset for the given frame index.
107 : int64_t OffsetFromFrameIndex(int64_t aFrameIndex) const;
108 :
109 : // Returns the estimated frame index for the given offset.
110 : int64_t FrameIndexFromOffset(int64_t aOffset) const;
111 :
112 : // Returns the estimated frame index for the given time.
113 : int64_t FrameIndexFromTime(const media::TimeUnit& aTime) const;
114 :
115 : // Reads aSize bytes into aBuffer from the source starting at aOffset.
116 : // Returns the actual size read.
117 : int32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize);
118 :
119 : // Returns the average frame length derived from the previously parsed frames.
120 : double AverageFrameLength() const;
121 :
122 : // The (hopefully) MPEG resource.
123 : MediaResourceIndex mSource;
124 :
125 : // MPEG frame parser used to detect frames and extract side info.
126 : FrameParser mParser;
127 :
128 : // Whether we've locked onto a valid sequence of frames or not.
129 : bool mFrameLock;
130 :
131 : // Current byte offset in the source stream.
132 : int64_t mOffset;
133 :
134 : // Byte offset of the begin of the first frame, or 0 if none parsed yet.
135 : int64_t mFirstFrameOffset;
136 :
137 : // Total parsed frames.
138 : uint64_t mNumParsedFrames;
139 :
140 : // Current frame index.
141 : int64_t mFrameIndex;
142 :
143 : // Sum of parsed frames' lengths in bytes.
144 : uint64_t mTotalFrameLen;
145 :
146 : // Samples per frame metric derived from frame headers or 0 if none available.
147 : int32_t mSamplesPerFrame;
148 :
149 : // Samples per second metric derived from frame headers or 0 if none available.
150 : int32_t mSamplesPerSecond;
151 :
152 : // Channel count derived from frame headers or 0 if none available.
153 : int32_t mChannels;
154 :
155 : // Audio track config info.
156 : UniquePtr<AudioInfo> mInfo;
157 : };
158 :
159 : } // namespace mozilla
160 :
161 : #endif
|