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 |