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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 play_channels_(0), | 46 play_channels_(0), |
| 47 playing_(false), | 47 playing_(false), |
| 48 recording_(false), | 48 recording_(false), |
| 49 current_mic_level_(0), | 49 current_mic_level_(0), |
| 50 new_mic_level_(0), | 50 new_mic_level_(0), |
| 51 typing_status_(false), | 51 typing_status_(false), |
| 52 play_delay_ms_(0), | 52 play_delay_ms_(0), |
| 53 rec_delay_ms_(0), | 53 rec_delay_ms_(0), |
| 54 clock_drift_(0), | 54 clock_drift_(0), |
| 55 num_stat_reports_(0), | 55 num_stat_reports_(0), |
| 56 rec_callbacks_(0), | |
| 57 last_rec_callbacks_(0), | 56 last_rec_callbacks_(0), |
| 58 play_callbacks_(0), | |
| 59 last_play_callbacks_(0), | 57 last_play_callbacks_(0), |
| 60 rec_samples_(0), | |
| 61 last_rec_samples_(0), | 58 last_rec_samples_(0), |
| 62 play_samples_(0), | |
| 63 last_play_samples_(0), | 59 last_play_samples_(0), |
| 64 max_rec_level_(0), | |
| 65 max_play_level_(0), | |
| 66 last_timer_task_time_(0), | 60 last_timer_task_time_(0), |
| 67 rec_stat_count_(0), | 61 rec_stat_count_(0), |
| 68 play_stat_count_(0), | 62 play_stat_count_(0), |
| 69 play_start_time_(0), | 63 play_start_time_(0), |
| 70 rec_start_time_(0), | 64 rec_start_time_(0), |
| 65 rec_callbacks_(0), | |
| 66 play_callbacks_(0), | |
| 67 rec_samples_(0), | |
| 68 play_samples_(0), | |
| 69 max_rec_level_(0), | |
| 70 max_play_level_(0), | |
| 71 only_silence_recorded_(true), | 71 only_silence_recorded_(true), |
| 72 log_stats_(false) { | 72 log_stats_(false) { |
| 73 LOG(INFO) << "AudioDeviceBuffer::ctor"; | 73 LOG(INFO) << "AudioDeviceBuffer::ctor"; |
| 74 playout_thread_checker_.DetachFromThread(); | 74 playout_thread_checker_.DetachFromThread(); |
| 75 recording_thread_checker_.DetachFromThread(); | 75 recording_thread_checker_.DetachFromThread(); |
| 76 } | 76 } |
| 77 | 77 |
| 78 AudioDeviceBuffer::~AudioDeviceBuffer() { | 78 AudioDeviceBuffer::~AudioDeviceBuffer() { |
| 79 RTC_DCHECK_RUN_ON(&main_thread_checker_); | 79 RTC_DCHECK_RUN_ON(&main_thread_checker_); |
| 80 RTC_DCHECK(!playing_); | 80 RTC_DCHECK(!playing_); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 // Returns the largest absolute value in a signed 16-bit vector. | 319 // Returns the largest absolute value in a signed 16-bit vector. |
| 320 max_abs = WebRtcSpl_MaxAbsValueW16(rec_buffer_.data(), rec_buffer_.size()); | 320 max_abs = WebRtcSpl_MaxAbsValueW16(rec_buffer_.data(), rec_buffer_.size()); |
| 321 rec_stat_count_ = 0; | 321 rec_stat_count_ = 0; |
| 322 // Set |only_silence_recorded_| to false as soon as at least one detection | 322 // Set |only_silence_recorded_| to false as soon as at least one detection |
| 323 // of a non-zero audio packet is found. It can only be restored to true | 323 // of a non-zero audio packet is found. It can only be restored to true |
| 324 // again by restarting the call. | 324 // again by restarting the call. |
| 325 if (max_abs > 0) { | 325 if (max_abs > 0) { |
| 326 only_silence_recorded_ = false; | 326 only_silence_recorded_ = false; |
| 327 } | 327 } |
| 328 } | 328 } |
| 329 // Update some stats but do it on the task queue to ensure that the members | 329 // Update recording stats which is used as base for periodic logging of the |
| 330 // are modified and read on the same thread. Note that |max_abs| will be | 330 // audio input state. |
| 331 // zero in most calls and then have no effect of the stats. It is only updated | 331 UpdateRecStats(max_abs, samples_per_channel); |
| 332 // approximately two times per second and can then change the stats. | |
| 333 task_queue_.PostTask([this, max_abs, samples_per_channel] { | |
| 334 UpdateRecStats(max_abs, samples_per_channel); | |
| 335 }); | |
| 336 return 0; | 332 return 0; |
| 337 } | 333 } |
| 338 | 334 |
| 339 int32_t AudioDeviceBuffer::DeliverRecordedData() { | 335 int32_t AudioDeviceBuffer::DeliverRecordedData() { |
| 340 RTC_DCHECK_RUN_ON(&recording_thread_checker_); | 336 RTC_DCHECK_RUN_ON(&recording_thread_checker_); |
| 341 if (!audio_transport_cb_) { | 337 if (!audio_transport_cb_) { |
| 342 LOG(LS_WARNING) << "Invalid audio transport"; | 338 LOG(LS_WARNING) << "Invalid audio transport"; |
| 343 return 0; | 339 return 0; |
| 344 } | 340 } |
| 345 const size_t frames = rec_buffer_.size() / rec_channels_; | 341 const size_t frames = rec_buffer_.size() / rec_channels_; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 | 386 |
| 391 // Derive a new level value twice per second. | 387 // Derive a new level value twice per second. |
| 392 int16_t max_abs = 0; | 388 int16_t max_abs = 0; |
| 393 RTC_DCHECK_LT(play_stat_count_, 50); | 389 RTC_DCHECK_LT(play_stat_count_, 50); |
| 394 if (++play_stat_count_ >= 50) { | 390 if (++play_stat_count_ >= 50) { |
| 395 // Returns the largest absolute value in a signed 16-bit vector. | 391 // Returns the largest absolute value in a signed 16-bit vector. |
| 396 max_abs = | 392 max_abs = |
| 397 WebRtcSpl_MaxAbsValueW16(play_buffer_.data(), play_buffer_.size()); | 393 WebRtcSpl_MaxAbsValueW16(play_buffer_.data(), play_buffer_.size()); |
| 398 play_stat_count_ = 0; | 394 play_stat_count_ = 0; |
| 399 } | 395 } |
| 400 // Update some stats but do it on the task queue to ensure that the members | 396 // Update playout stats which is used as base for periodic logging of the |
| 401 // are modified and read on the same thread. Note that |max_abs| will be | 397 // audio output state. |
| 402 // zero in most calls and then have no effect of the stats. It is only updated | 398 UpdatePlayStats(max_abs, num_samples_out); |
| 403 // approximately two times per second and can then change the stats. | |
| 404 task_queue_.PostTask([this, max_abs, num_samples_out] { | |
| 405 UpdatePlayStats(max_abs, num_samples_out); | |
| 406 }); | |
| 407 return static_cast<int32_t>(num_samples_out); | 399 return static_cast<int32_t>(num_samples_out); |
| 408 } | 400 } |
| 409 | 401 |
| 410 int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) { | 402 int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) { |
| 411 RTC_DCHECK_RUN_ON(&playout_thread_checker_); | 403 RTC_DCHECK_RUN_ON(&playout_thread_checker_); |
| 412 RTC_DCHECK_GT(play_buffer_.size(), 0); | 404 RTC_DCHECK_GT(play_buffer_.size(), 0); |
| 413 const size_t bytes_per_sample = sizeof(int16_t); | 405 const size_t bytes_per_sample = sizeof(int16_t); |
| 414 memcpy(audio_buffer, play_buffer_.data(), | 406 memcpy(audio_buffer, play_buffer_.data(), |
| 415 play_buffer_.size() * bytes_per_sample); | 407 play_buffer_.size() * bytes_per_sample); |
| 416 // Return samples per channel or number of frames. | 408 // Return samples per channel or number of frames. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 446 | 438 |
| 447 // Avoid adding more logs since we are in STOP mode. | 439 // Avoid adding more logs since we are in STOP mode. |
| 448 if (!log_stats_) { | 440 if (!log_stats_) { |
| 449 return; | 441 return; |
| 450 } | 442 } |
| 451 | 443 |
| 452 int64_t next_callback_time = now_time + kTimerIntervalInMilliseconds; | 444 int64_t next_callback_time = now_time + kTimerIntervalInMilliseconds; |
| 453 int64_t time_since_last = rtc::TimeDiff(now_time, last_timer_task_time_); | 445 int64_t time_since_last = rtc::TimeDiff(now_time, last_timer_task_time_); |
| 454 last_timer_task_time_ = now_time; | 446 last_timer_task_time_ = now_time; |
| 455 | 447 |
| 456 // Log the latest statistics but skip the first round just after state was | 448 { |
| 457 // set to LOG_START. Hence, first printed log will be after ~10 seconds. | 449 rtc::CritScope cs(&lock_); |
|
the sun
2017/02/01 22:37:42
It bothers me that you're holding the lock while l
henrika_webrtc
2017/02/02 13:51:48
Will do. Thanks.
| |
| 458 if (++num_stat_reports_ > 1 && time_since_last > 0) { | |
| 459 uint32_t diff_samples = rec_samples_ - last_rec_samples_; | |
| 460 float rate = diff_samples / (static_cast<float>(time_since_last) / 1000.0); | |
| 461 LOG(INFO) << "[REC : " << time_since_last << "msec, " | |
| 462 << rec_sample_rate_ / 1000 | |
| 463 << "kHz] callbacks: " << rec_callbacks_ - last_rec_callbacks_ | |
| 464 << ", " | |
| 465 << "samples: " << diff_samples << ", " | |
| 466 << "rate: " << static_cast<int>(rate + 0.5) << ", " | |
| 467 << "level: " << max_rec_level_; | |
| 468 | 450 |
| 469 diff_samples = play_samples_ - last_play_samples_; | 451 // Log the latest statistics but skip the first round just after state was |
| 470 rate = diff_samples / (static_cast<float>(time_since_last) / 1000.0); | 452 // set to LOG_START. Hence, first printed log will be after ~10 seconds. |
| 471 LOG(INFO) << "[PLAY: " << time_since_last << "msec, " | 453 if (++num_stat_reports_ > 1 && time_since_last > 0) { |
| 472 << play_sample_rate_ / 1000 | 454 uint32_t diff_samples = rec_samples_ - last_rec_samples_; |
| 473 << "kHz] callbacks: " << play_callbacks_ - last_play_callbacks_ | 455 float rate = |
| 474 << ", " | 456 diff_samples / (static_cast<float>(time_since_last) / 1000.0); |
| 475 << "samples: " << diff_samples << ", " | 457 LOG(INFO) << "[REC : " << time_since_last << "msec, " |
| 476 << "rate: " << static_cast<int>(rate + 0.5) << ", " | 458 << rec_sample_rate_ / 1000 |
| 477 << "level: " << max_play_level_; | 459 << "kHz] callbacks: " << rec_callbacks_ - last_rec_callbacks_ |
| 460 << ", " | |
| 461 << "samples: " << diff_samples << ", " | |
| 462 << "rate: " << static_cast<int>(rate + 0.5) << ", " | |
| 463 << "level: " << max_rec_level_; | |
| 464 | |
| 465 diff_samples = play_samples_ - last_play_samples_; | |
| 466 rate = diff_samples / (static_cast<float>(time_since_last) / 1000.0); | |
| 467 LOG(INFO) << "[PLAY: " << time_since_last << "msec, " | |
| 468 << play_sample_rate_ / 1000 | |
| 469 << "kHz] callbacks: " << play_callbacks_ - last_play_callbacks_ | |
| 470 << ", " | |
| 471 << "samples: " << diff_samples << ", " | |
| 472 << "rate: " << static_cast<int>(rate + 0.5) << ", " | |
| 473 << "level: " << max_play_level_; | |
| 474 } | |
| 475 | |
| 476 last_rec_callbacks_ = rec_callbacks_; | |
| 477 last_play_callbacks_ = play_callbacks_; | |
| 478 last_rec_samples_ = rec_samples_; | |
| 479 last_play_samples_ = play_samples_; | |
| 480 max_rec_level_ = 0; | |
| 481 max_play_level_ = 0; | |
| 478 } | 482 } |
| 479 | 483 |
| 480 last_rec_callbacks_ = rec_callbacks_; | |
| 481 last_play_callbacks_ = play_callbacks_; | |
| 482 last_rec_samples_ = rec_samples_; | |
| 483 last_play_samples_ = play_samples_; | |
| 484 max_rec_level_ = 0; | |
| 485 max_play_level_ = 0; | |
| 486 | |
| 487 int64_t time_to_wait_ms = next_callback_time - rtc::TimeMillis(); | 484 int64_t time_to_wait_ms = next_callback_time - rtc::TimeMillis(); |
| 488 RTC_DCHECK_GT(time_to_wait_ms, 0) << "Invalid timer interval"; | 485 RTC_DCHECK_GT(time_to_wait_ms, 0) << "Invalid timer interval"; |
| 489 | 486 |
| 490 // Keep posting new (delayed) tasks until state is changed to kLogStop. | 487 // Keep posting new (delayed) tasks until state is changed to kLogStop. |
| 491 task_queue_.PostDelayedTask(rtc::Bind(&AudioDeviceBuffer::LogStats, this, | 488 task_queue_.PostDelayedTask(rtc::Bind(&AudioDeviceBuffer::LogStats, this, |
| 492 AudioDeviceBuffer::LOG_ACTIVE), | 489 AudioDeviceBuffer::LOG_ACTIVE), |
| 493 time_to_wait_ms); | 490 time_to_wait_ms); |
| 494 } | 491 } |
| 495 | 492 |
| 496 void AudioDeviceBuffer::ResetRecStats() { | 493 void AudioDeviceBuffer::ResetRecStats() { |
| 497 RTC_DCHECK_RUN_ON(&task_queue_); | 494 RTC_DCHECK_RUN_ON(&task_queue_); |
| 495 rtc::CritScope cs(&lock_); | |
| 498 rec_callbacks_ = 0; | 496 rec_callbacks_ = 0; |
| 499 last_rec_callbacks_ = 0; | 497 last_rec_callbacks_ = 0; |
| 500 rec_samples_ = 0; | 498 rec_samples_ = 0; |
| 501 last_rec_samples_ = 0; | 499 last_rec_samples_ = 0; |
| 502 max_rec_level_ = 0; | 500 max_rec_level_ = 0; |
| 503 } | 501 } |
| 504 | 502 |
| 505 void AudioDeviceBuffer::ResetPlayStats() { | 503 void AudioDeviceBuffer::ResetPlayStats() { |
| 506 RTC_DCHECK_RUN_ON(&task_queue_); | 504 RTC_DCHECK_RUN_ON(&task_queue_); |
| 505 rtc::CritScope cs(&lock_); | |
| 507 play_callbacks_ = 0; | 506 play_callbacks_ = 0; |
| 508 last_play_callbacks_ = 0; | 507 last_play_callbacks_ = 0; |
| 509 play_samples_ = 0; | 508 play_samples_ = 0; |
| 510 last_play_samples_ = 0; | 509 last_play_samples_ = 0; |
| 511 max_play_level_ = 0; | 510 max_play_level_ = 0; |
| 512 } | 511 } |
| 513 | 512 |
| 514 void AudioDeviceBuffer::UpdateRecStats(int16_t max_abs, | 513 void AudioDeviceBuffer::UpdateRecStats(int16_t max_abs, |
| 515 size_t samples_per_channel) { | 514 size_t samples_per_channel) { |
| 516 RTC_DCHECK_RUN_ON(&task_queue_); | 515 RTC_DCHECK_RUN_ON(&recording_thread_checker_); |
| 516 rtc::CritScope cs(&lock_); | |
| 517 ++rec_callbacks_; | 517 ++rec_callbacks_; |
| 518 rec_samples_ += samples_per_channel; | 518 rec_samples_ += samples_per_channel; |
| 519 if (max_abs > max_rec_level_) { | 519 if (max_abs > max_rec_level_) { |
| 520 max_rec_level_ = max_abs; | 520 max_rec_level_ = max_abs; |
| 521 } | 521 } |
| 522 } | 522 } |
| 523 | 523 |
| 524 void AudioDeviceBuffer::UpdatePlayStats(int16_t max_abs, | 524 void AudioDeviceBuffer::UpdatePlayStats(int16_t max_abs, |
| 525 size_t samples_per_channel) { | 525 size_t samples_per_channel) { |
| 526 RTC_DCHECK_RUN_ON(&task_queue_); | 526 RTC_DCHECK_RUN_ON(&playout_thread_checker_); |
| 527 rtc::CritScope cs(&lock_); | |
| 527 ++play_callbacks_; | 528 ++play_callbacks_; |
| 528 play_samples_ += samples_per_channel; | 529 play_samples_ += samples_per_channel; |
| 529 if (max_abs > max_play_level_) { | 530 if (max_abs > max_play_level_) { |
| 530 max_play_level_ = max_abs; | 531 max_play_level_ = max_abs; |
| 531 } | 532 } |
| 532 } | 533 } |
| 533 | 534 |
| 534 } // namespace webrtc | 535 } // namespace webrtc |
| OLD | NEW |