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

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

Issue 2689483006: Switch browser side audio capture path to use base time primitives. (Closed)
Patch Set: Bloop Created 3 years, 10 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
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_sync_writer.h" 5 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 std::string log_string = base::StringPrintf( 112 std::string log_string = base::StringPrintf(
113 "AISW: number of detected audio glitches: %" PRIuS " out of %" PRIuS, 113 "AISW: number of detected audio glitches: %" PRIuS " out of %" PRIuS,
114 write_error_count_, write_count_); 114 write_error_count_, write_count_);
115 MediaStreamManager::SendMessageToNativeLog(log_string); 115 MediaStreamManager::SendMessageToNativeLog(log_string);
116 DVLOG(1) << log_string; 116 DVLOG(1) << log_string;
117 } 117 }
118 118
119 void AudioInputSyncWriter::Write(const AudioBus* data, 119 void AudioInputSyncWriter::Write(const AudioBus* data,
120 double volume, 120 double volume,
121 bool key_pressed, 121 bool key_pressed,
122 uint32_t hardware_delay_bytes) { 122 base::TimeDelta delay,
123 base::TimeTicks delay_timestamp) {
123 TRACE_EVENT0("audio", "AudioInputSyncWriter::Write"); 124 TRACE_EVENT0("audio", "AudioInputSyncWriter::Write");
124 ++write_count_; 125 ++write_count_;
125 CheckTimeSinceLastWrite(); 126 CheckTimeSinceLastWrite();
126 127
127 // Check that the renderer side has read data so that we don't overwrite data 128 // Check that the renderer side has read data so that we don't overwrite data
128 // that hasn't been read yet. The renderer side sends a signal over the socket 129 // that hasn't been read yet. The renderer side sends a signal over the socket
129 // each time it has read data. Here, we read those verifications before 130 // each time it has read data. Here, we read those verifications before
130 // writing. We verify that each buffer index is in sequence. 131 // writing. We verify that each buffer index is in sequence.
131 size_t number_of_indices_available = socket_->Peek() / sizeof(uint32_t); 132 size_t number_of_indices_available = socket_->Peek() / sizeof(uint32_t);
132 if (number_of_indices_available > 0) { 133 if (number_of_indices_available > 0) {
(...skipping 10 matching lines...) Expand all
143 CHECK_GE(number_of_filled_segments_, 0); 144 CHECK_GE(number_of_filled_segments_, 0);
144 } 145 }
145 } 146 }
146 147
147 bool write_error = !WriteDataFromFifoToSharedMemory(); 148 bool write_error = !WriteDataFromFifoToSharedMemory();
148 149
149 // Write the current data to the shared memory if there is room, otherwise 150 // Write the current data to the shared memory if there is room, otherwise
150 // put it in the fifo. 151 // put it in the fifo.
151 if (number_of_filled_segments_ < 152 if (number_of_filled_segments_ <
152 static_cast<int>(shared_memory_segment_count_)) { 153 static_cast<int>(shared_memory_segment_count_)) {
153 WriteParametersToCurrentSegment(volume, key_pressed, hardware_delay_bytes); 154 WriteParametersToCurrentSegment(volume, key_pressed, delay,
155 delay_timestamp);
154 156
155 // Copy data into shared memory using pre-allocated audio buses. 157 // Copy data into shared memory using pre-allocated audio buses.
156 AudioBus* audio_bus = audio_buses_[current_segment_id_]; 158 AudioBus* audio_bus = audio_buses_[current_segment_id_];
157 data->CopyTo(audio_bus); 159 data->CopyTo(audio_bus);
158 160
159 if (!SignalDataWrittenAndUpdateCounters()) 161 if (!SignalDataWrittenAndUpdateCounters())
160 write_error = true; 162 write_error = true;
161 163
162 trailing_write_to_fifo_count_ = 0; 164 trailing_write_to_fifo_count_ = 0;
163 } else { 165 } else {
164 if (!PushDataToFifo(data, volume, key_pressed, hardware_delay_bytes)) 166 if (!PushDataToFifo(data, volume, key_pressed, delay, delay_timestamp))
165 write_error = true; 167 write_error = true;
166 168
167 ++write_to_fifo_count_; 169 ++write_to_fifo_count_;
168 ++trailing_write_to_fifo_count_; 170 ++trailing_write_to_fifo_count_;
169 } 171 }
170 172
171 // Increase write error counts if error, or reset the trailing error counter 173 // Increase write error counts if error, or reset the trailing error counter
172 // if all write operations went well (no data dropped). 174 // if all write operations went well (no data dropped).
173 if (write_error) { 175 if (write_error) {
174 ++write_error_count_; 176 ++write_error_count_;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 #endif 226 #endif
225 } 227 }
226 228
227 void AudioInputSyncWriter::AddToNativeLog(const std::string& message) { 229 void AudioInputSyncWriter::AddToNativeLog(const std::string& message) {
228 MediaStreamManager::SendMessageToNativeLog(message); 230 MediaStreamManager::SendMessageToNativeLog(message);
229 } 231 }
230 232
231 bool AudioInputSyncWriter::PushDataToFifo(const AudioBus* data, 233 bool AudioInputSyncWriter::PushDataToFifo(const AudioBus* data,
232 double volume, 234 double volume,
233 bool key_pressed, 235 bool key_pressed,
234 uint32_t hardware_delay_bytes) { 236 base::TimeDelta delay,
237 base::TimeTicks delay_timestamp) {
235 if (overflow_buses_.size() == kMaxOverflowBusesSize) { 238 if (overflow_buses_.size() == kMaxOverflowBusesSize) {
236 // We use |write_error_count_| for capping number of log messages. 239 // We use |write_error_count_| for capping number of log messages.
237 // |write_error_count_| also includes socket Send() errors, but those should 240 // |write_error_count_| also includes socket Send() errors, but those should
238 // be rare. 241 // be rare.
239 if (write_error_count_ <= 50) { 242 if (write_error_count_ <= 50) {
240 const std::string error_message = "AISW: No room in fifo."; 243 const std::string error_message = "AISW: No room in fifo.";
241 LOG(WARNING) << error_message; 244 LOG(WARNING) << error_message;
242 AddToNativeLog(error_message); 245 AddToNativeLog(error_message);
243 if (write_error_count_ == 50) { 246 if (write_error_count_ == 50) {
244 const std::string error_message = 247 const std::string error_message =
245 "AISW: Log cap reached, suppressing further fifo overflow logs."; 248 "AISW: Log cap reached, suppressing further fifo overflow logs.";
246 LOG(WARNING) << error_message; 249 LOG(WARNING) << error_message;
247 AddToNativeLog(error_message); 250 AddToNativeLog(error_message);
248 } 251 }
249 } 252 }
250 return false; 253 return false;
251 } 254 }
252 255
253 if (overflow_buses_.empty()) { 256 if (overflow_buses_.empty()) {
254 const std::string message = "AISW: Starting to use fifo."; 257 const std::string message = "AISW: Starting to use fifo.";
255 DVLOG(1) << message; 258 DVLOG(1) << message;
256 AddToNativeLog(message); 259 AddToNativeLog(message);
257 } 260 }
258 261
259 // Push parameters to fifo. 262 // Push parameters to fifo.
260 OverflowParams params = { volume, hardware_delay_bytes, key_pressed }; 263 OverflowParams params = {volume, delay, delay_timestamp, key_pressed};
261 overflow_params_.push_back(params); 264 overflow_params_.push_back(params);
262 265
263 // Push audio data to fifo. 266 // Push audio data to fifo.
264 std::unique_ptr<AudioBus> audio_bus = 267 std::unique_ptr<AudioBus> audio_bus =
265 AudioBus::Create(data->channels(), data->frames()); 268 AudioBus::Create(data->channels(), data->frames());
266 data->CopyTo(audio_bus.get()); 269 data->CopyTo(audio_bus.get());
267 overflow_buses_.push_back(std::move(audio_bus)); 270 overflow_buses_.push_back(std::move(audio_bus));
268 271
269 DCHECK_LE(overflow_buses_.size(), static_cast<size_t>(kMaxOverflowBusesSize)); 272 DCHECK_LE(overflow_buses_.size(), static_cast<size_t>(kMaxOverflowBusesSize));
270 DCHECK_EQ(overflow_params_.size(), overflow_buses_.size()); 273 DCHECK_EQ(overflow_params_.size(), overflow_buses_.size());
271 274
272 return true; 275 return true;
273 } 276 }
274 277
275 bool AudioInputSyncWriter::WriteDataFromFifoToSharedMemory() { 278 bool AudioInputSyncWriter::WriteDataFromFifoToSharedMemory() {
276 if (overflow_buses_.empty()) 279 if (overflow_buses_.empty())
277 return true; 280 return true;
278 281
279 const int segment_count = static_cast<int>(shared_memory_segment_count_); 282 const int segment_count = static_cast<int>(shared_memory_segment_count_);
280 bool write_error = false; 283 bool write_error = false;
281 auto params_it = overflow_params_.begin(); 284 auto params_it = overflow_params_.begin();
282 auto audio_bus_it = overflow_buses_.begin(); 285 auto audio_bus_it = overflow_buses_.begin();
283 DCHECK_EQ(overflow_params_.size(), overflow_buses_.size()); 286 DCHECK_EQ(overflow_params_.size(), overflow_buses_.size());
284 287
285 while (audio_bus_it != overflow_buses_.end() && 288 while (audio_bus_it != overflow_buses_.end() &&
286 number_of_filled_segments_ < segment_count) { 289 number_of_filled_segments_ < segment_count) {
287 // Write parameters to shared memory. 290 // Write parameters to shared memory.
288 WriteParametersToCurrentSegment((*params_it).volume, 291 WriteParametersToCurrentSegment(
289 (*params_it).key_pressed, 292 (*params_it).volume, (*params_it).key_pressed, (*params_it).delay,
290 (*params_it).hardware_delay_bytes); 293 (*params_it).delay_timestamp);
291 294
292 // Copy data from the fifo into shared memory using pre-allocated audio 295 // Copy data from the fifo into shared memory using pre-allocated audio
293 // buses. 296 // buses.
294 (*audio_bus_it)->CopyTo(audio_buses_[current_segment_id_]); 297 (*audio_bus_it)->CopyTo(audio_buses_[current_segment_id_]);
295 298
296 if (!SignalDataWrittenAndUpdateCounters()) 299 if (!SignalDataWrittenAndUpdateCounters())
297 write_error = true; 300 write_error = true;
298 301
299 ++params_it; 302 ++params_it;
300 ++audio_bus_it; 303 ++audio_bus_it;
301 } 304 }
302 305
303 // Erase all copied data from fifo. 306 // Erase all copied data from fifo.
304 overflow_params_.erase(overflow_params_.begin(), params_it); 307 overflow_params_.erase(overflow_params_.begin(), params_it);
305 overflow_buses_.erase(overflow_buses_.begin(), audio_bus_it); 308 overflow_buses_.erase(overflow_buses_.begin(), audio_bus_it);
306 309
307 if (overflow_buses_.empty()) { 310 if (overflow_buses_.empty()) {
308 const std::string message = "AISW: Fifo emptied."; 311 const std::string message = "AISW: Fifo emptied.";
309 DVLOG(1) << message; 312 DVLOG(1) << message;
310 AddToNativeLog(message); 313 AddToNativeLog(message);
311 } 314 }
312 315
313 DCHECK_EQ(overflow_params_.size(), overflow_buses_.size()); 316 DCHECK_EQ(overflow_params_.size(), overflow_buses_.size());
314 return !write_error; 317 return !write_error;
315 } 318 }
316 319
317 void AudioInputSyncWriter::WriteParametersToCurrentSegment( 320 void AudioInputSyncWriter::WriteParametersToCurrentSegment(
318 double volume, 321 double volume,
319 bool key_pressed, 322 bool key_pressed,
320 uint32_t hardware_delay_bytes) { 323 base::TimeDelta delay,
324 base::TimeTicks delay_timestamp) {
321 uint8_t* ptr = shared_memory_; 325 uint8_t* ptr = shared_memory_;
322 ptr += current_segment_id_ * shared_memory_segment_size_; 326 ptr += current_segment_id_ * shared_memory_segment_size_;
323 AudioInputBuffer* buffer = reinterpret_cast<AudioInputBuffer*>(ptr); 327 AudioInputBuffer* buffer = reinterpret_cast<AudioInputBuffer*>(ptr);
324 buffer->params.volume = volume; 328 buffer->params.volume = volume;
325 buffer->params.size = audio_bus_memory_size_; 329 buffer->params.size = audio_bus_memory_size_;
326 buffer->params.key_pressed = key_pressed; 330 buffer->params.key_pressed = key_pressed;
327 buffer->params.hardware_delay_bytes = hardware_delay_bytes; 331 buffer->params.delay = delay.InMicroseconds();
332 buffer->params.delay_timestamp =
333 (delay_timestamp - base::TimeTicks()).InMicroseconds();
328 buffer->params.id = next_buffer_id_; 334 buffer->params.id = next_buffer_id_;
329 } 335 }
330 336
331 bool AudioInputSyncWriter::SignalDataWrittenAndUpdateCounters() { 337 bool AudioInputSyncWriter::SignalDataWrittenAndUpdateCounters() {
332 if (socket_->Send(&current_segment_id_, sizeof(current_segment_id_)) != 338 if (socket_->Send(&current_segment_id_, sizeof(current_segment_id_)) !=
333 sizeof(current_segment_id_)) { 339 sizeof(current_segment_id_)) {
334 const std::string error_message = "AISW: No room in socket buffer."; 340 const std::string error_message = "AISW: No room in socket buffer.";
335 LOG(WARNING) << error_message; 341 LOG(WARNING) << error_message;
336 AddToNativeLog(error_message); 342 AddToNativeLog(error_message);
337 TRACE_EVENT_INSTANT0("audio", 343 TRACE_EVENT_INSTANT0("audio",
338 "AudioInputSyncWriter: No room in socket buffer", 344 "AudioInputSyncWriter: No room in socket buffer",
339 TRACE_EVENT_SCOPE_THREAD); 345 TRACE_EVENT_SCOPE_THREAD);
340 return false; 346 return false;
341 } 347 }
342 348
343 if (++current_segment_id_ >= shared_memory_segment_count_) 349 if (++current_segment_id_ >= shared_memory_segment_count_)
344 current_segment_id_ = 0; 350 current_segment_id_ = 0;
345 ++number_of_filled_segments_; 351 ++number_of_filled_segments_;
346 CHECK_LE(number_of_filled_segments_, 352 CHECK_LE(number_of_filled_segments_,
347 static_cast<int>(shared_memory_segment_count_)); 353 static_cast<int>(shared_memory_segment_count_));
348 ++next_buffer_id_; 354 ++next_buffer_id_;
349 355
350 return true; 356 return true;
351 } 357 }
352 358
353 } // namespace content 359 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698