Make capture timestamp optional in ADM.

This is to avoid using 0 as a default value.

Also fix a bug in audio_device_buffer where the timestamp aligner used the wrong input timestamp.

Bug: webrtc:13609
Change-Id: I00016e68ab50d052990c2b9f80aa1e2d7e167b93
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291118
Reviewed-by: Olov Brändström <brandstrom@google.com>
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39177}
This commit is contained in:
Jakob Ivarsson 2023-01-20 22:09:29 +01:00 committed by WebRTC LUCI CQ
parent 6e627290bf
commit 22821deb38
7 changed files with 70 additions and 68 deletions

View File

@ -107,35 +107,35 @@ AudioTransportImpl::~AudioTransportImpl() {}
int32_t AudioTransportImpl::RecordedDataIsAvailable( int32_t AudioTransportImpl::RecordedDataIsAvailable(
const void* audio_data, const void* audio_data,
const size_t number_of_frames, size_t number_of_frames,
const size_t bytes_per_sample, size_t bytes_per_sample,
const size_t number_of_channels, size_t number_of_channels,
const uint32_t sample_rate, uint32_t sample_rate,
const uint32_t audio_delay_milliseconds, uint32_t audio_delay_milliseconds,
const int32_t clock_drift, int32_t clock_drift,
const uint32_t volume, uint32_t volume,
const bool key_pressed, bool key_pressed,
uint32_t& new_mic_volume) { // NOLINT: to avoid changing APIs uint32_t& new_mic_volume) { // NOLINT: to avoid changing APIs
return RecordedDataIsAvailable( return RecordedDataIsAvailable(
audio_data, number_of_frames, bytes_per_sample, number_of_channels, audio_data, number_of_frames, bytes_per_sample, number_of_channels,
sample_rate, audio_delay_milliseconds, clock_drift, volume, key_pressed, sample_rate, audio_delay_milliseconds, clock_drift, volume, key_pressed,
new_mic_volume, /* estimated_capture_time_ns */ 0); new_mic_volume, /*estimated_capture_time_ns=*/absl::nullopt);
} }
// Not used in Chromium. Process captured audio and distribute to all sending // Not used in Chromium. Process captured audio and distribute to all sending
// streams, and try to do this at the lowest possible sample rate. // streams, and try to do this at the lowest possible sample rate.
int32_t AudioTransportImpl::RecordedDataIsAvailable( int32_t AudioTransportImpl::RecordedDataIsAvailable(
const void* audio_data, const void* audio_data,
const size_t number_of_frames, size_t number_of_frames,
const size_t bytes_per_sample, size_t bytes_per_sample,
const size_t number_of_channels, size_t number_of_channels,
const uint32_t sample_rate, uint32_t sample_rate,
const uint32_t audio_delay_milliseconds, uint32_t audio_delay_milliseconds,
const int32_t /*clock_drift*/, int32_t /*clock_drift*/,
const uint32_t /*volume*/, uint32_t /*volume*/,
const bool key_pressed, bool key_pressed,
uint32_t& /*new_mic_volume*/, uint32_t& /*new_mic_volume*/,
const int64_t absl::optional<int64_t>
estimated_capture_time_ns) { // NOLINT: to avoid changing APIs estimated_capture_time_ns) { // NOLINT: to avoid changing APIs
RTC_DCHECK(audio_data); RTC_DCHECK(audio_data);
RTC_DCHECK_GE(number_of_channels, 1); RTC_DCHECK_GE(number_of_channels, 1);
@ -166,8 +166,11 @@ int32_t AudioTransportImpl::RecordedDataIsAvailable(
ProcessCaptureFrame(audio_delay_milliseconds, key_pressed, ProcessCaptureFrame(audio_delay_milliseconds, key_pressed,
swap_stereo_channels, audio_processing_, swap_stereo_channels, audio_processing_,
audio_frame.get()); audio_frame.get());
audio_frame->set_absolute_capture_timestamp_ms(estimated_capture_time_ns /
1000000); if (estimated_capture_time_ns) {
audio_frame->set_absolute_capture_timestamp_ms(*estimated_capture_time_ns /
1000000);
}
RTC_DCHECK_GT(audio_frame->samples_per_channel_, 0); RTC_DCHECK_GT(audio_frame->samples_per_channel_, 0);
if (async_audio_processing_) if (async_audio_processing_)

View File

@ -52,17 +52,18 @@ class AudioTransportImpl : public AudioTransport {
bool keyPressed, bool keyPressed,
uint32_t& newMicLevel) override; uint32_t& newMicLevel) override;
int32_t RecordedDataIsAvailable(const void* audioSamples, int32_t RecordedDataIsAvailable(
size_t nSamples, const void* audioSamples,
size_t nBytesPerSample, size_t nSamples,
size_t nChannels, size_t nBytesPerSample,
uint32_t samplesPerSec, size_t nChannels,
uint32_t totalDelayMS, uint32_t samplesPerSec,
int32_t clockDrift, uint32_t totalDelayMS,
uint32_t currentMicLevel, int32_t clockDrift,
bool keyPressed, uint32_t currentMicLevel,
uint32_t& newMicLevel, bool keyPressed,
int64_t estimated_capture_time_ns) override; uint32_t& newMicLevel,
absl::optional<int64_t> estimated_capture_time_ns) override;
int32_t NeedMorePlayData(size_t nSamples, int32_t NeedMorePlayData(size_t nSamples,
size_t nBytesPerSample, size_t nBytesPerSample,

View File

@ -55,7 +55,6 @@ AudioDeviceBuffer::AudioDeviceBuffer(TaskQueueFactory* task_queue_factory)
typing_status_(false), typing_status_(false),
play_delay_ms_(0), play_delay_ms_(0),
rec_delay_ms_(0), rec_delay_ms_(0),
capture_timestamp_ns_(0),
num_stat_reports_(0), num_stat_reports_(0),
last_timer_task_time_(0), last_timer_task_time_(0),
rec_stat_count_(0), rec_stat_count_(0),
@ -231,12 +230,13 @@ void AudioDeviceBuffer::SetVQEData(int play_delay_ms, int rec_delay_ms) {
int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer, int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer,
size_t samples_per_channel) { size_t samples_per_channel) {
return SetRecordedBuffer(audio_buffer, samples_per_channel, 0); return SetRecordedBuffer(audio_buffer, samples_per_channel, absl::nullopt);
} }
int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer, int32_t AudioDeviceBuffer::SetRecordedBuffer(
size_t samples_per_channel, const void* audio_buffer,
int64_t capture_timestamp_ns) { size_t samples_per_channel,
absl::optional<int64_t> capture_timestamp_ns) {
// Copy the complete input buffer to the local buffer. // Copy the complete input buffer to the local buffer.
const size_t old_size = rec_buffer_.size(); const size_t old_size = rec_buffer_.size();
rec_buffer_.SetData(static_cast<const int16_t*>(audio_buffer), rec_buffer_.SetData(static_cast<const int16_t*>(audio_buffer),
@ -247,17 +247,13 @@ int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer,
RTC_LOG(LS_INFO) << "Size of recording buffer: " << rec_buffer_.size(); RTC_LOG(LS_INFO) << "Size of recording buffer: " << rec_buffer_.size();
} }
// If the timestamp is less then or equal to zero, it's not valid and are if (capture_timestamp_ns) {
// ignored. If we do antimestamp alignment on them they might accidentally capture_timestamp_ns_ =
// become greater then zero, and will be handled as if they were a correct rtc::kNumNanosecsPerMicrosec *
// timestamp. timestamp_aligner_.TranslateTimestamp(
capture_timestamp_ns_ = *capture_timestamp_ns / rtc::kNumNanosecsPerMicrosec,
(capture_timestamp_ns > 0) rtc::TimeMicros());
? rtc::kNumNanosecsPerMicrosec * }
timestamp_aligner_.TranslateTimestamp(
capture_timestamp_ns_ / rtc::kNumNanosecsPerMicrosec,
rtc::TimeMicros())
: capture_timestamp_ns;
// Derive a new level value twice per second and check if it is non-zero. // Derive a new level value twice per second and check if it is non-zero.
int16_t max_abs = 0; int16_t max_abs = 0;
RTC_DCHECK_LT(rec_stat_count_, 50); RTC_DCHECK_LT(rec_stat_count_, 50);

View File

@ -102,9 +102,10 @@ class AudioDeviceBuffer {
virtual int32_t SetRecordedBuffer(const void* audio_buffer, virtual int32_t SetRecordedBuffer(const void* audio_buffer,
size_t samples_per_channel); size_t samples_per_channel);
virtual int32_t SetRecordedBuffer(const void* audio_buffer, virtual int32_t SetRecordedBuffer(
size_t samples_per_channel, const void* audio_buffer,
int64_t capture_timestamp_ns); size_t samples_per_channel,
absl::optional<int64_t> capture_timestamp_ns);
virtual void SetVQEData(int play_delay_ms, int rec_delay_ms); virtual void SetVQEData(int play_delay_ms, int rec_delay_ms);
virtual int32_t DeliverRecordedData(); virtual int32_t DeliverRecordedData();
uint32_t NewMicLevel() const; uint32_t NewMicLevel() const;
@ -194,7 +195,7 @@ class AudioDeviceBuffer {
int rec_delay_ms_; int rec_delay_ms_;
// Capture timestamp. // Capture timestamp.
int64_t capture_timestamp_ns_; absl::optional<int64_t> capture_timestamp_ns_;
// Counts number of times LogStats() has been called. // Counts number of times LogStats() has been called.
size_t num_stat_reports_ RTC_GUARDED_BY(task_queue_); size_t num_stat_reports_ RTC_GUARDED_BY(task_queue_);

View File

@ -55,24 +55,25 @@ class ADMWrapper : public AudioDeviceModule, public AudioTransport {
uint32_t currentMicLevel, uint32_t currentMicLevel,
bool keyPressed, bool keyPressed,
uint32_t& newMicLevel) override { uint32_t& newMicLevel) override {
return RecordedDataIsAvailable(audioSamples, nSamples, nBytesPerSample, return RecordedDataIsAvailable(
nChannels, samples_per_sec, total_delay_ms, audioSamples, nSamples, nBytesPerSample, nChannels, samples_per_sec,
clockDrift, currentMicLevel, keyPressed, total_delay_ms, clockDrift, currentMicLevel, keyPressed, newMicLevel,
newMicLevel, /*capture_timestamp_ns*/ 0); /*capture_timestamp_ns=*/absl::nullopt);
} }
// AudioTransport methods overrides. // AudioTransport methods overrides.
int32_t RecordedDataIsAvailable(const void* audioSamples, int32_t RecordedDataIsAvailable(
size_t nSamples, const void* audioSamples,
size_t nBytesPerSample, size_t nSamples,
size_t nChannels, size_t nBytesPerSample,
uint32_t samples_per_sec, size_t nChannels,
uint32_t total_delay_ms, uint32_t samples_per_sec,
int32_t clockDrift, uint32_t total_delay_ms,
uint32_t currentMicLevel, int32_t clockDrift,
bool keyPressed, uint32_t currentMicLevel,
uint32_t& newMicLevel, bool keyPressed,
int64_t capture_timestamp_ns) override { uint32_t& newMicLevel,
absl::optional<int64_t> capture_timestamp_ns) override {
int32_t res = 0; int32_t res = 0;
// Capture PCM data of locally captured audio. // Capture PCM data of locally captured audio.
if (observer_) { if (observer_) {

View File

@ -56,7 +56,7 @@ class AudioTransport {
uint32_t currentMicLevel, uint32_t currentMicLevel,
bool keyPressed, bool keyPressed,
uint32_t& newMicLevel, uint32_t& newMicLevel,
int64_t estimatedCaptureTimeNS) { // NOLINT absl::optional<int64_t> estimatedCaptureTimeNS) { // NOLINT
// TODO(webrtc:13620) Make the default behaver of the new API to behave as // TODO(webrtc:13620) Make the default behaver of the new API to behave as
// the old API. This can be pure virtual if all uses of the old API is // the old API. This can be pure virtual if all uses of the old API is
// removed. // removed.

View File

@ -48,7 +48,7 @@ class MockAudioTransport : public AudioTransport {
uint32_t currentMicLevel, uint32_t currentMicLevel,
bool keyPressed, bool keyPressed,
uint32_t& newMicLevel, uint32_t& newMicLevel,
int64_t estimated_capture_time_ns), absl::optional<int64_t> estimated_capture_time_ns),
(override)); (override));
MOCK_METHOD(int32_t, MOCK_METHOD(int32_t,