Ensure the AudioCodingModule is reset when sending is stopped.
Bug: webrtc:42226041
Change-Id: Ife3548bda3042a7447b7c50f48f023a2bc0bc443
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/362103
Commit-Queue: Lionel Koenig <lionelk@webrtc.org>
Reviewed-by: Jesus de Vicente Pena <devicentepena@webrtc.org>
Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43017}
diff --git a/audio/channel_send.cc b/audio/channel_send.cc
index d1683b7..fa8a421 100644
--- a/audio/channel_send.cc
+++ b/audio/channel_send.cc
@@ -562,7 +562,7 @@
rtc::Event flush;
encoder_queue_->PostTask([this, &flush]() {
RTC_DCHECK_RUN_ON(&encoder_queue_checker_);
- CallEncoder([](AudioEncoder* encoder) { encoder->Reset(); });
+ audio_coding_->Reset();
flush.Set();
});
flush.Wait(rtc::Event::kForever);
diff --git a/audio/channel_send_unittest.cc b/audio/channel_send_unittest.cc
index 2260c81..31cdaa0 100644
--- a/audio/channel_send_unittest.cc
+++ b/audio/channel_send_unittest.cc
@@ -140,6 +140,7 @@
ProcessNextFrame();
// StopSend should clear the previous audio frame stored in the encoder.
channel_->StopSend();
+
channel_->StartSend();
// The following frame should not trigger a new packet since the encoder
// needs 20 ms audio.
diff --git a/modules/audio_coding/acm2/audio_coding_module.cc b/modules/audio_coding/acm2/audio_coding_module.cc
index e1a775d..0300335 100644
--- a/modules/audio_coding/acm2/audio_coding_module.cc
+++ b/modules/audio_coding/acm2/audio_coding_module.cc
@@ -43,6 +43,8 @@
explicit AudioCodingModuleImpl();
~AudioCodingModuleImpl() override;
+ void Reset() override;
+
/////////////////////////////////////////
// Sender
//
@@ -280,7 +282,7 @@
absolute_capture_timestamp_ms_.value_or(-1));
}
}
- absolute_capture_timestamp_ms_ = std::nullopt;
+ absolute_capture_timestamp_ms_.reset();
previous_pltype_ = encoded_info.payload_type;
return static_cast<int32_t>(encode_buffer_.size());
}
@@ -289,6 +291,14 @@
// Sender
//
+void AudioCodingModuleImpl::Reset() {
+ MutexLock lock(&acm_mutex_);
+ absolute_capture_timestamp_ms_.reset();
+ if (HaveValidEncoder("Reset")) {
+ encoder_stack_->Reset();
+ }
+}
+
void AudioCodingModuleImpl::ModifyEncoder(
rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier) {
MutexLock lock(&acm_mutex_);
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index c8ef9df..c7e9dfc 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -522,6 +522,17 @@
(override));
};
+TEST(AudioCodingModule, DoesResetEncoder) {
+ std::unique_ptr<AudioCodingModule> acm = AudioCodingModule::Create();
+ auto encoder = std::make_unique<MockAudioEncoder>();
+ MockAudioEncoder* encoder_mock = encoder.get();
+
+ acm->SetEncoder(std::move(encoder));
+
+ EXPECT_CALL(*encoder_mock, Reset()).Times(1);
+ acm->Reset();
+}
+
class AcmAbsoluteCaptureTimestamp : public ::testing::Test {
public:
AcmAbsoluteCaptureTimestamp() : audio_frame_(kSampleRateHz, kNumChannels) {}
@@ -587,6 +598,40 @@
}
}
+TEST_F(AcmAbsoluteCaptureTimestamp, DoesResetWhenAudioCodingModuleDo) {
+ constexpr int64_t first_absolute_capture_timestamp_ms = 123456789;
+
+ int64_t absolute_capture_timestamp_ms = first_absolute_capture_timestamp_ms;
+ EXPECT_CALL(transport_,
+ SendData(_, _, _, _, _, first_absolute_capture_timestamp_ms))
+ .Times(1);
+ EXPECT_CALL(
+ transport_,
+ SendData(_, _, _, _, _, first_absolute_capture_timestamp_ms + kPTimeMs))
+ .Times(1);
+ for (int k = 0; k < 5; ++k) {
+ acm_->Add10MsData(
+ GetAudioWithAbsoluteCaptureTimestamp(absolute_capture_timestamp_ms));
+ absolute_capture_timestamp_ms += 10;
+ }
+
+ acm_->Reset();
+ constexpr int64_t after_reset_absolute_capture_timestamp_ms = 523456789;
+ EXPECT_CALL(transport_, SendData(_, _, _, _, _,
+ after_reset_absolute_capture_timestamp_ms))
+ .Times(1);
+ EXPECT_CALL(transport_,
+ SendData(_, _, _, _, _,
+ after_reset_absolute_capture_timestamp_ms + kPTimeMs))
+ .Times(1);
+ absolute_capture_timestamp_ms = after_reset_absolute_capture_timestamp_ms;
+ for (int k = 0; k < 5; ++k) {
+ acm_->Add10MsData(
+ GetAudioWithAbsoluteCaptureTimestamp(absolute_capture_timestamp_ms));
+ absolute_capture_timestamp_ms += 10;
+ }
+}
+
// Disabling all of these tests on iOS until file support has been added.
// See https://code.google.com/p/webrtc/issues/detail?id=4752 for details.
#if !defined(WEBRTC_IOS)
diff --git a/modules/audio_coding/include/audio_coding_module.h b/modules/audio_coding/include/audio_coding_module.h
index ec8255e..094ef0e 100644
--- a/modules/audio_coding/include/audio_coding_module.h
+++ b/modules/audio_coding/include/audio_coding_module.h
@@ -78,6 +78,10 @@
});
}
+ // Reset encoder and audio coding module. This throws away any audio passed
+ // and starts fresh.
+ virtual void Reset() = 0;
+
// int32_t RegisterTransportCallback()
// Register a transport callback which will be called to deliver
// the encoded buffers whenever Process() is called and a