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/media/media_internals.h" | 12 #include "content/browser/media/media_internals.h" |
13 #include "content/browser/renderer_host/media/audio_mirroring_manager.h" | 13 #include "content/browser/renderer_host/media/audio_mirroring_manager.h" |
14 #include "content/browser/renderer_host/media/audio_sync_reader.h" | 14 #include "content/browser/renderer_host/media/audio_sync_reader.h" |
15 #include "content/common/media/audio_messages.h" | 15 #include "content/common/media/audio_messages.h" |
| 16 #include "content/public/browser/content_browser_client.h" |
| 17 #include "content/public/browser/media_observer.h" |
16 #include "media/audio/shared_memory_util.h" | 18 #include "media/audio/shared_memory_util.h" |
17 #include "media/base/audio_bus.h" | 19 #include "media/base/audio_bus.h" |
18 #include "media/base/limits.h" | 20 #include "media/base/limits.h" |
19 | 21 |
20 using media::AudioBus; | 22 using media::AudioBus; |
21 | 23 |
22 namespace content { | 24 namespace content { |
23 | 25 |
24 struct AudioRendererHost::AudioEntry { | 26 struct AudioRendererHost::AudioEntry { |
25 AudioEntry(); | 27 AudioEntry(); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 | 327 |
326 AudioEntry* const entry = LookupById(stream_id); | 328 AudioEntry* const entry = LookupById(stream_id); |
327 if (!entry) { | 329 if (!entry) { |
328 SendErrorMessage(stream_id); | 330 SendErrorMessage(stream_id); |
329 return; | 331 return; |
330 } | 332 } |
331 | 333 |
332 if (entry->render_view_id == render_view_id) | 334 if (entry->render_view_id == render_view_id) |
333 return; | 335 return; |
334 | 336 |
| 337 // TODO(miu): Merge "AssociateWithProducer" message into "CreateStream" |
| 338 // message so AudioRendererHost can assume a simpler "render_view_id is set |
| 339 // once" scheme. http://crbug.com/166779 |
335 if (mirroring_manager_) { | 340 if (mirroring_manager_) { |
336 mirroring_manager_->RemoveDiverter( | 341 mirroring_manager_->RemoveDiverter( |
337 render_process_id_, entry->render_view_id, entry->controller); | 342 render_process_id_, entry->render_view_id, entry->controller); |
338 } | 343 } |
339 entry->render_view_id = render_view_id; | 344 entry->render_view_id = render_view_id; |
340 if (mirroring_manager_) { | 345 if (mirroring_manager_) { |
341 mirroring_manager_->AddDiverter( | 346 mirroring_manager_->AddDiverter( |
342 render_process_id_, entry->render_view_id, entry->controller); | 347 render_process_id_, entry->render_view_id, entry->controller); |
343 } | 348 } |
344 } | 349 } |
345 | 350 |
346 void AudioRendererHost::OnPlayStream(int stream_id) { | 351 void AudioRendererHost::OnPlayStream(int stream_id) { |
347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 352 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
348 | 353 |
349 AudioEntry* entry = LookupById(stream_id); | 354 AudioEntry* entry = LookupById(stream_id); |
350 if (!entry) { | 355 if (!entry) { |
351 SendErrorMessage(stream_id); | 356 SendErrorMessage(stream_id); |
352 return; | 357 return; |
353 } | 358 } |
354 | 359 |
355 entry->controller->Play(); | 360 entry->controller->Play(); |
356 if (media_internals_) | 361 if (media_internals_) |
357 media_internals_->OnSetAudioStreamPlaying(this, stream_id, true); | 362 media_internals_->OnSetAudioStreamPlaying(this, stream_id, true); |
| 363 |
| 364 MediaObserver* media_observer = |
| 365 GetContentClient()->browser()->GetMediaObserver(); |
| 366 if (media_observer) { |
| 367 media_observer->OnAudioStreamPlayingChanged( |
| 368 render_process_id_, entry->render_view_id, stream_id, true); |
| 369 } |
358 } | 370 } |
359 | 371 |
360 void AudioRendererHost::OnPauseStream(int stream_id) { | 372 void AudioRendererHost::OnPauseStream(int stream_id) { |
361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
362 | 374 |
363 AudioEntry* entry = LookupById(stream_id); | 375 AudioEntry* entry = LookupById(stream_id); |
364 if (!entry) { | 376 if (!entry) { |
365 SendErrorMessage(stream_id); | 377 SendErrorMessage(stream_id); |
366 return; | 378 return; |
367 } | 379 } |
368 | 380 |
369 entry->controller->Pause(); | 381 entry->controller->Pause(); |
370 if (media_internals_) | 382 if (media_internals_) |
371 media_internals_->OnSetAudioStreamPlaying(this, stream_id, false); | 383 media_internals_->OnSetAudioStreamPlaying(this, stream_id, false); |
| 384 |
| 385 MediaObserver* media_observer = |
| 386 GetContentClient()->browser()->GetMediaObserver(); |
| 387 if (media_observer) { |
| 388 media_observer->OnAudioStreamPlayingChanged( |
| 389 render_process_id_, entry->render_view_id, stream_id, false); |
| 390 } |
372 } | 391 } |
373 | 392 |
374 void AudioRendererHost::OnFlushStream(int stream_id) { | 393 void AudioRendererHost::OnFlushStream(int stream_id) { |
375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
376 | 395 |
377 AudioEntry* entry = LookupById(stream_id); | 396 AudioEntry* entry = LookupById(stream_id); |
378 if (!entry) { | 397 if (!entry) { |
379 SendErrorMessage(stream_id); | 398 SendErrorMessage(stream_id); |
380 return; | 399 return; |
381 } | 400 } |
382 | 401 |
383 entry->controller->Flush(); | 402 entry->controller->Flush(); |
384 if (media_internals_) | 403 if (media_internals_) |
385 media_internals_->OnSetAudioStreamStatus(this, stream_id, "flushed"); | 404 media_internals_->OnSetAudioStreamStatus(this, stream_id, "flushed"); |
386 } | 405 } |
387 | 406 |
388 void AudioRendererHost::OnCloseStream(int stream_id) { | 407 void AudioRendererHost::OnCloseStream(int stream_id) { |
389 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
390 | 409 |
391 if (media_internals_) | 410 if (media_internals_) |
392 media_internals_->OnSetAudioStreamStatus(this, stream_id, "closed"); | 411 media_internals_->OnSetAudioStreamStatus(this, stream_id, "closed"); |
393 | 412 |
394 AudioEntry* entry = LookupById(stream_id); | 413 AudioEntry* entry = LookupById(stream_id); |
395 | 414 |
396 if (entry) | 415 if (!entry) |
397 CloseAndDeleteStream(entry); | 416 return; |
| 417 |
| 418 CloseAndDeleteStream(entry); |
398 } | 419 } |
399 | 420 |
400 void AudioRendererHost::OnSetVolume(int stream_id, double volume) { | 421 void AudioRendererHost::OnSetVolume(int stream_id, double volume) { |
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 422 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
402 | 423 |
403 AudioEntry* entry = LookupById(stream_id); | 424 AudioEntry* entry = LookupById(stream_id); |
404 if (!entry) { | 425 if (!entry) { |
405 SendErrorMessage(stream_id); | 426 SendErrorMessage(stream_id); |
406 return; | 427 return; |
407 } | 428 } |
408 | 429 |
409 // Make sure the volume is valid. | 430 // Make sure the volume is valid. |
410 if (volume < 0 || volume > 1.0) | 431 if (volume < 0 || volume > 1.0) |
411 return; | 432 return; |
412 entry->controller->SetVolume(volume); | 433 entry->controller->SetVolume(volume); |
413 if (media_internals_) | 434 if (media_internals_) |
414 media_internals_->OnSetAudioStreamVolume(this, stream_id, volume); | 435 media_internals_->OnSetAudioStreamVolume(this, stream_id, volume); |
| 436 |
| 437 MediaObserver* media_observer = |
| 438 GetContentClient()->browser()->GetMediaObserver(); |
| 439 if (media_observer) { |
| 440 bool playing = volume > 0; |
| 441 media_observer->OnAudioStreamPlayingChanged( |
| 442 render_process_id_, entry->render_view_id, stream_id, playing); |
| 443 } |
415 } | 444 } |
416 | 445 |
417 void AudioRendererHost::SendErrorMessage(int32 stream_id) { | 446 void AudioRendererHost::SendErrorMessage(int32 stream_id) { |
418 Send(new AudioMsg_NotifyStreamStateChanged( | 447 Send(new AudioMsg_NotifyStreamStateChanged( |
419 stream_id, media::AudioOutputIPCDelegate::kError)); | 448 stream_id, media::AudioOutputIPCDelegate::kError)); |
420 } | 449 } |
421 | 450 |
422 void AudioRendererHost::DeleteEntries() { | 451 void AudioRendererHost::DeleteEntries() { |
423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
424 | 453 |
425 for (AudioEntryMap::iterator i = audio_entries_.begin(); | 454 for (AudioEntryMap::iterator i = audio_entries_.begin(); |
426 i != audio_entries_.end(); ++i) { | 455 i != audio_entries_.end(); ++i) { |
427 CloseAndDeleteStream(i->second); | 456 CloseAndDeleteStream(i->second); |
428 } | 457 } |
429 } | 458 } |
430 | 459 |
431 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) { | 460 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) { |
432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
433 | 462 |
| 463 MediaObserver* media_observer = |
| 464 GetContentClient()->browser()->GetMediaObserver(); |
| 465 if (media_observer) { |
| 466 media_observer->OnAudioStreamPlayingChanged( |
| 467 render_process_id_, entry->render_view_id, entry->stream_id, false); |
| 468 } |
434 if (!entry->pending_close) { | 469 if (!entry->pending_close) { |
435 if (mirroring_manager_) { | 470 if (mirroring_manager_) { |
436 mirroring_manager_->RemoveDiverter( | 471 mirroring_manager_->RemoveDiverter( |
437 render_process_id_, entry->render_view_id, entry->controller); | 472 render_process_id_, entry->render_view_id, entry->controller); |
438 } | 473 } |
439 entry->controller->Close( | 474 entry->controller->Close( |
440 base::Bind(&AudioRendererHost::DeleteEntry, this, entry)); | 475 base::Bind(&AudioRendererHost::DeleteEntry, this, entry)); |
441 entry->pending_close = true; | 476 entry->pending_close = true; |
442 } | 477 } |
443 } | 478 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 return NULL; | 526 return NULL; |
492 } | 527 } |
493 | 528 |
494 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting( | 529 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting( |
495 int stream_id) { | 530 int stream_id) { |
496 AudioEntry* const entry = LookupById(stream_id); | 531 AudioEntry* const entry = LookupById(stream_id); |
497 return entry ? entry->controller : NULL; | 532 return entry ? entry->controller : NULL; |
498 } | 533 } |
499 | 534 |
500 } // namespace content | 535 } // namespace content |
OLD | NEW |