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

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: Added guard against reentrancy in AudioMirroringManager methods. 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
23 struct AudioRendererHost::AudioEntry { 24 struct AudioRendererHost::AudioEntry {
24 AudioEntry(); 25 AudioEntry();
25 ~AudioEntry(); 26 ~AudioEntry();
26 27
27 // The AudioOutputController that manages the audio stream. 28 // The AudioOutputController that manages the audio stream.
28 scoped_refptr<media::AudioOutputController> controller; 29 scoped_refptr<media::AudioOutputController> controller;
29 30
30 // The audio stream ID. 31 // The audio stream ID.
31 int stream_id; 32 int stream_id;
32 33
34 // The routing ID of the source render view.
35 int render_view_id;
36
33 // Shared memory for transmission of the audio data. 37 // Shared memory for transmission of the audio data.
34 base::SharedMemory shared_memory; 38 base::SharedMemory shared_memory;
35 39
36 // The synchronous reader to be used by the controller. We have the 40 // The synchronous reader to be used by the controller. We have the
37 // ownership of the reader. 41 // ownership of the reader.
38 scoped_ptr<media::AudioOutputController::SyncReader> reader; 42 scoped_ptr<media::AudioOutputController::SyncReader> reader;
39 43
40 // Set to true after we called Close() for the controller. 44 // Set to true after we called Close() for the controller.
41 bool pending_close; 45 bool pending_close;
42 }; 46 };
43 47
44 AudioRendererHost::AudioEntry::AudioEntry() 48 AudioRendererHost::AudioEntry::AudioEntry()
45 : stream_id(0), 49 : stream_id(0),
50 render_view_id(MSG_ROUTING_NONE),
46 pending_close(false) { 51 pending_close(false) {
47 } 52 }
48 53
49 AudioRendererHost::AudioEntry::~AudioEntry() {} 54 AudioRendererHost::AudioEntry::~AudioEntry() {}
50 55
51 /////////////////////////////////////////////////////////////////////////////// 56 ///////////////////////////////////////////////////////////////////////////////
52 // AudioRendererHost implementations. 57 // AudioRendererHost implementations.
53 AudioRendererHost::AudioRendererHost( 58 AudioRendererHost::AudioRendererHost(
54 media::AudioManager* audio_manager, MediaObserver* media_observer) 59 int render_process_id,
55 : audio_manager_(audio_manager), 60 media::AudioManager* audio_manager,
61 AudioMirroringManager* mirroring_manager,
62 MediaObserver* media_observer)
63 : render_process_id_(render_process_id),
64 audio_manager_(audio_manager),
65 mirroring_manager_(mirroring_manager),
56 media_observer_(media_observer) { 66 media_observer_(media_observer) {
67 DCHECK(audio_manager_);
68 DCHECK(mirroring_manager_);
57 } 69 }
58 70
59 AudioRendererHost::~AudioRendererHost() { 71 AudioRendererHost::~AudioRendererHost() {
60 DCHECK(audio_entries_.empty()); 72 DCHECK(audio_entries_.empty());
61 } 73 }
62 74
63 void AudioRendererHost::OnChannelClosing() { 75 void AudioRendererHost::OnChannelClosing() {
64 BrowserMessageFilter::OnChannelClosing(); 76 BrowserMessageFilter::OnChannelClosing();
65 77
66 // Since the IPC channel is gone, close all requested audio streams. 78 // Since the IPC channel is gone, close all requested audio streams.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 // If we have created the controller successfully, create an entry and add it 286 // If we have created the controller successfully, create an entry and add it
275 // to the map. 287 // to the map.
276 entry->stream_id = stream_id; 288 entry->stream_id = stream_id;
277 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 289 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
278 if (media_observer_) 290 if (media_observer_)
279 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created"); 291 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created");
280 } 292 }
281 293
282 void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id, 294 void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id,
283 int render_view_id) { 295 int render_view_id) {
284 // TODO(miu): Will use render_view_id in upcoming change. 296 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
297
285 DVLOG(1) << "AudioRendererHost@" << this 298 DVLOG(1) << "AudioRendererHost@" << this
286 << "::OnAssociateStreamWithProducer(stream_id=" << stream_id 299 << "::OnAssociateStreamWithProducer(stream_id=" << stream_id
287 << ", render_view_id=" << render_view_id << ")"; 300 << ", render_view_id=" << render_view_id << ")";
301
302 AudioEntry* const entry = LookupById(stream_id);
303 if (!entry) {
304 SendErrorMessage(stream_id);
305 return;
306 }
307
308 if (entry->render_view_id == render_view_id)
309 return; // No change.
Chris Rogers 2013/01/09 21:18:44 comment is obvious - adds little value
miu 2013/01/10 21:23:26 Done.
310
311 mirroring_manager_->RemoveDiverter(
312 render_process_id_, entry->render_view_id, entry->controller);
313 entry->render_view_id = render_view_id;
314 mirroring_manager_->AddDiverter(
315 render_process_id_, entry->render_view_id, entry->controller);
Chris Rogers 2013/01/09 21:18:44 We certainly don't have to do this now, but struct
miu 2013/01/10 21:23:26 Agreed. There's also other clean-up and even bug
288 } 316 }
289 317
290 void AudioRendererHost::OnPlayStream(int stream_id) { 318 void AudioRendererHost::OnPlayStream(int stream_id) {
291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
292 320
293 AudioEntry* entry = LookupById(stream_id); 321 AudioEntry* entry = LookupById(stream_id);
294 if (!entry) { 322 if (!entry) {
295 SendErrorMessage(stream_id); 323 SendErrorMessage(stream_id);
296 return; 324 return;
297 } 325 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 for (AudioEntryMap::iterator i = audio_entries_.begin(); 397 for (AudioEntryMap::iterator i = audio_entries_.begin();
370 i != audio_entries_.end(); ++i) { 398 i != audio_entries_.end(); ++i) {
371 CloseAndDeleteStream(i->second); 399 CloseAndDeleteStream(i->second);
372 } 400 }
373 } 401 }
374 402
375 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) { 403 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
377 405
378 if (!entry->pending_close) { 406 if (!entry->pending_close) {
407 mirroring_manager_->RemoveDiverter(
408 render_process_id_, entry->render_view_id, entry->controller);
379 entry->controller->Close( 409 entry->controller->Close(
380 base::Bind(&AudioRendererHost::DeleteEntry, this, entry)); 410 base::Bind(&AudioRendererHost::DeleteEntry, this, entry));
381 entry->pending_close = true; 411 entry->pending_close = true;
382 } 412 }
383 } 413 }
384 414
385 void AudioRendererHost::DeleteEntry(AudioEntry* entry) { 415 void AudioRendererHost::DeleteEntry(AudioEntry* entry) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
387 417
388 // Delete the entry when this method goes out of scope. 418 // Delete the entry when this method goes out of scope.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 return NULL; 461 return NULL;
432 } 462 }
433 463
434 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting( 464 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting(
435 int stream_id) { 465 int stream_id) {
436 AudioEntry* const entry = LookupById(stream_id); 466 AudioEntry* const entry = LookupById(stream_id);
437 return entry ? entry->controller : NULL; 467 return entry ? entry->controller : NULL;
438 } 468 }
439 469
440 } // namespace content 470 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698