OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2010 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2010 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/sound/pulseaudiosoundsystem.h" | 11 #include "webrtc/sound/pulseaudiosoundsystem.h" |
12 | 12 |
13 #ifdef HAVE_LIBPULSE | 13 #ifdef HAVE_LIBPULSE |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
| 16 #include <string> |
16 | 17 |
17 #include "webrtc/base/arraysize.h" | 18 #include "webrtc/base/arraysize.h" |
18 #include "webrtc/base/common.h" | 19 #include "webrtc/base/common.h" |
19 #include "webrtc/base/fileutils.h" // for GetApplicationName() | 20 #include "webrtc/base/fileutils.h" // for GetApplicationName() |
20 #include "webrtc/base/logging.h" | 21 #include "webrtc/base/logging.h" |
21 #include "webrtc/base/timeutils.h" | 22 #include "webrtc/base/timeutils.h" |
22 #include "webrtc/base/worker.h" | 23 #include "webrtc/base/worker.h" |
23 #include "webrtc/sound/sounddevicelocator.h" | 24 #include "webrtc/sound/sounddevicelocator.h" |
24 #include "webrtc/sound/soundinputstreaminterface.h" | 25 #include "webrtc/sound/soundinputstreaminterface.h" |
25 #include "webrtc/sound/soundoutputstreaminterface.h" | 26 #include "webrtc/sound/soundoutputstreaminterface.h" |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 int flags_; | 210 int flags_; |
210 | 211 |
211 RTC_DISALLOW_COPY_AND_ASSIGN(PulseAudioStream); | 212 RTC_DISALLOW_COPY_AND_ASSIGN(PulseAudioStream); |
212 }; | 213 }; |
213 | 214 |
214 // Implementation of an input stream. See soundinputstreaminterface.h regarding | 215 // Implementation of an input stream. See soundinputstreaminterface.h regarding |
215 // thread-safety. | 216 // thread-safety. |
216 class PulseAudioInputStream : | 217 class PulseAudioInputStream : |
217 public SoundInputStreamInterface, | 218 public SoundInputStreamInterface, |
218 private rtc::Worker { | 219 private rtc::Worker { |
219 | |
220 struct GetVolumeCallbackData { | |
221 PulseAudioInputStream *instance; | |
222 pa_cvolume *channel_volumes; | |
223 }; | |
224 | |
225 struct GetSourceChannelCountCallbackData { | |
226 PulseAudioInputStream *instance; | |
227 uint8_t *channels; | |
228 }; | |
229 | |
230 public: | 220 public: |
231 PulseAudioInputStream(PulseAudioSoundSystem *pulse, | 221 PulseAudioInputStream(PulseAudioSoundSystem *pulse, |
232 pa_stream *stream, | 222 pa_stream *stream, |
233 int flags) | 223 int flags) |
234 : stream_(pulse, stream, flags), | 224 : stream_(pulse, stream, flags), |
235 temp_sample_data_(NULL), | 225 temp_sample_data_(NULL), |
236 temp_sample_data_size_(0) { | 226 temp_sample_data_size_(0) { |
237 // This callback seems to never be issued, but let's set it anyways. | 227 // This callback seems to never be issued, but let's set it anyways. |
238 symbol_table()->pa_stream_set_overflow_callback()(stream, &OverflowCallback, | 228 symbol_table()->pa_stream_set_overflow_callback()(stream, &OverflowCallback, |
239 NULL); | 229 NULL); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 Unlock(); | 369 Unlock(); |
380 } | 370 } |
381 return ret; | 371 return ret; |
382 } | 372 } |
383 | 373 |
384 virtual int LatencyUsecs() { | 374 virtual int LatencyUsecs() { |
385 return stream_.LatencyUsecs(); | 375 return stream_.LatencyUsecs(); |
386 } | 376 } |
387 | 377 |
388 private: | 378 private: |
| 379 struct GetVolumeCallbackData { |
| 380 PulseAudioInputStream* instance; |
| 381 pa_cvolume* channel_volumes; |
| 382 }; |
| 383 |
| 384 struct GetSourceChannelCountCallbackData { |
| 385 PulseAudioInputStream* instance; |
| 386 uint8_t* channels; |
| 387 }; |
| 388 |
389 void Lock() { | 389 void Lock() { |
390 stream_.Lock(); | 390 stream_.Lock(); |
391 } | 391 } |
392 | 392 |
393 void Unlock() { | 393 void Unlock() { |
394 stream_.Unlock(); | 394 stream_.Unlock(); |
395 } | 395 } |
396 | 396 |
397 PulseAudioSymbolTable *symbol_table() { | 397 PulseAudioSymbolTable *symbol_table() { |
398 return stream_.symbol_table(); | 398 return stream_.symbol_table(); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 size_t temp_sample_data_size_; | 573 size_t temp_sample_data_size_; |
574 | 574 |
575 RTC_DISALLOW_COPY_AND_ASSIGN(PulseAudioInputStream); | 575 RTC_DISALLOW_COPY_AND_ASSIGN(PulseAudioInputStream); |
576 }; | 576 }; |
577 | 577 |
578 // Implementation of an output stream. See soundoutputstreaminterface.h | 578 // Implementation of an output stream. See soundoutputstreaminterface.h |
579 // regarding thread-safety. | 579 // regarding thread-safety. |
580 class PulseAudioOutputStream : | 580 class PulseAudioOutputStream : |
581 public SoundOutputStreamInterface, | 581 public SoundOutputStreamInterface, |
582 private rtc::Worker { | 582 private rtc::Worker { |
583 | |
584 struct GetVolumeCallbackData { | |
585 PulseAudioOutputStream *instance; | |
586 pa_cvolume *channel_volumes; | |
587 }; | |
588 | |
589 public: | 583 public: |
590 PulseAudioOutputStream(PulseAudioSoundSystem *pulse, | 584 PulseAudioOutputStream(PulseAudioSoundSystem *pulse, |
591 pa_stream *stream, | 585 pa_stream *stream, |
592 int flags, | 586 int flags, |
593 int latency) | 587 int latency) |
594 : stream_(pulse, stream, flags), | 588 : stream_(pulse, stream, flags), |
595 configured_latency_(latency), | 589 configured_latency_(latency), |
596 temp_buffer_space_(0) { | 590 temp_buffer_space_(0) { |
597 symbol_table()->pa_stream_set_underflow_callback()(stream, | 591 symbol_table()->pa_stream_set_underflow_callback()(stream, |
598 &UnderflowCallbackThunk, | 592 &UnderflowCallbackThunk, |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 Unlock(); | 720 Unlock(); |
727 } | 721 } |
728 return ret; | 722 return ret; |
729 } | 723 } |
730 | 724 |
731 virtual int LatencyUsecs() { | 725 virtual int LatencyUsecs() { |
732 return stream_.LatencyUsecs(); | 726 return stream_.LatencyUsecs(); |
733 } | 727 } |
734 | 728 |
735 #if 0 | 729 #if 0 |
736 // TODO: Versions 0.9.16 and later of Pulse have a new API for | 730 // TODO(henrika): Versions 0.9.16 and later of Pulse have a new API for |
737 // zero-copy writes, but Hardy is not new enough to have that so we can't | 731 // zero-copy writes, but Hardy is not new enough to have that so we can't |
738 // rely on it. Perhaps auto-detect if it's present or not and use it if we | 732 // rely on it. Perhaps auto-detect if it's present or not and use it if we |
739 // can? | 733 // can? |
740 | 734 |
741 virtual bool GetWriteBuffer(void **buffer, size_t *size) { | 735 virtual bool GetWriteBuffer(void **buffer, size_t *size) { |
742 bool ret = true; | 736 bool ret = true; |
743 Lock(); | 737 Lock(); |
744 if (symbol_table()->pa_stream_begin_write()(stream_.stream(), buffer, size) | 738 if (symbol_table()->pa_stream_begin_write()(stream_.stream(), buffer, size) |
745 != 0) { | 739 != 0) { |
746 LOG(LS_ERROR) << "Can't get write buffer"; | 740 LOG(LS_ERROR) << "Can't get write buffer"; |
(...skipping 23 matching lines...) Expand all Loading... |
770 LOG(LS_ERROR) << "Unable to write"; | 764 LOG(LS_ERROR) << "Unable to write"; |
771 ret = false; | 765 ret = false; |
772 } | 766 } |
773 } | 767 } |
774 Unlock(); | 768 Unlock(); |
775 return ret; | 769 return ret; |
776 } | 770 } |
777 #endif | 771 #endif |
778 | 772 |
779 private: | 773 private: |
| 774 struct GetVolumeCallbackData { |
| 775 PulseAudioOutputStream* instance; |
| 776 pa_cvolume* channel_volumes; |
| 777 }; |
| 778 |
780 void Lock() { | 779 void Lock() { |
781 stream_.Lock(); | 780 stream_.Lock(); |
782 } | 781 } |
783 | 782 |
784 void Unlock() { | 783 void Unlock() { |
785 stream_.Unlock(); | 784 stream_.Unlock(); |
786 } | 785 } |
787 | 786 |
788 PulseAudioSymbolTable *symbol_table() { | 787 PulseAudioSymbolTable *symbol_table() { |
789 return stream_.symbol_table(); | 788 return stream_.symbol_table(); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 // change later, because the pointer to "data" will be invalid after return | 1157 // change later, because the pointer to "data" will be invalid after return |
1159 // from this function. | 1158 // from this function. |
1160 symbol_table_.pa_context_set_state_callback()(context, NULL, NULL); | 1159 symbol_table_.pa_context_set_state_callback()(context, NULL, NULL); |
1161 return ret; | 1160 return ret; |
1162 } | 1161 } |
1163 | 1162 |
1164 // Must be called with the lock held. | 1163 // Must be called with the lock held. |
1165 pa_context *PulseAudioSoundSystem::CreateNewConnection() { | 1164 pa_context *PulseAudioSoundSystem::CreateNewConnection() { |
1166 // Create connection context. | 1165 // Create connection context. |
1167 std::string app_name; | 1166 std::string app_name; |
1168 // TODO: Pulse etiquette says this name should be localized. Do | 1167 // TODO(henrika): Pulse etiquette says this name should be localized. Do |
1169 // we care? | 1168 // we care? |
1170 rtc::Filesystem::GetApplicationName(&app_name); | 1169 rtc::Filesystem::GetApplicationName(&app_name); |
1171 pa_context *context = symbol_table_.pa_context_new()( | 1170 pa_context *context = symbol_table_.pa_context_new()( |
1172 symbol_table_.pa_threaded_mainloop_get_api()(mainloop_), | 1171 symbol_table_.pa_threaded_mainloop_get_api()(mainloop_), |
1173 app_name.c_str()); | 1172 app_name.c_str()); |
1174 if (!context) { | 1173 if (!context) { |
1175 LOG(LS_ERROR) << "Can't create context"; | 1174 LOG(LS_ERROR) << "Can't create context"; |
1176 goto fail0; | 1175 goto fail0; |
1177 } | 1176 } |
1178 | 1177 |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 | 1533 |
1535 // Must be called with the lock held. | 1534 // Must be called with the lock held. |
1536 const char *PulseAudioSoundSystem::LastError() { | 1535 const char *PulseAudioSoundSystem::LastError() { |
1537 return symbol_table_.pa_strerror()(symbol_table_.pa_context_errno()( | 1536 return symbol_table_.pa_strerror()(symbol_table_.pa_context_errno()( |
1538 context_)); | 1537 context_)); |
1539 } | 1538 } |
1540 | 1539 |
1541 } // namespace rtc | 1540 } // namespace rtc |
1542 | 1541 |
1543 #endif // HAVE_LIBPULSE | 1542 #endif // HAVE_LIBPULSE |
OLD | NEW |