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/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/renderer_host/media/audio_input_device_manager.h" | 11 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
12 #include "content/browser/renderer_host/media/audio_input_sync_writer.h" | 12 #include "content/browser/renderer_host/media/audio_input_sync_writer.h" |
13 #include "content/browser/renderer_host/media/media_stream_manager.h" | 13 #include "content/browser/renderer_host/media/media_stream_manager.h" |
14 #include "content/browser/renderer_host/media/web_contents_audio_input_stream.h" | 14 #include "content/browser/renderer_host/media/web_contents_audio_input_stream.h" |
15 #include "content/browser/renderer_host/media/web_contents_capture_util.h" | 15 #include "content/browser/renderer_host/media/web_contents_capture_util.h" |
16 #include "content/common/media/audio_messages.h" | 16 #include "content/common/media/audio_messages.h" |
17 | 17 |
18 namespace content { | 18 namespace content { |
19 | 19 |
20 struct AudioInputRendererHost::AudioEntry { | 20 struct AudioInputRendererHost::AudioEntry { |
21 AudioEntry(); | 21 AudioEntry(); |
22 ~AudioEntry(); | 22 ~AudioEntry(); |
23 | 23 |
24 // The AudioInputController that manages the audio input stream. | 24 // The AudioInputController that manages the audio input stream. |
25 scoped_refptr<media::AudioInputController> controller; | 25 scoped_refptr<media::AudioInputController> controller; |
26 | 26 |
27 // The audio input stream ID in the render view. | 27 // The audio input stream ID in the render view. |
28 int stream_id; | 28 int stream_id; |
29 | 29 |
30 // Shared memory for transmission of the audio data. | 30 // Shared memory for transmission of the audio data. It has |
| 31 // |shared_memory_segment_count| equal lengthed segments. |
31 base::SharedMemory shared_memory; | 32 base::SharedMemory shared_memory; |
| 33 int shared_memory_segment_count; |
32 | 34 |
33 // The synchronous writer to be used by the controller. We have the | 35 // The synchronous writer to be used by the controller. We have the |
34 // ownership of the writer. | 36 // ownership of the writer. |
35 scoped_ptr<media::AudioInputController::SyncWriter> writer; | 37 scoped_ptr<media::AudioInputController::SyncWriter> writer; |
36 | 38 |
37 // Set to true after we called Close() for the controller. | 39 // Set to true after we called Close() for the controller. |
38 bool pending_close; | 40 bool pending_close; |
39 }; | 41 }; |
40 | 42 |
41 AudioInputRendererHost::AudioEntry::AudioEntry() | 43 AudioInputRendererHost::AudioEntry::AudioEntry() |
42 : stream_id(0), | 44 : stream_id(0), |
| 45 shared_memory_segment_count(0), |
43 pending_close(false) { | 46 pending_close(false) { |
44 } | 47 } |
45 | 48 |
46 AudioInputRendererHost::AudioEntry::~AudioEntry() {} | 49 AudioInputRendererHost::AudioEntry::~AudioEntry() {} |
47 | 50 |
48 AudioInputRendererHost::AudioInputRendererHost( | 51 AudioInputRendererHost::AudioInputRendererHost( |
49 media::AudioManager* audio_manager, | 52 media::AudioManager* audio_manager, |
50 MediaStreamManager* media_stream_manager) | 53 MediaStreamManager* media_stream_manager) |
51 : audio_manager_(audio_manager), | 54 : audio_manager_(audio_manager), |
52 media_stream_manager_(media_stream_manager) { | 55 media_stream_manager_(media_stream_manager) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 // If we failed to prepare the sync socket for the renderer then we fail | 151 // If we failed to prepare the sync socket for the renderer then we fail |
149 // the construction of audio input stream. | 152 // the construction of audio input stream. |
150 if (!writer->PrepareForeignSocketHandle(peer_handle(), | 153 if (!writer->PrepareForeignSocketHandle(peer_handle(), |
151 &foreign_socket_handle)) { | 154 &foreign_socket_handle)) { |
152 DeleteEntryOnError(entry); | 155 DeleteEntryOnError(entry); |
153 return; | 156 return; |
154 } | 157 } |
155 | 158 |
156 Send(new AudioInputMsg_NotifyStreamCreated(entry->stream_id, | 159 Send(new AudioInputMsg_NotifyStreamCreated(entry->stream_id, |
157 foreign_memory_handle, foreign_socket_handle, | 160 foreign_memory_handle, foreign_socket_handle, |
158 entry->shared_memory.created_size())); | 161 entry->shared_memory.created_size(), |
| 162 entry->shared_memory_segment_count)); |
159 } | 163 } |
160 | 164 |
161 void AudioInputRendererHost::DoSendRecordingMessage( | 165 void AudioInputRendererHost::DoSendRecordingMessage( |
162 media::AudioInputController* controller) { | 166 media::AudioInputController* controller) { |
163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
164 // TODO(henrika): See crbug.com/115262 for details on why this method | 168 // TODO(henrika): See crbug.com/115262 for details on why this method |
165 // should be implemented. | 169 // should be implemented. |
166 } | 170 } |
167 | 171 |
168 void AudioInputRendererHost::DoHandleError( | 172 void AudioInputRendererHost::DoHandleError( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 | 206 |
203 // Add the session entry to the map. | 207 // Add the session entry to the map. |
204 session_entries_[session_id] = stream_id; | 208 session_entries_[session_id] = stream_id; |
205 | 209 |
206 // Start the device with the session_id. If the device is started | 210 // Start the device with the session_id. If the device is started |
207 // successfully, OnDeviceStarted() callback will be triggered. | 211 // successfully, OnDeviceStarted() callback will be triggered. |
208 media_stream_manager_->audio_input_device_manager()->Start(session_id, this); | 212 media_stream_manager_->audio_input_device_manager()->Start(session_id, this); |
209 } | 213 } |
210 | 214 |
211 void AudioInputRendererHost::OnCreateStream( | 215 void AudioInputRendererHost::OnCreateStream( |
212 int stream_id, const media::AudioParameters& params, | 216 int stream_id, |
213 const std::string& device_id, bool automatic_gain_control) { | 217 const media::AudioParameters& params, |
| 218 const std::string& device_id, |
| 219 bool automatic_gain_control, |
| 220 int shared_memory_count) { |
214 VLOG(1) << "AudioInputRendererHost::OnCreateStream(stream_id=" | 221 VLOG(1) << "AudioInputRendererHost::OnCreateStream(stream_id=" |
215 << stream_id << ")"; | 222 << stream_id << ")"; |
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
217 // media::AudioParameters is validated in the deserializer. | 224 // media::AudioParameters is validated in the deserializer. |
218 if (LookupById(stream_id) != NULL) { | 225 if (LookupById(stream_id) != NULL) { |
219 SendErrorMessage(stream_id); | 226 SendErrorMessage(stream_id); |
220 return; | 227 return; |
221 } | 228 } |
222 | 229 |
223 media::AudioParameters audio_params(params); | 230 media::AudioParameters audio_params(params); |
224 | 231 |
225 if (media_stream_manager_->audio_input_device_manager()-> | 232 if (media_stream_manager_->audio_input_device_manager()-> |
226 ShouldUseFakeDevice()) { | 233 ShouldUseFakeDevice()) { |
227 audio_params.Reset(media::AudioParameters::AUDIO_FAKE, | 234 audio_params.Reset(media::AudioParameters::AUDIO_FAKE, |
228 params.channel_layout(), 0, params.sample_rate(), | 235 params.channel_layout(), 0, params.sample_rate(), |
229 params.bits_per_sample(), params.frames_per_buffer()); | 236 params.bits_per_sample(), params.frames_per_buffer()); |
230 } | 237 } |
231 | 238 |
232 uint32 buffer_size = audio_params.GetBytesPerBuffer(); | 239 uint32 buffer_size = audio_params.GetBytesPerBuffer(); |
233 | 240 |
234 // Create a new AudioEntry structure. | 241 // Create a new AudioEntry structure. |
235 scoped_ptr<AudioEntry> entry(new AudioEntry()); | 242 scoped_ptr<AudioEntry> entry(new AudioEntry()); |
236 | 243 |
237 uint32 mem_size = sizeof(media::AudioInputBufferParameters) + buffer_size; | 244 uint32 segment_size = |
| 245 sizeof(media::AudioInputBufferParameters) + buffer_size; |
| 246 entry->shared_memory_segment_count = shared_memory_count; |
238 | 247 |
239 // Create the shared memory and share it with the renderer process | 248 // Create the shared memory and share it with the renderer process |
240 // using a new SyncWriter object. | 249 // using a new SyncWriter object. |
241 if (!entry->shared_memory.CreateAndMapAnonymous(mem_size)) { | 250 if (!entry->shared_memory.CreateAndMapAnonymous( |
| 251 segment_size * entry->shared_memory_segment_count)) { |
242 // If creation of shared memory failed then send an error message. | 252 // If creation of shared memory failed then send an error message. |
243 SendErrorMessage(stream_id); | 253 SendErrorMessage(stream_id); |
244 return; | 254 return; |
245 } | 255 } |
246 | 256 |
247 scoped_ptr<AudioInputSyncWriter> writer( | 257 scoped_ptr<AudioInputSyncWriter> writer( |
248 new AudioInputSyncWriter(&entry->shared_memory)); | 258 new AudioInputSyncWriter(&entry->shared_memory, |
| 259 entry->shared_memory_segment_count)); |
249 | 260 |
250 if (!writer->Init()) { | 261 if (!writer->Init()) { |
251 SendErrorMessage(stream_id); | 262 SendErrorMessage(stream_id); |
252 return; | 263 return; |
253 } | 264 } |
254 | 265 |
255 // If we have successfully created the SyncWriter then assign it to the | 266 // If we have successfully created the SyncWriter then assign it to the |
256 // entry and construct an AudioInputController. | 267 // entry and construct an AudioInputController. |
257 entry->writer.reset(writer.release()); | 268 entry->writer.reset(writer.release()); |
258 if (WebContentsCaptureUtil::IsWebContentsDeviceId(device_id)) { | 269 if (WebContentsCaptureUtil::IsWebContentsDeviceId(device_id)) { |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 for (SessionEntryMap::iterator it = session_entries_.begin(); | 467 for (SessionEntryMap::iterator it = session_entries_.begin(); |
457 it != session_entries_.end(); ++it) { | 468 it != session_entries_.end(); ++it) { |
458 if (stream_id == it->second) { | 469 if (stream_id == it->second) { |
459 return it->first; | 470 return it->first; |
460 } | 471 } |
461 } | 472 } |
462 return 0; | 473 return 0; |
463 } | 474 } |
464 | 475 |
465 } // namespace content | 476 } // namespace content |
OLD | NEW |