OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "media/audio/audio_manager_base.h" | 5 #include "media/audio/audio_manager_base.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
10 #include "base/threading/thread.h" | |
11 #include "base/win/scoped_com_initializer.h" | |
12 #include "media/audio/audio_output_dispatcher_impl.h" | 10 #include "media/audio/audio_output_dispatcher_impl.h" |
13 #include "media/audio/audio_output_proxy.h" | 11 #include "media/audio/audio_output_proxy.h" |
14 #include "media/audio/audio_output_resampler.h" | 12 #include "media/audio/audio_output_resampler.h" |
15 #include "media/audio/audio_util.h" | 13 #include "media/audio/audio_util.h" |
16 #include "media/audio/fake_audio_input_stream.h" | 14 #include "media/audio/fake_audio_input_stream.h" |
17 #include "media/audio/fake_audio_output_stream.h" | 15 #include "media/audio/fake_audio_output_stream.h" |
18 #include "media/base/media_switches.h" | 16 #include "media/base/media_switches.h" |
19 | 17 |
20 // TODO(dalecurtis): Temporarily disabled while switching pipeline to use float, | 18 // TODO(dalecurtis): Temporarily disabled while switching pipeline to use float, |
21 // http://crbug.com/114700 | 19 // http://crbug.com/114700 |
22 #if defined(ENABLE_AUDIO_MIXER) | 20 #if defined(ENABLE_AUDIO_MIXER) |
23 #include "media/audio/audio_output_mixer.h" | 21 #include "media/audio/audio_output_mixer.h" |
24 #endif | 22 #endif |
25 | 23 |
26 using base::win::ScopedCOMInitializer; | |
27 | |
28 namespace media { | 24 namespace media { |
29 | 25 |
30 static const int kStreamCloseDelaySeconds = 5; | 26 static const int kStreamCloseDelaySeconds = 5; |
31 | 27 |
32 // Default maximum number of output streams that can be open simultaneously | 28 // Default maximum number of output streams that can be open simultaneously |
33 // for all platforms. | 29 // for all platforms. |
34 static const int kDefaultMaxOutputStreams = 16; | 30 static const int kDefaultMaxOutputStreams = 16; |
35 | 31 |
36 // Default maximum number of input streams that can be open simultaneously | 32 // Default maximum number of input streams that can be open simultaneously |
37 // for all platforms. | 33 // for all platforms. |
38 static const int kDefaultMaxInputStreams = 16; | 34 static const int kDefaultMaxInputStreams = 16; |
39 | 35 |
40 static const int kMaxInputChannels = 2; | 36 static const int kMaxInputChannels = 2; |
41 | 37 |
42 const char AudioManagerBase::kDefaultDeviceName[] = "Default"; | 38 const char AudioManagerBase::kDefaultDeviceName[] = "Default"; |
43 const char AudioManagerBase::kDefaultDeviceId[] = "default"; | 39 const char AudioManagerBase::kDefaultDeviceId[] = "default"; |
44 | 40 |
45 // Initializes the COM library for use by this thread and sets the thread's | 41 #if defined(OS_WIN) |
46 // COM threading model on Windows to MTA. | 42 AudioThread::AudioThread(const char* name) : base::Thread(name) { |
47 class AudioThread : public base::Thread { | |
48 public: | |
49 AudioThread(); | |
50 virtual ~AudioThread(); | |
51 | |
52 protected: | |
53 virtual void Init() OVERRIDE; | |
54 virtual void CleanUp() OVERRIDE; | |
55 | |
56 private: | |
57 scoped_ptr<ScopedCOMInitializer> com_initializer_; | |
58 DISALLOW_COPY_AND_ASSIGN(AudioThread); | |
59 }; | |
60 | |
61 AudioThread::AudioThread() : base::Thread("AudioThread") { | |
62 } | 43 } |
63 | 44 |
64 AudioThread::~AudioThread() {} | 45 AudioThread::~AudioThread() { |
| 46 } |
65 | 47 |
66 void AudioThread::Init() { | 48 void AudioThread::Init() { |
67 com_initializer_.reset(new ScopedCOMInitializer(ScopedCOMInitializer::kMTA)); | 49 com_initializer_.reset(new base::win::ScopedCOMInitializer( |
68 CHECK(com_initializer_->succeeded()); | 50 base::win::ScopedCOMInitializer::kMTA)); |
69 } | 51 } |
70 | 52 |
71 void AudioThread::CleanUp() { | 53 void AudioThread::CleanUp() { |
72 com_initializer_.reset(); | 54 com_initializer_.reset(); |
73 } | 55 } |
| 56 #endif |
74 | 57 |
75 AudioManagerBase::AudioManagerBase() | 58 AudioManagerBase::AudioManagerBase() |
76 : num_active_input_streams_(0), | 59 : num_active_input_streams_(0), |
77 max_num_output_streams_(kDefaultMaxOutputStreams), | 60 max_num_output_streams_(kDefaultMaxOutputStreams), |
78 max_num_input_streams_(kDefaultMaxInputStreams), | 61 max_num_input_streams_(kDefaultMaxInputStreams), |
79 num_output_streams_(0), | 62 num_output_streams_(0), |
80 num_input_streams_(0) { | 63 num_input_streams_(0) { |
81 } | 64 } |
82 | 65 |
83 AudioManagerBase::~AudioManagerBase() { | 66 AudioManagerBase::~AudioManagerBase() { |
84 // The platform specific AudioManager implementation must have already | 67 // The platform specific AudioManager implementation must have already |
85 // stopped the audio thread. Otherwise, we may destroy audio streams before | 68 // stopped the audio thread. Otherwise, we may destroy audio streams before |
86 // stopping the thread, resulting an unexpected behavior. | 69 // stopping the thread, resulting an unexpected behavior. |
87 // This way we make sure activities of the audio streams are all stopped | 70 // This way we make sure activities of the audio streams are all stopped |
88 // before we destroy them. | 71 // before we destroy them. |
89 CHECK(!audio_thread_.get()); | 72 CHECK(!audio_thread_.get()); |
90 // All the output streams should have been deleted. | 73 // All the output streams should have been deleted. |
91 DCHECK_EQ(0, num_output_streams_); | 74 DCHECK_EQ(0, num_output_streams_); |
92 // All the input streams should have been deleted. | 75 // All the input streams should have been deleted. |
93 DCHECK_EQ(0, num_input_streams_); | 76 DCHECK_EQ(0, num_input_streams_); |
94 } | 77 } |
95 | 78 |
96 void AudioManagerBase::Init() { | 79 void AudioManagerBase::Init() { |
97 base::AutoLock lock(audio_thread_lock_); | 80 base::AutoLock lock(audio_thread_lock_); |
98 DCHECK(!audio_thread_.get()); | 81 DCHECK(!audio_thread_.get()); |
99 audio_thread_.reset(new media::AudioThread()); | 82 audio_thread_.reset(new AudioThread("AudioThread")); |
100 CHECK(audio_thread_->Start()); | 83 CHECK(audio_thread_->Start()); |
101 } | 84 } |
102 | 85 |
103 string16 AudioManagerBase::GetAudioInputDeviceModel() { | 86 string16 AudioManagerBase::GetAudioInputDeviceModel() { |
104 return string16(); | 87 return string16(); |
105 } | 88 } |
106 | 89 |
107 scoped_refptr<base::MessageLoopProxy> AudioManagerBase::GetMessageLoop() { | 90 scoped_refptr<base::MessageLoopProxy> AudioManagerBase::GetMessageLoop() { |
108 base::AutoLock lock(audio_thread_lock_); | 91 base::AutoLock lock(audio_thread_lock_); |
109 return audio_thread_.get() ? audio_thread_->message_loop_proxy() : NULL; | 92 return audio_thread_.get() ? audio_thread_->message_loop_proxy() : NULL; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 base::AtomicRefCountDec(&num_active_input_streams_); | 237 base::AtomicRefCountDec(&num_active_input_streams_); |
255 } | 238 } |
256 | 239 |
257 bool AudioManagerBase::IsRecordingInProcess() { | 240 bool AudioManagerBase::IsRecordingInProcess() { |
258 return !base::AtomicRefCountIsZero(&num_active_input_streams_); | 241 return !base::AtomicRefCountIsZero(&num_active_input_streams_); |
259 } | 242 } |
260 | 243 |
261 void AudioManagerBase::Shutdown() { | 244 void AudioManagerBase::Shutdown() { |
262 // To avoid running into deadlocks while we stop the thread, shut it down | 245 // To avoid running into deadlocks while we stop the thread, shut it down |
263 // via a local variable while not holding the audio thread lock. | 246 // via a local variable while not holding the audio thread lock. |
264 scoped_ptr<media::AudioThread> audio_thread; | 247 scoped_ptr<AudioThread> audio_thread; |
265 { | 248 { |
266 base::AutoLock lock(audio_thread_lock_); | 249 base::AutoLock lock(audio_thread_lock_); |
267 audio_thread_.swap(audio_thread); | 250 audio_thread_.swap(audio_thread); |
268 } | 251 } |
269 | 252 |
270 if (!audio_thread.get()) | 253 if (!audio_thread.get()) |
271 return; | 254 return; |
272 | 255 |
273 CHECK_NE(MessageLoop::current(), audio_thread->message_loop()); | 256 CHECK_NE(MessageLoop::current(), audio_thread->message_loop()); |
274 | 257 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 #else | 302 #else |
320 // TODO(dalecurtis): This should include bits per channel and channel layout | 303 // TODO(dalecurtis): This should include bits per channel and channel layout |
321 // eventually. | 304 // eventually. |
322 return AudioParameters( | 305 return AudioParameters( |
323 AudioParameters::AUDIO_PCM_LOW_LATENCY, input_params.channel_layout(), | 306 AudioParameters::AUDIO_PCM_LOW_LATENCY, input_params.channel_layout(), |
324 GetAudioHardwareSampleRate(), 16, GetAudioHardwareBufferSize()); | 307 GetAudioHardwareSampleRate(), 16, GetAudioHardwareBufferSize()); |
325 #endif // defined(OS_IOS) | 308 #endif // defined(OS_IOS) |
326 } | 309 } |
327 | 310 |
328 } // namespace media | 311 } // namespace media |
OLD | NEW |