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

Side by Side Diff: content/browser/renderer_host/media/audio_renderer_host.cc

Issue 11413078: Tab Audio Capture: Browser-side connect/disconnect functionality. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed tommi's comments (dependency injection for testing AudioMirroringManager). Created 7 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/renderer_host/media/audio_renderer_host.h" 5 #include "content/browser/renderer_host/media/audio_renderer_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/process.h" 9 #include "base/process.h"
10 #include "base/shared_memory.h" 10 #include "base/shared_memory.h"
11 #include "content/browser/browser_main_loop.h" 11 #include "content/browser/browser_main_loop.h"
12 #include "content/browser/renderer_host/media/audio_mirroring_manager.h"
12 #include "content/browser/renderer_host/media/audio_sync_reader.h" 13 #include "content/browser/renderer_host/media/audio_sync_reader.h"
13 #include "content/common/media/audio_messages.h" 14 #include "content/common/media/audio_messages.h"
14 #include "content/public/browser/media_observer.h" 15 #include "content/public/browser/media_observer.h"
15 #include "media/audio/shared_memory_util.h" 16 #include "media/audio/shared_memory_util.h"
16 #include "media/base/audio_bus.h" 17 #include "media/base/audio_bus.h"
17 #include "media/base/limits.h" 18 #include "media/base/limits.h"
18 19
19 using media::AudioBus; 20 using media::AudioBus;
20 21
21 namespace content { 22 namespace content {
22 23
24 namespace {
25
26 // Simple wrapper around a media::AudioOutputController to implement the
27 // AudioMirroringManager::Diverter interface.
28 class ControllerDiverter : public AudioMirroringManager::Diverter {
DaleCurtis 2013/01/02 21:56:44 ISTM that you could just have AudioOutputControlle
miu 2013/01/03 22:30:42 Done. I had thought about this, but I quickly dis
29 public:
30 void SetController(media::AudioOutputController* controller);
31
32 // AudioMirroringManager::Diverter implementation.
33 virtual const media::AudioParameters& GetAudioParameters() OVERRIDE;
34 virtual void StartDiverting(media::AudioOutputStream* stream) OVERRIDE;
35 virtual void StopDiverting() OVERRIDE;
36
37 private:
38 media::AudioOutputController* controller_; // Not owned.
39 };
DaleCurtis 2013/01/02 21:56:44 Disallow copy and assign? Why not make provide con
miu 2013/01/03 22:30:42 No longer applicable.
40
41 void ControllerDiverter::SetController(media::AudioOutputController* ctlr) {
42 controller_ = ctlr;
DaleCurtis 2013/01/02 21:56:44 DCHECK(ctlr) for haystack hunts.
miu 2013/01/03 22:30:42 No longer applicable.
43 }
44
45 const media::AudioParameters& ControllerDiverter::GetAudioParameters() {
46 return controller_->params();
47 }
48
49 void ControllerDiverter::StartDiverting(media::AudioOutputStream* stream) {
50 controller_->StartDiverting(stream);
51 }
52
53 void ControllerDiverter::StopDiverting() {
54 controller_->StopDiverting();
55 }
56
57 } // namespace
58
23 struct AudioRendererHost::AudioEntry { 59 struct AudioRendererHost::AudioEntry {
24 AudioEntry(); 60 AudioEntry();
25 ~AudioEntry(); 61 ~AudioEntry();
26 62
27 // The AudioOutputController that manages the audio stream. 63 // The AudioOutputController that manages the audio stream.
28 scoped_refptr<media::AudioOutputController> controller; 64 scoped_refptr<media::AudioOutputController> controller;
65 ControllerDiverter diverter;
29 66
30 // The audio stream ID. 67 // The audio stream ID.
31 int stream_id; 68 int stream_id;
32 69
70 // The routing ID of the source render view.
71 int render_view_id;
72
33 // Shared memory for transmission of the audio data. 73 // Shared memory for transmission of the audio data.
34 base::SharedMemory shared_memory; 74 base::SharedMemory shared_memory;
35 75
36 // The synchronous reader to be used by the controller. We have the 76 // The synchronous reader to be used by the controller. We have the
37 // ownership of the reader. 77 // ownership of the reader.
38 scoped_ptr<media::AudioOutputController::SyncReader> reader; 78 scoped_ptr<media::AudioOutputController::SyncReader> reader;
39 79
40 // Set to true after we called Close() for the controller. 80 // Set to true after we called Close() for the controller.
41 bool pending_close; 81 bool pending_close;
42 }; 82 };
43 83
44 AudioRendererHost::AudioEntry::AudioEntry() 84 AudioRendererHost::AudioEntry::AudioEntry()
45 : stream_id(0), 85 : stream_id(0),
86 render_view_id(MSG_ROUTING_NONE),
46 pending_close(false) { 87 pending_close(false) {
47 } 88 }
48 89
49 AudioRendererHost::AudioEntry::~AudioEntry() {} 90 AudioRendererHost::AudioEntry::~AudioEntry() {}
50 91
51 /////////////////////////////////////////////////////////////////////////////// 92 ///////////////////////////////////////////////////////////////////////////////
52 // AudioRendererHost implementations. 93 // AudioRendererHost implementations.
53 AudioRendererHost::AudioRendererHost( 94 AudioRendererHost::AudioRendererHost(
54 media::AudioManager* audio_manager, MediaObserver* media_observer) 95 int render_process_id,
55 : audio_manager_(audio_manager), 96 media::AudioManager* audio_manager,
97 AudioMirroringManager* mirroring_manager,
98 MediaObserver* media_observer)
99 : render_process_id_(render_process_id),
100 audio_manager_(audio_manager),
101 mirroring_manager_(mirroring_manager),
56 media_observer_(media_observer) { 102 media_observer_(media_observer) {
57 } 103 }
58 104
59 AudioRendererHost::~AudioRendererHost() { 105 AudioRendererHost::~AudioRendererHost() {
60 DCHECK(audio_entries_.empty()); 106 DCHECK(audio_entries_.empty());
61 } 107 }
62 108
63 void AudioRendererHost::OnChannelClosing() { 109 void AudioRendererHost::OnChannelClosing() {
64 BrowserMessageFilter::OnChannelClosing(); 110 BrowserMessageFilter::OnChannelClosing();
65 111
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 if (!reader->Init()) { 308 if (!reader->Init()) {
263 SendErrorMessage(stream_id); 309 SendErrorMessage(stream_id);
264 return; 310 return;
265 } 311 }
266 312
267 // If we have successfully created the SyncReader then assign it to the 313 // If we have successfully created the SyncReader then assign it to the
268 // entry and construct an AudioOutputController. 314 // entry and construct an AudioOutputController.
269 entry->reader.reset(reader.release()); 315 entry->reader.reset(reader.release());
270 entry->controller = media::AudioOutputController::Create( 316 entry->controller = media::AudioOutputController::Create(
271 audio_manager_, this, audio_params, entry->reader.get()); 317 audio_manager_, this, audio_params, entry->reader.get());
272
273 if (!entry->controller) { 318 if (!entry->controller) {
274 SendErrorMessage(stream_id); 319 SendErrorMessage(stream_id);
275 return; 320 return;
276 } 321 }
277 322
323 entry->diverter.SetController(entry->controller);
324
278 // If we have created the controller successfully, create an entry and add it 325 // If we have created the controller successfully, create an entry and add it
279 // to the map. 326 // to the map.
280 entry->stream_id = stream_id; 327 entry->stream_id = stream_id;
281 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 328 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
282 if (media_observer_) 329 if (media_observer_)
283 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created"); 330 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created");
284 } 331 }
285 332
286 void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id, 333 void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id,
287 int render_view_id) { 334 int render_view_id) {
288 // TODO(miu): Will use render_view_id in upcoming change. 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
336
289 DVLOG(1) << "AudioRendererHost@" << this 337 DVLOG(1) << "AudioRendererHost@" << this
290 << "::OnAssociateStreamWithProducer(stream_id=" << stream_id 338 << "::OnAssociateStreamWithProducer(stream_id=" << stream_id
291 << ", render_view_id=" << render_view_id << ")"; 339 << ", render_view_id=" << render_view_id << ")";
340
341 AudioEntry* const entry = LookupById(stream_id);
342 if (!entry) {
343 SendErrorMessage(stream_id);
344 return;
345 }
346
347 if (entry->render_view_id == render_view_id)
348 return; // No change.
349
350 if (mirroring_manager_) {
DaleCurtis 2013/01/02 21:56:44 Mirroring manager should always be present since
miu 2013/01/03 22:30:42 Done. And fixed things so MediaObserver must neve
351 mirroring_manager_->RemoveDiverter(
352 render_process_id_, entry->render_view_id, &entry->diverter);
353 }
354 entry->render_view_id = render_view_id;
355 if (mirroring_manager_) {
356 mirroring_manager_->AddDiverter(
357 render_process_id_, entry->render_view_id, &entry->diverter);
358 }
292 } 359 }
293 360
294 void AudioRendererHost::OnPlayStream(int stream_id) { 361 void AudioRendererHost::OnPlayStream(int stream_id) {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
296 363
297 AudioEntry* entry = LookupById(stream_id); 364 AudioEntry* entry = LookupById(stream_id);
298 if (!entry) { 365 if (!entry) {
299 SendErrorMessage(stream_id); 366 SendErrorMessage(stream_id);
300 return; 367 return;
301 } 368 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 for (AudioEntryMap::iterator i = audio_entries_.begin(); 440 for (AudioEntryMap::iterator i = audio_entries_.begin();
374 i != audio_entries_.end(); ++i) { 441 i != audio_entries_.end(); ++i) {
375 CloseAndDeleteStream(i->second); 442 CloseAndDeleteStream(i->second);
376 } 443 }
377 } 444 }
378 445
379 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) { 446 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 447 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
381 448
382 if (!entry->pending_close) { 449 if (!entry->pending_close) {
450 if (mirroring_manager_) {
DaleCurtis 2013/01/02 21:56:44 Ditto.
miu 2013/01/03 22:30:42 Done.
451 mirroring_manager_->RemoveDiverter(
452 render_process_id_, entry->render_view_id, &entry->diverter);
453 }
383 entry->controller->Close( 454 entry->controller->Close(
384 base::Bind(&AudioRendererHost::DeleteEntry, this, entry)); 455 base::Bind(&AudioRendererHost::DeleteEntry, this, entry));
385 entry->pending_close = true; 456 entry->pending_close = true;
386 } 457 }
387 } 458 }
388 459
389 void AudioRendererHost::DeleteEntry(AudioEntry* entry) { 460 void AudioRendererHost::DeleteEntry(AudioEntry* entry) {
390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
391 462
392 // Delete the entry when this method goes out of scope. 463 // Delete the entry when this method goes out of scope.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 return NULL; 506 return NULL;
436 } 507 }
437 508
438 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting( 509 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting(
439 int stream_id) { 510 int stream_id) {
440 AudioEntry* const entry = LookupById(stream_id); 511 AudioEntry* const entry = LookupById(stream_id);
441 return entry ? entry->controller : NULL; 512 return entry ? entry->controller : NULL;
442 } 513 }
443 514
444 } // namespace content 515 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698