OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // Creates an output stream based on the ALSA PCM interface. | 5 // Creates an output stream based on the ALSA PCM interface. |
6 // | 6 // |
7 // On device write failure, the stream will move itself to an invalid state. | 7 // On device write failure, the stream will move itself to an invalid state. |
8 // No more data will be pulled from the data source, or written to the device. | 8 // No more data will be pulled from the data source, or written to the device. |
9 // All calls to public API functions will either no-op themselves, or return an | 9 // All calls to public API functions will either no-op themselves, or return an |
10 // error if possible. Specifically, If the stream is in an error state, Open() | 10 // error if possible. Specifically, If the stream is in an error state, Open() |
(...skipping 12 matching lines...) Expand all Loading... |
23 | 23 |
24 #include <alsa/asoundlib.h> | 24 #include <alsa/asoundlib.h> |
25 #include <stdint.h> | 25 #include <stdint.h> |
26 | 26 |
27 #include <memory> | 27 #include <memory> |
28 #include <string> | 28 #include <string> |
29 | 29 |
30 #include "base/compiler_specific.h" | 30 #include "base/compiler_specific.h" |
31 #include "base/gtest_prod_util.h" | 31 #include "base/gtest_prod_util.h" |
32 #include "base/macros.h" | 32 #include "base/macros.h" |
| 33 #include "base/memory/ref_counted.h" |
33 #include "base/memory/weak_ptr.h" | 34 #include "base/memory/weak_ptr.h" |
| 35 #include "base/single_thread_task_runner.h" |
| 36 #include "base/threading/non_thread_safe.h" |
34 #include "base/time/time.h" | 37 #include "base/time/time.h" |
35 #include "media/audio/audio_io.h" | 38 #include "media/audio/audio_io.h" |
36 #include "media/base/audio_parameters.h" | 39 #include "media/base/audio_parameters.h" |
37 | 40 |
38 namespace base { | |
39 class MessageLoop; | |
40 } | |
41 | |
42 namespace media { | 41 namespace media { |
43 | 42 |
44 class AlsaWrapper; | 43 class AlsaWrapper; |
45 class AudioManagerBase; | 44 class AudioManagerBase; |
46 class ChannelMixer; | 45 class ChannelMixer; |
47 class SeekableBuffer; | 46 class SeekableBuffer; |
48 | 47 |
49 class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { | 48 class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream, |
| 49 public base::NonThreadSafe { |
50 public: | 50 public: |
51 // String for the generic "default" ALSA device that has the highest | 51 // String for the generic "default" ALSA device that has the highest |
52 // compatibility and chance of working. | 52 // compatibility and chance of working. |
53 static const char kDefaultDevice[]; | 53 static const char kDefaultDevice[]; |
54 | 54 |
55 // Pass this to the AlsaPcmOutputStream if you want to attempt auto-selection | 55 // Pass this to the AlsaPcmOutputStream if you want to attempt auto-selection |
56 // of the audio device. | 56 // of the audio device. |
57 static const char kAutoSelectDevice[]; | 57 static const char kAutoSelectDevice[]; |
58 | 58 |
59 // Prefix for device names to enable ALSA library resampling. | 59 // Prefix for device names to enable ALSA library resampling. |
60 static const char kPlugPrefix[]; | 60 static const char kPlugPrefix[]; |
61 | 61 |
62 // The minimum latency that is accepted by the device. | 62 // The minimum latency that is accepted by the device. |
63 static const uint32_t kMinLatencyMicros; | 63 static const uint32_t kMinLatencyMicros; |
64 | 64 |
65 // Create a PCM Output stream for the ALSA device identified by | 65 // Create a PCM Output stream for the ALSA device identified by |
66 // |device_name|. The AlsaPcmOutputStream uses |wrapper| to communicate with | 66 // |device_name|. The AlsaPcmOutputStream uses |wrapper| to communicate with |
67 // the alsa libraries, allowing for dependency injection during testing. All | 67 // the alsa libraries, allowing for dependency injection during testing. All |
68 // requesting of data, and writing to the alsa device will be done on | 68 // requesting of data, and writing to the alsa device will be done on |
69 // |message_loop|. | 69 // the current thread. |
70 // | 70 // |
71 // If unsure of what to use for |device_name|, use |kAutoSelectDevice|. | 71 // If unsure of what to use for |device_name|, use |kAutoSelectDevice|. |
72 AlsaPcmOutputStream(const std::string& device_name, | 72 AlsaPcmOutputStream(const std::string& device_name, |
73 const AudioParameters& params, | 73 const AudioParameters& params, |
74 AlsaWrapper* wrapper, | 74 AlsaWrapper* wrapper, |
75 AudioManagerBase* manager); | 75 AudioManagerBase* manager); |
76 | 76 |
77 ~AlsaPcmOutputStream() override; | 77 ~AlsaPcmOutputStream() override; |
78 | 78 |
79 // Implementation of AudioOutputStream. | 79 // Implementation of AudioOutputStream. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 // Attempts to find the best matching linux audio device for the given number | 137 // Attempts to find the best matching linux audio device for the given number |
138 // of channels. This function will set |device_name_| and |channel_mixer_|. | 138 // of channels. This function will set |device_name_| and |channel_mixer_|. |
139 snd_pcm_t* AutoSelectDevice(uint32_t latency); | 139 snd_pcm_t* AutoSelectDevice(uint32_t latency); |
140 | 140 |
141 // Functions to safeguard state transitions. All changes to the object state | 141 // Functions to safeguard state transitions. All changes to the object state |
142 // should go through these functions. | 142 // should go through these functions. |
143 bool CanTransitionTo(InternalState to); | 143 bool CanTransitionTo(InternalState to); |
144 InternalState TransitionTo(InternalState to); | 144 InternalState TransitionTo(InternalState to); |
145 InternalState state(); | 145 InternalState state(); |
146 | 146 |
147 // Returns true when we're on the audio thread or if the audio thread's | |
148 // message loop is NULL (which will happen during shutdown). | |
149 bool IsOnAudioThread() const; | |
150 | |
151 // API for Proxying calls to the AudioSourceCallback provided during | 147 // API for Proxying calls to the AudioSourceCallback provided during |
152 // Start(). | 148 // Start(). |
153 // | 149 // |
154 // TODO(ajwong): This is necessary because the ownership semantics for the | 150 // TODO(ajwong): This is necessary because the ownership semantics for the |
155 // |source_callback_| object are incorrect in AudioRenderHost. The callback | 151 // |source_callback_| object are incorrect in AudioRenderHost. The callback |
156 // is passed into the output stream, but ownership is not transfered which | 152 // is passed into the output stream, but ownership is not transfered which |
157 // requires a synchronization on access of the |source_callback_| to avoid | 153 // requires a synchronization on access of the |source_callback_| to avoid |
158 // using a deleted callback. | 154 // using a deleted callback. |
159 int RunDataCallback(AudioBus* audio_bus, uint32_t total_bytes_delay); | 155 int RunDataCallback(AudioBus* audio_bus, uint32_t total_bytes_delay); |
160 void RunErrorCallback(int code); | 156 void RunErrorCallback(int code); |
(...skipping 23 matching lines...) Expand all Loading... |
184 // writing to the ALSA device. This is set because the device has entered | 180 // writing to the ALSA device. This is set because the device has entered |
185 // an unrecoverable error state, or the ClosedTask() has executed. | 181 // an unrecoverable error state, or the ClosedTask() has executed. |
186 bool stop_stream_; | 182 bool stop_stream_; |
187 | 183 |
188 // Wrapper class to invoke all the ALSA functions. | 184 // Wrapper class to invoke all the ALSA functions. |
189 AlsaWrapper* wrapper_; | 185 AlsaWrapper* wrapper_; |
190 | 186 |
191 // Audio manager that created us. Used to report that we've been closed. | 187 // Audio manager that created us. Used to report that we've been closed. |
192 AudioManagerBase* manager_; | 188 AudioManagerBase* manager_; |
193 | 189 |
194 // Message loop to use for polling. The object is owned by the AudioManager. | 190 // Task runner to use for polling. |
195 // We hold a reference to the audio thread message loop since | 191 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
196 // AudioManagerBase::ShutDown() can invalidate the message loop pointer | |
197 // before the stream gets deleted. | |
198 base::MessageLoop* message_loop_; | |
199 | 192 |
200 // Handle to the actual PCM playback device. | 193 // Handle to the actual PCM playback device. |
201 snd_pcm_t* playback_handle_; | 194 snd_pcm_t* playback_handle_; |
202 | 195 |
203 std::unique_ptr<media::SeekableBuffer> buffer_; | 196 std::unique_ptr<media::SeekableBuffer> buffer_; |
204 uint32_t frames_per_packet_; | 197 uint32_t frames_per_packet_; |
205 | 198 |
206 InternalState state_; | 199 InternalState state_; |
207 float volume_; // Volume level from 0.0 to 1.0. | 200 float volume_; // Volume level from 0.0 to 1.0. |
208 | 201 |
(...skipping 13 matching lines...) Expand all Loading... |
222 | 215 |
223 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStream); | 216 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStream); |
224 }; | 217 }; |
225 | 218 |
226 MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, | 219 MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, |
227 AlsaPcmOutputStream::InternalState); | 220 AlsaPcmOutputStream::InternalState); |
228 | 221 |
229 }; // namespace media | 222 }; // namespace media |
230 | 223 |
231 #endif // MEDIA_AUDIO_ALSA_ALSA_OUTPUT_H_ | 224 #endif // MEDIA_AUDIO_ALSA_ALSA_OUTPUT_H_ |
OLD | NEW |