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

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: Unittest Created 4 years, 7 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"
(...skipping 11 matching lines...) Expand all
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698