Index: content/browser/renderer_host/media/web_contents_audio_input_stream.cc |
diff --git a/content/browser/renderer_host/media/web_contents_audio_input_stream.cc b/content/browser/renderer_host/media/web_contents_audio_input_stream.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..64ebf47484d5bc10afe8b7333cc2a097e7c138d5 |
--- /dev/null |
+++ b/content/browser/renderer_host/media/web_contents_audio_input_stream.cc |
@@ -0,0 +1,166 @@ |
+// 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/browser/renderer_host/media/web_contents_audio_input_stream.h" |
+ |
+#include <string> |
+ |
+#include "base/bind.h" |
+#include "base/logging.h" |
+#include "content/browser/renderer_host/media/audio_renderer_host.h" |
+#include "media/base/bind_to_loop.h" |
+ |
+namespace content { |
+ |
+//static |
+WebContentsAudioInputStream* WebContentsAudioInputStream::Create( |
+ const std::string& device_id) { |
+ int render_process_id; |
+ int render_view_id; |
+ if (!WebContentsCaptureUtil::ExtractTabCaptureTarget( |
+ device_id, &render_process_id, &render_view_id)) { |
+ return NULL; |
+ } |
+ |
+ return new WebContentsAudioInputStream(render_process_id, render_view_id); |
+} |
+ |
+WebContentsAudioInputStream::WebContentsAudioInputStream(int render_process_id, |
+ int render_view_id) |
+ : state_(kConstructed), |
+ target_render_process_id_(render_process_id), |
+ target_render_view_id_(render_view_id) { |
+} |
+ |
+WebContentsAudioInputStream::~WebContentsAudioInputStream() { |
+ DCHECK(!tracker_) << "BUG: Close() not called after Open()."; |
+} |
+ |
+bool WebContentsAudioInputStream::Open() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ if (state_ != kConstructed) { |
+ return false; |
+ } |
+ |
+ state_ = kOpened; |
+ |
+ DCHECK(!tracker_); |
+ tracker_ = new WebContentsCaptureUtil::RenderViewTracker(); |
+ tracker_->Start( |
+ target_render_process_id_, target_render_view_id_, |
+ media::BindToLoop( |
+ base::MessageLoopProxy::current(), |
+ base::Bind(&WebContentsAudioInputStream::OnTargetChanged, this))); |
+ |
+ return true; |
+} |
+ |
+void WebContentsAudioInputStream::Start(AudioInputCallback* callback) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ if (state_ != kOpened) { |
+ return; |
+ } |
+ |
+ state_ = kRecording; |
+ |
+ if (target_host_) { |
+ target_host_->StartMirroring(target_render_view_id_, this); |
Alpha Left Google
2012/11/26 22:59:59
Does it work if WCAIS doesn't own or reference ARH
miu
2012/11/28 05:05:01
Done.
|
+ } |
+} |
+ |
+void WebContentsAudioInputStream::Stop() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ if (state_ != kRecording) { |
+ return; |
+ } |
+ |
+ if (target_host_) { |
+ target_host_->StopMirroring(target_render_view_id_, this); |
Alpha Left Google
2012/11/26 22:59:59
What if this becomes AudioRendererHost::StopMirror
miu
2012/11/28 05:05:01
Done.
|
+ } |
+ |
+ state_ = kOpened; |
+} |
+ |
+void WebContentsAudioInputStream::Close() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ Stop(); |
+ |
+ target_host_ = NULL; |
+ tracker_->Stop(); |
+ tracker_ = NULL; |
+ |
+ state_ = kClosed; |
+} |
+ |
+void WebContentsAudioInputStream::OnTargetChanged(int render_process_id, |
+ int render_view_id) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ if (target_render_process_id_ == render_process_id && |
+ target_render_view_id_ == render_view_id) { |
+ return; |
+ } |
+ |
+ if (state_ == kRecording) { |
+ if (target_host_) { |
+ target_host_->StopMirroring(target_render_view_id_, this); |
+ } |
+ } |
+ |
+ target_render_process_id_ = render_process_id; |
+ target_render_view_id_ = render_view_id; |
+ target_host_ = AudioRendererHost::FromRenderProcessID(render_process_id); |
+ |
+ if (state_ == kRecording) { |
+ if (target_host_) { |
+ target_host_->StartMirroring(target_render_view_id_, this); |
+ } |
+ } |
+} |
+ |
+double WebContentsAudioInputStream::GetMaxVolume() { |
+ return 1.0; |
+} |
+ |
+void WebContentsAudioInputStream::SetVolume(double volume) { |
+ // no-op |
+} |
+ |
+double WebContentsAudioInputStream::GetVolume() { |
+ return 1.0; |
+} |
+ |
+void WebContentsAudioInputStream::SetAutomaticGainControl(bool enabled) { |
+ // no-op |
+} |
+ |
+bool WebContentsAudioInputStream::GetAutomaticGainControl() { |
+ return false; |
+} |
+ |
+void WebContentsAudioInputStream::AddAudioOutputStream( |
+ media::DivertedAudioOutputStream* aos) { |
+ base::AutoLock guard(streams_lock_); |
Alpha Left Google
2012/11/26 22:59:59
Is a lock necessary here? I see these two methods
miu
2012/11/28 05:05:01
Removed the locking for now. I agree that it'll p
|
+ DCHECK(!streams_.count(aos)) << "BUG: Adding same stream twice."; |
+ streams_.insert(aos); |
+ |
+ DVLOG(1) << "STUB: WebContentsAudioInputStream@" << this |
+ << "->AddAudioOutputStream(" << aos << ')'; |
+} |
+ |
+void WebContentsAudioInputStream::RemoveAudioOutputStream( |
+ media::DivertedAudioOutputStream* aos) { |
+ base::AutoLock guard(streams_lock_); |
+ DCHECK(streams_.count(aos)) << "BUG: Removing unknown stream."; |
+ streams_.erase(aos); |
+ |
+ DVLOG(1) << "STUB: WebContentsAudioInputStream@" << this |
+ << "->RemoveAudioOutputStream(" << aos << ')'; |
+} |
+ |
+} // namespace content |