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 #ifndef FLAC_DEMUXER_H_ 8 #define FLAC_DEMUXER_H_ 9 10 #include "mozilla/Attributes.h" 11 #include "MediaDataDemuxer.h" 12 #include "MediaResource.h" 13 namespace mozilla { 14 15 namespace flac { 16 class Frame; 17 class FrameParser; 18 } // namespace flac 19 class FlacTrackDemuxer; 20 21 DDLoggedTypeDeclNameAndBase(FlacDemuxer, MediaDataDemuxer); 22 DDLoggedTypeNameAndBase(FlacTrackDemuxer, MediaTrackDemuxer); 23 24 class FlacDemuxer : public MediaDataDemuxer, 25 public DecoderDoctorLifeLogger<FlacDemuxer> { 26 public: 27 // MediaDataDemuxer interface. 28 explicit FlacDemuxer(MediaResource* aSource); 29 RefPtr<InitPromise> Init() override; 30 uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override; 31 already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer( 32 TrackInfo::TrackType aType, uint32_t aTrackNumber) override; 33 bool IsSeekable() const override; 34 35 // Return true if a valid flac frame header could be found. 36 static bool FlacSniffer(const uint8_t* aData, const uint32_t aLength); 37 38 private: 39 bool InitInternal(); 40 41 RefPtr<MediaResource> mSource; 42 RefPtr<FlacTrackDemuxer> mTrackDemuxer; 43 }; 44 45 class FlacTrackDemuxer : public MediaTrackDemuxer, 46 public DecoderDoctorLifeLogger<FlacTrackDemuxer> { 47 public: 48 explicit FlacTrackDemuxer(MediaResource* aSource); 49 50 // Initializes the track demuxer by reading the first frame for meta data. 51 // Returns initialization success state. 52 bool Init(); 53 54 // MediaTrackDemuxer interface. 55 UniquePtr<TrackInfo> GetInfo() const override; 56 RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override; 57 RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override; 58 void Reset() override; 59 int64_t GetResourceOffset() const override; 60 media::TimeIntervals GetBuffered() override; 61 RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint( 62 const media::TimeUnit& aTimeThreshold) override; 63 64 bool IsSeekable() const; 65 66 private: 67 // Destructor. 68 ~FlacTrackDemuxer(); 69 70 // Returns the estimated stream duration, or a 0-duration if unknown. 71 media::TimeUnit Duration() const; 72 media::TimeUnit TimeAtEnd(); 73 74 // Fast approximate seeking to given time. 75 media::TimeUnit FastSeek(const media::TimeUnit& aTime); 76 77 // Seeks by scanning the stream up to the given time for more accurate 78 // results. 79 media::TimeUnit ScanUntil(const media::TimeUnit& aTime); 80 81 // Finds the next valid frame and return it. 82 const flac::Frame& FindNextFrame(); 83 84 // Returns the next ADTS frame, if available. 85 already_AddRefed<MediaRawData> GetNextFrame(const flac::Frame& aFrame); 86 87 // Reads aSize bytes into aBuffer from the source starting at aOffset. 88 // Returns the actual size read. 89 int32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize); 90 91 // Returns the average frame length derived from the previously parsed frames. 92 double AverageFrameLength() const; 93 94 // The (hopefully) Flac resource. 95 MediaResourceIndex mSource; 96 97 // Flac frame parser used to detect frames and extract side info. 98 nsAutoPtr<flac::FrameParser> mParser; 99 100 // Total duration of parsed frames. 101 media::TimeUnit mParsedFramesDuration; 102 103 // Sum of parsed frames' lengths in bytes. 104 uint64_t mTotalFrameLen; 105 106 // Audio track config info. 107 UniquePtr<AudioInfo> mInfo; 108 }; 109 110 } // namespace mozilla 111 112 #endif // !FLAC_DEMUXER_H_ 113