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 ADTS_DEMUXER_H_
8 #define ADTS_DEMUXER_H_
9 
10 #include "mozilla/Attributes.h"
11 #include "mozilla/Maybe.h"
12 #include "MediaDataDemuxer.h"
13 #include "MediaResource.h"
14 
15 namespace mozilla {
16 
17 namespace adts {
18 class Frame;
19 class FrameParser;
20 }  // namespace adts
21 
22 class ADTSTrackDemuxer;
23 
24 DDLoggedTypeDeclNameAndBase(ADTSDemuxer, MediaDataDemuxer);
25 
26 class ADTSDemuxer : public MediaDataDemuxer,
27                     public DecoderDoctorLifeLogger<ADTSDemuxer> {
28  public:
29   // MediaDataDemuxer interface.
30   explicit ADTSDemuxer(MediaResource* aSource);
31   RefPtr<InitPromise> Init() override;
32   uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
33   already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
34       TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
35   bool IsSeekable() const override;
36 
37   // Return true if a valid ADTS frame header could be found.
38   static bool ADTSSniffer(const uint8_t* aData, const uint32_t aLength);
39 
40  private:
41   bool InitInternal();
42 
43   RefPtr<MediaResource> mSource;
44   RefPtr<ADTSTrackDemuxer> mTrackDemuxer;
45 };
46 
47 DDLoggedTypeNameAndBase(ADTSTrackDemuxer, MediaTrackDemuxer);
48 
49 class ADTSTrackDemuxer : public MediaTrackDemuxer,
50                          public DecoderDoctorLifeLogger<ADTSTrackDemuxer> {
51  public:
52   explicit ADTSTrackDemuxer(MediaResource* aSource);
53 
54   // Initializes the track demuxer by reading the first frame for meta data.
55   // Returns initialization success state.
56   bool Init();
57 
58   // Returns the total stream length if known, -1 otherwise.
59   int64_t StreamLength() const;
60 
61   // Returns the estimated stream duration, or a 0-duration if unknown.
62   media::TimeUnit Duration() const;
63 
64   // Returns the estimated duration up to the given frame number,
65   // or a 0-duration if unknown.
66   media::TimeUnit Duration(int64_t aNumFrames) const;
67 
68   // MediaTrackDemuxer interface.
69   UniquePtr<TrackInfo> GetInfo() const override;
70   RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override;
71   RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override;
72   void Reset() override;
73   RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
74       const media::TimeUnit& aTimeThreshold) override;
75   int64_t GetResourceOffset() const override;
76   media::TimeIntervals GetBuffered() override;
77 
78  private:
79   // Destructor.
80   ~ADTSTrackDemuxer();
81 
82   // Fast approximate seeking to given time.
83   media::TimeUnit FastSeek(const media::TimeUnit& aTime);
84 
85   // Seeks by scanning the stream up to the given time for more accurate
86   // results.
87   media::TimeUnit ScanUntil(const media::TimeUnit& aTime);
88 
89   // Finds the next valid frame and returns its byte range.
90   const adts::Frame& FindNextFrame(bool findFirstFrame = false);
91 
92   // Skips the next frame given the provided byte range.
93   bool SkipNextFrame(const adts::Frame& aFrame);
94 
95   // Returns the next ADTS frame, if available.
96   already_AddRefed<MediaRawData> GetNextFrame(const adts::Frame& aFrame);
97 
98   // Updates post-read meta data.
99   void UpdateState(const adts::Frame& aFrame);
100 
101   // Returns the frame index for the given offset.
102   int64_t FrameIndexFromOffset(int64_t aOffset) const;
103 
104   // Returns the frame index for the given time.
105   int64_t FrameIndexFromTime(const media::TimeUnit& aTime) const;
106 
107   // Reads aSize bytes into aBuffer from the source starting at aOffset.
108   // Returns the actual size read.
109   int32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize);
110 
111   // Returns the average frame length derived from the previously parsed frames.
112   double AverageFrameLength() const;
113 
114   // The (hopefully) ADTS resource.
115   MediaResourceIndex mSource;
116 
117   // ADTS frame parser used to detect frames and extract side info.
118   adts::FrameParser* mParser;
119 
120   // Current byte offset in the source stream.
121   int64_t mOffset;
122 
123   // Total parsed frames.
124   uint64_t mNumParsedFrames;
125 
126   // Current frame index.
127   int64_t mFrameIndex;
128 
129   // Sum of parsed frames' lengths in bytes.
130   uint64_t mTotalFrameLen;
131 
132   // Samples per frame metric derived from frame headers or 0 if none available.
133   uint32_t mSamplesPerFrame;
134 
135   // Samples per second metric derived from frame headers or 0 if none
136   // available.
137   uint32_t mSamplesPerSecond;
138 
139   // Channel count derived from frame headers or 0 if none available.
140   uint32_t mChannels;
141 
142   // Audio track config info.
143   UniquePtr<AudioInfo> mInfo;
144 
145   // Amount of pre-roll time when seeking.
146   // AAC encoder delay is by default 2112 audio frames.
147   media::TimeUnit mPreRoll;
148 };
149 
150 }  // namespace mozilla
151 
152 #endif  // !ADTS_DEMUXER_H_
153