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/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/memory/shared_memory.h" | 9 #include "base/memory/shared_memory.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 media::AudioOutputController* controller() const { return controller_.get(); } | 54 media::AudioOutputController* controller() const { return controller_.get(); } |
55 | 55 |
56 base::SharedMemory* shared_memory() { | 56 base::SharedMemory* shared_memory() { |
57 return shared_memory_.get(); | 57 return shared_memory_.get(); |
58 } | 58 } |
59 | 59 |
60 media::AudioOutputController::SyncReader* reader() const { | 60 media::AudioOutputController::SyncReader* reader() const { |
61 return reader_.get(); | 61 return reader_.get(); |
62 } | 62 } |
63 | 63 |
| 64 bool playing() const { return playing_; } |
| 65 void set_playing(bool playing) { playing_ = playing; } |
| 66 |
64 private: | 67 private: |
65 // media::AudioOutputController::EventHandler implementation. | 68 // media::AudioOutputController::EventHandler implementation. |
66 virtual void OnCreated() OVERRIDE; | 69 virtual void OnCreated() OVERRIDE; |
67 virtual void OnPlaying() OVERRIDE; | 70 virtual void OnPlaying() OVERRIDE; |
68 virtual void OnPaused() OVERRIDE; | 71 virtual void OnPaused() OVERRIDE; |
69 virtual void OnError() OVERRIDE; | 72 virtual void OnError() OVERRIDE; |
70 virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) | 73 virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) |
71 OVERRIDE; | 74 OVERRIDE; |
72 | 75 |
73 AudioRendererHost* const host_; | 76 AudioRendererHost* const host_; |
74 const int stream_id_; | 77 const int stream_id_; |
75 | 78 |
76 // The routing ID of the source render view/frame. | 79 // The routing ID of the source render view/frame. |
77 const int render_view_id_; | 80 const int render_view_id_; |
78 const int render_frame_id_; | 81 const int render_frame_id_; |
79 | 82 |
80 // Shared memory for transmission of the audio data. Used by |reader_|. | 83 // Shared memory for transmission of the audio data. Used by |reader_|. |
81 const scoped_ptr<base::SharedMemory> shared_memory_; | 84 const scoped_ptr<base::SharedMemory> shared_memory_; |
82 | 85 |
83 // The synchronous reader to be used by |controller_|. | 86 // The synchronous reader to be used by |controller_|. |
84 const scoped_ptr<media::AudioOutputController::SyncReader> reader_; | 87 const scoped_ptr<media::AudioOutputController::SyncReader> reader_; |
85 | 88 |
86 // The AudioOutputController that manages the audio stream. | 89 // The AudioOutputController that manages the audio stream. |
87 const scoped_refptr<media::AudioOutputController> controller_; | 90 const scoped_refptr<media::AudioOutputController> controller_; |
| 91 |
| 92 bool playing_; |
88 }; | 93 }; |
89 | 94 |
90 AudioRendererHost::AudioEntry::AudioEntry( | 95 AudioRendererHost::AudioEntry::AudioEntry( |
91 AudioRendererHost* host, | 96 AudioRendererHost* host, |
92 int stream_id, | 97 int stream_id, |
93 int render_view_id, | 98 int render_view_id, |
94 int render_frame_id, | 99 int render_frame_id, |
95 const media::AudioParameters& params, | 100 const media::AudioParameters& params, |
96 const std::string& output_device_id, | 101 const std::string& output_device_id, |
97 scoped_ptr<base::SharedMemory> shared_memory, | 102 scoped_ptr<base::SharedMemory> shared_memory, |
98 scoped_ptr<media::AudioOutputController::SyncReader> reader) | 103 scoped_ptr<media::AudioOutputController::SyncReader> reader) |
99 : host_(host), | 104 : host_(host), |
100 stream_id_(stream_id), | 105 stream_id_(stream_id), |
101 render_view_id_(render_view_id), | 106 render_view_id_(render_view_id), |
102 render_frame_id_(render_frame_id), | 107 render_frame_id_(render_frame_id), |
103 shared_memory_(shared_memory.Pass()), | 108 shared_memory_(shared_memory.Pass()), |
104 reader_(reader.Pass()), | 109 reader_(reader.Pass()), |
105 controller_(media::AudioOutputController::Create(host->audio_manager_, | 110 controller_(media::AudioOutputController::Create(host->audio_manager_, |
106 this, | 111 this, |
107 params, | 112 params, |
108 output_device_id, | 113 output_device_id, |
109 reader_.get())) { | 114 reader_.get())), |
| 115 playing_(false) { |
110 DCHECK(controller_.get()); | 116 DCHECK(controller_.get()); |
111 } | 117 } |
112 | 118 |
113 AudioRendererHost::AudioEntry::~AudioEntry() {} | 119 AudioRendererHost::AudioEntry::~AudioEntry() {} |
114 | 120 |
115 /////////////////////////////////////////////////////////////////////////////// | 121 /////////////////////////////////////////////////////////////////////////////// |
116 // AudioRendererHost implementations. | 122 // AudioRendererHost implementations. |
117 | 123 |
118 AudioRendererHost::AudioRendererHost( | 124 AudioRendererHost::AudioRendererHost( |
119 int render_process_id, | 125 int render_process_id, |
120 media::AudioManager* audio_manager, | 126 media::AudioManager* audio_manager, |
121 AudioMirroringManager* mirroring_manager, | 127 AudioMirroringManager* mirroring_manager, |
122 MediaInternals* media_internals, | 128 MediaInternals* media_internals, |
123 MediaStreamManager* media_stream_manager) | 129 MediaStreamManager* media_stream_manager) |
124 : BrowserMessageFilter(AudioMsgStart), | 130 : BrowserMessageFilter(AudioMsgStart), |
125 render_process_id_(render_process_id), | 131 render_process_id_(render_process_id), |
126 audio_manager_(audio_manager), | 132 audio_manager_(audio_manager), |
127 mirroring_manager_(mirroring_manager), | 133 mirroring_manager_(mirroring_manager), |
128 audio_log_(media_internals->CreateAudioLog( | 134 audio_log_(media_internals->CreateAudioLog( |
129 media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)), | 135 media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)), |
130 media_stream_manager_(media_stream_manager) { | 136 media_stream_manager_(media_stream_manager), |
| 137 num_playing_streams_(0) { |
131 DCHECK(audio_manager_); | 138 DCHECK(audio_manager_); |
132 DCHECK(media_stream_manager_); | 139 DCHECK(media_stream_manager_); |
133 } | 140 } |
134 | 141 |
135 AudioRendererHost::~AudioRendererHost() { | 142 AudioRendererHost::~AudioRendererHost() { |
136 DCHECK(audio_entries_.empty()); | 143 DCHECK(audio_entries_.empty()); |
137 } | 144 } |
138 | 145 |
139 void AudioRendererHost::GetOutputControllers( | 146 void AudioRendererHost::GetOutputControllers( |
140 int render_view_id, | 147 int render_view_id, |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 MediaObserver* const media_observer = | 275 MediaObserver* const media_observer = |
269 GetContentClient()->browser()->GetMediaObserver(); | 276 GetContentClient()->browser()->GetMediaObserver(); |
270 if (media_observer) { | 277 if (media_observer) { |
271 if (is_playing) { | 278 if (is_playing) { |
272 media_observer->OnAudioStreamPlaying( | 279 media_observer->OnAudioStreamPlaying( |
273 render_process_id_, | 280 render_process_id_, |
274 entry->render_frame_id(), | 281 entry->render_frame_id(), |
275 entry->stream_id(), | 282 entry->stream_id(), |
276 base::Bind(&media::AudioOutputController::ReadCurrentPowerAndClip, | 283 base::Bind(&media::AudioOutputController::ReadCurrentPowerAndClip, |
277 entry->controller())); | 284 entry->controller())); |
| 285 if (!entry->playing()) { |
| 286 entry->set_playing(true); |
| 287 base::AtomicRefCountInc(&num_playing_streams_); |
| 288 } |
278 } else { | 289 } else { |
279 media_observer->OnAudioStreamStopped(render_process_id_, | 290 media_observer->OnAudioStreamStopped(render_process_id_, |
280 entry->render_frame_id(), | 291 entry->render_frame_id(), |
281 entry->stream_id()); | 292 entry->stream_id()); |
| 293 if (entry->playing()) { |
| 294 entry->set_playing(false); |
| 295 base::AtomicRefCountDec(&num_playing_streams_); |
| 296 } |
282 } | 297 } |
283 } | 298 } |
284 } | 299 } |
285 | 300 |
286 RenderViewHost::AudioOutputControllerList | 301 RenderViewHost::AudioOutputControllerList |
287 AudioRendererHost::DoGetOutputControllers(int render_view_id) const { | 302 AudioRendererHost::DoGetOutputControllers(int render_view_id) const { |
288 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 303 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
289 | 304 |
290 RenderViewHost::AudioOutputControllerList controllers; | 305 RenderViewHost::AudioOutputControllerList controllers; |
291 AudioEntryMap::const_iterator it = audio_entries_.begin(); | 306 AudioEntryMap::const_iterator it = audio_entries_.begin(); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) { | 466 void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) { |
452 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 467 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
453 | 468 |
454 // At this point, make the final "say" in audio playback state. | 469 // At this point, make the final "say" in audio playback state. |
455 MediaObserver* const media_observer = | 470 MediaObserver* const media_observer = |
456 GetContentClient()->browser()->GetMediaObserver(); | 471 GetContentClient()->browser()->GetMediaObserver(); |
457 if (media_observer) { | 472 if (media_observer) { |
458 media_observer->OnAudioStreamStopped(render_process_id_, | 473 media_observer->OnAudioStreamStopped(render_process_id_, |
459 entry->render_frame_id(), | 474 entry->render_frame_id(), |
460 entry->stream_id()); | 475 entry->stream_id()); |
| 476 if (entry->playing()) |
| 477 base::AtomicRefCountDec(&num_playing_streams_); |
461 } | 478 } |
462 } | 479 } |
463 | 480 |
464 void AudioRendererHost::ReportErrorAndClose(int stream_id) { | 481 void AudioRendererHost::ReportErrorAndClose(int stream_id) { |
465 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 482 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
466 | 483 |
467 // Make sure this isn't a stray callback executing after the stream has been | 484 // Make sure this isn't a stray callback executing after the stream has been |
468 // closed, so error notifications aren't sent after clients believe the stream | 485 // closed, so error notifications aren't sent after clients believe the stream |
469 // is closed. | 486 // is closed. |
470 if (!LookupById(stream_id)) | 487 if (!LookupById(stream_id)) |
471 return; | 488 return; |
472 | 489 |
473 SendErrorMessage(stream_id); | 490 SendErrorMessage(stream_id); |
474 | 491 |
475 audio_log_->OnError(stream_id); | 492 audio_log_->OnError(stream_id); |
476 OnCloseStream(stream_id); | 493 OnCloseStream(stream_id); |
477 } | 494 } |
478 | 495 |
479 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { | 496 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { |
480 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 497 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
481 | 498 |
482 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); | 499 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); |
483 return i != audio_entries_.end() ? i->second : NULL; | 500 return i != audio_entries_.end() ? i->second : NULL; |
484 } | 501 } |
485 | 502 |
| 503 bool AudioRendererHost::HasActiveAudio() { |
| 504 return !base::AtomicRefCountIsZero(&num_playing_streams_); |
| 505 } |
| 506 |
486 } // namespace content | 507 } // namespace content |
OLD | NEW |