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

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: Broke mirroring out of AudioRendererHost into separate AudioMirroringManager class. Created 8 years 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_sync_reader.h" 12 #include "content/browser/renderer_host/media/audio_sync_reader.h"
13 #include "content/browser/renderer_host/media/audio_mirroring_manager.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 {
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 };
40
41 void ControllerDiverter::SetController(media::AudioOutputController* ctlr) {
42 controller_ = ctlr;
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(
95 int render_process_id,
54 media::AudioManager* audio_manager, MediaObserver* media_observer) 96 media::AudioManager* audio_manager, MediaObserver* media_observer)
55 : audio_manager_(audio_manager), 97 : render_process_id_(render_process_id),
98 audio_manager_(audio_manager),
56 media_observer_(media_observer) { 99 media_observer_(media_observer) {
57 } 100 }
58 101
59 AudioRendererHost::~AudioRendererHost() { 102 AudioRendererHost::~AudioRendererHost() {
60 DCHECK(audio_entries_.empty()); 103 DCHECK(audio_entries_.empty());
61 } 104 }
62 105
63 void AudioRendererHost::OnChannelClosing() { 106 void AudioRendererHost::OnChannelClosing() {
64 BrowserMessageFilter::OnChannelClosing(); 107 BrowserMessageFilter::OnChannelClosing();
65 108
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 if (!reader->Init()) { 305 if (!reader->Init()) {
263 SendErrorMessage(stream_id); 306 SendErrorMessage(stream_id);
264 return; 307 return;
265 } 308 }
266 309
267 // If we have successfully created the SyncReader then assign it to the 310 // If we have successfully created the SyncReader then assign it to the
268 // entry and construct an AudioOutputController. 311 // entry and construct an AudioOutputController.
269 entry->reader.reset(reader.release()); 312 entry->reader.reset(reader.release());
270 entry->controller = media::AudioOutputController::Create( 313 entry->controller = media::AudioOutputController::Create(
271 audio_manager_, this, audio_params, entry->reader.get()); 314 audio_manager_, this, audio_params, entry->reader.get());
272
273 if (!entry->controller) { 315 if (!entry->controller) {
274 SendErrorMessage(stream_id); 316 SendErrorMessage(stream_id);
275 return; 317 return;
276 } 318 }
319 entry->diverter.SetController(entry->controller);
tommi (sloooow) - chröme 2012/12/19 12:27:54 nit: keep an empty line after end of scope
miu 2012/12/28 23:03:49 Done.
277 320
278 // If we have created the controller successfully, create an entry and add it 321 // If we have created the controller successfully, create an entry and add it
279 // to the map. 322 // to the map.
280 entry->stream_id = stream_id; 323 entry->stream_id = stream_id;
281 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 324 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
282 if (media_observer_) 325 if (media_observer_)
283 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created"); 326 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created");
284 } 327 }
285 328
286 void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id, 329 void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id,
287 int render_view_id) { 330 int render_view_id) {
288 // TODO(miu): Will use render_view_id in upcoming change. 331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
332
289 DVLOG(1) << "AudioRendererHost@" << this 333 DVLOG(1) << "AudioRendererHost@" << this
290 << "::OnAssociateStreamWithProducer(stream_id=" << stream_id 334 << "::OnAssociateStreamWithProducer(stream_id=" << stream_id
291 << ", render_view_id=" << render_view_id << ")"; 335 << ", render_view_id=" << render_view_id << ")";
336
337 AudioEntry* const entry = LookupById(stream_id);
338 if (!entry) {
339 SendErrorMessage(stream_id);
340 return;
341 }
342
343 if (entry->render_view_id == render_view_id)
344 return; // No change.
345
346 AudioMirroringManager* const amm = AudioMirroringManager::GetInstance();
347 amm->RemoveDiverter(
348 render_process_id_, entry->render_view_id, &entry->diverter);
349 entry->render_view_id = render_view_id;
350 amm->AddDiverter(
351 render_process_id_, entry->render_view_id, &entry->diverter);
292 } 352 }
293 353
294 void AudioRendererHost::OnPlayStream(int stream_id) { 354 void AudioRendererHost::OnPlayStream(int stream_id) {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
296 356
297 AudioEntry* entry = LookupById(stream_id); 357 AudioEntry* entry = LookupById(stream_id);
298 if (!entry) { 358 if (!entry) {
299 SendErrorMessage(stream_id); 359 SendErrorMessage(stream_id);
300 return; 360 return;
301 } 361 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 for (AudioEntryMap::iterator i = audio_entries_.begin(); 433 for (AudioEntryMap::iterator i = audio_entries_.begin();
374 i != audio_entries_.end(); ++i) { 434 i != audio_entries_.end(); ++i) {
375 CloseAndDeleteStream(i->second); 435 CloseAndDeleteStream(i->second);
376 } 436 }
377 } 437 }
378 438
379 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) { 439 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
381 441
382 if (!entry->pending_close) { 442 if (!entry->pending_close) {
443 AudioMirroringManager::GetInstance()->RemoveDiverter(
444 render_process_id_, entry->render_view_id, &entry->diverter);
383 entry->controller->Close( 445 entry->controller->Close(
384 base::Bind(&AudioRendererHost::DeleteEntry, this, entry)); 446 base::Bind(&AudioRendererHost::DeleteEntry, this, entry));
385 entry->pending_close = true; 447 entry->pending_close = true;
386 } 448 }
387 } 449 }
388 450
389 void AudioRendererHost::DeleteEntry(AudioEntry* entry) { 451 void AudioRendererHost::DeleteEntry(AudioEntry* entry) {
390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
391 453
392 // Delete the entry when this method goes out of scope. 454 // 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; 497 return NULL;
436 } 498 }
437 499
438 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting( 500 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting(
439 int stream_id) { 501 int stream_id) {
440 AudioEntry* const entry = LookupById(stream_id); 502 AudioEntry* const entry = LookupById(stream_id);
441 return entry ? entry->controller : NULL; 503 return entry ? entry->controller : NULL;
442 } 504 }
443 505
444 } // namespace content 506 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698