| 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 18 matching lines...) Expand all Loading... |
| 29 namespace content { | 29 namespace content { |
| 30 | 30 |
| 31 class AudioRendererHost::AudioEntry | 31 class AudioRendererHost::AudioEntry |
| 32 : public media::AudioOutputController::EventHandler { | 32 : public media::AudioOutputController::EventHandler { |
| 33 public: | 33 public: |
| 34 AudioEntry(AudioRendererHost* host, | 34 AudioEntry(AudioRendererHost* host, |
| 35 int stream_id, | 35 int stream_id, |
| 36 int render_view_id, | 36 int render_view_id, |
| 37 const media::AudioParameters& params, | 37 const media::AudioParameters& params, |
| 38 const std::string& output_device_id, | 38 const std::string& output_device_id, |
| 39 const std::string& input_device_id, | |
| 40 scoped_ptr<base::SharedMemory> shared_memory, | 39 scoped_ptr<base::SharedMemory> shared_memory, |
| 41 scoped_ptr<media::AudioOutputController::SyncReader> reader); | 40 scoped_ptr<media::AudioOutputController::SyncReader> reader); |
| 42 virtual ~AudioEntry(); | 41 virtual ~AudioEntry(); |
| 43 | 42 |
| 44 int stream_id() const { | 43 int stream_id() const { |
| 45 return stream_id_; | 44 return stream_id_; |
| 46 } | 45 } |
| 47 | 46 |
| 48 int render_view_id() const { | 47 int render_view_id() const { |
| 49 return render_view_id_; | 48 return render_view_id_; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 const scoped_ptr<base::SharedMemory> shared_memory_; | 81 const scoped_ptr<base::SharedMemory> shared_memory_; |
| 83 | 82 |
| 84 // The synchronous reader to be used by the controller. | 83 // The synchronous reader to be used by the controller. |
| 85 const scoped_ptr<media::AudioOutputController::SyncReader> reader_; | 84 const scoped_ptr<media::AudioOutputController::SyncReader> reader_; |
| 86 }; | 85 }; |
| 87 | 86 |
| 88 AudioRendererHost::AudioEntry::AudioEntry( | 87 AudioRendererHost::AudioEntry::AudioEntry( |
| 89 AudioRendererHost* host, int stream_id, int render_view_id, | 88 AudioRendererHost* host, int stream_id, int render_view_id, |
| 90 const media::AudioParameters& params, | 89 const media::AudioParameters& params, |
| 91 const std::string& output_device_id, | 90 const std::string& output_device_id, |
| 92 const std::string& input_device_id, | |
| 93 scoped_ptr<base::SharedMemory> shared_memory, | 91 scoped_ptr<base::SharedMemory> shared_memory, |
| 94 scoped_ptr<media::AudioOutputController::SyncReader> reader) | 92 scoped_ptr<media::AudioOutputController::SyncReader> reader) |
| 95 : host_(host), | 93 : host_(host), |
| 96 stream_id_(stream_id), | 94 stream_id_(stream_id), |
| 97 render_view_id_(render_view_id), | 95 render_view_id_(render_view_id), |
| 98 controller_(media::AudioOutputController::Create( | 96 controller_(media::AudioOutputController::Create( |
| 99 host->audio_manager_, this, params, output_device_id, | 97 host->audio_manager_, this, params, output_device_id, reader.get())), |
| 100 input_device_id, reader.get())), | |
| 101 shared_memory_(shared_memory.Pass()), | 98 shared_memory_(shared_memory.Pass()), |
| 102 reader_(reader.Pass()) { | 99 reader_(reader.Pass()) { |
| 103 DCHECK(controller_.get()); | 100 DCHECK(controller_.get()); |
| 104 } | 101 } |
| 105 | 102 |
| 106 AudioRendererHost::AudioEntry::~AudioEntry() {} | 103 AudioRendererHost::AudioEntry::~AudioEntry() {} |
| 107 | 104 |
| 108 /////////////////////////////////////////////////////////////////////////////// | 105 /////////////////////////////////////////////////////////////////////////////// |
| 109 // AudioRendererHost implementations. | 106 // AudioRendererHost implementations. |
| 110 | 107 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 const media::AudioParameters& params) { | 304 const media::AudioParameters& params) { |
| 308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 305 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 309 | 306 |
| 310 DVLOG(1) << "AudioRendererHost@" << this | 307 DVLOG(1) << "AudioRendererHost@" << this |
| 311 << "::OnCreateStream(stream_id=" << stream_id | 308 << "::OnCreateStream(stream_id=" << stream_id |
| 312 << ", render_view_id=" << render_view_id | 309 << ", render_view_id=" << render_view_id |
| 313 << ", session_id=" << session_id << ")"; | 310 << ", session_id=" << session_id << ")"; |
| 314 DCHECK_GT(render_view_id, 0); | 311 DCHECK_GT(render_view_id, 0); |
| 315 | 312 |
| 316 // media::AudioParameters is validated in the deserializer. | 313 // media::AudioParameters is validated in the deserializer. |
| 317 int input_channels = params.input_channels(); | 314 if (LookupById(stream_id) != NULL) { |
| 318 if (input_channels < 0 || | |
| 319 input_channels > media::limits::kMaxChannels || | |
| 320 LookupById(stream_id) != NULL) { | |
| 321 SendErrorMessage(stream_id); | 315 SendErrorMessage(stream_id); |
| 322 return; | 316 return; |
| 323 } | 317 } |
| 324 | 318 |
| 325 // When the |input_channels| is valid, clients are trying to create a unified | |
| 326 // IO stream which opens an input device mapping to the |session_id|. | |
| 327 // Initialize the |output_device_id| to an empty string which indicates that | 319 // Initialize the |output_device_id| to an empty string which indicates that |
| 328 // the default device should be used. If a StreamDeviceInfo instance was found | 320 // the default device should be used. If a StreamDeviceInfo instance was found |
| 329 // though, then we use the matched output device. | 321 // though, then we use the matched output device. |
| 330 std::string input_device_id, output_device_id; | 322 std::string output_device_id; |
| 331 const StreamDeviceInfo* info = media_stream_manager_-> | 323 const StreamDeviceInfo* info = media_stream_manager_-> |
| 332 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); | 324 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); |
| 333 if (info) | 325 if (info) |
| 334 output_device_id = info->device.matched_output_device_id; | 326 output_device_id = info->device.matched_output_device_id; |
| 335 | 327 |
| 336 if (input_channels > 0) { | |
| 337 if (!info) { | |
| 338 SendErrorMessage(stream_id); | |
| 339 DLOG(WARNING) << "No permission has been granted to input stream with " | |
| 340 << "session_id=" << session_id; | |
| 341 return; | |
| 342 } | |
| 343 | |
| 344 input_device_id = info->device.id; | |
| 345 } | |
| 346 | |
| 347 // Calculate output and input memory size. | |
| 348 int output_memory_size = AudioBus::CalculateMemorySize(params); | |
| 349 int frames = params.frames_per_buffer(); | |
| 350 int input_memory_size = AudioBus::CalculateMemorySize(input_channels, frames); | |
| 351 | |
| 352 // Create the shared memory and share with the renderer process. | 328 // Create the shared memory and share with the renderer process. |
| 353 // For synchronized I/O (if input_channels > 0) then we allocate | 329 // For synchronized I/O (if input_channels > 0) then we allocate |
| 354 // extra memory after the output data for the input data. | 330 // extra memory after the output data for the input data. |
| 355 uint32 shared_memory_size = output_memory_size + input_memory_size; | 331 uint32 shared_memory_size = AudioBus::CalculateMemorySize(params);; |
| 356 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); | 332 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); |
| 357 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) { | 333 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) { |
| 358 SendErrorMessage(stream_id); | 334 SendErrorMessage(stream_id); |
| 359 return; | 335 return; |
| 360 } | 336 } |
| 361 | 337 |
| 362 scoped_ptr<AudioSyncReader> reader( | 338 scoped_ptr<AudioSyncReader> reader( |
| 363 new AudioSyncReader(shared_memory.get(), params, input_channels)); | 339 new AudioSyncReader(shared_memory.get(), params)); |
| 364 if (!reader->Init()) { | 340 if (!reader->Init()) { |
| 365 SendErrorMessage(stream_id); | 341 SendErrorMessage(stream_id); |
| 366 return; | 342 return; |
| 367 } | 343 } |
| 368 | 344 |
| 369 MediaObserver* const media_observer = | 345 MediaObserver* const media_observer = |
| 370 GetContentClient()->browser()->GetMediaObserver(); | 346 GetContentClient()->browser()->GetMediaObserver(); |
| 371 if (media_observer) | 347 if (media_observer) |
| 372 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); | 348 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); |
| 373 | 349 |
| 374 scoped_ptr<AudioEntry> entry(new AudioEntry( | 350 scoped_ptr<AudioEntry> entry(new AudioEntry( |
| 375 this, stream_id, render_view_id, params, output_device_id, | 351 this, stream_id, render_view_id, params, output_device_id, |
| 376 input_device_id, shared_memory.Pass(), | 352 shared_memory.Pass(), |
| 377 reader.PassAs<media::AudioOutputController::SyncReader>())); | 353 reader.PassAs<media::AudioOutputController::SyncReader>())); |
| 378 if (mirroring_manager_) { | 354 if (mirroring_manager_) { |
| 379 mirroring_manager_->AddDiverter( | 355 mirroring_manager_->AddDiverter( |
| 380 render_process_id_, entry->render_view_id(), entry->controller()); | 356 render_process_id_, entry->render_view_id(), entry->controller()); |
| 381 } | 357 } |
| 382 audio_entries_.insert(std::make_pair(stream_id, entry.release())); | 358 audio_entries_.insert(std::make_pair(stream_id, entry.release())); |
| 383 audio_log_->OnCreated(stream_id, params, input_device_id, output_device_id); | 359 audio_log_->OnCreated(stream_id, params, output_device_id); |
| 384 } | 360 } |
| 385 | 361 |
| 386 void AudioRendererHost::OnPlayStream(int stream_id) { | 362 void AudioRendererHost::OnPlayStream(int stream_id) { |
| 387 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 388 | 364 |
| 389 AudioEntry* entry = LookupById(stream_id); | 365 AudioEntry* entry = LookupById(stream_id); |
| 390 if (!entry) { | 366 if (!entry) { |
| 391 SendErrorMessage(stream_id); | 367 SendErrorMessage(stream_id); |
| 392 return; | 368 return; |
| 393 } | 369 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 } | 456 } |
| 481 | 457 |
| 482 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { | 458 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { |
| 483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 459 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 484 | 460 |
| 485 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); | 461 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); |
| 486 return i != audio_entries_.end() ? i->second : NULL; | 462 return i != audio_entries_.end() ? i->second : NULL; |
| 487 } | 463 } |
| 488 | 464 |
| 489 } // namespace content | 465 } // namespace content |
| OLD | NEW |