Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: content/browser/media/capture/web_contents_audio_input_stream.cc

Issue 1897953003: Unmute Tab Audio For Desktop Share (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nit Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/threading/thread_checker.h" 14 #include "base/threading/thread_checker.h"
15 #include "content/browser/media/capture/audio_mirroring_manager.h" 15 #include "content/browser/media/capture/audio_mirroring_manager.h"
16 #include "content/browser/media/capture/web_contents_tracker.h" 16 #include "content/browser/media/capture/web_contents_tracker.h"
17 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/render_frame_host.h" 18 #include "content/public/browser/render_frame_host.h"
19 #include "content/public/browser/web_contents.h" 19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_media_capture_id.h" 20 #include "content/public/browser/web_contents_media_capture_id.h"
21 #include "media/audio/virtual_audio_input_stream.h" 21 #include "media/audio/virtual_audio_input_stream.h"
22 #include "media/audio/virtual_audio_output_stream.h" 22 #include "media/audio/virtual_audio_output_stream.h"
23 #include "media/audio/virtual_audio_sink.h"
23 #include "media/base/bind_to_current_loop.h" 24 #include "media/base/bind_to_current_loop.h"
24 25
25 namespace content { 26 namespace content {
26 27
27 class WebContentsAudioInputStream::Impl 28 class WebContentsAudioInputStream::Impl
28 : public base::RefCountedThreadSafe<WebContentsAudioInputStream::Impl>, 29 : public base::RefCountedThreadSafe<WebContentsAudioInputStream::Impl>,
29 public AudioMirroringManager::MirroringDestination { 30 public AudioMirroringManager::MirroringDestination {
30 public: 31 public:
31 // Takes ownership of |mixer_stream|. The rest outlive this instance. 32 // Takes ownership of |mixer_stream|. The rest outlive this instance.
32 Impl(int render_process_id, int main_render_frame_id, 33 Impl(int render_process_id,
34 int main_render_frame_id,
33 AudioMirroringManager* mirroring_manager, 35 AudioMirroringManager* mirroring_manager,
34 const scoped_refptr<WebContentsTracker>& tracker, 36 const scoped_refptr<WebContentsTracker>& tracker,
35 media::VirtualAudioInputStream* mixer_stream); 37 media::VirtualAudioInputStream* mixer_stream,
38 bool is_duplication);
36 39
37 // Open underlying VirtualAudioInputStream and start tracker. 40 // Open underlying VirtualAudioInputStream and start tracker.
38 bool Open(); 41 bool Open();
39 42
40 // Start the underlying VirtualAudioInputStream and instruct 43 // Start the underlying VirtualAudioInputStream and instruct
41 // AudioMirroringManager to begin a mirroring session. 44 // AudioMirroringManager to begin a mirroring session.
42 void Start(AudioInputCallback* callback); 45 void Start(AudioInputCallback* callback);
43 46
44 // Stop the underlying VirtualAudioInputStream and instruct 47 // Stop the underlying VirtualAudioInputStream and instruct
45 // AudioMirroringManager to shutdown a mirroring session. 48 // AudioMirroringManager to shutdown a mirroring session.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // successful audio capture. 82 // successful audio capture.
80 void UnmuteWebContentsAudio(); 83 void UnmuteWebContentsAudio();
81 84
82 // AudioMirroringManager::MirroringDestination implementation 85 // AudioMirroringManager::MirroringDestination implementation
83 void QueryForMatches(const std::set<SourceFrameRef>& candidates, 86 void QueryForMatches(const std::set<SourceFrameRef>& candidates,
84 const MatchesCallback& results_callback) override; 87 const MatchesCallback& results_callback) override;
85 void QueryForMatchesOnUIThread(const std::set<SourceFrameRef>& candidates, 88 void QueryForMatchesOnUIThread(const std::set<SourceFrameRef>& candidates,
86 const MatchesCallback& results_callback); 89 const MatchesCallback& results_callback);
87 media::AudioOutputStream* AddInput( 90 media::AudioOutputStream* AddInput(
88 const media::AudioParameters& params) override; 91 const media::AudioParameters& params) override;
92 media::AudioPushSink* AddPushInput(
93 const media::AudioParameters& params) override;
89 94
90 // Callback which is run when |stream| is closed. Deletes |stream|. 95 // Callback which is run when |stream| is closed. Deletes |stream|.
91 void ReleaseInput(media::VirtualAudioOutputStream* stream); 96 void ReleaseInput(media::VirtualAudioOutputStream* stream);
97 void ReleasePushInput(media::VirtualAudioSink* sink);
92 98
93 // Called by WebContentsTracker when the target of the audio mirroring has 99 // Called by WebContentsTracker when the target of the audio mirroring has
94 // changed. 100 // changed.
95 void OnTargetChanged(bool had_target); 101 void OnTargetChanged(bool had_target);
96 102
97 // Injected dependencies. 103 // Injected dependencies.
98 const int initial_render_process_id_; 104 const int initial_render_process_id_;
99 const int initial_main_render_frame_id_; 105 const int initial_main_render_frame_id_;
100 AudioMirroringManager* const mirroring_manager_; 106 AudioMirroringManager* const mirroring_manager_;
101 const scoped_refptr<WebContentsTracker> tracker_; 107 const scoped_refptr<WebContentsTracker> tracker_;
102 // The AudioInputStream implementation that handles the audio conversion and 108 // The AudioInputStream implementation that handles the audio conversion and
103 // mixing details. 109 // mixing details.
104 const std::unique_ptr<media::VirtualAudioInputStream> mixer_stream_; 110 const std::unique_ptr<media::VirtualAudioInputStream> mixer_stream_;
105 111
106 State state_; 112 State state_;
107 113
108 // Set to true if |tracker_| reports a NULL target, which indicates the target 114 // Set to true if |tracker_| reports a NULL target, which indicates the target
109 // is permanently lost. 115 // is permanently lost.
110 bool is_target_lost_; 116 bool is_target_lost_;
111 117
112 // Current callback used to consume the resulting mixed audio data. 118 // Current callback used to consume the resulting mixed audio data.
113 AudioInputCallback* callback_; 119 AudioInputCallback* callback_;
114 120
121 // If true, this WebContentsAudioInputStream will request a duplication of
122 // audio data, instead of exclusive access to pull the audio data.
123 bool is_duplication_;
124
115 base::ThreadChecker thread_checker_; 125 base::ThreadChecker thread_checker_;
116 126
117 DISALLOW_COPY_AND_ASSIGN(Impl); 127 DISALLOW_COPY_AND_ASSIGN(Impl);
118 }; 128 };
119 129
120 WebContentsAudioInputStream::Impl::Impl( 130 WebContentsAudioInputStream::Impl::Impl(
121 int render_process_id, int main_render_frame_id, 131 int render_process_id,
132 int main_render_frame_id,
122 AudioMirroringManager* mirroring_manager, 133 AudioMirroringManager* mirroring_manager,
123 const scoped_refptr<WebContentsTracker>& tracker, 134 const scoped_refptr<WebContentsTracker>& tracker,
124 media::VirtualAudioInputStream* mixer_stream) 135 media::VirtualAudioInputStream* mixer_stream,
136 bool is_duplication)
125 : initial_render_process_id_(render_process_id), 137 : initial_render_process_id_(render_process_id),
126 initial_main_render_frame_id_(main_render_frame_id), 138 initial_main_render_frame_id_(main_render_frame_id),
127 mirroring_manager_(mirroring_manager), 139 mirroring_manager_(mirroring_manager),
128 tracker_(tracker), 140 tracker_(tracker),
129 mixer_stream_(mixer_stream), 141 mixer_stream_(mixer_stream),
130 state_(CONSTRUCTED), 142 state_(CONSTRUCTED),
131 is_target_lost_(false), 143 is_target_lost_(false),
132 callback_(NULL) { 144 callback_(NULL),
145 is_duplication_(is_duplication) {
133 DCHECK(mirroring_manager_); 146 DCHECK(mirroring_manager_);
134 DCHECK(tracker_); 147 DCHECK(tracker_);
135 DCHECK(mixer_stream_); 148 DCHECK(mixer_stream_);
136 149
137 // WAIS::Impl can be constructed on any thread, but will DCHECK that all 150 // 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. 151 // its methods from here on are called from the same thread.
139 thread_checker_.DetachFromThread(); 152 thread_checker_.DetachFromThread();
140 } 153 }
141 154
142 WebContentsAudioInputStream::Impl::~Impl() { 155 WebContentsAudioInputStream::Impl::~Impl() {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 for (std::set<SourceFrameRef>::const_iterator i = candidates.begin(); 289 for (std::set<SourceFrameRef>::const_iterator i = candidates.begin();
277 i != candidates.end(); ++i) { 290 i != candidates.end(); ++i) {
278 WebContents* const contents_containing_frame = 291 WebContents* const contents_containing_frame =
279 WebContents::FromRenderFrameHost( 292 WebContents::FromRenderFrameHost(
280 RenderFrameHost::FromID(i->first, i->second)); 293 RenderFrameHost::FromID(i->first, i->second));
281 if (contents_containing_frame == contents) 294 if (contents_containing_frame == contents)
282 matches.insert(*i); 295 matches.insert(*i);
283 } 296 }
284 } 297 }
285 298
286 results_callback.Run(matches); 299 results_callback.Run(matches, is_duplication_);
287 } 300 }
288 301
289 media::AudioOutputStream* WebContentsAudioInputStream::Impl::AddInput( 302 media::AudioOutputStream* WebContentsAudioInputStream::Impl::AddInput(
290 const media::AudioParameters& params) { 303 const media::AudioParameters& params) {
291 // Note: The closure created here holds a reference to "this," which will 304 // Note: The closure created here holds a reference to "this," which will
292 // guarantee the VirtualAudioInputStream (mixer_stream_) outlives the 305 // guarantee the VirtualAudioInputStream (mixer_stream_) outlives the
293 // VirtualAudioOutputStream. 306 // VirtualAudioOutputStream.
294 return new media::VirtualAudioOutputStream( 307 return new media::VirtualAudioOutputStream(
295 params, 308 params,
296 mixer_stream_.get(), 309 mixer_stream_.get(),
297 base::Bind(&Impl::ReleaseInput, this)); 310 base::Bind(&Impl::ReleaseInput, this));
298 } 311 }
299 312
300 void WebContentsAudioInputStream::Impl::ReleaseInput( 313 void WebContentsAudioInputStream::Impl::ReleaseInput(
301 media::VirtualAudioOutputStream* stream) { 314 media::VirtualAudioOutputStream* stream) {
302 delete stream; 315 delete stream;
303 } 316 }
304 317
318 media::AudioPushSink* WebContentsAudioInputStream::Impl::AddPushInput(
319 const media::AudioParameters& params) {
320 // Note: The closure created here holds a reference to "this," which will
321 // guarantee the VirtualAudioInputStream (mixer_stream_) outlives the
322 // VirtualAudioSink.
323 return new media::VirtualAudioSink(params, mixer_stream_.get(),
324 base::Bind(&Impl::ReleasePushInput, this));
325 }
326
327 void WebContentsAudioInputStream::Impl::ReleasePushInput(
328 media::VirtualAudioSink* stream) {
329 delete stream;
330 }
331
305 void WebContentsAudioInputStream::Impl::OnTargetChanged(bool had_target) { 332 void WebContentsAudioInputStream::Impl::OnTargetChanged(bool had_target) {
306 DCHECK(thread_checker_.CalledOnValidThread()); 333 DCHECK(thread_checker_.CalledOnValidThread());
307 334
308 is_target_lost_ = !had_target; 335 is_target_lost_ = !had_target;
309 336
310 if (state_ == MIRRORING) { 337 if (state_ == MIRRORING) {
311 if (is_target_lost_) { 338 if (is_target_lost_) {
312 ReportError(); 339 ReportError();
313 Stop(); 340 Stop();
314 } else { 341 } else {
315 StartMirroring(); 342 StartMirroring();
316 } 343 }
317 } 344 }
318 } 345 }
319 346
320 // static 347 // static
321 WebContentsAudioInputStream* WebContentsAudioInputStream::Create( 348 WebContentsAudioInputStream* WebContentsAudioInputStream::Create(
322 const std::string& device_id, 349 const std::string& device_id,
323 const media::AudioParameters& params, 350 const media::AudioParameters& params,
324 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, 351 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
325 AudioMirroringManager* audio_mirroring_manager) { 352 AudioMirroringManager* audio_mirroring_manager) {
326 int render_process_id; 353 int render_process_id;
327 int main_render_frame_id; 354 int main_render_frame_id;
328 if (!WebContentsMediaCaptureId::ExtractTabCaptureTarget( 355 if (!WebContentsMediaCaptureId::ExtractTabCaptureTarget(
329 device_id, &render_process_id, &main_render_frame_id)) { 356 device_id, &render_process_id, &main_render_frame_id)) {
330 return NULL; 357 return NULL;
331 } 358 }
332 359
360 // TODO(qiangchen): Plug in true for the case of Tab Typed Desktop Share.
333 return new WebContentsAudioInputStream( 361 return new WebContentsAudioInputStream(
334 render_process_id, main_render_frame_id, 362 render_process_id, main_render_frame_id, audio_mirroring_manager,
335 audio_mirroring_manager,
336 new WebContentsTracker(false), 363 new WebContentsTracker(false),
337 new media::VirtualAudioInputStream( 364 new media::VirtualAudioInputStream(
338 params, worker_task_runner, 365 params, worker_task_runner,
339 media::VirtualAudioInputStream::AfterCloseCallback())); 366 media::VirtualAudioInputStream::AfterCloseCallback()),
367 false);
340 } 368 }
341 369
342 WebContentsAudioInputStream::WebContentsAudioInputStream( 370 WebContentsAudioInputStream::WebContentsAudioInputStream(
343 int render_process_id, int main_render_frame_id, 371 int render_process_id,
372 int main_render_frame_id,
344 AudioMirroringManager* mirroring_manager, 373 AudioMirroringManager* mirroring_manager,
345 const scoped_refptr<WebContentsTracker>& tracker, 374 const scoped_refptr<WebContentsTracker>& tracker,
346 media::VirtualAudioInputStream* mixer_stream) 375 media::VirtualAudioInputStream* mixer_stream,
347 : impl_(new Impl(render_process_id, main_render_frame_id, 376 bool is_duplication)
348 mirroring_manager, tracker, mixer_stream)) {} 377 : impl_(new Impl(render_process_id,
378 main_render_frame_id,
379 mirroring_manager,
380 tracker,
381 mixer_stream,
382 is_duplication)) {}
349 383
350 WebContentsAudioInputStream::~WebContentsAudioInputStream() {} 384 WebContentsAudioInputStream::~WebContentsAudioInputStream() {}
351 385
352 bool WebContentsAudioInputStream::Open() { 386 bool WebContentsAudioInputStream::Open() {
353 return impl_->Open(); 387 return impl_->Open();
354 } 388 }
355 389
356 void WebContentsAudioInputStream::Start(AudioInputCallback* callback) { 390 void WebContentsAudioInputStream::Start(AudioInputCallback* callback) {
357 impl_->Start(callback); 391 impl_->Start(callback);
358 } 392 }
(...skipping 25 matching lines...) Expand all
384 418
385 bool WebContentsAudioInputStream::GetAutomaticGainControl() { 419 bool WebContentsAudioInputStream::GetAutomaticGainControl() {
386 return impl_->mixer_stream()->GetAutomaticGainControl(); 420 return impl_->mixer_stream()->GetAutomaticGainControl();
387 } 421 }
388 422
389 bool WebContentsAudioInputStream::IsMuted() { 423 bool WebContentsAudioInputStream::IsMuted() {
390 return false; 424 return false;
391 } 425 }
392 426
393 } // namespace content 427 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698