| 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 |