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 |