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..b64a8fd34e1b734427c4105b7fa4c9e080f38d0e |
--- /dev/null |
+++ b/content/browser/renderer_host/media/web_contents_audio_input_stream.cc |
@@ -0,0 +1,169 @@ |
+// 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 "content/public/browser/browser_thread.h" |
+#include "media/base/bind_to_loop.h" |
+ |
+namespace content { |
+ |
+//static |
+WebContentsAudioInputStream* WebContentsAudioInputStream::Create( |
+ const std::string& device_id, |
+ const media::AudioParameters& params) { |
+ 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, params); |
+} |
+ |
+WebContentsAudioInputStream::WebContentsAudioInputStream( |
+ int render_process_id, int render_view_id, |
+ const media::AudioParameters& params) |
+ : params_(params), |
+ thread_checker_(), |
+ 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; |
+ |
+ AudioRendererHost::StartMirroring( |
+ target_render_process_id_, target_render_view_id_, this); |
+} |
+ |
+void WebContentsAudioInputStream::Stop() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ if (state_ != kRecording) { |
+ return; |
+ } |
+ |
+ AudioRendererHost::StopMirroring( |
+ target_render_process_id_, target_render_view_id_, this); |
+ |
+ state_ = kOpened; |
+} |
+ |
+void WebContentsAudioInputStream::Close() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ Stop(); |
+ |
+ 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) { |
+ AudioRendererHost::StopMirroring( |
Alpha Left Google
2012/11/28 20:02:25
This is on IO thread right?
miu
2012/11/28 22:05:50
Nope. Audio thread. See my other comments for ex
|
+ target_render_process_id_, target_render_view_id_, this); |
+ } |
+ |
+ target_render_process_id_ = render_process_id; |
+ target_render_view_id_ = render_view_id; |
+ |
+ if (state_ == kRecording) { |
+ AudioRendererHost::StartMirroring( |
+ target_render_process_id_, 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::AddInput( |
+ media::AudioOutputStream::AudioSourceCallback* callback, |
+ const media::AudioParameters& params){ |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ DCHECK(!source_params_.count(callback)) << "BUG: Adding same callback twice."; |
+ source_params_.insert(std::make_pair(callback, params)); |
+ |
+ DVLOG(1) << "STUB: WebContentsAudioInputStream@" << this |
+ << "->AddInput(" << callback << ')'; |
+} |
+ |
+void WebContentsAudioInputStream::RemoveInput( |
+ media::AudioOutputStream::AudioSourceCallback* callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ DCHECK(source_params_.count(callback)) << "BUG: Removing unknown callback."; |
+ source_params_.erase(callback); |
+ |
+ DVLOG(1) << "STUB: WebContentsAudioInputStream@" << this |
+ << "->RemoveInput(" << callback << ')'; |
+} |
+ |
+} // namespace content |