Chromium Code Reviews| Index: media/audio/audio_manager_base.cc |
| diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc |
| index 07c56b6e4c0fe9f1c604ccea605bac16cec751e7..43dc31e20e742cbe56554c307ad1cf3efdd5b4c0 100644 |
| --- a/media/audio/audio_manager_base.cc |
| +++ b/media/audio/audio_manager_base.cc |
| @@ -32,6 +32,44 @@ static const int kMaxInputChannels = 2; |
| const char AudioManagerBase::kDefaultDeviceName[] = "Default"; |
| const char AudioManagerBase::kDefaultDeviceId[] = "default"; |
| +struct AudioManagerBase::DispatcherParams { |
| + DispatcherParams(const AudioParameters& input, |
| + const AudioParameters& output, |
| + const std::string& device_id) |
| + : input_params(input), |
| + output_params(output), |
| + input_device_id(device_id) {} |
| + ~DispatcherParams() {} |
| + |
| + const AudioParameters input_params; |
| + const AudioParameters output_params; |
| + const std::string input_device_id; |
| + scoped_refptr<AudioOutputDispatcher> dispatcher; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(DispatcherParams); |
| +}; |
| + |
| +class AudioManagerBase::CompareByParams { |
| + public: |
| + explicit CompareByParams(const DispatcherParams* dispatcher) |
| + : dispatcher_(dispatcher) {} |
| + bool operator()(DispatcherParams* dispatcher_in) const { |
| + // We will reuse the existing dispatcher when: |
| + // 1) Unified IO is not used, input_params and output_params of the |
| + // existing dispatcher are the same as the requested dispatcher. |
| + // 2) Unified IO is used, input_params, output_params and input_device_id |
| + // of the existing dispatcher are the same as the request dispatcher. |
| + return (dispatcher_->input_params == dispatcher_in->input_params && |
| + dispatcher_->output_params == dispatcher_in->output_params && |
| + (!dispatcher_->input_params.input_channels() || |
| + dispatcher_->input_device_id == dispatcher_in->input_device_id)); |
| + } |
| + |
| + private: |
| + const DispatcherParams* dispatcher_; |
| +}; |
| + |
| AudioManagerBase::AudioManagerBase() |
| : num_active_input_streams_(0), |
| max_num_output_streams_(kDefaultMaxOutputStreams), |
| @@ -77,7 +115,8 @@ scoped_refptr<base::MessageLoopProxy> AudioManagerBase::GetMessageLoop() { |
| } |
| AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( |
| - const AudioParameters& params) { |
| + const AudioParameters& params, |
| + const std::string& input_device_id) { |
| // TODO(miu): Fix ~50 call points across several unit test modules to call |
| // this method on the audio thread, then uncomment the following: |
| // DCHECK(message_loop_->BelongsToCurrentThread()); |
| @@ -105,7 +144,7 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( |
| stream = MakeLinearOutputStream(params); |
| break; |
| case AudioParameters::AUDIO_PCM_LOW_LATENCY: |
| - stream = MakeLowLatencyOutputStream(params); |
| + stream = MakeLowLatencyOutputStream(params, input_device_id); |
| break; |
| case AudioParameters::AUDIO_FAKE: |
| stream = FakeAudioOutputStream::MakeFakeStream(this, params); |
| @@ -165,7 +204,7 @@ AudioInputStream* AudioManagerBase::MakeAudioInputStream( |
| } |
| AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( |
| - const AudioParameters& params) { |
| + const AudioParameters& params, const std::string& input_device_id) { |
| #if defined(OS_IOS) |
| // IOS implements audio input only. |
| NOTIMPLEMENTED(); |
| @@ -199,26 +238,33 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( |
| } |
| } |
| - std::pair<AudioParameters, AudioParameters> dispatcher_key = |
| - std::make_pair(params, output_params); |
| - AudioOutputDispatchersMap::iterator it = |
| - output_dispatchers_.find(dispatcher_key); |
| - if (it != output_dispatchers_.end()) |
| - return new AudioOutputProxy(it->second.get()); |
| + DispatcherParams* dispatcher_params = |
| + new DispatcherParams(params, output_params, input_device_id); |
| + |
| + AudioOutputDispatchers::iterator it = |
| + std::find_if(output_dispatchers_.begin(), output_dispatchers_.end(), |
| + CompareByParams(dispatcher_params)); |
| + if (it != output_dispatchers_.end()) { |
| + delete dispatcher_params; |
| + return new AudioOutputProxy((*it)->dispatcher); |
| + } |
| const base::TimeDelta kCloseDelay = |
| base::TimeDelta::FromSeconds(kStreamCloseDelaySeconds); |
| if (output_params.format() != AudioParameters::AUDIO_FAKE) { |
| scoped_refptr<AudioOutputDispatcher> dispatcher = |
| - new AudioOutputResampler(this, params, output_params, kCloseDelay); |
| - output_dispatchers_[dispatcher_key] = dispatcher; |
| + new AudioOutputResampler(this, params, output_params, input_device_id, |
| + kCloseDelay); |
| + dispatcher_params->dispatcher = dispatcher; |
| 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
|
| } |
| scoped_refptr<AudioOutputDispatcher> dispatcher = |
| - new AudioOutputDispatcherImpl(this, output_params, kCloseDelay); |
| - output_dispatchers_[dispatcher_key] = dispatcher; |
| + new AudioOutputDispatcherImpl(this, output_params, input_device_id, |
| + kCloseDelay); |
| + dispatcher_params->dispatcher = dispatcher; |
| + output_dispatchers_.push_back(dispatcher_params); |
| return new AudioOutputProxy(dispatcher.get()); |
| #endif // defined(OS_IOS) |
| } |
| @@ -292,9 +338,9 @@ void AudioManagerBase::ShutdownOnAudioThread() { |
| // the audio_thread_ member pointer when we get here, we can't verify exactly |
| // what thread we're running on. The method is not public though and only |
| // called from one place, so we'll leave it at that. |
| - AudioOutputDispatchersMap::iterator it = output_dispatchers_.begin(); |
| + AudioOutputDispatchers::iterator it = output_dispatchers_.begin(); |
| for (; it != output_dispatchers_.end(); ++it) { |
| - scoped_refptr<AudioOutputDispatcher>& dispatcher = (*it).second; |
| + scoped_refptr<AudioOutputDispatcher>& dispatcher = (*it)->dispatcher; |
| if (dispatcher.get()) { |
| dispatcher->Shutdown(); |
| // All AudioOutputProxies must have been freed before Shutdown is called. |