OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/media/capture/web_contents_audio_input_stream.h" | 5 #include "content/browser/media/capture/web_contents_audio_input_stream.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "media/audio/virtual_audio_output_stream.h" | 22 #include "media/audio/virtual_audio_output_stream.h" |
23 #include "media/base/bind_to_current_loop.h" | 23 #include "media/base/bind_to_current_loop.h" |
24 | 24 |
25 namespace content { | 25 namespace content { |
26 | 26 |
27 class WebContentsAudioInputStream::Impl | 27 class WebContentsAudioInputStream::Impl |
28 : public base::RefCountedThreadSafe<WebContentsAudioInputStream::Impl>, | 28 : public base::RefCountedThreadSafe<WebContentsAudioInputStream::Impl>, |
29 public AudioMirroringManager::MirroringDestination { | 29 public AudioMirroringManager::MirroringDestination { |
30 public: | 30 public: |
31 // Takes ownership of |mixer_stream|. The rest outlive this instance. | 31 // Takes ownership of |mixer_stream|. The rest outlive this instance. |
32 Impl(int render_process_id, int main_render_frame_id, | 32 Impl(int render_process_id, |
33 int main_render_frame_id, | |
33 AudioMirroringManager* mirroring_manager, | 34 AudioMirroringManager* mirroring_manager, |
34 const scoped_refptr<WebContentsTracker>& tracker, | 35 const scoped_refptr<WebContentsTracker>& tracker, |
35 media::VirtualAudioInputStream* mixer_stream); | 36 media::VirtualAudioInputStream* mixer_stream, |
37 bool is_duplication); | |
36 | 38 |
37 // Open underlying VirtualAudioInputStream and start tracker. | 39 // Open underlying VirtualAudioInputStream and start tracker. |
38 bool Open(); | 40 bool Open(); |
39 | 41 |
40 // Start the underlying VirtualAudioInputStream and instruct | 42 // Start the underlying VirtualAudioInputStream and instruct |
41 // AudioMirroringManager to begin a mirroring session. | 43 // AudioMirroringManager to begin a mirroring session. |
42 void Start(AudioInputCallback* callback); | 44 void Start(AudioInputCallback* callback); |
43 | 45 |
44 // Stop the underlying VirtualAudioInputStream and instruct | 46 // Stop the underlying VirtualAudioInputStream and instruct |
45 // AudioMirroringManager to shutdown a mirroring session. | 47 // AudioMirroringManager to shutdown a mirroring session. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
79 // successful audio capture. | 81 // successful audio capture. |
80 void UnmuteWebContentsAudio(); | 82 void UnmuteWebContentsAudio(); |
81 | 83 |
82 // AudioMirroringManager::MirroringDestination implementation | 84 // AudioMirroringManager::MirroringDestination implementation |
83 void QueryForMatches(const std::set<SourceFrameRef>& candidates, | 85 void QueryForMatches(const std::set<SourceFrameRef>& candidates, |
84 const MatchesCallback& results_callback) override; | 86 const MatchesCallback& results_callback) override; |
85 void QueryForMatchesOnUIThread(const std::set<SourceFrameRef>& candidates, | 87 void QueryForMatchesOnUIThread(const std::set<SourceFrameRef>& candidates, |
86 const MatchesCallback& results_callback); | 88 const MatchesCallback& results_callback); |
87 media::AudioOutputStream* AddInput( | 89 media::AudioOutputStream* AddInput( |
88 const media::AudioParameters& params) override; | 90 const media::AudioParameters& params) override; |
91 media::AudioPushSink* AddPushInput( | |
92 const media::AudioParameters& params) override; | |
89 | 93 |
90 // Callback which is run when |stream| is closed. Deletes |stream|. | 94 // Callback which is run when |stream| is closed. Deletes |stream|. |
91 void ReleaseInput(media::VirtualAudioOutputStream* stream); | 95 void ReleaseInput(media::VirtualAudioOutputStream* stream); |
96 void ReleasePushInput(media::VirtualAudioSink* sink); | |
92 | 97 |
93 // Called by WebContentsTracker when the target of the audio mirroring has | 98 // Called by WebContentsTracker when the target of the audio mirroring has |
94 // changed. | 99 // changed. |
95 void OnTargetChanged(bool had_target); | 100 void OnTargetChanged(bool had_target); |
96 | 101 |
97 // Injected dependencies. | 102 // Injected dependencies. |
98 const int initial_render_process_id_; | 103 const int initial_render_process_id_; |
99 const int initial_main_render_frame_id_; | 104 const int initial_main_render_frame_id_; |
100 AudioMirroringManager* const mirroring_manager_; | 105 AudioMirroringManager* const mirroring_manager_; |
101 const scoped_refptr<WebContentsTracker> tracker_; | 106 const scoped_refptr<WebContentsTracker> tracker_; |
102 // The AudioInputStream implementation that handles the audio conversion and | 107 // The AudioInputStream implementation that handles the audio conversion and |
103 // mixing details. | 108 // mixing details. |
104 const std::unique_ptr<media::VirtualAudioInputStream> mixer_stream_; | 109 const std::unique_ptr<media::VirtualAudioInputStream> mixer_stream_; |
105 | 110 |
106 State state_; | 111 State state_; |
107 | 112 |
108 // Set to true if |tracker_| reports a NULL target, which indicates the target | 113 // Set to true if |tracker_| reports a NULL target, which indicates the target |
109 // is permanently lost. | 114 // is permanently lost. |
110 bool is_target_lost_; | 115 bool is_target_lost_; |
111 | 116 |
112 // Current callback used to consume the resulting mixed audio data. | 117 // Current callback used to consume the resulting mixed audio data. |
113 AudioInputCallback* callback_; | 118 AudioInputCallback* callback_; |
114 | 119 |
120 // If true, this WebContentsAudioInputStream will request a duplication of | |
121 // audio data. | |
miu
2016/05/06 22:29:49
nit: Append to the end of the sentence: "instead o
qiangchen
2016/05/10 22:36:52
Done.
| |
122 bool is_duplication_; | |
123 | |
115 base::ThreadChecker thread_checker_; | 124 base::ThreadChecker thread_checker_; |
116 | 125 |
117 DISALLOW_COPY_AND_ASSIGN(Impl); | 126 DISALLOW_COPY_AND_ASSIGN(Impl); |
118 }; | 127 }; |
119 | 128 |
120 WebContentsAudioInputStream::Impl::Impl( | 129 WebContentsAudioInputStream::Impl::Impl( |
121 int render_process_id, int main_render_frame_id, | 130 int render_process_id, |
131 int main_render_frame_id, | |
122 AudioMirroringManager* mirroring_manager, | 132 AudioMirroringManager* mirroring_manager, |
123 const scoped_refptr<WebContentsTracker>& tracker, | 133 const scoped_refptr<WebContentsTracker>& tracker, |
124 media::VirtualAudioInputStream* mixer_stream) | 134 media::VirtualAudioInputStream* mixer_stream, |
135 bool is_duplication) | |
125 : initial_render_process_id_(render_process_id), | 136 : initial_render_process_id_(render_process_id), |
126 initial_main_render_frame_id_(main_render_frame_id), | 137 initial_main_render_frame_id_(main_render_frame_id), |
127 mirroring_manager_(mirroring_manager), | 138 mirroring_manager_(mirroring_manager), |
128 tracker_(tracker), | 139 tracker_(tracker), |
129 mixer_stream_(mixer_stream), | 140 mixer_stream_(mixer_stream), |
130 state_(CONSTRUCTED), | 141 state_(CONSTRUCTED), |
131 is_target_lost_(false), | 142 is_target_lost_(false), |
132 callback_(NULL) { | 143 callback_(NULL), |
144 is_duplication_(is_duplication) { | |
133 DCHECK(mirroring_manager_); | 145 DCHECK(mirroring_manager_); |
134 DCHECK(tracker_); | 146 DCHECK(tracker_); |
135 DCHECK(mixer_stream_); | 147 DCHECK(mixer_stream_); |
136 | 148 |
137 // WAIS::Impl can be constructed on any thread, but will DCHECK that all | 149 // WAIS::Impl can be constructed on any thread, but will DCHECK that all |
138 // its methods from here on are called from the same thread. | 150 // its methods from here on are called from the same thread. |
139 thread_checker_.DetachFromThread(); | 151 thread_checker_.DetachFromThread(); |
140 } | 152 } |
141 | 153 |
142 WebContentsAudioInputStream::Impl::~Impl() { | 154 WebContentsAudioInputStream::Impl::~Impl() { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 for (std::set<SourceFrameRef>::const_iterator i = candidates.begin(); | 288 for (std::set<SourceFrameRef>::const_iterator i = candidates.begin(); |
277 i != candidates.end(); ++i) { | 289 i != candidates.end(); ++i) { |
278 WebContents* const contents_containing_frame = | 290 WebContents* const contents_containing_frame = |
279 WebContents::FromRenderFrameHost( | 291 WebContents::FromRenderFrameHost( |
280 RenderFrameHost::FromID(i->first, i->second)); | 292 RenderFrameHost::FromID(i->first, i->second)); |
281 if (contents_containing_frame == contents) | 293 if (contents_containing_frame == contents) |
282 matches.insert(*i); | 294 matches.insert(*i); |
283 } | 295 } |
284 } | 296 } |
285 | 297 |
286 results_callback.Run(matches); | 298 results_callback.Run(matches, is_duplication_); |
287 } | 299 } |
288 | 300 |
289 media::AudioOutputStream* WebContentsAudioInputStream::Impl::AddInput( | 301 media::AudioOutputStream* WebContentsAudioInputStream::Impl::AddInput( |
290 const media::AudioParameters& params) { | 302 const media::AudioParameters& params) { |
291 // Note: The closure created here holds a reference to "this," which will | 303 // Note: The closure created here holds a reference to "this," which will |
292 // guarantee the VirtualAudioInputStream (mixer_stream_) outlives the | 304 // guarantee the VirtualAudioInputStream (mixer_stream_) outlives the |
293 // VirtualAudioOutputStream. | 305 // VirtualAudioOutputStream. |
294 return new media::VirtualAudioOutputStream( | 306 return new media::VirtualAudioOutputStream( |
295 params, | 307 params, |
296 mixer_stream_.get(), | 308 mixer_stream_.get(), |
297 base::Bind(&Impl::ReleaseInput, this)); | 309 base::Bind(&Impl::ReleaseInput, this)); |
298 } | 310 } |
299 | 311 |
300 void WebContentsAudioInputStream::Impl::ReleaseInput( | 312 void WebContentsAudioInputStream::Impl::ReleaseInput( |
301 media::VirtualAudioOutputStream* stream) { | 313 media::VirtualAudioOutputStream* stream) { |
302 delete stream; | 314 delete stream; |
303 } | 315 } |
304 | 316 |
317 media::AudioPushSink* WebContentsAudioInputStream::Impl::AddPushInput( | |
318 const media::AudioParameters& params) { | |
319 // Note: The closure created here holds a reference to "this," which will | |
320 // guarantee the VirtualAudioInputStream (mixer_stream_) outlives the | |
321 // VirtualAudioSink. | |
322 return new media::VirtualAudioSink(params, mixer_stream_.get(), | |
323 base::Bind(&Impl::ReleasePushInput, this)); | |
324 } | |
325 | |
326 void WebContentsAudioInputStream::Impl::ReleasePushInput( | |
327 media::VirtualAudioSink* stream) { | |
328 delete stream; | |
329 } | |
330 | |
305 void WebContentsAudioInputStream::Impl::OnTargetChanged(bool had_target) { | 331 void WebContentsAudioInputStream::Impl::OnTargetChanged(bool had_target) { |
306 DCHECK(thread_checker_.CalledOnValidThread()); | 332 DCHECK(thread_checker_.CalledOnValidThread()); |
307 | 333 |
308 is_target_lost_ = !had_target; | 334 is_target_lost_ = !had_target; |
309 | 335 |
310 if (state_ == MIRRORING) { | 336 if (state_ == MIRRORING) { |
311 if (is_target_lost_) { | 337 if (is_target_lost_) { |
312 ReportError(); | 338 ReportError(); |
313 Stop(); | 339 Stop(); |
314 } else { | 340 } else { |
315 StartMirroring(); | 341 StartMirroring(); |
316 } | 342 } |
317 } | 343 } |
318 } | 344 } |
319 | 345 |
320 // static | 346 // static |
321 WebContentsAudioInputStream* WebContentsAudioInputStream::Create( | 347 WebContentsAudioInputStream* WebContentsAudioInputStream::Create( |
322 const std::string& device_id, | 348 const std::string& device_id, |
323 const media::AudioParameters& params, | 349 const media::AudioParameters& params, |
324 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, | 350 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, |
325 AudioMirroringManager* audio_mirroring_manager) { | 351 AudioMirroringManager* audio_mirroring_manager) { |
326 int render_process_id; | 352 int render_process_id; |
327 int main_render_frame_id; | 353 int main_render_frame_id; |
328 if (!WebContentsMediaCaptureId::ExtractTabCaptureTarget( | 354 if (!WebContentsMediaCaptureId::ExtractTabCaptureTarget( |
329 device_id, &render_process_id, &main_render_frame_id)) { | 355 device_id, &render_process_id, &main_render_frame_id)) { |
330 return NULL; | 356 return NULL; |
331 } | 357 } |
332 | 358 |
359 // TODO(qiangchen): Plug in true for the case of Tab Typed Desktop Share. | |
miu
2016/05/06 22:29:49
Note: The JavaScript API to start tab capture shou
qiangchen
2016/05/10 22:36:52
For the current use case: Cast uses chrome.tabCapt
| |
333 return new WebContentsAudioInputStream( | 360 return new WebContentsAudioInputStream( |
334 render_process_id, main_render_frame_id, | 361 render_process_id, main_render_frame_id, audio_mirroring_manager, |
335 audio_mirroring_manager, | |
336 new WebContentsTracker(false), | 362 new WebContentsTracker(false), |
337 new media::VirtualAudioInputStream( | 363 new media::VirtualAudioInputStream( |
338 params, worker_task_runner, | 364 params, worker_task_runner, |
339 media::VirtualAudioInputStream::AfterCloseCallback())); | 365 media::VirtualAudioInputStream::AfterCloseCallback()), |
366 false); | |
340 } | 367 } |
341 | 368 |
342 WebContentsAudioInputStream::WebContentsAudioInputStream( | 369 WebContentsAudioInputStream::WebContentsAudioInputStream( |
343 int render_process_id, int main_render_frame_id, | 370 int render_process_id, |
371 int main_render_frame_id, | |
344 AudioMirroringManager* mirroring_manager, | 372 AudioMirroringManager* mirroring_manager, |
345 const scoped_refptr<WebContentsTracker>& tracker, | 373 const scoped_refptr<WebContentsTracker>& tracker, |
346 media::VirtualAudioInputStream* mixer_stream) | 374 media::VirtualAudioInputStream* mixer_stream, |
347 : impl_(new Impl(render_process_id, main_render_frame_id, | 375 bool is_duplication) |
348 mirroring_manager, tracker, mixer_stream)) {} | 376 : impl_(new Impl(render_process_id, |
377 main_render_frame_id, | |
378 mirroring_manager, | |
379 tracker, | |
380 mixer_stream, | |
381 is_duplication)) {} | |
349 | 382 |
350 WebContentsAudioInputStream::~WebContentsAudioInputStream() {} | 383 WebContentsAudioInputStream::~WebContentsAudioInputStream() {} |
351 | 384 |
352 bool WebContentsAudioInputStream::Open() { | 385 bool WebContentsAudioInputStream::Open() { |
353 return impl_->Open(); | 386 return impl_->Open(); |
354 } | 387 } |
355 | 388 |
356 void WebContentsAudioInputStream::Start(AudioInputCallback* callback) { | 389 void WebContentsAudioInputStream::Start(AudioInputCallback* callback) { |
357 impl_->Start(callback); | 390 impl_->Start(callback); |
358 } | 391 } |
(...skipping 25 matching lines...) Expand all Loading... | |
384 | 417 |
385 bool WebContentsAudioInputStream::GetAutomaticGainControl() { | 418 bool WebContentsAudioInputStream::GetAutomaticGainControl() { |
386 return impl_->mixer_stream()->GetAutomaticGainControl(); | 419 return impl_->mixer_stream()->GetAutomaticGainControl(); |
387 } | 420 } |
388 | 421 |
389 bool WebContentsAudioInputStream::IsMuted() { | 422 bool WebContentsAudioInputStream::IsMuted() { |
390 return false; | 423 return false; |
391 } | 424 } |
392 | 425 |
393 } // namespace content | 426 } // namespace content |
OLD | NEW |