summaryrefslogtreecommitdiffstats
path: root/dom/media/ADTSDemuxer.h
blob: feb65d01b386aa326ea168a5319e0f3f1a3e7b4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef ADTS_DEMUXER_H_
#define ADTS_DEMUXER_H_

#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "MediaDataDemuxer.h"
#include "MediaResource.h"
#include "mp4_demuxer/ByteReader.h"

namespace mozilla {

namespace adts {
class Frame;
class FrameParser;
}

class ADTSTrackDemuxer;

class ADTSDemuxer : public MediaDataDemuxer {
public:
  // MediaDataDemuxer interface.
  explicit ADTSDemuxer(MediaResource* aSource);
  RefPtr<InitPromise> Init() override;
  bool HasTrackType(TrackInfo::TrackType aType) const override;
  uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
  already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
    TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
  bool IsSeekable() const override;

private:
  bool InitInternal();

  RefPtr<MediaResource> mSource;
  RefPtr<ADTSTrackDemuxer> mTrackDemuxer;
};

class ADTSTrackDemuxer : public MediaTrackDemuxer {
public:
  explicit ADTSTrackDemuxer(MediaResource* aSource);

  // Initializes the track demuxer by reading the first frame for meta data.
  // Returns initialization success state.
  bool Init();

  // Returns the total stream length if known, -1 otherwise.
  int64_t StreamLength() const;

  // Returns the estimated stream duration, or a 0-duration if unknown.
  media::TimeUnit Duration() const;

  // Returns the estimated duration up to the given frame number,
  // or a 0-duration if unknown.
  media::TimeUnit Duration(int64_t aNumFrames) const;

  // MediaTrackDemuxer interface.
  UniquePtr<TrackInfo> GetInfo() const override;
  RefPtr<SeekPromise> Seek(media::TimeUnit aTime) override;
  RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override;
  void Reset() override;
  RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
    media::TimeUnit aTimeThreshold) override;
  int64_t GetResourceOffset() const override;
  media::TimeIntervals GetBuffered() override;

private:
  // Destructor.
  ~ADTSTrackDemuxer();

  // Fast approximate seeking to given time.
  media::TimeUnit FastSeek(const media::TimeUnit& aTime);

  // Seeks by scanning the stream up to the given time for more accurate results.
  media::TimeUnit ScanUntil(const media::TimeUnit& aTime);

  // Finds the next valid frame and returns its byte range.
  const adts::Frame& FindNextFrame(bool findFirstFrame = false);

  // Skips the next frame given the provided byte range.
  bool SkipNextFrame(const adts::Frame& aFrame);

  // Returns the next ADTS frame, if available.
  already_AddRefed<MediaRawData> GetNextFrame(const adts::Frame& aFrame);

  // Updates post-read meta data.
  void UpdateState(const adts::Frame& aFrame);

  // Returns the frame index for the given offset.
  int64_t FrameIndexFromOffset(int64_t aOffset) const;

  // Returns the frame index for the given time.
  int64_t FrameIndexFromTime(const media::TimeUnit& aTime) const;

  // Reads aSize bytes into aBuffer from the source starting at aOffset.
  // Returns the actual size read.
  int32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize);

  // Returns the average frame length derived from the previously parsed frames.
  double AverageFrameLength() const;

  // The (hopefully) ADTS resource.
  MediaResourceIndex mSource;

  // ADTS frame parser used to detect frames and extract side info.
  adts::FrameParser* mParser;

  // Current byte offset in the source stream.
  int64_t mOffset;

  // Total parsed frames.
  uint64_t mNumParsedFrames;

  // Current frame index.
  int64_t mFrameIndex;

  // Sum of parsed frames' lengths in bytes.
  uint64_t mTotalFrameLen;

  // Samples per frame metric derived from frame headers or 0 if none available.
  uint32_t mSamplesPerFrame;

  // Samples per second metric derived from frame headers or 0 if none available.
  uint32_t mSamplesPerSecond;

  // Channel count derived from frame headers or 0 if none available.
  uint32_t mChannels;

  // Audio track config info.
  UniquePtr<AudioInfo> mInfo;
};

} // mozilla

#endif // !ADTS_DEMUXER_H_