| 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 int new_sample_rate) { | 197 int new_sample_rate) { |
| 198 BrowserThread::PostTask( | 198 BrowserThread::PostTask( |
| 199 BrowserThread::IO, | 199 BrowserThread::IO, |
| 200 FROM_HERE, | 200 FROM_HERE, |
| 201 base::Bind(base::IgnoreResult(&AudioRendererHost::Send), host_, | 201 base::Bind(base::IgnoreResult(&AudioRendererHost::Send), host_, |
| 202 new AudioMsg_NotifyDeviceChanged( | 202 new AudioMsg_NotifyDeviceChanged( |
| 203 stream_id_, new_buffer_size, new_sample_rate))); | 203 stream_id_, new_buffer_size, new_sample_rate))); |
| 204 } | 204 } |
| 205 | 205 |
| 206 void AudioRendererHost::DoCompleteCreation(int stream_id) { | 206 void AudioRendererHost::DoCompleteCreation(int stream_id) { |
| 207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 207 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 208 | 208 |
| 209 if (!PeerHandle()) { | 209 if (!PeerHandle()) { |
| 210 DLOG(WARNING) << "Renderer process handle is invalid."; | 210 DLOG(WARNING) << "Renderer process handle is invalid."; |
| 211 ReportErrorAndClose(stream_id); | 211 ReportErrorAndClose(stream_id); |
| 212 return; | 212 return; |
| 213 } | 213 } |
| 214 | 214 |
| 215 AudioEntry* const entry = LookupById(stream_id); | 215 AudioEntry* const entry = LookupById(stream_id); |
| 216 if (!entry) { | 216 if (!entry) { |
| 217 ReportErrorAndClose(stream_id); | 217 ReportErrorAndClose(stream_id); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 247 | 247 |
| 248 Send(new AudioMsg_NotifyStreamCreated( | 248 Send(new AudioMsg_NotifyStreamCreated( |
| 249 entry->stream_id(), | 249 entry->stream_id(), |
| 250 foreign_memory_handle, | 250 foreign_memory_handle, |
| 251 foreign_socket_handle, | 251 foreign_socket_handle, |
| 252 entry->shared_memory()->requested_size())); | 252 entry->shared_memory()->requested_size())); |
| 253 } | 253 } |
| 254 | 254 |
| 255 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, | 255 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, |
| 256 bool is_playing) { | 256 bool is_playing) { |
| 257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 257 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 258 | 258 |
| 259 AudioEntry* const entry = LookupById(stream_id); | 259 AudioEntry* const entry = LookupById(stream_id); |
| 260 if (!entry) | 260 if (!entry) |
| 261 return; | 261 return; |
| 262 | 262 |
| 263 Send(new AudioMsg_NotifyStreamStateChanged( | 263 Send(new AudioMsg_NotifyStreamStateChanged( |
| 264 stream_id, | 264 stream_id, |
| 265 is_playing ? media::AudioOutputIPCDelegate::kPlaying | 265 is_playing ? media::AudioOutputIPCDelegate::kPlaying |
| 266 : media::AudioOutputIPCDelegate::kPaused)); | 266 : media::AudioOutputIPCDelegate::kPaused)); |
| 267 | 267 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 278 } else { | 278 } else { |
| 279 media_observer->OnAudioStreamStopped(render_process_id_, | 279 media_observer->OnAudioStreamStopped(render_process_id_, |
| 280 entry->render_frame_id(), | 280 entry->render_frame_id(), |
| 281 entry->stream_id()); | 281 entry->stream_id()); |
| 282 } | 282 } |
| 283 } | 283 } |
| 284 } | 284 } |
| 285 | 285 |
| 286 RenderViewHost::AudioOutputControllerList | 286 RenderViewHost::AudioOutputControllerList |
| 287 AudioRendererHost::DoGetOutputControllers(int render_view_id) const { | 287 AudioRendererHost::DoGetOutputControllers(int render_view_id) const { |
| 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 288 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 289 | 289 |
| 290 RenderViewHost::AudioOutputControllerList controllers; | 290 RenderViewHost::AudioOutputControllerList controllers; |
| 291 AudioEntryMap::const_iterator it = audio_entries_.begin(); | 291 AudioEntryMap::const_iterator it = audio_entries_.begin(); |
| 292 for (; it != audio_entries_.end(); ++it) { | 292 for (; it != audio_entries_.end(); ++it) { |
| 293 AudioEntry* entry = it->second; | 293 AudioEntry* entry = it->second; |
| 294 if (entry->render_view_id() == render_view_id) | 294 if (entry->render_view_id() == render_view_id) |
| 295 controllers.push_back(entry->controller()); | 295 controllers.push_back(entry->controller()); |
| 296 } | 296 } |
| 297 | 297 |
| 298 return controllers; | 298 return controllers; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 311 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) | 311 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) |
| 312 IPC_MESSAGE_UNHANDLED(handled = false) | 312 IPC_MESSAGE_UNHANDLED(handled = false) |
| 313 IPC_END_MESSAGE_MAP_EX() | 313 IPC_END_MESSAGE_MAP_EX() |
| 314 | 314 |
| 315 return handled; | 315 return handled; |
| 316 } | 316 } |
| 317 | 317 |
| 318 void AudioRendererHost::OnCreateStream( | 318 void AudioRendererHost::OnCreateStream( |
| 319 int stream_id, int render_view_id, int render_frame_id, int session_id, | 319 int stream_id, int render_view_id, int render_frame_id, int session_id, |
| 320 const media::AudioParameters& params) { | 320 const media::AudioParameters& params) { |
| 321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 321 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 322 | 322 |
| 323 DVLOG(1) << "AudioRendererHost@" << this | 323 DVLOG(1) << "AudioRendererHost@" << this |
| 324 << "::OnCreateStream(stream_id=" << stream_id | 324 << "::OnCreateStream(stream_id=" << stream_id |
| 325 << ", render_view_id=" << render_view_id | 325 << ", render_view_id=" << render_view_id |
| 326 << ", session_id=" << session_id << ")"; | 326 << ", session_id=" << session_id << ")"; |
| 327 DCHECK_GT(render_view_id, 0); | 327 DCHECK_GT(render_view_id, 0); |
| 328 DCHECK_GT(render_frame_id, 0); | 328 DCHECK_GT(render_frame_id, 0); |
| 329 | 329 |
| 330 // media::AudioParameters is validated in the deserializer. | 330 // media::AudioParameters is validated in the deserializer. |
| 331 if (LookupById(stream_id) != NULL) { | 331 if (LookupById(stream_id) != NULL) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 reader.PassAs<media::AudioOutputController::SyncReader>())); | 375 reader.PassAs<media::AudioOutputController::SyncReader>())); |
| 376 if (mirroring_manager_) { | 376 if (mirroring_manager_) { |
| 377 mirroring_manager_->AddDiverter( | 377 mirroring_manager_->AddDiverter( |
| 378 render_process_id_, entry->render_view_id(), entry->controller()); | 378 render_process_id_, entry->render_view_id(), entry->controller()); |
| 379 } | 379 } |
| 380 audio_entries_.insert(std::make_pair(stream_id, entry.release())); | 380 audio_entries_.insert(std::make_pair(stream_id, entry.release())); |
| 381 audio_log_->OnCreated(stream_id, params, output_device_id); | 381 audio_log_->OnCreated(stream_id, params, output_device_id); |
| 382 } | 382 } |
| 383 | 383 |
| 384 void AudioRendererHost::OnPlayStream(int stream_id) { | 384 void AudioRendererHost::OnPlayStream(int stream_id) { |
| 385 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 385 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 386 | 386 |
| 387 AudioEntry* entry = LookupById(stream_id); | 387 AudioEntry* entry = LookupById(stream_id); |
| 388 if (!entry) { | 388 if (!entry) { |
| 389 SendErrorMessage(stream_id); | 389 SendErrorMessage(stream_id); |
| 390 return; | 390 return; |
| 391 } | 391 } |
| 392 | 392 |
| 393 entry->controller()->Play(); | 393 entry->controller()->Play(); |
| 394 audio_log_->OnStarted(stream_id); | 394 audio_log_->OnStarted(stream_id); |
| 395 } | 395 } |
| 396 | 396 |
| 397 void AudioRendererHost::OnPauseStream(int stream_id) { | 397 void AudioRendererHost::OnPauseStream(int stream_id) { |
| 398 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 398 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 399 | 399 |
| 400 AudioEntry* entry = LookupById(stream_id); | 400 AudioEntry* entry = LookupById(stream_id); |
| 401 if (!entry) { | 401 if (!entry) { |
| 402 SendErrorMessage(stream_id); | 402 SendErrorMessage(stream_id); |
| 403 return; | 403 return; |
| 404 } | 404 } |
| 405 | 405 |
| 406 entry->controller()->Pause(); | 406 entry->controller()->Pause(); |
| 407 audio_log_->OnStopped(stream_id); | 407 audio_log_->OnStopped(stream_id); |
| 408 } | 408 } |
| 409 | 409 |
| 410 void AudioRendererHost::OnSetVolume(int stream_id, double volume) { | 410 void AudioRendererHost::OnSetVolume(int stream_id, double volume) { |
| 411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 411 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 412 | 412 |
| 413 AudioEntry* entry = LookupById(stream_id); | 413 AudioEntry* entry = LookupById(stream_id); |
| 414 if (!entry) { | 414 if (!entry) { |
| 415 SendErrorMessage(stream_id); | 415 SendErrorMessage(stream_id); |
| 416 return; | 416 return; |
| 417 } | 417 } |
| 418 | 418 |
| 419 // Make sure the volume is valid. | 419 // Make sure the volume is valid. |
| 420 if (volume < 0 || volume > 1.0) | 420 if (volume < 0 || volume > 1.0) |
| 421 return; | 421 return; |
| 422 entry->controller()->SetVolume(volume); | 422 entry->controller()->SetVolume(volume); |
| 423 audio_log_->OnSetVolume(stream_id, volume); | 423 audio_log_->OnSetVolume(stream_id, volume); |
| 424 } | 424 } |
| 425 | 425 |
| 426 void AudioRendererHost::SendErrorMessage(int stream_id) { | 426 void AudioRendererHost::SendErrorMessage(int stream_id) { |
| 427 Send(new AudioMsg_NotifyStreamStateChanged( | 427 Send(new AudioMsg_NotifyStreamStateChanged( |
| 428 stream_id, media::AudioOutputIPCDelegate::kError)); | 428 stream_id, media::AudioOutputIPCDelegate::kError)); |
| 429 } | 429 } |
| 430 | 430 |
| 431 void AudioRendererHost::OnCloseStream(int stream_id) { | 431 void AudioRendererHost::OnCloseStream(int stream_id) { |
| 432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 432 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 433 | 433 |
| 434 // Prevent oustanding callbacks from attempting to close/delete the same | 434 // Prevent oustanding callbacks from attempting to close/delete the same |
| 435 // AudioEntry twice. | 435 // AudioEntry twice. |
| 436 AudioEntryMap::iterator i = audio_entries_.find(stream_id); | 436 AudioEntryMap::iterator i = audio_entries_.find(stream_id); |
| 437 if (i == audio_entries_.end()) | 437 if (i == audio_entries_.end()) |
| 438 return; | 438 return; |
| 439 scoped_ptr<AudioEntry> entry(i->second); | 439 scoped_ptr<AudioEntry> entry(i->second); |
| 440 audio_entries_.erase(i); | 440 audio_entries_.erase(i); |
| 441 | 441 |
| 442 media::AudioOutputController* const controller = entry->controller(); | 442 media::AudioOutputController* const controller = entry->controller(); |
| 443 if (mirroring_manager_) { | 443 if (mirroring_manager_) { |
| 444 mirroring_manager_->RemoveDiverter( | 444 mirroring_manager_->RemoveDiverter( |
| 445 render_process_id_, entry->render_view_id(), controller); | 445 render_process_id_, entry->render_view_id(), controller); |
| 446 } | 446 } |
| 447 controller->Close( | 447 controller->Close( |
| 448 base::Bind(&AudioRendererHost::DeleteEntry, this, base::Passed(&entry))); | 448 base::Bind(&AudioRendererHost::DeleteEntry, this, base::Passed(&entry))); |
| 449 audio_log_->OnClosed(stream_id); | 449 audio_log_->OnClosed(stream_id); |
| 450 } | 450 } |
| 451 | 451 |
| 452 void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) { | 452 void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) { |
| 453 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 453 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 454 | 454 |
| 455 // At this point, make the final "say" in audio playback state. | 455 // At this point, make the final "say" in audio playback state. |
| 456 MediaObserver* const media_observer = | 456 MediaObserver* const media_observer = |
| 457 GetContentClient()->browser()->GetMediaObserver(); | 457 GetContentClient()->browser()->GetMediaObserver(); |
| 458 if (media_observer) { | 458 if (media_observer) { |
| 459 media_observer->OnAudioStreamStopped(render_process_id_, | 459 media_observer->OnAudioStreamStopped(render_process_id_, |
| 460 entry->render_frame_id(), | 460 entry->render_frame_id(), |
| 461 entry->stream_id()); | 461 entry->stream_id()); |
| 462 } | 462 } |
| 463 } | 463 } |
| 464 | 464 |
| 465 void AudioRendererHost::ReportErrorAndClose(int stream_id) { | 465 void AudioRendererHost::ReportErrorAndClose(int stream_id) { |
| 466 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 466 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 467 | 467 |
| 468 // Make sure this isn't a stray callback executing after the stream has been | 468 // Make sure this isn't a stray callback executing after the stream has been |
| 469 // closed, so error notifications aren't sent after clients believe the stream | 469 // closed, so error notifications aren't sent after clients believe the stream |
| 470 // is closed. | 470 // is closed. |
| 471 if (!LookupById(stream_id)) | 471 if (!LookupById(stream_id)) |
| 472 return; | 472 return; |
| 473 | 473 |
| 474 SendErrorMessage(stream_id); | 474 SendErrorMessage(stream_id); |
| 475 | 475 |
| 476 audio_log_->OnError(stream_id); | 476 audio_log_->OnError(stream_id); |
| 477 OnCloseStream(stream_id); | 477 OnCloseStream(stream_id); |
| 478 } | 478 } |
| 479 | 479 |
| 480 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { | 480 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { |
| 481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 481 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 482 | 482 |
| 483 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); | 483 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); |
| 484 return i != audio_entries_.end() ? i->second : NULL; | 484 return i != audio_entries_.end() ? i->second : NULL; |
| 485 } | 485 } |
| 486 | 486 |
| 487 } // namespace content | 487 } // namespace content |
| OLD | NEW |