blob: 250ad4c51abc5591da7f01482903a850e81d12b7 [file] [log] [blame]
Harald Alvestrande15b9ff2023-01-25 16:32:54 +00001/*
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_receive.h"
12
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000013#include "absl/strings/escaping.h"
14#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Harald Alvestrande15b9ff2023-01-25 16:32:54 +000015#include "api/crypto/frame_decryptor_interface.h"
16#include "api/task_queue/default_task_queue_factory.h"
Harald Alvestrandba846cc2023-02-01 14:55:13 +000017#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
Harald Alvestrande15b9ff2023-01-25 16:32:54 +000018#include "modules/audio_device/include/audio_device.h"
19#include "modules/audio_device/include/mock_audio_device.h"
Harald Alvestrandba846cc2023-02-01 14:55:13 +000020#include "modules/rtp_rtcp/source/byte_io.h"
21#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000022#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
23#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
24#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
25#include "modules/rtp_rtcp/source/rtp_packet_received.h"
26#include "modules/rtp_rtcp/source/time_util.h"
Harald Alvestrandba846cc2023-02-01 14:55:13 +000027#include "rtc_base/logging.h"
Harald Alvestrande15b9ff2023-01-25 16:32:54 +000028#include "rtc_base/thread.h"
29#include "test/gmock.h"
30#include "test/gtest.h"
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000031#include "test/mock_audio_decoder_factory.h"
Harald Alvestrande15b9ff2023-01-25 16:32:54 +000032#include "test/mock_transport.h"
33#include "test/time_controller/simulated_time_controller.h"
34
35namespace webrtc {
36namespace voe {
Harald Alvestrandba846cc2023-02-01 14:55:13 +000037namespace {
Harald Alvestrande15b9ff2023-01-25 16:32:54 +000038
Harald Alvestrandba846cc2023-02-01 14:55:13 +000039using ::testing::NiceMock;
40using ::testing::NotNull;
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000041using ::testing::Return;
Harald Alvestrandba846cc2023-02-01 14:55:13 +000042using ::testing::Test;
43
44constexpr uint32_t kLocalSsrc = 1111;
45constexpr uint32_t kRemoteSsrc = 2222;
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000046// We run RTP data with 8 kHz PCMA (fixed payload type 8).
47constexpr char kPayloadName[] = "PCMA";
48constexpr int kPayloadType = 8;
49constexpr int kSampleRateHz = 8000;
Harald Alvestrandba846cc2023-02-01 14:55:13 +000050
51class ChannelReceiveTest : public Test {
52 public:
53 ChannelReceiveTest()
54 : time_controller_(Timestamp::Seconds(5555)),
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000055 audio_device_module_(test::MockAudioDeviceModule::CreateNice()),
56 audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()) {
57 ON_CALL(*audio_device_module_, PlayoutDelay).WillByDefault(Return(0));
58 }
Harald Alvestrandba846cc2023-02-01 14:55:13 +000059
60 std::unique_ptr<ChannelReceiveInterface> CreateTestChannelReceive() {
61 CryptoOptions crypto_options;
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000062 auto channel = CreateChannelReceive(
Harald Alvestrandba846cc2023-02-01 14:55:13 +000063 time_controller_.GetClock(),
64 /* neteq_factory= */ nullptr, audio_device_module_.get(), &transport_,
65 &event_log_, kLocalSsrc, kRemoteSsrc,
66 /* jitter_buffer_max_packets= */ 0,
67 /* jitter_buffer_fast_playout= */ false,
68 /* jitter_buffer_min_delay_ms= */ 0,
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000069 /* enable_non_sender_rtt= */ false, audio_decoder_factory_,
Harald Alvestrandba846cc2023-02-01 14:55:13 +000070 /* codec_pair_id= */ absl::nullopt,
71 /* frame_decryptor_interface= */ nullptr, crypto_options,
72 /* frame_transformer= */ nullptr);
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000073 channel->SetReceiveCodecs(
74 {{kPayloadType, {kPayloadName, kSampleRateHz, 1}}});
75 return channel;
Harald Alvestrandba846cc2023-02-01 14:55:13 +000076 }
77
78 NtpTime NtpNow() { return time_controller_.GetClock()->CurrentNtpTime(); }
79
Harald Alvestrand95d12ad2023-02-06 12:22:44 +000080 uint32_t RtpNow() {
81 // Note - the "random" offset of this timestamp is zero.
82 return rtc::TimeMillis() * 1000 / kSampleRateHz;
83 }
84
85 RtpPacketReceived CreateRtpPacket() {
86 RtpPacketReceived packet;
87 packet.set_arrival_time(time_controller_.GetClock()->CurrentTime());
88 packet.SetTimestamp(RtpNow());
89 packet.SetSsrc(kLocalSsrc);
90 packet.SetPayloadType(kPayloadType);
91 // Packet size should be enough to give at least 10 ms of data.
92 // For PCMA, that's 80 bytes; this should be enough.
93 uint8_t* datapos = packet.SetPayloadSize(100);
94 memset(datapos, 0, 100);
95 return packet;
96 }
97
98 std::vector<uint8_t> CreateRtcpSenderReport() {
99 std::vector<uint8_t> packet(1024);
100 size_t pos = 0;
101 rtcp::SenderReport report;
102 report.SetSenderSsrc(kRemoteSsrc);
103 report.SetNtp(NtpNow());
104 report.SetRtpTimestamp(RtpNow());
105 report.SetPacketCount(0);
106 report.SetOctetCount(0);
107 report.Create(&packet[0], &pos, packet.size(), nullptr);
108 // No report blocks.
109 packet.resize(pos);
110 return packet;
111 }
112
113 std::vector<uint8_t> CreateRtcpReceiverReport() {
114 rtcp::ReportBlock block;
115 block.SetMediaSsrc(kLocalSsrc);
116 // Middle 32 bits of the NTP timestamp from received SR
117 block.SetLastSr(CompactNtp(NtpNow()));
118 block.SetDelayLastSr(0);
119
120 rtcp::ReceiverReport report;
121 report.SetSenderSsrc(kRemoteSsrc);
122 report.AddReportBlock(block);
123
124 std::vector<uint8_t> packet(1024);
125 size_t pos = 0;
126 report.Create(&packet[0], &pos, packet.size(), nullptr);
127 packet.resize(pos);
128 return packet;
129 }
130
131 void HandleGeneratedRtcp(ChannelReceiveInterface& channel,
132 rtc::ArrayView<const uint8_t> packet) {
133 if (packet[1] == rtcp::ReceiverReport::kPacketType) {
134 // Ignore RR, it requires no response
135 } else {
136 RTC_LOG(LS_ERROR) << "Unexpected RTCP packet generated";
137 RTC_LOG(LS_ERROR) << "Packet content "
138 << rtc::hex_encode_with_delimiter(
139 absl::string_view(
140 reinterpret_cast<char*>(packet.data()[0]),
141 packet.size()),
142 ' ');
143 }
144 }
145
146 int64_t ProbeCaptureStartNtpTime(ChannelReceiveInterface& channel) {
147 // Computation of the capture_start_ntp_time_ms_ occurs when the
148 // audio data is pulled, not when it is received. So we need to
149 // inject an RTP packet, and then fetch its data.
150 AudioFrame audio_frame;
151 channel.OnRtpPacket(CreateRtpPacket());
152 channel.GetAudioFrameWithInfo(kSampleRateHz, &audio_frame);
153 CallReceiveStatistics stats = channel.GetRTCPStatistics();
154 return stats.capture_start_ntp_time_ms_;
155 }
156
Harald Alvestrandba846cc2023-02-01 14:55:13 +0000157 protected:
158 GlobalSimulatedTimeController time_controller_;
159 rtc::scoped_refptr<test::MockAudioDeviceModule> audio_device_module_;
Harald Alvestrand95d12ad2023-02-06 12:22:44 +0000160 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
Harald Alvestrandba846cc2023-02-01 14:55:13 +0000161 MockTransport transport_;
162 NiceMock<MockRtcEventLog> event_log_;
163};
164
165TEST_F(ChannelReceiveTest, CreateAndDestroy) {
166 auto channel = CreateTestChannelReceive();
167 EXPECT_THAT(channel, NotNull());
Harald Alvestrande15b9ff2023-01-25 16:32:54 +0000168}
169
Harald Alvestrandba846cc2023-02-01 14:55:13 +0000170TEST_F(ChannelReceiveTest, ReceiveReportGeneratedOnTime) {
171 auto channel = CreateTestChannelReceive();
Harald Alvestrandba846cc2023-02-01 14:55:13 +0000172
173 bool receiver_report_sent = false;
174 EXPECT_CALL(transport_, SendRtcp)
175 .WillRepeatedly([&](const uint8_t* packet, size_t length) {
176 if (length >= 2 && packet[1] == rtcp::ReceiverReport::kPacketType) {
177 receiver_report_sent = true;
178 }
179 return true;
180 });
181 // RFC 3550 section 6.2 mentions 5 seconds as a reasonable expectation
182 // for the interval between RTCP packets.
183 time_controller_.AdvanceTime(TimeDelta::Seconds(5));
184
185 EXPECT_TRUE(receiver_report_sent);
186}
187
Harald Alvestrand95d12ad2023-02-06 12:22:44 +0000188TEST_F(ChannelReceiveTest, CaptureStartTimeBecomesValid) {
189 auto channel = CreateTestChannelReceive();
190
191 EXPECT_CALL(transport_, SendRtcp)
192 .WillRepeatedly([&](const uint8_t* packet, size_t length) {
193 HandleGeneratedRtcp(*channel, rtc::MakeArrayView(packet, length));
194 return true;
195 });
196 // Before any packets are sent, CaptureStartTime is invalid.
197 EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
198
199 // Must start playout, otherwise packet is discarded.
200 channel->StartPlayout();
201 // Send one RTP packet. This causes registration of the SSRC.
202 channel->OnRtpPacket(CreateRtpPacket());
203 EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
204
205 // Receive a sender report.
206 auto rtcp_packet_1 = CreateRtcpSenderReport();
207 channel->ReceivedRTCPPacket(rtcp_packet_1.data(), rtcp_packet_1.size());
208 EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
209
210 time_controller_.AdvanceTime(TimeDelta::Seconds(5));
211
212 // Receive a receiver report. This is necessary, which is odd.
213 // Presumably it is because the receiver needs to know the RTT
214 // before it can compute the capture start NTP time.
215 // The receiver report must happen before the second sender report.
216 auto rtcp_rr = CreateRtcpReceiverReport();
217 channel->ReceivedRTCPPacket(rtcp_rr.data(), rtcp_rr.size());
218 EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
219
220 // Receive another sender report after 5 seconds.
221 // This should be enough to establish the capture start NTP time.
222 auto rtcp_packet_2 = CreateRtcpSenderReport();
223 channel->ReceivedRTCPPacket(rtcp_packet_2.data(), rtcp_packet_2.size());
224
225 EXPECT_NE(ProbeCaptureStartNtpTime(*channel), -1);
226}
227
Harald Alvestrandba846cc2023-02-01 14:55:13 +0000228} // namespace
Harald Alvestrande15b9ff2023-01-25 16:32:54 +0000229} // namespace voe
230} // namespace webrtc