OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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() |
11 // will return false, and Start() will call OnError() immediately on the | 11 // will return false, and Start() will call OnError() immediately on the |
12 // provided callback. | 12 // provided callback. |
13 // | 13 // |
14 // TODO(ajwong): The OnClose() and OnError() calling needing fixing. | 14 // TODO(ajwong): The OnClose() and OnError() calling needing fixing. |
15 // | 15 // |
16 // If the stream is successfully opened, Close() must be called before the | 16 // If the stream is successfully opened, Close() must be called before the |
17 // stream is deleted as Close() is responsible for ensuring resource cleanup | 17 // stream is deleted as Close() is responsible for ensuring resource cleanup |
18 // occurs. | 18 // occurs. |
19 // | 19 // |
20 // This object's thread-safety is a little tricky. This object's public API | 20 // This object's thread-safety is a little tricky. This object's public API |
21 // can only be called from the thread that created the object. Calling the | 21 // can only be called from the thread that created the object. Calling the |
22 // public APIs in any method that may cause concurrent execution will result in | 22 // public APIs in any method that may cause concurrent execution will result in |
23 // a race condition. When modifying the code in this class, please read the | 23 // a race condition. When modifying the code in this class, please read the |
24 // threading assumptions at the top of the implementation file to avoid | 24 // threading assumptions at the top of the implementation file to avoid |
25 // introducing race conditions between tasks posted to the internal | 25 // introducing race conditions between tasks posted to the internal |
26 // message_loop, and the thread calling the public APIs. | 26 // message_loop, and the thread calling the public APIs. |
| 27 // |
| 28 // TODO(sergeyu): AlsaPcmOutputStream is always created and used from the |
| 29 // audio thread (i.e. |client_thread_loop_| and |message_loop_| always point |
| 30 // to the same thread), so it doesn't need to be thread-safe anymore. |
| 31 // |
| 32 // TODO(sergeyu): Remove refcounter from AlsaPcmOutputStream and use |
| 33 // ScopedRunnableMethodFactory to create tasks. |
27 | 34 |
28 #ifndef MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ | 35 #ifndef MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ |
29 #define MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ | 36 #define MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ |
30 | 37 |
31 #include <alsa/asoundlib.h> | 38 #include <alsa/asoundlib.h> |
32 | 39 |
33 #include <string> | 40 #include <string> |
34 | 41 |
35 #include "base/gtest_prod_util.h" | 42 #include "base/gtest_prod_util.h" |
36 #include "base/lock.h" | 43 #include "base/lock.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 // |message_loop|. | 79 // |message_loop|. |
73 // | 80 // |
74 // If unsure of what to use for |device_name|, use |kAutoSelectDevice|. | 81 // If unsure of what to use for |device_name|, use |kAutoSelectDevice|. |
75 AlsaPcmOutputStream(const std::string& device_name, | 82 AlsaPcmOutputStream(const std::string& device_name, |
76 AudioParameters params, | 83 AudioParameters params, |
77 AlsaWrapper* wrapper, | 84 AlsaWrapper* wrapper, |
78 AudioManagerLinux* manager, | 85 AudioManagerLinux* manager, |
79 MessageLoop* message_loop); | 86 MessageLoop* message_loop); |
80 | 87 |
81 // Implementation of AudioOutputStream. | 88 // Implementation of AudioOutputStream. |
82 virtual bool Open(uint32 packet_size); | 89 virtual bool Open(); |
83 virtual void Close(); | 90 virtual void Close(); |
84 virtual void Start(AudioSourceCallback* callback); | 91 virtual void Start(AudioSourceCallback* callback); |
85 virtual void Stop(); | 92 virtual void Stop(); |
86 virtual void SetVolume(double volume); | 93 virtual void SetVolume(double volume); |
87 virtual void GetVolume(double* volume); | 94 virtual void GetVolume(double* volume); |
88 | 95 |
89 private: | 96 private: |
90 friend class base::RefCountedThreadSafe<AlsaPcmOutputStream>; | 97 friend class base::RefCountedThreadSafe<AlsaPcmOutputStream>; |
91 friend class AlsaPcmOutputStreamTest; | 98 friend class AlsaPcmOutputStreamTest; |
92 FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, | 99 FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, |
(...skipping 27 matching lines...) Expand all Loading... |
120 kInError = 0, | 127 kInError = 0, |
121 kCreated, | 128 kCreated, |
122 kIsOpened, | 129 kIsOpened, |
123 kIsPlaying, | 130 kIsPlaying, |
124 kIsStopped, | 131 kIsStopped, |
125 kIsClosed | 132 kIsClosed |
126 }; | 133 }; |
127 friend std::ostream& operator<<(std::ostream& os, InternalState); | 134 friend std::ostream& operator<<(std::ostream& os, InternalState); |
128 | 135 |
129 // Various tasks that complete actions started in the public API. | 136 // Various tasks that complete actions started in the public API. |
130 void OpenTask(uint32 packet_size); | 137 void OpenTask(); |
131 void StartTask(); | 138 void StartTask(); |
132 void CloseTask(); | 139 void CloseTask(); |
133 | 140 |
134 // Functions to get another packet from the data source and write it into the | 141 // Functions to get another packet from the data source and write it into the |
135 // ALSA device. | 142 // ALSA device. |
136 void BufferPacket(bool* source_exhausted); | 143 void BufferPacket(bool* source_exhausted); |
137 void WritePacket(); | 144 void WritePacket(); |
138 void WriteTask(); | 145 void WriteTask(); |
139 void ScheduleNextWrite(bool source_exhausted); | 146 void ScheduleNextWrite(bool source_exhausted); |
140 | 147 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 // API for Proxying calls to the AudioSourceCallback provided during | 179 // API for Proxying calls to the AudioSourceCallback provided during |
173 // Start(). These APIs are threadsafe. | 180 // Start(). These APIs are threadsafe. |
174 // | 181 // |
175 // TODO(ajwong): This is necessary because the ownership semantics for the | 182 // TODO(ajwong): This is necessary because the ownership semantics for the |
176 // |source_callback_| object are incorrect in AudioRenderHost. The callback | 183 // |source_callback_| object are incorrect in AudioRenderHost. The callback |
177 // is passed into the output stream, but ownership is not transfered which | 184 // is passed into the output stream, but ownership is not transfered which |
178 // requires a synchronization on access of the |source_callback_| to avoid | 185 // requires a synchronization on access of the |source_callback_| to avoid |
179 // using a deleted callback. | 186 // using a deleted callback. |
180 uint32 OnMoreData(AudioOutputStream* stream, uint8* dest, | 187 uint32 OnMoreData(AudioOutputStream* stream, uint8* dest, |
181 uint32 max_size, AudioBuffersState buffers_state); | 188 uint32 max_size, AudioBuffersState buffers_state); |
182 void OnClose(AudioOutputStream* stream); | |
183 void OnError(AudioOutputStream* stream, int code); | 189 void OnError(AudioOutputStream* stream, int code); |
184 | 190 |
185 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to | 191 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to |
186 // release ownership of the currently registered callback. | 192 // release ownership of the currently registered callback. |
187 void set_source_callback(AudioSourceCallback* callback); | 193 void set_source_callback(AudioSourceCallback* callback); |
188 | 194 |
189 private: | 195 private: |
190 Lock lock_; | 196 Lock lock_; |
191 | 197 |
192 InternalState state_; | 198 InternalState state_; |
(...skipping 11 matching lines...) Expand all Loading... |
204 const std::string requested_device_name_; | 210 const std::string requested_device_name_; |
205 const snd_pcm_format_t pcm_format_; | 211 const snd_pcm_format_t pcm_format_; |
206 const uint32 channels_; | 212 const uint32 channels_; |
207 const uint32 sample_rate_; | 213 const uint32 sample_rate_; |
208 const uint32 bytes_per_sample_; | 214 const uint32 bytes_per_sample_; |
209 const uint32 bytes_per_frame_; | 215 const uint32 bytes_per_frame_; |
210 | 216 |
211 // Device configuration data. Populated after OpenTask() completes. | 217 // Device configuration data. Populated after OpenTask() completes. |
212 std::string device_name_; | 218 std::string device_name_; |
213 bool should_downmix_; | 219 bool should_downmix_; |
214 uint32 latency_micros_; | |
215 uint32 packet_size_; | 220 uint32 packet_size_; |
216 uint32 micros_per_packet_; | 221 uint32 micros_per_packet_; |
| 222 uint32 latency_micros_; |
217 uint32 bytes_per_output_frame_; | 223 uint32 bytes_per_output_frame_; |
218 uint32 alsa_buffer_frames_; | 224 uint32 alsa_buffer_frames_; |
219 | 225 |
220 // Flag indicating the code should stop reading from the data source or | 226 // Flag indicating the code should stop reading from the data source or |
221 // writing to the ALSA device. This is set because the device has entered | 227 // writing to the ALSA device. This is set because the device has entered |
222 // an unrecoverable error state, or the ClosedTask() has executed. | 228 // an unrecoverable error state, or the ClosedTask() has executed. |
223 bool stop_stream_; | 229 bool stop_stream_; |
224 | 230 |
225 // Wrapper class to invoke all the ALSA functions. | 231 // Wrapper class to invoke all the ALSA functions. |
226 AlsaWrapper* wrapper_; | 232 AlsaWrapper* wrapper_; |
(...skipping 13 matching lines...) Expand all Loading... |
240 MessageLoop* client_thread_loop_; | 246 MessageLoop* client_thread_loop_; |
241 | 247 |
242 // The message loop responsible for querying the data source, and writing to | 248 // The message loop responsible for querying the data source, and writing to |
243 // the output device. | 249 // the output device. |
244 MessageLoop* message_loop_; | 250 MessageLoop* message_loop_; |
245 | 251 |
246 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStream); | 252 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStream); |
247 }; | 253 }; |
248 | 254 |
249 #endif // MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ | 255 #endif // MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ |
OLD | NEW |