blob: 67cad44d721c168cdde5efac1400ee0d40f3dc3f [file] [log] [blame]
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001/*
phoglund@webrtc.org78088c22012-02-07 14:56:45 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00003 *
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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/rtp_rtcp/source/rtp_sender.h"
12
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
danilchapb8b6fbb2015-12-10 05:05:27 -080014#include <vector>
15
Karl Wiberg918f50c2018-07-05 11:40:33 +020016#include "absl/memory/memory.h"
Per Kjellandere11b7d22019-02-21 07:55:59 +010017#include "api/transport/field_trial_based_config.h"
Erik Språngf93eda12019-01-16 17:10:57 +010018#include "api/video/video_codec_constants.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "api/video/video_timing.h"
Elad Alon4a87e1c2017-10-03 16:11:34 +020020#include "logging/rtc_event_log/events/rtc_event.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
22#include "modules/rtp_rtcp/include/rtp_cvo.h"
23#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
24#include "modules/rtp_rtcp/include/rtp_header_parser.h"
Erik Språngaa59eca2019-07-24 14:52:55 +020025#include "modules/rtp_rtcp/include/rtp_packet_sender.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
27#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
28#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
philipelb3e42a42018-09-13 10:57:14 +020029#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
30#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
32#include "modules/rtp_rtcp/source/rtp_packet_received.h"
33#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "modules/rtp_rtcp/source/rtp_sender_video.h"
35#include "modules/rtp_rtcp/source/rtp_utility.h"
36#include "rtc_base/arraysize.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "rtc_base/rate_limiter.h"
38#include "test/field_trial.h"
39#include "test/gmock.h"
40#include "test/gtest.h"
41#include "test/mock_transport.h"
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000042
43namespace webrtc {
44
andrew@webrtc.org8a442592011-12-16 21:24:30 +000045namespace {
Elad Alond8d32482019-02-18 23:45:57 +010046enum : int { // The first valid value is 1.
47 kAbsoluteSendTimeExtensionId = 1,
48 kAudioLevelExtensionId,
Elad Alonccb9b752019-02-19 13:01:31 +010049 kGenericDescriptorId00,
50 kGenericDescriptorId01,
Elad Alond8d32482019-02-18 23:45:57 +010051 kMidExtensionId,
52 kRepairedRidExtensionId,
53 kRidExtensionId,
54 kTransmissionTimeOffsetExtensionId,
55 kTransportSequenceNumberExtensionId,
56 kVideoRotationExtensionId,
57 kVideoTimingExtensionId,
58};
59
andrew@webrtc.org8a442592011-12-16 21:24:30 +000060const int kPayload = 100;
Shao Changbine62202f2015-04-21 20:24:50 +080061const int kRtxPayload = 98;
andrew@webrtc.org8a442592011-12-16 21:24:30 +000062const uint32_t kTimestamp = 10;
63const uint16_t kSeqNum = 33;
brandtr9dfff292016-11-14 05:14:50 -080064const uint32_t kSsrc = 725242;
Erik Språng9c771c22019-06-17 16:31:53 +020065const uint32_t kRtxSsrc = 12345;
66const uint32_t kFlexFecSsrc = 45678;
sprang@webrtc.org30933902015-03-17 14:33:12 +000067const uint16_t kTransportSequenceNumber = 0xaabbu;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +000068const uint64_t kStartTime = 123456789;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +000069const size_t kMaxPaddingSize = 224u;
Stefan Holmera246cfb2016-08-23 17:51:42 +020070const uint8_t kPayloadData[] = {47, 11, 32, 93, 89};
spranga8ae6f22017-09-04 07:23:56 -070071const int64_t kDefaultExpectedRetransmissionTimeMs = 125;
Amit Hilbuch77938e62018-12-21 09:23:38 -080072const char kNoRid[] = "";
73const char kNoMid[] = "";
andrew@webrtc.org8a442592011-12-16 21:24:30 +000074
Danil Chapovalov5e57b172016-09-02 19:15:59 +020075using ::testing::_;
Erik Språng30a276b2019-04-23 12:00:11 +020076using ::testing::AllOf;
Erik Språng214f5432019-06-20 15:09:58 +020077using ::testing::AtLeast;
78using ::testing::DoAll;
philipelb3e42a42018-09-13 10:57:14 +020079using ::testing::ElementsAre;
Danil Chapovalov5e57b172016-09-02 19:15:59 +020080using ::testing::ElementsAreArray;
Erik Språng30a276b2019-04-23 12:00:11 +020081using ::testing::Field;
Erik Språng478cb462019-06-26 15:49:27 +020082using ::testing::Gt;
sprang168794c2017-07-06 04:38:06 -070083using ::testing::Invoke;
Erik Språng9c771c22019-06-17 16:31:53 +020084using ::testing::NiceMock;
Erik Språng478cb462019-06-26 15:49:27 +020085using ::testing::Pointee;
86using ::testing::Property;
Erik Språng214f5432019-06-20 15:09:58 +020087using ::testing::Return;
88using ::testing::SaveArg;
Danil Chapovalov84ffb352018-09-25 18:59:09 +020089using ::testing::SizeIs;
Erik Språng9c771c22019-06-17 16:31:53 +020090using ::testing::StrictMock;
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +000091
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +000092uint64_t ConvertMsToAbsSendTime(int64_t time_ms) {
Stefan Holmer0a87ffc2015-10-21 13:41:48 +020093 return (((time_ms << 18) + 500) / 1000) & 0x00ffffff;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +000094}
95
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +000096class LoopbackTransportTest : public webrtc::Transport {
97 public:
Petter Strandmark26bc6692018-05-29 08:43:35 +020098 LoopbackTransportTest() : total_bytes_sent_(0) {
danilchap12ba1862016-10-26 02:41:55 -070099 receivers_extensions_.Register(kRtpExtensionTransmissionTimeOffset,
100 kTransmissionTimeOffsetExtensionId);
101 receivers_extensions_.Register(kRtpExtensionAbsoluteSendTime,
102 kAbsoluteSendTimeExtensionId);
103 receivers_extensions_.Register(kRtpExtensionTransportSequenceNumber,
104 kTransportSequenceNumberExtensionId);
105 receivers_extensions_.Register(kRtpExtensionVideoRotation,
106 kVideoRotationExtensionId);
107 receivers_extensions_.Register(kRtpExtensionAudioLevel,
108 kAudioLevelExtensionId);
ilnik04f4d122017-06-19 07:18:55 -0700109 receivers_extensions_.Register(kRtpExtensionVideoTiming,
110 kVideoTimingExtensionId);
Steve Anton296a0ce2018-03-22 15:17:27 -0700111 receivers_extensions_.Register(kRtpExtensionMid, kMidExtensionId);
Elad Alonccb9b752019-02-19 13:01:31 +0100112 receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor00,
113 kGenericDescriptorId00);
114 receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor01,
115 kGenericDescriptorId01);
Amit Hilbuch77938e62018-12-21 09:23:38 -0800116 receivers_extensions_.Register(kRtpExtensionRtpStreamId, kRidExtensionId);
117 receivers_extensions_.Register(kRtpExtensionRepairedRtpStreamId,
118 kRepairedRidExtensionId);
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000119 }
danilchap12ba1862016-10-26 02:41:55 -0700120
stefan1d8a5062015-10-02 03:39:33 -0700121 bool SendRtp(const uint8_t* data,
122 size_t len,
123 const PacketOptions& options) override {
Petter Strandmark26bc6692018-05-29 08:43:35 +0200124 last_options_ = options;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000125 total_bytes_sent_ += len;
danilchap12ba1862016-10-26 02:41:55 -0700126 sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
127 EXPECT_TRUE(sent_packets_.back().Parse(data, len));
pbos2d566682015-09-28 09:59:31 -0700128 return true;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000129 }
danilchap162abd32015-12-10 02:39:40 -0800130 bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
danilchap12ba1862016-10-26 02:41:55 -0700131 const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
132 int packets_sent() { return sent_packets_.size(); }
133
pbos@webrtc.org72491b92014-07-10 16:24:54 +0000134 size_t total_bytes_sent_;
Petter Strandmark26bc6692018-05-29 08:43:35 +0200135 PacketOptions last_options_;
danilchap12ba1862016-10-26 02:41:55 -0700136 std::vector<RtpPacketReceived> sent_packets_;
137
138 private:
139 RtpHeaderExtensionMap receivers_extensions_;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000140};
141
Elad Alon4a87e1c2017-10-03 16:11:34 +0200142MATCHER_P(SameRtcEventTypeAs, value, "") {
143 return value == arg->GetType();
144}
145
Erik Språngf6468d22019-07-05 16:53:43 +0200146struct TestConfig {
Erik Språngf5815fa2019-08-21 14:27:31 +0200147 explicit TestConfig(bool with_overhead) : with_overhead(with_overhead) {}
Erik Språngf6468d22019-07-05 16:53:43 +0200148 bool with_overhead = false;
Erik Språngf6468d22019-07-05 16:53:43 +0200149};
150
151std::string ToFieldTrialString(TestConfig config) {
152 std::string field_trials;
153 if (config.with_overhead) {
154 field_trials += "WebRTC-SendSideBwe-WithOverhead/Enabled/";
155 }
Erik Språngf6468d22019-07-05 16:53:43 +0200156 return field_trials;
157}
158
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000159} // namespace
160
Erik Språngaa59eca2019-07-24 14:52:55 +0200161class MockRtpPacketPacer : public RtpPacketSender {
sprangebbf8a82015-09-21 15:11:14 -0700162 public:
Erik Språng59b86542019-06-23 18:24:46 +0200163 MockRtpPacketPacer() {}
164 virtual ~MockRtpPacketPacer() {}
165
166 MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend>));
sprangebbf8a82015-09-21 15:11:14 -0700167
Erik Språngaa59eca2019-07-24 14:52:55 +0200168 MOCK_METHOD2(CreateProbeCluster, void(int bitrate_bps, int cluster_id));
169
170 MOCK_METHOD0(Pause, void());
171 MOCK_METHOD0(Resume, void());
172 MOCK_METHOD1(SetCongestionWindow,
173 void(absl::optional<int64_t> congestion_window_bytes));
174 MOCK_METHOD1(UpdateOutstandingData, void(int64_t outstanding_bytes));
175 MOCK_METHOD1(SetAccountForAudioPackets, void(bool account_for_audio));
sprangebbf8a82015-09-21 15:11:14 -0700176};
177
Stefan Holmerf5dca482016-01-27 12:58:51 +0100178class MockTransportSequenceNumberAllocator
179 : public TransportSequenceNumberAllocator {
180 public:
181 MOCK_METHOD0(AllocateSequenceNumber, uint16_t());
182};
183
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200184class MockSendSideDelayObserver : public SendSideDelayObserver {
185 public:
Henrik Boström9fe18342019-05-16 18:38:20 +0200186 MOCK_METHOD4(SendSideDelayUpdated, void(int, int, uint64_t, uint32_t));
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200187};
188
asapersson35151f32016-05-02 23:44:01 -0700189class MockSendPacketObserver : public SendPacketObserver {
190 public:
191 MOCK_METHOD3(OnSendPacket, void(uint16_t, int64_t, uint32_t));
192};
193
Stefan Holmera246cfb2016-08-23 17:51:42 +0200194class MockTransportFeedbackObserver : public TransportFeedbackObserver {
195 public:
Erik Språng30a276b2019-04-23 12:00:11 +0200196 MOCK_METHOD1(OnAddPacket, void(const RtpPacketSendInfo&));
Stefan Holmera246cfb2016-08-23 17:51:42 +0200197 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -0800198 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
Stefan Holmera246cfb2016-08-23 17:51:42 +0200199};
200
minyue3a407ee2017-04-03 01:10:33 -0700201class MockOverheadObserver : public OverheadObserver {
202 public:
203 MOCK_METHOD1(OnOverheadChanged, void(size_t overhead_bytes_per_packet));
204};
205
Erik Språngf6468d22019-07-05 16:53:43 +0200206class RtpSenderTest : public ::testing::TestWithParam<TestConfig> {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000207 protected:
208 RtpSenderTest()
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000209 : fake_clock_(kStartTime),
terelius429c3452016-01-21 05:42:04 -0800210 mock_rtc_event_log_(),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000211 mock_paced_sender_(),
sprangcd349d92016-07-13 09:11:28 -0700212 retransmission_rate_limiter_(&fake_clock_, 1000),
Erik Språng4580ca22019-07-04 10:38:43 +0200213 flexfec_sender_(0,
214 kFlexFecSsrc,
215 kSsrc,
216 "",
217 std::vector<RtpExtension>(),
218 std::vector<RtpExtensionSize>(),
219 nullptr,
220 &fake_clock_),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000221 rtp_sender_(),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000222 transport_(),
minyue3a407ee2017-04-03 01:10:33 -0700223 kMarkerBit(true),
Erik Språngf6468d22019-07-05 16:53:43 +0200224 field_trials_(ToFieldTrialString(GetParam())) {}
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +0000225
Erik Språng7b52f102018-02-07 14:37:37 +0100226 void SetUp() override { SetUpRtpSender(true, false); }
Peter Boströme23e7372015-10-08 11:44:14 +0200227
Erik Språng7b52f102018-02-07 14:37:37 +0100228 void SetUpRtpSender(bool pacer, bool populate_network2) {
Erik Språng4580ca22019-07-04 10:38:43 +0200229 RtpRtcp::Configuration config;
230 config.clock = &fake_clock_;
231 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200232 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200233 config.rtx_send_ssrc = kRtxSsrc;
234 config.flexfec_sender = &flexfec_sender_;
235 config.transport_sequence_number_allocator = &seq_num_allocator_;
236 config.event_log = &mock_rtc_event_log_;
237 config.send_packet_observer = &send_packet_observer_;
238 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
239 config.paced_sender = pacer ? &mock_paced_sender_ : nullptr;
240 config.populate_network2_timestamp = populate_network2;
241 rtp_sender_.reset(new RTPSender(config));
brandtr9dfff292016-11-14 05:14:50 -0800242 rtp_sender_->SetSequenceNumber(kSeqNum);
danilchap71fead22016-08-18 02:01:49 -0700243 rtp_sender_->SetTimestampOffset(0);
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +0000244 }
245
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000246 SimulatedClock fake_clock_;
Erik Språng9c771c22019-06-17 16:31:53 +0200247 NiceMock<MockRtcEventLog> mock_rtc_event_log_;
Erik Språng59b86542019-06-23 18:24:46 +0200248 MockRtpPacketPacer mock_paced_sender_;
Erik Språng9c771c22019-06-17 16:31:53 +0200249 StrictMock<MockTransportSequenceNumberAllocator> seq_num_allocator_;
250 StrictMock<MockSendPacketObserver> send_packet_observer_;
251 StrictMock<MockTransportFeedbackObserver> feedback_observer_;
sprangcd349d92016-07-13 09:11:28 -0700252 RateLimiter retransmission_rate_limiter_;
Erik Språng4580ca22019-07-04 10:38:43 +0200253 FlexfecSender flexfec_sender_;
kwiberg84be5112016-04-27 01:19:58 -0700254 std::unique_ptr<RTPSender> rtp_sender_;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000255 LoopbackTransportTest transport_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000256 const bool kMarkerBit;
minyue3a407ee2017-04-03 01:10:33 -0700257 test::ScopedFieldTrials field_trials_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000258
danilchapb6f1fb52016-10-19 06:11:39 -0700259 std::unique_ptr<RtpPacketToSend> BuildRtpPacket(int payload_type,
260 bool marker_bit,
261 uint32_t timestamp,
262 int64_t capture_time_ms) {
263 auto packet = rtp_sender_->AllocatePacket();
264 packet->SetPayloadType(payload_type);
Erik Språng60ffc312019-07-30 22:03:49 +0200265 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
danilchapb6f1fb52016-10-19 06:11:39 -0700266 packet->SetMarker(marker_bit);
267 packet->SetTimestamp(timestamp);
268 packet->set_capture_time_ms(capture_time_ms);
269 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
270 return packet;
271 }
272
Erik Språngf6468d22019-07-05 16:53:43 +0200273 std::unique_ptr<RtpPacketToSend> SendPacket(int64_t capture_time_ms,
274 int payload_length) {
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000275 uint32_t timestamp = capture_time_ms * 90;
danilchapb6f1fb52016-10-19 06:11:39 -0700276 auto packet =
277 BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
278 packet->AllocatePayload(payload_length);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000279
280 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +0200281 EXPECT_TRUE(rtp_sender_->SendToNetwork(
Erik Språng60ffc312019-07-30 22:03:49 +0200282 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
Erik Språngf6468d22019-07-05 16:53:43 +0200283 return packet;
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000284 }
asapersson35151f32016-05-02 23:44:01 -0700285
Erik Språngf6468d22019-07-05 16:53:43 +0200286 std::unique_ptr<RtpPacketToSend> SendGenericPacket() {
asapersson35151f32016-05-02 23:44:01 -0700287 const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
Erik Språngf6468d22019-07-05 16:53:43 +0200288 return SendPacket(kCaptureTimeMs, sizeof(kPayloadData));
asapersson35151f32016-05-02 23:44:01 -0700289 }
Steve Anton2bac7da2019-07-21 15:04:21 -0400290
Erik Språng4208a132019-08-26 08:58:45 +0200291 size_t GenerateAndSendPadding(size_t target_size_bytes) {
292 size_t generated_bytes = 0;
293 for (auto& packet : rtp_sender_->GeneratePadding(target_size_bytes)) {
294 generated_bytes += packet->payload_size() + packet->padding_size();
295 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
296 }
297 return generated_bytes;
298 }
299
Steve Anton2bac7da2019-07-21 15:04:21 -0400300 // The following are helpers for configuring the RTPSender. They must be
301 // called before sending any packets.
302
303 // Enable the retransmission stream with sizable packet storage.
304 void EnableRtx() {
305 // RTX needs to be able to read the source packets from the packet store.
306 // Pick a number of packets to store big enough for any unit test.
307 constexpr uint16_t kNumberOfPacketsToStore = 100;
308 rtp_sender_->SetStorePacketsStatus(true, kNumberOfPacketsToStore);
309 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
310 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
311 }
312
313 // Enable sending of the MID header extension for both the primary SSRC and
314 // the RTX SSRC.
315 void EnableMidSending(const std::string& mid) {
316 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionMid, kMidExtensionId);
317 rtp_sender_->SetMid(mid);
318 }
319
320 // Enable sending of the RSID header extension for the primary SSRC and the
321 // RRSID header extension for the RTX SSRC.
322 void EnableRidSending(const std::string& rid) {
323 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
324 kRidExtensionId);
325 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRepairedRtpStreamId,
326 kRepairedRidExtensionId);
327 rtp_sender_->SetRid(rid);
328 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000329};
330
Peter Boströme23e7372015-10-08 11:44:14 +0200331// TODO(pbos): Move tests over from WithoutPacer to RtpSenderTest as this is our
332// default code path.
333class RtpSenderTestWithoutPacer : public RtpSenderTest {
334 public:
Erik Språng7b52f102018-02-07 14:37:37 +0100335 void SetUp() override { SetUpRtpSender(false, false); }
Peter Boströme23e7372015-10-08 11:44:14 +0200336};
337
minyue3a407ee2017-04-03 01:10:33 -0700338TEST_P(RtpSenderTestWithoutPacer, AllocatePacketSetCsrc) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200339 // Configure rtp_sender with csrc.
340 std::vector<uint32_t> csrcs;
341 csrcs.push_back(0x23456789);
342 rtp_sender_->SetCsrcs(csrcs);
343
344 auto packet = rtp_sender_->AllocatePacket();
345
346 ASSERT_TRUE(packet);
347 EXPECT_EQ(rtp_sender_->SSRC(), packet->Ssrc());
348 EXPECT_EQ(csrcs, packet->Csrcs());
349}
350
minyue3a407ee2017-04-03 01:10:33 -0700351TEST_P(RtpSenderTestWithoutPacer, AllocatePacketReserveExtensions) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200352 // Configure rtp_sender with extensions.
353 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
354 kRtpExtensionTransmissionTimeOffset,
355 kTransmissionTimeOffsetExtensionId));
356 ASSERT_EQ(
357 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
358 kAbsoluteSendTimeExtensionId));
359 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
360 kAudioLevelExtensionId));
361 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
362 kRtpExtensionTransportSequenceNumber,
363 kTransportSequenceNumberExtensionId));
364 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
365 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
366
367 auto packet = rtp_sender_->AllocatePacket();
368
369 ASSERT_TRUE(packet);
370 // Preallocate BWE extensions RtpSender set itself.
371 EXPECT_TRUE(packet->HasExtension<TransmissionOffset>());
372 EXPECT_TRUE(packet->HasExtension<AbsoluteSendTime>());
373 EXPECT_TRUE(packet->HasExtension<TransportSequenceNumber>());
374 // Do not allocate media specific extensions.
375 EXPECT_FALSE(packet->HasExtension<AudioLevel>());
376 EXPECT_FALSE(packet->HasExtension<VideoOrientation>());
377}
378
minyue3a407ee2017-04-03 01:10:33 -0700379TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberAdvanceSequenceNumber) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200380 auto packet = rtp_sender_->AllocatePacket();
381 ASSERT_TRUE(packet);
382 const uint16_t sequence_number = rtp_sender_->SequenceNumber();
383
384 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
385
386 EXPECT_EQ(sequence_number, packet->SequenceNumber());
387 EXPECT_EQ(sequence_number + 1, rtp_sender_->SequenceNumber());
388}
389
minyue3a407ee2017-04-03 01:10:33 -0700390TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberFailsOnNotSending) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200391 auto packet = rtp_sender_->AllocatePacket();
392 ASSERT_TRUE(packet);
393
394 rtp_sender_->SetSendingMediaStatus(false);
395 EXPECT_FALSE(rtp_sender_->AssignSequenceNumber(packet.get()));
396}
397
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100398TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberMayAllowPaddingOnVideo) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200399 constexpr size_t kPaddingSize = 100;
400 auto packet = rtp_sender_->AllocatePacket();
401 ASSERT_TRUE(packet);
402
Erik Språng4208a132019-08-26 08:58:45 +0200403 ASSERT_TRUE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200404 packet->SetMarker(false);
405 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100406 // Packet without marker bit doesn't allow padding on video stream.
Erik Språng4208a132019-08-26 08:58:45 +0200407 ASSERT_TRUE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200408
409 packet->SetMarker(true);
410 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
411 // Packet with marker bit allows send padding.
Erik Språng4208a132019-08-26 08:58:45 +0200412 ASSERT_FALSE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200413}
414
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100415TEST_P(RtpSenderTest, AssignSequenceNumberAllowsPaddingOnAudio) {
416 MockTransport transport;
Erik Språng4580ca22019-07-04 10:38:43 +0200417 RtpRtcp::Configuration config;
418 config.audio = true;
419 config.clock = &fake_clock_;
420 config.outgoing_transport = &transport;
421 config.paced_sender = &mock_paced_sender_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200422 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200423 config.event_log = &mock_rtc_event_log_;
424 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
425 rtp_sender_ = absl::make_unique<RTPSender>(config);
426
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100427 rtp_sender_->SetTimestampOffset(0);
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100428
429 std::unique_ptr<RtpPacketToSend> audio_packet = rtp_sender_->AllocatePacket();
430 // Padding on audio stream allowed regardless of marker in the last packet.
431 audio_packet->SetMarker(false);
432 audio_packet->SetPayloadType(kPayload);
433 rtp_sender_->AssignSequenceNumber(audio_packet.get());
434
435 const size_t kPaddingSize = 59;
436 EXPECT_CALL(transport, SendRtp(_, kPaddingSize + kRtpHeaderSize, _))
Erik Språng214f5432019-06-20 15:09:58 +0200437 .WillOnce(Return(true));
Erik Språng4208a132019-08-26 08:58:45 +0200438 EXPECT_EQ(kPaddingSize, GenerateAndSendPadding(kPaddingSize));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100439
440 // Requested padding size is too small, will send a larger one.
441 const size_t kMinPaddingSize = 50;
442 EXPECT_CALL(transport, SendRtp(_, kMinPaddingSize + kRtpHeaderSize, _))
Erik Språng214f5432019-06-20 15:09:58 +0200443 .WillOnce(Return(true));
Erik Språng4208a132019-08-26 08:58:45 +0200444 EXPECT_EQ(kMinPaddingSize, GenerateAndSendPadding(kMinPaddingSize - 5));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100445}
446
minyue3a407ee2017-04-03 01:10:33 -0700447TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberSetPaddingTimestamps) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200448 constexpr size_t kPaddingSize = 100;
449 auto packet = rtp_sender_->AllocatePacket();
450 ASSERT_TRUE(packet);
451 packet->SetMarker(true);
452 packet->SetTimestamp(kTimestamp);
453
454 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
Erik Språng4208a132019-08-26 08:58:45 +0200455 auto padding_packets = rtp_sender_->GeneratePadding(kPaddingSize);
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200456
Erik Språng4208a132019-08-26 08:58:45 +0200457 ASSERT_EQ(1u, padding_packets.size());
danilchap12ba1862016-10-26 02:41:55 -0700458 // Verify padding packet timestamp.
Erik Språng4208a132019-08-26 08:58:45 +0200459 EXPECT_EQ(kTimestamp, padding_packets[0]->Timestamp());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200460}
461
minyue3a407ee2017-04-03 01:10:33 -0700462TEST_P(RtpSenderTestWithoutPacer,
463 TransportFeedbackObserverGetsCorrectByteCount) {
464 constexpr int kRtpOverheadBytesPerPacket = 12 + 8;
Erik Språng9c771c22019-06-17 16:31:53 +0200465 NiceMock<MockOverheadObserver> mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +0200466
467 RtpRtcp::Configuration config;
468 config.clock = &fake_clock_;
469 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200470 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200471 config.transport_sequence_number_allocator = &seq_num_allocator_;
472 config.transport_feedback_callback = &feedback_observer_;
473 config.event_log = &mock_rtc_event_log_;
474 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
475 config.overhead_observer = &mock_overhead_observer;
476 rtp_sender_ = absl::make_unique<RTPSender>(config);
477
minyue3a407ee2017-04-03 01:10:33 -0700478 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
479 kRtpExtensionTransportSequenceNumber,
480 kTransportSequenceNumberExtensionId));
481 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200482 .WillOnce(Return(kTransportSequenceNumber));
minyue3a407ee2017-04-03 01:10:33 -0700483
484 const size_t expected_bytes =
Erik Språngf6468d22019-07-05 16:53:43 +0200485 GetParam().with_overhead
486 ? sizeof(kPayloadData) + kRtpOverheadBytesPerPacket
487 : sizeof(kPayloadData);
minyue3a407ee2017-04-03 01:10:33 -0700488
489 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200490 OnAddPacket(AllOf(
491 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
492 Field(&RtpPacketSendInfo::transport_sequence_number,
493 kTransportSequenceNumber),
494 Field(&RtpPacketSendInfo::rtp_sequence_number,
495 rtp_sender_->SequenceNumber()),
496 Field(&RtpPacketSendInfo::length, expected_bytes),
497 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
minyue3a407ee2017-04-03 01:10:33 -0700498 .Times(1);
499 EXPECT_CALL(mock_overhead_observer,
500 OnOverheadChanged(kRtpOverheadBytesPerPacket))
501 .Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100502 SendGenericPacket();
minyue3a407ee2017-04-03 01:10:33 -0700503}
504
505TEST_P(RtpSenderTestWithoutPacer, SendsPacketsWithTransportSequenceNumber) {
Erik Språng4580ca22019-07-04 10:38:43 +0200506 RtpRtcp::Configuration config;
507 config.clock = &fake_clock_;
508 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200509 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200510 config.transport_sequence_number_allocator = &seq_num_allocator_;
511 config.transport_feedback_callback = &feedback_observer_;
512 config.event_log = &mock_rtc_event_log_;
513 config.send_packet_observer = &send_packet_observer_;
514 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
515 rtp_sender_ = absl::make_unique<RTPSender>(config);
516
Stefan Holmerf5dca482016-01-27 12:58:51 +0100517 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
518 kRtpExtensionTransportSequenceNumber,
519 kTransportSequenceNumberExtensionId));
520
Stefan Holmerf5dca482016-01-27 12:58:51 +0100521 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200522 .WillOnce(Return(kTransportSequenceNumber));
asapersson35151f32016-05-02 23:44:01 -0700523 EXPECT_CALL(send_packet_observer_,
524 OnSendPacket(kTransportSequenceNumber, _, _))
525 .Times(1);
minyue3a407ee2017-04-03 01:10:33 -0700526
527 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200528 OnAddPacket(AllOf(
529 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
530 Field(&RtpPacketSendInfo::transport_sequence_number,
531 kTransportSequenceNumber),
532 Field(&RtpPacketSendInfo::rtp_sequence_number,
533 rtp_sender_->SequenceNumber()),
534 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
Stefan Holmera246cfb2016-08-23 17:51:42 +0200535 .Times(1);
asapersson35151f32016-05-02 23:44:01 -0700536
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100537 SendGenericPacket();
Stefan Holmerf5dca482016-01-27 12:58:51 +0100538
danilchap12ba1862016-10-26 02:41:55 -0700539 const auto& packet = transport_.last_sent_packet();
540 uint16_t transport_seq_no;
541 ASSERT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
542 EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200543 EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200544 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200545}
546
547TEST_P(RtpSenderTestWithoutPacer, PacketOptionsNoRetransmission) {
Erik Språng4580ca22019-07-04 10:38:43 +0200548 RtpRtcp::Configuration config;
549 config.clock = &fake_clock_;
550 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200551 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200552 config.transport_sequence_number_allocator = &seq_num_allocator_;
553 config.transport_feedback_callback = &feedback_observer_;
554 config.event_log = &mock_rtc_event_log_;
555 config.send_packet_observer = &send_packet_observer_;
556 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
557 rtp_sender_ = absl::make_unique<RTPSender>(config);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200558
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100559 SendGenericPacket();
Petter Strandmark26bc6692018-05-29 08:43:35 +0200560
561 EXPECT_FALSE(transport_.last_options_.is_retransmit);
Stefan Holmerf5dca482016-01-27 12:58:51 +0100562}
563
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200564TEST_P(RtpSenderTestWithoutPacer,
565 SetsIncludedInFeedbackWhenTransportSequenceNumberExtensionIsRegistered) {
566 SetUpRtpSender(false, false);
567 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
568 kTransportSequenceNumberExtensionId);
569 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200570 .WillOnce(Return(kTransportSequenceNumber));
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200571 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100572 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200573 EXPECT_TRUE(transport_.last_options_.included_in_feedback);
574}
575
576TEST_P(
577 RtpSenderTestWithoutPacer,
578 SetsIncludedInAllocationWhenTransportSequenceNumberExtensionIsRegistered) {
579 SetUpRtpSender(false, false);
580 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
581 kTransportSequenceNumberExtensionId);
582 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200583 .WillOnce(Return(kTransportSequenceNumber));
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200584 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100585 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200586 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
587}
588
589TEST_P(RtpSenderTestWithoutPacer,
590 SetsIncludedInAllocationWhenForcedAsPartOfAllocation) {
591 SetUpRtpSender(false, false);
592 rtp_sender_->SetAsPartOfAllocation(true);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100593 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200594 EXPECT_FALSE(transport_.last_options_.included_in_feedback);
595 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
596}
597
598TEST_P(RtpSenderTestWithoutPacer, DoesnSetIncludedInAllocationByDefault) {
599 SetUpRtpSender(false, false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100600 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200601 EXPECT_FALSE(transport_.last_options_.included_in_feedback);
602 EXPECT_FALSE(transport_.last_options_.included_in_allocation);
stefana23fc622016-07-28 07:56:38 -0700603}
asapersson35151f32016-05-02 23:44:01 -0700604
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200605TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
Erik Språng9c771c22019-06-17 16:31:53 +0200606 StrictMock<MockSendSideDelayObserver> send_side_delay_observer_;
Erik Språng4580ca22019-07-04 10:38:43 +0200607
608 RtpRtcp::Configuration config;
609 config.clock = &fake_clock_;
610 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200611 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200612 config.send_side_delay_observer = &send_side_delay_observer_;
613 config.event_log = &mock_rtc_event_log_;
614 rtp_sender_ = absl::make_unique<RTPSender>(config);
615
Niels Möller5fe95102019-03-04 16:49:25 +0100616 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +0100617 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +0200618 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +0100619 FieldTrialBasedConfig());
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200620
621 const uint8_t kPayloadType = 127;
Niels Möller8a40edd2019-01-24 18:04:44 +0100622 const char payload_name[] = "GENERIC";
Niels Möller59ab1cf2019-02-06 22:48:11 +0100623
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +0200624 rtp_sender_video.RegisterPayloadType(kPayloadType, payload_name,
625 /*raw_payload=*/false);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100626
627 const uint32_t kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200628 RTPVideoHeader video_header;
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200629
Henrik Boström9fe18342019-05-16 18:38:20 +0200630 // Send packet with 10 ms send-side delay. The average, max and total should
631 // be 10 ms.
632 EXPECT_CALL(send_side_delay_observer_,
633 SendSideDelayUpdated(10, 10, 10, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200634 .Times(1);
635 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
636 fake_clock_.AdvanceTimeMilliseconds(10);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100637 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100638 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200639 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100640 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200641 kDefaultExpectedRetransmissionTimeMs));
642
Henrik Boström9fe18342019-05-16 18:38:20 +0200643 // Send another packet with 20 ms delay. The average, max and total should be
644 // 15, 20 and 30 ms respectively.
645 EXPECT_CALL(send_side_delay_observer_,
646 SendSideDelayUpdated(15, 20, 30, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200647 .Times(1);
648 fake_clock_.AdvanceTimeMilliseconds(10);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100649 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100650 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200651 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100652 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200653 kDefaultExpectedRetransmissionTimeMs));
654
655 // Send another packet at the same time, which replaces the last packet.
656 // Since this packet has 0 ms delay, the average is now 5 ms and max is 10 ms.
Henrik Boström9fe18342019-05-16 18:38:20 +0200657 // The total counter stays the same though.
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200658 // TODO(terelius): Is is not clear that this is the right behavior.
Henrik Boström9fe18342019-05-16 18:38:20 +0200659 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(5, 10, 30, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200660 .Times(1);
661 capture_time_ms = fake_clock_.TimeInMilliseconds();
Niels Möller59ab1cf2019-02-06 22:48:11 +0100662 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100663 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200664 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100665 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200666 kDefaultExpectedRetransmissionTimeMs));
667
668 // Send a packet 1 second later. The earlier packets should have timed
Henrik Boström9fe18342019-05-16 18:38:20 +0200669 // out, so both max and average should be the delay of this packet. The total
670 // keeps increasing.
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200671 fake_clock_.AdvanceTimeMilliseconds(1000);
672 capture_time_ms = fake_clock_.TimeInMilliseconds();
673 fake_clock_.AdvanceTimeMilliseconds(1);
Henrik Boström9fe18342019-05-16 18:38:20 +0200674 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(1, 1, 31, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200675 .Times(1);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100676 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100677 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200678 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100679 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200680 kDefaultExpectedRetransmissionTimeMs));
681}
682
minyue3a407ee2017-04-03 01:10:33 -0700683TEST_P(RtpSenderTestWithoutPacer, OnSendPacketUpdated) {
stefana23fc622016-07-28 07:56:38 -0700684 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
685 kRtpExtensionTransportSequenceNumber,
686 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -0700687 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200688 .WillOnce(Return(kTransportSequenceNumber));
asapersson35151f32016-05-02 23:44:01 -0700689 EXPECT_CALL(send_packet_observer_,
690 OnSendPacket(kTransportSequenceNumber, _, _))
691 .Times(1);
692
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100693 SendGenericPacket();
asapersson35151f32016-05-02 23:44:01 -0700694}
695
minyue3a407ee2017-04-03 01:10:33 -0700696TEST_P(RtpSenderTest, SendsPacketsWithTransportSequenceNumber) {
Erik Språng4580ca22019-07-04 10:38:43 +0200697 RtpRtcp::Configuration config;
698 config.clock = &fake_clock_;
699 config.outgoing_transport = &transport_;
700 config.paced_sender = &mock_paced_sender_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200701 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200702 config.transport_sequence_number_allocator = &seq_num_allocator_;
703 config.transport_feedback_callback = &feedback_observer_;
704 config.event_log = &mock_rtc_event_log_;
705 config.send_packet_observer = &send_packet_observer_;
706 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
707 rtp_sender_ = absl::make_unique<RTPSender>(config);
708
brandtr9dfff292016-11-14 05:14:50 -0800709 rtp_sender_->SetSequenceNumber(kSeqNum);
Stefan Holmera246cfb2016-08-23 17:51:42 +0200710 rtp_sender_->SetStorePacketsStatus(true, 10);
711 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
712 kRtpExtensionTransportSequenceNumber,
713 kTransportSequenceNumberExtensionId));
714
Stefan Holmera246cfb2016-08-23 17:51:42 +0200715 EXPECT_CALL(send_packet_observer_,
716 OnSendPacket(kTransportSequenceNumber, _, _))
717 .Times(1);
minyue3a407ee2017-04-03 01:10:33 -0700718 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200719 OnAddPacket(AllOf(
720 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
721 Field(&RtpPacketSendInfo::transport_sequence_number,
722 kTransportSequenceNumber),
723 Field(&RtpPacketSendInfo::rtp_sequence_number,
724 rtp_sender_->SequenceNumber()),
725 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
Stefan Holmera246cfb2016-08-23 17:51:42 +0200726 .Times(1);
727
Erik Språngf5815fa2019-08-21 14:27:31 +0200728 EXPECT_CALL(
729 mock_paced_sender_,
730 EnqueuePacket(
731 AllOf(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
732 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
733 auto packet = SendGenericPacket();
734 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
735 // Transport sequence number is set by PacketRouter, before TrySendPacket().
736 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
737 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Stefan Holmera246cfb2016-08-23 17:51:42 +0200738
danilchap12ba1862016-10-26 02:41:55 -0700739 uint16_t transport_seq_no;
Erik Språngf5815fa2019-08-21 14:27:31 +0200740 EXPECT_TRUE(
741 transport_.last_sent_packet().GetExtension<TransportSequenceNumber>(
742 &transport_seq_no));
danilchap12ba1862016-10-26 02:41:55 -0700743 EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200744 EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
Stefan Holmera246cfb2016-08-23 17:51:42 +0200745}
746
Erik Språng7b52f102018-02-07 14:37:37 +0100747TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) {
ilnik04f4d122017-06-19 07:18:55 -0700748 rtp_sender_->SetStorePacketsStatus(true, 10);
749 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
750 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
751 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
752 auto packet = rtp_sender_->AllocatePacket();
753 packet->SetPayloadType(kPayload);
754 packet->SetMarker(true);
755 packet->SetTimestamp(kTimestamp);
756 packet->set_capture_time_ms(capture_time_ms);
ilnik2edc6842017-07-06 03:06:50 -0700757 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
ilnik04f4d122017-06-19 07:18:55 -0700758 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
759 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
760 size_t packet_size = packet->size();
ilnik04f4d122017-06-19 07:18:55 -0700761
762 const int kStoredTimeInMs = 100;
Erik Språngf5815fa2019-08-21 14:27:31 +0200763 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
764 EXPECT_CALL(mock_paced_sender_,
765 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
766 EXPECT_TRUE(rtp_sender_->SendToNetwork(
767 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
768 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
769 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
ilnik04f4d122017-06-19 07:18:55 -0700770 EXPECT_EQ(1, transport_.packets_sent());
771 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
772
danilchapce251812017-09-11 12:24:41 -0700773 VideoSendTiming video_timing;
774 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
775 &video_timing));
776 EXPECT_EQ(kStoredTimeInMs, video_timing.pacer_exit_delta_ms);
Erik Språng7b52f102018-02-07 14:37:37 +0100777}
ilnik04f4d122017-06-19 07:18:55 -0700778
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100779TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithPacer) {
780 SetUpRtpSender(/*pacer=*/true, /*populate_network2=*/true);
Erik Språng7b52f102018-02-07 14:37:37 +0100781 rtp_sender_->SetStorePacketsStatus(true, 10);
782 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
783 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
784 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
785 auto packet = rtp_sender_->AllocatePacket();
786 packet->SetPayloadType(kPayload);
787 packet->SetMarker(true);
788 packet->SetTimestamp(kTimestamp);
789 packet->set_capture_time_ms(capture_time_ms);
790 const uint16_t kPacerExitMs = 1234u;
791 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, kPacerExitMs, 0u, 0u, true};
792 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
793 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
794 size_t packet_size = packet->size();
795
796 const int kStoredTimeInMs = 100;
Erik Språngf6468d22019-07-05 16:53:43 +0200797
Erik Språngf6468d22019-07-05 16:53:43 +0200798 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
799 EXPECT_CALL(
800 mock_paced_sender_,
801 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
802 EXPECT_TRUE(rtp_sender_->SendToNetwork(
Erik Språngf5815fa2019-08-21 14:27:31 +0200803 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
Erik Språngf6468d22019-07-05 16:53:43 +0200804 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
805 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +0200806
Erik Språng7b52f102018-02-07 14:37:37 +0100807 EXPECT_EQ(1, transport_.packets_sent());
ilnik04f4d122017-06-19 07:18:55 -0700808 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
809
Erik Språng7b52f102018-02-07 14:37:37 +0100810 VideoSendTiming video_timing;
danilchapce251812017-09-11 12:24:41 -0700811 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
812 &video_timing));
Erik Språng7b52f102018-02-07 14:37:37 +0100813 EXPECT_EQ(kStoredTimeInMs, video_timing.network2_timestamp_delta_ms);
814 EXPECT_EQ(kPacerExitMs, video_timing.pacer_exit_delta_ms);
ilnik04f4d122017-06-19 07:18:55 -0700815}
816
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100817TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithoutPacer) {
818 SetUpRtpSender(/*pacer=*/false, /*populate_network2=*/true);
819 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
820 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
821 auto packet = rtp_sender_->AllocatePacket();
822 packet->SetMarker(true);
823 packet->set_capture_time_ms(fake_clock_.TimeInMilliseconds());
824 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
825 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
826 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
827
828 const int kPropagateTimeMs = 10;
829 fake_clock_.AdvanceTimeMilliseconds(kPropagateTimeMs);
830
Erik Språngf5815fa2019-08-21 14:27:31 +0200831 EXPECT_TRUE(
832 rtp_sender_->SendToNetwork(std::move(packet), kAllowRetransmission));
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100833
834 EXPECT_EQ(1, transport_.packets_sent());
835 absl::optional<VideoSendTiming> video_timing =
836 transport_.last_sent_packet().GetExtension<VideoTimingExtension>();
837 ASSERT_TRUE(video_timing);
838 EXPECT_EQ(kPropagateTimeMs, video_timing->network2_timestamp_delta_ms);
839}
840
minyue3a407ee2017-04-03 01:10:33 -0700841TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) {
Elad Alon4a87e1c2017-10-03 16:11:34 +0200842 EXPECT_CALL(mock_rtc_event_log_,
843 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000844
pwestin@webrtc.orgc66e8b32012-11-07 17:01:04 +0000845 rtp_sender_->SetStorePacketsStatus(true, 10);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000846 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800847 kRtpExtensionTransmissionTimeOffset,
848 kTransmissionTimeOffsetExtensionId));
849 EXPECT_EQ(
850 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
851 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000852 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700853 auto packet =
854 BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
855 size_t packet_size = packet->size();
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000856
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000857 const int kStoredTimeInMs = 100;
Erik Språngf6468d22019-07-05 16:53:43 +0200858 EXPECT_CALL(
859 mock_paced_sender_,
860 EnqueuePacket(AllOf(
861 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
862 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
863 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
864 EXPECT_TRUE(rtp_sender_->SendToNetwork(
865 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
866 EXPECT_EQ(0, transport_.packets_sent());
867 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
868 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000869
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000870 // Process send bucket. Packet should now be sent.
danilchap12ba1862016-10-26 02:41:55 -0700871 EXPECT_EQ(1, transport_.packets_sent());
872 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
873
stefan@webrtc.orga5cb98c2013-05-29 12:12:51 +0000874 webrtc::RTPHeader rtp_header;
danilchap12ba1862016-10-26 02:41:55 -0700875 transport_.last_sent_packet().GetHeader(&rtp_header);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000876
877 // Verify transmission time offset.
878 EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000879 uint64_t expected_send_time =
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000880 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000881 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000882}
883
minyue3a407ee2017-04-03 01:10:33 -0700884TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) {
Elad Alon4a87e1c2017-10-03 16:11:34 +0200885 EXPECT_CALL(mock_rtc_event_log_,
886 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000887
888 rtp_sender_->SetStorePacketsStatus(true, 10);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000889 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800890 kRtpExtensionTransmissionTimeOffset,
891 kTransmissionTimeOffsetExtensionId));
892 EXPECT_EQ(
893 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
894 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000895 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700896 auto packet =
897 BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
898 size_t packet_size = packet->size();
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000899
900 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +0200901 EXPECT_CALL(
902 mock_paced_sender_,
903 EnqueuePacket(AllOf(
904 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
905 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
906 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
907 packet->set_allow_retransmission(true);
908 EXPECT_TRUE(rtp_sender_->SendToNetwork(
909 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
910 // Immediately process send bucket and send packet.
911 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +0200912
Erik Språng0f4f0552019-05-08 10:15:05 -0700913 EXPECT_EQ(1, transport_.packets_sent());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000914
Erik Språng0f4f0552019-05-08 10:15:05 -0700915 // Retransmit packet.
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000916 const int kStoredTimeInMs = 100;
917 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
918
Erik Språng0f4f0552019-05-08 10:15:05 -0700919 EXPECT_CALL(mock_rtc_event_log_,
920 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
Erik Språngf6468d22019-07-05 16:53:43 +0200921 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
922 packet->set_retransmitted_sequence_number(kSeqNum);
923 EXPECT_CALL(
924 mock_paced_sender_,
925 EnqueuePacket(AllOf(
926 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
927 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
928 EXPECT_EQ(static_cast<int>(packet_size),
929 rtp_sender_->ReSendPacket(kSeqNum));
930 EXPECT_EQ(1, transport_.packets_sent());
931 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000932
933 // Process send bucket. Packet should now be sent.
Erik Språng0f4f0552019-05-08 10:15:05 -0700934 EXPECT_EQ(2, transport_.packets_sent());
danilchap12ba1862016-10-26 02:41:55 -0700935 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000936
stefan@webrtc.orga5cb98c2013-05-29 12:12:51 +0000937 webrtc::RTPHeader rtp_header;
danilchap12ba1862016-10-26 02:41:55 -0700938 transport_.last_sent_packet().GetHeader(&rtp_header);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000939
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000940 // Verify transmission time offset.
941 EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000942 uint64_t expected_send_time =
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000943 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
944 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
945}
946
947// This test sends 1 regular video packet, then 4 padding packets, and then
948// 1 more regular packet.
minyue3a407ee2017-04-03 01:10:33 -0700949TEST_P(RtpSenderTest, SendPadding) {
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000950 // Make all (non-padding) packets go to send queue.
Elad Alon4a87e1c2017-10-03 16:11:34 +0200951 EXPECT_CALL(mock_rtc_event_log_,
952 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
953 .Times(1 + 4 + 1);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000954
955 uint16_t seq_num = kSeqNum;
956 uint32_t timestamp = kTimestamp;
957 rtp_sender_->SetStorePacketsStatus(true, 10);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000958 size_t rtp_header_len = kRtpHeaderSize;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000959 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800960 kRtpExtensionTransmissionTimeOffset,
961 kTransmissionTimeOffsetExtensionId));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000962 rtp_header_len += 4; // 4 bytes extension.
danilchap162abd32015-12-10 02:39:40 -0800963 EXPECT_EQ(
964 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
965 kAbsoluteSendTimeExtensionId));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000966 rtp_header_len += 4; // 4 bytes extension.
967 rtp_header_len += 4; // 4 extra bytes common to all extension headers.
968
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000969 webrtc::RTPHeader rtp_header;
970
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000971 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700972 auto packet =
973 BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
Stefan Holmer586b19b2015-09-18 11:14:31 +0200974 const uint32_t media_packet_timestamp = timestamp;
danilchapb6f1fb52016-10-19 06:11:39 -0700975 size_t packet_size = packet->size();
Erik Språngf6468d22019-07-05 16:53:43 +0200976 int total_packets_sent = 0;
977 const int kStoredTimeInMs = 100;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000978
979 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +0200980 EXPECT_CALL(
981 mock_paced_sender_,
982 EnqueuePacket(AllOf(
983 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
984 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
985 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
986 packet->set_allow_retransmission(true);
987 EXPECT_TRUE(rtp_sender_->SendToNetwork(
988 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
989 EXPECT_EQ(total_packets_sent, transport_.packets_sent());
990 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
991 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
992 ++seq_num;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000993
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000994 // Packet should now be sent. This test doesn't verify the regular video
995 // packet, since it is tested in another test.
danilchap12ba1862016-10-26 02:41:55 -0700996 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000997 timestamp += 90 * kStoredTimeInMs;
998
999 // Send padding 4 times, waiting 50 ms between each.
1000 for (int i = 0; i < 4; ++i) {
1001 const int kPaddingPeriodMs = 50;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001002 const size_t kPaddingBytes = 100;
1003 const size_t kMaxPaddingLength = 224; // Value taken from rtp_sender.cc.
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001004 // Padding will be forced to full packets.
Erik Språng4208a132019-08-26 08:58:45 +02001005 EXPECT_EQ(kMaxPaddingLength, GenerateAndSendPadding(kPaddingBytes));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001006
1007 // Process send bucket. Padding should now be sent.
danilchap12ba1862016-10-26 02:41:55 -07001008 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001009 EXPECT_EQ(kMaxPaddingLength + rtp_header_len,
danilchap12ba1862016-10-26 02:41:55 -07001010 transport_.last_sent_packet().size());
1011
1012 transport_.last_sent_packet().GetHeader(&rtp_header);
pbosbd2522a2015-07-01 05:35:53 -07001013 EXPECT_EQ(kMaxPaddingLength, rtp_header.paddingLength);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001014
Stefan Holmer586b19b2015-09-18 11:14:31 +02001015 // Verify sequence number and timestamp. The timestamp should be the same
1016 // as the last media packet.
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001017 EXPECT_EQ(seq_num++, rtp_header.sequenceNumber);
Stefan Holmer586b19b2015-09-18 11:14:31 +02001018 EXPECT_EQ(media_packet_timestamp, rtp_header.timestamp);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001019 // Verify transmission time offset.
Stefan Holmer586b19b2015-09-18 11:14:31 +02001020 int offset = timestamp - media_packet_timestamp;
1021 EXPECT_EQ(offset, rtp_header.extension.transmissionTimeOffset);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001022 uint64_t expected_send_time =
1023 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
1024 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
1025 fake_clock_.AdvanceTimeMilliseconds(kPaddingPeriodMs);
1026 timestamp += 90 * kPaddingPeriodMs;
1027 }
1028
1029 // Send a regular video packet again.
1030 capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -07001031 packet = BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
1032 packet_size = packet->size();
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001033
Erik Språngf6468d22019-07-05 16:53:43 +02001034 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1035 EXPECT_CALL(
1036 mock_paced_sender_,
1037 EnqueuePacket(AllOf(
1038 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1039 Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
1040 EXPECT_TRUE(rtp_sender_->SendToNetwork(
1041 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
1042 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
terelius5d332ac2016-01-14 14:37:39 -08001043
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001044 // Process send bucket.
danilchap12ba1862016-10-26 02:41:55 -07001045 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
1046 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
1047 transport_.last_sent_packet().GetHeader(&rtp_header);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001048
1049 // Verify sequence number and timestamp.
1050 EXPECT_EQ(seq_num, rtp_header.sequenceNumber);
1051 EXPECT_EQ(timestamp, rtp_header.timestamp);
1052 // Verify transmission time offset. This packet is sent without delay.
1053 EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset);
1054 uint64_t expected_send_time =
1055 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +00001056 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +00001057}
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001058
minyue3a407ee2017-04-03 01:10:33 -07001059TEST_P(RtpSenderTest, OnSendPacketUpdated) {
stefana23fc622016-07-28 07:56:38 -07001060 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1061 kRtpExtensionTransportSequenceNumber,
1062 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -07001063 rtp_sender_->SetStorePacketsStatus(true, 10);
1064
1065 EXPECT_CALL(send_packet_observer_,
1066 OnSendPacket(kTransportSequenceNumber, _, _))
1067 .Times(1);
asapersson35151f32016-05-02 23:44:01 -07001068
Erik Språngf6468d22019-07-05 16:53:43 +02001069 EXPECT_CALL(
1070 mock_paced_sender_,
1071 EnqueuePacket(AllOf(
1072 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1073 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
1074 auto packet = SendGenericPacket();
1075 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1076 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
1077 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001078
danilchap12ba1862016-10-26 02:41:55 -07001079 EXPECT_EQ(1, transport_.packets_sent());
asapersson35151f32016-05-02 23:44:01 -07001080}
1081
minyue3a407ee2017-04-03 01:10:33 -07001082TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
stefana23fc622016-07-28 07:56:38 -07001083 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1084 kRtpExtensionTransportSequenceNumber,
1085 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -07001086 rtp_sender_->SetStorePacketsStatus(true, 10);
1087
1088 EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
asapersson35151f32016-05-02 23:44:01 -07001089
Erik Språngf6468d22019-07-05 16:53:43 +02001090 EXPECT_CALL(
1091 mock_paced_sender_,
1092 EnqueuePacket(AllOf(
1093 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1094 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
1095 auto packet = SendGenericPacket();
1096 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
1097 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
1098 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001099
danilchap12ba1862016-10-26 02:41:55 -07001100 EXPECT_EQ(1, transport_.packets_sent());
Petter Strandmark26bc6692018-05-29 08:43:35 +02001101 EXPECT_TRUE(transport_.last_options_.is_retransmit);
asapersson35151f32016-05-02 23:44:01 -07001102}
1103
minyue3a407ee2017-04-03 01:10:33 -07001104TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
Niels Möller8a40edd2019-01-24 18:04:44 +01001105 const char payload_name[] = "GENERIC";
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001106 const uint8_t payload_type = 127;
Niels Möller5fe95102019-03-04 16:49:25 +01001107 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001108 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001109 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01001110 FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001111 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1112 /*raw_payload=*/false);
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001113 uint8_t payload[] = {47, 11, 32, 93, 89};
1114
1115 // Send keyframe
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001116 RTPVideoHeader video_header;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001117 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001118 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1119 sizeof(payload), nullptr, &video_header,
1120 kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001121
danilchap96c15872016-11-21 01:35:29 -08001122 auto sent_payload = transport_.last_sent_packet().payload();
1123 uint8_t generic_header = sent_payload[0];
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001124 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
1125 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
danilchap96c15872016-11-21 01:35:29 -08001126 EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001127
1128 // Send delta frame
1129 payload[0] = 13;
1130 payload[1] = 42;
1131 payload[4] = 13;
1132
Niels Möller59ab1cf2019-02-06 22:48:11 +01001133 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001134 VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload,
1135 sizeof(payload), nullptr, &video_header,
1136 kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001137
danilchap96c15872016-11-21 01:35:29 -08001138 sent_payload = transport_.last_sent_packet().payload();
1139 generic_header = sent_payload[0];
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001140 EXPECT_FALSE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
1141 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
danilchap96c15872016-11-21 01:35:29 -08001142 EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001143}
1144
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001145TEST_P(RtpSenderTestWithoutPacer, SendRawVideo) {
1146 const char payload_name[] = "VP8";
1147 const uint8_t payload_type = 111;
1148 const uint8_t payload[] = {11, 22, 33, 44, 55};
1149
1150 PlayoutDelayOracle playout_delay_oracle;
1151 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001152 &playout_delay_oracle, nullptr, false, false,
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001153 FieldTrialBasedConfig());
1154 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1155 /*raw_payload=*/true);
1156
1157 // Send a frame.
1158 RTPVideoHeader video_header;
1159 ASSERT_TRUE(rtp_sender_video.SendVideo(
1160 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1161 sizeof(payload), nullptr, &video_header,
1162 kDefaultExpectedRetransmissionTimeMs));
1163
1164 auto sent_payload = transport_.last_sent_packet().payload();
1165 EXPECT_THAT(sent_payload, ElementsAreArray(payload));
1166}
1167
minyue3a407ee2017-04-03 01:10:33 -07001168TEST_P(RtpSenderTest, SendFlexfecPackets) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001169 constexpr uint32_t kTimestamp = 1234;
brandtrdbdb3f12016-11-10 05:04:48 -08001170 constexpr int kMediaPayloadType = 127;
1171 constexpr int kFlexfecPayloadType = 118;
brandtrdbdb3f12016-11-10 05:04:48 -08001172 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001173 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språng4580ca22019-07-04 10:38:43 +02001174 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1175 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001176 nullptr /* rtp_state */, &fake_clock_);
brandtrdbdb3f12016-11-10 05:04:48 -08001177
1178 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001179 RtpRtcp::Configuration config;
1180 config.clock = &fake_clock_;
1181 config.outgoing_transport = &transport_;
1182 config.paced_sender = &mock_paced_sender_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001183 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001184 config.flexfec_sender = &flexfec_sender_;
1185 config.transport_sequence_number_allocator = &seq_num_allocator_;
1186 config.event_log = &mock_rtc_event_log_;
1187 config.send_packet_observer = &send_packet_observer_;
1188 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1189 rtp_sender_ = absl::make_unique<RTPSender>(config);
1190
brandtrdbdb3f12016-11-10 05:04:48 -08001191 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtrdbdb3f12016-11-10 05:04:48 -08001192 rtp_sender_->SetStorePacketsStatus(true, 10);
1193
Niels Möller5fe95102019-03-04 16:49:25 +01001194 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001195 RTPSenderVideo rtp_sender_video(
1196 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1197 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001198 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1199 /*raw_payload=*/false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001200
brandtrdbdb3f12016-11-10 05:04:48 -08001201 // Parameters selected to generate a single FEC packet per media packet.
1202 FecProtectionParams params;
1203 params.fec_rate = 15;
1204 params.max_fec_frames = 1;
1205 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001206 rtp_sender_video.SetFecParameters(params, params);
brandtrdbdb3f12016-11-10 05:04:48 -08001207
brandtr9dfff292016-11-14 05:14:50 -08001208 uint16_t flexfec_seq_num;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001209 RTPVideoHeader video_header;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001210
Erik Språngf6468d22019-07-05 16:53:43 +02001211 std::unique_ptr<RtpPacketToSend> media_packet;
1212 std::unique_ptr<RtpPacketToSend> fec_packet;
1213
1214 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1215 .Times(2)
1216 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) {
1217 if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
1218 EXPECT_EQ(packet->Ssrc(), kSsrc);
1219 EXPECT_EQ(packet->SequenceNumber(), kSeqNum);
1220 media_packet = std::move(packet);
1221 } else {
1222 EXPECT_EQ(packet->packet_type(),
1223 RtpPacketToSend::Type::kForwardErrorCorrection);
1224 EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
1225 fec_packet = std::move(packet);
1226 }
1227 });
1228
1229 EXPECT_TRUE(rtp_sender_video.SendVideo(
1230 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
1231 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1232 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1233 ASSERT_TRUE(media_packet != nullptr);
1234 ASSERT_TRUE(fec_packet != nullptr);
1235
1236 flexfec_seq_num = fec_packet->SequenceNumber();
1237 rtp_sender_->TrySendPacket(media_packet.get(), PacedPacketInfo());
1238 rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001239
brandtr9dfff292016-11-14 05:14:50 -08001240 ASSERT_EQ(2, transport_.packets_sent());
Erik Språngf5815fa2019-08-21 14:27:31 +02001241 const RtpPacketReceived& sent_media_packet = transport_.sent_packets_[0];
1242 EXPECT_EQ(kMediaPayloadType, sent_media_packet.PayloadType());
1243 EXPECT_EQ(kSeqNum, sent_media_packet.SequenceNumber());
1244 EXPECT_EQ(kSsrc, sent_media_packet.Ssrc());
1245 const RtpPacketReceived& sent_flexfec_packet = transport_.sent_packets_[1];
1246 EXPECT_EQ(kFlexfecPayloadType, sent_flexfec_packet.PayloadType());
1247 EXPECT_EQ(flexfec_seq_num, sent_flexfec_packet.SequenceNumber());
1248 EXPECT_EQ(kFlexFecSsrc, sent_flexfec_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001249}
1250
Erik Språngf6468d22019-07-05 16:53:43 +02001251// TODO(ilnik): because of webrtc:7859. Once FEC moved below pacer, this test
1252// should be removed.
1253TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
1254 constexpr uint32_t kTimestamp = 1234;
1255 const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
1256 constexpr int kMediaPayloadType = 127;
1257 constexpr int kFlexfecPayloadType = 118;
1258 const std::vector<RtpExtension> kNoRtpExtensions;
1259 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
1260
1261 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1262 kNoRtpExtensions, kNoRtpExtensionSizes,
1263 nullptr /* rtp_state */, &fake_clock_);
1264
1265 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng630443a2019-07-26 16:44:55 +02001266 RtpRtcp::Configuration config;
1267 config.clock = &fake_clock_;
1268 config.outgoing_transport = &transport_;
1269 config.paced_sender = &mock_paced_sender_;
1270 config.flexfec_sender = &flexfec_sender;
1271 config.transport_sequence_number_allocator = &seq_num_allocator_;
1272 config.event_log = &mock_rtc_event_log_;
1273 config.send_packet_observer = &send_packet_observer_;
1274 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001275 config.local_media_ssrc = kSsrc;
Erik Språng630443a2019-07-26 16:44:55 +02001276 rtp_sender_ = absl::make_unique<RTPSender>(config);
Erik Språngf6468d22019-07-05 16:53:43 +02001277 rtp_sender_->SetSequenceNumber(kSeqNum);
1278 rtp_sender_->SetStorePacketsStatus(true, 10);
1279
1280 PlayoutDelayOracle playout_delay_oracle;
1281 RTPSenderVideo rtp_sender_video(
1282 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1283 nullptr, false, false, FieldTrialBasedConfig());
1284 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1285 /*raw_payload=*/false);
1286
1287 // Need extension to be registered for timing frames to be sent.
1288 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1289 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
1290
1291 // Parameters selected to generate a single FEC packet per media packet.
1292 FecProtectionParams params;
1293 params.fec_rate = 15;
1294 params.max_fec_frames = 1;
1295 params.fec_mask_type = kFecMaskRandom;
1296 rtp_sender_video.SetFecParameters(params, params);
1297
1298 RTPVideoHeader video_header;
1299 video_header.video_timing.flags = VideoSendTiming::kTriggeredByTimer;
1300
1301 EXPECT_CALL(mock_rtc_event_log_,
1302 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1303 .Times(1);
Erik Språngf6468d22019-07-05 16:53:43 +02001304 std::unique_ptr<RtpPacketToSend> rtp_packet;
1305 EXPECT_CALL(
1306 mock_paced_sender_,
1307 EnqueuePacket(AllOf(
1308 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1309 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))))
1310 .WillOnce([&rtp_packet](std::unique_ptr<RtpPacketToSend> packet) {
1311 rtp_packet = std::move(packet);
1312 });
1313
1314 EXPECT_CALL(
1315 mock_paced_sender_,
1316 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kFlexFecSsrc))))
1317 .Times(0); // Not called because packet should not be protected.
1318
1319 EXPECT_TRUE(rtp_sender_video.SendVideo(
1320 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
1321 kCaptureTimeMs, kPayloadData, sizeof(kPayloadData), nullptr,
1322 &video_header, kDefaultExpectedRetransmissionTimeMs));
1323
1324 EXPECT_TRUE(
1325 rtp_sender_->TrySendPacket(rtp_packet.get(), PacedPacketInfo()));
Erik Språngf6468d22019-07-05 16:53:43 +02001326
1327 ASSERT_EQ(1, transport_.packets_sent());
Erik Språngf5815fa2019-08-21 14:27:31 +02001328 const RtpPacketReceived& sent_media_packet1 = transport_.sent_packets_[0];
1329 EXPECT_EQ(kMediaPayloadType, sent_media_packet1.PayloadType());
1330 EXPECT_EQ(kSeqNum, sent_media_packet1.SequenceNumber());
1331 EXPECT_EQ(kSsrc, sent_media_packet1.Ssrc());
Erik Språngf6468d22019-07-05 16:53:43 +02001332
1333 // Now try to send not a timing frame.
1334 uint16_t flexfec_seq_num;
1335
1336 EXPECT_CALL(mock_rtc_event_log_,
1337 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1338 .Times(2);
Erik Språngf5815fa2019-08-21 14:27:31 +02001339 std::unique_ptr<RtpPacketToSend> media_packet2;
1340 std::unique_ptr<RtpPacketToSend> fec_packet;
Erik Språngf6468d22019-07-05 16:53:43 +02001341
Erik Språngf5815fa2019-08-21 14:27:31 +02001342 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1343 .Times(2)
1344 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) {
1345 if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
1346 EXPECT_EQ(packet->Ssrc(), kSsrc);
1347 EXPECT_EQ(packet->SequenceNumber(), kSeqNum + 1);
1348 media_packet2 = std::move(packet);
1349 } else {
1350 EXPECT_EQ(packet->packet_type(),
1351 RtpPacketToSend::Type::kForwardErrorCorrection);
1352 EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
1353 fec_packet = std::move(packet);
1354 }
1355 });
Erik Språngf6468d22019-07-05 16:53:43 +02001356
Erik Språngf5815fa2019-08-21 14:27:31 +02001357 video_header.video_timing.flags = VideoSendTiming::kInvalid;
1358 EXPECT_TRUE(rtp_sender_video.SendVideo(
1359 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp + 1,
1360 kCaptureTimeMs + 1, kPayloadData, sizeof(kPayloadData), nullptr,
1361 &video_header, kDefaultExpectedRetransmissionTimeMs));
Erik Språngf6468d22019-07-05 16:53:43 +02001362
Erik Språngf5815fa2019-08-21 14:27:31 +02001363 ASSERT_TRUE(media_packet2 != nullptr);
1364 ASSERT_TRUE(fec_packet != nullptr);
Erik Språngf6468d22019-07-05 16:53:43 +02001365
Erik Språngf5815fa2019-08-21 14:27:31 +02001366 flexfec_seq_num = fec_packet->SequenceNumber();
1367 rtp_sender_->TrySendPacket(media_packet2.get(), PacedPacketInfo());
1368 rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001369
1370 ASSERT_EQ(3, transport_.packets_sent());
Erik Språngf5815fa2019-08-21 14:27:31 +02001371 const RtpPacketReceived& sent_media_packet2 = transport_.sent_packets_[1];
1372 EXPECT_EQ(kMediaPayloadType, sent_media_packet2.PayloadType());
1373 EXPECT_EQ(kSeqNum + 1, sent_media_packet2.SequenceNumber());
1374 EXPECT_EQ(kSsrc, sent_media_packet2.Ssrc());
Erik Språngf6468d22019-07-05 16:53:43 +02001375 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[2];
1376 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
1377 EXPECT_EQ(flexfec_seq_num, flexfec_packet.SequenceNumber());
1378 EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
1379}
1380
minyue3a407ee2017-04-03 01:10:33 -07001381TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001382 constexpr uint32_t kTimestamp = 1234;
brandtrdbdb3f12016-11-10 05:04:48 -08001383 constexpr int kMediaPayloadType = 127;
1384 constexpr int kFlexfecPayloadType = 118;
brandtrdbdb3f12016-11-10 05:04:48 -08001385 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001386 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språngf6468d22019-07-05 16:53:43 +02001387 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
Erik Språng4580ca22019-07-04 10:38:43 +02001388 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001389 nullptr /* rtp_state */, &fake_clock_);
brandtrdbdb3f12016-11-10 05:04:48 -08001390
1391 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001392 RtpRtcp::Configuration config;
1393 config.clock = &fake_clock_;
1394 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001395 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001396 config.flexfec_sender = &flexfec_sender;
1397 config.transport_sequence_number_allocator = &seq_num_allocator_;
1398 config.event_log = &mock_rtc_event_log_;
1399 config.send_packet_observer = &send_packet_observer_;
1400 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1401 rtp_sender_ = absl::make_unique<RTPSender>(config);
1402
brandtrdbdb3f12016-11-10 05:04:48 -08001403 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtrdbdb3f12016-11-10 05:04:48 -08001404
Niels Möller5fe95102019-03-04 16:49:25 +01001405 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001406 RTPSenderVideo rtp_sender_video(
1407 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1408 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001409 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1410 /*raw_payload=*/false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001411
brandtrdbdb3f12016-11-10 05:04:48 -08001412 // Parameters selected to generate a single FEC packet per media packet.
1413 FecProtectionParams params;
1414 params.fec_rate = 15;
1415 params.max_fec_frames = 1;
1416 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001417 rtp_sender_video.SetFecParameters(params, params);
brandtrdbdb3f12016-11-10 05:04:48 -08001418
Elad Alon4a87e1c2017-10-03 16:11:34 +02001419 EXPECT_CALL(mock_rtc_event_log_,
1420 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1421 .Times(2);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001422 RTPVideoHeader video_header;
1423 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001424 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001425 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1426 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1427
brandtrdbdb3f12016-11-10 05:04:48 -08001428 ASSERT_EQ(2, transport_.packets_sent());
1429 const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
1430 EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
Erik Språng4580ca22019-07-04 10:38:43 +02001431 EXPECT_EQ(kSsrc, media_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001432 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[1];
1433 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
Erik Språngf6468d22019-07-05 16:53:43 +02001434 EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001435}
1436
Steve Anton296a0ce2018-03-22 15:17:27 -07001437// Test that the MID header extension is included on sent packets when
1438// configured.
1439TEST_P(RtpSenderTestWithoutPacer, MidIncludedOnSentPackets) {
1440 const char kMid[] = "mid";
1441
Steve Anton2bac7da2019-07-21 15:04:21 -04001442 EnableMidSending(kMid);
Steve Anton296a0ce2018-03-22 15:17:27 -07001443
1444 // Send a couple packets.
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001445 SendGenericPacket();
1446 SendGenericPacket();
Steve Anton296a0ce2018-03-22 15:17:27 -07001447
1448 // Expect both packets to have the MID set.
1449 ASSERT_EQ(2u, transport_.sent_packets_.size());
1450 for (const RtpPacketReceived& packet : transport_.sent_packets_) {
1451 std::string mid;
1452 ASSERT_TRUE(packet.GetExtension<RtpMid>(&mid));
1453 EXPECT_EQ(kMid, mid);
1454 }
1455}
1456
Amit Hilbuch77938e62018-12-21 09:23:38 -08001457TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnSentPackets) {
1458 const char kRid[] = "f";
1459
Steve Anton2bac7da2019-07-21 15:04:21 -04001460 EnableRidSending(kRid);
Amit Hilbuch77938e62018-12-21 09:23:38 -08001461
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001462 SendGenericPacket();
Amit Hilbuch77938e62018-12-21 09:23:38 -08001463
1464 ASSERT_EQ(1u, transport_.sent_packets_.size());
1465 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1466 std::string rid;
1467 ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
1468 EXPECT_EQ(kRid, rid);
1469}
1470
1471TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnRtxSentPackets) {
1472 const char kRid[] = "f";
Amit Hilbuch77938e62018-12-21 09:23:38 -08001473
Steve Anton2bac7da2019-07-21 15:04:21 -04001474 EnableRtx();
1475 EnableRidSending(kRid);
Amit Hilbuch77938e62018-12-21 09:23:38 -08001476
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001477 SendGenericPacket();
Amit Hilbuch77938e62018-12-21 09:23:38 -08001478 ASSERT_EQ(1u, transport_.sent_packets_.size());
1479 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1480 std::string rid;
1481 ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
1482 EXPECT_EQ(kRid, rid);
1483 rid = kNoRid;
Steve Anton2bac7da2019-07-21 15:04:21 -04001484 EXPECT_FALSE(packet.HasExtension<RepairedRtpStreamId>());
Amit Hilbuch77938e62018-12-21 09:23:38 -08001485
1486 uint16_t packet_id = packet.SequenceNumber();
1487 rtp_sender_->ReSendPacket(packet_id);
1488 ASSERT_EQ(2u, transport_.sent_packets_.size());
1489 const RtpPacketReceived& rtx_packet = transport_.sent_packets_[1];
1490 ASSERT_TRUE(rtx_packet.GetExtension<RepairedRtpStreamId>(&rid));
1491 EXPECT_EQ(kRid, rid);
1492 EXPECT_FALSE(rtx_packet.HasExtension<RtpStreamId>());
1493}
1494
Steve Anton2bac7da2019-07-21 15:04:21 -04001495TEST_P(RtpSenderTestWithoutPacer, MidAndRidNotIncludedOnSentPacketsAfterAck) {
1496 const char kMid[] = "mid";
1497 const char kRid[] = "f";
1498
1499 EnableMidSending(kMid);
1500 EnableRidSending(kRid);
1501
1502 // This first packet should include both MID and RID.
1503 auto first_built_packet = SendGenericPacket();
1504
1505 rtp_sender_->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
1506
1507 // The second packet should include neither since an ack was received.
1508 SendGenericPacket();
1509
1510 ASSERT_EQ(2u, transport_.sent_packets_.size());
1511
1512 const RtpPacketReceived& first_packet = transport_.sent_packets_[0];
1513 std::string mid, rid;
1514 ASSERT_TRUE(first_packet.GetExtension<RtpMid>(&mid));
1515 EXPECT_EQ(kMid, mid);
1516 ASSERT_TRUE(first_packet.GetExtension<RtpStreamId>(&rid));
1517 EXPECT_EQ(kRid, rid);
1518
1519 const RtpPacketReceived& second_packet = transport_.sent_packets_[1];
1520 EXPECT_FALSE(second_packet.HasExtension<RtpMid>());
1521 EXPECT_FALSE(second_packet.HasExtension<RtpStreamId>());
1522}
1523
1524// Test that the first RTX packet includes both MID and RRID even if the packet
1525// being retransmitted did not have MID or RID. The MID and RID are needed on
1526// the first packets for a given SSRC, and RTX packets are sent on a separate
1527// SSRC.
1528TEST_P(RtpSenderTestWithoutPacer, MidAndRidIncludedOnFirstRtxPacket) {
1529 const char kMid[] = "mid";
1530 const char kRid[] = "f";
1531
1532 EnableRtx();
1533 EnableMidSending(kMid);
1534 EnableRidSending(kRid);
1535
1536 // This first packet will include both MID and RID.
1537 auto first_built_packet = SendGenericPacket();
1538 rtp_sender_->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
1539
1540 // The second packet will include neither since an ack was received.
1541 auto second_built_packet = SendGenericPacket();
1542
1543 // The first RTX packet should include MID and RRID.
1544 ASSERT_LT(0,
1545 rtp_sender_->ReSendPacket(second_built_packet->SequenceNumber()));
1546
1547 ASSERT_EQ(3u, transport_.sent_packets_.size());
1548
1549 const RtpPacketReceived& rtx_packet = transport_.sent_packets_[2];
1550 std::string mid, rrid;
1551 ASSERT_TRUE(rtx_packet.GetExtension<RtpMid>(&mid));
1552 EXPECT_EQ(kMid, mid);
1553 ASSERT_TRUE(rtx_packet.GetExtension<RepairedRtpStreamId>(&rrid));
1554 EXPECT_EQ(kRid, rrid);
1555}
1556
1557// Test that the RTX packets sent after receving an ACK on the RTX SSRC does
1558// not include either MID or RRID even if the packet being retransmitted did
1559// had a MID or RID.
1560TEST_P(RtpSenderTestWithoutPacer, MidAndRidNotIncludedOnRtxPacketsAfterAck) {
1561 const char kMid[] = "mid";
1562 const char kRid[] = "f";
1563
1564 EnableRtx();
1565 EnableMidSending(kMid);
1566 EnableRidSending(kRid);
1567
1568 // This first packet will include both MID and RID.
1569 auto first_built_packet = SendGenericPacket();
1570 rtp_sender_->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
1571
1572 // The second packet will include neither since an ack was received.
1573 auto second_built_packet = SendGenericPacket();
1574
1575 // The first RTX packet will include MID and RRID.
1576 ASSERT_LT(0,
1577 rtp_sender_->ReSendPacket(second_built_packet->SequenceNumber()));
1578
1579 ASSERT_EQ(3u, transport_.sent_packets_.size());
1580 const RtpPacketReceived& first_rtx_packet = transport_.sent_packets_[2];
1581
1582 rtp_sender_->OnReceivedAckOnRtxSsrc(first_rtx_packet.SequenceNumber());
1583
1584 // The second and third RTX packets should not include MID nor RRID.
1585 ASSERT_LT(0, rtp_sender_->ReSendPacket(first_built_packet->SequenceNumber()));
1586 ASSERT_LT(0,
1587 rtp_sender_->ReSendPacket(second_built_packet->SequenceNumber()));
1588
1589 ASSERT_EQ(5u, transport_.sent_packets_.size());
1590
1591 const RtpPacketReceived& second_rtx_packet = transport_.sent_packets_[3];
1592 EXPECT_FALSE(second_rtx_packet.HasExtension<RtpMid>());
1593 EXPECT_FALSE(second_rtx_packet.HasExtension<RepairedRtpStreamId>());
1594
1595 const RtpPacketReceived& third_rtx_packet = transport_.sent_packets_[4];
1596 EXPECT_FALSE(third_rtx_packet.HasExtension<RtpMid>());
1597 EXPECT_FALSE(third_rtx_packet.HasExtension<RepairedRtpStreamId>());
1598}
1599
1600// Test that if the RtpState indicates an ACK has been received on that SSRC
1601// then neither the MID nor RID header extensions will be sent.
1602TEST_P(RtpSenderTestWithoutPacer,
1603 MidAndRidNotIncludedOnSentPacketsAfterRtpStateRestored) {
1604 const char kMid[] = "mid";
1605 const char kRid[] = "f";
1606
1607 EnableMidSending(kMid);
1608 EnableRidSending(kRid);
1609
1610 RtpState state = rtp_sender_->GetRtpState();
1611 EXPECT_FALSE(state.ssrc_has_acked);
1612 state.ssrc_has_acked = true;
1613 rtp_sender_->SetRtpState(state);
1614
1615 SendGenericPacket();
1616
1617 ASSERT_EQ(1u, transport_.sent_packets_.size());
1618 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1619 EXPECT_FALSE(packet.HasExtension<RtpMid>());
1620 EXPECT_FALSE(packet.HasExtension<RtpStreamId>());
1621}
1622
1623// Test that if the RTX RtpState indicates an ACK has been received on that
1624// RTX SSRC then neither the MID nor RRID header extensions will be sent on
1625// RTX packets.
1626TEST_P(RtpSenderTestWithoutPacer,
1627 MidAndRridNotIncludedOnRtxPacketsAfterRtpStateRestored) {
1628 const char kMid[] = "mid";
1629 const char kRid[] = "f";
1630
1631 EnableRtx();
1632 EnableMidSending(kMid);
1633 EnableRidSending(kRid);
1634
1635 RtpState rtx_state = rtp_sender_->GetRtxRtpState();
1636 EXPECT_FALSE(rtx_state.ssrc_has_acked);
1637 rtx_state.ssrc_has_acked = true;
1638 rtp_sender_->SetRtxRtpState(rtx_state);
1639
1640 auto built_packet = SendGenericPacket();
1641 ASSERT_LT(0, rtp_sender_->ReSendPacket(built_packet->SequenceNumber()));
1642
1643 ASSERT_EQ(2u, transport_.sent_packets_.size());
1644 const RtpPacketReceived& rtx_packet = transport_.sent_packets_[1];
1645 EXPECT_FALSE(rtx_packet.HasExtension<RtpMid>());
1646 EXPECT_FALSE(rtx_packet.HasExtension<RepairedRtpStreamId>());
1647}
1648
minyue3a407ee2017-04-03 01:10:33 -07001649TEST_P(RtpSenderTest, FecOverheadRate) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001650 constexpr uint32_t kTimestamp = 1234;
1651 constexpr int kMediaPayloadType = 127;
brandtr81eab612017-01-24 04:06:09 -08001652 constexpr int kFlexfecPayloadType = 118;
brandtr81eab612017-01-24 04:06:09 -08001653 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001654 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språng4580ca22019-07-04 10:38:43 +02001655 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1656 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001657 nullptr /* rtp_state */, &fake_clock_);
brandtr81eab612017-01-24 04:06:09 -08001658
1659 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001660 RtpRtcp::Configuration config;
1661 config.clock = &fake_clock_;
1662 config.outgoing_transport = &transport_;
1663 config.paced_sender = &mock_paced_sender_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001664 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001665 config.flexfec_sender = &flexfec_sender;
1666 config.transport_sequence_number_allocator = &seq_num_allocator_;
1667 config.event_log = &mock_rtc_event_log_;
1668 config.send_packet_observer = &send_packet_observer_;
1669 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1670 rtp_sender_ = absl::make_unique<RTPSender>(config);
1671
brandtr81eab612017-01-24 04:06:09 -08001672 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtr81eab612017-01-24 04:06:09 -08001673
Niels Möller5fe95102019-03-04 16:49:25 +01001674 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001675 RTPSenderVideo rtp_sender_video(
1676 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1677 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001678 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1679 /*raw_payload=*/false);
brandtr81eab612017-01-24 04:06:09 -08001680 // Parameters selected to generate a single FEC packet per media packet.
1681 FecProtectionParams params;
1682 params.fec_rate = 15;
1683 params.max_fec_frames = 1;
1684 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001685 rtp_sender_video.SetFecParameters(params, params);
brandtr81eab612017-01-24 04:06:09 -08001686
1687 constexpr size_t kNumMediaPackets = 10;
1688 constexpr size_t kNumFecPackets = kNumMediaPackets;
1689 constexpr int64_t kTimeBetweenPacketsMs = 10;
Erik Språngf6468d22019-07-05 16:53:43 +02001690 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1691 .Times(kNumMediaPackets + kNumFecPackets);
brandtr81eab612017-01-24 04:06:09 -08001692 for (size_t i = 0; i < kNumMediaPackets; ++i) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001693 RTPVideoHeader video_header;
1694
1695 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001696 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001697 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1698 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1699
brandtr81eab612017-01-24 04:06:09 -08001700 fake_clock_.AdvanceTimeMilliseconds(kTimeBetweenPacketsMs);
1701 }
1702 constexpr size_t kRtpHeaderLength = 12;
1703 constexpr size_t kFlexfecHeaderLength = 20;
1704 constexpr size_t kGenericCodecHeaderLength = 1;
1705 constexpr size_t kPayloadLength = sizeof(kPayloadData);
1706 constexpr size_t kPacketLength = kRtpHeaderLength + kFlexfecHeaderLength +
1707 kGenericCodecHeaderLength + kPayloadLength;
1708 EXPECT_NEAR(kNumFecPackets * kPacketLength * 8 /
1709 (kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f),
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001710 rtp_sender_video.FecOverheadRate(), 500);
brandtr81eab612017-01-24 04:06:09 -08001711}
1712
minyue3a407ee2017-04-03 01:10:33 -07001713TEST_P(RtpSenderTest, BitrateCallbacks) {
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001714 class TestCallback : public BitrateStatisticsObserver {
1715 public:
sprangcd349d92016-07-13 09:11:28 -07001716 TestCallback()
1717 : BitrateStatisticsObserver(),
1718 num_calls_(0),
1719 ssrc_(0),
1720 total_bitrate_(0),
1721 retransmit_bitrate_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +00001722 ~TestCallback() override = default;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001723
sprangcd349d92016-07-13 09:11:28 -07001724 void Notify(uint32_t total_bitrate,
1725 uint32_t retransmit_bitrate,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001726 uint32_t ssrc) override {
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001727 ++num_calls_;
1728 ssrc_ = ssrc;
sprangcd349d92016-07-13 09:11:28 -07001729 total_bitrate_ = total_bitrate;
1730 retransmit_bitrate_ = retransmit_bitrate;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001731 }
1732
1733 uint32_t num_calls_;
1734 uint32_t ssrc_;
sprangcd349d92016-07-13 09:11:28 -07001735 uint32_t total_bitrate_;
1736 uint32_t retransmit_bitrate_;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001737 } callback;
Erik Språng4580ca22019-07-04 10:38:43 +02001738
1739 RtpRtcp::Configuration config;
1740 config.clock = &fake_clock_;
1741 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001742 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001743 config.send_bitrate_observer = &callback;
1744 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1745 rtp_sender_ = absl::make_unique<RTPSender>(config);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001746
Niels Möller5fe95102019-03-04 16:49:25 +01001747 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001748 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001749 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01001750 FieldTrialBasedConfig());
Niels Möller59ab1cf2019-02-06 22:48:11 +01001751 const char payload_name[] = "GENERIC";
1752 const uint8_t payload_type = 127;
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001753 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1754 /*raw_payload=*/false);
Niels Möller59ab1cf2019-02-06 22:48:11 +01001755
sprangcd349d92016-07-13 09:11:28 -07001756 // Simulate kNumPackets sent with kPacketInterval ms intervals, with the
1757 // number of packets selected so that we fill (but don't overflow) the one
1758 // second averaging window.
1759 const uint32_t kWindowSizeMs = 1000;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001760 const uint32_t kPacketInterval = 20;
sprangcd349d92016-07-13 09:11:28 -07001761 const uint32_t kNumPackets =
1762 (kWindowSizeMs - kPacketInterval) / kPacketInterval;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001763 // Overhead = 12 bytes RTP header + 1 byte generic header.
1764 const uint32_t kPacketOverhead = 13;
1765
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001766 uint8_t payload[] = {47, 11, 32, 93, 89};
1767 rtp_sender_->SetStorePacketsStatus(true, 1);
1768 uint32_t ssrc = rtp_sender_->SSRC();
1769
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001770 // Initial process call so we get a new time window.
1771 rtp_sender_->ProcessBitrate();
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001772
1773 // Send a few frames.
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001774 RTPVideoHeader video_header;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001775 for (uint32_t i = 0; i < kNumPackets; ++i) {
Niels Möller59ab1cf2019-02-06 22:48:11 +01001776 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001777 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1778 sizeof(payload), nullptr, &video_header,
1779 kDefaultExpectedRetransmissionTimeMs));
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001780 fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
1781 }
1782
1783 rtp_sender_->ProcessBitrate();
1784
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001785 // We get one call for every stats updated, thus two calls since both the
1786 // stream stats and the retransmit stats are updated once.
1787 EXPECT_EQ(2u, callback.num_calls_);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001788 EXPECT_EQ(ssrc, callback.ssrc_);
sprangcd349d92016-07-13 09:11:28 -07001789 const uint32_t kTotalPacketSize = kPacketOverhead + sizeof(payload);
1790 // Bitrate measured over delta between last and first timestamp, plus one.
1791 const uint32_t kExpectedWindowMs = kNumPackets * kPacketInterval + 1;
1792 const uint32_t kExpectedBitsAccumulated = kTotalPacketSize * kNumPackets * 8;
1793 const uint32_t kExpectedRateBps =
1794 (kExpectedBitsAccumulated * 1000 + (kExpectedWindowMs / 2)) /
1795 kExpectedWindowMs;
1796 EXPECT_EQ(kExpectedRateBps, callback.total_bitrate_);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001797
andresp@webrtc.orgd11bec42014-07-08 14:32:58 +00001798 rtp_sender_.reset();
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001799}
1800
minyue3a407ee2017-04-03 01:10:33 -07001801TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001802 class TestCallback : public StreamDataCountersCallback {
1803 public:
danilchap162abd32015-12-10 02:39:40 -08001804 TestCallback() : StreamDataCountersCallback(), ssrc_(0), counters_() {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +00001805 ~TestCallback() override = default;
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001806
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001807 void DataCountersUpdated(const StreamDataCounters& counters,
1808 uint32_t ssrc) override {
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001809 ssrc_ = ssrc;
1810 counters_ = counters;
1811 }
1812
1813 uint32_t ssrc_;
1814 StreamDataCounters counters_;
asapersson@webrtc.org44149392015-02-04 08:34:47 +00001815
1816 void MatchPacketCounter(const RtpPacketCounter& expected,
1817 const RtpPacketCounter& actual) {
1818 EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
1819 EXPECT_EQ(expected.header_bytes, actual.header_bytes);
1820 EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
1821 EXPECT_EQ(expected.packets, actual.packets);
1822 }
1823
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001824 void Matches(uint32_t ssrc, const StreamDataCounters& counters) {
1825 EXPECT_EQ(ssrc, ssrc_);
asapersson@webrtc.org44149392015-02-04 08:34:47 +00001826 MatchPacketCounter(counters.transmitted, counters_.transmitted);
1827 MatchPacketCounter(counters.retransmitted, counters_.retransmitted);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001828 EXPECT_EQ(counters.fec.packets, counters_.fec.packets);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001829 }
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001830 } callback;
1831
1832 const uint8_t kRedPayloadType = 96;
1833 const uint8_t kUlpfecPayloadType = 97;
Niels Möller8a40edd2019-01-24 18:04:44 +01001834 const char payload_name[] = "GENERIC";
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001835 const uint8_t payload_type = 127;
Niels Möller5fe95102019-03-04 16:49:25 +01001836 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001837 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001838 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01001839 FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001840 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1841 /*raw_payload=*/false);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001842 uint8_t payload[] = {47, 11, 32, 93, 89};
1843 rtp_sender_->SetStorePacketsStatus(true, 1);
1844 uint32_t ssrc = rtp_sender_->SSRC();
1845
1846 rtp_sender_->RegisterRtpStatisticsCallback(&callback);
1847
1848 // Send a frame.
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001849 RTPVideoHeader video_header;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001850 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001851 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1852 sizeof(payload), nullptr, &video_header,
1853 kDefaultExpectedRetransmissionTimeMs));
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001854 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001855 expected.transmitted.payload_bytes = 6;
1856 expected.transmitted.header_bytes = 12;
1857 expected.transmitted.padding_bytes = 0;
1858 expected.transmitted.packets = 1;
1859 expected.retransmitted.payload_bytes = 0;
1860 expected.retransmitted.header_bytes = 0;
1861 expected.retransmitted.padding_bytes = 0;
1862 expected.retransmitted.packets = 0;
1863 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001864 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001865
1866 // Retransmit a frame.
1867 uint16_t seqno = rtp_sender_->SequenceNumber() - 1;
Erik Språnga12b1d62018-03-14 12:39:24 +01001868 rtp_sender_->ReSendPacket(seqno);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001869 expected.transmitted.payload_bytes = 12;
1870 expected.transmitted.header_bytes = 24;
1871 expected.transmitted.packets = 2;
1872 expected.retransmitted.payload_bytes = 6;
1873 expected.retransmitted.header_bytes = 12;
1874 expected.retransmitted.padding_bytes = 0;
1875 expected.retransmitted.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001876 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001877
1878 // Send padding.
Erik Språng4208a132019-08-26 08:58:45 +02001879 GenerateAndSendPadding(kMaxPaddingSize);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001880 expected.transmitted.payload_bytes = 12;
1881 expected.transmitted.header_bytes = 36;
1882 expected.transmitted.padding_bytes = kMaxPaddingSize;
1883 expected.transmitted.packets = 3;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001884 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001885
brandtrf1bb4762016-11-07 03:05:06 -08001886 // Send ULPFEC.
Niels Möller59ab1cf2019-02-06 22:48:11 +01001887 rtp_sender_video.SetUlpfecConfig(kRedPayloadType, kUlpfecPayloadType);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001888 FecProtectionParams fec_params;
1889 fec_params.fec_mask_type = kFecMaskRandom;
1890 fec_params.fec_rate = 1;
1891 fec_params.max_fec_frames = 1;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001892 rtp_sender_video.SetFecParameters(fec_params, fec_params);
1893 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001894 VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload,
1895 sizeof(payload), nullptr, &video_header,
1896 kDefaultExpectedRetransmissionTimeMs));
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001897 expected.transmitted.payload_bytes = 40;
1898 expected.transmitted.header_bytes = 60;
1899 expected.transmitted.packets = 5;
1900 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001901 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001902
sprang867fb522015-08-03 04:38:41 -07001903 rtp_sender_->RegisterRtpStatisticsCallback(nullptr);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001904}
1905
minyue3a407ee2017-04-03 01:10:33 -07001906TEST_P(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
Niels Möller59ab1cf2019-02-06 22:48:11 +01001907 // XXX const char* kPayloadName = "GENERIC";
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001908 const uint8_t kPayloadType = 127;
Shao Changbine62202f2015-04-21 20:24:50 +08001909 rtp_sender_->SetRtxPayloadType(kPayloadType - 1, kPayloadType);
pbos@webrtc.org0b0c2412015-01-13 14:15:15 +00001910 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001911
Niels Möller59ab1cf2019-02-06 22:48:11 +01001912 SendGenericPacket();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001913 // Will send 2 full-size padding packets.
Erik Språng4208a132019-08-26 08:58:45 +02001914 GenerateAndSendPadding(1);
1915 GenerateAndSendPadding(1);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001916
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001917 StreamDataCounters rtp_stats;
1918 StreamDataCounters rtx_stats;
1919 rtp_sender_->GetDataCounters(&rtp_stats, &rtx_stats);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001920
Niels Möller59ab1cf2019-02-06 22:48:11 +01001921 // Payload
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +00001922 EXPECT_GT(rtp_stats.first_packet_time_ms, -1);
Niels Möller59ab1cf2019-02-06 22:48:11 +01001923 EXPECT_EQ(rtp_stats.transmitted.payload_bytes, sizeof(kPayloadData));
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001924 EXPECT_EQ(rtp_stats.transmitted.header_bytes, 12u);
1925 EXPECT_EQ(rtp_stats.transmitted.padding_bytes, 0u);
1926 EXPECT_EQ(rtx_stats.transmitted.payload_bytes, 0u);
1927 EXPECT_EQ(rtx_stats.transmitted.header_bytes, 24u);
1928 EXPECT_EQ(rtx_stats.transmitted.padding_bytes, 2 * kMaxPaddingSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001929
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001930 EXPECT_EQ(rtp_stats.transmitted.TotalBytes(),
danilchap162abd32015-12-10 02:39:40 -08001931 rtp_stats.transmitted.payload_bytes +
1932 rtp_stats.transmitted.header_bytes +
1933 rtp_stats.transmitted.padding_bytes);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001934 EXPECT_EQ(rtx_stats.transmitted.TotalBytes(),
danilchap162abd32015-12-10 02:39:40 -08001935 rtx_stats.transmitted.payload_bytes +
1936 rtx_stats.transmitted.header_bytes +
1937 rtx_stats.transmitted.padding_bytes);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001938
danilchap162abd32015-12-10 02:39:40 -08001939 EXPECT_EQ(
1940 transport_.total_bytes_sent_,
1941 rtp_stats.transmitted.TotalBytes() + rtx_stats.transmitted.TotalBytes());
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001942}
guoweis@webrtc.org45362892015-03-04 22:55:15 +00001943
minyue3a407ee2017-04-03 01:10:33 -07001944TEST_P(RtpSenderTestWithoutPacer, RespectsNackBitrateLimit) {
sprang38778b02015-09-29 09:48:22 -07001945 const int32_t kPacketSize = 1400;
1946 const int32_t kNumPackets = 30;
1947
sprangcd349d92016-07-13 09:11:28 -07001948 retransmission_rate_limiter_.SetMaxRate(kPacketSize * kNumPackets * 8);
1949
sprang38778b02015-09-29 09:48:22 -07001950 rtp_sender_->SetStorePacketsStatus(true, kNumPackets);
sprang38778b02015-09-29 09:48:22 -07001951 const uint16_t kStartSequenceNumber = rtp_sender_->SequenceNumber();
Danil Chapovalov2800d742016-08-26 18:48:46 +02001952 std::vector<uint16_t> sequence_numbers;
sprang38778b02015-09-29 09:48:22 -07001953 for (int32_t i = 0; i < kNumPackets; ++i) {
1954 sequence_numbers.push_back(kStartSequenceNumber + i);
1955 fake_clock_.AdvanceTimeMilliseconds(1);
1956 SendPacket(fake_clock_.TimeInMilliseconds(), kPacketSize);
1957 }
danilchap12ba1862016-10-26 02:41:55 -07001958 EXPECT_EQ(kNumPackets, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001959
1960 fake_clock_.AdvanceTimeMilliseconds(1000 - kNumPackets);
1961
1962 // Resending should work - brings the bandwidth up to the limit.
1963 // NACK bitrate is capped to the same bitrate as the encoder, since the max
1964 // protection overhead is 50% (see MediaOptimization::SetTargetRates).
Danil Chapovalov2800d742016-08-26 18:48:46 +02001965 rtp_sender_->OnReceivedNack(sequence_numbers, 0);
danilchap12ba1862016-10-26 02:41:55 -07001966 EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001967
sprangcd349d92016-07-13 09:11:28 -07001968 // Must be at least 5ms in between retransmission attempts.
1969 fake_clock_.AdvanceTimeMilliseconds(5);
1970
sprang38778b02015-09-29 09:48:22 -07001971 // Resending should not work, bandwidth exceeded.
Danil Chapovalov2800d742016-08-26 18:48:46 +02001972 rtp_sender_->OnReceivedNack(sequence_numbers, 0);
danilchap12ba1862016-10-26 02:41:55 -07001973 EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001974}
1975
minyue3a407ee2017-04-03 01:10:33 -07001976TEST_P(RtpSenderTest, OnOverheadChanged) {
michaelt4da30442016-11-17 01:38:43 -08001977 MockOverheadObserver mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02001978 RtpRtcp::Configuration config;
1979 config.clock = &fake_clock_;
1980 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001981 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001982 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1983 config.overhead_observer = &mock_overhead_observer;
1984 rtp_sender_ = absl::make_unique<RTPSender>(config);
michaelt4da30442016-11-17 01:38:43 -08001985
michaelt4da30442016-11-17 01:38:43 -08001986 // RTP overhead is 12B.
nisse284542b2017-01-10 08:58:32 -08001987 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(12)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001988 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08001989
1990 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
1991 kTransmissionTimeOffsetExtensionId);
1992
1993 // TransmissionTimeOffset extension has a size of 8B.
nisse284542b2017-01-10 08:58:32 -08001994 // 12B + 8B = 20B
1995 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(20)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001996 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08001997}
1998
minyue3a407ee2017-04-03 01:10:33 -07001999TEST_P(RtpSenderTest, DoesNotUpdateOverheadOnEqualSize) {
michaelt4da30442016-11-17 01:38:43 -08002000 MockOverheadObserver mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02002001 RtpRtcp::Configuration config;
2002 config.clock = &fake_clock_;
2003 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02002004 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02002005 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
2006 config.overhead_observer = &mock_overhead_observer;
2007 rtp_sender_ = absl::make_unique<RTPSender>(config);
michaelt4da30442016-11-17 01:38:43 -08002008
2009 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(_)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01002010 SendGenericPacket();
2011 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08002012}
2013
Erik Språng9c771c22019-06-17 16:31:53 +02002014TEST_P(RtpSenderTest, TrySendPacketMatchesVideo) {
2015 std::unique_ptr<RtpPacketToSend> packet =
2016 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2017 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2018
2019 // Verify not sent with wrong SSRC.
2020 packet->SetSsrc(kSsrc + 1);
2021 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2022
2023 // Verify sent with correct SSRC.
2024 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2025 packet->SetSsrc(kSsrc);
2026 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2027 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2028}
2029
2030TEST_P(RtpSenderTest, TrySendPacketMatchesAudio) {
2031 std::unique_ptr<RtpPacketToSend> packet =
2032 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2033 packet->set_packet_type(RtpPacketToSend::Type::kAudio);
2034
2035 // Verify not sent with wrong SSRC.
2036 packet->SetSsrc(kSsrc + 1);
2037 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2038
2039 // Verify sent with correct SSRC.
2040 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2041 packet->SetSsrc(kSsrc);
2042 packet->set_packet_type(RtpPacketToSend::Type::kAudio);
2043 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2044}
2045
2046TEST_P(RtpSenderTest, TrySendPacketMatchesRetransmissions) {
2047 std::unique_ptr<RtpPacketToSend> packet =
2048 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2049 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2050
2051 // Verify not sent with wrong SSRC.
2052 packet->SetSsrc(kSsrc + 1);
2053 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2054
2055 // Verify sent with correct SSRC (non-RTX).
2056 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2057 packet->SetSsrc(kSsrc);
2058 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2059 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2060
2061 // RTX retransmission.
2062 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2063 packet->SetSsrc(kRtxSsrc);
2064 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2065 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2066}
2067
2068TEST_P(RtpSenderTest, TrySendPacketMatchesPadding) {
2069 std::unique_ptr<RtpPacketToSend> packet =
2070 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2071 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2072
2073 // Verify not sent with wrong SSRC.
2074 packet->SetSsrc(kSsrc + 1);
2075 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2076
2077 // Verify sent with correct SSRC (non-RTX).
2078 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2079 packet->SetSsrc(kSsrc);
2080 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2081 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2082
2083 // RTX padding.
2084 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2085 packet->SetSsrc(kRtxSsrc);
2086 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2087 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2088}
2089
2090TEST_P(RtpSenderTest, TrySendPacketMatchesFlexfec) {
2091 std::unique_ptr<RtpPacketToSend> packet =
2092 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2093 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2094
2095 // Verify not sent with wrong SSRC.
2096 packet->SetSsrc(kSsrc + 1);
2097 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2098
2099 // Verify sent with correct SSRC.
2100 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2101 packet->SetSsrc(kFlexFecSsrc);
2102 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2103 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2104}
2105
2106TEST_P(RtpSenderTest, TrySendPacketMatchesUlpfec) {
2107 std::unique_ptr<RtpPacketToSend> packet =
2108 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2109 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2110
2111 // Verify not sent with wrong SSRC.
2112 packet->SetSsrc(kSsrc + 1);
2113 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2114
2115 // Verify sent with correct SSRC.
2116 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2117 packet->SetSsrc(kSsrc);
2118 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2119 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2120}
2121
2122TEST_P(RtpSenderTest, TrySendPacketHandlesRetransmissionHistory) {
2123 rtp_sender_->SetStorePacketsStatus(true, 10);
2124
2125 // Build a media packet and send it.
2126 std::unique_ptr<RtpPacketToSend> packet =
2127 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2128 const uint16_t media_sequence_number = packet->SequenceNumber();
2129 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2130 packet->set_allow_retransmission(true);
2131 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2132
2133 // Simulate retransmission request.
2134 fake_clock_.AdvanceTimeMilliseconds(30);
2135 EXPECT_GT(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2136
2137 // Packet already pending, retransmission not allowed.
2138 fake_clock_.AdvanceTimeMilliseconds(30);
2139 EXPECT_EQ(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2140
2141 // Packet exiting pacer, mark as not longer pending.
2142 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2143 EXPECT_NE(packet->SequenceNumber(), media_sequence_number);
2144 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2145 packet->SetSsrc(kRtxSsrc);
2146 packet->set_retransmitted_sequence_number(media_sequence_number);
2147 packet->set_allow_retransmission(false);
2148 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2149
2150 // Retransmissions allowed again.
2151 fake_clock_.AdvanceTimeMilliseconds(30);
2152 EXPECT_GT(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2153
2154 // Retransmission of RTX packet should not be allowed.
2155 EXPECT_EQ(rtp_sender_->ReSendPacket(packet->SequenceNumber()), 0);
2156}
2157
2158TEST_P(RtpSenderTest, TrySendPacketUpdatesExtensions) {
2159 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2160 kRtpExtensionTransmissionTimeOffset,
2161 kTransmissionTimeOffsetExtensionId),
2162 0);
2163 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2164 kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId),
2165 0);
2166 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionVideoTiming,
2167 kVideoTimingExtensionId),
2168 0);
2169
2170 std::unique_ptr<RtpPacketToSend> packet =
2171 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2172 packet->set_packetization_finish_time_ms(fake_clock_.TimeInMilliseconds());
2173
2174 const int32_t kDiffMs = 10;
2175 fake_clock_.AdvanceTimeMilliseconds(kDiffMs);
2176
2177 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2178 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2179
2180 const RtpPacketReceived& received_packet = transport_.last_sent_packet();
2181
2182 EXPECT_EQ(received_packet.GetExtension<TransmissionOffset>(), kDiffMs * 90);
2183
2184 EXPECT_EQ(received_packet.GetExtension<AbsoluteSendTime>(),
2185 AbsoluteSendTime::MsTo24Bits(fake_clock_.TimeInMilliseconds()));
2186
2187 VideoSendTiming timing;
2188 EXPECT_TRUE(received_packet.GetExtension<VideoTimingExtension>(&timing));
2189 EXPECT_EQ(timing.pacer_exit_delta_ms, kDiffMs);
2190}
2191
2192TEST_P(RtpSenderTest, TrySendPacketSetsPacketOptions) {
2193 const uint16_t kPacketId = 42;
2194 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2195 kRtpExtensionTransportSequenceNumber,
2196 kTransportSequenceNumberExtensionId),
2197 0);
2198 std::unique_ptr<RtpPacketToSend> packet =
2199 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2200 packet->SetExtension<TransportSequenceNumber>(kPacketId);
2201
2202 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2203 EXPECT_CALL(send_packet_observer_, OnSendPacket);
2204 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2205
2206 EXPECT_EQ(transport_.last_options_.packet_id, kPacketId);
2207 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
2208 EXPECT_TRUE(transport_.last_options_.included_in_feedback);
2209 EXPECT_FALSE(transport_.last_options_.is_retransmit);
2210
2211 // Send another packet as retransmission, verify options are populated.
2212 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2213 packet->SetExtension<TransportSequenceNumber>(kPacketId + 1);
2214 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2215 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2216 EXPECT_TRUE(transport_.last_options_.is_retransmit);
2217}
2218
2219TEST_P(RtpSenderTest, TrySendPacketUpdatesStats) {
2220 const size_t kPayloadSize = 1000;
2221
2222 StrictMock<MockSendSideDelayObserver> send_side_delay_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02002223
2224 RtpRtcp::Configuration config;
2225 config.clock = &fake_clock_;
2226 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02002227 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02002228 config.rtx_send_ssrc = kRtxSsrc;
2229 config.flexfec_sender = &flexfec_sender_;
2230 config.send_side_delay_observer = &send_side_delay_observer;
2231 config.event_log = &mock_rtc_event_log_;
2232 config.send_packet_observer = &send_packet_observer_;
2233 rtp_sender_ = absl::make_unique<RTPSender>(config);
Erik Språng9c771c22019-06-17 16:31:53 +02002234 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2235 kRtpExtensionTransportSequenceNumber,
2236 kTransportSequenceNumberExtensionId));
2237
2238 const int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
2239
2240 std::unique_ptr<RtpPacketToSend> video_packet =
2241 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2242 video_packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2243 video_packet->SetPayloadSize(kPayloadSize);
2244 video_packet->SetExtension<TransportSequenceNumber>(1);
2245
2246 std::unique_ptr<RtpPacketToSend> rtx_packet =
2247 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2248 rtx_packet->SetSsrc(kRtxSsrc);
2249 rtx_packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2250 rtx_packet->SetPayloadSize(kPayloadSize);
2251 rtx_packet->SetExtension<TransportSequenceNumber>(2);
2252
2253 std::unique_ptr<RtpPacketToSend> fec_packet =
2254 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2255 fec_packet->SetSsrc(kFlexFecSsrc);
2256 fec_packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2257 fec_packet->SetPayloadSize(kPayloadSize);
2258 fec_packet->SetExtension<TransportSequenceNumber>(3);
2259
2260 const int64_t kDiffMs = 25;
2261 fake_clock_.AdvanceTimeMilliseconds(kDiffMs);
2262
2263 EXPECT_CALL(send_side_delay_observer,
2264 SendSideDelayUpdated(kDiffMs, kDiffMs, kDiffMs, kSsrc));
2265 EXPECT_CALL(
2266 send_side_delay_observer,
2267 SendSideDelayUpdated(kDiffMs, kDiffMs, 2 * kDiffMs, kFlexFecSsrc));
2268
2269 EXPECT_CALL(send_packet_observer_, OnSendPacket(1, capture_time_ms, kSsrc));
2270 EXPECT_TRUE(
2271 rtp_sender_->TrySendPacket(video_packet.get(), PacedPacketInfo()));
2272
2273 // Send packet observer not called for padding/retransmissions.
2274 EXPECT_CALL(send_packet_observer_, OnSendPacket(2, _, _)).Times(0);
2275 EXPECT_TRUE(rtp_sender_->TrySendPacket(rtx_packet.get(), PacedPacketInfo()));
2276
2277 EXPECT_CALL(send_packet_observer_,
2278 OnSendPacket(3, capture_time_ms, kFlexFecSsrc));
2279 EXPECT_TRUE(rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo()));
2280
2281 StreamDataCounters rtp_stats;
2282 StreamDataCounters rtx_stats;
2283 rtp_sender_->GetDataCounters(&rtp_stats, &rtx_stats);
2284 EXPECT_EQ(rtp_stats.transmitted.packets, 2u);
2285 EXPECT_EQ(rtp_stats.fec.packets, 1u);
2286 EXPECT_EQ(rtx_stats.retransmitted.packets, 1u);
2287}
2288
Erik Språng478cb462019-06-26 15:49:27 +02002289TEST_P(RtpSenderTest, GeneratePaddingResendsOldPacketsWithRtx) {
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002290 // Min requested size in order to use RTX payload.
2291 const size_t kMinPaddingSize = 50;
2292
Erik Språng478cb462019-06-26 15:49:27 +02002293 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2294 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2295 rtp_sender_->SetStorePacketsStatus(true, 1);
2296
Erik Språng0f6191d2019-07-15 20:33:40 +02002297 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2298 kRtpExtensionTransmissionTimeOffset,
2299 kTransmissionTimeOffsetExtensionId));
2300 ASSERT_EQ(
2301 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
2302 kAbsoluteSendTimeExtensionId));
2303 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2304 kRtpExtensionTransportSequenceNumber,
2305 kTransportSequenceNumberExtensionId));
2306
Erik Språng478cb462019-06-26 15:49:27 +02002307 const size_t kPayloadPacketSize = 1234;
2308 std::unique_ptr<RtpPacketToSend> packet =
2309 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2310 packet->set_allow_retransmission(true);
2311 packet->SetPayloadSize(kPayloadPacketSize);
2312 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2313
2314 // Send a dummy video packet so it ends up in the packet history.
Erik Språng0f6191d2019-07-15 20:33:40 +02002315 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Erik Språng478cb462019-06-26 15:49:27 +02002316 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2317
2318 // Generated padding has large enough budget that the video packet should be
2319 // retransmitted as padding.
Erik Språngf6468d22019-07-05 16:53:43 +02002320 std::vector<std::unique_ptr<RtpPacketToSend>> generated_packets =
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002321 rtp_sender_->GeneratePadding(kMinPaddingSize);
Erik Språngf6468d22019-07-05 16:53:43 +02002322 ASSERT_EQ(generated_packets.size(), 1u);
2323 auto& padding_packet = generated_packets.front();
2324 EXPECT_EQ(padding_packet->packet_type(), RtpPacketToSend::Type::kPadding);
2325 EXPECT_EQ(padding_packet->Ssrc(), kRtxSsrc);
2326 EXPECT_EQ(padding_packet->payload_size(),
2327 kPayloadPacketSize + kRtxHeaderSize);
Erik Språng0f6191d2019-07-15 20:33:40 +02002328 EXPECT_TRUE(padding_packet->IsExtensionReserved<TransportSequenceNumber>());
2329 EXPECT_TRUE(padding_packet->IsExtensionReserved<AbsoluteSendTime>());
2330 EXPECT_TRUE(padding_packet->IsExtensionReserved<TransmissionOffset>());
2331
2332 // Verify all header extensions are received.
2333 EXPECT_TRUE(
2334 rtp_sender_->TrySendPacket(padding_packet.get(), PacedPacketInfo()));
2335 webrtc::RTPHeader rtp_header;
2336 transport_.last_sent_packet().GetHeader(&rtp_header);
2337 EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
2338 EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
2339 EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
Erik Språng478cb462019-06-26 15:49:27 +02002340
2341 // Not enough budged for payload padding, use plain padding instead.
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002342 const size_t kPaddingBytesRequested = kMinPaddingSize - 1;
Erik Språngf6468d22019-07-05 16:53:43 +02002343
2344 size_t padding_bytes_generated = 0;
2345 generated_packets = rtp_sender_->GeneratePadding(kPaddingBytesRequested);
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002346 EXPECT_EQ(generated_packets.size(), 1u);
Erik Språngf6468d22019-07-05 16:53:43 +02002347 for (auto& packet : generated_packets) {
2348 EXPECT_EQ(packet->packet_type(), RtpPacketToSend::Type::kPadding);
2349 EXPECT_EQ(packet->Ssrc(), kRtxSsrc);
2350 EXPECT_EQ(packet->payload_size(), 0u);
2351 EXPECT_GT(packet->padding_size(), 0u);
2352 padding_bytes_generated += packet->padding_size();
Erik Språng0f6191d2019-07-15 20:33:40 +02002353
2354 EXPECT_TRUE(packet->IsExtensionReserved<TransportSequenceNumber>());
2355 EXPECT_TRUE(packet->IsExtensionReserved<AbsoluteSendTime>());
2356 EXPECT_TRUE(packet->IsExtensionReserved<TransmissionOffset>());
2357
2358 // Verify all header extensions are received.
2359 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2360 webrtc::RTPHeader rtp_header;
2361 transport_.last_sent_packet().GetHeader(&rtp_header);
2362 EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
2363 EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
2364 EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
Erik Språngf6468d22019-07-05 16:53:43 +02002365 }
2366
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002367 EXPECT_EQ(padding_bytes_generated, kMaxPaddingSize);
Erik Språng478cb462019-06-26 15:49:27 +02002368}
2369
2370TEST_P(RtpSenderTest, GeneratePaddingCreatesPurePaddingWithoutRtx) {
2371 rtp_sender_->SetStorePacketsStatus(true, 1);
Erik Språng0f6191d2019-07-15 20:33:40 +02002372 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2373 kRtpExtensionTransmissionTimeOffset,
2374 kTransmissionTimeOffsetExtensionId));
2375 ASSERT_EQ(
2376 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
2377 kAbsoluteSendTimeExtensionId));
2378 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2379 kRtpExtensionTransportSequenceNumber,
2380 kTransportSequenceNumberExtensionId));
Erik Språng478cb462019-06-26 15:49:27 +02002381
2382 const size_t kPayloadPacketSize = 1234;
2383 // Send a dummy video packet so it ends up in the packet history. Since we
2384 // are not using RTX, it should never be used as padding.
2385 std::unique_ptr<RtpPacketToSend> packet =
2386 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2387 packet->set_allow_retransmission(true);
2388 packet->SetPayloadSize(kPayloadPacketSize);
2389 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
Erik Språng0f6191d2019-07-15 20:33:40 +02002390 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Erik Språng478cb462019-06-26 15:49:27 +02002391 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2392
2393 // Payload padding not available without RTX, only generate plain padding on
2394 // the media SSRC.
2395 // Number of padding packets is the requested padding size divided by max
2396 // padding packet size, rounded up. Pure padding packets are always of the
2397 // maximum size.
2398 const size_t kPaddingBytesRequested = kPayloadPacketSize + kRtxHeaderSize;
2399 const size_t kExpectedNumPaddingPackets =
2400 (kPaddingBytesRequested + kMaxPaddingSize - 1) / kMaxPaddingSize;
Erik Språngf6468d22019-07-05 16:53:43 +02002401 size_t padding_bytes_generated = 0;
2402 std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets =
2403 rtp_sender_->GeneratePadding(kPaddingBytesRequested);
2404 EXPECT_EQ(padding_packets.size(), kExpectedNumPaddingPackets);
2405 for (auto& packet : padding_packets) {
2406 EXPECT_EQ(packet->packet_type(), RtpPacketToSend::Type::kPadding);
2407 EXPECT_EQ(packet->Ssrc(), kSsrc);
2408 EXPECT_EQ(packet->payload_size(), 0u);
2409 EXPECT_GT(packet->padding_size(), 0u);
2410 padding_bytes_generated += packet->padding_size();
Erik Språng0f6191d2019-07-15 20:33:40 +02002411 EXPECT_TRUE(packet->IsExtensionReserved<TransportSequenceNumber>());
2412 EXPECT_TRUE(packet->IsExtensionReserved<AbsoluteSendTime>());
2413 EXPECT_TRUE(packet->IsExtensionReserved<TransmissionOffset>());
2414
2415 // Verify all header extensions are received.
2416 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2417 webrtc::RTPHeader rtp_header;
2418 transport_.last_sent_packet().GetHeader(&rtp_header);
2419 EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
2420 EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
2421 EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
Erik Språngf6468d22019-07-05 16:53:43 +02002422 }
2423
2424 EXPECT_EQ(padding_bytes_generated,
2425 kExpectedNumPaddingPackets * kMaxPaddingSize);
Erik Språng478cb462019-06-26 15:49:27 +02002426}
2427
Mirko Bonadei999a72a2019-07-12 17:33:46 +00002428TEST_P(RtpSenderTest, SupportsPadding) {
2429 bool kSendingMediaStats[] = {true, false};
2430 bool kEnableRedundantPayloads[] = {true, false};
2431 RTPExtensionType kBweExtensionTypes[] = {
2432 kRtpExtensionTransportSequenceNumber,
2433 kRtpExtensionTransportSequenceNumber02, kRtpExtensionAbsoluteSendTime,
2434 kRtpExtensionTransmissionTimeOffset};
2435 const int kExtensionsId = 7;
2436
2437 for (bool sending_media : kSendingMediaStats) {
2438 rtp_sender_->SetSendingMediaStatus(sending_media);
2439 for (bool redundant_payloads : kEnableRedundantPayloads) {
2440 int rtx_mode = kRtxRetransmitted;
2441 if (redundant_payloads) {
2442 rtx_mode |= kRtxRedundantPayloads;
2443 }
2444 rtp_sender_->SetRtxStatus(rtx_mode);
2445
2446 for (auto extension_type : kBweExtensionTypes) {
2447 EXPECT_FALSE(rtp_sender_->SupportsPadding());
2448 rtp_sender_->RegisterRtpHeaderExtension(extension_type, kExtensionsId);
2449 if (!sending_media) {
2450 EXPECT_FALSE(rtp_sender_->SupportsPadding());
2451 } else {
2452 EXPECT_TRUE(rtp_sender_->SupportsPadding());
2453 if (redundant_payloads) {
2454 EXPECT_TRUE(rtp_sender_->SupportsRtxPayloadPadding());
2455 } else {
2456 EXPECT_FALSE(rtp_sender_->SupportsRtxPayloadPadding());
2457 }
2458 }
2459 rtp_sender_->DeregisterRtpHeaderExtension(extension_type);
2460 EXPECT_FALSE(rtp_sender_->SupportsPadding());
2461 }
2462 }
2463 }
2464}
2465
Erik Språnga57711c2019-07-24 10:47:20 +02002466TEST_P(RtpSenderTest, SetsCaptureTimeAndPopulatesTransmissionOffset) {
2467 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
2468 kTransmissionTimeOffsetExtensionId);
2469
2470 rtp_sender_->SetSendingMediaStatus(true);
2471 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2472 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2473 rtp_sender_->SetStorePacketsStatus(true, 10);
2474
2475 const int64_t kMissingCaptureTimeMs = 0;
2476 const uint32_t kTimestampTicksPerMs = 90;
2477 const int64_t kOffsetMs = 10;
2478
Erik Språnga57711c2019-07-24 10:47:20 +02002479 auto packet =
2480 BuildRtpPacket(kPayload, kMarkerBit, fake_clock_.TimeInMilliseconds(),
2481 kMissingCaptureTimeMs);
2482 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2483 packet->ReserveExtension<TransmissionOffset>();
2484 packet->AllocatePayload(sizeof(kPayloadData));
2485
2486 std::unique_ptr<RtpPacketToSend> packet_to_pace;
2487 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
2488 .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
2489 EXPECT_GT(packet->capture_time_ms(), 0);
2490 packet_to_pace = std::move(packet);
2491 });
2492
2493 EXPECT_TRUE(
2494 rtp_sender_->SendToNetwork(std::move(packet), kAllowRetransmission));
2495
2496 fake_clock_.AdvanceTimeMilliseconds(kOffsetMs);
2497
2498 rtp_sender_->TrySendPacket(packet_to_pace.get(), PacedPacketInfo());
Erik Språnga57711c2019-07-24 10:47:20 +02002499
2500 EXPECT_EQ(1, transport_.packets_sent());
2501 absl::optional<int32_t> transmission_time_extension =
2502 transport_.sent_packets_.back().GetExtension<TransmissionOffset>();
2503 ASSERT_TRUE(transmission_time_extension.has_value());
2504 EXPECT_EQ(*transmission_time_extension, kOffsetMs * kTimestampTicksPerMs);
2505
2506 // Retransmit packet. The RTX packet should get the same capture time as the
2507 // original packet, so offset is delta from original packet to now.
2508 fake_clock_.AdvanceTimeMilliseconds(kOffsetMs);
2509
Erik Språnga57711c2019-07-24 10:47:20 +02002510 std::unique_ptr<RtpPacketToSend> rtx_packet_to_pace;
2511 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
2512 .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
2513 EXPECT_GT(packet->capture_time_ms(), 0);
2514 rtx_packet_to_pace = std::move(packet);
2515 });
2516
2517 EXPECT_GT(rtp_sender_->ReSendPacket(kSeqNum), 0);
2518 rtp_sender_->TrySendPacket(rtx_packet_to_pace.get(), PacedPacketInfo());
Erik Språnga57711c2019-07-24 10:47:20 +02002519
2520 EXPECT_EQ(2, transport_.packets_sent());
2521 transmission_time_extension =
2522 transport_.sent_packets_.back().GetExtension<TransmissionOffset>();
2523 ASSERT_TRUE(transmission_time_extension.has_value());
2524 EXPECT_EQ(*transmission_time_extension, 2 * kOffsetMs * kTimestampTicksPerMs);
2525}
2526
Erik Språng6cacef22019-07-24 14:15:51 +02002527TEST_P(RtpSenderTestWithoutPacer, ClearHistoryOnSsrcChange) {
2528 const int64_t kRtt = 10;
2529
2530 rtp_sender_->SetSendingMediaStatus(true);
2531 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2532 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2533 rtp_sender_->SetStorePacketsStatus(true, 10);
2534 rtp_sender_->SetRtt(kRtt);
Erik Språng6cacef22019-07-24 14:15:51 +02002535
2536 // Send a packet and record its sequence numbers.
2537 SendGenericPacket();
2538 ASSERT_EQ(1u, transport_.sent_packets_.size());
2539 const uint16_t packet_seqence_number =
2540 transport_.sent_packets_.back().SequenceNumber();
2541
2542 // Advance time and make sure it can be retransmitted, even if we try to set
2543 // the ssrc the what it already is.
2544 rtp_sender_->SetSSRC(kSsrc);
2545 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2546 EXPECT_GT(rtp_sender_->ReSendPacket(packet_seqence_number), 0);
2547
2548 // Change the SSRC, then move the time and try to retransmit again. The old
2549 // packet should now be gone.
2550 rtp_sender_->SetSSRC(kSsrc + 1);
2551 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2552 EXPECT_EQ(rtp_sender_->ReSendPacket(packet_seqence_number), 0);
2553}
2554
2555TEST_P(RtpSenderTestWithoutPacer, ClearHistoryOnSequenceNumberCange) {
2556 const int64_t kRtt = 10;
2557
2558 rtp_sender_->SetSendingMediaStatus(true);
2559 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2560 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2561 rtp_sender_->SetStorePacketsStatus(true, 10);
2562 rtp_sender_->SetRtt(kRtt);
2563
2564 // Send a packet and record its sequence numbers.
2565 SendGenericPacket();
2566 ASSERT_EQ(1u, transport_.sent_packets_.size());
2567 const uint16_t packet_seqence_number =
2568 transport_.sent_packets_.back().SequenceNumber();
2569
2570 // Advance time and make sure it can be retransmitted, even if we try to set
2571 // the ssrc the what it already is.
2572 rtp_sender_->SetSequenceNumber(rtp_sender_->SequenceNumber());
2573 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2574 EXPECT_GT(rtp_sender_->ReSendPacket(packet_seqence_number), 0);
2575
2576 // Change the sequence number, then move the time and try to retransmit again.
2577 // The old packet should now be gone.
2578 rtp_sender_->SetSequenceNumber(rtp_sender_->SequenceNumber() - 1);
2579 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2580 EXPECT_EQ(rtp_sender_->ReSendPacket(packet_seqence_number), 0);
2581}
2582
Erik Språng60ffc312019-07-30 22:03:49 +02002583TEST_P(RtpSenderTest, IgnoresNackAfterDisablingMedia) {
2584 const int64_t kRtt = 10;
2585
2586 rtp_sender_->SetSendingMediaStatus(true);
2587 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2588 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2589 rtp_sender_->SetStorePacketsStatus(true, 10);
2590 rtp_sender_->SetRtt(kRtt);
2591
2592 // Send a packet so it is in the packet history.
Erik Språng60ffc312019-07-30 22:03:49 +02002593 std::unique_ptr<RtpPacketToSend> packet_to_pace;
2594 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
2595 .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
2596 packet_to_pace = std::move(packet);
2597 });
2598
2599 SendGenericPacket();
2600 rtp_sender_->TrySendPacket(packet_to_pace.get(), PacedPacketInfo());
2601
2602 ASSERT_EQ(1u, transport_.sent_packets_.size());
2603
2604 // Disable media sending and try to retransmit the packet, it should fail.
2605 rtp_sender_->SetSendingMediaStatus(false);
2606 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2607 EXPECT_LT(rtp_sender_->ReSendPacket(kSeqNum), 0);
Erik Språng60ffc312019-07-30 22:03:49 +02002608}
2609
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002610INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2611 RtpSenderTest,
Erik Språngf5815fa2019-08-21 14:27:31 +02002612 ::testing::Values(TestConfig{false},
2613 TestConfig{true}));
Erik Språngf6468d22019-07-05 16:53:43 +02002614
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002615INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2616 RtpSenderTestWithoutPacer,
Erik Språngf5815fa2019-08-21 14:27:31 +02002617 ::testing::Values(TestConfig{false},
2618 TestConfig{true}));
Niels Möllera34d7762019-02-01 14:13:29 +01002619
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +00002620} // namespace webrtc