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_input_renderer_host.h" | 5 #include "content/browser/renderer_host/media/audio_input_renderer_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/shared_memory.h" | 8 #include "base/memory/shared_memory.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/numerics/safe_math.h" | 10 #include "base/numerics/safe_math.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 // |shared_memory_segment_count| equal lengthed segments. | 49 // |shared_memory_segment_count| equal lengthed segments. |
50 base::SharedMemory shared_memory; | 50 base::SharedMemory shared_memory; |
51 int shared_memory_segment_count; | 51 int shared_memory_segment_count; |
52 | 52 |
53 // The synchronous writer to be used by the controller. We have the | 53 // The synchronous writer to be used by the controller. We have the |
54 // ownership of the writer. | 54 // ownership of the writer. |
55 scoped_ptr<media::AudioInputController::SyncWriter> writer; | 55 scoped_ptr<media::AudioInputController::SyncWriter> writer; |
56 | 56 |
57 // Set to true after we called Close() for the controller. | 57 // Set to true after we called Close() for the controller. |
58 bool pending_close; | 58 bool pending_close; |
59 | |
60 // If this entry's layout has a keyboard mic channel. | |
61 bool has_keyboard_mic_; | |
59 }; | 62 }; |
60 | 63 |
61 AudioInputRendererHost::AudioEntry::AudioEntry() | 64 AudioInputRendererHost::AudioEntry::AudioEntry() |
62 : stream_id(0), | 65 : stream_id(0), |
63 shared_memory_segment_count(0), | 66 shared_memory_segment_count(0), |
64 pending_close(false) { | 67 pending_close(false), |
68 has_keyboard_mic_(false) { | |
65 } | 69 } |
66 | 70 |
67 AudioInputRendererHost::AudioEntry::~AudioEntry() {} | 71 AudioInputRendererHost::AudioEntry::~AudioEntry() {} |
68 | 72 |
69 AudioInputRendererHost::AudioInputRendererHost( | 73 AudioInputRendererHost::AudioInputRendererHost( |
70 media::AudioManager* audio_manager, | 74 media::AudioManager* audio_manager, |
71 MediaStreamManager* media_stream_manager, | 75 MediaStreamManager* media_stream_manager, |
72 AudioMirroringManager* audio_mirroring_manager, | 76 AudioMirroringManager* audio_mirroring_manager, |
73 media::UserInputMonitor* user_input_monitor) | 77 media::UserInputMonitor* user_input_monitor) |
74 : BrowserMessageFilter(AudioMsgStart), | 78 : BrowserMessageFilter(AudioMsgStart), |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 return handled; | 270 return handled; |
267 } | 271 } |
268 | 272 |
269 void AudioInputRendererHost::OnCreateStream( | 273 void AudioInputRendererHost::OnCreateStream( |
270 int stream_id, | 274 int stream_id, |
271 int render_view_id, | 275 int render_view_id, |
272 int session_id, | 276 int session_id, |
273 const AudioInputHostMsg_CreateStream_Config& config) { | 277 const AudioInputHostMsg_CreateStream_Config& config) { |
274 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 278 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
275 | 279 |
280 #if defined(OS_CHROMEOS) | |
281 if (config.params.channel_layout() == | |
282 media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) { | |
283 media_stream_manager_->audio_input_device_manager() | |
284 ->RegisterKeyboardMicStream( | |
285 base::Bind(&AudioInputRendererHost::DoCreateStream, | |
286 this, | |
287 stream_id, | |
288 render_view_id, | |
289 session_id, | |
290 config)); | |
291 } else { | |
292 DoCreateStream(stream_id, render_view_id, session_id, config); | |
tommi (sloooow) - chröme
2014/09/23 13:47:36
fix indent
Henrik Grunell
2014/09/23 15:00:20
Done.
| |
293 } | |
294 #else | |
295 DoCreateStream(stream_id, render_view_id, session_id, config); | |
296 #endif | |
297 } | |
298 | |
299 void AudioInputRendererHost::DoCreateStream( | |
300 int stream_id, | |
301 int render_view_id, | |
302 int session_id, | |
303 const AudioInputHostMsg_CreateStream_Config& config) { | |
304 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
305 | |
276 std::ostringstream oss; | 306 std::ostringstream oss; |
277 oss << "[stream_id=" << stream_id << "] " | 307 oss << "[stream_id=" << stream_id << "] " |
278 << "AIRH::OnCreateStream(render_view_id=" << render_view_id | 308 << "AIRH::OnCreateStream(render_view_id=" << render_view_id |
279 << ", session_id=" << session_id << ")"; | 309 << ", session_id=" << session_id << ")"; |
280 DCHECK_GT(render_view_id, 0); | 310 DCHECK_GT(render_view_id, 0); |
281 | 311 |
282 // media::AudioParameters is validated in the deserializer. | 312 // media::AudioParameters is validated in the deserializer. |
283 if (LookupById(stream_id) != NULL) { | 313 if (LookupById(stream_id) != NULL) { |
284 SendErrorMessage(stream_id, STREAM_ALREADY_EXISTS); | 314 SendErrorMessage(stream_id, STREAM_ALREADY_EXISTS); |
315 MaybeUnregisterKeyboardMicStream(config); | |
285 return; | 316 return; |
286 } | 317 } |
287 | 318 |
288 media::AudioParameters audio_params(config.params); | 319 media::AudioParameters audio_params(config.params); |
289 if (media_stream_manager_->audio_input_device_manager()-> | 320 if (media_stream_manager_->audio_input_device_manager()-> |
290 ShouldUseFakeDevice()) { | 321 ShouldUseFakeDevice()) { |
291 audio_params.Reset( | 322 audio_params.Reset( |
292 media::AudioParameters::AUDIO_FAKE, | 323 media::AudioParameters::AUDIO_FAKE, |
293 config.params.channel_layout(), config.params.channels(), | 324 config.params.channel_layout(), config.params.channels(), |
294 config.params.sample_rate(), config.params.bits_per_sample(), | 325 config.params.sample_rate(), config.params.bits_per_sample(), |
295 config.params.frames_per_buffer()); | 326 config.params.frames_per_buffer()); |
296 } | 327 } |
297 | 328 |
298 // Check if we have the permission to open the device and which device to use. | 329 // Check if we have the permission to open the device and which device to use. |
299 std::string device_name; | 330 std::string device_name; |
300 std::string device_id = media::AudioManagerBase::kDefaultDeviceId; | 331 std::string device_id = media::AudioManagerBase::kDefaultDeviceId; |
301 if (audio_params.format() != media::AudioParameters::AUDIO_FAKE) { | 332 if (audio_params.format() != media::AudioParameters::AUDIO_FAKE) { |
302 const StreamDeviceInfo* info = media_stream_manager_-> | 333 const StreamDeviceInfo* info = media_stream_manager_-> |
303 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); | 334 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); |
304 if (!info) { | 335 if (!info) { |
305 SendErrorMessage(stream_id, PERMISSION_DENIED); | 336 SendErrorMessage(stream_id, PERMISSION_DENIED); |
306 DLOG(WARNING) << "No permission has been granted to input stream with " | 337 DLOG(WARNING) << "No permission has been granted to input stream with " |
307 << "session_id=" << session_id; | 338 << "session_id=" << session_id; |
339 MaybeUnregisterKeyboardMicStream(config); | |
308 return; | 340 return; |
309 } | 341 } |
310 | 342 |
311 device_id = info->device.id; | 343 device_id = info->device.id; |
312 device_name = info->device.name; | 344 device_name = info->device.name; |
313 oss << ": device_name=" << device_name; | 345 oss << ": device_name=" << device_name; |
314 } | 346 } |
315 | 347 |
316 // Create a new AudioEntry structure. | 348 // Create a new AudioEntry structure. |
317 scoped_ptr<AudioEntry> entry(new AudioEntry()); | 349 scoped_ptr<AudioEntry> entry(new AudioEntry()); |
318 | 350 |
319 const uint32 segment_size = | 351 const uint32 segment_size = |
320 (sizeof(media::AudioInputBufferParameters) + | 352 (sizeof(media::AudioInputBufferParameters) + |
321 media::AudioBus::CalculateMemorySize(audio_params)); | 353 media::AudioBus::CalculateMemorySize(audio_params)); |
322 entry->shared_memory_segment_count = config.shared_memory_count; | 354 entry->shared_memory_segment_count = config.shared_memory_count; |
323 | 355 |
324 // Create the shared memory and share it with the renderer process | 356 // Create the shared memory and share it with the renderer process |
325 // using a new SyncWriter object. | 357 // using a new SyncWriter object. |
326 base::CheckedNumeric<uint32> size = segment_size; | 358 base::CheckedNumeric<uint32> size = segment_size; |
327 size *= entry->shared_memory_segment_count; | 359 size *= entry->shared_memory_segment_count; |
328 if (!size.IsValid() || | 360 if (!size.IsValid() || |
329 !entry->shared_memory.CreateAndMapAnonymous(size.ValueOrDie())) { | 361 !entry->shared_memory.CreateAndMapAnonymous(size.ValueOrDie())) { |
330 // If creation of shared memory failed then send an error message. | 362 // If creation of shared memory failed then send an error message. |
331 SendErrorMessage(stream_id, SHARED_MEMORY_CREATE_FAILED); | 363 SendErrorMessage(stream_id, SHARED_MEMORY_CREATE_FAILED); |
364 MaybeUnregisterKeyboardMicStream(config); | |
332 return; | 365 return; |
333 } | 366 } |
334 | 367 |
335 scoped_ptr<AudioInputSyncWriter> writer(new AudioInputSyncWriter( | 368 scoped_ptr<AudioInputSyncWriter> writer(new AudioInputSyncWriter( |
336 &entry->shared_memory, entry->shared_memory_segment_count, audio_params)); | 369 &entry->shared_memory, entry->shared_memory_segment_count, audio_params)); |
337 | 370 |
338 if (!writer->Init()) { | 371 if (!writer->Init()) { |
339 SendErrorMessage(stream_id, SYNC_WRITER_INIT_FAILED); | 372 SendErrorMessage(stream_id, SYNC_WRITER_INIT_FAILED); |
373 MaybeUnregisterKeyboardMicStream(config); | |
340 return; | 374 return; |
341 } | 375 } |
342 | 376 |
343 // If we have successfully created the SyncWriter then assign it to the | 377 // If we have successfully created the SyncWriter then assign it to the |
344 // entry and construct an AudioInputController. | 378 // entry and construct an AudioInputController. |
345 entry->writer.reset(writer.release()); | 379 entry->writer.reset(writer.release()); |
346 if (WebContentsCaptureUtil::IsWebContentsDeviceId(device_id)) { | 380 if (WebContentsCaptureUtil::IsWebContentsDeviceId(device_id)) { |
347 entry->controller = media::AudioInputController::CreateForStream( | 381 entry->controller = media::AudioInputController::CreateForStream( |
348 audio_manager_->GetTaskRunner(), | 382 audio_manager_->GetTaskRunner(), |
349 this, | 383 this, |
(...skipping 12 matching lines...) Expand all Loading... | |
362 media::AudioInputController::CreateLowLatency(audio_manager_, | 396 media::AudioInputController::CreateLowLatency(audio_manager_, |
363 this, | 397 this, |
364 audio_params, | 398 audio_params, |
365 device_id, | 399 device_id, |
366 entry->writer.get(), | 400 entry->writer.get(), |
367 user_input_monitor_); | 401 user_input_monitor_); |
368 } | 402 } |
369 | 403 |
370 if (!entry->controller.get()) { | 404 if (!entry->controller.get()) { |
371 SendErrorMessage(stream_id, STREAM_CREATE_ERROR); | 405 SendErrorMessage(stream_id, STREAM_CREATE_ERROR); |
406 MaybeUnregisterKeyboardMicStream(config); | |
372 return; | 407 return; |
373 } | 408 } |
374 | 409 |
375 // Set the initial AGC state for the audio input stream. Note that, the AGC | 410 // Set the initial AGC state for the audio input stream. Note that, the AGC |
376 // is only supported in AUDIO_PCM_LOW_LATENCY mode. | 411 // is only supported in AUDIO_PCM_LOW_LATENCY mode. |
377 if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 412 if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
378 entry->controller->SetAutomaticGainControl(config.automatic_gain_control); | 413 entry->controller->SetAutomaticGainControl(config.automatic_gain_control); |
379 oss << ", AGC=" << config.automatic_gain_control; | 414 oss << ", AGC=" << config.automatic_gain_control; |
380 } | 415 } |
381 | 416 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 this, entry)); | 489 this, entry)); |
455 entry->pending_close = true; | 490 entry->pending_close = true; |
456 audio_log_->OnClosed(entry->stream_id); | 491 audio_log_->OnClosed(entry->stream_id); |
457 } | 492 } |
458 } | 493 } |
459 | 494 |
460 void AudioInputRendererHost::DeleteEntry(AudioEntry* entry) { | 495 void AudioInputRendererHost::DeleteEntry(AudioEntry* entry) { |
461 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 496 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
462 LogMessage(entry->stream_id, "DeleteEntry: stream is now closed", true); | 497 LogMessage(entry->stream_id, "DeleteEntry: stream is now closed", true); |
463 | 498 |
499 #if defined(OS_CHROMEOS) | |
500 if (entry->has_keyboard_mic_) { | |
501 media_stream_manager_->audio_input_device_manager() | |
502 ->UnregisterKeyboardMicStream(); | |
503 } | |
504 #endif | |
505 | |
464 // Delete the entry when this method goes out of scope. | 506 // Delete the entry when this method goes out of scope. |
465 scoped_ptr<AudioEntry> entry_deleter(entry); | 507 scoped_ptr<AudioEntry> entry_deleter(entry); |
466 | 508 |
467 // Erase the entry from the map. | 509 // Erase the entry from the map. |
468 audio_entries_.erase(entry->stream_id); | 510 audio_entries_.erase(entry->stream_id); |
469 } | 511 } |
470 | 512 |
471 void AudioInputRendererHost::DeleteEntryOnError(AudioEntry* entry, | 513 void AudioInputRendererHost::DeleteEntryOnError(AudioEntry* entry, |
472 ErrorCode error_code) { | 514 ErrorCode error_code) { |
473 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 515 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
(...skipping 21 matching lines...) Expand all Loading... | |
495 // Iterate the map of entries. | 537 // Iterate the map of entries. |
496 // TODO(hclam): Implement a faster look up method. | 538 // TODO(hclam): Implement a faster look up method. |
497 for (AudioEntryMap::iterator i = audio_entries_.begin(); | 539 for (AudioEntryMap::iterator i = audio_entries_.begin(); |
498 i != audio_entries_.end(); ++i) { | 540 i != audio_entries_.end(); ++i) { |
499 if (controller == i->second->controller.get()) | 541 if (controller == i->second->controller.get()) |
500 return i->second; | 542 return i->second; |
501 } | 543 } |
502 return NULL; | 544 return NULL; |
503 } | 545 } |
504 | 546 |
547 void AudioInputRendererHost::MaybeUnregisterKeyboardMicStream( | |
548 const AudioInputHostMsg_CreateStream_Config& config) { | |
549 #if defined(OS_CHROMEOS) | |
550 if (config.params.channel_layout() == | |
551 media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) { | |
tommi (sloooow) - chröme
2014/09/23 13:47:36
were there any plans to support mono+keyboard mic?
Henrik Grunell
2014/09/23 15:00:20
No.
| |
552 media_stream_manager_->audio_input_device_manager() | |
553 ->UnregisterKeyboardMicStream(); | |
554 } | |
555 #endif | |
556 } | |
557 | |
505 } // namespace content | 558 } // namespace content |
OLD | NEW |