Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/mediasink/AudioSink.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim:set ts=2 sw=2 sts=2 et cindent: */
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
#ifndef AudioSink_h__
7
#define AudioSink_h__
8
9
#include "AudioStream.h"
10
#include "MediaEventSource.h"
11
#include "MediaQueue.h"
12
#include "MediaInfo.h"
13
#include "MediaSink.h"
14
15
#include "mozilla/Atomics.h"
16
#include "mozilla/Maybe.h"
17
#include "mozilla/MozPromise.h"
18
#include "mozilla/Monitor.h"
19
#include "mozilla/RefPtr.h"
20
#include "nsISupportsImpl.h"
21
22
namespace mozilla {
23
24
class AudioConverter;
25
26
namespace media {
27
28
class AudioSink : private AudioStream::DataSource {
29
  using PlaybackParams = MediaSink::PlaybackParams;
30
31
public:
32
  AudioSink(AbstractThread* aThread,
33
            MediaQueue<AudioData>& aAudioQueue,
34
            const TimeUnit& aStartTime,
35
            const AudioInfo& aInfo);
36
37
  ~AudioSink();
38
39
  // Return a promise which will be resolved when AudioSink
40
  // finishes playing, or rejected if any error.
41
  RefPtr<GenericPromise> Init(const PlaybackParams& aParams);
42
43
  /*
44
   * All public functions are not thread-safe.
45
   * Called on the task queue of MDSM only.
46
   */
47
  TimeUnit GetPosition();
48
  TimeUnit GetEndTime() const;
49
50
  // Check whether we've pushed more frames to the audio hardware than it has
51
  // played.
52
  bool HasUnplayedFrames();
53
54
  // Shut down the AudioSink's resources.
55
  void Shutdown();
56
57
  void SetVolume(double aVolume);
58
  void SetPlaybackRate(double aPlaybackRate);
59
  void SetPreservesPitch(bool aPreservesPitch);
60
  void SetPlaying(bool aPlaying);
61
62
0
  MediaEventSource<bool>& AudibleEvent() {
63
0
    return mAudibleEvent;
64
0
  }
65
66
  nsCString GetDebugInfo();
67
68
private:
69
  // Allocate and initialize mAudioStream. Returns NS_OK on success.
70
  nsresult InitializeAudioStream(const PlaybackParams& aParams);
71
72
  // Interface of AudioStream::DataSource.
73
  // Called on the callback thread of cubeb.
74
  UniquePtr<AudioStream::Chunk> PopFrames(uint32_t aFrames) override;
75
  bool Ended() const override;
76
  void Drained() override;
77
78
  void CheckIsAudible(const AudioData* aData);
79
80
  // The audio stream resource. Used on the task queue of MDSM only.
81
  RefPtr<AudioStream> mAudioStream;
82
83
  // The presentation time of the first audio frame that was played.
84
  // We can add this to the audio stream position to determine
85
  // the current audio time.
86
  const TimeUnit mStartTime;
87
88
  // Keep the last good position returned from the audio stream. Used to ensure
89
  // position returned by GetPosition() is mono-increasing in spite of audio
90
  // stream error. Used on the task queue of MDSM only.
91
  TimeUnit mLastGoodPosition;
92
93
  const AudioInfo mInfo;
94
95
  // Used on the task queue of MDSM only.
96
  bool mPlaying;
97
98
  MozPromiseHolder<GenericPromise> mEndPromise;
99
100
  /*
101
   * Members to implement AudioStream::DataSource.
102
   * Used on the callback thread of cubeb.
103
   */
104
  // The AudioData at which AudioStream::DataSource is reading.
105
  RefPtr<AudioData> mCurrentData;
106
107
  // Monitor protecting access to mCursor and mWritten.
108
  // mCursor is created/destroyed on the cubeb thread, while we must also
109
  // ensure that mWritten and mCursor::Available() get modified simultaneously.
110
  // (written on cubeb thread, and read on MDSM task queue).
111
  mutable Monitor mMonitor;
112
  // Keep track of the read position of mCurrentData.
113
  UniquePtr<AudioBufferCursor> mCursor;
114
115
  // PCM frames written to the stream so far.
116
  int64_t mWritten;
117
118
  // True if there is any error in processing audio data like overflow.
119
  Atomic<bool> mErrored;
120
121
  // Set on the callback thread of cubeb once the stream has drained.
122
  Atomic<bool> mPlaybackComplete;
123
124
  const RefPtr<AbstractThread> mOwnerThread;
125
126
  // Audio Processing objects and methods
127
  void OnAudioPopped(const RefPtr<AudioData>& aSample);
128
  void OnAudioPushed(const RefPtr<AudioData>& aSample);
129
  void NotifyAudioNeeded();
130
  // Drain the converter and add the output to the processed audio queue.
131
  // A maximum of aMaxFrames will be added.
132
  uint32_t DrainConverter(uint32_t aMaxFrames = UINT32_MAX);
133
  already_AddRefed<AudioData> CreateAudioFromBuffer(AlignedAudioBuffer&& aBuffer,
134
                                                    AudioData* aReference);
135
  // Add data to the processsed queue, update mProcessedQueueLength and
136
  // return the number of frames added.
137
  uint32_t PushProcessedAudio(AudioData* aData);
138
  UniquePtr<AudioConverter> mConverter;
139
  MediaQueue<AudioData> mProcessedQueue;
140
  // Length in microseconds of the ProcessedQueue
141
  Atomic<int32_t> mProcessedQueueLength;
142
  MediaEventListener mAudioQueueListener;
143
  MediaEventListener mAudioQueueFinishListener;
144
  MediaEventListener mProcessedQueueListener;
145
  // Number of frames processed from mAudioQueue. Used to determine gaps in
146
  // the input stream. It indicates the time in frames since playback started
147
  // at the current input framerate.
148
  int64_t mFramesParsed;
149
  Maybe<RefPtr<AudioData>> mLastProcessedPacket;
150
  TimeUnit mLastEndTime;
151
  // Never modifed after construction.
152
  uint32_t mOutputRate;
153
  uint32_t mOutputChannels;
154
155
  // True when audio is producing audible sound, false when audio is silent.
156
  bool mIsAudioDataAudible;
157
158
  MediaEventProducer<bool> mAudibleEvent;
159
160
  MediaQueue<AudioData>& mAudioQueue;
161
};
162
163
} // namespace media
164
} // namespace mozilla
165
166
#endif // AudioSink_h__