OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |