blob: 523408ec19b3e9c9a3d62c229271e578c3218dd9 [file] [log] [blame]
Jakob Ivarssondcb09ff2023-01-25 19:03:561/*
2 * Copyright 2023 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "audio/channel_send.h"
12
13#include <utility>
14
15#include "api/audio/audio_frame.h"
16#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Danil Chapovalovee27f382023-12-18 12:09:1217#include "api/environment/environment.h"
18#include "api/environment/environment_factory.h"
Jakob Ivarssondcb09ff2023-01-25 19:03:5619#include "api/scoped_refptr.h"
Tony Herre9c6874602024-01-26 10:16:4520#include "api/test/mock_frame_transformer.h"
Tony Herre64437e82024-04-29 13:13:4821#include "api/test/mock_transformable_audio_frame.h"
Jakob Ivarssondcb09ff2023-01-25 19:03:5622#include "api/units/time_delta.h"
23#include "api/units/timestamp.h"
24#include "call/rtp_transport_controller_send.h"
Tony Herre36500ab2023-08-29 10:01:3225#include "rtc_base/gunit.h"
Jakob Ivarssondcb09ff2023-01-25 19:03:5626#include "test/gtest.h"
27#include "test/mock_transport.h"
28#include "test/scoped_key_value_config.h"
29#include "test/time_controller/simulated_time_controller.h"
30
31namespace webrtc {
32namespace voe {
33namespace {
34
Jakob Ivarssondb208312023-01-27 14:13:2235using ::testing::Invoke;
36using ::testing::NiceMock;
37using ::testing::Return;
Tony Herre36500ab2023-08-29 10:01:3238using ::testing::SaveArg;
Jakob Ivarssondb208312023-01-27 14:13:2239
Jakob Ivarssondcb09ff2023-01-25 19:03:5640constexpr int kRtcpIntervalMs = 1000;
41constexpr int kSsrc = 333;
42constexpr int kPayloadType = 1;
Jakob Ivarssondb208312023-01-27 14:13:2243constexpr int kSampleRateHz = 48000;
44constexpr int kRtpRateHz = 48000;
Jakob Ivarssondcb09ff2023-01-25 19:03:5645
46BitrateConstraints GetBitrateConfig() {
47 BitrateConstraints bitrate_config;
48 bitrate_config.min_bitrate_bps = 10000;
49 bitrate_config.start_bitrate_bps = 100000;
50 bitrate_config.max_bitrate_bps = 1000000;
51 return bitrate_config;
52}
53
Jakob Ivarssondcb09ff2023-01-25 19:03:5654class ChannelSendTest : public ::testing::Test {
55 protected:
56 ChannelSendTest()
57 : time_controller_(Timestamp::Seconds(1)),
Danil Chapovalovee27f382023-12-18 12:09:1258 env_(CreateEnvironment(&field_trials_,
59 time_controller_.GetClock(),
60 time_controller_.CreateTaskQueueFactory())),
Jakob Ivarssondcb09ff2023-01-25 19:03:5661 transport_controller_(
Danil Chapovalovee27f382023-12-18 12:09:1262 RtpTransportConfig{.env = env_,
63 .bitrate_config = GetBitrateConfig()}) {
Jakob Ivarssondb208312023-01-27 14:13:2264 channel_ = voe::CreateChannelSend(
Jakob Ivarssondcb09ff2023-01-25 19:03:5665 time_controller_.GetClock(), time_controller_.GetTaskQueueFactory(),
Danil Chapovalovee27f382023-12-18 12:09:1266 &transport_, nullptr, &env_.event_log(), nullptr, crypto_options_,
67 false, kRtcpIntervalMs, kSsrc, nullptr, &transport_controller_,
68 env_.field_trials());
Jakob Ivarssondb208312023-01-27 14:13:2269 encoder_factory_ = CreateBuiltinAudioEncoderFactory();
Philipp Hancked2098932023-11-01 18:18:3270 SdpAudioFormat opus = SdpAudioFormat("opus", kRtpRateHz, 2);
71 std::unique_ptr<AudioEncoder> encoder =
72 encoder_factory_->MakeAudioEncoder(kPayloadType, opus, {});
73 channel_->SetEncoder(kPayloadType, opus, std::move(encoder));
Jakob Ivarssondb208312023-01-27 14:13:2274 transport_controller_.EnsureStarted();
Danil Chapovalova2cf8ee2023-05-16 11:26:3375 channel_->RegisterSenderCongestionControlObjects(&transport_controller_);
Jakob Ivarssondb208312023-01-27 14:13:2276 ON_CALL(transport_, SendRtcp).WillByDefault(Return(true));
77 ON_CALL(transport_, SendRtp).WillByDefault(Return(true));
78 }
79
Tony Herre64437e82024-04-29 13:13:4880 std::unique_ptr<AudioFrame> CreateAudioFrame(uint8_t data_init_value = 0) {
Jakob Ivarssondb208312023-01-27 14:13:2281 auto frame = std::make_unique<AudioFrame>();
82 frame->sample_rate_hz_ = kSampleRateHz;
83 frame->samples_per_channel_ = kSampleRateHz / 100;
84 frame->num_channels_ = 1;
85 frame->set_absolute_capture_timestamp_ms(
86 time_controller_.GetClock()->TimeInMilliseconds());
Tony Herre64437e82024-04-29 13:13:4887 int16_t* dest = frame->mutable_data();
88 for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_;
89 i++, dest++) {
90 *dest = data_init_value;
91 }
Jakob Ivarssondb208312023-01-27 14:13:2292 return frame;
93 }
94
Tony Herre64437e82024-04-29 13:13:4895 void ProcessNextFrame(std::unique_ptr<AudioFrame> audio_frame) {
96 channel_->ProcessAndEncodeAudio(std::move(audio_frame));
Jakob Ivarssondb208312023-01-27 14:13:2297 // Advance time to process the task queue.
98 time_controller_.AdvanceTime(TimeDelta::Millis(10));
Jakob Ivarssondcb09ff2023-01-25 19:03:5699 }
100
Tony Herre64437e82024-04-29 13:13:48101 void ProcessNextFrame() { ProcessNextFrame(CreateAudioFrame()); }
102
Jakob Ivarssondcb09ff2023-01-25 19:03:56103 GlobalSimulatedTimeController time_controller_;
104 webrtc::test::ScopedKeyValueConfig field_trials_;
Danil Chapovalovee27f382023-12-18 12:09:12105 Environment env_;
Jakob Ivarssondb208312023-01-27 14:13:22106 NiceMock<MockTransport> transport_;
Jakob Ivarssondcb09ff2023-01-25 19:03:56107 CryptoOptions crypto_options_;
Jakob Ivarssondb208312023-01-27 14:13:22108 RtpTransportControllerSend transport_controller_;
109 std::unique_ptr<ChannelSendInterface> channel_;
110 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
Jakob Ivarssondcb09ff2023-01-25 19:03:56111};
112
113TEST_F(ChannelSendTest, StopSendShouldResetEncoder) {
Jakob Ivarssondb208312023-01-27 14:13:22114 channel_->StartSend();
Jakob Ivarssondcb09ff2023-01-25 19:03:56115 // Insert two frames which should trigger a new packet.
116 EXPECT_CALL(transport_, SendRtp).Times(1);
Jakob Ivarssondb208312023-01-27 14:13:22117 ProcessNextFrame();
118 ProcessNextFrame();
Jakob Ivarssondcb09ff2023-01-25 19:03:56119
120 EXPECT_CALL(transport_, SendRtp).Times(0);
Jakob Ivarssondb208312023-01-27 14:13:22121 ProcessNextFrame();
Jakob Ivarssondcb09ff2023-01-25 19:03:56122 // StopSend should clear the previous audio frame stored in the encoder.
Jakob Ivarssondb208312023-01-27 14:13:22123 channel_->StopSend();
124 channel_->StartSend();
Jakob Ivarssondcb09ff2023-01-25 19:03:56125 // The following frame should not trigger a new packet since the encoder
126 // needs 20 ms audio.
Jakob Ivarssondb208312023-01-27 14:13:22127 EXPECT_CALL(transport_, SendRtp).Times(0);
128 ProcessNextFrame();
129}
130
131TEST_F(ChannelSendTest, IncreaseRtpTimestampByPauseDuration) {
132 channel_->StartSend();
133 uint32_t timestamp;
134 int sent_packets = 0;
Harald Alvestrandd43af912023-08-15 11:41:45135 auto send_rtp = [&](rtc::ArrayView<const uint8_t> data,
Jakob Ivarssondb208312023-01-27 14:13:22136 const PacketOptions& options) {
137 ++sent_packets;
138 RtpPacketReceived packet;
Harald Alvestrandd43af912023-08-15 11:41:45139 packet.Parse(data);
Jakob Ivarssondb208312023-01-27 14:13:22140 timestamp = packet.Timestamp();
141 return true;
142 };
143 EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
144 ProcessNextFrame();
145 ProcessNextFrame();
146 EXPECT_EQ(sent_packets, 1);
147 uint32_t first_timestamp = timestamp;
148 channel_->StopSend();
149 time_controller_.AdvanceTime(TimeDelta::Seconds(10));
150 channel_->StartSend();
151
152 ProcessNextFrame();
153 ProcessNextFrame();
154 EXPECT_EQ(sent_packets, 2);
155 int64_t timestamp_gap_ms =
156 static_cast<int64_t>(timestamp - first_timestamp) * 1000 / kRtpRateHz;
157 EXPECT_EQ(timestamp_gap_ms, 10020);
Jakob Ivarssondcb09ff2023-01-25 19:03:56158}
159
Tony Herre36500ab2023-08-29 10:01:32160TEST_F(ChannelSendTest, FrameTransformerGetsCorrectTimestamp) {
161 rtc::scoped_refptr<MockFrameTransformer> mock_frame_transformer =
162 rtc::make_ref_counted<MockFrameTransformer>();
163 channel_->SetEncoderToPacketizerFrameTransformer(mock_frame_transformer);
164 rtc::scoped_refptr<TransformedFrameCallback> callback;
165 EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
166 .WillOnce(SaveArg<0>(&callback));
167 EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
168
169 absl::optional<uint32_t> sent_timestamp;
170 auto send_rtp = [&](rtc::ArrayView<const uint8_t> data,
171 const PacketOptions& options) {
172 RtpPacketReceived packet;
173 packet.Parse(data);
174 if (!sent_timestamp) {
175 sent_timestamp = packet.Timestamp();
176 }
177 return true;
178 };
179 EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
180
181 channel_->StartSend();
182 int64_t transformable_frame_timestamp = -1;
183 EXPECT_CALL(*mock_frame_transformer, Transform)
184 .WillOnce([&](std::unique_ptr<TransformableFrameInterface> frame) {
185 transformable_frame_timestamp = frame->GetTimestamp();
186 callback->OnTransformedFrame(std::move(frame));
187 });
188 // Insert two frames which should trigger a new packet.
189 ProcessNextFrame();
190 ProcessNextFrame();
191
192 // Ensure the RTP timestamp on the frame passed to the transformer
193 // includes the RTP offset and matches the actual RTP timestamp on the sent
194 // packet.
195 EXPECT_EQ_WAIT(transformable_frame_timestamp,
196 0 + channel_->GetRtpRtcp()->StartTimestamp(), 1000);
197 EXPECT_TRUE_WAIT(sent_timestamp, 1000);
198 EXPECT_EQ(*sent_timestamp, transformable_frame_timestamp);
199}
Tony Herre64437e82024-04-29 13:13:48200
201// Ensure that AudioLevel calculations are performed correctly per-packet even
202// if there's an async Encoded Frame Transform happening.
203TEST_F(ChannelSendTest, AudioLevelsAttachedToCorrectTransformedFrame) {
204 channel_->SetSendAudioLevelIndicationStatus(true, /*id=*/1);
205 RtpPacketReceived::ExtensionManager extension_manager;
206 extension_manager.RegisterByType(1, kRtpExtensionAudioLevel);
207
208 rtc::scoped_refptr<MockFrameTransformer> mock_frame_transformer =
209 rtc::make_ref_counted<MockFrameTransformer>();
210 channel_->SetEncoderToPacketizerFrameTransformer(mock_frame_transformer);
211 rtc::scoped_refptr<TransformedFrameCallback> callback;
212 EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
213 .WillOnce(SaveArg<0>(&callback));
214 EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
215
216 std::vector<uint8_t> sent_audio_levels;
217 auto send_rtp = [&](rtc::ArrayView<const uint8_t> data,
218 const PacketOptions& options) {
219 RtpPacketReceived packet(&extension_manager);
220 packet.Parse(data);
221 RTPHeader header;
222 packet.GetHeader(&header);
223 sent_audio_levels.push_back(header.extension.audio_level()->level());
224 return true;
225 };
226 EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
227
228 channel_->StartSend();
229 std::vector<std::unique_ptr<TransformableFrameInterface>> frames;
230 EXPECT_CALL(*mock_frame_transformer, Transform)
231 .Times(2)
232 .WillRepeatedly([&](std::unique_ptr<TransformableFrameInterface> frame) {
233 frames.push_back(std::move(frame));
234 });
235
236 // Insert two frames of 7s which should trigger a new packet.
237 ProcessNextFrame(CreateAudioFrame(/*data_init_value=*/7));
238 ProcessNextFrame(CreateAudioFrame(/*data_init_value=*/7));
239
240 // Insert two more frames of 3s, meaning a second packet is
241 // prepared and sent to the transform before the first packet has
242 // been sent.
243 ProcessNextFrame(CreateAudioFrame(/*data_init_value=*/3));
244 ProcessNextFrame(CreateAudioFrame(/*data_init_value=*/3));
245
246 // Wait for both packets to be encoded and sent to the transform.
247 EXPECT_EQ_WAIT(frames.size(), 2ul, 1000);
248 // Complete the transforms on both frames at the same time
249 callback->OnTransformedFrame(std::move(frames[0]));
250 callback->OnTransformedFrame(std::move(frames[1]));
251
252 // Allow things posted back to the encoder queue to run.
253 time_controller_.AdvanceTime(TimeDelta::Millis(10));
254
255 // Ensure the audio levels on both sent packets is present and
256 // matches their contents.
257 EXPECT_EQ_WAIT(sent_audio_levels.size(), 2ul, 1000);
258 // rms dbov of the packet with raw audio of 7s is 73.
259 EXPECT_EQ(sent_audio_levels[0], 73);
260 // rms dbov of the second packet with raw audio of 3s is 81.
261 EXPECT_EQ(sent_audio_levels[1], 81);
262}
263
264// Ensure that AudioLevels are attached to frames injected into the
265// Encoded Frame transform.
266TEST_F(ChannelSendTest, AudioLevelsAttachedToInsertedTransformedFrame) {
267 channel_->SetSendAudioLevelIndicationStatus(true, /*id=*/1);
268 RtpPacketReceived::ExtensionManager extension_manager;
269 extension_manager.RegisterByType(1, kRtpExtensionAudioLevel);
270
271 rtc::scoped_refptr<MockFrameTransformer> mock_frame_transformer =
272 rtc::make_ref_counted<MockFrameTransformer>();
273 channel_->SetEncoderToPacketizerFrameTransformer(mock_frame_transformer);
274 rtc::scoped_refptr<TransformedFrameCallback> callback;
275 EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
276 .WillOnce(SaveArg<0>(&callback));
277 EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
278
279 std::optional<uint8_t> sent_audio_level;
280 auto send_rtp = [&](rtc::ArrayView<const uint8_t> data,
281 const PacketOptions& options) {
282 RtpPacketReceived packet(&extension_manager);
283 packet.Parse(data);
284 RTPHeader header;
285 packet.GetHeader(&header);
286 sent_audio_level = header.extension.audio_level()->level();
287 return true;
288 };
289 EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
290
291 channel_->StartSend();
292
293 time_controller_.AdvanceTime(TimeDelta::Millis(10));
294 // Inject a frame encoded elsewhere.
295 auto mock_frame = std::make_unique<NiceMock<MockTransformableAudioFrame>>();
296 uint8_t audio_level = 67;
297 ON_CALL(*mock_frame, AudioLevel()).WillByDefault(Return(audio_level));
298 uint8_t payload[10];
299 ON_CALL(*mock_frame, GetData())
300 .WillByDefault(Return(rtc::ArrayView<uint8_t>(&payload[0], 10)));
301 EXPECT_TRUE_WAIT(callback, 1000);
302 callback->OnTransformedFrame(std::move(mock_frame));
303
304 // Allow things posted back to the encoder queue to run.
305 time_controller_.AdvanceTime(TimeDelta::Millis(10));
306
307 // Ensure the audio levels is set on the sent packet.
308 EXPECT_TRUE_WAIT(sent_audio_level, 1000);
309 EXPECT_EQ(*sent_audio_level, audio_level);
310}
Jakob Ivarssondcb09ff2023-01-25 19:03:56311} // namespace
312} // namespace voe
313} // namespace webrtc