Chromium Code Reviews| Index: content/renderer/media/restartable_audio_output_device_factory.cc |
| diff --git a/content/renderer/media/restartable_audio_output_device_factory.cc b/content/renderer/media/restartable_audio_output_device_factory.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c72259f423678c243af1fa4e8aa0549880c4c503 |
| --- /dev/null |
| +++ b/content/renderer/media/restartable_audio_output_device_factory.cc |
| @@ -0,0 +1,110 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/renderer/media/restartable_audio_output_device_factory.h" |
| + |
| +#include "content/renderer/media/audio_device_factory.h" |
| +#include "content/renderer/media/audio_renderer_mixer_manager.h" |
| +#include "content/renderer/render_thread_impl.h" |
| +#include "media/audio/audio_output_device.h" |
| +#include "media/audio/restartable_audio_output_device_impl.h" |
| +#include "media/base/audio_renderer_mixer_input.h" |
| +#include "url/origin.h" |
| + |
| +namespace content { |
| + |
| +RestartableAudioOutputDeviceFactory* |
| + RestartableAudioOutputDeviceFactory::factory_ = nullptr; |
| + |
| +namespace { |
| + |
| +// This is where we decide which audio will go to mixers and wich one to |
| +// AudioOutpuDevice directly. |
| +bool IsMixable(RestartableAudioOutputDeviceFactory::SourceType source_type) { |
| + if (source_type == RestartableAudioOutputDeviceFactory::kSourceHighLatency) |
| + return true; // Must ALWAYS go through mixer. |
| + |
| + // TODO(olka): make a decision for the rest of the sources basing on OS |
| + // type and configuration parameters. |
| + return false; |
| +} |
| + |
| +scoped_refptr<media::RestartableAudioRendererSink> NewMixableSink( |
| + int render_frame_id, |
| + const std::string& device_id, |
| + const url::Origin& security_origin) { |
| + RenderThreadImpl* render_thread = RenderThreadImpl::current(); |
| + return render_thread->GetAudioRendererMixerManager()->CreateInput( |
| + render_frame_id, device_id, security_origin); |
| +} |
| + |
| +scoped_refptr<media::RestartableAudioRendererSink> NewUnmixableSink( |
| + int render_frame_id, |
| + int session_id, |
| + const std::string& device_id, |
| + const url::Origin& security_origin) { |
| + return new media::RestartableAudioOutputDeviceImpl( |
| + base::Bind(&AudioDeviceFactory::NewOutputDevice, render_frame_id, |
| + session_id, device_id, security_origin), |
| + base::Bind(&RestartableAudioOutputDeviceFactory::GetOutputHWParams, |
| + render_frame_id, session_id, device_id, security_origin)); |
| +} |
| + |
| +} // namespace |
| + |
| +// static |
| +scoped_refptr<media::RestartableAudioRendererSink> |
| +RestartableAudioOutputDeviceFactory::NewOutputDevice( |
| + SourceType source_type, |
| + int render_frame_id, |
| + int session_id, |
| + const std::string& device_id, |
| + const url::Origin& security_origin) { |
| + if (factory_) { |
| + media::RestartableAudioRendererSink* const device = |
| + factory_->CreateOutputDevice(source_type, render_frame_id, session_id, |
| + device_id, security_origin); |
| + if (device) |
| + return device; |
| + } |
| + |
| + if (IsMixable(source_type)) |
| + return NewMixableSink(render_frame_id, device_id, security_origin); |
| + |
| + return NewUnmixableSink(render_frame_id, session_id, device_id, |
| + security_origin); |
| +} |
| + |
| +RestartableAudioOutputDeviceFactory::RestartableAudioOutputDeviceFactory() { |
| + DCHECK(!factory_) << "Can't register two factories at once."; |
| + factory_ = this; |
| +} |
| + |
| +RestartableAudioOutputDeviceFactory::~RestartableAudioOutputDeviceFactory() { |
| + factory_ = NULL; |
| +} |
| + |
| +// static |
| +media::AudioParameters RestartableAudioOutputDeviceFactory::GetOutputHWParams( |
|
DaleCurtis
2016/02/08 19:10:25
This adds overhead that I don't think we want. Whe
o1ka
2016/02/09 14:15:38
This is a great idea. I'll take care of it.
|
| + int render_frame_id, |
| + int session_id, |
| + const std::string& device_id, |
| + const url::Origin& security_origin) { |
| + media::AudioParameters params; // Invalid parameters to return by default. |
| + |
| + // AudioOutputDevice is the only interface we have to communicate with output |
| + // device via IPC. So, that's how we get the parameters when there is no |
| + // AudioOutputDevice: |
| + scoped_refptr<media::AudioOutputDevice> aod = |
| + AudioDeviceFactory::NewOutputDevice(render_frame_id, session_id, |
| + device_id, security_origin); |
| + |
| + if (aod->GetDeviceStatus() == media::OUTPUT_DEVICE_STATUS_OK) |
| + params = aod->GetOutputParameters(); |
| + |
| + aod->Stop(); // Must be stopped. |
| + return params; |
| +} |
| + |
| +} // namespace content |