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 13 matching lines...) Expand all Loading... |
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/weak_ptr.h" | 33 #include "base/memory/weak_ptr.h" |
| 34 #include "base/threading/non_thread_safe.h" |
34 #include "base/time/time.h" | 35 #include "base/time/time.h" |
35 #include "media/audio/audio_io.h" | 36 #include "media/audio/audio_io.h" |
36 #include "media/base/audio_parameters.h" | 37 #include "media/base/audio_parameters.h" |
37 | 38 |
38 namespace base { | |
39 class MessageLoop; | |
40 } | |
41 | |
42 namespace media { | 39 namespace media { |
43 | 40 |
44 class AlsaWrapper; | 41 class AlsaWrapper; |
45 class AudioManagerBase; | 42 class AudioManagerBase; |
46 class ChannelMixer; | 43 class ChannelMixer; |
47 class SeekableBuffer; | 44 class SeekableBuffer; |
48 | 45 |
49 class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { | 46 class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream, |
| 47 public base::NonThreadSafe { |
50 public: | 48 public: |
51 // String for the generic "default" ALSA device that has the highest | 49 // String for the generic "default" ALSA device that has the highest |
52 // compatibility and chance of working. | 50 // compatibility and chance of working. |
53 static const char kDefaultDevice[]; | 51 static const char kDefaultDevice[]; |
54 | 52 |
55 // Pass this to the AlsaPcmOutputStream if you want to attempt auto-selection | 53 // Pass this to the AlsaPcmOutputStream if you want to attempt auto-selection |
56 // of the audio device. | 54 // of the audio device. |
57 static const char kAutoSelectDevice[]; | 55 static const char kAutoSelectDevice[]; |
58 | 56 |
59 // Prefix for device names to enable ALSA library resampling. | 57 // Prefix for device names to enable ALSA library resampling. |
60 static const char kPlugPrefix[]; | 58 static const char kPlugPrefix[]; |
61 | 59 |
62 // The minimum latency that is accepted by the device. | 60 // The minimum latency that is accepted by the device. |
63 static const uint32_t kMinLatencyMicros; | 61 static const uint32_t kMinLatencyMicros; |
64 | 62 |
65 // Create a PCM Output stream for the ALSA device identified by | 63 // Create a PCM Output stream for the ALSA device identified by |
66 // |device_name|. The AlsaPcmOutputStream uses |wrapper| to communicate with | 64 // |device_name|. The AlsaPcmOutputStream uses |wrapper| to communicate with |
67 // the alsa libraries, allowing for dependency injection during testing. All | 65 // the alsa libraries, allowing for dependency injection during testing. All |
68 // requesting of data, and writing to the alsa device will be done on | 66 // requesting of data, and writing to the alsa device will be done on |
69 // |message_loop|. | 67 // |task_runner|. |
70 // | 68 // |
71 // If unsure of what to use for |device_name|, use |kAutoSelectDevice|. | 69 // If unsure of what to use for |device_name|, use |kAutoSelectDevice|. |
72 AlsaPcmOutputStream(const std::string& device_name, | 70 AlsaPcmOutputStream(const std::string& device_name, |
73 const AudioParameters& params, | 71 const AudioParameters& params, |
74 AlsaWrapper* wrapper, | 72 AlsaWrapper* wrapper, |
75 AudioManagerBase* manager); | 73 AudioManagerBase* manager); |
76 | 74 |
77 ~AlsaPcmOutputStream() override; | 75 ~AlsaPcmOutputStream() override; |
78 | 76 |
79 // Implementation of AudioOutputStream. | 77 // 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 | 135 // 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_|. | 136 // of channels. This function will set |device_name_| and |channel_mixer_|. |
139 snd_pcm_t* AutoSelectDevice(uint32_t latency); | 137 snd_pcm_t* AutoSelectDevice(uint32_t latency); |
140 | 138 |
141 // Functions to safeguard state transitions. All changes to the object state | 139 // Functions to safeguard state transitions. All changes to the object state |
142 // should go through these functions. | 140 // should go through these functions. |
143 bool CanTransitionTo(InternalState to); | 141 bool CanTransitionTo(InternalState to); |
144 InternalState TransitionTo(InternalState to); | 142 InternalState TransitionTo(InternalState to); |
145 InternalState state(); | 143 InternalState state(); |
146 | 144 |
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 | 145 // API for Proxying calls to the AudioSourceCallback provided during |
152 // Start(). | 146 // Start(). |
153 // | 147 // |
154 // TODO(ajwong): This is necessary because the ownership semantics for the | 148 // TODO(ajwong): This is necessary because the ownership semantics for the |
155 // |source_callback_| object are incorrect in AudioRenderHost. The callback | 149 // |source_callback_| object are incorrect in AudioRenderHost. The callback |
156 // is passed into the output stream, but ownership is not transfered which | 150 // is passed into the output stream, but ownership is not transfered which |
157 // requires a synchronization on access of the |source_callback_| to avoid | 151 // requires a synchronization on access of the |source_callback_| to avoid |
158 // using a deleted callback. | 152 // using a deleted callback. |
159 int RunDataCallback(AudioBus* audio_bus, uint32_t total_bytes_delay); | 153 int RunDataCallback(AudioBus* audio_bus, uint32_t total_bytes_delay); |
160 void RunErrorCallback(int code); | 154 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 | 178 // writing to the ALSA device. This is set because the device has entered |
185 // an unrecoverable error state, or the ClosedTask() has executed. | 179 // an unrecoverable error state, or the ClosedTask() has executed. |
186 bool stop_stream_; | 180 bool stop_stream_; |
187 | 181 |
188 // Wrapper class to invoke all the ALSA functions. | 182 // Wrapper class to invoke all the ALSA functions. |
189 AlsaWrapper* wrapper_; | 183 AlsaWrapper* wrapper_; |
190 | 184 |
191 // Audio manager that created us. Used to report that we've been closed. | 185 // Audio manager that created us. Used to report that we've been closed. |
192 AudioManagerBase* manager_; | 186 AudioManagerBase* manager_; |
193 | 187 |
194 // Message loop to use for polling. The object is owned by the AudioManager. | 188 // Task runner to use for polling. |
195 // We hold a reference to the audio thread message loop since | 189 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 | 190 |
200 // Handle to the actual PCM playback device. | 191 // Handle to the actual PCM playback device. |
201 snd_pcm_t* playback_handle_; | 192 snd_pcm_t* playback_handle_; |
202 | 193 |
203 std::unique_ptr<media::SeekableBuffer> buffer_; | 194 std::unique_ptr<media::SeekableBuffer> buffer_; |
204 uint32_t frames_per_packet_; | 195 uint32_t frames_per_packet_; |
205 | 196 |
206 InternalState state_; | 197 InternalState state_; |
207 float volume_; // Volume level from 0.0 to 1.0. | 198 float volume_; // Volume level from 0.0 to 1.0. |
208 | 199 |
(...skipping 13 matching lines...) Expand all Loading... |
222 | 213 |
223 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStream); | 214 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStream); |
224 }; | 215 }; |
225 | 216 |
226 MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, | 217 MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, |
227 AlsaPcmOutputStream::InternalState); | 218 AlsaPcmOutputStream::InternalState); |
228 | 219 |
229 }; // namespace media | 220 }; // namespace media |
230 | 221 |
231 #endif // MEDIA_AUDIO_ALSA_ALSA_OUTPUT_H_ | 222 #endif // MEDIA_AUDIO_ALSA_ALSA_OUTPUT_H_ |
OLD | NEW |