OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/browser/renderer_host/media/web_contents_audio_input_stream.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/logging.h" | |
11 #include "content/browser/renderer_host/media/audio_renderer_host.h" | |
12 #include "media/base/bind_to_loop.h" | |
13 | |
14 namespace content { | |
15 | |
16 //static | |
17 WebContentsAudioInputStream* WebContentsAudioInputStream::Create( | |
18 const std::string& device_id) { | |
19 int render_process_id; | |
20 int render_view_id; | |
21 if (!WebContentsCaptureUtil::ExtractTabCaptureTarget( | |
22 device_id, &render_process_id, &render_view_id)) { | |
23 return NULL; | |
24 } | |
25 | |
26 return new WebContentsAudioInputStream(render_process_id, render_view_id); | |
27 } | |
28 | |
29 WebContentsAudioInputStream::WebContentsAudioInputStream(int render_process_id, | |
30 int render_view_id) | |
31 : state_(kConstructed), | |
32 target_render_process_id_(render_process_id), | |
33 target_render_view_id_(render_view_id) { | |
34 } | |
35 | |
36 WebContentsAudioInputStream::~WebContentsAudioInputStream() { | |
37 DCHECK(!tracker_) << "BUG: Close() not called after Open()."; | |
38 } | |
39 | |
40 bool WebContentsAudioInputStream::Open() { | |
41 DCHECK(thread_checker_.CalledOnValidThread()); | |
42 | |
43 if (state_ != kConstructed) { | |
44 return false; | |
45 } | |
46 | |
47 state_ = kOpened; | |
48 | |
49 DCHECK(!tracker_); | |
50 tracker_ = new WebContentsCaptureUtil::RenderViewTracker(); | |
51 tracker_->Start( | |
52 target_render_process_id_, target_render_view_id_, | |
53 media::BindToLoop( | |
54 base::MessageLoopProxy::current(), | |
55 base::Bind(&WebContentsAudioInputStream::OnTargetChanged, this))); | |
56 | |
57 return true; | |
58 } | |
59 | |
60 void WebContentsAudioInputStream::Start(AudioInputCallback* callback) { | |
61 DCHECK(thread_checker_.CalledOnValidThread()); | |
62 | |
63 if (state_ != kOpened) { | |
64 return; | |
65 } | |
66 | |
67 state_ = kRecording; | |
68 | |
69 if (target_host_) { | |
70 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.
| |
71 } | |
72 } | |
73 | |
74 void WebContentsAudioInputStream::Stop() { | |
75 DCHECK(thread_checker_.CalledOnValidThread()); | |
76 | |
77 if (state_ != kRecording) { | |
78 return; | |
79 } | |
80 | |
81 if (target_host_) { | |
82 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.
| |
83 } | |
84 | |
85 state_ = kOpened; | |
86 } | |
87 | |
88 void WebContentsAudioInputStream::Close() { | |
89 DCHECK(thread_checker_.CalledOnValidThread()); | |
90 | |
91 Stop(); | |
92 | |
93 target_host_ = NULL; | |
94 tracker_->Stop(); | |
95 tracker_ = NULL; | |
96 | |
97 state_ = kClosed; | |
98 } | |
99 | |
100 void WebContentsAudioInputStream::OnTargetChanged(int render_process_id, | |
101 int render_view_id) { | |
102 DCHECK(thread_checker_.CalledOnValidThread()); | |
103 | |
104 if (target_render_process_id_ == render_process_id && | |
105 target_render_view_id_ == render_view_id) { | |
106 return; | |
107 } | |
108 | |
109 if (state_ == kRecording) { | |
110 if (target_host_) { | |
111 target_host_->StopMirroring(target_render_view_id_, this); | |
112 } | |
113 } | |
114 | |
115 target_render_process_id_ = render_process_id; | |
116 target_render_view_id_ = render_view_id; | |
117 target_host_ = AudioRendererHost::FromRenderProcessID(render_process_id); | |
118 | |
119 if (state_ == kRecording) { | |
120 if (target_host_) { | |
121 target_host_->StartMirroring(target_render_view_id_, this); | |
122 } | |
123 } | |
124 } | |
125 | |
126 double WebContentsAudioInputStream::GetMaxVolume() { | |
127 return 1.0; | |
128 } | |
129 | |
130 void WebContentsAudioInputStream::SetVolume(double volume) { | |
131 // no-op | |
132 } | |
133 | |
134 double WebContentsAudioInputStream::GetVolume() { | |
135 return 1.0; | |
136 } | |
137 | |
138 void WebContentsAudioInputStream::SetAutomaticGainControl(bool enabled) { | |
139 // no-op | |
140 } | |
141 | |
142 bool WebContentsAudioInputStream::GetAutomaticGainControl() { | |
143 return false; | |
144 } | |
145 | |
146 void WebContentsAudioInputStream::AddAudioOutputStream( | |
147 media::DivertedAudioOutputStream* aos) { | |
148 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
| |
149 DCHECK(!streams_.count(aos)) << "BUG: Adding same stream twice."; | |
150 streams_.insert(aos); | |
151 | |
152 DVLOG(1) << "STUB: WebContentsAudioInputStream@" << this | |
153 << "->AddAudioOutputStream(" << aos << ')'; | |
154 } | |
155 | |
156 void WebContentsAudioInputStream::RemoveAudioOutputStream( | |
157 media::DivertedAudioOutputStream* aos) { | |
158 base::AutoLock guard(streams_lock_); | |
159 DCHECK(streams_.count(aos)) << "BUG: Removing unknown stream."; | |
160 streams_.erase(aos); | |
161 | |
162 DVLOG(1) << "STUB: WebContentsAudioInputStream@" << this | |
163 << "->RemoveAudioOutputStream(" << aos << ')'; | |
164 } | |
165 | |
166 } // namespace content | |
OLD | NEW |