| 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/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 } | 56 } |
| 57 | 57 |
| 58 media::AudioOutputController::SyncReader* reader() const { | 58 media::AudioOutputController::SyncReader* reader() const { |
| 59 return reader_.get(); | 59 return reader_.get(); |
| 60 } | 60 } |
| 61 | 61 |
| 62 private: | 62 private: |
| 63 // media::AudioOutputController::EventHandler implementation. | 63 // media::AudioOutputController::EventHandler implementation. |
| 64 virtual void OnCreated() OVERRIDE; | 64 virtual void OnCreated() OVERRIDE; |
| 65 virtual void OnPlaying() OVERRIDE; | 65 virtual void OnPlaying() OVERRIDE; |
| 66 virtual void OnAudible(bool is_audible) OVERRIDE; | 66 virtual void OnPowerMeasured(float power_dbfs, bool clipped) OVERRIDE; |
| 67 virtual void OnPaused() OVERRIDE; | 67 virtual void OnPaused() OVERRIDE; |
| 68 virtual void OnError() OVERRIDE; | 68 virtual void OnError() OVERRIDE; |
| 69 virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) | 69 virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) |
| 70 OVERRIDE; | 70 OVERRIDE; |
| 71 | 71 |
| 72 AudioRendererHost* const host_; | 72 AudioRendererHost* const host_; |
| 73 const int stream_id_; | 73 const int stream_id_; |
| 74 | 74 |
| 75 // The routing ID of the source render view. | 75 // The routing ID of the source render view. |
| 76 const int render_view_id_; | 76 const int render_view_id_; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 } | 137 } |
| 138 | 138 |
| 139 void AudioRendererHost::OnDestruct() const { | 139 void AudioRendererHost::OnDestruct() const { |
| 140 BrowserThread::DeleteOnIOThread::Destruct(this); | 140 BrowserThread::DeleteOnIOThread::Destruct(this); |
| 141 } | 141 } |
| 142 | 142 |
| 143 void AudioRendererHost::AudioEntry::OnCreated() { | 143 void AudioRendererHost::AudioEntry::OnCreated() { |
| 144 BrowserThread::PostTask( | 144 BrowserThread::PostTask( |
| 145 BrowserThread::IO, | 145 BrowserThread::IO, |
| 146 FROM_HERE, | 146 FROM_HERE, |
| 147 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, this)); | 147 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_)); |
| 148 } | 148 } |
| 149 | 149 |
| 150 void AudioRendererHost::AudioEntry::OnPlaying() { | 150 void AudioRendererHost::AudioEntry::OnPlaying() { |
| 151 BrowserThread::PostTask( | 151 BrowserThread::PostTask( |
| 152 BrowserThread::IO, | 152 BrowserThread::IO, |
| 153 FROM_HERE, | 153 FROM_HERE, |
| 154 base::Bind( | 154 base::Bind( |
| 155 base::IgnoreResult(&AudioRendererHost::Send), host_, | 155 base::IgnoreResult(&AudioRendererHost::Send), host_, |
| 156 new AudioMsg_NotifyStreamStateChanged( | 156 new AudioMsg_NotifyStreamStateChanged( |
| 157 stream_id_, media::AudioOutputIPCDelegate::kPlaying))); | 157 stream_id_, media::AudioOutputIPCDelegate::kPlaying))); |
| 158 } | 158 } |
| 159 | 159 |
| 160 void AudioRendererHost::AudioEntry::OnAudible(bool is_audible) { | 160 void AudioRendererHost::AudioEntry::OnPowerMeasured(float power_dbfs, |
| 161 bool clipped) { |
| 161 BrowserThread::PostTask( | 162 BrowserThread::PostTask( |
| 162 BrowserThread::IO, | 163 BrowserThread::IO, |
| 163 FROM_HERE, | 164 FROM_HERE, |
| 164 base::Bind(&AudioRendererHost::DoNotifyAudibleState, host_, | 165 base::Bind(&AudioRendererHost::DoNotifyAudioPowerLevel, host_, |
| 165 this, is_audible)); | 166 stream_id_, power_dbfs, clipped)); |
| 166 } | 167 } |
| 167 | 168 |
| 168 void AudioRendererHost::AudioEntry::OnPaused() { | 169 void AudioRendererHost::AudioEntry::OnPaused() { |
| 169 BrowserThread::PostTask( | 170 BrowserThread::PostTask( |
| 170 BrowserThread::IO, | 171 BrowserThread::IO, |
| 171 FROM_HERE, | 172 FROM_HERE, |
| 172 base::Bind( | 173 base::Bind( |
| 173 base::IgnoreResult(&AudioRendererHost::Send), host_, | 174 base::IgnoreResult(&AudioRendererHost::Send), host_, |
| 174 new AudioMsg_NotifyStreamStateChanged( | 175 new AudioMsg_NotifyStreamStateChanged( |
| 175 stream_id_, media::AudioOutputIPCDelegate::kPaused))); | 176 stream_id_, media::AudioOutputIPCDelegate::kPaused))); |
| 176 } | 177 } |
| 177 | 178 |
| 178 void AudioRendererHost::AudioEntry::OnError() { | 179 void AudioRendererHost::AudioEntry::OnError() { |
| 179 BrowserThread::PostTask( | 180 BrowserThread::PostTask( |
| 180 BrowserThread::IO, | 181 BrowserThread::IO, |
| 181 FROM_HERE, | 182 FROM_HERE, |
| 182 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_)); | 183 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_)); |
| 183 } | 184 } |
| 184 | 185 |
| 185 void AudioRendererHost::AudioEntry::OnDeviceChange(int new_buffer_size, | 186 void AudioRendererHost::AudioEntry::OnDeviceChange(int new_buffer_size, |
| 186 int new_sample_rate) { | 187 int new_sample_rate) { |
| 187 BrowserThread::PostTask( | 188 BrowserThread::PostTask( |
| 188 BrowserThread::IO, | 189 BrowserThread::IO, |
| 189 FROM_HERE, | 190 FROM_HERE, |
| 190 base::Bind(base::IgnoreResult(&AudioRendererHost::Send), host_, | 191 base::Bind(base::IgnoreResult(&AudioRendererHost::Send), host_, |
| 191 new AudioMsg_NotifyDeviceChanged( | 192 new AudioMsg_NotifyDeviceChanged( |
| 192 stream_id_, new_buffer_size, new_sample_rate))); | 193 stream_id_, new_buffer_size, new_sample_rate))); |
| 193 } | 194 } |
| 194 | 195 |
| 195 void AudioRendererHost::DoCompleteCreation(AudioEntry* entry) { | 196 void AudioRendererHost::DoCompleteCreation(int stream_id) { |
| 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 197 | 198 |
| 198 if (!PeerHandle()) { | 199 if (!PeerHandle()) { |
| 199 NOTREACHED() << "Renderer process handle is invalid."; | 200 NOTREACHED() << "Renderer process handle is invalid."; |
| 200 ReportErrorAndClose(entry->stream_id()); | 201 ReportErrorAndClose(stream_id); |
| 201 return; | 202 return; |
| 202 } | 203 } |
| 203 | 204 |
| 205 AudioEntry* const entry = LookupById(stream_id); |
| 206 if (!entry) { |
| 207 ReportErrorAndClose(stream_id); |
| 208 return; |
| 209 } |
| 210 |
| 204 // Once the audio stream is created then complete the creation process by | 211 // Once the audio stream is created then complete the creation process by |
| 205 // mapping shared memory and sharing with the renderer process. | 212 // mapping shared memory and sharing with the renderer process. |
| 206 base::SharedMemoryHandle foreign_memory_handle; | 213 base::SharedMemoryHandle foreign_memory_handle; |
| 207 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), | 214 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), |
| 208 &foreign_memory_handle)) { | 215 &foreign_memory_handle)) { |
| 209 // If we failed to map and share the shared memory then close the audio | 216 // If we failed to map and share the shared memory then close the audio |
| 210 // stream and send an error message. | 217 // stream and send an error message. |
| 211 ReportErrorAndClose(entry->stream_id()); | 218 ReportErrorAndClose(entry->stream_id()); |
| 212 return; | 219 return; |
| 213 } | 220 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 228 return; | 235 return; |
| 229 } | 236 } |
| 230 | 237 |
| 231 Send(new AudioMsg_NotifyStreamCreated( | 238 Send(new AudioMsg_NotifyStreamCreated( |
| 232 entry->stream_id(), | 239 entry->stream_id(), |
| 233 foreign_memory_handle, | 240 foreign_memory_handle, |
| 234 foreign_socket_handle, | 241 foreign_socket_handle, |
| 235 media::PacketSizeInBytes(entry->shared_memory()->requested_size()))); | 242 media::PacketSizeInBytes(entry->shared_memory()->requested_size()))); |
| 236 } | 243 } |
| 237 | 244 |
| 238 void AudioRendererHost::DoNotifyAudibleState(AudioEntry* entry, | 245 void AudioRendererHost::DoNotifyAudioPowerLevel(int stream_id, |
| 239 bool is_audible) { | 246 float power_dbfs, |
| 247 bool clipped) { |
| 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 241 | 249 |
| 242 MediaObserver* const media_observer = | 250 MediaObserver* const media_observer = |
| 243 GetContentClient()->browser()->GetMediaObserver(); | 251 GetContentClient()->browser()->GetMediaObserver(); |
| 244 if (media_observer) { | 252 if (media_observer) { |
| 245 DVLOG(1) << "AudioRendererHost@" << this | |
| 246 << "::DoNotifyAudibleState(is_audible=" << is_audible | |
| 247 << ") for stream_id=" << entry->stream_id(); | |
| 248 | |
| 249 if (CommandLine::ForCurrentProcess()->HasSwitch( | 253 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 250 switches::kEnableAudibleNotifications)) { | 254 switches::kEnableAudibleNotifications)) { |
| 251 media_observer->OnAudioStreamPlayingChanged( | 255 AudioEntry* const entry = LookupById(stream_id); |
| 252 render_process_id_, entry->render_view_id(), entry->stream_id(), | 256 if (entry) { |
| 253 is_audible); | 257 media_observer->OnAudioStreamPlayingChanged( |
| 258 render_process_id_, entry->render_view_id(), entry->stream_id(), |
| 259 true, power_dbfs, clipped); |
| 260 } |
| 254 } | 261 } |
| 255 } | 262 } |
| 256 } | 263 } |
| 257 | 264 |
| 258 /////////////////////////////////////////////////////////////////////////////// | 265 /////////////////////////////////////////////////////////////////////////////// |
| 259 // IPC Messages handler | 266 // IPC Messages handler |
| 260 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message, | 267 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message, |
| 261 bool* message_was_ok) { | 268 bool* message_was_ok) { |
| 262 bool handled = true; | 269 bool handled = true; |
| 263 IPC_BEGIN_MESSAGE_MAP_EX(AudioRendererHost, message, *message_was_ok) | 270 IPC_BEGIN_MESSAGE_MAP_EX(AudioRendererHost, message, *message_was_ok) |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 } | 432 } |
| 426 | 433 |
| 427 void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) { | 434 void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) { |
| 428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 429 | 436 |
| 430 // At this point, make the final "say" in audio playback state. | 437 // At this point, make the final "say" in audio playback state. |
| 431 MediaObserver* const media_observer = | 438 MediaObserver* const media_observer = |
| 432 GetContentClient()->browser()->GetMediaObserver(); | 439 GetContentClient()->browser()->GetMediaObserver(); |
| 433 if (media_observer) { | 440 if (media_observer) { |
| 434 media_observer->OnAudioStreamPlayingChanged( | 441 media_observer->OnAudioStreamPlayingChanged( |
| 435 render_process_id_, entry->render_view_id(), entry->stream_id(), false); | 442 render_process_id_, entry->render_view_id(), entry->stream_id(), |
| 443 false, -std::numeric_limits<float>::infinity(), false); |
| 436 } | 444 } |
| 437 | 445 |
| 438 // Notify the media observer. | 446 // Notify the media observer. |
| 439 if (media_internals_) | 447 if (media_internals_) |
| 440 media_internals_->OnDeleteAudioStream(this, entry->stream_id()); | 448 media_internals_->OnDeleteAudioStream(this, entry->stream_id()); |
| 441 | 449 |
| 442 // Note: |entry| will be deleted upon leaving this scope. | 450 // Note: |entry| will be deleted upon leaving this scope. |
| 443 } | 451 } |
| 444 | 452 |
| 445 void AudioRendererHost::ReportErrorAndClose(int stream_id) { | 453 void AudioRendererHost::ReportErrorAndClose(int stream_id) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 460 } | 468 } |
| 461 | 469 |
| 462 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { | 470 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { |
| 463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 471 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 464 | 472 |
| 465 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); | 473 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); |
| 466 return i != audio_entries_.end() ? i->second : NULL; | 474 return i != audio_entries_.end() ? i->second : NULL; |
| 467 } | 475 } |
| 468 | 476 |
| 469 } // namespace content | 477 } // namespace content |
| OLD | NEW |