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

Side by Side Diff: webrtc/modules/audio_device/audio_device_buffer.cc

Issue 2324113002: Avoids crash at device switch on iOS (Closed)
Patch Set: Feedback from grunell@ Created 4 years, 3 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
« no previous file with comments | « webrtc/modules/audio_device/audio_device_buffer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 rec_callbacks_(0), 54 rec_callbacks_(0),
55 last_rec_callbacks_(0), 55 last_rec_callbacks_(0),
56 play_callbacks_(0), 56 play_callbacks_(0),
57 last_play_callbacks_(0), 57 last_play_callbacks_(0),
58 rec_samples_(0), 58 rec_samples_(0),
59 last_rec_samples_(0), 59 last_rec_samples_(0),
60 play_samples_(0), 60 play_samples_(0),
61 last_play_samples_(0), 61 last_play_samples_(0),
62 last_log_stat_time_(0) { 62 last_log_stat_time_(0) {
63 LOG(INFO) << "AudioDeviceBuffer::ctor"; 63 LOG(INFO) << "AudioDeviceBuffer::ctor";
64 // TODO(henrika): improve buffer handling and ensure that we don't allocate
65 // more than what is required.
66 play_buffer_.reset(new int8_t[kMaxBufferSizeBytes]);
67 rec_buffer_.reset(new int8_t[kMaxBufferSizeBytes]);
64 } 68 }
65 69
66 AudioDeviceBuffer::~AudioDeviceBuffer() { 70 AudioDeviceBuffer::~AudioDeviceBuffer() {
67 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 71 RTC_DCHECK(thread_checker_.CalledOnValidThread());
68 LOG(INFO) << "AudioDeviceBuffer::~dtor"; 72 LOG(INFO) << "AudioDeviceBuffer::~dtor";
69 73
70 size_t total_diff_time = 0; 74 size_t total_diff_time = 0;
71 int num_measurements = 0; 75 int num_measurements = 0;
72 LOG(INFO) << "[playout diff time => #measurements]"; 76 LOG(INFO) << "[playout diff time => #measurements]";
73 for (size_t diff = 0; diff < arraysize(playout_diff_times_); ++diff) { 77 for (size_t diff = 0; diff < arraysize(playout_diff_times_); ++diff) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 return 0; 232 return 0;
229 } 233 }
230 234
231 int32_t AudioDeviceBuffer::StopOutputFileRecording() { 235 int32_t AudioDeviceBuffer::StopOutputFileRecording() {
232 LOG(LS_WARNING) << "Not implemented"; 236 LOG(LS_WARNING) << "Not implemented";
233 return 0; 237 return 0;
234 } 238 }
235 239
236 int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer, 240 int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer,
237 size_t num_samples) { 241 size_t num_samples) {
238 AllocateRecordingBufferIfNeeded(); 242 UpdateRecordingParameters();
239 RTC_CHECK(rec_buffer_);
240 // WebRTC can only receive audio in 10ms chunks, hence we fail if the native 243 // WebRTC can only receive audio in 10ms chunks, hence we fail if the native
241 // audio layer tries to deliver something else. 244 // audio layer tries to deliver something else.
242 RTC_CHECK_EQ(num_samples, rec_samples_per_10ms_); 245 RTC_CHECK_EQ(num_samples, rec_samples_per_10ms_);
243 246
244 rtc::CritScope lock(&_critSect); 247 rtc::CritScope lock(&_critSect);
245 248
246 if (rec_channel_ == AudioDeviceModule::kChannelBoth) { 249 if (rec_channel_ == AudioDeviceModule::kChannelBoth) {
247 // Copy the complete input buffer to the local buffer. 250 // Copy the complete input buffer to the local buffer.
248 memcpy(&rec_buffer_[0], audio_buffer, rec_bytes_per_10ms_); 251 memcpy(&rec_buffer_[0], audio_buffer, rec_bytes_per_10ms_);
249 } else { 252 } else {
(...skipping 12 matching lines...) Expand all
262 } 265 }
263 266
264 // Update some stats but do it on the task queue to ensure that the members 267 // Update some stats but do it on the task queue to ensure that the members
265 // are modified and read on the same thread. 268 // are modified and read on the same thread.
266 task_queue_.PostTask( 269 task_queue_.PostTask(
267 rtc::Bind(&AudioDeviceBuffer::UpdateRecStats, this, num_samples)); 270 rtc::Bind(&AudioDeviceBuffer::UpdateRecStats, this, num_samples));
268 return 0; 271 return 0;
269 } 272 }
270 273
271 int32_t AudioDeviceBuffer::DeliverRecordedData() { 274 int32_t AudioDeviceBuffer::DeliverRecordedData() {
272 RTC_CHECK(rec_buffer_);
273 RTC_DCHECK(audio_transport_cb_); 275 RTC_DCHECK(audio_transport_cb_);
274 rtc::CritScope lock(&_critSectCb); 276 rtc::CritScope lock(&_critSectCb);
275 277
276 if (!audio_transport_cb_) { 278 if (!audio_transport_cb_) {
277 LOG(LS_WARNING) << "Invalid audio transport"; 279 LOG(LS_WARNING) << "Invalid audio transport";
278 return 0; 280 return 0;
279 } 281 }
280 282
281 int32_t res(0); 283 int32_t res(0);
282 uint32_t newMicLevel(0); 284 uint32_t newMicLevel(0);
(...skipping 16 matching lines...) Expand all
299 // position/index corresponds to time differences (in milliseconds) between 301 // position/index corresponds to time differences (in milliseconds) between
300 // two successive playout callbacks, and the stored value is the number of 302 // two successive playout callbacks, and the stored value is the number of
301 // times a given time difference was found. 303 // times a given time difference was found.
302 int64_t now_time = rtc::TimeMillis(); 304 int64_t now_time = rtc::TimeMillis();
303 size_t diff_time = rtc::TimeDiff(now_time, last_playout_time_); 305 size_t diff_time = rtc::TimeDiff(now_time, last_playout_time_);
304 // Truncate at 500ms to limit the size of the array. 306 // Truncate at 500ms to limit the size of the array.
305 diff_time = std::min(kMaxDeltaTimeInMs, diff_time); 307 diff_time = std::min(kMaxDeltaTimeInMs, diff_time);
306 last_playout_time_ = now_time; 308 last_playout_time_ = now_time;
307 playout_diff_times_[diff_time]++; 309 playout_diff_times_[diff_time]++;
308 310
309 AllocatePlayoutBufferIfNeeded(); 311 UpdatePlayoutParameters();
310 RTC_CHECK(play_buffer_);
311 // WebRTC can only provide audio in 10ms chunks, hence we fail if the native 312 // WebRTC can only provide audio in 10ms chunks, hence we fail if the native
312 // audio layer asks for something else. 313 // audio layer asks for something else.
313 RTC_CHECK_EQ(num_samples, play_samples_per_10ms_); 314 RTC_CHECK_EQ(num_samples, play_samples_per_10ms_);
314 315
315 rtc::CritScope lock(&_critSectCb); 316 rtc::CritScope lock(&_critSectCb);
316 317
317 // It is currently supported to start playout without a valid audio 318 // It is currently supported to start playout without a valid audio
318 // transport object. Leads to warning and silence. 319 // transport object. Leads to warning and silence.
319 if (!audio_transport_cb_) { 320 if (!audio_transport_cb_) {
320 LOG(LS_WARNING) << "Invalid audio transport"; 321 LOG(LS_WARNING) << "Invalid audio transport";
(...skipping 18 matching lines...) Expand all
339 rtc::Bind(&AudioDeviceBuffer::UpdatePlayStats, this, num_samples_out)); 340 rtc::Bind(&AudioDeviceBuffer::UpdatePlayStats, this, num_samples_out));
340 return static_cast<int32_t>(num_samples_out); 341 return static_cast<int32_t>(num_samples_out);
341 } 342 }
342 343
343 int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) { 344 int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) {
344 rtc::CritScope lock(&_critSect); 345 rtc::CritScope lock(&_critSect);
345 memcpy(audio_buffer, &play_buffer_[0], play_bytes_per_10ms_); 346 memcpy(audio_buffer, &play_buffer_[0], play_bytes_per_10ms_);
346 return static_cast<int32_t>(play_samples_per_10ms_); 347 return static_cast<int32_t>(play_samples_per_10ms_);
347 } 348 }
348 349
349 void AudioDeviceBuffer::AllocatePlayoutBufferIfNeeded() { 350 void AudioDeviceBuffer::UpdatePlayoutParameters() {
350 RTC_CHECK(play_bytes_per_sample_); 351 RTC_CHECK(play_bytes_per_sample_);
351 if (play_buffer_)
352 return;
353 LOG(INFO) << __FUNCTION__;
354 rtc::CritScope lock(&_critSect); 352 rtc::CritScope lock(&_critSect);
355 // Derive the required buffer size given sample rate and number of channels. 353 // Update the required buffer size given sample rate and number of channels.
356 play_samples_per_10ms_ = static_cast<size_t>(play_sample_rate_ * 10 / 1000); 354 play_samples_per_10ms_ = static_cast<size_t>(play_sample_rate_ * 10 / 1000);
357 play_bytes_per_10ms_ = play_bytes_per_sample_ * play_samples_per_10ms_; 355 play_bytes_per_10ms_ = play_bytes_per_sample_ * play_samples_per_10ms_;
358 LOG(INFO) << "playout samples per 10ms: " << play_samples_per_10ms_; 356 RTC_DCHECK_LE(play_bytes_per_10ms_, kMaxBufferSizeBytes);
Henrik Grunell WebRTC 2016/09/09 10:19:29 Nit: I think it should even be a CHECK (not DCHECK
359 LOG(INFO) << "playout bytes per 10ms: " << play_bytes_per_10ms_;
360 // Allocate memory for the playout audio buffer. It will always contain audio
361 // samples corresponding to 10ms of audio to be played out.
362 play_buffer_.reset(new int8_t[play_bytes_per_10ms_]);
363 } 357 }
364 358
365 void AudioDeviceBuffer::AllocateRecordingBufferIfNeeded() { 359 void AudioDeviceBuffer::UpdateRecordingParameters() {
366 RTC_CHECK(rec_bytes_per_sample_); 360 RTC_CHECK(rec_bytes_per_sample_);
367 if (rec_buffer_)
368 return;
369 LOG(INFO) << __FUNCTION__;
370 rtc::CritScope lock(&_critSect); 361 rtc::CritScope lock(&_critSect);
371 // Derive the required buffer size given sample rate and number of channels. 362 // Update the required buffer size given sample rate and number of channels.
372 rec_samples_per_10ms_ = static_cast<size_t>(rec_sample_rate_ * 10 / 1000); 363 rec_samples_per_10ms_ = static_cast<size_t>(rec_sample_rate_ * 10 / 1000);
373 rec_bytes_per_10ms_ = rec_bytes_per_sample_ * rec_samples_per_10ms_; 364 rec_bytes_per_10ms_ = rec_bytes_per_sample_ * rec_samples_per_10ms_;
374 LOG(INFO) << "recorded samples per 10ms: " << rec_samples_per_10ms_; 365 RTC_DCHECK_LE(rec_bytes_per_10ms_, kMaxBufferSizeBytes);
375 LOG(INFO) << "recorded bytes per 10ms: " << rec_bytes_per_10ms_;
376 // Allocate memory for the recording audio buffer. It will always contain
377 // audio samples corresponding to 10ms of audio.
378 rec_buffer_.reset(new int8_t[rec_bytes_per_10ms_]);
379 } 366 }
380 367
381 void AudioDeviceBuffer::StartTimer() { 368 void AudioDeviceBuffer::StartTimer() {
382 last_log_stat_time_ = rtc::TimeMillis(); 369 last_log_stat_time_ = rtc::TimeMillis();
383 task_queue_.PostDelayedTask(rtc::Bind(&AudioDeviceBuffer::LogStats, this), 370 task_queue_.PostDelayedTask(rtc::Bind(&AudioDeviceBuffer::LogStats, this),
384 kTimerIntervalInMilliseconds); 371 kTimerIntervalInMilliseconds);
385 } 372 }
386 373
387 void AudioDeviceBuffer::LogStats() { 374 void AudioDeviceBuffer::LogStats() {
388 RTC_DCHECK(task_queue_.IsCurrent()); 375 RTC_DCHECK(task_queue_.IsCurrent());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 rec_samples_ += num_samples; 422 rec_samples_ += num_samples;
436 } 423 }
437 424
438 void AudioDeviceBuffer::UpdatePlayStats(size_t num_samples) { 425 void AudioDeviceBuffer::UpdatePlayStats(size_t num_samples) {
439 RTC_DCHECK(task_queue_.IsCurrent()); 426 RTC_DCHECK(task_queue_.IsCurrent());
440 ++play_callbacks_; 427 ++play_callbacks_;
441 play_samples_ += num_samples; 428 play_samples_ += num_samples;
442 } 429 }
443 430
444 } // namespace webrtc 431 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_device/audio_device_buffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698