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_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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 media::AudioInputController* controller) { | 175 media::AudioInputController* controller) { |
| 176 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 176 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 177 // TODO(henrika): See crbug.com/115262 for details on why this method | 177 // TODO(henrika): See crbug.com/115262 for details on why this method |
| 178 // should be implemented. | 178 // should be implemented. |
| 179 } | 179 } |
| 180 | 180 |
| 181 void AudioInputRendererHost::DoHandleError( | 181 void AudioInputRendererHost::DoHandleError( |
| 182 media::AudioInputController* controller, | 182 media::AudioInputController* controller, |
| 183 media::AudioInputController::ErrorCode error_code) { | 183 media::AudioInputController::ErrorCode error_code) { |
| 184 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 184 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 185 // Log all errors even it is ignored later. | |
| 185 MediaStreamManager::SendMessageToNativeLog( | 186 MediaStreamManager::SendMessageToNativeLog( |
| 186 base::StringPrintf("AudioInputController error: %d", error_code)); | 187 base::StringPrintf("AudioInputController error: %d", error_code)); |
| 187 | 188 |
| 189 // This is a fix for crbug.com/357501. The error can be triggered when closing | |
| 190 // the lid on Macs, which causes more problems than it fixes. | |
| 191 // Also, in crbug.com/357569, the goal is to remove usage of the error since | |
| 192 // it was added to solve a crash on Windows that no longer can be reproduced. | |
| 193 if (error_code == media::AudioInputController::NO_DATA_ERROR) { | |
| 194 DVLOG(1) << "AudioInputRendererHost@" << this << "::DoHandleError: " | |
| 195 << "NO_DATA_ERROR ignored."; | |
| 196 return; | |
| 197 } | |
| 198 | |
| 188 AudioEntry* entry = LookupByController(controller); | 199 AudioEntry* entry = LookupByController(controller); |
| 189 if (!entry) | 200 if (!entry) |
| 190 return; | 201 return; |
| 191 | 202 |
| 192 audio_log_->OnError(entry->stream_id); | 203 audio_log_->OnError(entry->stream_id); |
| 193 DeleteEntryOnError(entry, AUDIO_INPUT_CONTROLLER_ERROR); | 204 DeleteEntryOnError(entry, AUDIO_INPUT_CONTROLLER_ERROR); |
| 194 } | 205 } |
| 195 | 206 |
| 196 bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message, | 207 bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message, |
| 197 bool* message_was_ok) { | 208 bool* message_was_ok) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 if (media_stream_manager_->audio_input_device_manager()-> | 241 if (media_stream_manager_->audio_input_device_manager()-> |
| 231 ShouldUseFakeDevice()) { | 242 ShouldUseFakeDevice()) { |
| 232 audio_params.Reset( | 243 audio_params.Reset( |
| 233 media::AudioParameters::AUDIO_FAKE, | 244 media::AudioParameters::AUDIO_FAKE, |
| 234 config.params.channel_layout(), config.params.channels(), 0, | 245 config.params.channel_layout(), config.params.channels(), 0, |
| 235 config.params.sample_rate(), config.params.bits_per_sample(), | 246 config.params.sample_rate(), config.params.bits_per_sample(), |
| 236 config.params.frames_per_buffer()); | 247 config.params.frames_per_buffer()); |
| 237 } | 248 } |
| 238 | 249 |
| 239 // Check if we have the permission to open the device and which device to use. | 250 // Check if we have the permission to open the device and which device to use. |
| 240 std::string device_id = media::AudioManagerBase::kDefaultDeviceId; | 251 media::AudioDeviceName device_name( |
| 252 media::AudioManagerBase::kDefaultDeviceName, | |
| 253 media::AudioManagerBase::kDefaultDeviceId); | |
| 241 if (audio_params.format() != media::AudioParameters::AUDIO_FAKE) { | 254 if (audio_params.format() != media::AudioParameters::AUDIO_FAKE) { |
| 242 const StreamDeviceInfo* info = media_stream_manager_-> | 255 const StreamDeviceInfo* info = media_stream_manager_-> |
| 243 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); | 256 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); |
| 244 if (!info) { | 257 if (!info) { |
| 245 SendErrorMessage(stream_id, PERMISSION_DENIED); | 258 SendErrorMessage(stream_id, PERMISSION_DENIED); |
| 246 DLOG(WARNING) << "No permission has been granted to input stream with " | 259 DLOG(WARNING) << "No permission has been granted to input stream with " |
| 247 << "session_id=" << session_id; | 260 << "session_id=" << session_id; |
| 248 return; | 261 return; |
| 249 } | 262 } |
| 250 | 263 |
| 251 device_id = info->device.id; | 264 device_name.unique_id = info->device.id; |
|
tommi (sloooow) - chröme
2014/04/10 20:04:30
ah, I thought that |device| was of type AudioDevic
| |
| 265 device_name.device_name = info->device.name; | |
| 252 } | 266 } |
| 253 | 267 |
| 254 // Create a new AudioEntry structure. | 268 // Create a new AudioEntry structure. |
| 255 scoped_ptr<AudioEntry> entry(new AudioEntry()); | 269 scoped_ptr<AudioEntry> entry(new AudioEntry()); |
| 256 | 270 |
| 257 const uint32 segment_size = (sizeof(media::AudioInputBufferParameters) + | 271 const uint32 segment_size = (sizeof(media::AudioInputBufferParameters) + |
| 258 audio_params.GetBytesPerBuffer()); | 272 audio_params.GetBytesPerBuffer()); |
| 259 entry->shared_memory_segment_count = config.shared_memory_count; | 273 entry->shared_memory_segment_count = config.shared_memory_count; |
| 260 | 274 |
| 261 // Create the shared memory and share it with the renderer process | 275 // Create the shared memory and share it with the renderer process |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 274 entry->shared_memory_segment_count)); | 288 entry->shared_memory_segment_count)); |
| 275 | 289 |
| 276 if (!writer->Init()) { | 290 if (!writer->Init()) { |
| 277 SendErrorMessage(stream_id, SYNC_WRITER_INIT_FAILED); | 291 SendErrorMessage(stream_id, SYNC_WRITER_INIT_FAILED); |
| 278 return; | 292 return; |
| 279 } | 293 } |
| 280 | 294 |
| 281 // If we have successfully created the SyncWriter then assign it to the | 295 // If we have successfully created the SyncWriter then assign it to the |
| 282 // entry and construct an AudioInputController. | 296 // entry and construct an AudioInputController. |
| 283 entry->writer.reset(writer.release()); | 297 entry->writer.reset(writer.release()); |
| 284 if (WebContentsCaptureUtil::IsWebContentsDeviceId(device_id)) { | 298 if (WebContentsCaptureUtil::IsWebContentsDeviceId(device_name.unique_id)) { |
| 285 entry->controller = media::AudioInputController::CreateForStream( | 299 entry->controller = media::AudioInputController::CreateForStream( |
| 286 audio_manager_->GetTaskRunner(), | 300 audio_manager_->GetTaskRunner(), |
| 287 this, | 301 this, |
| 288 WebContentsAudioInputStream::Create( | 302 WebContentsAudioInputStream::Create( |
| 289 device_id, | 303 device_name.unique_id, |
| 290 audio_params, | 304 audio_params, |
| 291 audio_manager_->GetWorkerTaskRunner(), | 305 audio_manager_->GetWorkerTaskRunner(), |
| 292 audio_mirroring_manager_), | 306 audio_mirroring_manager_), |
| 293 entry->writer.get(), | 307 entry->writer.get(), |
| 294 user_input_monitor_); | 308 user_input_monitor_); |
| 295 } else { | 309 } else { |
| 296 // TODO(henrika): replace CreateLowLatency() with Create() as soon | 310 // TODO(henrika): replace CreateLowLatency() with Create() as soon |
| 297 // as satish has ensured that Speech Input also uses the default low- | 311 // as satish has ensured that Speech Input also uses the default low- |
| 298 // latency path. See crbug.com/112472 for details. | 312 // latency path. See crbug.com/112472 for details. |
| 299 entry->controller = | 313 entry->controller = |
| 300 media::AudioInputController::CreateLowLatency(audio_manager_, | 314 media::AudioInputController::CreateLowLatency(audio_manager_, |
| 301 this, | 315 this, |
| 302 audio_params, | 316 audio_params, |
| 303 device_id, | 317 device_name.unique_id, |
| 304 entry->writer.get(), | 318 entry->writer.get(), |
| 305 user_input_monitor_); | 319 user_input_monitor_); |
| 306 } | 320 } |
| 307 | 321 |
| 308 if (!entry->controller.get()) { | 322 if (!entry->controller.get()) { |
| 309 SendErrorMessage(stream_id, STREAM_CREATE_ERROR); | 323 SendErrorMessage(stream_id, STREAM_CREATE_ERROR); |
| 310 return; | 324 return; |
| 311 } | 325 } |
| 312 | 326 |
| 313 // Set the initial AGC state for the audio input stream. Note that, the AGC | 327 // Set the initial AGC state for the audio input stream. Note that, the AGC |
| 314 // is only supported in AUDIO_PCM_LOW_LATENCY mode. | 328 // is only supported in AUDIO_PCM_LOW_LATENCY mode. |
| 315 if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY) | 329 if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY) |
| 316 entry->controller->SetAutomaticGainControl(config.automatic_gain_control); | 330 entry->controller->SetAutomaticGainControl(config.automatic_gain_control); |
| 317 | 331 |
| 318 // Since the controller was created successfully, create an entry and add it | 332 // Since the controller was created successfully, create an entry and add it |
| 319 // to the map. | 333 // to the map. |
| 320 entry->stream_id = stream_id; | 334 entry->stream_id = stream_id; |
| 321 audio_entries_.insert(std::make_pair(stream_id, entry.release())); | 335 audio_entries_.insert(std::make_pair(stream_id, entry.release())); |
| 322 | 336 |
| 323 MediaStreamManager::SendMessageToNativeLog( | 337 MediaStreamManager::SendMessageToNativeLog( |
| 324 "Audio input stream created successfully."); | 338 "Audio input stream created successfully. Device name: " + |
| 325 audio_log_->OnCreated(stream_id, audio_params, device_id); | 339 device_name.device_name); |
| 340 audio_log_->OnCreated(stream_id, audio_params, device_name.unique_id); | |
| 326 } | 341 } |
| 327 | 342 |
| 328 void AudioInputRendererHost::OnRecordStream(int stream_id) { | 343 void AudioInputRendererHost::OnRecordStream(int stream_id) { |
| 329 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 344 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 330 | 345 |
| 331 AudioEntry* entry = LookupById(stream_id); | 346 AudioEntry* entry = LookupById(stream_id); |
| 332 if (!entry) { | 347 if (!entry) { |
| 333 SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY); | 348 SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY); |
| 334 return; | 349 return; |
| 335 } | 350 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 // TODO(hclam): Implement a faster look up method. | 441 // TODO(hclam): Implement a faster look up method. |
| 427 for (AudioEntryMap::iterator i = audio_entries_.begin(); | 442 for (AudioEntryMap::iterator i = audio_entries_.begin(); |
| 428 i != audio_entries_.end(); ++i) { | 443 i != audio_entries_.end(); ++i) { |
| 429 if (controller == i->second->controller.get()) | 444 if (controller == i->second->controller.get()) |
| 430 return i->second; | 445 return i->second; |
| 431 } | 446 } |
| 432 return NULL; | 447 return NULL; |
| 433 } | 448 } |
| 434 | 449 |
| 435 } // namespace content | 450 } // namespace content |
| OLD | NEW |