blob: 125a0b899456209d298727b747e12a0175898f2d [file] [log] [blame]
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001/*
phoglund@webrtc.org78088c22012-02-07 14:56:45 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/rtp_rtcp/source/rtp_sender.h"
12
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
danilchapb8b6fbb2015-12-10 05:05:27 -080014#include <vector>
15
Karl Wiberg918f50c2018-07-05 11:40:33 +020016#include "absl/memory/memory.h"
Per Kjellandere11b7d22019-02-21 07:55:59 +010017#include "api/transport/field_trial_based_config.h"
Erik Språngf93eda12019-01-16 17:10:57 +010018#include "api/video/video_codec_constants.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "api/video/video_timing.h"
Elad Alon4a87e1c2017-10-03 16:11:34 +020020#include "logging/rtc_event_log/events/rtc_event.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
22#include "modules/rtp_rtcp/include/rtp_cvo.h"
23#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
24#include "modules/rtp_rtcp/include/rtp_header_parser.h"
Erik Språngaa59eca2019-07-24 14:52:55 +020025#include "modules/rtp_rtcp/include/rtp_packet_sender.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
27#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
28#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
philipelb3e42a42018-09-13 10:57:14 +020029#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
30#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
32#include "modules/rtp_rtcp/source/rtp_packet_received.h"
33#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "modules/rtp_rtcp/source/rtp_sender_video.h"
35#include "modules/rtp_rtcp/source/rtp_utility.h"
36#include "rtc_base/arraysize.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "rtc_base/rate_limiter.h"
38#include "test/field_trial.h"
39#include "test/gmock.h"
40#include "test/gtest.h"
41#include "test/mock_transport.h"
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000042
43namespace webrtc {
44
andrew@webrtc.org8a442592011-12-16 21:24:30 +000045namespace {
Elad Alond8d32482019-02-18 23:45:57 +010046enum : int { // The first valid value is 1.
47 kAbsoluteSendTimeExtensionId = 1,
48 kAudioLevelExtensionId,
Elad Alonccb9b752019-02-19 13:01:31 +010049 kGenericDescriptorId00,
50 kGenericDescriptorId01,
Elad Alond8d32482019-02-18 23:45:57 +010051 kMidExtensionId,
52 kRepairedRidExtensionId,
53 kRidExtensionId,
54 kTransmissionTimeOffsetExtensionId,
55 kTransportSequenceNumberExtensionId,
56 kVideoRotationExtensionId,
57 kVideoTimingExtensionId,
58};
59
andrew@webrtc.org8a442592011-12-16 21:24:30 +000060const int kPayload = 100;
Shao Changbine62202f2015-04-21 20:24:50 +080061const int kRtxPayload = 98;
andrew@webrtc.org8a442592011-12-16 21:24:30 +000062const uint32_t kTimestamp = 10;
63const uint16_t kSeqNum = 33;
brandtr9dfff292016-11-14 05:14:50 -080064const uint32_t kSsrc = 725242;
Erik Språng9c771c22019-06-17 16:31:53 +020065const uint32_t kRtxSsrc = 12345;
66const uint32_t kFlexFecSsrc = 45678;
Erik Språng1fbfecd2019-08-26 19:00:05 +020067const uint16_t kTransportSequenceNumber = 1;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +000068const uint64_t kStartTime = 123456789;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +000069const size_t kMaxPaddingSize = 224u;
Stefan Holmera246cfb2016-08-23 17:51:42 +020070const uint8_t kPayloadData[] = {47, 11, 32, 93, 89};
spranga8ae6f22017-09-04 07:23:56 -070071const int64_t kDefaultExpectedRetransmissionTimeMs = 125;
Amit Hilbuch77938e62018-12-21 09:23:38 -080072const char kNoRid[] = "";
73const char kNoMid[] = "";
andrew@webrtc.org8a442592011-12-16 21:24:30 +000074
Danil Chapovalov5e57b172016-09-02 19:15:59 +020075using ::testing::_;
Erik Språng30a276b2019-04-23 12:00:11 +020076using ::testing::AllOf;
Erik Språng214f5432019-06-20 15:09:58 +020077using ::testing::AtLeast;
78using ::testing::DoAll;
philipelb3e42a42018-09-13 10:57:14 +020079using ::testing::ElementsAre;
Danil Chapovalov5e57b172016-09-02 19:15:59 +020080using ::testing::ElementsAreArray;
Erik Språng30a276b2019-04-23 12:00:11 +020081using ::testing::Field;
Erik Språng478cb462019-06-26 15:49:27 +020082using ::testing::Gt;
sprang168794c2017-07-06 04:38:06 -070083using ::testing::Invoke;
Erik Språng9c771c22019-06-17 16:31:53 +020084using ::testing::NiceMock;
Erik Språng478cb462019-06-26 15:49:27 +020085using ::testing::Pointee;
86using ::testing::Property;
Erik Språng214f5432019-06-20 15:09:58 +020087using ::testing::Return;
88using ::testing::SaveArg;
Danil Chapovalov84ffb352018-09-25 18:59:09 +020089using ::testing::SizeIs;
Erik Språng9c771c22019-06-17 16:31:53 +020090using ::testing::StrictMock;
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +000091
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +000092uint64_t ConvertMsToAbsSendTime(int64_t time_ms) {
Stefan Holmer0a87ffc2015-10-21 13:41:48 +020093 return (((time_ms << 18) + 500) / 1000) & 0x00ffffff;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +000094}
95
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +000096class LoopbackTransportTest : public webrtc::Transport {
97 public:
Petter Strandmark26bc6692018-05-29 08:43:35 +020098 LoopbackTransportTest() : total_bytes_sent_(0) {
danilchap12ba1862016-10-26 02:41:55 -070099 receivers_extensions_.Register(kRtpExtensionTransmissionTimeOffset,
100 kTransmissionTimeOffsetExtensionId);
101 receivers_extensions_.Register(kRtpExtensionAbsoluteSendTime,
102 kAbsoluteSendTimeExtensionId);
103 receivers_extensions_.Register(kRtpExtensionTransportSequenceNumber,
104 kTransportSequenceNumberExtensionId);
105 receivers_extensions_.Register(kRtpExtensionVideoRotation,
106 kVideoRotationExtensionId);
107 receivers_extensions_.Register(kRtpExtensionAudioLevel,
108 kAudioLevelExtensionId);
ilnik04f4d122017-06-19 07:18:55 -0700109 receivers_extensions_.Register(kRtpExtensionVideoTiming,
110 kVideoTimingExtensionId);
Steve Anton296a0ce2018-03-22 15:17:27 -0700111 receivers_extensions_.Register(kRtpExtensionMid, kMidExtensionId);
Elad Alonccb9b752019-02-19 13:01:31 +0100112 receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor00,
113 kGenericDescriptorId00);
114 receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor01,
115 kGenericDescriptorId01);
Amit Hilbuch77938e62018-12-21 09:23:38 -0800116 receivers_extensions_.Register(kRtpExtensionRtpStreamId, kRidExtensionId);
117 receivers_extensions_.Register(kRtpExtensionRepairedRtpStreamId,
118 kRepairedRidExtensionId);
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000119 }
danilchap12ba1862016-10-26 02:41:55 -0700120
stefan1d8a5062015-10-02 03:39:33 -0700121 bool SendRtp(const uint8_t* data,
122 size_t len,
123 const PacketOptions& options) override {
Petter Strandmark26bc6692018-05-29 08:43:35 +0200124 last_options_ = options;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000125 total_bytes_sent_ += len;
danilchap12ba1862016-10-26 02:41:55 -0700126 sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
127 EXPECT_TRUE(sent_packets_.back().Parse(data, len));
pbos2d566682015-09-28 09:59:31 -0700128 return true;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000129 }
danilchap162abd32015-12-10 02:39:40 -0800130 bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
danilchap12ba1862016-10-26 02:41:55 -0700131 const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
132 int packets_sent() { return sent_packets_.size(); }
133
pbos@webrtc.org72491b92014-07-10 16:24:54 +0000134 size_t total_bytes_sent_;
Petter Strandmark26bc6692018-05-29 08:43:35 +0200135 PacketOptions last_options_;
danilchap12ba1862016-10-26 02:41:55 -0700136 std::vector<RtpPacketReceived> sent_packets_;
137
138 private:
139 RtpHeaderExtensionMap receivers_extensions_;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000140};
141
Elad Alon4a87e1c2017-10-03 16:11:34 +0200142MATCHER_P(SameRtcEventTypeAs, value, "") {
143 return value == arg->GetType();
144}
145
Erik Språngf6468d22019-07-05 16:53:43 +0200146struct TestConfig {
Erik Språngf5815fa2019-08-21 14:27:31 +0200147 explicit TestConfig(bool with_overhead) : with_overhead(with_overhead) {}
Erik Språngf6468d22019-07-05 16:53:43 +0200148 bool with_overhead = false;
Erik Språngf6468d22019-07-05 16:53:43 +0200149};
150
151std::string ToFieldTrialString(TestConfig config) {
152 std::string field_trials;
153 if (config.with_overhead) {
154 field_trials += "WebRTC-SendSideBwe-WithOverhead/Enabled/";
155 }
Erik Språngf6468d22019-07-05 16:53:43 +0200156 return field_trials;
157}
158
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000159} // namespace
160
Erik Språngaa59eca2019-07-24 14:52:55 +0200161class MockRtpPacketPacer : public RtpPacketSender {
sprangebbf8a82015-09-21 15:11:14 -0700162 public:
Erik Språng59b86542019-06-23 18:24:46 +0200163 MockRtpPacketPacer() {}
164 virtual ~MockRtpPacketPacer() {}
165
166 MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend>));
sprangebbf8a82015-09-21 15:11:14 -0700167
Erik Språngaa59eca2019-07-24 14:52:55 +0200168 MOCK_METHOD2(CreateProbeCluster, void(int bitrate_bps, int cluster_id));
169
170 MOCK_METHOD0(Pause, void());
171 MOCK_METHOD0(Resume, void());
172 MOCK_METHOD1(SetCongestionWindow,
173 void(absl::optional<int64_t> congestion_window_bytes));
174 MOCK_METHOD1(UpdateOutstandingData, void(int64_t outstanding_bytes));
175 MOCK_METHOD1(SetAccountForAudioPackets, void(bool account_for_audio));
sprangebbf8a82015-09-21 15:11:14 -0700176};
177
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200178class MockSendSideDelayObserver : public SendSideDelayObserver {
179 public:
Henrik Boström9fe18342019-05-16 18:38:20 +0200180 MOCK_METHOD4(SendSideDelayUpdated, void(int, int, uint64_t, uint32_t));
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200181};
182
asapersson35151f32016-05-02 23:44:01 -0700183class MockSendPacketObserver : public SendPacketObserver {
184 public:
185 MOCK_METHOD3(OnSendPacket, void(uint16_t, int64_t, uint32_t));
186};
187
Stefan Holmera246cfb2016-08-23 17:51:42 +0200188class MockTransportFeedbackObserver : public TransportFeedbackObserver {
189 public:
Erik Språng30a276b2019-04-23 12:00:11 +0200190 MOCK_METHOD1(OnAddPacket, void(const RtpPacketSendInfo&));
Stefan Holmera246cfb2016-08-23 17:51:42 +0200191 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -0800192 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
Stefan Holmera246cfb2016-08-23 17:51:42 +0200193};
194
minyue3a407ee2017-04-03 01:10:33 -0700195class MockOverheadObserver : public OverheadObserver {
196 public:
197 MOCK_METHOD1(OnOverheadChanged, void(size_t overhead_bytes_per_packet));
198};
199
Erik Språngf6468d22019-07-05 16:53:43 +0200200class RtpSenderTest : public ::testing::TestWithParam<TestConfig> {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000201 protected:
202 RtpSenderTest()
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000203 : fake_clock_(kStartTime),
terelius429c3452016-01-21 05:42:04 -0800204 mock_rtc_event_log_(),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000205 mock_paced_sender_(),
sprangcd349d92016-07-13 09:11:28 -0700206 retransmission_rate_limiter_(&fake_clock_, 1000),
Erik Språng4580ca22019-07-04 10:38:43 +0200207 flexfec_sender_(0,
208 kFlexFecSsrc,
209 kSsrc,
210 "",
211 std::vector<RtpExtension>(),
212 std::vector<RtpExtensionSize>(),
213 nullptr,
214 &fake_clock_),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000215 rtp_sender_(),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000216 transport_(),
minyue3a407ee2017-04-03 01:10:33 -0700217 kMarkerBit(true),
Erik Språngf6468d22019-07-05 16:53:43 +0200218 field_trials_(ToFieldTrialString(GetParam())) {}
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +0000219
Erik Språng7b52f102018-02-07 14:37:37 +0100220 void SetUp() override { SetUpRtpSender(true, false); }
Peter Boströme23e7372015-10-08 11:44:14 +0200221
Erik Språng7b52f102018-02-07 14:37:37 +0100222 void SetUpRtpSender(bool pacer, bool populate_network2) {
Erik Språng4580ca22019-07-04 10:38:43 +0200223 RtpRtcp::Configuration config;
224 config.clock = &fake_clock_;
225 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200226 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200227 config.rtx_send_ssrc = kRtxSsrc;
228 config.flexfec_sender = &flexfec_sender_;
Erik Språng4580ca22019-07-04 10:38:43 +0200229 config.event_log = &mock_rtc_event_log_;
230 config.send_packet_observer = &send_packet_observer_;
231 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
232 config.paced_sender = pacer ? &mock_paced_sender_ : nullptr;
233 config.populate_network2_timestamp = populate_network2;
234 rtp_sender_.reset(new RTPSender(config));
brandtr9dfff292016-11-14 05:14:50 -0800235 rtp_sender_->SetSequenceNumber(kSeqNum);
danilchap71fead22016-08-18 02:01:49 -0700236 rtp_sender_->SetTimestampOffset(0);
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +0000237 }
238
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000239 SimulatedClock fake_clock_;
Erik Språng9c771c22019-06-17 16:31:53 +0200240 NiceMock<MockRtcEventLog> mock_rtc_event_log_;
Erik Språng59b86542019-06-23 18:24:46 +0200241 MockRtpPacketPacer mock_paced_sender_;
Erik Språng9c771c22019-06-17 16:31:53 +0200242 StrictMock<MockSendPacketObserver> send_packet_observer_;
243 StrictMock<MockTransportFeedbackObserver> feedback_observer_;
sprangcd349d92016-07-13 09:11:28 -0700244 RateLimiter retransmission_rate_limiter_;
Erik Språng4580ca22019-07-04 10:38:43 +0200245 FlexfecSender flexfec_sender_;
kwiberg84be5112016-04-27 01:19:58 -0700246 std::unique_ptr<RTPSender> rtp_sender_;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000247 LoopbackTransportTest transport_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000248 const bool kMarkerBit;
minyue3a407ee2017-04-03 01:10:33 -0700249 test::ScopedFieldTrials field_trials_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000250
danilchapb6f1fb52016-10-19 06:11:39 -0700251 std::unique_ptr<RtpPacketToSend> BuildRtpPacket(int payload_type,
252 bool marker_bit,
253 uint32_t timestamp,
254 int64_t capture_time_ms) {
255 auto packet = rtp_sender_->AllocatePacket();
256 packet->SetPayloadType(payload_type);
Erik Språng60ffc312019-07-30 22:03:49 +0200257 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
danilchapb6f1fb52016-10-19 06:11:39 -0700258 packet->SetMarker(marker_bit);
259 packet->SetTimestamp(timestamp);
260 packet->set_capture_time_ms(capture_time_ms);
261 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
262 return packet;
263 }
264
Erik Språngf6468d22019-07-05 16:53:43 +0200265 std::unique_ptr<RtpPacketToSend> SendPacket(int64_t capture_time_ms,
266 int payload_length) {
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000267 uint32_t timestamp = capture_time_ms * 90;
danilchapb6f1fb52016-10-19 06:11:39 -0700268 auto packet =
269 BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
270 packet->AllocatePayload(payload_length);
Erik Språng70768f42019-08-27 18:16:26 +0200271 packet->set_allow_retransmission(true);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000272
273 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +0200274 EXPECT_TRUE(rtp_sender_->SendToNetwork(
Erik Språng70768f42019-08-27 18:16:26 +0200275 absl::make_unique<RtpPacketToSend>(*packet)));
Erik Språngf6468d22019-07-05 16:53:43 +0200276 return packet;
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000277 }
asapersson35151f32016-05-02 23:44:01 -0700278
Erik Språngf6468d22019-07-05 16:53:43 +0200279 std::unique_ptr<RtpPacketToSend> SendGenericPacket() {
asapersson35151f32016-05-02 23:44:01 -0700280 const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
Erik Språngf6468d22019-07-05 16:53:43 +0200281 return SendPacket(kCaptureTimeMs, sizeof(kPayloadData));
asapersson35151f32016-05-02 23:44:01 -0700282 }
Steve Anton2bac7da2019-07-21 15:04:21 -0400283
Erik Språng4208a132019-08-26 08:58:45 +0200284 size_t GenerateAndSendPadding(size_t target_size_bytes) {
285 size_t generated_bytes = 0;
286 for (auto& packet : rtp_sender_->GeneratePadding(target_size_bytes)) {
287 generated_bytes += packet->payload_size() + packet->padding_size();
288 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
289 }
290 return generated_bytes;
291 }
292
Steve Anton2bac7da2019-07-21 15:04:21 -0400293 // The following are helpers for configuring the RTPSender. They must be
294 // called before sending any packets.
295
296 // Enable the retransmission stream with sizable packet storage.
297 void EnableRtx() {
298 // RTX needs to be able to read the source packets from the packet store.
299 // Pick a number of packets to store big enough for any unit test.
300 constexpr uint16_t kNumberOfPacketsToStore = 100;
301 rtp_sender_->SetStorePacketsStatus(true, kNumberOfPacketsToStore);
302 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
303 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
304 }
305
306 // Enable sending of the MID header extension for both the primary SSRC and
307 // the RTX SSRC.
308 void EnableMidSending(const std::string& mid) {
309 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionMid, kMidExtensionId);
310 rtp_sender_->SetMid(mid);
311 }
312
313 // Enable sending of the RSID header extension for the primary SSRC and the
314 // RRSID header extension for the RTX SSRC.
315 void EnableRidSending(const std::string& rid) {
316 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
317 kRidExtensionId);
318 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRepairedRtpStreamId,
319 kRepairedRidExtensionId);
320 rtp_sender_->SetRid(rid);
321 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000322};
323
Peter Boströme23e7372015-10-08 11:44:14 +0200324// TODO(pbos): Move tests over from WithoutPacer to RtpSenderTest as this is our
325// default code path.
326class RtpSenderTestWithoutPacer : public RtpSenderTest {
327 public:
Erik Språng7b52f102018-02-07 14:37:37 +0100328 void SetUp() override { SetUpRtpSender(false, false); }
Peter Boströme23e7372015-10-08 11:44:14 +0200329};
330
minyue3a407ee2017-04-03 01:10:33 -0700331TEST_P(RtpSenderTestWithoutPacer, AllocatePacketSetCsrc) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200332 // Configure rtp_sender with csrc.
333 std::vector<uint32_t> csrcs;
334 csrcs.push_back(0x23456789);
335 rtp_sender_->SetCsrcs(csrcs);
336
337 auto packet = rtp_sender_->AllocatePacket();
338
339 ASSERT_TRUE(packet);
340 EXPECT_EQ(rtp_sender_->SSRC(), packet->Ssrc());
341 EXPECT_EQ(csrcs, packet->Csrcs());
342}
343
minyue3a407ee2017-04-03 01:10:33 -0700344TEST_P(RtpSenderTestWithoutPacer, AllocatePacketReserveExtensions) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200345 // Configure rtp_sender with extensions.
346 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
347 kRtpExtensionTransmissionTimeOffset,
348 kTransmissionTimeOffsetExtensionId));
349 ASSERT_EQ(
350 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
351 kAbsoluteSendTimeExtensionId));
352 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
353 kAudioLevelExtensionId));
354 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
355 kRtpExtensionTransportSequenceNumber,
356 kTransportSequenceNumberExtensionId));
357 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
358 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
359
360 auto packet = rtp_sender_->AllocatePacket();
361
362 ASSERT_TRUE(packet);
363 // Preallocate BWE extensions RtpSender set itself.
364 EXPECT_TRUE(packet->HasExtension<TransmissionOffset>());
365 EXPECT_TRUE(packet->HasExtension<AbsoluteSendTime>());
366 EXPECT_TRUE(packet->HasExtension<TransportSequenceNumber>());
367 // Do not allocate media specific extensions.
368 EXPECT_FALSE(packet->HasExtension<AudioLevel>());
369 EXPECT_FALSE(packet->HasExtension<VideoOrientation>());
370}
371
minyue3a407ee2017-04-03 01:10:33 -0700372TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberAdvanceSequenceNumber) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200373 auto packet = rtp_sender_->AllocatePacket();
374 ASSERT_TRUE(packet);
375 const uint16_t sequence_number = rtp_sender_->SequenceNumber();
376
377 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
378
379 EXPECT_EQ(sequence_number, packet->SequenceNumber());
380 EXPECT_EQ(sequence_number + 1, rtp_sender_->SequenceNumber());
381}
382
minyue3a407ee2017-04-03 01:10:33 -0700383TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberFailsOnNotSending) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200384 auto packet = rtp_sender_->AllocatePacket();
385 ASSERT_TRUE(packet);
386
387 rtp_sender_->SetSendingMediaStatus(false);
388 EXPECT_FALSE(rtp_sender_->AssignSequenceNumber(packet.get()));
389}
390
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100391TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberMayAllowPaddingOnVideo) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200392 constexpr size_t kPaddingSize = 100;
393 auto packet = rtp_sender_->AllocatePacket();
394 ASSERT_TRUE(packet);
395
Erik Språng4208a132019-08-26 08:58:45 +0200396 ASSERT_TRUE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200397 packet->SetMarker(false);
398 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100399 // Packet without marker bit doesn't allow padding on video stream.
Erik Språng4208a132019-08-26 08:58:45 +0200400 ASSERT_TRUE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200401
402 packet->SetMarker(true);
403 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
404 // Packet with marker bit allows send padding.
Erik Språng4208a132019-08-26 08:58:45 +0200405 ASSERT_FALSE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200406}
407
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100408TEST_P(RtpSenderTest, AssignSequenceNumberAllowsPaddingOnAudio) {
409 MockTransport transport;
Erik Språng4580ca22019-07-04 10:38:43 +0200410 RtpRtcp::Configuration config;
411 config.audio = true;
412 config.clock = &fake_clock_;
413 config.outgoing_transport = &transport;
414 config.paced_sender = &mock_paced_sender_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200415 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200416 config.event_log = &mock_rtc_event_log_;
417 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
418 rtp_sender_ = absl::make_unique<RTPSender>(config);
419
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100420 rtp_sender_->SetTimestampOffset(0);
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100421
422 std::unique_ptr<RtpPacketToSend> audio_packet = rtp_sender_->AllocatePacket();
423 // Padding on audio stream allowed regardless of marker in the last packet.
424 audio_packet->SetMarker(false);
425 audio_packet->SetPayloadType(kPayload);
426 rtp_sender_->AssignSequenceNumber(audio_packet.get());
427
428 const size_t kPaddingSize = 59;
429 EXPECT_CALL(transport, SendRtp(_, kPaddingSize + kRtpHeaderSize, _))
Erik Språng214f5432019-06-20 15:09:58 +0200430 .WillOnce(Return(true));
Erik Språng4208a132019-08-26 08:58:45 +0200431 EXPECT_EQ(kPaddingSize, GenerateAndSendPadding(kPaddingSize));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100432
433 // Requested padding size is too small, will send a larger one.
434 const size_t kMinPaddingSize = 50;
435 EXPECT_CALL(transport, SendRtp(_, kMinPaddingSize + kRtpHeaderSize, _))
Erik Språng214f5432019-06-20 15:09:58 +0200436 .WillOnce(Return(true));
Erik Språng4208a132019-08-26 08:58:45 +0200437 EXPECT_EQ(kMinPaddingSize, GenerateAndSendPadding(kMinPaddingSize - 5));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100438}
439
minyue3a407ee2017-04-03 01:10:33 -0700440TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberSetPaddingTimestamps) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200441 constexpr size_t kPaddingSize = 100;
442 auto packet = rtp_sender_->AllocatePacket();
443 ASSERT_TRUE(packet);
444 packet->SetMarker(true);
445 packet->SetTimestamp(kTimestamp);
446
447 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
Erik Språng4208a132019-08-26 08:58:45 +0200448 auto padding_packets = rtp_sender_->GeneratePadding(kPaddingSize);
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200449
Erik Språng4208a132019-08-26 08:58:45 +0200450 ASSERT_EQ(1u, padding_packets.size());
danilchap12ba1862016-10-26 02:41:55 -0700451 // Verify padding packet timestamp.
Erik Språng4208a132019-08-26 08:58:45 +0200452 EXPECT_EQ(kTimestamp, padding_packets[0]->Timestamp());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200453}
454
minyue3a407ee2017-04-03 01:10:33 -0700455TEST_P(RtpSenderTestWithoutPacer,
456 TransportFeedbackObserverGetsCorrectByteCount) {
457 constexpr int kRtpOverheadBytesPerPacket = 12 + 8;
Erik Språng9c771c22019-06-17 16:31:53 +0200458 NiceMock<MockOverheadObserver> mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +0200459
460 RtpRtcp::Configuration config;
461 config.clock = &fake_clock_;
462 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200463 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200464 config.transport_feedback_callback = &feedback_observer_;
465 config.event_log = &mock_rtc_event_log_;
466 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
467 config.overhead_observer = &mock_overhead_observer;
468 rtp_sender_ = absl::make_unique<RTPSender>(config);
469
minyue3a407ee2017-04-03 01:10:33 -0700470 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
471 kRtpExtensionTransportSequenceNumber,
472 kTransportSequenceNumberExtensionId));
minyue3a407ee2017-04-03 01:10:33 -0700473
474 const size_t expected_bytes =
Erik Språngf6468d22019-07-05 16:53:43 +0200475 GetParam().with_overhead
476 ? sizeof(kPayloadData) + kRtpOverheadBytesPerPacket
477 : sizeof(kPayloadData);
minyue3a407ee2017-04-03 01:10:33 -0700478
479 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200480 OnAddPacket(AllOf(
481 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
482 Field(&RtpPacketSendInfo::transport_sequence_number,
483 kTransportSequenceNumber),
484 Field(&RtpPacketSendInfo::rtp_sequence_number,
485 rtp_sender_->SequenceNumber()),
486 Field(&RtpPacketSendInfo::length, expected_bytes),
487 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
minyue3a407ee2017-04-03 01:10:33 -0700488 .Times(1);
489 EXPECT_CALL(mock_overhead_observer,
490 OnOverheadChanged(kRtpOverheadBytesPerPacket))
491 .Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100492 SendGenericPacket();
minyue3a407ee2017-04-03 01:10:33 -0700493}
494
495TEST_P(RtpSenderTestWithoutPacer, SendsPacketsWithTransportSequenceNumber) {
Erik Språng4580ca22019-07-04 10:38:43 +0200496 RtpRtcp::Configuration config;
497 config.clock = &fake_clock_;
498 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200499 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200500 config.transport_feedback_callback = &feedback_observer_;
501 config.event_log = &mock_rtc_event_log_;
502 config.send_packet_observer = &send_packet_observer_;
503 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
504 rtp_sender_ = absl::make_unique<RTPSender>(config);
505
Stefan Holmerf5dca482016-01-27 12:58:51 +0100506 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
507 kRtpExtensionTransportSequenceNumber,
508 kTransportSequenceNumberExtensionId));
509
asapersson35151f32016-05-02 23:44:01 -0700510 EXPECT_CALL(send_packet_observer_,
511 OnSendPacket(kTransportSequenceNumber, _, _))
512 .Times(1);
minyue3a407ee2017-04-03 01:10:33 -0700513
514 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200515 OnAddPacket(AllOf(
516 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
517 Field(&RtpPacketSendInfo::transport_sequence_number,
518 kTransportSequenceNumber),
519 Field(&RtpPacketSendInfo::rtp_sequence_number,
520 rtp_sender_->SequenceNumber()),
521 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
Stefan Holmera246cfb2016-08-23 17:51:42 +0200522 .Times(1);
asapersson35151f32016-05-02 23:44:01 -0700523
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100524 SendGenericPacket();
Stefan Holmerf5dca482016-01-27 12:58:51 +0100525
danilchap12ba1862016-10-26 02:41:55 -0700526 const auto& packet = transport_.last_sent_packet();
527 uint16_t transport_seq_no;
528 ASSERT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
529 EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200530 EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200531 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200532}
533
534TEST_P(RtpSenderTestWithoutPacer, PacketOptionsNoRetransmission) {
Erik Språng4580ca22019-07-04 10:38:43 +0200535 RtpRtcp::Configuration config;
536 config.clock = &fake_clock_;
537 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200538 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200539 config.transport_feedback_callback = &feedback_observer_;
540 config.event_log = &mock_rtc_event_log_;
541 config.send_packet_observer = &send_packet_observer_;
542 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
543 rtp_sender_ = absl::make_unique<RTPSender>(config);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200544
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100545 SendGenericPacket();
Petter Strandmark26bc6692018-05-29 08:43:35 +0200546
547 EXPECT_FALSE(transport_.last_options_.is_retransmit);
Stefan Holmerf5dca482016-01-27 12:58:51 +0100548}
549
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200550TEST_P(RtpSenderTestWithoutPacer,
551 SetsIncludedInFeedbackWhenTransportSequenceNumberExtensionIsRegistered) {
552 SetUpRtpSender(false, false);
553 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
554 kTransportSequenceNumberExtensionId);
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200555 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100556 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200557 EXPECT_TRUE(transport_.last_options_.included_in_feedback);
558}
559
560TEST_P(
561 RtpSenderTestWithoutPacer,
562 SetsIncludedInAllocationWhenTransportSequenceNumberExtensionIsRegistered) {
563 SetUpRtpSender(false, false);
564 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
565 kTransportSequenceNumberExtensionId);
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200566 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100567 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200568 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
569}
570
571TEST_P(RtpSenderTestWithoutPacer,
572 SetsIncludedInAllocationWhenForcedAsPartOfAllocation) {
573 SetUpRtpSender(false, false);
574 rtp_sender_->SetAsPartOfAllocation(true);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100575 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200576 EXPECT_FALSE(transport_.last_options_.included_in_feedback);
577 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
578}
579
580TEST_P(RtpSenderTestWithoutPacer, DoesnSetIncludedInAllocationByDefault) {
581 SetUpRtpSender(false, false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100582 SendGenericPacket();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200583 EXPECT_FALSE(transport_.last_options_.included_in_feedback);
584 EXPECT_FALSE(transport_.last_options_.included_in_allocation);
stefana23fc622016-07-28 07:56:38 -0700585}
asapersson35151f32016-05-02 23:44:01 -0700586
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200587TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
Erik Språng9c771c22019-06-17 16:31:53 +0200588 StrictMock<MockSendSideDelayObserver> send_side_delay_observer_;
Erik Språng4580ca22019-07-04 10:38:43 +0200589
590 RtpRtcp::Configuration config;
591 config.clock = &fake_clock_;
592 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200593 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200594 config.send_side_delay_observer = &send_side_delay_observer_;
595 config.event_log = &mock_rtc_event_log_;
596 rtp_sender_ = absl::make_unique<RTPSender>(config);
597
Niels Möller5fe95102019-03-04 16:49:25 +0100598 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +0100599 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +0200600 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +0100601 FieldTrialBasedConfig());
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200602
603 const uint8_t kPayloadType = 127;
Niels Möller8a40edd2019-01-24 18:04:44 +0100604 const char payload_name[] = "GENERIC";
Niels Möller59ab1cf2019-02-06 22:48:11 +0100605
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +0200606 rtp_sender_video.RegisterPayloadType(kPayloadType, payload_name,
607 /*raw_payload=*/false);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100608
609 const uint32_t kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200610 RTPVideoHeader video_header;
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200611
Henrik Boström9fe18342019-05-16 18:38:20 +0200612 // Send packet with 10 ms send-side delay. The average, max and total should
613 // be 10 ms.
614 EXPECT_CALL(send_side_delay_observer_,
615 SendSideDelayUpdated(10, 10, 10, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200616 .Times(1);
617 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
618 fake_clock_.AdvanceTimeMilliseconds(10);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100619 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100620 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200621 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100622 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200623 kDefaultExpectedRetransmissionTimeMs));
624
Henrik Boström9fe18342019-05-16 18:38:20 +0200625 // Send another packet with 20 ms delay. The average, max and total should be
626 // 15, 20 and 30 ms respectively.
627 EXPECT_CALL(send_side_delay_observer_,
628 SendSideDelayUpdated(15, 20, 30, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200629 .Times(1);
630 fake_clock_.AdvanceTimeMilliseconds(10);
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 another packet at the same time, which replaces the last packet.
638 // 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 +0200639 // The total counter stays the same though.
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200640 // TODO(terelius): Is is not clear that this is the right behavior.
Henrik Boström9fe18342019-05-16 18:38:20 +0200641 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(5, 10, 30, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200642 .Times(1);
643 capture_time_ms = fake_clock_.TimeInMilliseconds();
Niels Möller59ab1cf2019-02-06 22:48:11 +0100644 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100645 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200646 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100647 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200648 kDefaultExpectedRetransmissionTimeMs));
649
650 // Send a packet 1 second later. The earlier packets should have timed
Henrik Boström9fe18342019-05-16 18:38:20 +0200651 // out, so both max and average should be the delay of this packet. The total
652 // keeps increasing.
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200653 fake_clock_.AdvanceTimeMilliseconds(1000);
654 capture_time_ms = fake_clock_.TimeInMilliseconds();
655 fake_clock_.AdvanceTimeMilliseconds(1);
Henrik Boström9fe18342019-05-16 18:38:20 +0200656 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(1, 1, 31, kSsrc))
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200657 .Times(1);
Niels Möller59ab1cf2019-02-06 22:48:11 +0100658 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +0100659 VideoFrameType::kVideoFrameKey, kPayloadType,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200660 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
Niels Möller59ab1cf2019-02-06 22:48:11 +0100661 kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200662 kDefaultExpectedRetransmissionTimeMs));
663}
664
minyue3a407ee2017-04-03 01:10:33 -0700665TEST_P(RtpSenderTestWithoutPacer, OnSendPacketUpdated) {
stefana23fc622016-07-28 07:56:38 -0700666 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
667 kRtpExtensionTransportSequenceNumber,
668 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -0700669 EXPECT_CALL(send_packet_observer_,
670 OnSendPacket(kTransportSequenceNumber, _, _))
671 .Times(1);
672
Niels Möllere7b9e6b2019-02-06 18:23:44 +0100673 SendGenericPacket();
asapersson35151f32016-05-02 23:44:01 -0700674}
675
minyue3a407ee2017-04-03 01:10:33 -0700676TEST_P(RtpSenderTest, SendsPacketsWithTransportSequenceNumber) {
Erik Språng4580ca22019-07-04 10:38:43 +0200677 RtpRtcp::Configuration config;
678 config.clock = &fake_clock_;
679 config.outgoing_transport = &transport_;
680 config.paced_sender = &mock_paced_sender_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200681 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +0200682 config.transport_feedback_callback = &feedback_observer_;
683 config.event_log = &mock_rtc_event_log_;
684 config.send_packet_observer = &send_packet_observer_;
685 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
686 rtp_sender_ = absl::make_unique<RTPSender>(config);
687
brandtr9dfff292016-11-14 05:14:50 -0800688 rtp_sender_->SetSequenceNumber(kSeqNum);
Stefan Holmera246cfb2016-08-23 17:51:42 +0200689 rtp_sender_->SetStorePacketsStatus(true, 10);
690 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
691 kRtpExtensionTransportSequenceNumber,
692 kTransportSequenceNumberExtensionId));
693
Stefan Holmera246cfb2016-08-23 17:51:42 +0200694 EXPECT_CALL(send_packet_observer_,
695 OnSendPacket(kTransportSequenceNumber, _, _))
696 .Times(1);
minyue3a407ee2017-04-03 01:10:33 -0700697 EXPECT_CALL(feedback_observer_,
Erik Språng30a276b2019-04-23 12:00:11 +0200698 OnAddPacket(AllOf(
699 Field(&RtpPacketSendInfo::ssrc, rtp_sender_->SSRC()),
700 Field(&RtpPacketSendInfo::transport_sequence_number,
701 kTransportSequenceNumber),
702 Field(&RtpPacketSendInfo::rtp_sequence_number,
703 rtp_sender_->SequenceNumber()),
704 Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
Stefan Holmera246cfb2016-08-23 17:51:42 +0200705 .Times(1);
706
Erik Språngf5815fa2019-08-21 14:27:31 +0200707 EXPECT_CALL(
708 mock_paced_sender_,
709 EnqueuePacket(
710 AllOf(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
711 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
712 auto packet = SendGenericPacket();
713 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
714 // Transport sequence number is set by PacketRouter, before TrySendPacket().
715 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
716 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Stefan Holmera246cfb2016-08-23 17:51:42 +0200717
danilchap12ba1862016-10-26 02:41:55 -0700718 uint16_t transport_seq_no;
Erik Språngf5815fa2019-08-21 14:27:31 +0200719 EXPECT_TRUE(
720 transport_.last_sent_packet().GetExtension<TransportSequenceNumber>(
721 &transport_seq_no));
danilchap12ba1862016-10-26 02:41:55 -0700722 EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200723 EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
Stefan Holmera246cfb2016-08-23 17:51:42 +0200724}
725
Erik Språng7b52f102018-02-07 14:37:37 +0100726TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) {
ilnik04f4d122017-06-19 07:18:55 -0700727 rtp_sender_->SetStorePacketsStatus(true, 10);
728 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
729 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
730 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
731 auto packet = rtp_sender_->AllocatePacket();
732 packet->SetPayloadType(kPayload);
733 packet->SetMarker(true);
734 packet->SetTimestamp(kTimestamp);
735 packet->set_capture_time_ms(capture_time_ms);
ilnik2edc6842017-07-06 03:06:50 -0700736 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
ilnik04f4d122017-06-19 07:18:55 -0700737 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
738 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
739 size_t packet_size = packet->size();
ilnik04f4d122017-06-19 07:18:55 -0700740
741 const int kStoredTimeInMs = 100;
Erik Språngf5815fa2019-08-21 14:27:31 +0200742 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
Erik Språng70768f42019-08-27 18:16:26 +0200743 packet->set_allow_retransmission(true);
Erik Språngf5815fa2019-08-21 14:27:31 +0200744 EXPECT_CALL(mock_paced_sender_,
745 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
Erik Språng70768f42019-08-27 18:16:26 +0200746 EXPECT_TRUE(
747 rtp_sender_->SendToNetwork(absl::make_unique<RtpPacketToSend>(*packet)));
Erik Språngf5815fa2019-08-21 14:27:31 +0200748 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
749 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
ilnik04f4d122017-06-19 07:18:55 -0700750 EXPECT_EQ(1, transport_.packets_sent());
751 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
752
danilchapce251812017-09-11 12:24:41 -0700753 VideoSendTiming video_timing;
754 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
755 &video_timing));
756 EXPECT_EQ(kStoredTimeInMs, video_timing.pacer_exit_delta_ms);
Erik Språng7b52f102018-02-07 14:37:37 +0100757}
ilnik04f4d122017-06-19 07:18:55 -0700758
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100759TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithPacer) {
760 SetUpRtpSender(/*pacer=*/true, /*populate_network2=*/true);
Erik Språng7b52f102018-02-07 14:37:37 +0100761 rtp_sender_->SetStorePacketsStatus(true, 10);
762 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
763 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
764 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
765 auto packet = rtp_sender_->AllocatePacket();
766 packet->SetPayloadType(kPayload);
767 packet->SetMarker(true);
768 packet->SetTimestamp(kTimestamp);
769 packet->set_capture_time_ms(capture_time_ms);
770 const uint16_t kPacerExitMs = 1234u;
771 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, kPacerExitMs, 0u, 0u, true};
772 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
773 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
774 size_t packet_size = packet->size();
775
776 const int kStoredTimeInMs = 100;
Erik Språngf6468d22019-07-05 16:53:43 +0200777
Erik Språngf6468d22019-07-05 16:53:43 +0200778 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
Erik Språng70768f42019-08-27 18:16:26 +0200779 packet->set_allow_retransmission(true);
Erik Språngf6468d22019-07-05 16:53:43 +0200780 EXPECT_CALL(
781 mock_paced_sender_,
782 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
783 EXPECT_TRUE(rtp_sender_->SendToNetwork(
Erik Språng70768f42019-08-27 18:16:26 +0200784 absl::make_unique<RtpPacketToSend>(*packet)));
Erik Språngf6468d22019-07-05 16:53:43 +0200785 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
786 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +0200787
Erik Språng7b52f102018-02-07 14:37:37 +0100788 EXPECT_EQ(1, transport_.packets_sent());
ilnik04f4d122017-06-19 07:18:55 -0700789 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
790
Erik Språng7b52f102018-02-07 14:37:37 +0100791 VideoSendTiming video_timing;
danilchapce251812017-09-11 12:24:41 -0700792 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
793 &video_timing));
Erik Språng7b52f102018-02-07 14:37:37 +0100794 EXPECT_EQ(kStoredTimeInMs, video_timing.network2_timestamp_delta_ms);
795 EXPECT_EQ(kPacerExitMs, video_timing.pacer_exit_delta_ms);
ilnik04f4d122017-06-19 07:18:55 -0700796}
797
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100798TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithoutPacer) {
799 SetUpRtpSender(/*pacer=*/false, /*populate_network2=*/true);
800 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
801 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
802 auto packet = rtp_sender_->AllocatePacket();
803 packet->SetMarker(true);
804 packet->set_capture_time_ms(fake_clock_.TimeInMilliseconds());
805 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
806 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
Erik Språng70768f42019-08-27 18:16:26 +0200807 packet->set_allow_retransmission(true);
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100808 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
Erik Språng1fbfecd2019-08-26 19:00:05 +0200809 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100810
811 const int kPropagateTimeMs = 10;
812 fake_clock_.AdvanceTimeMilliseconds(kPropagateTimeMs);
813
Erik Språng70768f42019-08-27 18:16:26 +0200814 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet)));
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100815
816 EXPECT_EQ(1, transport_.packets_sent());
817 absl::optional<VideoSendTiming> video_timing =
818 transport_.last_sent_packet().GetExtension<VideoTimingExtension>();
819 ASSERT_TRUE(video_timing);
820 EXPECT_EQ(kPropagateTimeMs, video_timing->network2_timestamp_delta_ms);
821}
822
minyue3a407ee2017-04-03 01:10:33 -0700823TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) {
Elad Alon4a87e1c2017-10-03 16:11:34 +0200824 EXPECT_CALL(mock_rtc_event_log_,
825 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000826
pwestin@webrtc.orgc66e8b32012-11-07 17:01:04 +0000827 rtp_sender_->SetStorePacketsStatus(true, 10);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000828 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800829 kRtpExtensionTransmissionTimeOffset,
830 kTransmissionTimeOffsetExtensionId));
831 EXPECT_EQ(
832 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
833 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000834 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700835 auto packet =
836 BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
837 size_t packet_size = packet->size();
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000838
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000839 const int kStoredTimeInMs = 100;
Erik Språngf6468d22019-07-05 16:53:43 +0200840 EXPECT_CALL(
841 mock_paced_sender_,
842 EnqueuePacket(AllOf(
843 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
844 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
845 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
Erik Språng70768f42019-08-27 18:16:26 +0200846 packet->set_allow_retransmission(true);
Erik Språngf6468d22019-07-05 16:53:43 +0200847 EXPECT_TRUE(rtp_sender_->SendToNetwork(
Erik Språng70768f42019-08-27 18:16:26 +0200848 absl::make_unique<RtpPacketToSend>(*packet)));
Erik Språngf6468d22019-07-05 16:53:43 +0200849 EXPECT_EQ(0, transport_.packets_sent());
850 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
851 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000852
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000853 // Process send bucket. Packet should now be sent.
danilchap12ba1862016-10-26 02:41:55 -0700854 EXPECT_EQ(1, transport_.packets_sent());
855 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
856
stefan@webrtc.orga5cb98c2013-05-29 12:12:51 +0000857 webrtc::RTPHeader rtp_header;
danilchap12ba1862016-10-26 02:41:55 -0700858 transport_.last_sent_packet().GetHeader(&rtp_header);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000859
860 // Verify transmission time offset.
861 EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000862 uint64_t expected_send_time =
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000863 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000864 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000865}
866
minyue3a407ee2017-04-03 01:10:33 -0700867TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) {
Elad Alon4a87e1c2017-10-03 16:11:34 +0200868 EXPECT_CALL(mock_rtc_event_log_,
869 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000870
871 rtp_sender_->SetStorePacketsStatus(true, 10);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000872 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800873 kRtpExtensionTransmissionTimeOffset,
874 kTransmissionTimeOffsetExtensionId));
875 EXPECT_EQ(
876 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
877 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000878 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700879 auto packet =
880 BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
881 size_t packet_size = packet->size();
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000882
883 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +0200884 EXPECT_CALL(
885 mock_paced_sender_,
886 EnqueuePacket(AllOf(
887 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
888 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
889 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
890 packet->set_allow_retransmission(true);
891 EXPECT_TRUE(rtp_sender_->SendToNetwork(
Erik Språng70768f42019-08-27 18:16:26 +0200892 absl::make_unique<RtpPacketToSend>(*packet)));
Erik Språngf6468d22019-07-05 16:53:43 +0200893 // Immediately process send bucket and send packet.
894 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +0200895
Erik Språng0f4f0552019-05-08 10:15:05 -0700896 EXPECT_EQ(1, transport_.packets_sent());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000897
Erik Språng0f4f0552019-05-08 10:15:05 -0700898 // Retransmit packet.
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000899 const int kStoredTimeInMs = 100;
900 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
901
Erik Språng0f4f0552019-05-08 10:15:05 -0700902 EXPECT_CALL(mock_rtc_event_log_,
903 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
Erik Språngf6468d22019-07-05 16:53:43 +0200904 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
905 packet->set_retransmitted_sequence_number(kSeqNum);
906 EXPECT_CALL(
907 mock_paced_sender_,
908 EnqueuePacket(AllOf(
909 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
910 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
911 EXPECT_EQ(static_cast<int>(packet_size),
912 rtp_sender_->ReSendPacket(kSeqNum));
913 EXPECT_EQ(1, transport_.packets_sent());
914 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000915
916 // Process send bucket. Packet should now be sent.
Erik Språng0f4f0552019-05-08 10:15:05 -0700917 EXPECT_EQ(2, transport_.packets_sent());
danilchap12ba1862016-10-26 02:41:55 -0700918 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000919
stefan@webrtc.orga5cb98c2013-05-29 12:12:51 +0000920 webrtc::RTPHeader rtp_header;
danilchap12ba1862016-10-26 02:41:55 -0700921 transport_.last_sent_packet().GetHeader(&rtp_header);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000922
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000923 // Verify transmission time offset.
924 EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000925 uint64_t expected_send_time =
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000926 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
927 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
928}
929
930// This test sends 1 regular video packet, then 4 padding packets, and then
931// 1 more regular packet.
minyue3a407ee2017-04-03 01:10:33 -0700932TEST_P(RtpSenderTest, SendPadding) {
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000933 // Make all (non-padding) packets go to send queue.
Elad Alon4a87e1c2017-10-03 16:11:34 +0200934 EXPECT_CALL(mock_rtc_event_log_,
935 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
936 .Times(1 + 4 + 1);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000937
938 uint16_t seq_num = kSeqNum;
939 uint32_t timestamp = kTimestamp;
940 rtp_sender_->SetStorePacketsStatus(true, 10);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000941 size_t rtp_header_len = kRtpHeaderSize;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000942 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800943 kRtpExtensionTransmissionTimeOffset,
944 kTransmissionTimeOffsetExtensionId));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000945 rtp_header_len += 4; // 4 bytes extension.
danilchap162abd32015-12-10 02:39:40 -0800946 EXPECT_EQ(
947 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
948 kAbsoluteSendTimeExtensionId));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000949 rtp_header_len += 4; // 4 bytes extension.
950 rtp_header_len += 4; // 4 extra bytes common to all extension headers.
951
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000952 webrtc::RTPHeader rtp_header;
953
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000954 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700955 auto packet =
956 BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
Stefan Holmer586b19b2015-09-18 11:14:31 +0200957 const uint32_t media_packet_timestamp = timestamp;
danilchapb6f1fb52016-10-19 06:11:39 -0700958 size_t packet_size = packet->size();
Erik Språngf6468d22019-07-05 16:53:43 +0200959 int total_packets_sent = 0;
960 const int kStoredTimeInMs = 100;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000961
962 // Packet should be stored in a send bucket.
Erik Språngf6468d22019-07-05 16:53:43 +0200963 EXPECT_CALL(
964 mock_paced_sender_,
965 EnqueuePacket(AllOf(
966 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
967 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
968 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
969 packet->set_allow_retransmission(true);
970 EXPECT_TRUE(rtp_sender_->SendToNetwork(
Erik Språng70768f42019-08-27 18:16:26 +0200971 absl::make_unique<RtpPacketToSend>(*packet)));
Erik Språngf6468d22019-07-05 16:53:43 +0200972 EXPECT_EQ(total_packets_sent, transport_.packets_sent());
973 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
974 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
975 ++seq_num;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000976
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000977 // Packet should now be sent. This test doesn't verify the regular video
978 // packet, since it is tested in another test.
danilchap12ba1862016-10-26 02:41:55 -0700979 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000980 timestamp += 90 * kStoredTimeInMs;
981
982 // Send padding 4 times, waiting 50 ms between each.
983 for (int i = 0; i < 4; ++i) {
984 const int kPaddingPeriodMs = 50;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000985 const size_t kPaddingBytes = 100;
986 const size_t kMaxPaddingLength = 224; // Value taken from rtp_sender.cc.
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000987 // Padding will be forced to full packets.
Erik Språng4208a132019-08-26 08:58:45 +0200988 EXPECT_EQ(kMaxPaddingLength, GenerateAndSendPadding(kPaddingBytes));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000989
990 // Process send bucket. Padding should now be sent.
danilchap12ba1862016-10-26 02:41:55 -0700991 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000992 EXPECT_EQ(kMaxPaddingLength + rtp_header_len,
danilchap12ba1862016-10-26 02:41:55 -0700993 transport_.last_sent_packet().size());
994
995 transport_.last_sent_packet().GetHeader(&rtp_header);
pbosbd2522a2015-07-01 05:35:53 -0700996 EXPECT_EQ(kMaxPaddingLength, rtp_header.paddingLength);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000997
Stefan Holmer586b19b2015-09-18 11:14:31 +0200998 // Verify sequence number and timestamp. The timestamp should be the same
999 // as the last media packet.
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001000 EXPECT_EQ(seq_num++, rtp_header.sequenceNumber);
Stefan Holmer586b19b2015-09-18 11:14:31 +02001001 EXPECT_EQ(media_packet_timestamp, rtp_header.timestamp);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001002 // Verify transmission time offset.
Stefan Holmer586b19b2015-09-18 11:14:31 +02001003 int offset = timestamp - media_packet_timestamp;
1004 EXPECT_EQ(offset, rtp_header.extension.transmissionTimeOffset);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001005 uint64_t expected_send_time =
1006 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
1007 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
1008 fake_clock_.AdvanceTimeMilliseconds(kPaddingPeriodMs);
1009 timestamp += 90 * kPaddingPeriodMs;
1010 }
1011
1012 // Send a regular video packet again.
1013 capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -07001014 packet = BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
1015 packet_size = packet->size();
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001016
Erik Språngf6468d22019-07-05 16:53:43 +02001017 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
Erik Språng70768f42019-08-27 18:16:26 +02001018 packet->set_allow_retransmission(true);
Erik Språngf6468d22019-07-05 16:53:43 +02001019 EXPECT_CALL(
1020 mock_paced_sender_,
1021 EnqueuePacket(AllOf(
1022 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1023 Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
1024 EXPECT_TRUE(rtp_sender_->SendToNetwork(
Erik Språng70768f42019-08-27 18:16:26 +02001025 absl::make_unique<RtpPacketToSend>(*packet)));
Erik Språngf6468d22019-07-05 16:53:43 +02001026 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
terelius5d332ac2016-01-14 14:37:39 -08001027
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001028 // Process send bucket.
danilchap12ba1862016-10-26 02:41:55 -07001029 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
1030 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
1031 transport_.last_sent_packet().GetHeader(&rtp_header);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +00001032
1033 // Verify sequence number and timestamp.
1034 EXPECT_EQ(seq_num, rtp_header.sequenceNumber);
1035 EXPECT_EQ(timestamp, rtp_header.timestamp);
1036 // Verify transmission time offset. This packet is sent without delay.
1037 EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset);
1038 uint64_t expected_send_time =
1039 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +00001040 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +00001041}
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001042
minyue3a407ee2017-04-03 01:10:33 -07001043TEST_P(RtpSenderTest, OnSendPacketUpdated) {
stefana23fc622016-07-28 07:56:38 -07001044 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1045 kRtpExtensionTransportSequenceNumber,
1046 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -07001047 rtp_sender_->SetStorePacketsStatus(true, 10);
1048
1049 EXPECT_CALL(send_packet_observer_,
1050 OnSendPacket(kTransportSequenceNumber, _, _))
1051 .Times(1);
asapersson35151f32016-05-02 23:44:01 -07001052
Erik Språngf6468d22019-07-05 16:53:43 +02001053 EXPECT_CALL(
1054 mock_paced_sender_,
1055 EnqueuePacket(AllOf(
1056 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1057 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
1058 auto packet = SendGenericPacket();
1059 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1060 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
1061 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001062
danilchap12ba1862016-10-26 02:41:55 -07001063 EXPECT_EQ(1, transport_.packets_sent());
asapersson35151f32016-05-02 23:44:01 -07001064}
1065
minyue3a407ee2017-04-03 01:10:33 -07001066TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
stefana23fc622016-07-28 07:56:38 -07001067 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1068 kRtpExtensionTransportSequenceNumber,
1069 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -07001070 rtp_sender_->SetStorePacketsStatus(true, 10);
1071
1072 EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
asapersson35151f32016-05-02 23:44:01 -07001073
Erik Språngf6468d22019-07-05 16:53:43 +02001074 EXPECT_CALL(
1075 mock_paced_sender_,
1076 EnqueuePacket(AllOf(
1077 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1078 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
1079 auto packet = SendGenericPacket();
1080 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
1081 packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
1082 rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001083
danilchap12ba1862016-10-26 02:41:55 -07001084 EXPECT_EQ(1, transport_.packets_sent());
Petter Strandmark26bc6692018-05-29 08:43:35 +02001085 EXPECT_TRUE(transport_.last_options_.is_retransmit);
asapersson35151f32016-05-02 23:44:01 -07001086}
1087
minyue3a407ee2017-04-03 01:10:33 -07001088TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
Niels Möller8a40edd2019-01-24 18:04:44 +01001089 const char payload_name[] = "GENERIC";
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001090 const uint8_t payload_type = 127;
Niels Möller5fe95102019-03-04 16:49:25 +01001091 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001092 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001093 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01001094 FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001095 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1096 /*raw_payload=*/false);
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001097 uint8_t payload[] = {47, 11, 32, 93, 89};
1098
1099 // Send keyframe
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001100 RTPVideoHeader video_header;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001101 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001102 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1103 sizeof(payload), nullptr, &video_header,
1104 kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001105
danilchap96c15872016-11-21 01:35:29 -08001106 auto sent_payload = transport_.last_sent_packet().payload();
1107 uint8_t generic_header = sent_payload[0];
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001108 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
1109 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
danilchap96c15872016-11-21 01:35:29 -08001110 EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001111
1112 // Send delta frame
1113 payload[0] = 13;
1114 payload[1] = 42;
1115 payload[4] = 13;
1116
Niels Möller59ab1cf2019-02-06 22:48:11 +01001117 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001118 VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload,
1119 sizeof(payload), nullptr, &video_header,
1120 kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001121
danilchap96c15872016-11-21 01:35:29 -08001122 sent_payload = transport_.last_sent_packet().payload();
1123 generic_header = sent_payload[0];
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001124 EXPECT_FALSE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
1125 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
danilchap96c15872016-11-21 01:35:29 -08001126 EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001127}
1128
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001129TEST_P(RtpSenderTestWithoutPacer, SendRawVideo) {
1130 const char payload_name[] = "VP8";
1131 const uint8_t payload_type = 111;
1132 const uint8_t payload[] = {11, 22, 33, 44, 55};
1133
1134 PlayoutDelayOracle playout_delay_oracle;
1135 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001136 &playout_delay_oracle, nullptr, false, false,
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001137 FieldTrialBasedConfig());
1138 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1139 /*raw_payload=*/true);
1140
1141 // Send a frame.
1142 RTPVideoHeader video_header;
1143 ASSERT_TRUE(rtp_sender_video.SendVideo(
1144 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1145 sizeof(payload), nullptr, &video_header,
1146 kDefaultExpectedRetransmissionTimeMs));
1147
1148 auto sent_payload = transport_.last_sent_packet().payload();
1149 EXPECT_THAT(sent_payload, ElementsAreArray(payload));
1150}
1151
minyue3a407ee2017-04-03 01:10:33 -07001152TEST_P(RtpSenderTest, SendFlexfecPackets) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001153 constexpr uint32_t kTimestamp = 1234;
brandtrdbdb3f12016-11-10 05:04:48 -08001154 constexpr int kMediaPayloadType = 127;
1155 constexpr int kFlexfecPayloadType = 118;
brandtrdbdb3f12016-11-10 05:04:48 -08001156 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001157 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språng4580ca22019-07-04 10:38:43 +02001158 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1159 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001160 nullptr /* rtp_state */, &fake_clock_);
brandtrdbdb3f12016-11-10 05:04:48 -08001161
1162 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001163 RtpRtcp::Configuration config;
1164 config.clock = &fake_clock_;
1165 config.outgoing_transport = &transport_;
1166 config.paced_sender = &mock_paced_sender_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001167 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001168 config.flexfec_sender = &flexfec_sender_;
Erik Språng4580ca22019-07-04 10:38:43 +02001169 config.event_log = &mock_rtc_event_log_;
1170 config.send_packet_observer = &send_packet_observer_;
1171 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1172 rtp_sender_ = absl::make_unique<RTPSender>(config);
1173
brandtrdbdb3f12016-11-10 05:04:48 -08001174 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtrdbdb3f12016-11-10 05:04:48 -08001175 rtp_sender_->SetStorePacketsStatus(true, 10);
1176
Niels Möller5fe95102019-03-04 16:49:25 +01001177 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001178 RTPSenderVideo rtp_sender_video(
1179 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1180 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001181 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1182 /*raw_payload=*/false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001183
brandtrdbdb3f12016-11-10 05:04:48 -08001184 // Parameters selected to generate a single FEC packet per media packet.
1185 FecProtectionParams params;
1186 params.fec_rate = 15;
1187 params.max_fec_frames = 1;
1188 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001189 rtp_sender_video.SetFecParameters(params, params);
brandtrdbdb3f12016-11-10 05:04:48 -08001190
brandtr9dfff292016-11-14 05:14:50 -08001191 uint16_t flexfec_seq_num;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001192 RTPVideoHeader video_header;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001193
Erik Språngf6468d22019-07-05 16:53:43 +02001194 std::unique_ptr<RtpPacketToSend> media_packet;
1195 std::unique_ptr<RtpPacketToSend> fec_packet;
1196
1197 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1198 .Times(2)
1199 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) {
1200 if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
1201 EXPECT_EQ(packet->Ssrc(), kSsrc);
1202 EXPECT_EQ(packet->SequenceNumber(), kSeqNum);
1203 media_packet = std::move(packet);
1204 } else {
1205 EXPECT_EQ(packet->packet_type(),
1206 RtpPacketToSend::Type::kForwardErrorCorrection);
1207 EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
1208 fec_packet = std::move(packet);
1209 }
1210 });
1211
1212 EXPECT_TRUE(rtp_sender_video.SendVideo(
1213 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
1214 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1215 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1216 ASSERT_TRUE(media_packet != nullptr);
1217 ASSERT_TRUE(fec_packet != nullptr);
1218
1219 flexfec_seq_num = fec_packet->SequenceNumber();
1220 rtp_sender_->TrySendPacket(media_packet.get(), PacedPacketInfo());
1221 rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001222
brandtr9dfff292016-11-14 05:14:50 -08001223 ASSERT_EQ(2, transport_.packets_sent());
Erik Språngf5815fa2019-08-21 14:27:31 +02001224 const RtpPacketReceived& sent_media_packet = transport_.sent_packets_[0];
1225 EXPECT_EQ(kMediaPayloadType, sent_media_packet.PayloadType());
1226 EXPECT_EQ(kSeqNum, sent_media_packet.SequenceNumber());
1227 EXPECT_EQ(kSsrc, sent_media_packet.Ssrc());
1228 const RtpPacketReceived& sent_flexfec_packet = transport_.sent_packets_[1];
1229 EXPECT_EQ(kFlexfecPayloadType, sent_flexfec_packet.PayloadType());
1230 EXPECT_EQ(flexfec_seq_num, sent_flexfec_packet.SequenceNumber());
1231 EXPECT_EQ(kFlexFecSsrc, sent_flexfec_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001232}
1233
Erik Språngf6468d22019-07-05 16:53:43 +02001234// TODO(ilnik): because of webrtc:7859. Once FEC moved below pacer, this test
1235// should be removed.
1236TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
1237 constexpr uint32_t kTimestamp = 1234;
1238 const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
1239 constexpr int kMediaPayloadType = 127;
1240 constexpr int kFlexfecPayloadType = 118;
1241 const std::vector<RtpExtension> kNoRtpExtensions;
1242 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
1243
1244 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1245 kNoRtpExtensions, kNoRtpExtensionSizes,
1246 nullptr /* rtp_state */, &fake_clock_);
1247
1248 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng630443a2019-07-26 16:44:55 +02001249 RtpRtcp::Configuration config;
1250 config.clock = &fake_clock_;
1251 config.outgoing_transport = &transport_;
1252 config.paced_sender = &mock_paced_sender_;
1253 config.flexfec_sender = &flexfec_sender;
Erik Språng630443a2019-07-26 16:44:55 +02001254 config.event_log = &mock_rtc_event_log_;
1255 config.send_packet_observer = &send_packet_observer_;
1256 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001257 config.local_media_ssrc = kSsrc;
Erik Språng630443a2019-07-26 16:44:55 +02001258 rtp_sender_ = absl::make_unique<RTPSender>(config);
Erik Språngf6468d22019-07-05 16:53:43 +02001259 rtp_sender_->SetSequenceNumber(kSeqNum);
1260 rtp_sender_->SetStorePacketsStatus(true, 10);
1261
1262 PlayoutDelayOracle playout_delay_oracle;
1263 RTPSenderVideo rtp_sender_video(
1264 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1265 nullptr, false, false, FieldTrialBasedConfig());
1266 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1267 /*raw_payload=*/false);
1268
1269 // Need extension to be registered for timing frames to be sent.
1270 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1271 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
1272
1273 // Parameters selected to generate a single FEC packet per media packet.
1274 FecProtectionParams params;
1275 params.fec_rate = 15;
1276 params.max_fec_frames = 1;
1277 params.fec_mask_type = kFecMaskRandom;
1278 rtp_sender_video.SetFecParameters(params, params);
1279
1280 RTPVideoHeader video_header;
1281 video_header.video_timing.flags = VideoSendTiming::kTriggeredByTimer;
1282
1283 EXPECT_CALL(mock_rtc_event_log_,
1284 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1285 .Times(1);
Erik Språngf6468d22019-07-05 16:53:43 +02001286 std::unique_ptr<RtpPacketToSend> rtp_packet;
1287 EXPECT_CALL(
1288 mock_paced_sender_,
1289 EnqueuePacket(AllOf(
1290 Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
1291 Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))))
1292 .WillOnce([&rtp_packet](std::unique_ptr<RtpPacketToSend> packet) {
1293 rtp_packet = std::move(packet);
1294 });
1295
1296 EXPECT_CALL(
1297 mock_paced_sender_,
1298 EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kFlexFecSsrc))))
1299 .Times(0); // Not called because packet should not be protected.
1300
1301 EXPECT_TRUE(rtp_sender_video.SendVideo(
1302 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
1303 kCaptureTimeMs, kPayloadData, sizeof(kPayloadData), nullptr,
1304 &video_header, kDefaultExpectedRetransmissionTimeMs));
1305
1306 EXPECT_TRUE(
1307 rtp_sender_->TrySendPacket(rtp_packet.get(), PacedPacketInfo()));
Erik Språngf6468d22019-07-05 16:53:43 +02001308
1309 ASSERT_EQ(1, transport_.packets_sent());
Erik Språngf5815fa2019-08-21 14:27:31 +02001310 const RtpPacketReceived& sent_media_packet1 = transport_.sent_packets_[0];
1311 EXPECT_EQ(kMediaPayloadType, sent_media_packet1.PayloadType());
1312 EXPECT_EQ(kSeqNum, sent_media_packet1.SequenceNumber());
1313 EXPECT_EQ(kSsrc, sent_media_packet1.Ssrc());
Erik Språngf6468d22019-07-05 16:53:43 +02001314
1315 // Now try to send not a timing frame.
1316 uint16_t flexfec_seq_num;
1317
1318 EXPECT_CALL(mock_rtc_event_log_,
1319 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1320 .Times(2);
Erik Språngf5815fa2019-08-21 14:27:31 +02001321 std::unique_ptr<RtpPacketToSend> media_packet2;
1322 std::unique_ptr<RtpPacketToSend> fec_packet;
Erik Språngf6468d22019-07-05 16:53:43 +02001323
Erik Språngf5815fa2019-08-21 14:27:31 +02001324 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1325 .Times(2)
1326 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) {
1327 if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
1328 EXPECT_EQ(packet->Ssrc(), kSsrc);
1329 EXPECT_EQ(packet->SequenceNumber(), kSeqNum + 1);
1330 media_packet2 = std::move(packet);
1331 } else {
1332 EXPECT_EQ(packet->packet_type(),
1333 RtpPacketToSend::Type::kForwardErrorCorrection);
1334 EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
1335 fec_packet = std::move(packet);
1336 }
1337 });
Erik Språngf6468d22019-07-05 16:53:43 +02001338
Erik Språngf5815fa2019-08-21 14:27:31 +02001339 video_header.video_timing.flags = VideoSendTiming::kInvalid;
1340 EXPECT_TRUE(rtp_sender_video.SendVideo(
1341 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp + 1,
1342 kCaptureTimeMs + 1, kPayloadData, sizeof(kPayloadData), nullptr,
1343 &video_header, kDefaultExpectedRetransmissionTimeMs));
Erik Språngf6468d22019-07-05 16:53:43 +02001344
Erik Språngf5815fa2019-08-21 14:27:31 +02001345 ASSERT_TRUE(media_packet2 != nullptr);
1346 ASSERT_TRUE(fec_packet != nullptr);
Erik Språngf6468d22019-07-05 16:53:43 +02001347
Erik Språngf5815fa2019-08-21 14:27:31 +02001348 flexfec_seq_num = fec_packet->SequenceNumber();
1349 rtp_sender_->TrySendPacket(media_packet2.get(), PacedPacketInfo());
1350 rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo());
Erik Språngf6468d22019-07-05 16:53:43 +02001351
1352 ASSERT_EQ(3, transport_.packets_sent());
Erik Språngf5815fa2019-08-21 14:27:31 +02001353 const RtpPacketReceived& sent_media_packet2 = transport_.sent_packets_[1];
1354 EXPECT_EQ(kMediaPayloadType, sent_media_packet2.PayloadType());
1355 EXPECT_EQ(kSeqNum + 1, sent_media_packet2.SequenceNumber());
1356 EXPECT_EQ(kSsrc, sent_media_packet2.Ssrc());
Erik Språngf6468d22019-07-05 16:53:43 +02001357 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[2];
1358 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
1359 EXPECT_EQ(flexfec_seq_num, flexfec_packet.SequenceNumber());
1360 EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
1361}
1362
minyue3a407ee2017-04-03 01:10:33 -07001363TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001364 constexpr uint32_t kTimestamp = 1234;
brandtrdbdb3f12016-11-10 05:04:48 -08001365 constexpr int kMediaPayloadType = 127;
1366 constexpr int kFlexfecPayloadType = 118;
brandtrdbdb3f12016-11-10 05:04:48 -08001367 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001368 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språngf6468d22019-07-05 16:53:43 +02001369 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
Erik Språng4580ca22019-07-04 10:38:43 +02001370 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001371 nullptr /* rtp_state */, &fake_clock_);
brandtrdbdb3f12016-11-10 05:04:48 -08001372
1373 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001374 RtpRtcp::Configuration config;
1375 config.clock = &fake_clock_;
1376 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001377 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001378 config.flexfec_sender = &flexfec_sender;
Erik Språng4580ca22019-07-04 10:38:43 +02001379 config.event_log = &mock_rtc_event_log_;
1380 config.send_packet_observer = &send_packet_observer_;
1381 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1382 rtp_sender_ = absl::make_unique<RTPSender>(config);
1383
brandtrdbdb3f12016-11-10 05:04:48 -08001384 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtrdbdb3f12016-11-10 05:04:48 -08001385
Niels Möller5fe95102019-03-04 16:49:25 +01001386 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001387 RTPSenderVideo rtp_sender_video(
1388 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1389 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001390 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1391 /*raw_payload=*/false);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001392
brandtrdbdb3f12016-11-10 05:04:48 -08001393 // Parameters selected to generate a single FEC packet per media packet.
1394 FecProtectionParams params;
1395 params.fec_rate = 15;
1396 params.max_fec_frames = 1;
1397 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001398 rtp_sender_video.SetFecParameters(params, params);
brandtrdbdb3f12016-11-10 05:04:48 -08001399
Elad Alon4a87e1c2017-10-03 16:11:34 +02001400 EXPECT_CALL(mock_rtc_event_log_,
1401 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1402 .Times(2);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001403 RTPVideoHeader video_header;
1404 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001405 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001406 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1407 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1408
brandtrdbdb3f12016-11-10 05:04:48 -08001409 ASSERT_EQ(2, transport_.packets_sent());
1410 const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
1411 EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
Erik Språng4580ca22019-07-04 10:38:43 +02001412 EXPECT_EQ(kSsrc, media_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001413 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[1];
1414 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
Erik Språngf6468d22019-07-05 16:53:43 +02001415 EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001416}
1417
Steve Anton296a0ce2018-03-22 15:17:27 -07001418// Test that the MID header extension is included on sent packets when
1419// configured.
1420TEST_P(RtpSenderTestWithoutPacer, MidIncludedOnSentPackets) {
1421 const char kMid[] = "mid";
1422
Steve Anton2bac7da2019-07-21 15:04:21 -04001423 EnableMidSending(kMid);
Steve Anton296a0ce2018-03-22 15:17:27 -07001424
1425 // Send a couple packets.
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001426 SendGenericPacket();
1427 SendGenericPacket();
Steve Anton296a0ce2018-03-22 15:17:27 -07001428
1429 // Expect both packets to have the MID set.
1430 ASSERT_EQ(2u, transport_.sent_packets_.size());
1431 for (const RtpPacketReceived& packet : transport_.sent_packets_) {
1432 std::string mid;
1433 ASSERT_TRUE(packet.GetExtension<RtpMid>(&mid));
1434 EXPECT_EQ(kMid, mid);
1435 }
1436}
1437
Amit Hilbuch77938e62018-12-21 09:23:38 -08001438TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnSentPackets) {
1439 const char kRid[] = "f";
1440
Steve Anton2bac7da2019-07-21 15:04:21 -04001441 EnableRidSending(kRid);
Amit Hilbuch77938e62018-12-21 09:23:38 -08001442
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001443 SendGenericPacket();
Amit Hilbuch77938e62018-12-21 09:23:38 -08001444
1445 ASSERT_EQ(1u, transport_.sent_packets_.size());
1446 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1447 std::string rid;
1448 ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
1449 EXPECT_EQ(kRid, rid);
1450}
1451
1452TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnRtxSentPackets) {
1453 const char kRid[] = "f";
Amit Hilbuch77938e62018-12-21 09:23:38 -08001454
Steve Anton2bac7da2019-07-21 15:04:21 -04001455 EnableRtx();
1456 EnableRidSending(kRid);
Amit Hilbuch77938e62018-12-21 09:23:38 -08001457
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001458 SendGenericPacket();
Amit Hilbuch77938e62018-12-21 09:23:38 -08001459 ASSERT_EQ(1u, transport_.sent_packets_.size());
1460 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1461 std::string rid;
1462 ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
1463 EXPECT_EQ(kRid, rid);
1464 rid = kNoRid;
Steve Anton2bac7da2019-07-21 15:04:21 -04001465 EXPECT_FALSE(packet.HasExtension<RepairedRtpStreamId>());
Amit Hilbuch77938e62018-12-21 09:23:38 -08001466
1467 uint16_t packet_id = packet.SequenceNumber();
1468 rtp_sender_->ReSendPacket(packet_id);
1469 ASSERT_EQ(2u, transport_.sent_packets_.size());
1470 const RtpPacketReceived& rtx_packet = transport_.sent_packets_[1];
1471 ASSERT_TRUE(rtx_packet.GetExtension<RepairedRtpStreamId>(&rid));
1472 EXPECT_EQ(kRid, rid);
1473 EXPECT_FALSE(rtx_packet.HasExtension<RtpStreamId>());
1474}
1475
Steve Anton2bac7da2019-07-21 15:04:21 -04001476TEST_P(RtpSenderTestWithoutPacer, MidAndRidNotIncludedOnSentPacketsAfterAck) {
1477 const char kMid[] = "mid";
1478 const char kRid[] = "f";
1479
1480 EnableMidSending(kMid);
1481 EnableRidSending(kRid);
1482
1483 // This first packet should include both MID and RID.
1484 auto first_built_packet = SendGenericPacket();
1485
1486 rtp_sender_->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
1487
1488 // The second packet should include neither since an ack was received.
1489 SendGenericPacket();
1490
1491 ASSERT_EQ(2u, transport_.sent_packets_.size());
1492
1493 const RtpPacketReceived& first_packet = transport_.sent_packets_[0];
1494 std::string mid, rid;
1495 ASSERT_TRUE(first_packet.GetExtension<RtpMid>(&mid));
1496 EXPECT_EQ(kMid, mid);
1497 ASSERT_TRUE(first_packet.GetExtension<RtpStreamId>(&rid));
1498 EXPECT_EQ(kRid, rid);
1499
1500 const RtpPacketReceived& second_packet = transport_.sent_packets_[1];
1501 EXPECT_FALSE(second_packet.HasExtension<RtpMid>());
1502 EXPECT_FALSE(second_packet.HasExtension<RtpStreamId>());
1503}
1504
1505// Test that the first RTX packet includes both MID and RRID even if the packet
1506// being retransmitted did not have MID or RID. The MID and RID are needed on
1507// the first packets for a given SSRC, and RTX packets are sent on a separate
1508// SSRC.
1509TEST_P(RtpSenderTestWithoutPacer, MidAndRidIncludedOnFirstRtxPacket) {
1510 const char kMid[] = "mid";
1511 const char kRid[] = "f";
1512
1513 EnableRtx();
1514 EnableMidSending(kMid);
1515 EnableRidSending(kRid);
1516
1517 // This first packet will include both MID and RID.
1518 auto first_built_packet = SendGenericPacket();
1519 rtp_sender_->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
1520
1521 // The second packet will include neither since an ack was received.
1522 auto second_built_packet = SendGenericPacket();
1523
1524 // The first RTX packet should include MID and RRID.
1525 ASSERT_LT(0,
1526 rtp_sender_->ReSendPacket(second_built_packet->SequenceNumber()));
1527
1528 ASSERT_EQ(3u, transport_.sent_packets_.size());
1529
1530 const RtpPacketReceived& rtx_packet = transport_.sent_packets_[2];
1531 std::string mid, rrid;
1532 ASSERT_TRUE(rtx_packet.GetExtension<RtpMid>(&mid));
1533 EXPECT_EQ(kMid, mid);
1534 ASSERT_TRUE(rtx_packet.GetExtension<RepairedRtpStreamId>(&rrid));
1535 EXPECT_EQ(kRid, rrid);
1536}
1537
1538// Test that the RTX packets sent after receving an ACK on the RTX SSRC does
1539// not include either MID or RRID even if the packet being retransmitted did
1540// had a MID or RID.
1541TEST_P(RtpSenderTestWithoutPacer, MidAndRidNotIncludedOnRtxPacketsAfterAck) {
1542 const char kMid[] = "mid";
1543 const char kRid[] = "f";
1544
1545 EnableRtx();
1546 EnableMidSending(kMid);
1547 EnableRidSending(kRid);
1548
1549 // This first packet will include both MID and RID.
1550 auto first_built_packet = SendGenericPacket();
1551 rtp_sender_->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
1552
1553 // The second packet will include neither since an ack was received.
1554 auto second_built_packet = SendGenericPacket();
1555
1556 // The first RTX packet will include MID and RRID.
1557 ASSERT_LT(0,
1558 rtp_sender_->ReSendPacket(second_built_packet->SequenceNumber()));
1559
1560 ASSERT_EQ(3u, transport_.sent_packets_.size());
1561 const RtpPacketReceived& first_rtx_packet = transport_.sent_packets_[2];
1562
1563 rtp_sender_->OnReceivedAckOnRtxSsrc(first_rtx_packet.SequenceNumber());
1564
1565 // The second and third RTX packets should not include MID nor RRID.
1566 ASSERT_LT(0, rtp_sender_->ReSendPacket(first_built_packet->SequenceNumber()));
1567 ASSERT_LT(0,
1568 rtp_sender_->ReSendPacket(second_built_packet->SequenceNumber()));
1569
1570 ASSERT_EQ(5u, transport_.sent_packets_.size());
1571
1572 const RtpPacketReceived& second_rtx_packet = transport_.sent_packets_[3];
1573 EXPECT_FALSE(second_rtx_packet.HasExtension<RtpMid>());
1574 EXPECT_FALSE(second_rtx_packet.HasExtension<RepairedRtpStreamId>());
1575
1576 const RtpPacketReceived& third_rtx_packet = transport_.sent_packets_[4];
1577 EXPECT_FALSE(third_rtx_packet.HasExtension<RtpMid>());
1578 EXPECT_FALSE(third_rtx_packet.HasExtension<RepairedRtpStreamId>());
1579}
1580
1581// Test that if the RtpState indicates an ACK has been received on that SSRC
1582// then neither the MID nor RID header extensions will be sent.
1583TEST_P(RtpSenderTestWithoutPacer,
1584 MidAndRidNotIncludedOnSentPacketsAfterRtpStateRestored) {
1585 const char kMid[] = "mid";
1586 const char kRid[] = "f";
1587
1588 EnableMidSending(kMid);
1589 EnableRidSending(kRid);
1590
1591 RtpState state = rtp_sender_->GetRtpState();
1592 EXPECT_FALSE(state.ssrc_has_acked);
1593 state.ssrc_has_acked = true;
1594 rtp_sender_->SetRtpState(state);
1595
1596 SendGenericPacket();
1597
1598 ASSERT_EQ(1u, transport_.sent_packets_.size());
1599 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1600 EXPECT_FALSE(packet.HasExtension<RtpMid>());
1601 EXPECT_FALSE(packet.HasExtension<RtpStreamId>());
1602}
1603
1604// Test that if the RTX RtpState indicates an ACK has been received on that
1605// RTX SSRC then neither the MID nor RRID header extensions will be sent on
1606// RTX packets.
1607TEST_P(RtpSenderTestWithoutPacer,
1608 MidAndRridNotIncludedOnRtxPacketsAfterRtpStateRestored) {
1609 const char kMid[] = "mid";
1610 const char kRid[] = "f";
1611
1612 EnableRtx();
1613 EnableMidSending(kMid);
1614 EnableRidSending(kRid);
1615
1616 RtpState rtx_state = rtp_sender_->GetRtxRtpState();
1617 EXPECT_FALSE(rtx_state.ssrc_has_acked);
1618 rtx_state.ssrc_has_acked = true;
1619 rtp_sender_->SetRtxRtpState(rtx_state);
1620
1621 auto built_packet = SendGenericPacket();
1622 ASSERT_LT(0, rtp_sender_->ReSendPacket(built_packet->SequenceNumber()));
1623
1624 ASSERT_EQ(2u, transport_.sent_packets_.size());
1625 const RtpPacketReceived& rtx_packet = transport_.sent_packets_[1];
1626 EXPECT_FALSE(rtx_packet.HasExtension<RtpMid>());
1627 EXPECT_FALSE(rtx_packet.HasExtension<RepairedRtpStreamId>());
1628}
1629
minyue3a407ee2017-04-03 01:10:33 -07001630TEST_P(RtpSenderTest, FecOverheadRate) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001631 constexpr uint32_t kTimestamp = 1234;
1632 constexpr int kMediaPayloadType = 127;
brandtr81eab612017-01-24 04:06:09 -08001633 constexpr int kFlexfecPayloadType = 118;
brandtr81eab612017-01-24 04:06:09 -08001634 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001635 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
Erik Språng4580ca22019-07-04 10:38:43 +02001636 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
1637 kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001638 nullptr /* rtp_state */, &fake_clock_);
brandtr81eab612017-01-24 04:06:09 -08001639
1640 // Reset |rtp_sender_| to use FlexFEC.
Erik Språng4580ca22019-07-04 10:38:43 +02001641 RtpRtcp::Configuration config;
1642 config.clock = &fake_clock_;
1643 config.outgoing_transport = &transport_;
1644 config.paced_sender = &mock_paced_sender_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001645 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001646 config.flexfec_sender = &flexfec_sender;
Erik Språng4580ca22019-07-04 10:38:43 +02001647 config.event_log = &mock_rtc_event_log_;
1648 config.send_packet_observer = &send_packet_observer_;
1649 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1650 rtp_sender_ = absl::make_unique<RTPSender>(config);
1651
brandtr81eab612017-01-24 04:06:09 -08001652 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtr81eab612017-01-24 04:06:09 -08001653
Niels Möller5fe95102019-03-04 16:49:25 +01001654 PlayoutDelayOracle playout_delay_oracle;
Elad Alona0e99432019-05-24 13:50:56 +02001655 RTPSenderVideo rtp_sender_video(
1656 &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
1657 nullptr, false, false, FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001658 rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
1659 /*raw_payload=*/false);
brandtr81eab612017-01-24 04:06:09 -08001660 // Parameters selected to generate a single FEC packet per media packet.
1661 FecProtectionParams params;
1662 params.fec_rate = 15;
1663 params.max_fec_frames = 1;
1664 params.fec_mask_type = kFecMaskRandom;
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001665 rtp_sender_video.SetFecParameters(params, params);
brandtr81eab612017-01-24 04:06:09 -08001666
1667 constexpr size_t kNumMediaPackets = 10;
1668 constexpr size_t kNumFecPackets = kNumMediaPackets;
1669 constexpr int64_t kTimeBetweenPacketsMs = 10;
Erik Språngf6468d22019-07-05 16:53:43 +02001670 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
1671 .Times(kNumMediaPackets + kNumFecPackets);
brandtr81eab612017-01-24 04:06:09 -08001672 for (size_t i = 0; i < kNumMediaPackets; ++i) {
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001673 RTPVideoHeader video_header;
1674
1675 EXPECT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001676 VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001677 fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
1678 nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
1679
brandtr81eab612017-01-24 04:06:09 -08001680 fake_clock_.AdvanceTimeMilliseconds(kTimeBetweenPacketsMs);
1681 }
1682 constexpr size_t kRtpHeaderLength = 12;
1683 constexpr size_t kFlexfecHeaderLength = 20;
1684 constexpr size_t kGenericCodecHeaderLength = 1;
1685 constexpr size_t kPayloadLength = sizeof(kPayloadData);
1686 constexpr size_t kPacketLength = kRtpHeaderLength + kFlexfecHeaderLength +
1687 kGenericCodecHeaderLength + kPayloadLength;
1688 EXPECT_NEAR(kNumFecPackets * kPacketLength * 8 /
1689 (kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f),
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001690 rtp_sender_video.FecOverheadRate(), 500);
brandtr81eab612017-01-24 04:06:09 -08001691}
1692
minyue3a407ee2017-04-03 01:10:33 -07001693TEST_P(RtpSenderTest, BitrateCallbacks) {
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001694 class TestCallback : public BitrateStatisticsObserver {
1695 public:
sprangcd349d92016-07-13 09:11:28 -07001696 TestCallback()
1697 : BitrateStatisticsObserver(),
1698 num_calls_(0),
1699 ssrc_(0),
1700 total_bitrate_(0),
1701 retransmit_bitrate_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +00001702 ~TestCallback() override = default;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001703
sprangcd349d92016-07-13 09:11:28 -07001704 void Notify(uint32_t total_bitrate,
1705 uint32_t retransmit_bitrate,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001706 uint32_t ssrc) override {
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001707 ++num_calls_;
1708 ssrc_ = ssrc;
sprangcd349d92016-07-13 09:11:28 -07001709 total_bitrate_ = total_bitrate;
1710 retransmit_bitrate_ = retransmit_bitrate;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001711 }
1712
1713 uint32_t num_calls_;
1714 uint32_t ssrc_;
sprangcd349d92016-07-13 09:11:28 -07001715 uint32_t total_bitrate_;
1716 uint32_t retransmit_bitrate_;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001717 } callback;
Erik Språng4580ca22019-07-04 10:38:43 +02001718
1719 RtpRtcp::Configuration config;
1720 config.clock = &fake_clock_;
1721 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001722 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001723 config.send_bitrate_observer = &callback;
1724 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1725 rtp_sender_ = absl::make_unique<RTPSender>(config);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001726
Niels Möller5fe95102019-03-04 16:49:25 +01001727 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001728 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001729 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01001730 FieldTrialBasedConfig());
Niels Möller59ab1cf2019-02-06 22:48:11 +01001731 const char payload_name[] = "GENERIC";
1732 const uint8_t payload_type = 127;
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001733 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1734 /*raw_payload=*/false);
Niels Möller59ab1cf2019-02-06 22:48:11 +01001735
sprangcd349d92016-07-13 09:11:28 -07001736 // Simulate kNumPackets sent with kPacketInterval ms intervals, with the
1737 // number of packets selected so that we fill (but don't overflow) the one
1738 // second averaging window.
1739 const uint32_t kWindowSizeMs = 1000;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001740 const uint32_t kPacketInterval = 20;
sprangcd349d92016-07-13 09:11:28 -07001741 const uint32_t kNumPackets =
1742 (kWindowSizeMs - kPacketInterval) / kPacketInterval;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001743 // Overhead = 12 bytes RTP header + 1 byte generic header.
1744 const uint32_t kPacketOverhead = 13;
1745
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001746 uint8_t payload[] = {47, 11, 32, 93, 89};
1747 rtp_sender_->SetStorePacketsStatus(true, 1);
1748 uint32_t ssrc = rtp_sender_->SSRC();
1749
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001750 // Initial process call so we get a new time window.
1751 rtp_sender_->ProcessBitrate();
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001752
1753 // Send a few frames.
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001754 RTPVideoHeader video_header;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001755 for (uint32_t i = 0; i < kNumPackets; ++i) {
Niels Möller59ab1cf2019-02-06 22:48:11 +01001756 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001757 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1758 sizeof(payload), nullptr, &video_header,
1759 kDefaultExpectedRetransmissionTimeMs));
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001760 fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
1761 }
1762
1763 rtp_sender_->ProcessBitrate();
1764
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001765 // We get one call for every stats updated, thus two calls since both the
1766 // stream stats and the retransmit stats are updated once.
1767 EXPECT_EQ(2u, callback.num_calls_);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001768 EXPECT_EQ(ssrc, callback.ssrc_);
sprangcd349d92016-07-13 09:11:28 -07001769 const uint32_t kTotalPacketSize = kPacketOverhead + sizeof(payload);
1770 // Bitrate measured over delta between last and first timestamp, plus one.
1771 const uint32_t kExpectedWindowMs = kNumPackets * kPacketInterval + 1;
1772 const uint32_t kExpectedBitsAccumulated = kTotalPacketSize * kNumPackets * 8;
1773 const uint32_t kExpectedRateBps =
1774 (kExpectedBitsAccumulated * 1000 + (kExpectedWindowMs / 2)) /
1775 kExpectedWindowMs;
1776 EXPECT_EQ(kExpectedRateBps, callback.total_bitrate_);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001777
andresp@webrtc.orgd11bec42014-07-08 14:32:58 +00001778 rtp_sender_.reset();
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001779}
1780
minyue3a407ee2017-04-03 01:10:33 -07001781TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001782 class TestCallback : public StreamDataCountersCallback {
1783 public:
danilchap162abd32015-12-10 02:39:40 -08001784 TestCallback() : StreamDataCountersCallback(), ssrc_(0), counters_() {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +00001785 ~TestCallback() override = default;
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001786
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001787 void DataCountersUpdated(const StreamDataCounters& counters,
1788 uint32_t ssrc) override {
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001789 ssrc_ = ssrc;
1790 counters_ = counters;
1791 }
1792
1793 uint32_t ssrc_;
1794 StreamDataCounters counters_;
asapersson@webrtc.org44149392015-02-04 08:34:47 +00001795
1796 void MatchPacketCounter(const RtpPacketCounter& expected,
1797 const RtpPacketCounter& actual) {
1798 EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
1799 EXPECT_EQ(expected.header_bytes, actual.header_bytes);
1800 EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
1801 EXPECT_EQ(expected.packets, actual.packets);
1802 }
1803
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001804 void Matches(uint32_t ssrc, const StreamDataCounters& counters) {
1805 EXPECT_EQ(ssrc, ssrc_);
asapersson@webrtc.org44149392015-02-04 08:34:47 +00001806 MatchPacketCounter(counters.transmitted, counters_.transmitted);
1807 MatchPacketCounter(counters.retransmitted, counters_.retransmitted);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001808 EXPECT_EQ(counters.fec.packets, counters_.fec.packets);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001809 }
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001810 } callback;
1811
1812 const uint8_t kRedPayloadType = 96;
1813 const uint8_t kUlpfecPayloadType = 97;
Niels Möller8a40edd2019-01-24 18:04:44 +01001814 const char payload_name[] = "GENERIC";
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001815 const uint8_t payload_type = 127;
Niels Möller5fe95102019-03-04 16:49:25 +01001816 PlayoutDelayOracle playout_delay_oracle;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001817 RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
Elad Alona0e99432019-05-24 13:50:56 +02001818 &playout_delay_oracle, nullptr, false, false,
Niels Möller5fe95102019-03-04 16:49:25 +01001819 FieldTrialBasedConfig());
Mirta Dvornicicfe68daa2019-05-23 13:21:12 +02001820 rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
1821 /*raw_payload=*/false);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001822 uint8_t payload[] = {47, 11, 32, 93, 89};
1823 rtp_sender_->SetStorePacketsStatus(true, 1);
1824 uint32_t ssrc = rtp_sender_->SSRC();
1825
1826 rtp_sender_->RegisterRtpStatisticsCallback(&callback);
1827
1828 // Send a frame.
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001829 RTPVideoHeader video_header;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001830 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001831 VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
1832 sizeof(payload), nullptr, &video_header,
1833 kDefaultExpectedRetransmissionTimeMs));
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001834 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001835 expected.transmitted.payload_bytes = 6;
1836 expected.transmitted.header_bytes = 12;
1837 expected.transmitted.padding_bytes = 0;
1838 expected.transmitted.packets = 1;
1839 expected.retransmitted.payload_bytes = 0;
1840 expected.retransmitted.header_bytes = 0;
1841 expected.retransmitted.padding_bytes = 0;
1842 expected.retransmitted.packets = 0;
1843 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001844 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001845
1846 // Retransmit a frame.
1847 uint16_t seqno = rtp_sender_->SequenceNumber() - 1;
Erik Språnga12b1d62018-03-14 12:39:24 +01001848 rtp_sender_->ReSendPacket(seqno);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001849 expected.transmitted.payload_bytes = 12;
1850 expected.transmitted.header_bytes = 24;
1851 expected.transmitted.packets = 2;
1852 expected.retransmitted.payload_bytes = 6;
1853 expected.retransmitted.header_bytes = 12;
1854 expected.retransmitted.padding_bytes = 0;
1855 expected.retransmitted.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001856 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001857
1858 // Send padding.
Erik Språng4208a132019-08-26 08:58:45 +02001859 GenerateAndSendPadding(kMaxPaddingSize);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001860 expected.transmitted.payload_bytes = 12;
1861 expected.transmitted.header_bytes = 36;
1862 expected.transmitted.padding_bytes = kMaxPaddingSize;
1863 expected.transmitted.packets = 3;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001864 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001865
brandtrf1bb4762016-11-07 03:05:06 -08001866 // Send ULPFEC.
Niels Möller59ab1cf2019-02-06 22:48:11 +01001867 rtp_sender_video.SetUlpfecConfig(kRedPayloadType, kUlpfecPayloadType);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001868 FecProtectionParams fec_params;
1869 fec_params.fec_mask_type = kFecMaskRandom;
1870 fec_params.fec_rate = 1;
1871 fec_params.max_fec_frames = 1;
Niels Möller59ab1cf2019-02-06 22:48:11 +01001872 rtp_sender_video.SetFecParameters(fec_params, fec_params);
1873 ASSERT_TRUE(rtp_sender_video.SendVideo(
Niels Möller8f7ce222019-03-21 15:43:58 +01001874 VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload,
1875 sizeof(payload), nullptr, &video_header,
1876 kDefaultExpectedRetransmissionTimeMs));
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001877 expected.transmitted.payload_bytes = 40;
1878 expected.transmitted.header_bytes = 60;
1879 expected.transmitted.packets = 5;
1880 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001881 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001882
sprang867fb522015-08-03 04:38:41 -07001883 rtp_sender_->RegisterRtpStatisticsCallback(nullptr);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001884}
1885
minyue3a407ee2017-04-03 01:10:33 -07001886TEST_P(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
Niels Möller59ab1cf2019-02-06 22:48:11 +01001887 // XXX const char* kPayloadName = "GENERIC";
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001888 const uint8_t kPayloadType = 127;
Shao Changbine62202f2015-04-21 20:24:50 +08001889 rtp_sender_->SetRtxPayloadType(kPayloadType - 1, kPayloadType);
pbos@webrtc.org0b0c2412015-01-13 14:15:15 +00001890 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001891
Niels Möller59ab1cf2019-02-06 22:48:11 +01001892 SendGenericPacket();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001893 // Will send 2 full-size padding packets.
Erik Språng4208a132019-08-26 08:58:45 +02001894 GenerateAndSendPadding(1);
1895 GenerateAndSendPadding(1);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001896
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001897 StreamDataCounters rtp_stats;
1898 StreamDataCounters rtx_stats;
1899 rtp_sender_->GetDataCounters(&rtp_stats, &rtx_stats);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001900
Niels Möller59ab1cf2019-02-06 22:48:11 +01001901 // Payload
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +00001902 EXPECT_GT(rtp_stats.first_packet_time_ms, -1);
Niels Möller59ab1cf2019-02-06 22:48:11 +01001903 EXPECT_EQ(rtp_stats.transmitted.payload_bytes, sizeof(kPayloadData));
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001904 EXPECT_EQ(rtp_stats.transmitted.header_bytes, 12u);
1905 EXPECT_EQ(rtp_stats.transmitted.padding_bytes, 0u);
1906 EXPECT_EQ(rtx_stats.transmitted.payload_bytes, 0u);
1907 EXPECT_EQ(rtx_stats.transmitted.header_bytes, 24u);
1908 EXPECT_EQ(rtx_stats.transmitted.padding_bytes, 2 * kMaxPaddingSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001909
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001910 EXPECT_EQ(rtp_stats.transmitted.TotalBytes(),
danilchap162abd32015-12-10 02:39:40 -08001911 rtp_stats.transmitted.payload_bytes +
1912 rtp_stats.transmitted.header_bytes +
1913 rtp_stats.transmitted.padding_bytes);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001914 EXPECT_EQ(rtx_stats.transmitted.TotalBytes(),
danilchap162abd32015-12-10 02:39:40 -08001915 rtx_stats.transmitted.payload_bytes +
1916 rtx_stats.transmitted.header_bytes +
1917 rtx_stats.transmitted.padding_bytes);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001918
danilchap162abd32015-12-10 02:39:40 -08001919 EXPECT_EQ(
1920 transport_.total_bytes_sent_,
1921 rtp_stats.transmitted.TotalBytes() + rtx_stats.transmitted.TotalBytes());
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001922}
guoweis@webrtc.org45362892015-03-04 22:55:15 +00001923
minyue3a407ee2017-04-03 01:10:33 -07001924TEST_P(RtpSenderTestWithoutPacer, RespectsNackBitrateLimit) {
sprang38778b02015-09-29 09:48:22 -07001925 const int32_t kPacketSize = 1400;
1926 const int32_t kNumPackets = 30;
1927
sprangcd349d92016-07-13 09:11:28 -07001928 retransmission_rate_limiter_.SetMaxRate(kPacketSize * kNumPackets * 8);
1929
sprang38778b02015-09-29 09:48:22 -07001930 rtp_sender_->SetStorePacketsStatus(true, kNumPackets);
sprang38778b02015-09-29 09:48:22 -07001931 const uint16_t kStartSequenceNumber = rtp_sender_->SequenceNumber();
Danil Chapovalov2800d742016-08-26 18:48:46 +02001932 std::vector<uint16_t> sequence_numbers;
sprang38778b02015-09-29 09:48:22 -07001933 for (int32_t i = 0; i < kNumPackets; ++i) {
1934 sequence_numbers.push_back(kStartSequenceNumber + i);
1935 fake_clock_.AdvanceTimeMilliseconds(1);
1936 SendPacket(fake_clock_.TimeInMilliseconds(), kPacketSize);
1937 }
danilchap12ba1862016-10-26 02:41:55 -07001938 EXPECT_EQ(kNumPackets, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001939
1940 fake_clock_.AdvanceTimeMilliseconds(1000 - kNumPackets);
1941
1942 // Resending should work - brings the bandwidth up to the limit.
1943 // NACK bitrate is capped to the same bitrate as the encoder, since the max
1944 // protection overhead is 50% (see MediaOptimization::SetTargetRates).
Danil Chapovalov2800d742016-08-26 18:48:46 +02001945 rtp_sender_->OnReceivedNack(sequence_numbers, 0);
danilchap12ba1862016-10-26 02:41:55 -07001946 EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001947
sprangcd349d92016-07-13 09:11:28 -07001948 // Must be at least 5ms in between retransmission attempts.
1949 fake_clock_.AdvanceTimeMilliseconds(5);
1950
sprang38778b02015-09-29 09:48:22 -07001951 // Resending should not work, bandwidth exceeded.
Danil Chapovalov2800d742016-08-26 18:48:46 +02001952 rtp_sender_->OnReceivedNack(sequence_numbers, 0);
danilchap12ba1862016-10-26 02:41:55 -07001953 EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001954}
1955
minyue3a407ee2017-04-03 01:10:33 -07001956TEST_P(RtpSenderTest, OnOverheadChanged) {
michaelt4da30442016-11-17 01:38:43 -08001957 MockOverheadObserver mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02001958 RtpRtcp::Configuration config;
1959 config.clock = &fake_clock_;
1960 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001961 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001962 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1963 config.overhead_observer = &mock_overhead_observer;
1964 rtp_sender_ = absl::make_unique<RTPSender>(config);
michaelt4da30442016-11-17 01:38:43 -08001965
michaelt4da30442016-11-17 01:38:43 -08001966 // RTP overhead is 12B.
nisse284542b2017-01-10 08:58:32 -08001967 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(12)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001968 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08001969
1970 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
1971 kTransmissionTimeOffsetExtensionId);
1972
1973 // TransmissionTimeOffset extension has a size of 8B.
nisse284542b2017-01-10 08:58:32 -08001974 // 12B + 8B = 20B
1975 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(20)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001976 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08001977}
1978
minyue3a407ee2017-04-03 01:10:33 -07001979TEST_P(RtpSenderTest, DoesNotUpdateOverheadOnEqualSize) {
michaelt4da30442016-11-17 01:38:43 -08001980 MockOverheadObserver mock_overhead_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02001981 RtpRtcp::Configuration config;
1982 config.clock = &fake_clock_;
1983 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02001984 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02001985 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
1986 config.overhead_observer = &mock_overhead_observer;
1987 rtp_sender_ = absl::make_unique<RTPSender>(config);
michaelt4da30442016-11-17 01:38:43 -08001988
1989 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(_)).Times(1);
Niels Möllere7b9e6b2019-02-06 18:23:44 +01001990 SendGenericPacket();
1991 SendGenericPacket();
michaelt4da30442016-11-17 01:38:43 -08001992}
1993
Erik Språng9c771c22019-06-17 16:31:53 +02001994TEST_P(RtpSenderTest, TrySendPacketMatchesVideo) {
1995 std::unique_ptr<RtpPacketToSend> packet =
1996 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
1997 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
1998
1999 // Verify not sent with wrong SSRC.
2000 packet->SetSsrc(kSsrc + 1);
2001 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2002
2003 // Verify sent with correct SSRC.
2004 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2005 packet->SetSsrc(kSsrc);
2006 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2007 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2008}
2009
2010TEST_P(RtpSenderTest, TrySendPacketMatchesAudio) {
2011 std::unique_ptr<RtpPacketToSend> packet =
2012 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2013 packet->set_packet_type(RtpPacketToSend::Type::kAudio);
2014
2015 // Verify not sent with wrong SSRC.
2016 packet->SetSsrc(kSsrc + 1);
2017 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2018
2019 // Verify sent with correct SSRC.
2020 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2021 packet->SetSsrc(kSsrc);
2022 packet->set_packet_type(RtpPacketToSend::Type::kAudio);
2023 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2024}
2025
2026TEST_P(RtpSenderTest, TrySendPacketMatchesRetransmissions) {
2027 std::unique_ptr<RtpPacketToSend> packet =
2028 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2029 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2030
2031 // Verify not sent with wrong SSRC.
2032 packet->SetSsrc(kSsrc + 1);
2033 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2034
2035 // Verify sent with correct SSRC (non-RTX).
2036 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2037 packet->SetSsrc(kSsrc);
2038 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2039 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2040
2041 // RTX retransmission.
2042 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2043 packet->SetSsrc(kRtxSsrc);
2044 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2045 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2046}
2047
2048TEST_P(RtpSenderTest, TrySendPacketMatchesPadding) {
2049 std::unique_ptr<RtpPacketToSend> packet =
2050 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2051 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2052
2053 // Verify not sent with wrong SSRC.
2054 packet->SetSsrc(kSsrc + 1);
2055 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2056
2057 // Verify sent with correct SSRC (non-RTX).
2058 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2059 packet->SetSsrc(kSsrc);
2060 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2061 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2062
2063 // RTX padding.
2064 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2065 packet->SetSsrc(kRtxSsrc);
2066 packet->set_packet_type(RtpPacketToSend::Type::kPadding);
2067 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2068}
2069
2070TEST_P(RtpSenderTest, TrySendPacketMatchesFlexfec) {
2071 std::unique_ptr<RtpPacketToSend> packet =
2072 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2073 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2074
2075 // Verify not sent with wrong SSRC.
2076 packet->SetSsrc(kSsrc + 1);
2077 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2078
2079 // Verify sent with correct SSRC.
2080 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2081 packet->SetSsrc(kFlexFecSsrc);
2082 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2083 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2084}
2085
2086TEST_P(RtpSenderTest, TrySendPacketMatchesUlpfec) {
2087 std::unique_ptr<RtpPacketToSend> packet =
2088 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2089 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2090
2091 // Verify not sent with wrong SSRC.
2092 packet->SetSsrc(kSsrc + 1);
2093 EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2094
2095 // Verify sent with correct SSRC.
2096 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2097 packet->SetSsrc(kSsrc);
2098 packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2099 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2100}
2101
2102TEST_P(RtpSenderTest, TrySendPacketHandlesRetransmissionHistory) {
2103 rtp_sender_->SetStorePacketsStatus(true, 10);
2104
2105 // Build a media packet and send it.
2106 std::unique_ptr<RtpPacketToSend> packet =
2107 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2108 const uint16_t media_sequence_number = packet->SequenceNumber();
2109 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2110 packet->set_allow_retransmission(true);
2111 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2112
2113 // Simulate retransmission request.
2114 fake_clock_.AdvanceTimeMilliseconds(30);
2115 EXPECT_GT(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2116
2117 // Packet already pending, retransmission not allowed.
2118 fake_clock_.AdvanceTimeMilliseconds(30);
2119 EXPECT_EQ(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2120
2121 // Packet exiting pacer, mark as not longer pending.
2122 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2123 EXPECT_NE(packet->SequenceNumber(), media_sequence_number);
2124 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2125 packet->SetSsrc(kRtxSsrc);
2126 packet->set_retransmitted_sequence_number(media_sequence_number);
2127 packet->set_allow_retransmission(false);
2128 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2129
2130 // Retransmissions allowed again.
2131 fake_clock_.AdvanceTimeMilliseconds(30);
2132 EXPECT_GT(rtp_sender_->ReSendPacket(media_sequence_number), 0);
2133
2134 // Retransmission of RTX packet should not be allowed.
2135 EXPECT_EQ(rtp_sender_->ReSendPacket(packet->SequenceNumber()), 0);
2136}
2137
2138TEST_P(RtpSenderTest, TrySendPacketUpdatesExtensions) {
2139 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2140 kRtpExtensionTransmissionTimeOffset,
2141 kTransmissionTimeOffsetExtensionId),
2142 0);
2143 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2144 kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId),
2145 0);
2146 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionVideoTiming,
2147 kVideoTimingExtensionId),
2148 0);
2149
2150 std::unique_ptr<RtpPacketToSend> packet =
2151 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2152 packet->set_packetization_finish_time_ms(fake_clock_.TimeInMilliseconds());
2153
2154 const int32_t kDiffMs = 10;
2155 fake_clock_.AdvanceTimeMilliseconds(kDiffMs);
2156
2157 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2158 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2159
2160 const RtpPacketReceived& received_packet = transport_.last_sent_packet();
2161
2162 EXPECT_EQ(received_packet.GetExtension<TransmissionOffset>(), kDiffMs * 90);
2163
2164 EXPECT_EQ(received_packet.GetExtension<AbsoluteSendTime>(),
2165 AbsoluteSendTime::MsTo24Bits(fake_clock_.TimeInMilliseconds()));
2166
2167 VideoSendTiming timing;
2168 EXPECT_TRUE(received_packet.GetExtension<VideoTimingExtension>(&timing));
2169 EXPECT_EQ(timing.pacer_exit_delta_ms, kDiffMs);
2170}
2171
2172TEST_P(RtpSenderTest, TrySendPacketSetsPacketOptions) {
2173 const uint16_t kPacketId = 42;
2174 ASSERT_EQ(rtp_sender_->RegisterRtpHeaderExtension(
2175 kRtpExtensionTransportSequenceNumber,
2176 kTransportSequenceNumberExtensionId),
2177 0);
2178 std::unique_ptr<RtpPacketToSend> packet =
2179 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2180 packet->SetExtension<TransportSequenceNumber>(kPacketId);
2181
2182 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2183 EXPECT_CALL(send_packet_observer_, OnSendPacket);
2184 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2185
2186 EXPECT_EQ(transport_.last_options_.packet_id, kPacketId);
2187 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
2188 EXPECT_TRUE(transport_.last_options_.included_in_feedback);
2189 EXPECT_FALSE(transport_.last_options_.is_retransmit);
2190
2191 // Send another packet as retransmission, verify options are populated.
2192 packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2193 packet->SetExtension<TransportSequenceNumber>(kPacketId + 1);
2194 packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2195 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2196 EXPECT_TRUE(transport_.last_options_.is_retransmit);
2197}
2198
2199TEST_P(RtpSenderTest, TrySendPacketUpdatesStats) {
2200 const size_t kPayloadSize = 1000;
2201
2202 StrictMock<MockSendSideDelayObserver> send_side_delay_observer;
Erik Språng4580ca22019-07-04 10:38:43 +02002203
2204 RtpRtcp::Configuration config;
2205 config.clock = &fake_clock_;
2206 config.outgoing_transport = &transport_;
Erik Språng54d5d2c2019-08-20 17:22:36 +02002207 config.local_media_ssrc = kSsrc;
Erik Språng4580ca22019-07-04 10:38:43 +02002208 config.rtx_send_ssrc = kRtxSsrc;
2209 config.flexfec_sender = &flexfec_sender_;
2210 config.send_side_delay_observer = &send_side_delay_observer;
2211 config.event_log = &mock_rtc_event_log_;
2212 config.send_packet_observer = &send_packet_observer_;
2213 rtp_sender_ = absl::make_unique<RTPSender>(config);
Erik Språng9c771c22019-06-17 16:31:53 +02002214 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2215 kRtpExtensionTransportSequenceNumber,
2216 kTransportSequenceNumberExtensionId));
2217
2218 const int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
2219
2220 std::unique_ptr<RtpPacketToSend> video_packet =
2221 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2222 video_packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2223 video_packet->SetPayloadSize(kPayloadSize);
2224 video_packet->SetExtension<TransportSequenceNumber>(1);
2225
2226 std::unique_ptr<RtpPacketToSend> rtx_packet =
2227 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2228 rtx_packet->SetSsrc(kRtxSsrc);
2229 rtx_packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
2230 rtx_packet->SetPayloadSize(kPayloadSize);
2231 rtx_packet->SetExtension<TransportSequenceNumber>(2);
2232
2233 std::unique_ptr<RtpPacketToSend> fec_packet =
2234 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2235 fec_packet->SetSsrc(kFlexFecSsrc);
2236 fec_packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
2237 fec_packet->SetPayloadSize(kPayloadSize);
2238 fec_packet->SetExtension<TransportSequenceNumber>(3);
2239
2240 const int64_t kDiffMs = 25;
2241 fake_clock_.AdvanceTimeMilliseconds(kDiffMs);
2242
2243 EXPECT_CALL(send_side_delay_observer,
2244 SendSideDelayUpdated(kDiffMs, kDiffMs, kDiffMs, kSsrc));
2245 EXPECT_CALL(
2246 send_side_delay_observer,
2247 SendSideDelayUpdated(kDiffMs, kDiffMs, 2 * kDiffMs, kFlexFecSsrc));
2248
2249 EXPECT_CALL(send_packet_observer_, OnSendPacket(1, capture_time_ms, kSsrc));
2250 EXPECT_TRUE(
2251 rtp_sender_->TrySendPacket(video_packet.get(), PacedPacketInfo()));
2252
2253 // Send packet observer not called for padding/retransmissions.
2254 EXPECT_CALL(send_packet_observer_, OnSendPacket(2, _, _)).Times(0);
2255 EXPECT_TRUE(rtp_sender_->TrySendPacket(rtx_packet.get(), PacedPacketInfo()));
2256
2257 EXPECT_CALL(send_packet_observer_,
2258 OnSendPacket(3, capture_time_ms, kFlexFecSsrc));
2259 EXPECT_TRUE(rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo()));
2260
2261 StreamDataCounters rtp_stats;
2262 StreamDataCounters rtx_stats;
2263 rtp_sender_->GetDataCounters(&rtp_stats, &rtx_stats);
2264 EXPECT_EQ(rtp_stats.transmitted.packets, 2u);
2265 EXPECT_EQ(rtp_stats.fec.packets, 1u);
2266 EXPECT_EQ(rtx_stats.retransmitted.packets, 1u);
2267}
2268
Erik Språng478cb462019-06-26 15:49:27 +02002269TEST_P(RtpSenderTest, GeneratePaddingResendsOldPacketsWithRtx) {
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002270 // Min requested size in order to use RTX payload.
2271 const size_t kMinPaddingSize = 50;
2272
Erik Språng478cb462019-06-26 15:49:27 +02002273 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2274 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2275 rtp_sender_->SetStorePacketsStatus(true, 1);
2276
Erik Språng0f6191d2019-07-15 20:33:40 +02002277 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2278 kRtpExtensionTransmissionTimeOffset,
2279 kTransmissionTimeOffsetExtensionId));
2280 ASSERT_EQ(
2281 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
2282 kAbsoluteSendTimeExtensionId));
2283 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2284 kRtpExtensionTransportSequenceNumber,
2285 kTransportSequenceNumberExtensionId));
2286
Erik Språng478cb462019-06-26 15:49:27 +02002287 const size_t kPayloadPacketSize = 1234;
2288 std::unique_ptr<RtpPacketToSend> packet =
2289 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2290 packet->set_allow_retransmission(true);
2291 packet->SetPayloadSize(kPayloadPacketSize);
2292 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2293
2294 // Send a dummy video packet so it ends up in the packet history.
Erik Språng0f6191d2019-07-15 20:33:40 +02002295 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Erik Språng478cb462019-06-26 15:49:27 +02002296 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2297
2298 // Generated padding has large enough budget that the video packet should be
2299 // retransmitted as padding.
Erik Språngf6468d22019-07-05 16:53:43 +02002300 std::vector<std::unique_ptr<RtpPacketToSend>> generated_packets =
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002301 rtp_sender_->GeneratePadding(kMinPaddingSize);
Erik Språngf6468d22019-07-05 16:53:43 +02002302 ASSERT_EQ(generated_packets.size(), 1u);
2303 auto& padding_packet = generated_packets.front();
2304 EXPECT_EQ(padding_packet->packet_type(), RtpPacketToSend::Type::kPadding);
2305 EXPECT_EQ(padding_packet->Ssrc(), kRtxSsrc);
2306 EXPECT_EQ(padding_packet->payload_size(),
2307 kPayloadPacketSize + kRtxHeaderSize);
Erik Språng0f6191d2019-07-15 20:33:40 +02002308 EXPECT_TRUE(padding_packet->IsExtensionReserved<TransportSequenceNumber>());
2309 EXPECT_TRUE(padding_packet->IsExtensionReserved<AbsoluteSendTime>());
2310 EXPECT_TRUE(padding_packet->IsExtensionReserved<TransmissionOffset>());
2311
2312 // Verify all header extensions are received.
2313 EXPECT_TRUE(
2314 rtp_sender_->TrySendPacket(padding_packet.get(), PacedPacketInfo()));
2315 webrtc::RTPHeader rtp_header;
2316 transport_.last_sent_packet().GetHeader(&rtp_header);
2317 EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
2318 EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
2319 EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
Erik Språng478cb462019-06-26 15:49:27 +02002320
2321 // Not enough budged for payload padding, use plain padding instead.
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002322 const size_t kPaddingBytesRequested = kMinPaddingSize - 1;
Erik Språngf6468d22019-07-05 16:53:43 +02002323
2324 size_t padding_bytes_generated = 0;
2325 generated_packets = rtp_sender_->GeneratePadding(kPaddingBytesRequested);
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002326 EXPECT_EQ(generated_packets.size(), 1u);
Erik Språngf6468d22019-07-05 16:53:43 +02002327 for (auto& packet : generated_packets) {
2328 EXPECT_EQ(packet->packet_type(), RtpPacketToSend::Type::kPadding);
2329 EXPECT_EQ(packet->Ssrc(), kRtxSsrc);
2330 EXPECT_EQ(packet->payload_size(), 0u);
2331 EXPECT_GT(packet->padding_size(), 0u);
2332 padding_bytes_generated += packet->padding_size();
Erik Språng0f6191d2019-07-15 20:33:40 +02002333
2334 EXPECT_TRUE(packet->IsExtensionReserved<TransportSequenceNumber>());
2335 EXPECT_TRUE(packet->IsExtensionReserved<AbsoluteSendTime>());
2336 EXPECT_TRUE(packet->IsExtensionReserved<TransmissionOffset>());
2337
2338 // Verify all header extensions are received.
2339 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2340 webrtc::RTPHeader rtp_header;
2341 transport_.last_sent_packet().GetHeader(&rtp_header);
2342 EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
2343 EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
2344 EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
Erik Språngf6468d22019-07-05 16:53:43 +02002345 }
2346
Mirko Bonadeia7e3bce2019-07-12 17:35:56 +00002347 EXPECT_EQ(padding_bytes_generated, kMaxPaddingSize);
Erik Språng478cb462019-06-26 15:49:27 +02002348}
2349
2350TEST_P(RtpSenderTest, GeneratePaddingCreatesPurePaddingWithoutRtx) {
2351 rtp_sender_->SetStorePacketsStatus(true, 1);
Erik Språng0f6191d2019-07-15 20:33:40 +02002352 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2353 kRtpExtensionTransmissionTimeOffset,
2354 kTransmissionTimeOffsetExtensionId));
2355 ASSERT_EQ(
2356 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
2357 kAbsoluteSendTimeExtensionId));
2358 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2359 kRtpExtensionTransportSequenceNumber,
2360 kTransportSequenceNumberExtensionId));
Erik Språng478cb462019-06-26 15:49:27 +02002361
2362 const size_t kPayloadPacketSize = 1234;
2363 // Send a dummy video packet so it ends up in the packet history. Since we
2364 // are not using RTX, it should never be used as padding.
2365 std::unique_ptr<RtpPacketToSend> packet =
2366 BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
2367 packet->set_allow_retransmission(true);
2368 packet->SetPayloadSize(kPayloadPacketSize);
2369 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
Erik Språng0f6191d2019-07-15 20:33:40 +02002370 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
Erik Språng478cb462019-06-26 15:49:27 +02002371 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2372
2373 // Payload padding not available without RTX, only generate plain padding on
2374 // the media SSRC.
2375 // Number of padding packets is the requested padding size divided by max
2376 // padding packet size, rounded up. Pure padding packets are always of the
2377 // maximum size.
2378 const size_t kPaddingBytesRequested = kPayloadPacketSize + kRtxHeaderSize;
2379 const size_t kExpectedNumPaddingPackets =
2380 (kPaddingBytesRequested + kMaxPaddingSize - 1) / kMaxPaddingSize;
Erik Språngf6468d22019-07-05 16:53:43 +02002381 size_t padding_bytes_generated = 0;
2382 std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets =
2383 rtp_sender_->GeneratePadding(kPaddingBytesRequested);
2384 EXPECT_EQ(padding_packets.size(), kExpectedNumPaddingPackets);
2385 for (auto& packet : padding_packets) {
2386 EXPECT_EQ(packet->packet_type(), RtpPacketToSend::Type::kPadding);
2387 EXPECT_EQ(packet->Ssrc(), kSsrc);
2388 EXPECT_EQ(packet->payload_size(), 0u);
2389 EXPECT_GT(packet->padding_size(), 0u);
2390 padding_bytes_generated += packet->padding_size();
Erik Språng0f6191d2019-07-15 20:33:40 +02002391 EXPECT_TRUE(packet->IsExtensionReserved<TransportSequenceNumber>());
2392 EXPECT_TRUE(packet->IsExtensionReserved<AbsoluteSendTime>());
2393 EXPECT_TRUE(packet->IsExtensionReserved<TransmissionOffset>());
2394
2395 // Verify all header extensions are received.
2396 EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
2397 webrtc::RTPHeader rtp_header;
2398 transport_.last_sent_packet().GetHeader(&rtp_header);
2399 EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
2400 EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
2401 EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
Erik Språngf6468d22019-07-05 16:53:43 +02002402 }
2403
2404 EXPECT_EQ(padding_bytes_generated,
2405 kExpectedNumPaddingPackets * kMaxPaddingSize);
Erik Språng478cb462019-06-26 15:49:27 +02002406}
2407
Mirko Bonadei999a72a2019-07-12 17:33:46 +00002408TEST_P(RtpSenderTest, SupportsPadding) {
2409 bool kSendingMediaStats[] = {true, false};
2410 bool kEnableRedundantPayloads[] = {true, false};
2411 RTPExtensionType kBweExtensionTypes[] = {
2412 kRtpExtensionTransportSequenceNumber,
2413 kRtpExtensionTransportSequenceNumber02, kRtpExtensionAbsoluteSendTime,
2414 kRtpExtensionTransmissionTimeOffset};
2415 const int kExtensionsId = 7;
2416
2417 for (bool sending_media : kSendingMediaStats) {
2418 rtp_sender_->SetSendingMediaStatus(sending_media);
2419 for (bool redundant_payloads : kEnableRedundantPayloads) {
2420 int rtx_mode = kRtxRetransmitted;
2421 if (redundant_payloads) {
2422 rtx_mode |= kRtxRedundantPayloads;
2423 }
2424 rtp_sender_->SetRtxStatus(rtx_mode);
2425
2426 for (auto extension_type : kBweExtensionTypes) {
2427 EXPECT_FALSE(rtp_sender_->SupportsPadding());
2428 rtp_sender_->RegisterRtpHeaderExtension(extension_type, kExtensionsId);
2429 if (!sending_media) {
2430 EXPECT_FALSE(rtp_sender_->SupportsPadding());
2431 } else {
2432 EXPECT_TRUE(rtp_sender_->SupportsPadding());
2433 if (redundant_payloads) {
2434 EXPECT_TRUE(rtp_sender_->SupportsRtxPayloadPadding());
2435 } else {
2436 EXPECT_FALSE(rtp_sender_->SupportsRtxPayloadPadding());
2437 }
2438 }
2439 rtp_sender_->DeregisterRtpHeaderExtension(extension_type);
2440 EXPECT_FALSE(rtp_sender_->SupportsPadding());
2441 }
2442 }
2443 }
2444}
2445
Erik Språnga57711c2019-07-24 10:47:20 +02002446TEST_P(RtpSenderTest, SetsCaptureTimeAndPopulatesTransmissionOffset) {
2447 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
2448 kTransmissionTimeOffsetExtensionId);
2449
2450 rtp_sender_->SetSendingMediaStatus(true);
2451 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2452 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2453 rtp_sender_->SetStorePacketsStatus(true, 10);
2454
2455 const int64_t kMissingCaptureTimeMs = 0;
2456 const uint32_t kTimestampTicksPerMs = 90;
2457 const int64_t kOffsetMs = 10;
2458
Erik Språnga57711c2019-07-24 10:47:20 +02002459 auto packet =
2460 BuildRtpPacket(kPayload, kMarkerBit, fake_clock_.TimeInMilliseconds(),
2461 kMissingCaptureTimeMs);
2462 packet->set_packet_type(RtpPacketToSend::Type::kVideo);
2463 packet->ReserveExtension<TransmissionOffset>();
2464 packet->AllocatePayload(sizeof(kPayloadData));
2465
2466 std::unique_ptr<RtpPacketToSend> packet_to_pace;
2467 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
2468 .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
2469 EXPECT_GT(packet->capture_time_ms(), 0);
2470 packet_to_pace = std::move(packet);
2471 });
2472
Erik Språng70768f42019-08-27 18:16:26 +02002473 packet->set_allow_retransmission(true);
2474 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet)));
Erik Språnga57711c2019-07-24 10:47:20 +02002475
2476 fake_clock_.AdvanceTimeMilliseconds(kOffsetMs);
2477
2478 rtp_sender_->TrySendPacket(packet_to_pace.get(), PacedPacketInfo());
Erik Språnga57711c2019-07-24 10:47:20 +02002479
2480 EXPECT_EQ(1, transport_.packets_sent());
2481 absl::optional<int32_t> transmission_time_extension =
2482 transport_.sent_packets_.back().GetExtension<TransmissionOffset>();
2483 ASSERT_TRUE(transmission_time_extension.has_value());
2484 EXPECT_EQ(*transmission_time_extension, kOffsetMs * kTimestampTicksPerMs);
2485
2486 // Retransmit packet. The RTX packet should get the same capture time as the
2487 // original packet, so offset is delta from original packet to now.
2488 fake_clock_.AdvanceTimeMilliseconds(kOffsetMs);
2489
Erik Språnga57711c2019-07-24 10:47:20 +02002490 std::unique_ptr<RtpPacketToSend> rtx_packet_to_pace;
2491 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
2492 .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
2493 EXPECT_GT(packet->capture_time_ms(), 0);
2494 rtx_packet_to_pace = std::move(packet);
2495 });
2496
2497 EXPECT_GT(rtp_sender_->ReSendPacket(kSeqNum), 0);
2498 rtp_sender_->TrySendPacket(rtx_packet_to_pace.get(), PacedPacketInfo());
Erik Språnga57711c2019-07-24 10:47:20 +02002499
2500 EXPECT_EQ(2, transport_.packets_sent());
2501 transmission_time_extension =
2502 transport_.sent_packets_.back().GetExtension<TransmissionOffset>();
2503 ASSERT_TRUE(transmission_time_extension.has_value());
2504 EXPECT_EQ(*transmission_time_extension, 2 * kOffsetMs * kTimestampTicksPerMs);
2505}
2506
Erik Språng6cacef22019-07-24 14:15:51 +02002507TEST_P(RtpSenderTestWithoutPacer, ClearHistoryOnSsrcChange) {
2508 const int64_t kRtt = 10;
2509
2510 rtp_sender_->SetSendingMediaStatus(true);
2511 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2512 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2513 rtp_sender_->SetStorePacketsStatus(true, 10);
2514 rtp_sender_->SetRtt(kRtt);
Erik Språng6cacef22019-07-24 14:15:51 +02002515
2516 // Send a packet and record its sequence numbers.
2517 SendGenericPacket();
2518 ASSERT_EQ(1u, transport_.sent_packets_.size());
2519 const uint16_t packet_seqence_number =
2520 transport_.sent_packets_.back().SequenceNumber();
2521
2522 // Advance time and make sure it can be retransmitted, even if we try to set
2523 // the ssrc the what it already is.
2524 rtp_sender_->SetSSRC(kSsrc);
2525 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2526 EXPECT_GT(rtp_sender_->ReSendPacket(packet_seqence_number), 0);
2527
2528 // Change the SSRC, then move the time and try to retransmit again. The old
2529 // packet should now be gone.
2530 rtp_sender_->SetSSRC(kSsrc + 1);
2531 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2532 EXPECT_EQ(rtp_sender_->ReSendPacket(packet_seqence_number), 0);
2533}
2534
2535TEST_P(RtpSenderTestWithoutPacer, ClearHistoryOnSequenceNumberCange) {
2536 const int64_t kRtt = 10;
2537
2538 rtp_sender_->SetSendingMediaStatus(true);
2539 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2540 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2541 rtp_sender_->SetStorePacketsStatus(true, 10);
2542 rtp_sender_->SetRtt(kRtt);
2543
2544 // Send a packet and record its sequence numbers.
2545 SendGenericPacket();
2546 ASSERT_EQ(1u, transport_.sent_packets_.size());
2547 const uint16_t packet_seqence_number =
2548 transport_.sent_packets_.back().SequenceNumber();
2549
2550 // Advance time and make sure it can be retransmitted, even if we try to set
2551 // the ssrc the what it already is.
2552 rtp_sender_->SetSequenceNumber(rtp_sender_->SequenceNumber());
2553 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2554 EXPECT_GT(rtp_sender_->ReSendPacket(packet_seqence_number), 0);
2555
2556 // Change the sequence number, then move the time and try to retransmit again.
2557 // The old packet should now be gone.
2558 rtp_sender_->SetSequenceNumber(rtp_sender_->SequenceNumber() - 1);
2559 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2560 EXPECT_EQ(rtp_sender_->ReSendPacket(packet_seqence_number), 0);
2561}
2562
Erik Språng60ffc312019-07-30 22:03:49 +02002563TEST_P(RtpSenderTest, IgnoresNackAfterDisablingMedia) {
2564 const int64_t kRtt = 10;
2565
2566 rtp_sender_->SetSendingMediaStatus(true);
2567 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
2568 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
2569 rtp_sender_->SetStorePacketsStatus(true, 10);
2570 rtp_sender_->SetRtt(kRtt);
2571
2572 // Send a packet so it is in the packet history.
Erik Språng60ffc312019-07-30 22:03:49 +02002573 std::unique_ptr<RtpPacketToSend> packet_to_pace;
2574 EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
2575 .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
2576 packet_to_pace = std::move(packet);
2577 });
2578
2579 SendGenericPacket();
2580 rtp_sender_->TrySendPacket(packet_to_pace.get(), PacedPacketInfo());
2581
2582 ASSERT_EQ(1u, transport_.sent_packets_.size());
2583
2584 // Disable media sending and try to retransmit the packet, it should fail.
2585 rtp_sender_->SetSendingMediaStatus(false);
2586 fake_clock_.AdvanceTimeMilliseconds(kRtt);
2587 EXPECT_LT(rtp_sender_->ReSendPacket(kSeqNum), 0);
Erik Språng60ffc312019-07-30 22:03:49 +02002588}
2589
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002590INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2591 RtpSenderTest,
Erik Språngf5815fa2019-08-21 14:27:31 +02002592 ::testing::Values(TestConfig{false},
2593 TestConfig{true}));
Erik Språngf6468d22019-07-05 16:53:43 +02002594
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002595INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2596 RtpSenderTestWithoutPacer,
Erik Språngf5815fa2019-08-21 14:27:31 +02002597 ::testing::Values(TestConfig{false},
2598 TestConfig{true}));
Niels Möllera34d7762019-02-01 14:13:29 +01002599
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +00002600} // namespace webrtc