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 buffers for transmission of the audio data. |
31 base::SharedMemory shared_memory; | 31 AudioInputSyncWriter::SharedMemoryVector shared_memory; |
32 | 32 |
33 // The synchronous writer to be used by the controller. We have the | 33 // The synchronous writer to be used by the controller. We have the |
34 // ownership of the writer. | 34 // ownership of the writer. |
35 scoped_ptr<media::AudioInputController::SyncWriter> writer; | 35 scoped_ptr<media::AudioInputController::SyncWriter> writer; |
36 | 36 |
37 // Set to true after we called Close() for the controller. | 37 // Set to true after we called Close() for the controller. |
38 bool pending_close; | 38 bool pending_close; |
39 }; | 39 }; |
40 | 40 |
41 AudioInputRendererHost::AudioEntry::AudioEntry() | 41 AudioInputRendererHost::AudioEntry::AudioEntry() |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 } | 120 } |
121 | 121 |
122 if (!entry->controller->LowLatencyMode()) { | 122 if (!entry->controller->LowLatencyMode()) { |
123 NOTREACHED() << "Only low-latency mode is supported."; | 123 NOTREACHED() << "Only low-latency mode is supported."; |
124 DeleteEntryOnError(entry); | 124 DeleteEntryOnError(entry); |
125 return; | 125 return; |
126 } | 126 } |
127 | 127 |
128 // Once the audio stream is created then complete the creation process by | 128 // Once the audio stream is created then complete the creation process by |
129 // mapping shared memory and sharing with the renderer process. | 129 // mapping shared memory and sharing with the renderer process. |
130 base::SharedMemoryHandle foreign_memory_handle; | |
131 if (!entry->shared_memory.ShareToProcess(peer_handle(), | |
132 &foreign_memory_handle)) { | |
133 // If we failed to map and share the shared memory then close the audio | |
134 // stream and send an error message. | |
135 DeleteEntryOnError(entry); | |
136 return; | |
137 } | |
138 | |
139 AudioInputSyncWriter* writer = | 130 AudioInputSyncWriter* writer = |
140 static_cast<AudioInputSyncWriter*>(entry->writer.get()); | 131 static_cast<AudioInputSyncWriter*>(entry->writer.get()); |
141 | 132 |
142 #if defined(OS_WIN) | 133 #if defined(OS_WIN) |
143 base::SyncSocket::Handle foreign_socket_handle; | 134 base::SyncSocket::Handle foreign_socket_handle; |
144 #else | 135 #else |
145 base::FileDescriptor foreign_socket_handle; | 136 base::FileDescriptor foreign_socket_handle; |
146 #endif | 137 #endif |
147 | 138 |
148 // If we failed to prepare the sync socket for the renderer then we fail | 139 // If we failed to prepare the sync socket for the renderer then we fail |
149 // the construction of audio input stream. | 140 // the construction of audio input stream. |
150 if (!writer->PrepareForeignSocketHandle(peer_handle(), | 141 if (!writer->PrepareForeignSocketHandle(peer_handle(), |
151 &foreign_socket_handle)) { | 142 &foreign_socket_handle)) { |
152 DeleteEntryOnError(entry); | 143 DeleteEntryOnError(entry); |
153 return; | 144 return; |
154 } | 145 } |
| 146 Send(new AudioInputMsg_NotifyStreamCreated(entry->stream_id, |
| 147 foreign_socket_handle, |
| 148 entry->shared_memory.size())); |
155 | 149 |
156 Send(new AudioInputMsg_NotifyStreamCreated(entry->stream_id, | 150 for (size_t i = 0; i < entry->shared_memory.size(); ++i) { |
157 foreign_memory_handle, foreign_socket_handle, | 151 base::SharedMemoryHandle foreign_memory_handle; |
158 entry->shared_memory.created_size())); | 152 if (!entry->shared_memory[i]->ShareToProcess(peer_handle(), |
| 153 &foreign_memory_handle)) { |
| 154 // If we failed to map and share the shared memory then close the audio |
| 155 // stream and send an error message. |
| 156 DeleteEntryOnError(entry); |
| 157 return; |
| 158 } |
| 159 Send(new AudioInputMsg_NotifySharedMemoryCreated(entry->stream_id, |
| 160 foreign_memory_handle, |
| 161 entry->shared_memory[i]->created_size(), i)); |
| 162 } |
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 mem_size = sizeof(media::AudioInputBufferParameters) + buffer_size; |
238 | 245 |
239 // Create the shared memory and share it with the renderer process | 246 // Create the shared memory and share it with the renderer process |
240 // using a new SyncWriter object. | 247 // using a new SyncWriter object. |
241 if (!entry->shared_memory.CreateAndMapAnonymous(mem_size)) { | 248 entry->shared_memory.resize(shared_memory_count); |
242 // If creation of shared memory failed then send an error message. | 249 for (size_t i = 0; i < entry->shared_memory.size(); ++i) { |
243 SendErrorMessage(stream_id); | 250 entry->shared_memory[i] = new base::SharedMemory(); |
244 return; | 251 if (!entry->shared_memory[i]->CreateAndMapAnonymous(mem_size)) { |
| 252 // If creation of shared memory failed then send an error message. |
| 253 SendErrorMessage(stream_id); |
| 254 return; |
| 255 } |
245 } | 256 } |
246 | 257 |
247 scoped_ptr<AudioInputSyncWriter> writer( | 258 scoped_ptr<AudioInputSyncWriter> writer( |
248 new AudioInputSyncWriter(&entry->shared_memory)); | 259 new AudioInputSyncWriter(&entry->shared_memory)); |
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 |
(...skipping 201 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 |