MP3Demuxer.h (6083B)
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 "MP3FrameParser.h" 9 #include "MediaDataDemuxer.h" 10 #include "MediaResource.h" 11 12 namespace mozilla { 13 14 class MP3TrackDemuxer; 15 16 DDLoggedTypeDeclNameAndBase(MP3Demuxer, MediaDataDemuxer); 17 DDLoggedTypeNameAndBase(MP3TrackDemuxer, MediaTrackDemuxer); 18 19 class MP3Demuxer : public MediaDataDemuxer, 20 public DecoderDoctorLifeLogger<MP3Demuxer> { 21 public: 22 // MediaDataDemuxer interface. 23 explicit MP3Demuxer(MediaResource* aSource); 24 RefPtr<InitPromise> Init() override; 25 uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override; 26 already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer( 27 TrackInfo::TrackType aType, uint32_t aTrackNumber) override; 28 bool IsSeekable() const override; 29 void NotifyDataArrived() override; 30 void NotifyDataRemoved() override; 31 32 private: 33 // Synchronous initialization. 34 bool InitInternal(); 35 36 RefPtr<MediaResource> mSource; 37 RefPtr<MP3TrackDemuxer> mTrackDemuxer; 38 }; 39 40 // The MP3 demuxer used to extract MPEG frames and side information out of 41 // MPEG streams. 42 class MP3TrackDemuxer : public MediaTrackDemuxer, 43 public DecoderDoctorLifeLogger<MP3TrackDemuxer> { 44 public: 45 // Constructor, expecting a valid media resource. 46 explicit MP3TrackDemuxer(MediaResource* aSource); 47 48 // Initializes the track demuxer by reading the first frame for meta data. 49 // Returns initialization success state. 50 bool Init(); 51 52 // Returns the total stream length if known, -1 otherwise. 53 int64_t StreamLength() const; 54 55 // Returns the estimated stream duration, or a 0-duration if unknown. 56 media::NullableTimeUnit Duration() const; 57 58 // Returns the estimated duration up to the given frame number, 59 // or a 0-duration if unknown. 60 media::TimeUnit Duration(int64_t aNumFrames) const; 61 62 // Returns the estimated current seek position time. 63 media::TimeUnit SeekPosition() const; 64 65 const FrameParser::Frame& LastFrame() const; 66 RefPtr<MediaRawData> DemuxSample(); 67 68 const ID3Parser::ID3Header& ID3Header() const; 69 const FrameParser::VBRHeader& VBRInfo() const; 70 71 // MediaTrackDemuxer interface. 72 UniquePtr<TrackInfo> GetInfo() const override; 73 RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override; 74 RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override; 75 void Reset() override; 76 RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint( 77 const media::TimeUnit& aTimeThreshold) override; 78 int64_t GetResourceOffset() const override; 79 media::TimeIntervals GetBuffered() override; 80 // Return the duration in frames of the encoder delay. 81 uint32_t EncoderDelayFrames() const; 82 // Return the duration in frames of the padding. 83 uint32_t PaddingFrames() const; 84 85 private: 86 // Destructor. 87 ~MP3TrackDemuxer() = default; 88 89 // Fast approximate seeking to given time. 90 media::TimeUnit FastSeek(const media::TimeUnit& aTime); 91 92 // Seeks by scanning the stream up to the given time for more accurate 93 // results. 94 media::TimeUnit ScanUntil(const media::TimeUnit& aTime); 95 96 // Finds the first valid frame and returns its byte range if found 97 // or a null-byte range otherwise. 98 MediaByteRange FindFirstFrame(); 99 100 // Finds the next valid frame and returns its byte range if found 101 // or a null-byte range otherwise. 102 MediaByteRange FindNextFrame(); 103 104 // Skips the next frame given the provided byte range. 105 bool SkipNextFrame(const MediaByteRange& aRange); 106 107 // Returns the next MPEG frame, if available. 108 already_AddRefed<MediaRawData> GetNextFrame(const MediaByteRange& aRange); 109 110 // Updates post-read meta data. 111 void UpdateState(const MediaByteRange& aRange); 112 113 // Returns the estimated offset for the given frame index. 114 int64_t OffsetFromFrameIndex(int64_t aFrameIndex) const; 115 116 // Returns the estimated frame index for the given offset. 117 int64_t FrameIndexFromOffset(int64_t aOffset) const; 118 119 // Returns the estimated frame index for the given time. 120 int64_t FrameIndexFromTime(const media::TimeUnit& aTime) const; 121 122 // Reads aSize bytes into aBuffer from the source starting at aOffset. 123 // Returns the actual size read. 124 uint32_t Read(uint8_t* aBuffer, int64_t aOffset, uint32_t aSize); 125 126 // Returns the average frame length derived from the previously parsed frames. 127 double AverageFrameLength() const; 128 129 // Returns the number of frames reported by the header if it's valid. Nothing 130 // otherwise. 131 Maybe<uint32_t> ValidNumAudioFrames() const; 132 133 // Return the duration of the encoder delay. 134 media::TimeUnit EncoderDelay() const; 135 136 // Return the duration of the padding. 137 media::TimeUnit Padding() const; 138 139 // The (hopefully) MPEG resource. 140 MediaResourceIndex mSource; 141 142 // MPEG frame parser used to detect frames and extract side info. 143 FrameParser mParser; 144 145 // Whether we've locked onto a valid sequence of frames or not. 146 bool mFrameLock; 147 148 // Current byte offset in the source stream. 149 int64_t mOffset; 150 151 // Byte offset of the begin of the first frame, or 0 if none parsed yet. 152 int64_t mFirstFrameOffset; 153 154 // Total parsed frames. 155 uint64_t mNumParsedFrames; 156 157 // Current frame index. 158 int64_t mFrameIndex; 159 160 // Sum of parsed frames' lengths in bytes. 161 int64_t mTotalFrameLen; 162 163 // Samples per frame metric derived from frame headers or 0 if none available. 164 uint32_t mSamplesPerFrame; 165 166 // Samples per second metric derived from frame headers or 0 if none 167 // available. 168 uint32_t mSamplesPerSecond; 169 170 // Channel count derived from frame headers or 0 if none available. 171 uint32_t mChannels; 172 173 // Audio track config info. 174 UniquePtr<AudioInfo> mInfo; 175 176 // Number of frames to skip at the beginning 177 uint32_t mEncoderDelay = 0; 178 // Number of frames to skip at the end 179 uint32_t mEncoderPadding = 0; 180 int32_t mRemainingEncoderPadding = 0; 181 // End of stream has been found 182 bool mEOS = false; 183 }; 184 185 } // namespace mozilla 186 187 #endif