| 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 |