Chromium Code Reviews| 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/renderer_host/media/audio_sync_reader.h" | 12 #include "content/browser/renderer_host/media/audio_sync_reader.h" |
| 13 #include "content/browser/renderer_host/media/audio_mirroring_manager.h" | |
| 13 #include "content/common/media/audio_messages.h" | 14 #include "content/common/media/audio_messages.h" |
| 14 #include "content/public/browser/media_observer.h" | 15 #include "content/public/browser/media_observer.h" |
| 15 #include "media/audio/shared_memory_util.h" | 16 #include "media/audio/shared_memory_util.h" |
| 16 #include "media/base/audio_bus.h" | 17 #include "media/base/audio_bus.h" |
| 17 #include "media/base/limits.h" | 18 #include "media/base/limits.h" |
| 18 | 19 |
| 19 using media::AudioBus; | 20 using media::AudioBus; |
| 20 | 21 |
| 21 namespace content { | 22 namespace content { |
| 22 | 23 |
| 24 namespace { | |
| 25 | |
| 26 // Simple wrapper around a media::AudioOutputController to implement the | |
| 27 // AudioMirroringManager::Diverter interface. | |
| 28 class ControllerDiverter : public AudioMirroringManager::Diverter { | |
| 29 public: | |
| 30 void SetController(media::AudioOutputController* controller); | |
| 31 | |
| 32 // AudioMirroringManager::Diverter implementation. | |
| 33 virtual const media::AudioParameters& GetAudioParameters() OVERRIDE; | |
| 34 virtual void StartDiverting(media::AudioOutputStream* stream) OVERRIDE; | |
| 35 virtual void StopDiverting() OVERRIDE; | |
| 36 | |
| 37 private: | |
| 38 media::AudioOutputController* controller_; // Not owned. | |
| 39 }; | |
| 40 | |
| 41 void ControllerDiverter::SetController(media::AudioOutputController* ctlr) { | |
| 42 controller_ = ctlr; | |
| 43 } | |
| 44 | |
| 45 const media::AudioParameters& ControllerDiverter::GetAudioParameters() { | |
| 46 return controller_->params(); | |
| 47 } | |
| 48 | |
| 49 void ControllerDiverter::StartDiverting(media::AudioOutputStream* stream) { | |
| 50 controller_->StartDiverting(stream); | |
| 51 } | |
| 52 | |
| 53 void ControllerDiverter::StopDiverting() { | |
| 54 controller_->StopDiverting(); | |
| 55 } | |
| 56 | |
| 57 } // namespace | |
| 58 | |
| 23 struct AudioRendererHost::AudioEntry { | 59 struct AudioRendererHost::AudioEntry { |
| 24 AudioEntry(); | 60 AudioEntry(); |
| 25 ~AudioEntry(); | 61 ~AudioEntry(); |
| 26 | 62 |
| 27 // The AudioOutputController that manages the audio stream. | 63 // The AudioOutputController that manages the audio stream. |
| 28 scoped_refptr<media::AudioOutputController> controller; | 64 scoped_refptr<media::AudioOutputController> controller; |
| 65 ControllerDiverter diverter; | |
| 29 | 66 |
| 30 // The audio stream ID. | 67 // The audio stream ID. |
| 31 int stream_id; | 68 int stream_id; |
| 32 | 69 |
| 70 // The routing ID of the source render view. | |
| 71 int render_view_id; | |
| 72 | |
| 33 // Shared memory for transmission of the audio data. | 73 // Shared memory for transmission of the audio data. |
| 34 base::SharedMemory shared_memory; | 74 base::SharedMemory shared_memory; |
| 35 | 75 |
| 36 // The synchronous reader to be used by the controller. We have the | 76 // The synchronous reader to be used by the controller. We have the |
| 37 // ownership of the reader. | 77 // ownership of the reader. |
| 38 scoped_ptr<media::AudioOutputController::SyncReader> reader; | 78 scoped_ptr<media::AudioOutputController::SyncReader> reader; |
| 39 | 79 |
| 40 // Set to true after we called Close() for the controller. | 80 // Set to true after we called Close() for the controller. |
| 41 bool pending_close; | 81 bool pending_close; |
| 42 }; | 82 }; |
| 43 | 83 |
| 44 AudioRendererHost::AudioEntry::AudioEntry() | 84 AudioRendererHost::AudioEntry::AudioEntry() |
| 45 : stream_id(0), | 85 : stream_id(0), |
| 86 render_view_id(MSG_ROUTING_NONE), | |
| 46 pending_close(false) { | 87 pending_close(false) { |
| 47 } | 88 } |
| 48 | 89 |
| 49 AudioRendererHost::AudioEntry::~AudioEntry() {} | 90 AudioRendererHost::AudioEntry::~AudioEntry() {} |
| 50 | 91 |
| 51 /////////////////////////////////////////////////////////////////////////////// | 92 /////////////////////////////////////////////////////////////////////////////// |
| 52 // AudioRendererHost implementations. | 93 // AudioRendererHost implementations. |
| 53 AudioRendererHost::AudioRendererHost( | 94 AudioRendererHost::AudioRendererHost( |
| 95 int render_process_id, | |
| 54 media::AudioManager* audio_manager, MediaObserver* media_observer) | 96 media::AudioManager* audio_manager, MediaObserver* media_observer) |
| 55 : audio_manager_(audio_manager), | 97 : render_process_id_(render_process_id), |
| 98 audio_manager_(audio_manager), | |
| 56 media_observer_(media_observer) { | 99 media_observer_(media_observer) { |
| 57 } | 100 } |
| 58 | 101 |
| 59 AudioRendererHost::~AudioRendererHost() { | 102 AudioRendererHost::~AudioRendererHost() { |
| 60 DCHECK(audio_entries_.empty()); | 103 DCHECK(audio_entries_.empty()); |
| 61 } | 104 } |
| 62 | 105 |
| 63 void AudioRendererHost::OnChannelClosing() { | 106 void AudioRendererHost::OnChannelClosing() { |
| 64 BrowserMessageFilter::OnChannelClosing(); | 107 BrowserMessageFilter::OnChannelClosing(); |
| 65 | 108 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 if (!reader->Init()) { | 305 if (!reader->Init()) { |
| 263 SendErrorMessage(stream_id); | 306 SendErrorMessage(stream_id); |
| 264 return; | 307 return; |
| 265 } | 308 } |
| 266 | 309 |
| 267 // If we have successfully created the SyncReader then assign it to the | 310 // If we have successfully created the SyncReader then assign it to the |
| 268 // entry and construct an AudioOutputController. | 311 // entry and construct an AudioOutputController. |
| 269 entry->reader.reset(reader.release()); | 312 entry->reader.reset(reader.release()); |
| 270 entry->controller = media::AudioOutputController::Create( | 313 entry->controller = media::AudioOutputController::Create( |
| 271 audio_manager_, this, audio_params, entry->reader.get()); | 314 audio_manager_, this, audio_params, entry->reader.get()); |
| 272 | |
| 273 if (!entry->controller) { | 315 if (!entry->controller) { |
| 274 SendErrorMessage(stream_id); | 316 SendErrorMessage(stream_id); |
| 275 return; | 317 return; |
| 276 } | 318 } |
| 319 entry->diverter.SetController(entry->controller); | |
|
tommi (sloooow) - chröme
2012/12/19 12:27:54
nit: keep an empty line after end of scope
miu
2012/12/28 23:03:49
Done.
| |
| 277 | 320 |
| 278 // If we have created the controller successfully, create an entry and add it | 321 // If we have created the controller successfully, create an entry and add it |
| 279 // to the map. | 322 // to the map. |
| 280 entry->stream_id = stream_id; | 323 entry->stream_id = stream_id; |
| 281 audio_entries_.insert(std::make_pair(stream_id, entry.release())); | 324 audio_entries_.insert(std::make_pair(stream_id, entry.release())); |
| 282 if (media_observer_) | 325 if (media_observer_) |
| 283 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created"); | 326 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created"); |
| 284 } | 327 } |
| 285 | 328 |
| 286 void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id, | 329 void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id, |
| 287 int render_view_id) { | 330 int render_view_id) { |
| 288 // TODO(miu): Will use render_view_id in upcoming change. | 331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 332 | |
| 289 DVLOG(1) << "AudioRendererHost@" << this | 333 DVLOG(1) << "AudioRendererHost@" << this |
| 290 << "::OnAssociateStreamWithProducer(stream_id=" << stream_id | 334 << "::OnAssociateStreamWithProducer(stream_id=" << stream_id |
| 291 << ", render_view_id=" << render_view_id << ")"; | 335 << ", render_view_id=" << render_view_id << ")"; |
| 336 | |
| 337 AudioEntry* const entry = LookupById(stream_id); | |
| 338 if (!entry) { | |
| 339 SendErrorMessage(stream_id); | |
| 340 return; | |
| 341 } | |
| 342 | |
| 343 if (entry->render_view_id == render_view_id) | |
| 344 return; // No change. | |
| 345 | |
| 346 AudioMirroringManager* const amm = AudioMirroringManager::GetInstance(); | |
| 347 amm->RemoveDiverter( | |
| 348 render_process_id_, entry->render_view_id, &entry->diverter); | |
| 349 entry->render_view_id = render_view_id; | |
| 350 amm->AddDiverter( | |
| 351 render_process_id_, entry->render_view_id, &entry->diverter); | |
| 292 } | 352 } |
| 293 | 353 |
| 294 void AudioRendererHost::OnPlayStream(int stream_id) { | 354 void AudioRendererHost::OnPlayStream(int stream_id) { |
| 295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 296 | 356 |
| 297 AudioEntry* entry = LookupById(stream_id); | 357 AudioEntry* entry = LookupById(stream_id); |
| 298 if (!entry) { | 358 if (!entry) { |
| 299 SendErrorMessage(stream_id); | 359 SendErrorMessage(stream_id); |
| 300 return; | 360 return; |
| 301 } | 361 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 for (AudioEntryMap::iterator i = audio_entries_.begin(); | 433 for (AudioEntryMap::iterator i = audio_entries_.begin(); |
| 374 i != audio_entries_.end(); ++i) { | 434 i != audio_entries_.end(); ++i) { |
| 375 CloseAndDeleteStream(i->second); | 435 CloseAndDeleteStream(i->second); |
| 376 } | 436 } |
| 377 } | 437 } |
| 378 | 438 |
| 379 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) { | 439 void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) { |
| 380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 381 | 441 |
| 382 if (!entry->pending_close) { | 442 if (!entry->pending_close) { |
| 443 AudioMirroringManager::GetInstance()->RemoveDiverter( | |
| 444 render_process_id_, entry->render_view_id, &entry->diverter); | |
| 383 entry->controller->Close( | 445 entry->controller->Close( |
| 384 base::Bind(&AudioRendererHost::DeleteEntry, this, entry)); | 446 base::Bind(&AudioRendererHost::DeleteEntry, this, entry)); |
| 385 entry->pending_close = true; | 447 entry->pending_close = true; |
| 386 } | 448 } |
| 387 } | 449 } |
| 388 | 450 |
| 389 void AudioRendererHost::DeleteEntry(AudioEntry* entry) { | 451 void AudioRendererHost::DeleteEntry(AudioEntry* entry) { |
| 390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 391 | 453 |
| 392 // Delete the entry when this method goes out of scope. | 454 // Delete the entry when this method goes out of scope. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 435 return NULL; | 497 return NULL; |
| 436 } | 498 } |
| 437 | 499 |
| 438 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting( | 500 media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting( |
| 439 int stream_id) { | 501 int stream_id) { |
| 440 AudioEntry* const entry = LookupById(stream_id); | 502 AudioEntry* const entry = LookupById(stream_id); |
| 441 return entry ? entry->controller : NULL; | 503 return entry ? entry->controller : NULL; |
| 442 } | 504 } |
| 443 | 505 |
| 444 } // namespace content | 506 } // namespace content |
| OLD | NEW |