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 |