blob: 02462b40d93fd3c6c591159cfe10550e4ceb5668 [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
kwiberg84be5112016-04-27 01:19:58 -070011#include <memory>
danilchapb8b6fbb2015-12-10 05:05:27 -080012#include <vector>
13
Karl Wiberg918f50c2018-07-05 11:40:33 +020014#include "absl/memory/memory.h"
Per Kjellandere11b7d22019-02-21 07:55:59 +010015#include "api/transport/field_trial_based_config.h"
Erik Språngf93eda12019-01-16 17:10:57 +010016#include "api/video/video_codec_constants.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/video/video_timing.h"
Elad Alon4a87e1c2017-10-03 16:11:34 +020018#include "logging/rtc_event_log/events/rtc_event.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
20#include "modules/rtp_rtcp/include/rtp_cvo.h"
21#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
22#include "modules/rtp_rtcp/include/rtp_header_parser.h"
Erik Språng59b86542019-06-23 18:24:46 +020023#include "modules/rtp_rtcp/include/rtp_packet_pacer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
25#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
26#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
philipelb3e42a42018-09-13 10:57:14 +020027#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
28#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
30#include "modules/rtp_rtcp/source/rtp_packet_received.h"
31#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
32#include "modules/rtp_rtcp/source/rtp_sender.h"
33#include "modules/rtp_rtcp/source/rtp_sender_video.h"
34#include "modules/rtp_rtcp/source/rtp_utility.h"
35#include "rtc_base/arraysize.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "rtc_base/rate_limiter.h"
37#include "test/field_trial.h"
38#include "test/gmock.h"
39#include "test/gtest.h"
40#include "test/mock_transport.h"
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000041
42namespace webrtc {
43
andrew@webrtc.org8a442592011-12-16 21:24:30 +000044namespace {
Elad Alond8d32482019-02-18 23:45:57 +010045enum : int { // The first valid value is 1.
46 kAbsoluteSendTimeExtensionId = 1,
47 kAudioLevelExtensionId,
Elad Alonccb9b752019-02-19 13:01:31 +010048 kGenericDescriptorId00,
49 kGenericDescriptorId01,
Elad Alond8d32482019-02-18 23:45:57 +010050 kMidExtensionId,
51 kRepairedRidExtensionId,
52 kRidExtensionId,
53 kTransmissionTimeOffsetExtensionId,
54 kTransportSequenceNumberExtensionId,
55 kVideoRotationExtensionId,
56 kVideoTimingExtensionId,
57};
58
andrew@webrtc.org8a442592011-12-16 21:24:30 +000059const int kPayload = 100;
Shao Changbine62202f2015-04-21 20:24:50 +080060const int kRtxPayload = 98;
andrew@webrtc.org8a442592011-12-16 21:24:30 +000061const uint32_t kTimestamp = 10;
62const uint16_t kSeqNum = 33;
brandtr9dfff292016-11-14 05:14:50 -080063const uint32_t kSsrc = 725242;
Erik Språng9c771c22019-06-17 16:31:53 +020064const uint32_t kRtxSsrc = 12345;
65const uint32_t kFlexFecSsrc = 45678;
sprang@webrtc.org30933902015-03-17 14:33:12 +000066const uint16_t kTransportSequenceNumber = 0xaabbu;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +000067const uint64_t kStartTime = 123456789;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +000068const size_t kMaxPaddingSize = 224u;
Stefan Holmera246cfb2016-08-23 17:51:42 +020069const uint8_t kPayloadData[] = {47, 11, 32, 93, 89};
spranga8ae6f22017-09-04 07:23:56 -070070const int64_t kDefaultExpectedRetransmissionTimeMs = 125;
Amit Hilbuch77938e62018-12-21 09:23:38 -080071const char kNoRid[] = "";
72const char kNoMid[] = "";
andrew@webrtc.org8a442592011-12-16 21:24:30 +000073
Danil Chapovalov5e57b172016-09-02 19:15:59 +020074using ::testing::_;
Erik Språng30a276b2019-04-23 12:00:11 +020075using ::testing::AllOf;
Erik Språng214f5432019-06-20 15:09:58 +020076using ::testing::AtLeast;
77using ::testing::DoAll;
philipelb3e42a42018-09-13 10:57:14 +020078using ::testing::ElementsAre;
Danil Chapovalov5e57b172016-09-02 19:15:59 +020079using ::testing::ElementsAreArray;
Erik Språng30a276b2019-04-23 12:00:11 +020080using ::testing::Field;
Erik Språng478cb462019-06-26 15:49:27 +020081using ::testing::Gt;
sprang168794c2017-07-06 04:38:06 -070082using ::testing::Invoke;
Erik Språng9c771c22019-06-17 16:31:53 +020083using ::testing::NiceMock;
Erik Språng478cb462019-06-26 15:49:27 +020084using ::testing::Pointee;
85using ::testing::Property;
Erik Språng214f5432019-06-20 15:09:58 +020086using ::testing::Return;
87using ::testing::SaveArg;
Danil Chapovalov84ffb352018-09-25 18:59:09 +020088using ::testing::SizeIs;
Erik Språng9c771c22019-06-17 16:31:53 +020089using ::testing::StrictMock;
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +000090
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +000091uint64_t ConvertMsToAbsSendTime(int64_t time_ms) {
Stefan Holmer0a87ffc2015-10-21 13:41:48 +020092 return (((time_ms << 18) + 500) / 1000) & 0x00ffffff;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +000093}
94
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +000095class LoopbackTransportTest : public webrtc::Transport {
96 public:
Petter Strandmark26bc6692018-05-29 08:43:35 +020097 LoopbackTransportTest() : total_bytes_sent_(0) {
danilchap12ba1862016-10-26 02:41:55 -070098 receivers_extensions_.Register(kRtpExtensionTransmissionTimeOffset,
99 kTransmissionTimeOffsetExtensionId);
100 receivers_extensions_.Register(kRtpExtensionAbsoluteSendTime,
101 kAbsoluteSendTimeExtensionId);
102 receivers_extensions_.Register(kRtpExtensionTransportSequenceNumber,
103 kTransportSequenceNumberExtensionId);
104 receivers_extensions_.Register(kRtpExtensionVideoRotation,
105 kVideoRotationExtensionId);
106 receivers_extensions_.Register(kRtpExtensionAudioLevel,
107 kAudioLevelExtensionId);
ilnik04f4d122017-06-19 07:18:55 -0700108 receivers_extensions_.Register(kRtpExtensionVideoTiming,
109 kVideoTimingExtensionId);
Steve Anton296a0ce2018-03-22 15:17:27 -0700110 receivers_extensions_.Register(kRtpExtensionMid, kMidExtensionId);
Elad Alonccb9b752019-02-19 13:01:31 +0100111 receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor00,
112 kGenericDescriptorId00);
113 receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor01,
114 kGenericDescriptorId01);
Amit Hilbuch77938e62018-12-21 09:23:38 -0800115 receivers_extensions_.Register(kRtpExtensionRtpStreamId, kRidExtensionId);
116 receivers_extensions_.Register(kRtpExtensionRepairedRtpStreamId,
117 kRepairedRidExtensionId);
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000118 }
danilchap12ba1862016-10-26 02:41:55 -0700119
stefan1d8a5062015-10-02 03:39:33 -0700120 bool SendRtp(const uint8_t* data,
121 size_t len,
122 const PacketOptions& options) override {
Petter Strandmark26bc6692018-05-29 08:43:35 +0200123 last_options_ = options;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000124 total_bytes_sent_ += len;
danilchap12ba1862016-10-26 02:41:55 -0700125 sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
126 EXPECT_TRUE(sent_packets_.back().Parse(data, len));
pbos2d566682015-09-28 09:59:31 -0700127 return true;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000128 }
danilchap162abd32015-12-10 02:39:40 -0800129 bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
danilchap12ba1862016-10-26 02:41:55 -0700130 const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
131 int packets_sent() { return sent_packets_.size(); }
132
pbos@webrtc.org72491b92014-07-10 16:24:54 +0000133 size_t total_bytes_sent_;
Petter Strandmark26bc6692018-05-29 08:43:35 +0200134 PacketOptions last_options_;
danilchap12ba1862016-10-26 02:41:55 -0700135 std::vector<RtpPacketReceived> sent_packets_;
136
137 private:
138 RtpHeaderExtensionMap receivers_extensions_;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000139};
140
Elad Alon4a87e1c2017-10-03 16:11:34 +0200141MATCHER_P(SameRtcEventTypeAs, value, "") {
142 return value == arg->GetType();
143}
144
Erik Språngf6468d22019-07-05 16:53:43 +0200145struct TestConfig {
146 TestConfig(bool with_overhead, bool pacer_references_packets)
147 : with_overhead(with_overhead),
148 pacer_references_packets(pacer_references_packets) {}
149 bool with_overhead = false;
150 bool pacer_references_packets = false;
151};
152
153std::string ToFieldTrialString(TestConfig config) {
154 std::string field_trials;
155 if (config.with_overhead) {
156 field_trials += "WebRTC-SendSideBwe-WithOverhead/Enabled/";
157 }
158 if (config.pacer_references_packets) {
159 field_trials += "WebRTC-Pacer-LegacyPacketReferencing/Enabled/";
160 } else {
161 field_trials += "WebRTC-Pacer-LegacyPacketReferencing/Disabled/";
162 }
163 return field_trials;
164}
165
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000166} // namespace
167
Erik Språng59b86542019-06-23 18:24:46 +0200168class MockRtpPacketPacer : public RtpPacketPacer {
sprangebbf8a82015-09-21 15:11:14 -0700169 public:
Erik Språng59b86542019-06-23 18:24:46 +0200170 MockRtpPacketPacer() {}
171 virtual ~MockRtpPacketPacer() {}
172
173 MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend>));
sprangebbf8a82015-09-21 15:11:14 -0700174
Peter Boströme23e7372015-10-08 11:44:14 +0200175 MOCK_METHOD6(InsertPacket,
176 void(Priority priority,
sprangebbf8a82015-09-21 15:11:14 -0700177 uint32_t ssrc,
178 uint16_t sequence_number,
179 int64_t capture_time_ms,
180 size_t bytes,
181 bool retransmission));
182};
183
Stefan Holmerf5dca482016-01-27 12:58:51 +0100184class MockTransportSequenceNumberAllocator
185 : public TransportSequenceNumberAllocator {
186 public:
187 MOCK_METHOD0(AllocateSequenceNumber, uint16_t());
188};
189
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200190class MockSendSideDelayObserver : public SendSideDelayObserver {
191 public:
Henrik Boström9fe18342019-05-16 18:38:20 +0200192 MOCK_METHOD4(SendSideDelayUpdated, void(int, int, uint64_t, uint32_t));
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200193};
194
asapersson35151f32016-05-02 23:44:01 -0700195class MockSendPacketObserver : public SendPacketObserver {
196 public:
197 MOCK_METHOD3(OnSendPacket, void(uint16_t, int64_t, uint32_t));
198};
199
Stefan Holmera246cfb2016-08-23 17:51:42 +0200200class MockTransportFeedbackObserver : public TransportFeedbackObserver {
201 public:
Erik Språng30a276b2019-04-23 12:00:11 +0200202 MOCK_METHOD1(OnAddPacket, void(const RtpPacketSendInfo&));
Stefan Holmera246cfb2016-08-23 17:51:42 +0200203 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -0800204 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
Stefan Holmera246cfb2016-08-23 17:51:42 +0200205};
206
minyue3a407ee2017-04-03 01:10:33 -0700207class MockOverheadObserver : public OverheadObserver {
208 public:
209 MOCK_METHOD1(OnOverheadChanged, void(size_t overhead_bytes_per_packet));
210};
211
Erik Språngf6468d22019-07-05 16:53:43 +0200212class RtpSenderTest : public ::testing::TestWithParam<TestConfig> {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000213 protected:
214 RtpSenderTest()
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000215 : fake_clock_(kStartTime),
terelius429c3452016-01-21 05:42:04 -0800216 mock_rtc_event_log_(),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000217 mock_paced_sender_(),
sprangcd349d92016-07-13 09:11:28 -0700218 retransmission_rate_limiter_(&fake_clock_, 1000),
Erik Språng4580ca22019-07-04 10:38:43 +0200219 flexfec_sender_(0,
220 kFlexFecSsrc,
221 kSsrc,
222 "",
223 std::vector<RtpExtension>(),
224 std::vector<RtpExtensionSize>(),
225 nullptr,
226 &fake_clock_),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000227 rtp_sender_(),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000228 transport_(),
minyue3a407ee2017-04-03 01:10:33 -0700229 kMarkerBit(true),
Erik Språngf6468d22019-07-05 16:53:43 +0200230 field_trials_(ToFieldTrialString(GetParam())) {}
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +0000231
Erik Språng7b52f102018-02-07 14:37:37 +0100232 void SetUp() override { SetUpRtpSender(true, false); }
Peter Boströme23e7372015-10-08 11:44:14 +0200233
Erik Språng7b52f102018-02-07 14:37:37 +0100234 void SetUpRtpSender(bool pacer, bool populate_network2) {
Erik Språng4580ca22019-07-04 10:38:43 +0200235 RtpRtcp::Configuration config;
236 config.clock = &fake_clock_;
237 config.outgoing_transport = &transport_;
238 config.media_send_ssrc = kSsrc;
239 config.rtx_send_ssrc = kRtxSsrc;
240 config.flexfec_sender = &flexfec_sender_;
241 config.transport_sequence_number_allocator = &seq_num_allocator_;
242 config.event_log = &mock_rtc_event_log_;
243 config.send_packet_observer = &send_packet_observer_;
244 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
245 config.paced_sender = pacer ? &mock_paced_sender_ : nullptr;
246 config.populate_network2_timestamp = populate_network2;
247 rtp_sender_.reset(new RTPSender(config));
brandtr9dfff292016-11-14 05:14:50 -0800248 rtp_sender_->SetSequenceNumber(kSeqNum);
danilchap71fead22016-08-18 02:01:49 -0700249 rtp_sender_->SetTimestampOffset(0);
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +0000250 }
251
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000252 SimulatedClock fake_clock_;
Erik Språng9c771c22019-06-17 16:31:53 +0200253 NiceMock<MockRtcEventLog> mock_rtc_event_log_;
Erik Språng59b86542019-06-23 18:24:46 +0200254 MockRtpPacketPacer mock_paced_sender_;
Erik Språng9c771c22019-06-17 16:31:53 +0200255 StrictMock<MockTransportSequenceNumberAllocator> seq_num_allocator_;
256 StrictMock<MockSendPacketObserver> send_packet_observer_;
257 StrictMock<MockTransportFeedbackObserver> feedback_observer_;
sprangcd349d92016-07-13 09:11:28 -0700258 RateLimiter retransmission_rate_limiter_;
Erik Språng4580ca22019-07-04 10:38:43 +0200259 FlexfecSender flexfec_sender_;
kwiberg84be5112016-04-27 01:19:58 -0700260 std::unique_ptr<RTPSender> rtp_sender_;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000261 LoopbackTransportTest transport_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000262 const bool kMarkerBit;
minyue3a407ee2017-04-03 01:10:33 -0700263 test::ScopedFieldTrials field_trials_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000264
danilchapb6f1fb52016-10-19 06:11:39 -0700265 std::unique_ptr<RtpPacketToSend> BuildRtpPacket(int payload_type,
266 bool marker_bit,
267 uint32_t timestamp,
268 int64_t capture_time_ms) {
269 auto packet = rtp_sender_->AllocatePacket();
270 packet->SetPayloadType(payload_type);
271 packet->SetMarker(marker_bit);
272 packet->SetTimestamp(timestamp);
273 packet->set_capture_time_ms(capture_time_ms);
274 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
275 return packet;
276 }
277
Erik Språngf6468d22019-07-05 16:53:43 +0200278 std::unique_ptr<RtpPacketToSend> SendPacket(int64_t capture_time_ms,
279 int payload_length) {
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000280 uint32_t timestamp = capture_time_ms * 90;
danilchapb6f1fb52016-10-19 06:11:39 -0700281 auto packet =
282 BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
283 packet->AllocatePayload(payload_length);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000284
285 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +0200286 EXPECT_TRUE(rtp_sender_->SendToNetwork(
287 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission,
288 RtpPacketSender::kNormalPriority));
289 return packet;
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000290 }
asapersson35151f32016-05-02 23:44:01 -0700291
Erik Språngf6468d22019-07-05 16:53:43 +0200292 std::unique_ptr<RtpPacketToSend> SendGenericPacket() {
asapersson35151f32016-05-02 23:44:01 -0700293 const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
Erik Språngf6468d22019-07-05 16:53:43 +0200294 return SendPacket(kCaptureTimeMs, sizeof(kPayloadData));
asapersson35151f32016-05-02 23:44:01 -0700295 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000296};
297
Peter Boströme23e7372015-10-08 11:44:14 +0200298// TODO(pbos): Move tests over from WithoutPacer to RtpSenderTest as this is our
299// default code path.
300class RtpSenderTestWithoutPacer : public RtpSenderTest {
301 public:
Erik Språng7b52f102018-02-07 14:37:37 +0100302 void SetUp() override { SetUpRtpSender(false, false); }
Peter Boströme23e7372015-10-08 11:44:14 +0200303};
304
minyue3a407ee2017-04-03 01:10:33 -0700305TEST_P(RtpSenderTestWithoutPacer, AllocatePacketSetCsrc) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200306 // Configure rtp_sender with csrc.
307 std::vector<uint32_t> csrcs;
308 csrcs.push_back(0x23456789);
309 rtp_sender_->SetCsrcs(csrcs);
310
311 auto packet = rtp_sender_->AllocatePacket();
312
313 ASSERT_TRUE(packet);
314 EXPECT_EQ(rtp_sender_->SSRC(), packet->Ssrc());
315 EXPECT_EQ(csrcs, packet->Csrcs());
316}
317
minyue3a407ee2017-04-03 01:10:33 -0700318TEST_P(RtpSenderTestWithoutPacer, AllocatePacketReserveExtensions) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200319 // Configure rtp_sender with extensions.
320 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
321 kRtpExtensionTransmissionTimeOffset,
322 kTransmissionTimeOffsetExtensionId));
323 ASSERT_EQ(
324 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
325 kAbsoluteSendTimeExtensionId));
326 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
327 kAudioLevelExtensionId));
328 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
329 kRtpExtensionTransportSequenceNumber,
330 kTransportSequenceNumberExtensionId));
331 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
332 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
333
334 auto packet = rtp_sender_->AllocatePacket();
335
336 ASSERT_TRUE(packet);
337 // Preallocate BWE extensions RtpSender set itself.
338 EXPECT_TRUE(packet->HasExtension<TransmissionOffset>());
339 EXPECT_TRUE(packet->HasExtension<AbsoluteSendTime>());
340 EXPECT_TRUE(packet->HasExtension<TransportSequenceNumber>());
341 // Do not allocate media specific extensions.
342 EXPECT_FALSE(packet->HasExtension<AudioLevel>());
343 EXPECT_FALSE(packet->HasExtension<VideoOrientation>());
344}
345
minyue3a407ee2017-04-03 01:10:33 -0700346TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberAdvanceSequenceNumber) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200347 auto packet = rtp_sender_->AllocatePacket();
348 ASSERT_TRUE(packet);
349 const uint16_t sequence_number = rtp_sender_->SequenceNumber();
350
351 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
352
353 EXPECT_EQ(sequence_number, packet->SequenceNumber());
354 EXPECT_EQ(sequence_number + 1, rtp_sender_->SequenceNumber());
355}
356
minyue3a407ee2017-04-03 01:10:33 -0700357TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberFailsOnNotSending) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200358 auto packet = rtp_sender_->AllocatePacket();
359 ASSERT_TRUE(packet);
360
361 rtp_sender_->SetSendingMediaStatus(false);
362 EXPECT_FALSE(rtp_sender_->AssignSequenceNumber(packet.get()));
363}
364
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100365TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberMayAllowPaddingOnVideo) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200366 constexpr size_t kPaddingSize = 100;
367 auto packet = rtp_sender_->AllocatePacket();
368 ASSERT_TRUE(packet);
369
philipel8aadd502017-02-23 02:56:13 -0800370 ASSERT_FALSE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200371 packet->SetMarker(false);
372 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100373 // Packet without marker bit doesn't allow padding on video stream.
philipel8aadd502017-02-23 02:56:13 -0800374 EXPECT_FALSE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200375
376 packet->SetMarker(true);
377 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
378 // Packet with marker bit allows send padding.
philipel8aadd502017-02-23 02:56:13 -0800379 EXPECT_TRUE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200380}
381
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100382TEST_P(RtpSenderTest, AssignSequenceNumberAllowsPaddingOnAudio) {
383 MockTransport transport;
Erik Språng4580ca22019-07-04 10:38:43 +0200384 RtpRtcp::Configuration config;
385 config.audio = true;
386 config.clock = &fake_clock_;
387 config.outgoing_transport = &transport;
388 config.paced_sender = &mock_paced_sender_;
389 config.media_send_ssrc = kSsrc;
390 config.event_log = &mock_rtc_event_log_;
391 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
392 rtp_sender_ = absl::make_unique<RTPSender>(config);
393
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100394 rtp_sender_->SetTimestampOffset(0);
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100395
396 std::unique_ptr<RtpPacketToSend> audio_packet = rtp_sender_->AllocatePacket();
397 // Padding on audio stream allowed regardless of marker in the last packet.
398 audio_packet->SetMarker(false);
399 audio_packet->SetPayloadType(kPayload);
400 rtp_sender_->AssignSequenceNumber(audio_packet.get());
401
402 const size_t kPaddingSize = 59;
403 EXPECT_CALL(transport, SendRtp(_, kPaddingSize + kRtpHeaderSize, _))
Erik Språng214f5432019-06-20 15:09:58 +0200404 .WillOnce(Return(true));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100405 EXPECT_EQ(kPaddingSize,
406 rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
407
408 // Requested padding size is too small, will send a larger one.
409 const size_t kMinPaddingSize = 50;
410 EXPECT_CALL(transport, SendRtp(_, kMinPaddingSize + kRtpHeaderSize, _))
Erik Språng214f5432019-06-20 15:09:58 +0200411 .WillOnce(Return(true));
Yves Gerey665174f2018-06-19 15:03:05 +0200412 EXPECT_EQ(kMinPaddingSize, rtp_sender_->TimeToSendPadding(kMinPaddingSize - 5,
413 PacedPacketInfo()));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100414}
415
minyue3a407ee2017-04-03 01:10:33 -0700416TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberSetPaddingTimestamps) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200417 constexpr size_t kPaddingSize = 100;
418 auto packet = rtp_sender_->AllocatePacket();
419 ASSERT_TRUE(packet);
420 packet->SetMarker(true);
421 packet->SetTimestamp(kTimestamp);
422
423 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
philipel8aadd502017-02-23 02:56:13 -0800424 ASSERT_TRUE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200425
426 ASSERT_EQ(1u, transport_.sent_packets_.size());
danilchap12ba1862016-10-26 02:41:55 -0700427 // Verify padding packet timestamp.
428 EXPECT_EQ(kTimestamp, transport_.last_sent_packet().Timestamp());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200429}
430
minyue3a407ee2017-04-03 01:10:33 -0700431TEST_P(RtpSenderTestWithoutPacer,
432 TransportFeedbackObserverGetsCorrectByteCount) {
433 constexpr int kRtpOverheadBytesPerPacket = 12 + 8;
Erik Språng9c771c22019-06-17 16:31:53 +0200434 NiceMock<MockOverheadObserver> mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +0200435
436 RtpRtcp::Configuration config;
437 config.clock = &fake_clock_;
438 config.outgoing_transport = &transport_;
439 config.media_send_ssrc = kSsrc;
440 config.transport_sequence_number_allocator = &seq_num_allocator_;
441 config.transport_feedback_callback = &feedback_observer_;
442 config.event_log = &mock_rtc_event_log_;
443 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
444 config.overhead_observer = &mock_overhead_observer;
445 rtp_sender_ = absl::make_unique<RTPSender>(config);
446
minyue3a407ee2017-04-03 01:10:33 -0700447 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
448 kRtpExtensionTransportSequenceNumber,
449 kTransportSequenceNumberExtensionId));
450 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200451 .WillOnce(Return(kTransportSequenceNumber));
minyue3a407ee2017-04-03 01:10:33 -0700452
453 const size_t expected_bytes =
Erik Språngf6468d22019-07-05 16:53:43 +0200454 GetParam().with_overhead
455 ? sizeof(kPayloadData) + kRtpOverheadBytesPerPacket
456 : sizeof(kPayloadData);
minyue3a407ee2017-04-03 01:10:33 -0700457
458 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200459 OnAddPacket(AllOf(
460 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
461 Field(&RtpPacketSendInfo::transport_sequence_number,
462 kTransportSequenceNumber),
463 Field(&RtpPacketSendInfo::rtp_sequence_number,
464 rtp_sender_->SequenceNumber()),
465 Field(&RtpPacketSendInfo::length, expected_bytes),
466 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
minyue3a407ee2017-04-03 01:10:33 -0700467 .Times(1);
468 EXPECT_CALL(mock_overhead_observer,
469 OnOverheadChanged(kRtpOverheadBytesPerPacket))
470 .Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100471 SendGenericPacket();
minyue3a407ee2017-04-03 01:10:33 -0700472}
473
474TEST_P(RtpSenderTestWithoutPacer, SendsPacketsWithTransportSequenceNumber) {
Erik Språng4580ca22019-07-04 10:38:43 +0200475 RtpRtcp::Configuration config;
476 config.clock = &fake_clock_;
477 config.outgoing_transport = &transport_;
478 config.media_send_ssrc = kSsrc;
479 config.transport_sequence_number_allocator = &seq_num_allocator_;
480 config.transport_feedback_callback = &feedback_observer_;
481 config.event_log = &mock_rtc_event_log_;
482 config.send_packet_observer = &send_packet_observer_;
483 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
484 rtp_sender_ = absl::make_unique<RTPSender>(config);
485
Stefan Holmerf5dca482016-01-27 12:58:51 +0100486 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
487 kRtpExtensionTransportSequenceNumber,
488 kTransportSequenceNumberExtensionId));
489
Stefan Holmerf5dca482016-01-27 12:58:51 +0100490 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200491 .WillOnce(Return(kTransportSequenceNumber));
asapersson35151f32016-05-02 23:44:01 -0700492 EXPECT_CALL(send_packet_observer_,
493 OnSendPacket(kTransportSequenceNumber, _, _))
494 .Times(1);
minyue3a407ee2017-04-03 01:10:33 -0700495
496 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200497 OnAddPacket(AllOf(
498 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
499 Field(&RtpPacketSendInfo::transport_sequence_number,
500 kTransportSequenceNumber),
501 Field(&RtpPacketSendInfo::rtp_sequence_number,
502 rtp_sender_->SequenceNumber()),
503 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
Stefan Holmera246cfb2016-08-23 17:51:42 +0200504 .Times(1);
asapersson35151f32016-05-02 23:44:01 -0700505
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100506 SendGenericPacket();
Stefan Holmerf5dca482016-01-27 12:58:51 +0100507
danilchap12ba1862016-10-26 02:41:55 -0700508 const auto& packet = transport_.last_sent_packet();
509 uint16_t transport_seq_no;
510 ASSERT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
511 EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200512 EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200513 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200514}
515
516TEST_P(RtpSenderTestWithoutPacer, PacketOptionsNoRetransmission) {
Erik Språng4580ca22019-07-04 10:38:43 +0200517 RtpRtcp::Configuration config;
518 config.clock = &fake_clock_;
519 config.outgoing_transport = &transport_;
520 config.media_send_ssrc = kSsrc;
521 config.transport_sequence_number_allocator = &seq_num_allocator_;
522 config.transport_feedback_callback = &feedback_observer_;
523 config.event_log = &mock_rtc_event_log_;
524 config.send_packet_observer = &send_packet_observer_;
525 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
526 rtp_sender_ = absl::make_unique<RTPSender>(config);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200527
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100528 SendGenericPacket();
Petter Strandmark26bc6692018-05-29 08:43:35 +0200529
530 EXPECT_FALSE(transport_.last_options_.is_retransmit);
Stefan Holmerf5dca482016-01-27 12:58:51 +0100531}
532
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200533TEST_P(RtpSenderTestWithoutPacer,
534 SetsIncludedInFeedbackWhenTransportSequenceNumberExtensionIsRegistered) {
535 SetUpRtpSender(false, false);
536 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
537 kTransportSequenceNumberExtensionId);
538 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200539 .WillOnce(Return(kTransportSequenceNumber));
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200540 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100541 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200542 EXPECT_TRUE(transport_.last_options_.included_in_feedback);
543}
544
545TEST_P(
546 RtpSenderTestWithoutPacer,
547 SetsIncludedInAllocationWhenTransportSequenceNumberExtensionIsRegistered) {
548 SetUpRtpSender(false, false);
549 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
550 kTransportSequenceNumberExtensionId);
551 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200552 .WillOnce(Return(kTransportSequenceNumber));
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200553 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100554 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200555 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
556}
557
558TEST_P(RtpSenderTestWithoutPacer,
559 SetsIncludedInAllocationWhenForcedAsPartOfAllocation) {
560 SetUpRtpSender(false, false);
561 rtp_sender_->SetAsPartOfAllocation(true);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100562 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200563 EXPECT_FALSE(transport_.last_options_.included_in_feedback);
564 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
565}
566
567TEST_P(RtpSenderTestWithoutPacer, DoesnSetIncludedInAllocationByDefault) {
568 SetUpRtpSender(false, false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100569 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200570 EXPECT_FALSE(transport_.last_options_.included_in_feedback);
571 EXPECT_FALSE(transport_.last_options_.included_in_allocation);
stefana23fc622016-07-28 07:56:38 -0700572}
asapersson35151f32016-05-02 23:44:01 -0700573
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200574TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
Erik Språng9c771c22019-06-17 16:31:53 +0200575 StrictMock<MockSendSideDelayObserver> send_side_delay_observer_;
Erik Språng4580ca22019-07-04 10:38:43 +0200576
577 RtpRtcp::Configuration config;
578 config.clock = &fake_clock_;
579 config.outgoing_transport = &transport_;
580 config.media_send_ssrc = kSsrc;
581 config.send_side_delay_observer = &send_side_delay_observer_;
582 config.event_log = &mock_rtc_event_log_;
583 rtp_sender_ = absl::make_unique<RTPSender>(config);
584
Niels Möller5fe95102019-03-04 16:49:25 +0100585 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +0100586 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +0200587 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +0100588 FieldTrialBasedConfig());
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200589
590 const uint8_t kPayloadType = 127;
Niels Möller8a40edd2019-01-24 18:04:44 +0100591 const char payload_name[] = "GENERIC";
Niels Möller59ab1cf2019-02-06 22:48:11 +0100592
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +0200593 rtp_sender_video.RegisterPayloadType(kPayloadType, payload_name,
594 /*raw_payload=*/false);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100595
596 const uint32_t kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200597 RTPVideoHeader video_header;
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200598
Henrik Boström9fe18342019-05-16 18:38:20 +0200599 // Send packet with 10 ms send-side delay. The average, max and total should
600 // be 10 ms.
601 EXPECT_CALL(send_side_delay_observer_,
602 SendSideDelayUpdated(10, 10, 10, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200603 .Times(1);
604 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
605 fake_clock_.AdvanceTimeMilliseconds(10);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100606 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100607 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200608 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100609 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200610 kDefaultExpectedRetransmissionTimeMs));
611
Henrik Boström9fe18342019-05-16 18:38:20 +0200612 // Send another packet with 20 ms delay. The average, max and total should be
613 // 15, 20 and 30 ms respectively.
614 EXPECT_CALL(send_side_delay_observer_,
615 SendSideDelayUpdated(15, 20, 30, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200616 .Times(1);
617 fake_clock_.AdvanceTimeMilliseconds(10);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100618 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100619 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200620 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100621 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200622 kDefaultExpectedRetransmissionTimeMs));
623
624 // Send another packet at the same time, which replaces the last packet.
625 // 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 +0200626 // The total counter stays the same though.
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200627 // TODO(terelius): Is is not clear that this is the right behavior.
Henrik Boström9fe18342019-05-16 18:38:20 +0200628 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(5, 10, 30, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200629 .Times(1);
630 capture_time_ms = fake_clock_.TimeInMilliseconds();
Niels Möller59ab1cf2019-02-06 22:48:11 +0100631 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100632 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200633 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100634 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200635 kDefaultExpectedRetransmissionTimeMs));
636
637 // Send a packet 1 second later. The earlier packets should have timed
Henrik Boström9fe18342019-05-16 18:38:20 +0200638 // out, so both max and average should be the delay of this packet. The total
639 // keeps increasing.
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200640 fake_clock_.AdvanceTimeMilliseconds(1000);
641 capture_time_ms = fake_clock_.TimeInMilliseconds();
642 fake_clock_.AdvanceTimeMilliseconds(1);
Henrik Boström9fe18342019-05-16 18:38:20 +0200643 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(1, 1, 31, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200644 .Times(1);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100645 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100646 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200647 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100648 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200649 kDefaultExpectedRetransmissionTimeMs));
650}
651
minyue3a407ee2017-04-03 01:10:33 -0700652TEST_P(RtpSenderTestWithoutPacer, OnSendPacketUpdated) {
stefana23fc622016-07-28 07:56:38 -0700653 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
654 kRtpExtensionTransportSequenceNumber,
655 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -0700656 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
Erik Språng214f5432019-06-20 15:09:58 +0200657 .WillOnce(Return(kTransportSequenceNumber));
asapersson35151f32016-05-02 23:44:01 -0700658 EXPECT_CALL(send_packet_observer_,
659 OnSendPacket(kTransportSequenceNumber, _, _))
660 .Times(1);
661
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100662 SendGenericPacket();
asapersson35151f32016-05-02 23:44:01 -0700663}
664
minyue3a407ee2017-04-03 01:10:33 -0700665TEST_P(RtpSenderTest, SendsPacketsWithTransportSequenceNumber) {
Erik Språng4580ca22019-07-04 10:38:43 +0200666 RtpRtcp::Configuration config;
667 config.clock = &fake_clock_;
668 config.outgoing_transport = &transport_;
669 config.paced_sender = &mock_paced_sender_;
670 config.media_send_ssrc = kSsrc;
671 config.transport_sequence_number_allocator = &seq_num_allocator_;
672 config.transport_feedback_callback = &feedback_observer_;
673 config.event_log = &mock_rtc_event_log_;
674 config.send_packet_observer = &send_packet_observer_;
675 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
676 rtp_sender_ = absl::make_unique<RTPSender>(config);
677
brandtr9dfff292016-11-14 05:14:50 -0800678 rtp_sender_->SetSequenceNumber(kSeqNum);
Stefan Holmera246cfb2016-08-23 17:51:42 +0200679 rtp_sender_->SetStorePacketsStatus(true, 10);
680 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
681 kRtpExtensionTransportSequenceNumber,
682 kTransportSequenceNumberExtensionId));
683
Stefan Holmera246cfb2016-08-23 17:51:42 +0200684 EXPECT_CALL(send_packet_observer_,
685 OnSendPacket(kTransportSequenceNumber, _, _))
686 .Times(1);
minyue3a407ee2017-04-03 01:10:33 -0700687 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200688 OnAddPacket(AllOf(
689 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
690 Field(&RtpPacketSendInfo::transport_sequence_number,
691 kTransportSequenceNumber),
692 Field(&RtpPacketSendInfo::rtp_sequence_number,
693 rtp_sender_->SequenceNumber()),
694 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
Stefan Holmera246cfb2016-08-23 17:51:42 +0200695 .Times(1);
696
Erik Språngf6468d22019-07-05 16:53:43 +0200697 if (GetParam().pacer_references_packets) {
698 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
699 SendGenericPacket();
700 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
701 .WillOnce(Return(kTransportSequenceNumber));
702 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
703 fake_clock_.TimeInMilliseconds(), false,
704 PacedPacketInfo());
705 } else {
706 EXPECT_CALL(
707 mock_paced_sender_,
708 EnqueuePacket(AllOf(
709 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
710 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
711 auto packet = SendGenericPacket();
712 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
713 // Transport sequence number is set by PacketRouter, before TrySendPacket().
714 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
715 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
716 }
Stefan Holmera246cfb2016-08-23 17:51:42 +0200717
danilchap12ba1862016-10-26 02:41:55 -0700718 const auto& packet = transport_.last_sent_packet();
719 uint16_t transport_seq_no;
720 EXPECT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
721 EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200722 EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
Stefan Holmera246cfb2016-08-23 17:51:42 +0200723}
724
Erik Språng7b52f102018-02-07 14:37:37 +0100725TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) {
ilnik04f4d122017-06-19 07:18:55 -0700726 rtp_sender_->SetStorePacketsStatus(true, 10);
727 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
728 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
729 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
730 auto packet = rtp_sender_->AllocatePacket();
731 packet->SetPayloadType(kPayload);
732 packet->SetMarker(true);
733 packet->SetTimestamp(kTimestamp);
734 packet->set_capture_time_ms(capture_time_ms);
ilnik2edc6842017-07-06 03:06:50 -0700735 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
ilnik04f4d122017-06-19 07:18:55 -0700736 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
737 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
738 size_t packet_size = packet->size();
ilnik04f4d122017-06-19 07:18:55 -0700739
740 const int kStoredTimeInMs = 100;
Erik Språngf6468d22019-07-05 16:53:43 +0200741 if (GetParam().pacer_references_packets) {
Erik Språng7b52f102018-02-07 14:37:37 +0100742 EXPECT_CALL(
743 mock_paced_sender_,
744 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _));
745 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
746 kAllowRetransmission,
747 RtpPacketSender::kNormalPriority));
Erik Språngf6468d22019-07-05 16:53:43 +0200748 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
749 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
750 PacedPacketInfo());
751 } else {
752 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
753 EXPECT_CALL(
754 mock_paced_sender_,
755 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
756 EXPECT_TRUE(rtp_sender_->SendToNetwork(
757 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
758 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
759 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språng7b52f102018-02-07 14:37:37 +0100760 }
ilnik04f4d122017-06-19 07:18:55 -0700761 EXPECT_EQ(1, transport_.packets_sent());
762 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
763
danilchapce251812017-09-11 12:24:41 -0700764 VideoSendTiming video_timing;
765 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
766 &video_timing));
767 EXPECT_EQ(kStoredTimeInMs, video_timing.pacer_exit_delta_ms);
Erik Språng7b52f102018-02-07 14:37:37 +0100768}
ilnik04f4d122017-06-19 07:18:55 -0700769
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100770TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithPacer) {
771 SetUpRtpSender(/*pacer=*/true, /*populate_network2=*/true);
Erik Språng7b52f102018-02-07 14:37:37 +0100772 rtp_sender_->SetStorePacketsStatus(true, 10);
773 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
774 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
775 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
776 auto packet = rtp_sender_->AllocatePacket();
777 packet->SetPayloadType(kPayload);
778 packet->SetMarker(true);
779 packet->SetTimestamp(kTimestamp);
780 packet->set_capture_time_ms(capture_time_ms);
781 const uint16_t kPacerExitMs = 1234u;
782 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, kPacerExitMs, 0u, 0u, true};
783 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
784 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
785 size_t packet_size = packet->size();
786
787 const int kStoredTimeInMs = 100;
Erik Språngf6468d22019-07-05 16:53:43 +0200788
789 if (GetParam().pacer_references_packets) {
Erik Språng7b52f102018-02-07 14:37:37 +0100790 EXPECT_CALL(
791 mock_paced_sender_,
792 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _));
793 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
794 kAllowRetransmission,
795 RtpPacketSender::kNormalPriority));
Erik Språngf6468d22019-07-05 16:53:43 +0200796 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
797 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
798 PacedPacketInfo());
799 } else {
800 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
801 EXPECT_CALL(
802 mock_paced_sender_,
803 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
804 EXPECT_TRUE(rtp_sender_->SendToNetwork(
805 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission,
806 RtpPacketSender::kNormalPriority));
807 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
808 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språng7b52f102018-02-07 14:37:37 +0100809 }
Erik Språngf6468d22019-07-05 16:53:43 +0200810
Erik Språng7b52f102018-02-07 14:37:37 +0100811 EXPECT_EQ(1, transport_.packets_sent());
ilnik04f4d122017-06-19 07:18:55 -0700812 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
813
Erik Språng7b52f102018-02-07 14:37:37 +0100814 VideoSendTiming video_timing;
danilchapce251812017-09-11 12:24:41 -0700815 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
816 &video_timing));
Erik Språng7b52f102018-02-07 14:37:37 +0100817 EXPECT_EQ(kStoredTimeInMs, video_timing.network2_timestamp_delta_ms);
818 EXPECT_EQ(kPacerExitMs, video_timing.pacer_exit_delta_ms);
ilnik04f4d122017-06-19 07:18:55 -0700819}
820
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100821TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithoutPacer) {
822 SetUpRtpSender(/*pacer=*/false, /*populate_network2=*/true);
823 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
824 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
825 auto packet = rtp_sender_->AllocatePacket();
826 packet->SetMarker(true);
827 packet->set_capture_time_ms(fake_clock_.TimeInMilliseconds());
828 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
829 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
830 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
831
832 const int kPropagateTimeMs = 10;
833 fake_clock_.AdvanceTimeMilliseconds(kPropagateTimeMs);
834
835 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
836 kAllowRetransmission,
837 RtpPacketSender::kNormalPriority));
838
839 EXPECT_EQ(1, transport_.packets_sent());
840 absl::optional<VideoSendTiming> video_timing =
841 transport_.last_sent_packet().GetExtension<VideoTimingExtension>();
842 ASSERT_TRUE(video_timing);
843 EXPECT_EQ(kPropagateTimeMs, video_timing->network2_timestamp_delta_ms);
844}
845
minyue3a407ee2017-04-03 01:10:33 -0700846TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) {
Elad Alon4a87e1c2017-10-03 16:11:34 +0200847 EXPECT_CALL(mock_rtc_event_log_,
848 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000849
pwestin@webrtc.orgc66e8b32012-11-07 17:01:04 +0000850 rtp_sender_->SetStorePacketsStatus(true, 10);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000851 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800852 kRtpExtensionTransmissionTimeOffset,
853 kTransmissionTimeOffsetExtensionId));
854 EXPECT_EQ(
855 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
856 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000857 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700858 auto packet =
859 BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
860 size_t packet_size = packet->size();
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000861
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000862 const int kStoredTimeInMs = 100;
Erik Språngf6468d22019-07-05 16:53:43 +0200863 if (GetParam().pacer_references_packets) {
864 EXPECT_CALL(mock_paced_sender_,
865 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum,
866 _, _, _));
867 // Packet should be stored in a send bucket.
868 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
869 kAllowRetransmission,
870 RtpPacketSender::kNormalPriority));
871 EXPECT_EQ(0, transport_.packets_sent());
872 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
873 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
874 PacedPacketInfo());
875 } else {
876 EXPECT_CALL(
877 mock_paced_sender_,
878 EnqueuePacket(AllOf(
879 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
880 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
881 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
882 EXPECT_TRUE(rtp_sender_->SendToNetwork(
883 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
884 EXPECT_EQ(0, transport_.packets_sent());
885 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
886 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
887 }
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000888
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000889 // Process send bucket. Packet should now be sent.
danilchap12ba1862016-10-26 02:41:55 -0700890 EXPECT_EQ(1, transport_.packets_sent());
891 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
892
stefan@webrtc.orga5cb98c2013-05-29 12:12:51 +0000893 webrtc::RTPHeader rtp_header;
danilchap12ba1862016-10-26 02:41:55 -0700894 transport_.last_sent_packet().GetHeader(&rtp_header);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000895
896 // Verify transmission time offset.
897 EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000898 uint64_t expected_send_time =
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000899 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000900 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000901}
902
minyue3a407ee2017-04-03 01:10:33 -0700903TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) {
Elad Alon4a87e1c2017-10-03 16:11:34 +0200904 EXPECT_CALL(mock_rtc_event_log_,
905 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000906
907 rtp_sender_->SetStorePacketsStatus(true, 10);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000908 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800909 kRtpExtensionTransmissionTimeOffset,
910 kTransmissionTimeOffsetExtensionId));
911 EXPECT_EQ(
912 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
913 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000914 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700915 auto packet =
916 BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
917 size_t packet_size = packet->size();
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000918
919 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +0200920 if (GetParam().pacer_references_packets) {
921 EXPECT_CALL(mock_paced_sender_,
922 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum,
923 _, _, _));
924 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
925 kAllowRetransmission,
926 RtpPacketSender::kNormalPriority));
927 // Immediately process send bucket and send packet.
928 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
929 PacedPacketInfo());
930 } else {
931 EXPECT_CALL(
932 mock_paced_sender_,
933 EnqueuePacket(AllOf(
934 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
935 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
936 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
937 packet->set_allow_retransmission(true);
938 EXPECT_TRUE(rtp_sender_->SendToNetwork(
939 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
940 // Immediately process send bucket and send packet.
941 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
942 }
943
Erik Språng0f4f0552019-05-08 10:15:05 -0700944 EXPECT_EQ(1, transport_.packets_sent());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000945
Erik Språng0f4f0552019-05-08 10:15:05 -0700946 // Retransmit packet.
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000947 const int kStoredTimeInMs = 100;
948 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
949
Erik Språng0f4f0552019-05-08 10:15:05 -0700950 EXPECT_CALL(mock_rtc_event_log_,
951 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
Erik Språngf6468d22019-07-05 16:53:43 +0200952 if (GetParam().pacer_references_packets) {
953 EXPECT_CALL(mock_paced_sender_,
954 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum,
955 _, _, _));
956 EXPECT_EQ(static_cast<int>(packet_size),
957 rtp_sender_->ReSendPacket(kSeqNum));
958 EXPECT_EQ(1, transport_.packets_sent());
959 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, true,
960 PacedPacketInfo());
961 } else {
962 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
963 packet->set_retransmitted_sequence_number(kSeqNum);
964 EXPECT_CALL(
965 mock_paced_sender_,
966 EnqueuePacket(AllOf(
967 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
968 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
969 EXPECT_EQ(static_cast<int>(packet_size),
970 rtp_sender_->ReSendPacket(kSeqNum));
971 EXPECT_EQ(1, transport_.packets_sent());
972 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
973 }
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000974
975 // Process send bucket. Packet should now be sent.
Erik Språng0f4f0552019-05-08 10:15:05 -0700976 EXPECT_EQ(2, transport_.packets_sent());
danilchap12ba1862016-10-26 02:41:55 -0700977 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000978
stefan@webrtc.orga5cb98c2013-05-29 12:12:51 +0000979 webrtc::RTPHeader rtp_header;
danilchap12ba1862016-10-26 02:41:55 -0700980 transport_.last_sent_packet().GetHeader(&rtp_header);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000981
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000982 // Verify transmission time offset.
983 EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000984 uint64_t expected_send_time =
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000985 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
986 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
987}
988
989// This test sends 1 regular video packet, then 4 padding packets, and then
990// 1 more regular packet.
minyue3a407ee2017-04-03 01:10:33 -0700991TEST_P(RtpSenderTest, SendPadding) {
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000992 // Make all (non-padding) packets go to send queue.
Elad Alon4a87e1c2017-10-03 16:11:34 +0200993 EXPECT_CALL(mock_rtc_event_log_,
994 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
995 .Times(1 + 4 + 1);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000996
997 uint16_t seq_num = kSeqNum;
998 uint32_t timestamp = kTimestamp;
999 rtp_sender_->SetStorePacketsStatus(true, 10);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001000 size_t rtp_header_len = kRtpHeaderSize;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001001 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -08001002 kRtpExtensionTransmissionTimeOffset,
1003 kTransmissionTimeOffsetExtensionId));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001004 rtp_header_len += 4; // 4 bytes extension.
danilchap162abd32015-12-10 02:39:40 -08001005 EXPECT_EQ(
1006 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
1007 kAbsoluteSendTimeExtensionId));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001008 rtp_header_len += 4; // 4 bytes extension.
1009 rtp_header_len += 4; // 4 extra bytes common to all extension headers.
1010
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001011 webrtc::RTPHeader rtp_header;
1012
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001013 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -07001014 auto packet =
1015 BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
Stefan Holmer586b19b2015-09-18 11:14:31 +02001016 const uint32_t media_packet_timestamp = timestamp;
danilchapb6f1fb52016-10-19 06:11:39 -07001017 size_t packet_size = packet->size();
Erik Språngf6468d22019-07-05 16:53:43 +02001018 int total_packets_sent = 0;
1019 const int kStoredTimeInMs = 100;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001020
1021 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +02001022 if (GetParam().pacer_references_packets) {
1023 EXPECT_CALL(mock_paced_sender_,
1024 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum,
1025 _, _, _));
1026 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
1027 kAllowRetransmission,
1028 RtpPacketSender::kNormalPriority));
1029 EXPECT_EQ(total_packets_sent, transport_.packets_sent());
1030 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
1031 rtp_sender_->TimeToSendPacket(kSsrc, seq_num++, capture_time_ms, false,
1032 PacedPacketInfo());
1033 } else {
1034 EXPECT_CALL(
1035 mock_paced_sender_,
1036 EnqueuePacket(AllOf(
1037 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1038 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
1039 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1040 packet->set_allow_retransmission(true);
1041 EXPECT_TRUE(rtp_sender_->SendToNetwork(
1042 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
1043 EXPECT_EQ(total_packets_sent, transport_.packets_sent());
1044 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
1045 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
1046 ++seq_num;
1047 }
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001048
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001049 // Packet should now be sent. This test doesn't verify the regular video
1050 // packet, since it is tested in another test.
danilchap12ba1862016-10-26 02:41:55 -07001051 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001052 timestamp += 90 * kStoredTimeInMs;
1053
1054 // Send padding 4 times, waiting 50 ms between each.
1055 for (int i = 0; i < 4; ++i) {
1056 const int kPaddingPeriodMs = 50;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001057 const size_t kPaddingBytes = 100;
1058 const size_t kMaxPaddingLength = 224; // Value taken from rtp_sender.cc.
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001059 // Padding will be forced to full packets.
philipelc7bf32a2017-02-17 03:59:43 -08001060 EXPECT_EQ(kMaxPaddingLength,
philipel8aadd502017-02-23 02:56:13 -08001061 rtp_sender_->TimeToSendPadding(kPaddingBytes, PacedPacketInfo()));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001062
1063 // Process send bucket. Padding should now be sent.
danilchap12ba1862016-10-26 02:41:55 -07001064 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001065 EXPECT_EQ(kMaxPaddingLength + rtp_header_len,
danilchap12ba1862016-10-26 02:41:55 -07001066 transport_.last_sent_packet().size());
1067
1068 transport_.last_sent_packet().GetHeader(&rtp_header);
pbosbd2522a2015-07-01 05:35:53 -07001069 EXPECT_EQ(kMaxPaddingLength, rtp_header.paddingLength);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001070
Stefan Holmer586b19b2015-09-18 11:14:31 +02001071 // Verify sequence number and timestamp. The timestamp should be the same
1072 // as the last media packet.
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001073 EXPECT_EQ(seq_num++, rtp_header.sequenceNumber);
Stefan Holmer586b19b2015-09-18 11:14:31 +02001074 EXPECT_EQ(media_packet_timestamp, rtp_header.timestamp);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001075 // Verify transmission time offset.
Stefan Holmer586b19b2015-09-18 11:14:31 +02001076 int offset = timestamp - media_packet_timestamp;
1077 EXPECT_EQ(offset, rtp_header.extension.transmissionTimeOffset);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001078 uint64_t expected_send_time =
1079 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
1080 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
1081 fake_clock_.AdvanceTimeMilliseconds(kPaddingPeriodMs);
1082 timestamp += 90 * kPaddingPeriodMs;
1083 }
1084
1085 // Send a regular video packet again.
1086 capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -07001087 packet = BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
1088 packet_size = packet->size();
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001089
Erik Språngf6468d22019-07-05 16:53:43 +02001090 if (GetParam().pacer_references_packets) {
1091 EXPECT_CALL(mock_paced_sender_,
1092 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, seq_num,
1093 _, _, _));
1094 // Packet should be stored in a send bucket.
1095 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
1096 kAllowRetransmission,
1097 RtpPacketSender::kNormalPriority));
1098 rtp_sender_->TimeToSendPacket(kSsrc, seq_num, capture_time_ms, false,
1099 PacedPacketInfo());
1100 } else {
1101 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1102 EXPECT_CALL(
1103 mock_paced_sender_,
1104 EnqueuePacket(AllOf(
1105 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1106 Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
1107 EXPECT_TRUE(rtp_sender_->SendToNetwork(
1108 absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
1109 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
1110 }
terelius5d332ac2016-01-14 14:37:39 -08001111
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001112 // Process send bucket.
danilchap12ba1862016-10-26 02:41:55 -07001113 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
1114 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
1115 transport_.last_sent_packet().GetHeader(&rtp_header);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001116
1117 // Verify sequence number and timestamp.
1118 EXPECT_EQ(seq_num, rtp_header.sequenceNumber);
1119 EXPECT_EQ(timestamp, rtp_header.timestamp);
1120 // Verify transmission time offset. This packet is sent without delay.
1121 EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset);
1122 uint64_t expected_send_time =
1123 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +00001124 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +00001125}
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001126
minyue3a407ee2017-04-03 01:10:33 -07001127TEST_P(RtpSenderTest, OnSendPacketUpdated) {
stefana23fc622016-07-28 07:56:38 -07001128 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1129 kRtpExtensionTransportSequenceNumber,
1130 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -07001131 rtp_sender_->SetStorePacketsStatus(true, 10);
1132
1133 EXPECT_CALL(send_packet_observer_,
1134 OnSendPacket(kTransportSequenceNumber, _, _))
1135 .Times(1);
asapersson35151f32016-05-02 23:44:01 -07001136
Erik Språngf6468d22019-07-05 16:53:43 +02001137 if (GetParam().pacer_references_packets) {
1138 const bool kIsRetransmit = false;
1139 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
1140 SendGenericPacket(); // Packet passed to pacer.
1141 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
1142 .WillOnce(::testing::Return(kTransportSequenceNumber));
1143 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
1144 fake_clock_.TimeInMilliseconds(),
1145 kIsRetransmit, PacedPacketInfo());
1146 } else {
1147 EXPECT_CALL(
1148 mock_paced_sender_,
1149 EnqueuePacket(AllOf(
1150 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1151 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
1152 auto packet = SendGenericPacket();
1153 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1154 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
1155 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
1156 }
1157
danilchap12ba1862016-10-26 02:41:55 -07001158 EXPECT_EQ(1, transport_.packets_sent());
asapersson35151f32016-05-02 23:44:01 -07001159}
1160
minyue3a407ee2017-04-03 01:10:33 -07001161TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
stefana23fc622016-07-28 07:56:38 -07001162 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1163 kRtpExtensionTransportSequenceNumber,
1164 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -07001165 rtp_sender_->SetStorePacketsStatus(true, 10);
1166
1167 EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
asapersson35151f32016-05-02 23:44:01 -07001168
Erik Språngf6468d22019-07-05 16:53:43 +02001169 if (GetParam().pacer_references_packets) {
1170 const bool kIsRetransmit = true;
1171 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
1172 SendGenericPacket(); // Packet passed to pacer.
1173 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
1174 .WillOnce(Return(kTransportSequenceNumber));
1175 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
1176 fake_clock_.TimeInMilliseconds(),
1177 kIsRetransmit, PacedPacketInfo());
1178 } else {
1179 EXPECT_CALL(
1180 mock_paced_sender_,
1181 EnqueuePacket(AllOf(
1182 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1183 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
1184 auto packet = SendGenericPacket();
1185 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
1186 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
1187 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
1188 }
1189
danilchap12ba1862016-10-26 02:41:55 -07001190 EXPECT_EQ(1, transport_.packets_sent());
Petter Strandmark26bc6692018-05-29 08:43:35 +02001191 EXPECT_TRUE(transport_.last_options_.is_retransmit);
asapersson35151f32016-05-02 23:44:01 -07001192}
1193
minyue3a407ee2017-04-03 01:10:33 -07001194TEST_P(RtpSenderTest, OnSendPacketNotUpdatedWithoutSeqNumAllocator) {
Erik Språngf6468d22019-07-05 16:53:43 +02001195 if (!GetParam().pacer_references_packets) {
1196 // When PacedSender owns packets, there is no
1197 // TransportSequenceNumberAllocator callback, so this test does not make any
1198 // sense.
1199 // TODO(bugs.webrtc.org/10633): Remove this test once old code is gone.
1200 return;
1201 }
1202
Erik Språng4580ca22019-07-04 10:38:43 +02001203 RtpRtcp::Configuration config;
1204 config.clock = &fake_clock_;
1205 config.outgoing_transport = &transport_;
1206 config.paced_sender = &mock_paced_sender_;
1207 config.media_send_ssrc = kSsrc;
1208 config.send_packet_observer = &send_packet_observer_;
1209 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1210 rtp_sender_ = absl::make_unique<RTPSender>(config);
1211
brandtr9dfff292016-11-14 05:14:50 -08001212 rtp_sender_->SetSequenceNumber(kSeqNum);
stefana23fc622016-07-28 07:56:38 -07001213 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1214 kRtpExtensionTransportSequenceNumber,
1215 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -07001216 rtp_sender_->SetSequenceNumber(kSeqNum);
1217 rtp_sender_->SetStorePacketsStatus(true, 10);
1218
1219 EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
asapersson35151f32016-05-02 23:44:01 -07001220
asapersson35151f32016-05-02 23:44:01 -07001221 const bool kIsRetransmit = false;
Erik Språngf6468d22019-07-05 16:53:43 +02001222 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
1223 SendGenericPacket(); // Packet passed to pacer.
brandtr9dfff292016-11-14 05:14:50 -08001224 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
1225 fake_clock_.TimeInMilliseconds(), kIsRetransmit,
philipel8aadd502017-02-23 02:56:13 -08001226 PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001227
danilchap12ba1862016-10-26 02:41:55 -07001228 EXPECT_EQ(1, transport_.packets_sent());
asapersson35151f32016-05-02 23:44:01 -07001229}
1230
Erik Språng214f5432019-06-20 15:09:58 +02001231// TODO(bugs.webrtc.org/8975): Remove this test when non-useful padding is
1232// removed.
minyue3a407ee2017-04-03 01:10:33 -07001233TEST_P(RtpSenderTest, SendRedundantPayloads) {
Erik Språngf6468d22019-07-05 16:53:43 +02001234 if (!GetParam().pacer_references_packets) {
1235 // If PacedSender owns the RTP packets, GeneratePadding() family of methods
1236 // will be called instead and this test makes no sense.
1237 return;
1238 }
1239
Erik Språng214f5432019-06-20 15:09:58 +02001240 test::ScopedFieldTrials field_trials(
1241 "WebRTC-PayloadPadding-UseMostUsefulPacket/Disabled/");
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001242 MockTransport transport;
Erik Språng4580ca22019-07-04 10:38:43 +02001243 RtpRtcp::Configuration config;
1244 config.clock = &fake_clock_;
1245 config.outgoing_transport = &transport;
1246 config.paced_sender = &mock_paced_sender_;
1247 config.media_send_ssrc = kSsrc;
1248 config.rtx_send_ssrc = kRtxSsrc;
1249 config.event_log = &mock_rtc_event_log_;
1250 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1251 rtp_sender_ = absl::make_unique<RTPSender>(config);
1252
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001253 rtp_sender_->SetSequenceNumber(kSeqNum);
Shao Changbine62202f2015-04-21 20:24:50 +08001254 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001255
1256 uint16_t seq_num = kSeqNum;
1257 rtp_sender_->SetStorePacketsStatus(true, 10);
wu@webrtc.orgebdb0e32014-03-06 23:49:08 +00001258 int32_t rtp_header_len = kRtpHeaderSize;
danilchap162abd32015-12-10 02:39:40 -08001259 EXPECT_EQ(
1260 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
1261 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001262 rtp_header_len += 4; // 4 bytes extension.
1263 rtp_header_len += 4; // 4 extra bytes common to all extension headers.
1264
pbos@webrtc.org0b0c2412015-01-13 14:15:15 +00001265 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001266
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001267 const size_t kNumPayloadSizes = 10;
danilchap162abd32015-12-10 02:39:40 -08001268 const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700,
1269 750, 800, 850, 900, 950};
terelius5d332ac2016-01-14 14:37:39 -08001270 // Expect all packets go through the pacer.
Elad Alon4a87e1c2017-10-03 16:11:34 +02001271 EXPECT_CALL(mock_rtc_event_log_,
1272 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
terelius429c3452016-01-21 05:42:04 -08001273 .Times(kNumPayloadSizes);
1274
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001275 // Send 10 packets of increasing size.
1276 for (size_t i = 0; i < kNumPayloadSizes; ++i) {
1277 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
Erik Språngf6468d22019-07-05 16:53:43 +02001278
1279 EXPECT_CALL(transport, SendRtp(_, _, _)).WillOnce(::testing::Return(true));
1280
1281 if (GetParam().pacer_references_packets) {
1282 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, seq_num, _, _, _));
1283 SendPacket(capture_time_ms, kPayloadSizes[i]);
1284 rtp_sender_->TimeToSendPacket(kSsrc, seq_num,
1285 fake_clock_.TimeInMilliseconds(), false,
1286 PacedPacketInfo());
1287 } else {
1288 EXPECT_CALL(
1289 mock_paced_sender_,
1290 EnqueuePacket(AllOf(
1291 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1292 Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
1293 auto packet = SendPacket(capture_time_ms, kPayloadSizes[i]);
1294 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1295 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
1296 }
1297
1298 ++seq_num;
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001299 fake_clock_.AdvanceTimeMilliseconds(33);
1300 }
terelius429c3452016-01-21 05:42:04 -08001301
Elad Alon4a87e1c2017-10-03 16:11:34 +02001302 EXPECT_CALL(mock_rtc_event_log_,
1303 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
Erik Språng214f5432019-06-20 15:09:58 +02001304 .Times(AtLeast(4));
terelius429c3452016-01-21 05:42:04 -08001305
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001306 // The amount of padding to send it too small to send a payload packet.
stefan1d8a5062015-10-02 03:39:33 -07001307 EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
Erik Språng214f5432019-06-20 15:09:58 +02001308 .WillOnce(Return(true));
philipela1ed0b32016-06-01 06:31:17 -07001309 EXPECT_EQ(kMaxPaddingSize,
philipel8aadd502017-02-23 02:56:13 -08001310 rtp_sender_->TimeToSendPadding(49, PacedPacketInfo()));
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001311
Petter Strandmark26bc6692018-05-29 08:43:35 +02001312 PacketOptions options;
Peter Boströmac547a62015-09-17 23:03:57 +02001313 EXPECT_CALL(transport,
stefan1d8a5062015-10-02 03:39:33 -07001314 SendRtp(_, kPayloadSizes[0] + rtp_header_len + kRtxHeaderSize, _))
Erik Språng214f5432019-06-20 15:09:58 +02001315 .WillOnce(DoAll(SaveArg<2>(&options), Return(true)));
philipela1ed0b32016-06-01 06:31:17 -07001316 EXPECT_EQ(kPayloadSizes[0],
philipel8aadd502017-02-23 02:56:13 -08001317 rtp_sender_->TimeToSendPadding(500, PacedPacketInfo()));
Petter Strandmark26bc6692018-05-29 08:43:35 +02001318 EXPECT_TRUE(options.is_retransmit);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001319
Yves Gerey665174f2018-06-19 15:03:05 +02001320 EXPECT_CALL(transport, SendRtp(_,
1321 kPayloadSizes[kNumPayloadSizes - 1] +
1322 rtp_header_len + kRtxHeaderSize,
stefan1d8a5062015-10-02 03:39:33 -07001323 _))
Erik Språng214f5432019-06-20 15:09:58 +02001324 .WillOnce(Return(true));
Petter Strandmark26bc6692018-05-29 08:43:35 +02001325
1326 options.is_retransmit = false;
stefan1d8a5062015-10-02 03:39:33 -07001327 EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
Erik Språng214f5432019-06-20 15:09:58 +02001328 .WillOnce(DoAll(SaveArg<2>(&options), Return(true)));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001329 EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1] + kMaxPaddingSize,
philipel8aadd502017-02-23 02:56:13 -08001330 rtp_sender_->TimeToSendPadding(999, PacedPacketInfo()));
Petter Strandmark26bc6692018-05-29 08:43:35 +02001331 EXPECT_FALSE(options.is_retransmit);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001332}
1333
Erik Språng214f5432019-06-20 15:09:58 +02001334TEST_P(RtpSenderTest, SendRedundantPayloadsUsefulPadding) {
Erik Språngf6468d22019-07-05 16:53:43 +02001335 if (!GetParam().pacer_references_packets) {
1336 // If PacedSender owns the RTP packets, GeneratePadding() family of methods
1337 // will be called instead and this test makes no sense.
1338 return;
1339 }
1340
Erik Språng214f5432019-06-20 15:09:58 +02001341 test::ScopedFieldTrials field_trials(
1342 "WebRTC-PayloadPadding-UseMostUsefulPacket/Enabled/");
1343 MockTransport transport;
Erik Språng4580ca22019-07-04 10:38:43 +02001344 RtpRtcp::Configuration config;
1345 config.clock = &fake_clock_;
1346 config.outgoing_transport = &transport;
1347 config.paced_sender = &mock_paced_sender_;
1348 config.media_send_ssrc = kSsrc;
1349 config.rtx_send_ssrc = kRtxSsrc;
1350 config.event_log = &mock_rtc_event_log_;
1351 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1352 rtp_sender_ = absl::make_unique<RTPSender>(config);
1353
Erik Språng214f5432019-06-20 15:09:58 +02001354 rtp_sender_->SetSequenceNumber(kSeqNum);
Erik Språng214f5432019-06-20 15:09:58 +02001355 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
1356
1357 uint16_t seq_num = kSeqNum;
1358 rtp_sender_->SetStorePacketsStatus(true, 10);
1359 int32_t rtp_header_len = kRtpHeaderSize;
1360 EXPECT_EQ(
1361 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
1362 kAbsoluteSendTimeExtensionId));
1363 rtp_header_len += 4; // 4 bytes extension.
1364 rtp_header_len += 4; // 4 extra bytes common to all extension headers.
1365
1366 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
Erik Språng214f5432019-06-20 15:09:58 +02001367
1368 const size_t kNumPayloadSizes = 10;
1369 const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700,
1370 750, 800, 850, 900, 950};
1371 // Expect all packets go through the pacer.
Erik Språng214f5432019-06-20 15:09:58 +02001372 EXPECT_CALL(mock_rtc_event_log_,
1373 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1374 .Times(kNumPayloadSizes);
1375
1376 // Send 10 packets of increasing size.
Erik Språng214f5432019-06-20 15:09:58 +02001377 for (size_t i = 0; i < kNumPayloadSizes; ++i) {
1378 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
Erik Språngf6468d22019-07-05 16:53:43 +02001379
1380 EXPECT_CALL(transport, SendRtp(_, _, _)).WillOnce(::testing::Return(true));
1381
1382 if (GetParam().pacer_references_packets) {
1383 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, seq_num, _, _, _));
1384 SendPacket(capture_time_ms, kPayloadSizes[i]);
1385 rtp_sender_->TimeToSendPacket(kSsrc, seq_num,
1386 fake_clock_.TimeInMilliseconds(), false,
1387 PacedPacketInfo());
1388 } else {
1389 EXPECT_CALL(
1390 mock_paced_sender_,
1391 EnqueuePacket(AllOf(
1392 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1393 Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
1394 auto packet = SendPacket(capture_time_ms, kPayloadSizes[i]);
1395 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1396 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
1397 }
1398
1399 ++seq_num;
Erik Språng214f5432019-06-20 15:09:58 +02001400 fake_clock_.AdvanceTimeMilliseconds(33);
1401 }
1402
1403 EXPECT_CALL(mock_rtc_event_log_,
1404 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1405 .Times(AtLeast(4));
1406
1407 // The amount of padding to send it too small to send a payload packet.
1408 EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
1409 .WillOnce(Return(true));
1410 EXPECT_EQ(kMaxPaddingSize,
1411 rtp_sender_->TimeToSendPadding(49, PacedPacketInfo()));
1412
1413 // Payload padding will prefer packets with lower transmit count first and
1414 // lower age second.
1415 EXPECT_CALL(transport, SendRtp(_,
1416 kPayloadSizes[kNumPayloadSizes - 1] +
1417 rtp_header_len + kRtxHeaderSize,
1418 Field(&PacketOptions::is_retransmit, true)))
1419 .WillOnce(Return(true));
1420 EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1],
1421 rtp_sender_->TimeToSendPadding(500, PacedPacketInfo()));
1422
1423 EXPECT_CALL(transport, SendRtp(_,
1424 kPayloadSizes[kNumPayloadSizes - 2] +
1425 rtp_header_len + kRtxHeaderSize,
1426 _))
1427 .WillOnce(Return(true));
1428
1429 EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len,
1430 Field(&PacketOptions::is_retransmit, false)))
1431 .WillOnce(Return(true));
1432 EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 2] + kMaxPaddingSize,
1433 rtp_sender_->TimeToSendPadding(
1434 kPayloadSizes[kNumPayloadSizes - 2] + 49, PacedPacketInfo()));
1435}
1436
minyue3a407ee2017-04-03 01:10:33 -07001437TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
Niels Möller8a40edd2019-01-24 18:04:44 +01001438 const char payload_name[] = "GENERIC";
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001439 const uint8_t payload_type = 127;
Niels Möller5fe95102019-03-04 16:49:25 +01001440 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001441 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001442 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01001443 FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001444 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1445 /*raw_payload=*/false);
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001446 uint8_t payload[] = {47, 11, 32, 93, 89};
1447
1448 // Send keyframe
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001449 RTPVideoHeader video_header;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001450 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001451 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1452 sizeof(payload), nullptr, &video_header,
1453 kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001454
danilchap96c15872016-11-21 01:35:29 -08001455 auto sent_payload = transport_.last_sent_packet().payload();
1456 uint8_t generic_header = sent_payload[0];
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001457 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
1458 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
danilchap96c15872016-11-21 01:35:29 -08001459 EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001460
1461 // Send delta frame
1462 payload[0] = 13;
1463 payload[1] = 42;
1464 payload[4] = 13;
1465
Niels Möller59ab1cf2019-02-06 22:48:11 +01001466 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001467 VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload,
1468 sizeof(payload), nullptr, &video_header,
1469 kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001470
danilchap96c15872016-11-21 01:35:29 -08001471 sent_payload = transport_.last_sent_packet().payload();
1472 generic_header = sent_payload[0];
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001473 EXPECT_FALSE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
1474 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
danilchap96c15872016-11-21 01:35:29 -08001475 EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001476}
1477
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001478TEST_P(RtpSenderTestWithoutPacer, SendRawVideo) {
1479 const char payload_name[] = "VP8";
1480 const uint8_t payload_type = 111;
1481 const uint8_t payload[] = {11, 22, 33, 44, 55};
1482
1483 PlayoutDelayOracle playout_delay_oracle;
1484 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001485 &playout_delay_oracle, nullptr, false, false,
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001486 FieldTrialBasedConfig());
1487 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1488 /*raw_payload=*/true);
1489
1490 // Send a frame.
1491 RTPVideoHeader video_header;
1492 ASSERT_TRUE(rtp_sender_video.SendVideo(
1493 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1494 sizeof(payload), nullptr, &video_header,
1495 kDefaultExpectedRetransmissionTimeMs));
1496
1497 auto sent_payload = transport_.last_sent_packet().payload();
1498 EXPECT_THAT(sent_payload, ElementsAreArray(payload));
1499}
1500
minyue3a407ee2017-04-03 01:10:33 -07001501TEST_P(RtpSenderTest, SendFlexfecPackets) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001502 constexpr uint32_t kTimestamp = 1234;
brandtrdbdb3f12016-11-10 05:04:48 -08001503 constexpr int kMediaPayloadType = 127;
1504 constexpr int kFlexfecPayloadType = 118;
brandtrdbdb3f12016-11-10 05:04:48 -08001505 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001506 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språng4580ca22019-07-04 10:38:43 +02001507 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1508 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001509 nullptr /* rtp_state */, &fake_clock_);
brandtrdbdb3f12016-11-10 05:04:48 -08001510
1511 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001512 RtpRtcp::Configuration config;
1513 config.clock = &fake_clock_;
1514 config.outgoing_transport = &transport_;
1515 config.paced_sender = &mock_paced_sender_;
1516 config.media_send_ssrc = kSsrc;
1517 config.flexfec_sender = &flexfec_sender_;
1518 config.transport_sequence_number_allocator = &seq_num_allocator_;
1519 config.event_log = &mock_rtc_event_log_;
1520 config.send_packet_observer = &send_packet_observer_;
1521 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1522 rtp_sender_ = absl::make_unique<RTPSender>(config);
1523
brandtrdbdb3f12016-11-10 05:04:48 -08001524 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtrdbdb3f12016-11-10 05:04:48 -08001525 rtp_sender_->SetStorePacketsStatus(true, 10);
1526
Niels Möller5fe95102019-03-04 16:49:25 +01001527 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001528 RTPSenderVideo rtp_sender_video(
1529 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1530 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001531 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1532 /*raw_payload=*/false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001533
brandtrdbdb3f12016-11-10 05:04:48 -08001534 // Parameters selected to generate a single FEC packet per media packet.
1535 FecProtectionParams params;
1536 params.fec_rate = 15;
1537 params.max_fec_frames = 1;
1538 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001539 rtp_sender_video.SetFecParameters(params, params);
brandtrdbdb3f12016-11-10 05:04:48 -08001540
brandtr9dfff292016-11-14 05:14:50 -08001541 uint16_t flexfec_seq_num;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001542 RTPVideoHeader video_header;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001543
Erik Språngf6468d22019-07-05 16:53:43 +02001544 if (GetParam().pacer_references_packets) {
1545 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
1546 kSsrc, kSeqNum, _, _, false));
1547 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
1548 kFlexFecSsrc, _, _, _, false))
1549 .WillOnce(::testing::SaveArg<2>(&flexfec_seq_num));
1550
1551 EXPECT_TRUE(rtp_sender_video.SendVideo(
1552 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
1553 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1554 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1555
1556 EXPECT_EQ(RtpPacketSendResult::kSuccess,
1557 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
1558 fake_clock_.TimeInMilliseconds(),
1559 false, PacedPacketInfo()));
1560 EXPECT_EQ(RtpPacketSendResult::kSuccess,
1561 rtp_sender_->TimeToSendPacket(kFlexFecSsrc, flexfec_seq_num,
1562 fake_clock_.TimeInMilliseconds(),
1563 false, PacedPacketInfo()));
1564 } else {
1565 std::unique_ptr<RtpPacketToSend> media_packet;
1566 std::unique_ptr<RtpPacketToSend> fec_packet;
1567
1568 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1569 .Times(2)
1570 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) {
1571 if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
1572 EXPECT_EQ(packet->Ssrc(), kSsrc);
1573 EXPECT_EQ(packet->SequenceNumber(), kSeqNum);
1574 media_packet = std::move(packet);
1575 } else {
1576 EXPECT_EQ(packet->packet_type(),
1577 RtpPacketToSend::Type::kForwardErrorCorrection);
1578 EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
1579 fec_packet = std::move(packet);
1580 }
1581 });
1582
1583 EXPECT_TRUE(rtp_sender_video.SendVideo(
1584 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
1585 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1586 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1587 ASSERT_TRUE(media_packet != nullptr);
1588 ASSERT_TRUE(fec_packet != nullptr);
1589
1590 flexfec_seq_num = fec_packet->SequenceNumber();
1591 rtp_sender_->TrySendPacket(media_packet.get(), PacedPacketInfo());
1592 rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo());
1593 }
1594
brandtr9dfff292016-11-14 05:14:50 -08001595 ASSERT_EQ(2, transport_.packets_sent());
brandtrdbdb3f12016-11-10 05:04:48 -08001596 const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
1597 EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
brandtr9dfff292016-11-14 05:14:50 -08001598 EXPECT_EQ(kSeqNum, media_packet.SequenceNumber());
Erik Språng4580ca22019-07-04 10:38:43 +02001599 EXPECT_EQ(kSsrc, media_packet.Ssrc());
brandtr9dfff292016-11-14 05:14:50 -08001600 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[1];
1601 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
1602 EXPECT_EQ(flexfec_seq_num, flexfec_packet.SequenceNumber());
Erik Språng4580ca22019-07-04 10:38:43 +02001603 EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001604}
1605
Erik Språngf6468d22019-07-05 16:53:43 +02001606// TODO(ilnik): because of webrtc:7859. Once FEC moved below pacer, this test
1607// should be removed.
1608TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
1609 constexpr uint32_t kTimestamp = 1234;
1610 const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
1611 constexpr int kMediaPayloadType = 127;
1612 constexpr int kFlexfecPayloadType = 118;
1613 const std::vector<RtpExtension> kNoRtpExtensions;
1614 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
1615
1616 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1617 kNoRtpExtensions, kNoRtpExtensionSizes,
1618 nullptr /* rtp_state */, &fake_clock_);
1619
1620 // Reset |rtp_sender_| to use FlexFEC.
1621 rtp_sender_.reset(new RTPSender(
1622 false, &fake_clock_, &transport_, &mock_paced_sender_,
1623 flexfec_sender.ssrc(), &seq_num_allocator_, nullptr, nullptr, nullptr,
1624 &mock_rtc_event_log_, &send_packet_observer_,
1625 &retransmission_rate_limiter_, nullptr, false, nullptr, false, false,
1626 FieldTrialBasedConfig()));
1627 rtp_sender_->SetSSRC(kSsrc);
1628 rtp_sender_->SetSequenceNumber(kSeqNum);
1629 rtp_sender_->SetStorePacketsStatus(true, 10);
1630
1631 PlayoutDelayOracle playout_delay_oracle;
1632 RTPSenderVideo rtp_sender_video(
1633 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1634 nullptr, false, false, FieldTrialBasedConfig());
1635 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1636 /*raw_payload=*/false);
1637
1638 // Need extension to be registered for timing frames to be sent.
1639 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1640 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
1641
1642 // Parameters selected to generate a single FEC packet per media packet.
1643 FecProtectionParams params;
1644 params.fec_rate = 15;
1645 params.max_fec_frames = 1;
1646 params.fec_mask_type = kFecMaskRandom;
1647 rtp_sender_video.SetFecParameters(params, params);
1648
1649 RTPVideoHeader video_header;
1650 video_header.video_timing.flags = VideoSendTiming::kTriggeredByTimer;
1651
1652 EXPECT_CALL(mock_rtc_event_log_,
1653 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1654 .Times(1);
1655 if (GetParam().pacer_references_packets) {
1656 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
1657 kSsrc, kSeqNum, _, _, false));
1658 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
1659 kFlexFecSsrc, _, _, _, false))
1660 .Times(0); // Not called because packet should not be protected.
1661
1662 EXPECT_TRUE(rtp_sender_video.SendVideo(
1663 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
1664 kCaptureTimeMs, kPayloadData, sizeof(kPayloadData), nullptr,
1665 &video_header, kDefaultExpectedRetransmissionTimeMs));
1666
1667 EXPECT_EQ(RtpPacketSendResult::kSuccess,
1668 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
1669 fake_clock_.TimeInMilliseconds(),
1670 false, PacedPacketInfo()));
1671 } else {
1672 std::unique_ptr<RtpPacketToSend> rtp_packet;
1673 EXPECT_CALL(
1674 mock_paced_sender_,
1675 EnqueuePacket(AllOf(
1676 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1677 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))))
1678 .WillOnce([&rtp_packet](std::unique_ptr<RtpPacketToSend> packet) {
1679 rtp_packet = std::move(packet);
1680 });
1681
1682 EXPECT_CALL(
1683 mock_paced_sender_,
1684 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kFlexFecSsrc))))
1685 .Times(0); // Not called because packet should not be protected.
1686
1687 EXPECT_TRUE(rtp_sender_video.SendVideo(
1688 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
1689 kCaptureTimeMs, kPayloadData, sizeof(kPayloadData), nullptr,
1690 &video_header, kDefaultExpectedRetransmissionTimeMs));
1691
1692 EXPECT_TRUE(
1693 rtp_sender_->TrySendPacket(rtp_packet.get(), PacedPacketInfo()));
1694 }
1695
1696 ASSERT_EQ(1, transport_.packets_sent());
1697 const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
1698 EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
1699 EXPECT_EQ(kSeqNum, media_packet.SequenceNumber());
1700 EXPECT_EQ(kSsrc, media_packet.Ssrc());
1701
1702 // Now try to send not a timing frame.
1703 uint16_t flexfec_seq_num;
1704
1705 EXPECT_CALL(mock_rtc_event_log_,
1706 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1707 .Times(2);
1708 if (GetParam().pacer_references_packets) {
1709 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
1710 kFlexFecSsrc, _, _, _, false))
1711 .WillOnce(::testing::SaveArg<2>(&flexfec_seq_num));
1712 EXPECT_CALL(mock_paced_sender_,
1713 InsertPacket(RtpPacketSender::kLowPriority, kSsrc, kSeqNum + 1,
1714 _, _, false));
1715 video_header.video_timing.flags = VideoSendTiming::kInvalid;
1716 EXPECT_TRUE(rtp_sender_video.SendVideo(
1717 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp + 1,
1718 kCaptureTimeMs + 1, kPayloadData, sizeof(kPayloadData), nullptr,
1719 &video_header, kDefaultExpectedRetransmissionTimeMs));
1720
1721 EXPECT_EQ(RtpPacketSendResult::kSuccess,
1722 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum + 1,
1723 fake_clock_.TimeInMilliseconds(),
1724 false, PacedPacketInfo()));
1725 EXPECT_EQ(RtpPacketSendResult::kSuccess,
1726 rtp_sender_->TimeToSendPacket(kFlexFecSsrc, flexfec_seq_num,
1727 fake_clock_.TimeInMilliseconds(),
1728 false, PacedPacketInfo()));
1729 } else {
1730 std::unique_ptr<RtpPacketToSend> media_packet;
1731 std::unique_ptr<RtpPacketToSend> fec_packet;
1732
1733 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1734 .Times(2)
1735 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) {
1736 if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
1737 EXPECT_EQ(packet->Ssrc(), kSsrc);
1738 EXPECT_EQ(packet->SequenceNumber(), kSeqNum + 1);
1739 media_packet = std::move(packet);
1740 } else {
1741 EXPECT_EQ(packet->packet_type(),
1742 RtpPacketToSend::Type::kForwardErrorCorrection);
1743 EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
1744 fec_packet = std::move(packet);
1745 }
1746 });
1747
1748 video_header.video_timing.flags = VideoSendTiming::kInvalid;
1749 EXPECT_TRUE(rtp_sender_video.SendVideo(
1750 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp + 1,
1751 kCaptureTimeMs + 1, kPayloadData, sizeof(kPayloadData), nullptr,
1752 &video_header, kDefaultExpectedRetransmissionTimeMs));
1753
1754 ASSERT_TRUE(media_packet != nullptr);
1755 ASSERT_TRUE(fec_packet != nullptr);
1756
1757 flexfec_seq_num = fec_packet->SequenceNumber();
1758 rtp_sender_->TrySendPacket(media_packet.get(), PacedPacketInfo());
1759 rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo());
1760 }
1761
1762 ASSERT_EQ(3, transport_.packets_sent());
1763 const RtpPacketReceived& media_packet2 = transport_.sent_packets_[1];
1764 EXPECT_EQ(kMediaPayloadType, media_packet2.PayloadType());
1765 EXPECT_EQ(kSeqNum + 1, media_packet2.SequenceNumber());
1766 EXPECT_EQ(kSsrc, media_packet2.Ssrc());
1767 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[2];
1768 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
1769 EXPECT_EQ(flexfec_seq_num, flexfec_packet.SequenceNumber());
1770 EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
1771}
1772
minyue3a407ee2017-04-03 01:10:33 -07001773TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001774 constexpr uint32_t kTimestamp = 1234;
brandtrdbdb3f12016-11-10 05:04:48 -08001775 constexpr int kMediaPayloadType = 127;
1776 constexpr int kFlexfecPayloadType = 118;
brandtrdbdb3f12016-11-10 05:04:48 -08001777 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001778 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språngf6468d22019-07-05 16:53:43 +02001779 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
Erik Språng4580ca22019-07-04 10:38:43 +02001780 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001781 nullptr /* rtp_state */, &fake_clock_);
brandtrdbdb3f12016-11-10 05:04:48 -08001782
1783 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001784 RtpRtcp::Configuration config;
1785 config.clock = &fake_clock_;
1786 config.outgoing_transport = &transport_;
1787 config.media_send_ssrc = kSsrc;
1788 config.flexfec_sender = &flexfec_sender;
1789 config.transport_sequence_number_allocator = &seq_num_allocator_;
1790 config.event_log = &mock_rtc_event_log_;
1791 config.send_packet_observer = &send_packet_observer_;
1792 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1793 rtp_sender_ = absl::make_unique<RTPSender>(config);
1794
brandtrdbdb3f12016-11-10 05:04:48 -08001795 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtrdbdb3f12016-11-10 05:04:48 -08001796
Niels Möller5fe95102019-03-04 16:49:25 +01001797 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001798 RTPSenderVideo rtp_sender_video(
1799 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1800 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001801 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1802 /*raw_payload=*/false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001803
brandtrdbdb3f12016-11-10 05:04:48 -08001804 // Parameters selected to generate a single FEC packet per media packet.
1805 FecProtectionParams params;
1806 params.fec_rate = 15;
1807 params.max_fec_frames = 1;
1808 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001809 rtp_sender_video.SetFecParameters(params, params);
brandtrdbdb3f12016-11-10 05:04:48 -08001810
Elad Alon4a87e1c2017-10-03 16:11:34 +02001811 EXPECT_CALL(mock_rtc_event_log_,
1812 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1813 .Times(2);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001814 RTPVideoHeader video_header;
1815 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001816 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001817 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1818 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1819
brandtrdbdb3f12016-11-10 05:04:48 -08001820 ASSERT_EQ(2, transport_.packets_sent());
1821 const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
1822 EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
Erik Språng4580ca22019-07-04 10:38:43 +02001823 EXPECT_EQ(kSsrc, media_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001824 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[1];
1825 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
Erik Språngf6468d22019-07-05 16:53:43 +02001826 EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001827}
1828
Steve Anton296a0ce2018-03-22 15:17:27 -07001829// Test that the MID header extension is included on sent packets when
1830// configured.
1831TEST_P(RtpSenderTestWithoutPacer, MidIncludedOnSentPackets) {
1832 const char kMid[] = "mid";
1833
1834 // Register MID header extension and set the MID for the RTPSender.
1835 rtp_sender_->SetSendingMediaStatus(false);
1836 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionMid, kMidExtensionId);
1837 rtp_sender_->SetMid(kMid);
1838 rtp_sender_->SetSendingMediaStatus(true);
1839
1840 // Send a couple packets.
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001841 SendGenericPacket();
1842 SendGenericPacket();
Steve Anton296a0ce2018-03-22 15:17:27 -07001843
1844 // Expect both packets to have the MID set.
1845 ASSERT_EQ(2u, transport_.sent_packets_.size());
1846 for (const RtpPacketReceived& packet : transport_.sent_packets_) {
1847 std::string mid;
1848 ASSERT_TRUE(packet.GetExtension<RtpMid>(&mid));
1849 EXPECT_EQ(kMid, mid);
1850 }
1851}
1852
Amit Hilbuch77938e62018-12-21 09:23:38 -08001853TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnSentPackets) {
1854 const char kRid[] = "f";
1855
1856 rtp_sender_->SetSendingMediaStatus(false);
1857 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
1858 kRidExtensionId);
1859 rtp_sender_->SetRid(kRid);
1860 rtp_sender_->SetSendingMediaStatus(true);
1861
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001862 SendGenericPacket();
Amit Hilbuch77938e62018-12-21 09:23:38 -08001863
1864 ASSERT_EQ(1u, transport_.sent_packets_.size());
1865 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1866 std::string rid;
1867 ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
1868 EXPECT_EQ(kRid, rid);
1869}
1870
1871TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnRtxSentPackets) {
1872 const char kRid[] = "f";
Amit Hilbuch77938e62018-12-21 09:23:38 -08001873
1874 rtp_sender_->SetSendingMediaStatus(false);
1875 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
1876 kRidExtensionId);
1877 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRepairedRtpStreamId,
1878 kRepairedRidExtensionId);
1879 rtp_sender_->SetRid(kRid);
1880 rtp_sender_->SetSendingMediaStatus(true);
1881
1882 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001883 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
Amit Hilbuch77938e62018-12-21 09:23:38 -08001884
1885 rtp_sender_->SetStorePacketsStatus(true, 10);
1886
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001887 SendGenericPacket();
Amit Hilbuch77938e62018-12-21 09:23:38 -08001888 ASSERT_EQ(1u, transport_.sent_packets_.size());
1889 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1890 std::string rid;
1891 ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
1892 EXPECT_EQ(kRid, rid);
1893 rid = kNoRid;
1894 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&rid));
1895
1896 uint16_t packet_id = packet.SequenceNumber();
1897 rtp_sender_->ReSendPacket(packet_id);
1898 ASSERT_EQ(2u, transport_.sent_packets_.size());
1899 const RtpPacketReceived& rtx_packet = transport_.sent_packets_[1];
1900 ASSERT_TRUE(rtx_packet.GetExtension<RepairedRtpStreamId>(&rid));
1901 EXPECT_EQ(kRid, rid);
1902 EXPECT_FALSE(rtx_packet.HasExtension<RtpStreamId>());
1903}
1904
minyue3a407ee2017-04-03 01:10:33 -07001905TEST_P(RtpSenderTest, FecOverheadRate) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001906 constexpr uint32_t kTimestamp = 1234;
1907 constexpr int kMediaPayloadType = 127;
brandtr81eab612017-01-24 04:06:09 -08001908 constexpr int kFlexfecPayloadType = 118;
brandtr81eab612017-01-24 04:06:09 -08001909 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001910 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språng4580ca22019-07-04 10:38:43 +02001911 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1912 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001913 nullptr /* rtp_state */, &fake_clock_);
brandtr81eab612017-01-24 04:06:09 -08001914
1915 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001916 RtpRtcp::Configuration config;
1917 config.clock = &fake_clock_;
1918 config.outgoing_transport = &transport_;
1919 config.paced_sender = &mock_paced_sender_;
1920 config.media_send_ssrc = kSsrc;
1921 config.flexfec_sender = &flexfec_sender;
1922 config.transport_sequence_number_allocator = &seq_num_allocator_;
1923 config.event_log = &mock_rtc_event_log_;
1924 config.send_packet_observer = &send_packet_observer_;
1925 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1926 rtp_sender_ = absl::make_unique<RTPSender>(config);
1927
brandtr81eab612017-01-24 04:06:09 -08001928 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtr81eab612017-01-24 04:06:09 -08001929
Niels Möller5fe95102019-03-04 16:49:25 +01001930 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001931 RTPSenderVideo rtp_sender_video(
1932 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1933 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001934 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1935 /*raw_payload=*/false);
brandtr81eab612017-01-24 04:06:09 -08001936 // Parameters selected to generate a single FEC packet per media packet.
1937 FecProtectionParams params;
1938 params.fec_rate = 15;
1939 params.max_fec_frames = 1;
1940 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001941 rtp_sender_video.SetFecParameters(params, params);
brandtr81eab612017-01-24 04:06:09 -08001942
1943 constexpr size_t kNumMediaPackets = 10;
1944 constexpr size_t kNumFecPackets = kNumMediaPackets;
1945 constexpr int64_t kTimeBetweenPacketsMs = 10;
Erik Språngf6468d22019-07-05 16:53:43 +02001946 if (GetParam().pacer_references_packets) {
1947 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, _, _, _, _, false))
1948 .Times(kNumMediaPackets + kNumFecPackets);
1949 } else {
1950 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1951 .Times(kNumMediaPackets + kNumFecPackets);
1952 }
brandtr81eab612017-01-24 04:06:09 -08001953 for (size_t i = 0; i < kNumMediaPackets; ++i) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001954 RTPVideoHeader video_header;
1955
1956 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001957 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001958 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1959 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1960
brandtr81eab612017-01-24 04:06:09 -08001961 fake_clock_.AdvanceTimeMilliseconds(kTimeBetweenPacketsMs);
1962 }
1963 constexpr size_t kRtpHeaderLength = 12;
1964 constexpr size_t kFlexfecHeaderLength = 20;
1965 constexpr size_t kGenericCodecHeaderLength = 1;
1966 constexpr size_t kPayloadLength = sizeof(kPayloadData);
1967 constexpr size_t kPacketLength = kRtpHeaderLength + kFlexfecHeaderLength +
1968 kGenericCodecHeaderLength + kPayloadLength;
1969 EXPECT_NEAR(kNumFecPackets * kPacketLength * 8 /
1970 (kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f),
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001971 rtp_sender_video.FecOverheadRate(), 500);
brandtr81eab612017-01-24 04:06:09 -08001972}
1973
minyue3a407ee2017-04-03 01:10:33 -07001974TEST_P(RtpSenderTest, BitrateCallbacks) {
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001975 class TestCallback : public BitrateStatisticsObserver {
1976 public:
sprangcd349d92016-07-13 09:11:28 -07001977 TestCallback()
1978 : BitrateStatisticsObserver(),
1979 num_calls_(0),
1980 ssrc_(0),
1981 total_bitrate_(0),
1982 retransmit_bitrate_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +00001983 ~TestCallback() override = default;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001984
sprangcd349d92016-07-13 09:11:28 -07001985 void Notify(uint32_t total_bitrate,
1986 uint32_t retransmit_bitrate,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001987 uint32_t ssrc) override {
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001988 ++num_calls_;
1989 ssrc_ = ssrc;
sprangcd349d92016-07-13 09:11:28 -07001990 total_bitrate_ = total_bitrate;
1991 retransmit_bitrate_ = retransmit_bitrate;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001992 }
1993
1994 uint32_t num_calls_;
1995 uint32_t ssrc_;
sprangcd349d92016-07-13 09:11:28 -07001996 uint32_t total_bitrate_;
1997 uint32_t retransmit_bitrate_;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001998 } callback;
Erik Språng4580ca22019-07-04 10:38:43 +02001999
2000 RtpRtcp::Configuration config;
2001 config.clock = &fake_clock_;
2002 config.outgoing_transport = &transport_;
2003 config.media_send_ssrc = kSsrc;
2004 config.send_bitrate_observer = &callback;
2005 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
2006 rtp_sender_ = absl::make_unique<RTPSender>(config);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002007
Niels Möller5fe95102019-03-04 16:49:25 +01002008 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01002009 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02002010 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01002011 FieldTrialBasedConfig());
Niels Möller59ab1cf2019-02-06 22:48:11 +01002012 const char payload_name[] = "GENERIC";
2013 const uint8_t payload_type = 127;
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02002014 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
2015 /*raw_payload=*/false);
Niels Möller59ab1cf2019-02-06 22:48:11 +01002016
sprangcd349d92016-07-13 09:11:28 -07002017 // Simulate kNumPackets sent with kPacketInterval ms intervals, with the
2018 // number of packets selected so that we fill (but don't overflow) the one
2019 // second averaging window.
2020 const uint32_t kWindowSizeMs = 1000;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002021 const uint32_t kPacketInterval = 20;
sprangcd349d92016-07-13 09:11:28 -07002022 const uint32_t kNumPackets =
2023 (kWindowSizeMs - kPacketInterval) / kPacketInterval;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002024 // Overhead = 12 bytes RTP header + 1 byte generic header.
2025 const uint32_t kPacketOverhead = 13;
2026
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002027 uint8_t payload[] = {47, 11, 32, 93, 89};
2028 rtp_sender_->SetStorePacketsStatus(true, 1);
2029 uint32_t ssrc = rtp_sender_->SSRC();
2030
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002031 // Initial process call so we get a new time window.
2032 rtp_sender_->ProcessBitrate();
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002033
2034 // Send a few frames.
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02002035 RTPVideoHeader video_header;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002036 for (uint32_t i = 0; i < kNumPackets; ++i) {
Niels Möller59ab1cf2019-02-06 22:48:11 +01002037 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01002038 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
2039 sizeof(payload), nullptr, &video_header,
2040 kDefaultExpectedRetransmissionTimeMs));
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002041 fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
2042 }
2043
2044 rtp_sender_->ProcessBitrate();
2045
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00002046 // We get one call for every stats updated, thus two calls since both the
2047 // stream stats and the retransmit stats are updated once.
2048 EXPECT_EQ(2u, callback.num_calls_);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002049 EXPECT_EQ(ssrc, callback.ssrc_);
sprangcd349d92016-07-13 09:11:28 -07002050 const uint32_t kTotalPacketSize = kPacketOverhead + sizeof(payload);
2051 // Bitrate measured over delta between last and first timestamp, plus one.
2052 const uint32_t kExpectedWindowMs = kNumPackets * kPacketInterval + 1;
2053 const uint32_t kExpectedBitsAccumulated = kTotalPacketSize * kNumPackets * 8;
2054 const uint32_t kExpectedRateBps =
2055 (kExpectedBitsAccumulated * 1000 + (kExpectedWindowMs / 2)) /
2056 kExpectedWindowMs;
2057 EXPECT_EQ(kExpectedRateBps, callback.total_bitrate_);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002058
andresp@webrtc.orgd11bec42014-07-08 14:32:58 +00002059 rtp_sender_.reset();
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00002060}
2061
minyue3a407ee2017-04-03 01:10:33 -07002062TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002063 class TestCallback : public StreamDataCountersCallback {
2064 public:
danilchap162abd32015-12-10 02:39:40 -08002065 TestCallback() : StreamDataCountersCallback(), ssrc_(0), counters_() {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +00002066 ~TestCallback() override = default;
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002067
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002068 void DataCountersUpdated(const StreamDataCounters& counters,
2069 uint32_t ssrc) override {
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002070 ssrc_ = ssrc;
2071 counters_ = counters;
2072 }
2073
2074 uint32_t ssrc_;
2075 StreamDataCounters counters_;
asapersson@webrtc.org44149392015-02-04 08:34:47 +00002076
2077 void MatchPacketCounter(const RtpPacketCounter& expected,
2078 const RtpPacketCounter& actual) {
2079 EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
2080 EXPECT_EQ(expected.header_bytes, actual.header_bytes);
2081 EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
2082 EXPECT_EQ(expected.packets, actual.packets);
2083 }
2084
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00002085 void Matches(uint32_t ssrc, const StreamDataCounters& counters) {
2086 EXPECT_EQ(ssrc, ssrc_);
asapersson@webrtc.org44149392015-02-04 08:34:47 +00002087 MatchPacketCounter(counters.transmitted, counters_.transmitted);
2088 MatchPacketCounter(counters.retransmitted, counters_.retransmitted);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002089 EXPECT_EQ(counters.fec.packets, counters_.fec.packets);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002090 }
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002091 } callback;
2092
2093 const uint8_t kRedPayloadType = 96;
2094 const uint8_t kUlpfecPayloadType = 97;
Niels Möller8a40edd2019-01-24 18:04:44 +01002095 const char payload_name[] = "GENERIC";
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002096 const uint8_t payload_type = 127;
Niels Möller5fe95102019-03-04 16:49:25 +01002097 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01002098 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02002099 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01002100 FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02002101 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
2102 /*raw_payload=*/false);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002103 uint8_t payload[] = {47, 11, 32, 93, 89};
2104 rtp_sender_->SetStorePacketsStatus(true, 1);
2105 uint32_t ssrc = rtp_sender_->SSRC();
2106
2107 rtp_sender_->RegisterRtpStatisticsCallback(&callback);
2108
2109 // Send a frame.
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02002110 RTPVideoHeader video_header;
Niels Möller59ab1cf2019-02-06 22:48:11 +01002111 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01002112 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
2113 sizeof(payload), nullptr, &video_header,
2114 kDefaultExpectedRetransmissionTimeMs));
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00002115 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002116 expected.transmitted.payload_bytes = 6;
2117 expected.transmitted.header_bytes = 12;
2118 expected.transmitted.padding_bytes = 0;
2119 expected.transmitted.packets = 1;
2120 expected.retransmitted.payload_bytes = 0;
2121 expected.retransmitted.header_bytes = 0;
2122 expected.retransmitted.padding_bytes = 0;
2123 expected.retransmitted.packets = 0;
2124 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00002125 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002126
2127 // Retransmit a frame.
2128 uint16_t seqno = rtp_sender_->SequenceNumber() - 1;
Erik Språnga12b1d62018-03-14 12:39:24 +01002129 rtp_sender_->ReSendPacket(seqno);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002130 expected.transmitted.payload_bytes = 12;
2131 expected.transmitted.header_bytes = 24;
2132 expected.transmitted.packets = 2;
2133 expected.retransmitted.payload_bytes = 6;
2134 expected.retransmitted.header_bytes = 12;
2135 expected.retransmitted.padding_bytes = 0;
2136 expected.retransmitted.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00002137 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002138
2139 // Send padding.
philipel8aadd502017-02-23 02:56:13 -08002140 rtp_sender_->TimeToSendPadding(kMaxPaddingSize, PacedPacketInfo());
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002141 expected.transmitted.payload_bytes = 12;
2142 expected.transmitted.header_bytes = 36;
2143 expected.transmitted.padding_bytes = kMaxPaddingSize;
2144 expected.transmitted.packets = 3;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00002145 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002146
brandtrf1bb4762016-11-07 03:05:06 -08002147 // Send ULPFEC.
Niels Möller59ab1cf2019-02-06 22:48:11 +01002148 rtp_sender_video.SetUlpfecConfig(kRedPayloadType, kUlpfecPayloadType);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002149 FecProtectionParams fec_params;
2150 fec_params.fec_mask_type = kFecMaskRandom;
2151 fec_params.fec_rate = 1;
2152 fec_params.max_fec_frames = 1;
Niels Möller59ab1cf2019-02-06 22:48:11 +01002153 rtp_sender_video.SetFecParameters(fec_params, fec_params);
2154 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01002155 VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload,
2156 sizeof(payload), nullptr, &video_header,
2157 kDefaultExpectedRetransmissionTimeMs));
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002158 expected.transmitted.payload_bytes = 40;
2159 expected.transmitted.header_bytes = 60;
2160 expected.transmitted.packets = 5;
2161 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00002162 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002163
sprang867fb522015-08-03 04:38:41 -07002164 rtp_sender_->RegisterRtpStatisticsCallback(nullptr);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00002165}
2166
minyue3a407ee2017-04-03 01:10:33 -07002167TEST_P(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
Niels Möller59ab1cf2019-02-06 22:48:11 +01002168 // XXX const char* kPayloadName = "GENERIC";
pbos@webrtc.org72491b92014-07-10 16:24:54 +00002169 const uint8_t kPayloadType = 127;
Shao Changbine62202f2015-04-21 20:24:50 +08002170 rtp_sender_->SetRtxPayloadType(kPayloadType - 1, kPayloadType);
pbos@webrtc.org0b0c2412015-01-13 14:15:15 +00002171 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00002172
Niels Möller59ab1cf2019-02-06 22:48:11 +01002173 SendGenericPacket();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002174 // Will send 2 full-size padding packets.
philipel8aadd502017-02-23 02:56:13 -08002175 rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
2176 rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
pbos@webrtc.org72491b92014-07-10 16:24:54 +00002177
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002178 StreamDataCounters rtp_stats;
2179 StreamDataCounters rtx_stats;
2180 rtp_sender_->GetDataCounters(&rtp_stats, &rtx_stats);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00002181
Niels Möller59ab1cf2019-02-06 22:48:11 +01002182 // Payload
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +00002183 EXPECT_GT(rtp_stats.first_packet_time_ms, -1);
Niels Möller59ab1cf2019-02-06 22:48:11 +01002184 EXPECT_EQ(rtp_stats.transmitted.payload_bytes, sizeof(kPayloadData));
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002185 EXPECT_EQ(rtp_stats.transmitted.header_bytes, 12u);
2186 EXPECT_EQ(rtp_stats.transmitted.padding_bytes, 0u);
2187 EXPECT_EQ(rtx_stats.transmitted.payload_bytes, 0u);
2188 EXPECT_EQ(rtx_stats.transmitted.header_bytes, 24u);
2189 EXPECT_EQ(rtx_stats.transmitted.padding_bytes, 2 * kMaxPaddingSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002190
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002191 EXPECT_EQ(rtp_stats.transmitted.TotalBytes(),
danilchap162abd32015-12-10 02:39:40 -08002192 rtp_stats.transmitted.payload_bytes +
2193 rtp_stats.transmitted.header_bytes +
2194 rtp_stats.transmitted.padding_bytes);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002195 EXPECT_EQ(rtx_stats.transmitted.TotalBytes(),
danilchap162abd32015-12-10 02:39:40 -08002196 rtx_stats.transmitted.payload_bytes +
2197 rtx_stats.transmitted.header_bytes +
2198 rtx_stats.transmitted.padding_bytes);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00002199
danilchap162abd32015-12-10 02:39:40 -08002200 EXPECT_EQ(
2201 transport_.total_bytes_sent_,
2202 rtp_stats.transmitted.TotalBytes() + rtx_stats.transmitted.TotalBytes());
pbos@webrtc.org72491b92014-07-10 16:24:54 +00002203}
guoweis@webrtc.org45362892015-03-04 22:55:15 +00002204
minyue3a407ee2017-04-03 01:10:33 -07002205TEST_P(RtpSenderTestWithoutPacer, RespectsNackBitrateLimit) {
sprang38778b02015-09-29 09:48:22 -07002206 const int32_t kPacketSize = 1400;
2207 const int32_t kNumPackets = 30;
2208
sprangcd349d92016-07-13 09:11:28 -07002209 retransmission_rate_limiter_.SetMaxRate(kPacketSize * kNumPackets * 8);
2210
sprang38778b02015-09-29 09:48:22 -07002211 rtp_sender_->SetStorePacketsStatus(true, kNumPackets);
sprang38778b02015-09-29 09:48:22 -07002212 const uint16_t kStartSequenceNumber = rtp_sender_->SequenceNumber();
Danil Chapovalov2800d742016-08-26 18:48:46 +02002213 std::vector<uint16_t> sequence_numbers;
sprang38778b02015-09-29 09:48:22 -07002214 for (int32_t i = 0; i < kNumPackets; ++i) {
2215 sequence_numbers.push_back(kStartSequenceNumber + i);
2216 fake_clock_.AdvanceTimeMilliseconds(1);
2217 SendPacket(fake_clock_.TimeInMilliseconds(), kPacketSize);
2218 }
danilchap12ba1862016-10-26 02:41:55 -07002219 EXPECT_EQ(kNumPackets, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07002220
2221 fake_clock_.AdvanceTimeMilliseconds(1000 - kNumPackets);
2222
2223 // Resending should work - brings the bandwidth up to the limit.
2224 // NACK bitrate is capped to the same bitrate as the encoder, since the max
2225 // protection overhead is 50% (see MediaOptimization::SetTargetRates).
Danil Chapovalov2800d742016-08-26 18:48:46 +02002226 rtp_sender_->OnReceivedNack(sequence_numbers, 0);
danilchap12ba1862016-10-26 02:41:55 -07002227 EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07002228
sprangcd349d92016-07-13 09:11:28 -07002229 // Must be at least 5ms in between retransmission attempts.
2230 fake_clock_.AdvanceTimeMilliseconds(5);
2231
sprang38778b02015-09-29 09:48:22 -07002232 // Resending should not work, bandwidth exceeded.
Danil Chapovalov2800d742016-08-26 18:48:46 +02002233 rtp_sender_->OnReceivedNack(sequence_numbers, 0);
danilchap12ba1862016-10-26 02:41:55 -07002234 EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07002235}
2236
minyue3a407ee2017-04-03 01:10:33 -07002237TEST_P(RtpSenderTest, OnOverheadChanged) {
michaelt4da30442016-11-17 01:38:43 -08002238 MockOverheadObserver mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02002239 RtpRtcp::Configuration config;
2240 config.clock = &fake_clock_;
2241 config.outgoing_transport = &transport_;
2242 config.media_send_ssrc = kSsrc;
2243 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
2244 config.overhead_observer = &mock_overhead_observer;
2245 rtp_sender_ = absl::make_unique<RTPSender>(config);
michaelt4da30442016-11-17 01:38:43 -08002246
michaelt4da30442016-11-17 01:38:43 -08002247 // RTP overhead is 12B.
nisse284542b2017-01-10 08:58:32 -08002248 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(12)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01002249 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08002250
2251 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
2252 kTransmissionTimeOffsetExtensionId);
2253
2254 // TransmissionTimeOffset extension has a size of 8B.
nisse284542b2017-01-10 08:58:32 -08002255 // 12B + 8B = 20B
2256 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(20)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01002257 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08002258}
2259
minyue3a407ee2017-04-03 01:10:33 -07002260TEST_P(RtpSenderTest, DoesNotUpdateOverheadOnEqualSize) {
michaelt4da30442016-11-17 01:38:43 -08002261 MockOverheadObserver mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02002262 RtpRtcp::Configuration config;
2263 config.clock = &fake_clock_;
2264 config.outgoing_transport = &transport_;
2265 config.media_send_ssrc = kSsrc;
2266 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
2267 config.overhead_observer = &mock_overhead_observer;
2268 rtp_sender_ = absl::make_unique<RTPSender>(config);
michaelt4da30442016-11-17 01:38:43 -08002269
2270 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(_)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01002271 SendGenericPacket();
2272 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08002273}
2274
Erik Språng9c771c22019-06-17 16:31:53 +02002275TEST_P(RtpSenderTest, TrySendPacketMatchesVideo) {
2276 std::unique_ptr<RtpPacketToSend> packet =
2277 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2278 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2279
2280 // Verify not sent with wrong SSRC.
2281 packet->SetSsrc(kSsrc + 1);
2282 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2283
2284 // Verify sent with correct SSRC.
2285 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2286 packet->SetSsrc(kSsrc);
2287 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2288 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2289}
2290
2291TEST_P(RtpSenderTest, TrySendPacketMatchesAudio) {
2292 std::unique_ptr<RtpPacketToSend> packet =
2293 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2294 packet->set_packet_type(RtpPacketToSend::Type::kAudio);
2295
2296 // Verify not sent with wrong SSRC.
2297 packet->SetSsrc(kSsrc + 1);
2298 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2299
2300 // Verify sent with correct SSRC.
2301 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2302 packet->SetSsrc(kSsrc);
2303 packet->set_packet_type(RtpPacketToSend::Type::kAudio);
2304 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2305}
2306
2307TEST_P(RtpSenderTest, TrySendPacketMatchesRetransmissions) {
2308 std::unique_ptr<RtpPacketToSend> packet =
2309 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2310 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2311
2312 // Verify not sent with wrong SSRC.
2313 packet->SetSsrc(kSsrc + 1);
2314 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2315
2316 // Verify sent with correct SSRC (non-RTX).
2317 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2318 packet->SetSsrc(kSsrc);
2319 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2320 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2321
2322 // RTX retransmission.
2323 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2324 packet->SetSsrc(kRtxSsrc);
2325 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2326 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2327}
2328
2329TEST_P(RtpSenderTest, TrySendPacketMatchesPadding) {
2330 std::unique_ptr<RtpPacketToSend> packet =
2331 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2332 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2333
2334 // Verify not sent with wrong SSRC.
2335 packet->SetSsrc(kSsrc + 1);
2336 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2337
2338 // Verify sent with correct SSRC (non-RTX).
2339 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2340 packet->SetSsrc(kSsrc);
2341 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2342 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2343
2344 // RTX padding.
2345 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2346 packet->SetSsrc(kRtxSsrc);
2347 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2348 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2349}
2350
2351TEST_P(RtpSenderTest, TrySendPacketMatchesFlexfec) {
2352 std::unique_ptr<RtpPacketToSend> packet =
2353 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2354 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2355
2356 // Verify not sent with wrong SSRC.
2357 packet->SetSsrc(kSsrc + 1);
2358 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2359
2360 // Verify sent with correct SSRC.
2361 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2362 packet->SetSsrc(kFlexFecSsrc);
2363 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2364 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2365}
2366
2367TEST_P(RtpSenderTest, TrySendPacketMatchesUlpfec) {
2368 std::unique_ptr<RtpPacketToSend> packet =
2369 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2370 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2371
2372 // Verify not sent with wrong SSRC.
2373 packet->SetSsrc(kSsrc + 1);
2374 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2375
2376 // Verify sent with correct SSRC.
2377 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2378 packet->SetSsrc(kSsrc);
2379 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2380 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2381}
2382
2383TEST_P(RtpSenderTest, TrySendPacketHandlesRetransmissionHistory) {
2384 rtp_sender_->SetStorePacketsStatus(true, 10);
2385
2386 // Build a media packet and send it.
2387 std::unique_ptr<RtpPacketToSend> packet =
2388 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2389 const uint16_t media_sequence_number = packet->SequenceNumber();
2390 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2391 packet->set_allow_retransmission(true);
2392 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2393
2394 // Simulate retransmission request.
2395 fake_clock_.AdvanceTimeMilliseconds(30);
2396 EXPECT_GT(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2397
2398 // Packet already pending, retransmission not allowed.
2399 fake_clock_.AdvanceTimeMilliseconds(30);
2400 EXPECT_EQ(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2401
2402 // Packet exiting pacer, mark as not longer pending.
2403 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2404 EXPECT_NE(packet->SequenceNumber(), media_sequence_number);
2405 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2406 packet->SetSsrc(kRtxSsrc);
2407 packet->set_retransmitted_sequence_number(media_sequence_number);
2408 packet->set_allow_retransmission(false);
2409 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2410
2411 // Retransmissions allowed again.
2412 fake_clock_.AdvanceTimeMilliseconds(30);
2413 EXPECT_GT(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2414
2415 // Retransmission of RTX packet should not be allowed.
2416 EXPECT_EQ(rtp_sender_->ReSendPacket(packet->SequenceNumber()), 0);
2417}
2418
2419TEST_P(RtpSenderTest, TrySendPacketUpdatesExtensions) {
2420 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2421 kRtpExtensionTransmissionTimeOffset,
2422 kTransmissionTimeOffsetExtensionId),
2423 0);
2424 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2425 kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId),
2426 0);
2427 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionVideoTiming,
2428 kVideoTimingExtensionId),
2429 0);
2430
2431 std::unique_ptr<RtpPacketToSend> packet =
2432 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2433 packet->set_packetization_finish_time_ms(fake_clock_.TimeInMilliseconds());
2434
2435 const int32_t kDiffMs = 10;
2436 fake_clock_.AdvanceTimeMilliseconds(kDiffMs);
2437
2438 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2439 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2440
2441 const RtpPacketReceived& received_packet = transport_.last_sent_packet();
2442
2443 EXPECT_EQ(received_packet.GetExtension<TransmissionOffset>(), kDiffMs * 90);
2444
2445 EXPECT_EQ(received_packet.GetExtension<AbsoluteSendTime>(),
2446 AbsoluteSendTime::MsTo24Bits(fake_clock_.TimeInMilliseconds()));
2447
2448 VideoSendTiming timing;
2449 EXPECT_TRUE(received_packet.GetExtension<VideoTimingExtension>(&timing));
2450 EXPECT_EQ(timing.pacer_exit_delta_ms, kDiffMs);
2451}
2452
2453TEST_P(RtpSenderTest, TrySendPacketSetsPacketOptions) {
2454 const uint16_t kPacketId = 42;
2455 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2456 kRtpExtensionTransportSequenceNumber,
2457 kTransportSequenceNumberExtensionId),
2458 0);
2459 std::unique_ptr<RtpPacketToSend> packet =
2460 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2461 packet->SetExtension<TransportSequenceNumber>(kPacketId);
2462
2463 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2464 EXPECT_CALL(send_packet_observer_, OnSendPacket);
2465 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2466
2467 EXPECT_EQ(transport_.last_options_.packet_id, kPacketId);
2468 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
2469 EXPECT_TRUE(transport_.last_options_.included_in_feedback);
2470 EXPECT_FALSE(transport_.last_options_.is_retransmit);
2471
2472 // Send another packet as retransmission, verify options are populated.
2473 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2474 packet->SetExtension<TransportSequenceNumber>(kPacketId + 1);
2475 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2476 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2477 EXPECT_TRUE(transport_.last_options_.is_retransmit);
2478}
2479
2480TEST_P(RtpSenderTest, TrySendPacketUpdatesStats) {
2481 const size_t kPayloadSize = 1000;
2482
2483 StrictMock<MockSendSideDelayObserver> send_side_delay_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02002484
2485 RtpRtcp::Configuration config;
2486 config.clock = &fake_clock_;
2487 config.outgoing_transport = &transport_;
2488 config.media_send_ssrc = kSsrc;
2489 config.rtx_send_ssrc = kRtxSsrc;
2490 config.flexfec_sender = &flexfec_sender_;
2491 config.send_side_delay_observer = &send_side_delay_observer;
2492 config.event_log = &mock_rtc_event_log_;
2493 config.send_packet_observer = &send_packet_observer_;
2494 rtp_sender_ = absl::make_unique<RTPSender>(config);
Erik Språng9c771c22019-06-17 16:31:53 +02002495 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2496 kRtpExtensionTransportSequenceNumber,
2497 kTransportSequenceNumberExtensionId));
2498
2499 const int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
2500
2501 std::unique_ptr<RtpPacketToSend> video_packet =
2502 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2503 video_packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2504 video_packet->SetPayloadSize(kPayloadSize);
2505 video_packet->SetExtension<TransportSequenceNumber>(1);
2506
2507 std::unique_ptr<RtpPacketToSend> rtx_packet =
2508 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2509 rtx_packet->SetSsrc(kRtxSsrc);
2510 rtx_packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2511 rtx_packet->SetPayloadSize(kPayloadSize);
2512 rtx_packet->SetExtension<TransportSequenceNumber>(2);
2513
2514 std::unique_ptr<RtpPacketToSend> fec_packet =
2515 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2516 fec_packet->SetSsrc(kFlexFecSsrc);
2517 fec_packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2518 fec_packet->SetPayloadSize(kPayloadSize);
2519 fec_packet->SetExtension<TransportSequenceNumber>(3);
2520
2521 const int64_t kDiffMs = 25;
2522 fake_clock_.AdvanceTimeMilliseconds(kDiffMs);
2523
2524 EXPECT_CALL(send_side_delay_observer,
2525 SendSideDelayUpdated(kDiffMs, kDiffMs, kDiffMs, kSsrc));
2526 EXPECT_CALL(
2527 send_side_delay_observer,
2528 SendSideDelayUpdated(kDiffMs, kDiffMs, 2 * kDiffMs, kFlexFecSsrc));
2529
2530 EXPECT_CALL(send_packet_observer_, OnSendPacket(1, capture_time_ms, kSsrc));
2531 EXPECT_TRUE(
2532 rtp_sender_->TrySendPacket(video_packet.get(), PacedPacketInfo()));
2533
2534 // Send packet observer not called for padding/retransmissions.
2535 EXPECT_CALL(send_packet_observer_, OnSendPacket(2, _, _)).Times(0);
2536 EXPECT_TRUE(rtp_sender_->TrySendPacket(rtx_packet.get(), PacedPacketInfo()));
2537
2538 EXPECT_CALL(send_packet_observer_,
2539 OnSendPacket(3, capture_time_ms, kFlexFecSsrc));
2540 EXPECT_TRUE(rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo()));
2541
2542 StreamDataCounters rtp_stats;
2543 StreamDataCounters rtx_stats;
2544 rtp_sender_->GetDataCounters(&rtp_stats, &rtx_stats);
2545 EXPECT_EQ(rtp_stats.transmitted.packets, 2u);
2546 EXPECT_EQ(rtp_stats.fec.packets, 1u);
2547 EXPECT_EQ(rtx_stats.retransmitted.packets, 1u);
2548}
2549
Erik Språng478cb462019-06-26 15:49:27 +02002550TEST_P(RtpSenderTest, GeneratePaddingResendsOldPacketsWithRtx) {
2551 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2552 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2553 rtp_sender_->SetStorePacketsStatus(true, 1);
2554
2555 const size_t kPayloadPacketSize = 1234;
2556 std::unique_ptr<RtpPacketToSend> packet =
2557 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2558 packet->set_allow_retransmission(true);
2559 packet->SetPayloadSize(kPayloadPacketSize);
2560 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2561
2562 // Send a dummy video packet so it ends up in the packet history.
2563 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2564
2565 // Generated padding has large enough budget that the video packet should be
2566 // retransmitted as padding.
Erik Språngf6468d22019-07-05 16:53:43 +02002567 std::vector<std::unique_ptr<RtpPacketToSend>> generated_packets =
2568 rtp_sender_->GeneratePadding(kPayloadPacketSize + kRtxHeaderSize);
2569 ASSERT_EQ(generated_packets.size(), 1u);
2570 auto& padding_packet = generated_packets.front();
2571 EXPECT_EQ(padding_packet->packet_type(), RtpPacketToSend::Type::kPadding);
2572 EXPECT_EQ(padding_packet->Ssrc(), kRtxSsrc);
2573 EXPECT_EQ(padding_packet->payload_size(),
2574 kPayloadPacketSize + kRtxHeaderSize);
Erik Språng478cb462019-06-26 15:49:27 +02002575
2576 // Not enough budged for payload padding, use plain padding instead.
Erik Språngf6468d22019-07-05 16:53:43 +02002577 const size_t kPaddingBytesRequested = kPayloadPacketSize + kRtxHeaderSize - 1;
2578 const size_t kExpectedNumPaddingPackets =
2579 (kPaddingBytesRequested + kMaxPaddingSize - 1) / kMaxPaddingSize;
2580
2581 size_t padding_bytes_generated = 0;
2582 generated_packets = rtp_sender_->GeneratePadding(kPaddingBytesRequested);
2583 EXPECT_EQ(generated_packets.size(), kExpectedNumPaddingPackets);
2584 for (auto& packet : generated_packets) {
2585 EXPECT_EQ(packet->packet_type(), RtpPacketToSend::Type::kPadding);
2586 EXPECT_EQ(packet->Ssrc(), kRtxSsrc);
2587 EXPECT_EQ(packet->payload_size(), 0u);
2588 EXPECT_GT(packet->padding_size(), 0u);
2589 padding_bytes_generated += packet->padding_size();
2590 }
2591
2592 EXPECT_EQ(padding_bytes_generated,
2593 kExpectedNumPaddingPackets * kMaxPaddingSize);
Erik Språng478cb462019-06-26 15:49:27 +02002594}
2595
2596TEST_P(RtpSenderTest, GeneratePaddingCreatesPurePaddingWithoutRtx) {
2597 rtp_sender_->SetStorePacketsStatus(true, 1);
2598
2599 const size_t kPayloadPacketSize = 1234;
2600 // Send a dummy video packet so it ends up in the packet history. Since we
2601 // are not using RTX, it should never be used as padding.
2602 std::unique_ptr<RtpPacketToSend> packet =
2603 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2604 packet->set_allow_retransmission(true);
2605 packet->SetPayloadSize(kPayloadPacketSize);
2606 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2607 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2608
2609 // Payload padding not available without RTX, only generate plain padding on
2610 // the media SSRC.
2611 // Number of padding packets is the requested padding size divided by max
2612 // padding packet size, rounded up. Pure padding packets are always of the
2613 // maximum size.
2614 const size_t kPaddingBytesRequested = kPayloadPacketSize + kRtxHeaderSize;
2615 const size_t kExpectedNumPaddingPackets =
2616 (kPaddingBytesRequested + kMaxPaddingSize - 1) / kMaxPaddingSize;
Erik Språngf6468d22019-07-05 16:53:43 +02002617 size_t padding_bytes_generated = 0;
2618 std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets =
2619 rtp_sender_->GeneratePadding(kPaddingBytesRequested);
2620 EXPECT_EQ(padding_packets.size(), kExpectedNumPaddingPackets);
2621 for (auto& packet : padding_packets) {
2622 EXPECT_EQ(packet->packet_type(), RtpPacketToSend::Type::kPadding);
2623 EXPECT_EQ(packet->Ssrc(), kSsrc);
2624 EXPECT_EQ(packet->payload_size(), 0u);
2625 EXPECT_GT(packet->padding_size(), 0u);
2626 padding_bytes_generated += packet->padding_size();
2627 }
2628
2629 EXPECT_EQ(padding_bytes_generated,
2630 kExpectedNumPaddingPackets * kMaxPaddingSize);
Erik Språng478cb462019-06-26 15:49:27 +02002631}
2632
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002633INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2634 RtpSenderTest,
Erik Språngf6468d22019-07-05 16:53:43 +02002635 ::testing::Values(TestConfig{false, false},
2636 TestConfig{false, true},
2637 TestConfig{true, false},
2638 TestConfig{true, true}));
2639
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002640INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2641 RtpSenderTestWithoutPacer,
Erik Språngf6468d22019-07-05 16:53:43 +02002642 ::testing::Values(TestConfig{false, false},
2643 TestConfig{true, false}));
Niels Möllera34d7762019-02-01 14:13:29 +01002644
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +00002645} // namespace webrtc