Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |