Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Side by Side Diff: content/browser/renderer_host/media/audio_input_renderer_host.cc

Issue 12379071: Use multiple shared memory buffers cyclically for audio capture. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: rebase Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698