Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: media/audio/audio_manager_base.cc

Issue 15979015: Reland 15721002: Hook up the device selection to the WebAudio live audio (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed the comments. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/audio_manager_base.h ('k') | media/audio/audio_output_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/message_loop_proxy.h" 9 #include "base/message_loop_proxy.h"
10 #include "base/threading/thread.h" 10 #include "base/threading/thread.h"
(...skipping 14 matching lines...) Expand all
25 25
26 // Default maximum number of input streams that can be open simultaneously 26 // Default maximum number of input streams that can be open simultaneously
27 // for all platforms. 27 // for all platforms.
28 static const int kDefaultMaxInputStreams = 16; 28 static const int kDefaultMaxInputStreams = 16;
29 29
30 static const int kMaxInputChannels = 2; 30 static const int kMaxInputChannels = 2;
31 31
32 const char AudioManagerBase::kDefaultDeviceName[] = "Default"; 32 const char AudioManagerBase::kDefaultDeviceName[] = "Default";
33 const char AudioManagerBase::kDefaultDeviceId[] = "default"; 33 const char AudioManagerBase::kDefaultDeviceId[] = "default";
34 34
35 struct AudioManagerBase::DispatcherParams {
36 DispatcherParams(const AudioParameters& input,
37 const AudioParameters& output,
38 const std::string& device_id)
39 : input_params(input),
40 output_params(output),
41 input_device_id(device_id) {}
42 ~DispatcherParams() {}
43
44 const AudioParameters input_params;
45 const AudioParameters output_params;
46 const std::string input_device_id;
47 scoped_refptr<AudioOutputDispatcher> dispatcher;
48
49 private:
50 DISALLOW_COPY_AND_ASSIGN(DispatcherParams);
51 };
52
53 class AudioManagerBase::CompareByParams {
54 public:
55 explicit CompareByParams(const DispatcherParams* dispatcher)
56 : dispatcher_(dispatcher) {}
57 bool operator()(DispatcherParams* dispatcher_in) const {
58 // We will reuse the existing dispatcher when:
59 // 1) Unified IO is not used, input_params and output_params of the
60 // existing dispatcher are the same as the requested dispatcher.
61 // 2) Unified IO is used, input_params, output_params and input_device_id
62 // of the existing dispatcher are the same as the request dispatcher.
63 return (dispatcher_->input_params == dispatcher_in->input_params &&
64 dispatcher_->output_params == dispatcher_in->output_params &&
65 (!dispatcher_->input_params.input_channels() ||
66 dispatcher_->input_device_id == dispatcher_in->input_device_id));
67 }
68
69 private:
70 const DispatcherParams* dispatcher_;
71 };
72
35 AudioManagerBase::AudioManagerBase() 73 AudioManagerBase::AudioManagerBase()
36 : num_active_input_streams_(0), 74 : num_active_input_streams_(0),
37 max_num_output_streams_(kDefaultMaxOutputStreams), 75 max_num_output_streams_(kDefaultMaxOutputStreams),
38 max_num_input_streams_(kDefaultMaxInputStreams), 76 max_num_input_streams_(kDefaultMaxInputStreams),
39 num_output_streams_(0), 77 num_output_streams_(0),
40 num_input_streams_(0), 78 num_input_streams_(0),
41 output_listeners_( 79 output_listeners_(
42 ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY), 80 ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY),
43 audio_thread_(new base::Thread("AudioThread")) { 81 audio_thread_(new base::Thread("AudioThread")) {
44 #if defined(OS_WIN) 82 #if defined(OS_WIN)
(...skipping 25 matching lines...) Expand all
70 108
71 string16 AudioManagerBase::GetAudioInputDeviceModel() { 109 string16 AudioManagerBase::GetAudioInputDeviceModel() {
72 return string16(); 110 return string16();
73 } 111 }
74 112
75 scoped_refptr<base::MessageLoopProxy> AudioManagerBase::GetMessageLoop() { 113 scoped_refptr<base::MessageLoopProxy> AudioManagerBase::GetMessageLoop() {
76 return message_loop_; 114 return message_loop_;
77 } 115 }
78 116
79 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( 117 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream(
80 const AudioParameters& params) { 118 const AudioParameters& params,
119 const std::string& input_device_id) {
81 // TODO(miu): Fix ~50 call points across several unit test modules to call 120 // TODO(miu): Fix ~50 call points across several unit test modules to call
82 // this method on the audio thread, then uncomment the following: 121 // this method on the audio thread, then uncomment the following:
83 // DCHECK(message_loop_->BelongsToCurrentThread()); 122 // DCHECK(message_loop_->BelongsToCurrentThread());
84 123
85 if (!params.IsValid()) { 124 if (!params.IsValid()) {
86 DLOG(ERROR) << "Audio parameters are invalid"; 125 DLOG(ERROR) << "Audio parameters are invalid";
87 return NULL; 126 return NULL;
88 } 127 }
89 128
90 // Limit the number of audio streams opened. This is to prevent using 129 // Limit the number of audio streams opened. This is to prevent using
91 // excessive resources for a large number of audio streams. More 130 // excessive resources for a large number of audio streams. More
92 // importantly it prevents instability on certain systems. 131 // importantly it prevents instability on certain systems.
93 // See bug: http://crbug.com/30242. 132 // See bug: http://crbug.com/30242.
94 if (num_output_streams_ >= max_num_output_streams_) { 133 if (num_output_streams_ >= max_num_output_streams_) {
95 DLOG(ERROR) << "Number of opened output audio streams " 134 DLOG(ERROR) << "Number of opened output audio streams "
96 << num_output_streams_ 135 << num_output_streams_
97 << " exceed the max allowed number " 136 << " exceed the max allowed number "
98 << max_num_output_streams_; 137 << max_num_output_streams_;
99 return NULL; 138 return NULL;
100 } 139 }
101 140
102 AudioOutputStream* stream; 141 AudioOutputStream* stream;
103 switch (params.format()) { 142 switch (params.format()) {
104 case AudioParameters::AUDIO_PCM_LINEAR: 143 case AudioParameters::AUDIO_PCM_LINEAR:
105 stream = MakeLinearOutputStream(params); 144 stream = MakeLinearOutputStream(params);
106 break; 145 break;
107 case AudioParameters::AUDIO_PCM_LOW_LATENCY: 146 case AudioParameters::AUDIO_PCM_LOW_LATENCY:
108 stream = MakeLowLatencyOutputStream(params); 147 stream = MakeLowLatencyOutputStream(params, input_device_id);
109 break; 148 break;
110 case AudioParameters::AUDIO_FAKE: 149 case AudioParameters::AUDIO_FAKE:
111 stream = FakeAudioOutputStream::MakeFakeStream(this, params); 150 stream = FakeAudioOutputStream::MakeFakeStream(this, params);
112 break; 151 break;
113 default: 152 default:
114 stream = NULL; 153 stream = NULL;
115 break; 154 break;
116 } 155 }
117 156
118 if (stream) { 157 if (stream) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 } 197 }
159 198
160 if (stream) { 199 if (stream) {
161 ++num_input_streams_; 200 ++num_input_streams_;
162 } 201 }
163 202
164 return stream; 203 return stream;
165 } 204 }
166 205
167 AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( 206 AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy(
168 const AudioParameters& params) { 207 const AudioParameters& params, const std::string& input_device_id) {
169 #if defined(OS_IOS) 208 #if defined(OS_IOS)
170 // IOS implements audio input only. 209 // IOS implements audio input only.
171 NOTIMPLEMENTED(); 210 NOTIMPLEMENTED();
172 return NULL; 211 return NULL;
173 #else 212 #else
174 DCHECK(message_loop_->BelongsToCurrentThread()); 213 DCHECK(message_loop_->BelongsToCurrentThread());
175 214
176 // If we're not using AudioOutputResampler our output parameters are the same 215 // If we're not using AudioOutputResampler our output parameters are the same
177 // as our input parameters. 216 // as our input parameters.
178 AudioParameters output_params = params; 217 AudioParameters output_params = params;
(...skipping 13 matching lines...) Expand all
192 << output_params.frames_per_buffer(); 231 << output_params.frames_per_buffer();
193 232
194 // Tell the AudioManager to create a fake output device. 233 // Tell the AudioManager to create a fake output device.
195 output_params = AudioParameters( 234 output_params = AudioParameters(
196 AudioParameters::AUDIO_FAKE, params.channel_layout(), 235 AudioParameters::AUDIO_FAKE, params.channel_layout(),
197 params.sample_rate(), params.bits_per_sample(), 236 params.sample_rate(), params.bits_per_sample(),
198 params.frames_per_buffer()); 237 params.frames_per_buffer());
199 } 238 }
200 } 239 }
201 240
202 std::pair<AudioParameters, AudioParameters> dispatcher_key = 241 DispatcherParams* dispatcher_params =
203 std::make_pair(params, output_params); 242 new DispatcherParams(params, output_params, input_device_id);
204 AudioOutputDispatchersMap::iterator it = 243
205 output_dispatchers_.find(dispatcher_key); 244 AudioOutputDispatchers::iterator it =
206 if (it != output_dispatchers_.end()) 245 std::find_if(output_dispatchers_.begin(), output_dispatchers_.end(),
207 return new AudioOutputProxy(it->second.get()); 246 CompareByParams(dispatcher_params));
247 if (it != output_dispatchers_.end()) {
248 delete dispatcher_params;
249 return new AudioOutputProxy((*it)->dispatcher);
250 }
208 251
209 const base::TimeDelta kCloseDelay = 252 const base::TimeDelta kCloseDelay =
210 base::TimeDelta::FromSeconds(kStreamCloseDelaySeconds); 253 base::TimeDelta::FromSeconds(kStreamCloseDelaySeconds);
211 254
212 if (output_params.format() != AudioParameters::AUDIO_FAKE) { 255 if (output_params.format() != AudioParameters::AUDIO_FAKE) {
213 scoped_refptr<AudioOutputDispatcher> dispatcher = 256 scoped_refptr<AudioOutputDispatcher> dispatcher =
214 new AudioOutputResampler(this, params, output_params, kCloseDelay); 257 new AudioOutputResampler(this, params, output_params, input_device_id,
215 output_dispatchers_[dispatcher_key] = dispatcher; 258 kCloseDelay);
259 dispatcher_params->dispatcher = dispatcher;
216 return new AudioOutputProxy(dispatcher.get()); 260 return new AudioOutputProxy(dispatcher.get());
Jeffrey Yasskin 2013/08/07 23:00:47 This leaks the dispatcher_params. What did you mea
no longer working on chromium 2013/08/08 08:35:00 Oh, thanks for finding it out, I am making a CL to
217 } 261 }
218 262
219 scoped_refptr<AudioOutputDispatcher> dispatcher = 263 scoped_refptr<AudioOutputDispatcher> dispatcher =
220 new AudioOutputDispatcherImpl(this, output_params, kCloseDelay); 264 new AudioOutputDispatcherImpl(this, output_params, input_device_id,
221 output_dispatchers_[dispatcher_key] = dispatcher; 265 kCloseDelay);
266 dispatcher_params->dispatcher = dispatcher;
267 output_dispatchers_.push_back(dispatcher_params);
222 return new AudioOutputProxy(dispatcher.get()); 268 return new AudioOutputProxy(dispatcher.get());
223 #endif // defined(OS_IOS) 269 #endif // defined(OS_IOS)
224 } 270 }
225 271
226 void AudioManagerBase::ShowAudioInputSettings() { 272 void AudioManagerBase::ShowAudioInputSettings() {
227 } 273 }
228 274
229 void AudioManagerBase::GetAudioInputDeviceNames( 275 void AudioManagerBase::GetAudioInputDeviceNames(
230 media::AudioDeviceNames* device_names) { 276 media::AudioDeviceNames* device_names) {
231 } 277 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 331
286 void AudioManagerBase::ShutdownOnAudioThread() { 332 void AudioManagerBase::ShutdownOnAudioThread() {
287 // IOS implements audio input only. 333 // IOS implements audio input only.
288 #if defined(OS_IOS) 334 #if defined(OS_IOS)
289 return; 335 return;
290 #else 336 #else
291 // This should always be running on the audio thread, but since we've cleared 337 // This should always be running on the audio thread, but since we've cleared
292 // the audio_thread_ member pointer when we get here, we can't verify exactly 338 // the audio_thread_ member pointer when we get here, we can't verify exactly
293 // what thread we're running on. The method is not public though and only 339 // what thread we're running on. The method is not public though and only
294 // called from one place, so we'll leave it at that. 340 // called from one place, so we'll leave it at that.
295 AudioOutputDispatchersMap::iterator it = output_dispatchers_.begin(); 341 AudioOutputDispatchers::iterator it = output_dispatchers_.begin();
296 for (; it != output_dispatchers_.end(); ++it) { 342 for (; it != output_dispatchers_.end(); ++it) {
297 scoped_refptr<AudioOutputDispatcher>& dispatcher = (*it).second; 343 scoped_refptr<AudioOutputDispatcher>& dispatcher = (*it)->dispatcher;
298 if (dispatcher.get()) { 344 if (dispatcher.get()) {
299 dispatcher->Shutdown(); 345 dispatcher->Shutdown();
300 // All AudioOutputProxies must have been freed before Shutdown is called. 346 // All AudioOutputProxies must have been freed before Shutdown is called.
301 // If they still exist, things will go bad. They have direct pointers to 347 // If they still exist, things will go bad. They have direct pointers to
302 // both physical audio stream objects that belong to the dispatcher as 348 // both physical audio stream objects that belong to the dispatcher as
303 // well as the message loop of the audio thread that will soon go away. 349 // well as the message loop of the audio thread that will soon go away.
304 // So, better crash now than later. 350 // So, better crash now than later.
305 DCHECK(dispatcher->HasOneRef()) << "AudioOutputProxies are still alive"; 351 DCHECK(dispatcher->HasOneRef()) << "AudioOutputProxies are still alive";
306 dispatcher = NULL; 352 dispatcher = NULL;
307 } 353 }
(...skipping 25 matching lines...) Expand all
333 return GetPreferredOutputStreamParameters(AudioParameters()); 379 return GetPreferredOutputStreamParameters(AudioParameters());
334 } 380 }
335 381
336 AudioParameters AudioManagerBase::GetInputStreamParameters( 382 AudioParameters AudioManagerBase::GetInputStreamParameters(
337 const std::string& device_id) { 383 const std::string& device_id) {
338 NOTREACHED(); 384 NOTREACHED();
339 return AudioParameters(); 385 return AudioParameters();
340 } 386 }
341 387
342 } // namespace media 388 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_manager_base.h ('k') | media/audio/audio_output_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698