blob: c421cf96fec401575a18351608d77d362dad3427 [file] [log] [blame]
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001/*
phoglund@webrtc.org78088c22012-02-07 14:56:45 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kwiberg84be5112016-04-27 01:19:58 -070011#include <memory>
danilchapb8b6fbb2015-12-10 05:05:27 -080012#include <vector>
13
Karl Wiberg918f50c2018-07-05 11:40:33 +020014#include "absl/memory/memory.h"
Erik Språngf93eda12019-01-16 17:10:57 +010015#include "api/video/video_codec_constants.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "api/video/video_timing.h"
Elad Alon4a87e1c2017-10-03 16:11:34 +020017#include "logging/rtc_event_log/events/rtc_event.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
19#include "modules/rtp_rtcp/include/rtp_cvo.h"
20#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
21#include "modules/rtp_rtcp/include/rtp_header_parser.h"
22#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
23#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
24#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
philipelb3e42a42018-09-13 10:57:14 +020025#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
26#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
28#include "modules/rtp_rtcp/source/rtp_packet_received.h"
29#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
30#include "modules/rtp_rtcp/source/rtp_sender.h"
31#include "modules/rtp_rtcp/source/rtp_sender_video.h"
32#include "modules/rtp_rtcp/source/rtp_utility.h"
33#include "rtc_base/arraysize.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/rate_limiter.h"
35#include "test/field_trial.h"
36#include "test/gmock.h"
37#include "test/gtest.h"
38#include "test/mock_transport.h"
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000039
40namespace webrtc {
41
andrew@webrtc.org8a442592011-12-16 21:24:30 +000042namespace {
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +000043const int kTransmissionTimeOffsetExtensionId = 1;
44const int kAbsoluteSendTimeExtensionId = 14;
sprang@webrtc.org30933902015-03-17 14:33:12 +000045const int kTransportSequenceNumberExtensionId = 13;
ilnik04f4d122017-06-19 07:18:55 -070046const int kVideoTimingExtensionId = 12;
Steve Anton296a0ce2018-03-22 15:17:27 -070047const int kMidExtensionId = 11;
Amit Hilbuch77938e62018-12-21 09:23:38 -080048const int kGenericDescriptorId = 10;
49const int kAudioLevelExtensionId = 9;
50const int kRidExtensionId = 8;
51const int kRepairedRidExtensionId = 7;
52const int kVideoRotationExtensionId = 5;
andrew@webrtc.org8a442592011-12-16 21:24:30 +000053const int kPayload = 100;
Shao Changbine62202f2015-04-21 20:24:50 +080054const int kRtxPayload = 98;
andrew@webrtc.org8a442592011-12-16 21:24:30 +000055const uint32_t kTimestamp = 10;
56const uint16_t kSeqNum = 33;
brandtr9dfff292016-11-14 05:14:50 -080057const uint32_t kSsrc = 725242;
andrew@webrtc.org8a442592011-12-16 21:24:30 +000058const int kMaxPacketLength = 1500;
sprang@webrtc.org30933902015-03-17 14:33:12 +000059const uint16_t kTransportSequenceNumber = 0xaabbu;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +000060const uint64_t kStartTime = 123456789;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +000061const size_t kMaxPaddingSize = 224u;
Stefan Holmera246cfb2016-08-23 17:51:42 +020062const size_t kGenericHeaderLength = 1;
63const uint8_t kPayloadData[] = {47, 11, 32, 93, 89};
spranga8ae6f22017-09-04 07:23:56 -070064const int64_t kDefaultExpectedRetransmissionTimeMs = 125;
Amit Hilbuch77938e62018-12-21 09:23:38 -080065const char kNoRid[] = "";
66const char kNoMid[] = "";
andrew@webrtc.org8a442592011-12-16 21:24:30 +000067
Danil Chapovalov5e57b172016-09-02 19:15:59 +020068using ::testing::_;
philipelb3e42a42018-09-13 10:57:14 +020069using ::testing::ElementsAre;
Danil Chapovalov5e57b172016-09-02 19:15:59 +020070using ::testing::ElementsAreArray;
sprang168794c2017-07-06 04:38:06 -070071using ::testing::Invoke;
Danil Chapovalov84ffb352018-09-25 18:59:09 +020072using ::testing::SizeIs;
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +000073
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +000074uint64_t ConvertMsToAbsSendTime(int64_t time_ms) {
Stefan Holmer0a87ffc2015-10-21 13:41:48 +020075 return (((time_ms << 18) + 500) / 1000) & 0x00ffffff;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +000076}
77
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +000078class LoopbackTransportTest : public webrtc::Transport {
79 public:
Petter Strandmark26bc6692018-05-29 08:43:35 +020080 LoopbackTransportTest() : total_bytes_sent_(0) {
danilchap12ba1862016-10-26 02:41:55 -070081 receivers_extensions_.Register(kRtpExtensionTransmissionTimeOffset,
82 kTransmissionTimeOffsetExtensionId);
83 receivers_extensions_.Register(kRtpExtensionAbsoluteSendTime,
84 kAbsoluteSendTimeExtensionId);
85 receivers_extensions_.Register(kRtpExtensionTransportSequenceNumber,
86 kTransportSequenceNumberExtensionId);
87 receivers_extensions_.Register(kRtpExtensionVideoRotation,
88 kVideoRotationExtensionId);
89 receivers_extensions_.Register(kRtpExtensionAudioLevel,
90 kAudioLevelExtensionId);
ilnik04f4d122017-06-19 07:18:55 -070091 receivers_extensions_.Register(kRtpExtensionVideoTiming,
92 kVideoTimingExtensionId);
Steve Anton296a0ce2018-03-22 15:17:27 -070093 receivers_extensions_.Register(kRtpExtensionMid, kMidExtensionId);
philipelb3e42a42018-09-13 10:57:14 +020094 receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor,
95 kGenericDescriptorId);
Amit Hilbuch77938e62018-12-21 09:23:38 -080096 receivers_extensions_.Register(kRtpExtensionRtpStreamId, kRidExtensionId);
97 receivers_extensions_.Register(kRtpExtensionRepairedRtpStreamId,
98 kRepairedRidExtensionId);
guoweis@webrtc.org45362892015-03-04 22:55:15 +000099 }
danilchap12ba1862016-10-26 02:41:55 -0700100
stefan1d8a5062015-10-02 03:39:33 -0700101 bool SendRtp(const uint8_t* data,
102 size_t len,
103 const PacketOptions& options) override {
Petter Strandmark26bc6692018-05-29 08:43:35 +0200104 last_options_ = options;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000105 total_bytes_sent_ += len;
danilchap12ba1862016-10-26 02:41:55 -0700106 sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
107 EXPECT_TRUE(sent_packets_.back().Parse(data, len));
pbos2d566682015-09-28 09:59:31 -0700108 return true;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000109 }
danilchap162abd32015-12-10 02:39:40 -0800110 bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
danilchap12ba1862016-10-26 02:41:55 -0700111 const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
112 int packets_sent() { return sent_packets_.size(); }
113
pbos@webrtc.org72491b92014-07-10 16:24:54 +0000114 size_t total_bytes_sent_;
Petter Strandmark26bc6692018-05-29 08:43:35 +0200115 PacketOptions last_options_;
danilchap12ba1862016-10-26 02:41:55 -0700116 std::vector<RtpPacketReceived> sent_packets_;
117
118 private:
119 RtpHeaderExtensionMap receivers_extensions_;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000120};
121
Elad Alon4a87e1c2017-10-03 16:11:34 +0200122MATCHER_P(SameRtcEventTypeAs, value, "") {
123 return value == arg->GetType();
124}
125
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000126} // namespace
127
sprangebbf8a82015-09-21 15:11:14 -0700128class MockRtpPacketSender : public RtpPacketSender {
129 public:
130 MockRtpPacketSender() {}
131 virtual ~MockRtpPacketSender() {}
132
Peter Boströme23e7372015-10-08 11:44:14 +0200133 MOCK_METHOD6(InsertPacket,
134 void(Priority priority,
sprangebbf8a82015-09-21 15:11:14 -0700135 uint32_t ssrc,
136 uint16_t sequence_number,
137 int64_t capture_time_ms,
138 size_t bytes,
139 bool retransmission));
140};
141
Stefan Holmerf5dca482016-01-27 12:58:51 +0100142class MockTransportSequenceNumberAllocator
143 : public TransportSequenceNumberAllocator {
144 public:
145 MOCK_METHOD0(AllocateSequenceNumber, uint16_t());
146};
147
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200148class MockSendSideDelayObserver : public SendSideDelayObserver {
149 public:
150 MOCK_METHOD3(SendSideDelayUpdated, void(int, int, uint32_t));
151};
152
asapersson35151f32016-05-02 23:44:01 -0700153class MockSendPacketObserver : public SendPacketObserver {
154 public:
155 MOCK_METHOD3(OnSendPacket, void(uint16_t, int64_t, uint32_t));
156};
157
Stefan Holmera246cfb2016-08-23 17:51:42 +0200158class MockTransportFeedbackObserver : public TransportFeedbackObserver {
159 public:
elad.alond12a8e12017-03-23 11:04:48 -0700160 MOCK_METHOD4(AddPacket,
161 void(uint32_t, uint16_t, size_t, const PacedPacketInfo&));
Stefan Holmera246cfb2016-08-23 17:51:42 +0200162 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -0800163 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
Stefan Holmera246cfb2016-08-23 17:51:42 +0200164};
165
minyue3a407ee2017-04-03 01:10:33 -0700166class MockOverheadObserver : public OverheadObserver {
167 public:
168 MOCK_METHOD1(OnOverheadChanged, void(size_t overhead_bytes_per_packet));
169};
170
171class RtpSenderTest : public ::testing::TestWithParam<bool> {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000172 protected:
173 RtpSenderTest()
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000174 : fake_clock_(kStartTime),
terelius429c3452016-01-21 05:42:04 -0800175 mock_rtc_event_log_(),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000176 mock_paced_sender_(),
sprangcd349d92016-07-13 09:11:28 -0700177 retransmission_rate_limiter_(&fake_clock_, 1000),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000178 rtp_sender_(),
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +0000179 transport_(),
minyue3a407ee2017-04-03 01:10:33 -0700180 kMarkerBit(true),
181 field_trials_(GetParam() ? "WebRTC-SendSideBwe-WithOverhead/Enabled/"
182 : "") {}
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +0000183
Erik Språng7b52f102018-02-07 14:37:37 +0100184 void SetUp() override { SetUpRtpSender(true, false); }
Peter Boströme23e7372015-10-08 11:44:14 +0200185
Erik Språng7b52f102018-02-07 14:37:37 +0100186 void SetUpRtpSender(bool pacer, bool populate_network2) {
asapersson35151f32016-05-02 23:44:01 -0700187 rtp_sender_.reset(new RTPSender(
188 false, &fake_clock_, &transport_, pacer ? &mock_paced_sender_ : nullptr,
Niels Möller949f0fd2019-01-29 09:44:24 +0100189 nullptr, &seq_num_allocator_, nullptr, nullptr, nullptr,
sprangcd349d92016-07-13 09:11:28 -0700190 &mock_rtc_event_log_, &send_packet_observer_,
Benjamin Wright192eeec2018-10-17 17:27:25 -0700191 &retransmission_rate_limiter_, nullptr, populate_network2, nullptr,
Johannes Kron9190b822018-10-29 11:22:05 +0100192 false, false));
brandtr9dfff292016-11-14 05:14:50 -0800193 rtp_sender_->SetSequenceNumber(kSeqNum);
danilchap71fead22016-08-18 02:01:49 -0700194 rtp_sender_->SetTimestampOffset(0);
brandtr9dfff292016-11-14 05:14:50 -0800195 rtp_sender_->SetSSRC(kSsrc);
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +0000196 }
197
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000198 SimulatedClock fake_clock_;
stefana23fc622016-07-28 07:56:38 -0700199 testing::NiceMock<MockRtcEventLog> mock_rtc_event_log_;
sprangebbf8a82015-09-21 15:11:14 -0700200 MockRtpPacketSender mock_paced_sender_;
stefana23fc622016-07-28 07:56:38 -0700201 testing::StrictMock<MockTransportSequenceNumberAllocator> seq_num_allocator_;
202 testing::StrictMock<MockSendPacketObserver> send_packet_observer_;
Stefan Holmera246cfb2016-08-23 17:51:42 +0200203 testing::StrictMock<MockTransportFeedbackObserver> feedback_observer_;
sprangcd349d92016-07-13 09:11:28 -0700204 RateLimiter retransmission_rate_limiter_;
kwiberg84be5112016-04-27 01:19:58 -0700205 std::unique_ptr<RTPSender> rtp_sender_;
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000206 LoopbackTransportTest transport_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000207 const bool kMarkerBit;
minyue3a407ee2017-04-03 01:10:33 -0700208 test::ScopedFieldTrials field_trials_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000209
danilchapb6f1fb52016-10-19 06:11:39 -0700210 std::unique_ptr<RtpPacketToSend> BuildRtpPacket(int payload_type,
211 bool marker_bit,
212 uint32_t timestamp,
213 int64_t capture_time_ms) {
214 auto packet = rtp_sender_->AllocatePacket();
215 packet->SetPayloadType(payload_type);
216 packet->SetMarker(marker_bit);
217 packet->SetTimestamp(timestamp);
218 packet->set_capture_time_ms(capture_time_ms);
219 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
220 return packet;
221 }
222
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000223 void SendPacket(int64_t capture_time_ms, int payload_length) {
224 uint32_t timestamp = capture_time_ms * 90;
danilchapb6f1fb52016-10-19 06:11:39 -0700225 auto packet =
226 BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
227 packet->AllocatePayload(payload_length);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000228
229 // Packet should be stored in a send bucket.
danilchapb6f1fb52016-10-19 06:11:39 -0700230 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
231 kAllowRetransmission,
232 RtpPacketSender::kNormalPriority));
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000233 }
asapersson35151f32016-05-02 23:44:01 -0700234
235 void SendGenericPayload() {
asapersson35151f32016-05-02 23:44:01 -0700236 const uint32_t kTimestamp = 1234;
237 const uint8_t kPayloadType = 127;
238 const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
Niels Möller8a40edd2019-01-24 18:04:44 +0100239 const char payload_name[] = "GENERIC";
asapersson35151f32016-05-02 23:44:01 -0700240 EXPECT_EQ(0, rtp_sender_->RegisterPayload(payload_name, kPayloadType, 90000,
241 0, 1500));
242
Sami Kalliomäki426a80c2018-08-08 11:37:59 +0200243 RTPVideoHeader video_header;
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700244 EXPECT_TRUE(rtp_sender_->SendOutgoingData(
Stefan Holmera246cfb2016-08-23 17:51:42 +0200245 kVideoFrameKey, kPayloadType, kTimestamp, kCaptureTimeMs, kPayloadData,
Sami Kalliomäki426a80c2018-08-08 11:37:59 +0200246 sizeof(kPayloadData), nullptr, &video_header, nullptr,
spranga8ae6f22017-09-04 07:23:56 -0700247 kDefaultExpectedRetransmissionTimeMs));
asapersson35151f32016-05-02 23:44:01 -0700248 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000249};
250
Peter Boströme23e7372015-10-08 11:44:14 +0200251// TODO(pbos): Move tests over from WithoutPacer to RtpSenderTest as this is our
252// default code path.
253class RtpSenderTestWithoutPacer : public RtpSenderTest {
254 public:
Erik Språng7b52f102018-02-07 14:37:37 +0100255 void SetUp() override { SetUpRtpSender(false, false); }
Peter Boströme23e7372015-10-08 11:44:14 +0200256};
257
spranga8ae6f22017-09-04 07:23:56 -0700258class TestRtpSenderVideo : public RTPSenderVideo {
259 public:
260 TestRtpSenderVideo(Clock* clock,
261 RTPSender* rtp_sender,
262 FlexfecSender* flexfec_sender)
Benjamin Wright192eeec2018-10-17 17:27:25 -0700263 : RTPSenderVideo(clock, rtp_sender, flexfec_sender, nullptr, false) {}
spranga8ae6f22017-09-04 07:23:56 -0700264 ~TestRtpSenderVideo() override {}
265
266 StorageType GetStorageType(const RTPVideoHeader& header,
267 int32_t retransmission_settings,
268 int64_t expected_retransmission_time_ms) {
269 return RTPSenderVideo::GetStorageType(GetTemporalId(header),
270 retransmission_settings,
271 expected_retransmission_time_ms);
272 }
273};
274
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000275class RtpSenderVideoTest : public RtpSenderTest {
276 protected:
danilchap162abd32015-12-10 02:39:40 -0800277 void SetUp() override {
Peter Boströme23e7372015-10-08 11:44:14 +0200278 // TODO(pbos): Set up to use pacer.
Erik Språng7b52f102018-02-07 14:37:37 +0100279 SetUpRtpSender(false, false);
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000280 rtp_sender_video_.reset(
spranga8ae6f22017-09-04 07:23:56 -0700281 new TestRtpSenderVideo(&fake_clock_, rtp_sender_.get(), nullptr));
Niels Möller3ea55d52019-01-24 09:44:14 +0100282 rtp_sender_video_->RegisterPayloadType(kPayload, "generic");
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000283 }
spranga8ae6f22017-09-04 07:23:56 -0700284 std::unique_ptr<TestRtpSenderVideo> rtp_sender_video_;
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000285};
286
minyue3a407ee2017-04-03 01:10:33 -0700287TEST_P(RtpSenderTestWithoutPacer, AllocatePacketSetCsrc) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200288 // Configure rtp_sender with csrc.
289 std::vector<uint32_t> csrcs;
290 csrcs.push_back(0x23456789);
291 rtp_sender_->SetCsrcs(csrcs);
292
293 auto packet = rtp_sender_->AllocatePacket();
294
295 ASSERT_TRUE(packet);
296 EXPECT_EQ(rtp_sender_->SSRC(), packet->Ssrc());
297 EXPECT_EQ(csrcs, packet->Csrcs());
298}
299
minyue3a407ee2017-04-03 01:10:33 -0700300TEST_P(RtpSenderTestWithoutPacer, AllocatePacketReserveExtensions) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200301 // Configure rtp_sender with extensions.
302 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
303 kRtpExtensionTransmissionTimeOffset,
304 kTransmissionTimeOffsetExtensionId));
305 ASSERT_EQ(
306 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
307 kAbsoluteSendTimeExtensionId));
308 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
309 kAudioLevelExtensionId));
310 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
311 kRtpExtensionTransportSequenceNumber,
312 kTransportSequenceNumberExtensionId));
313 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
314 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
315
316 auto packet = rtp_sender_->AllocatePacket();
317
318 ASSERT_TRUE(packet);
319 // Preallocate BWE extensions RtpSender set itself.
320 EXPECT_TRUE(packet->HasExtension<TransmissionOffset>());
321 EXPECT_TRUE(packet->HasExtension<AbsoluteSendTime>());
322 EXPECT_TRUE(packet->HasExtension<TransportSequenceNumber>());
323 // Do not allocate media specific extensions.
324 EXPECT_FALSE(packet->HasExtension<AudioLevel>());
325 EXPECT_FALSE(packet->HasExtension<VideoOrientation>());
326}
327
minyue3a407ee2017-04-03 01:10:33 -0700328TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberAdvanceSequenceNumber) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200329 auto packet = rtp_sender_->AllocatePacket();
330 ASSERT_TRUE(packet);
331 const uint16_t sequence_number = rtp_sender_->SequenceNumber();
332
333 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
334
335 EXPECT_EQ(sequence_number, packet->SequenceNumber());
336 EXPECT_EQ(sequence_number + 1, rtp_sender_->SequenceNumber());
337}
338
minyue3a407ee2017-04-03 01:10:33 -0700339TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberFailsOnNotSending) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200340 auto packet = rtp_sender_->AllocatePacket();
341 ASSERT_TRUE(packet);
342
343 rtp_sender_->SetSendingMediaStatus(false);
344 EXPECT_FALSE(rtp_sender_->AssignSequenceNumber(packet.get()));
345}
346
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100347TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberMayAllowPaddingOnVideo) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200348 constexpr size_t kPaddingSize = 100;
349 auto packet = rtp_sender_->AllocatePacket();
350 ASSERT_TRUE(packet);
351
philipel8aadd502017-02-23 02:56:13 -0800352 ASSERT_FALSE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200353 packet->SetMarker(false);
354 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100355 // Packet without marker bit doesn't allow padding on video stream.
philipel8aadd502017-02-23 02:56:13 -0800356 EXPECT_FALSE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200357
358 packet->SetMarker(true);
359 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
360 // Packet with marker bit allows send padding.
philipel8aadd502017-02-23 02:56:13 -0800361 EXPECT_TRUE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200362}
363
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100364TEST_P(RtpSenderTest, AssignSequenceNumberAllowsPaddingOnAudio) {
365 MockTransport transport;
366 const bool kEnableAudio = true;
367 rtp_sender_.reset(new RTPSender(
368 kEnableAudio, &fake_clock_, &transport, &mock_paced_sender_, nullptr,
Niels Möller949f0fd2019-01-29 09:44:24 +0100369 nullptr, nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr,
370 &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100371 rtp_sender_->SetTimestampOffset(0);
372 rtp_sender_->SetSSRC(kSsrc);
373
374 std::unique_ptr<RtpPacketToSend> audio_packet = rtp_sender_->AllocatePacket();
375 // Padding on audio stream allowed regardless of marker in the last packet.
376 audio_packet->SetMarker(false);
377 audio_packet->SetPayloadType(kPayload);
378 rtp_sender_->AssignSequenceNumber(audio_packet.get());
379
380 const size_t kPaddingSize = 59;
381 EXPECT_CALL(transport, SendRtp(_, kPaddingSize + kRtpHeaderSize, _))
382 .WillOnce(testing::Return(true));
383 EXPECT_EQ(kPaddingSize,
384 rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
385
386 // Requested padding size is too small, will send a larger one.
387 const size_t kMinPaddingSize = 50;
388 EXPECT_CALL(transport, SendRtp(_, kMinPaddingSize + kRtpHeaderSize, _))
389 .WillOnce(testing::Return(true));
Yves Gerey665174f2018-06-19 15:03:05 +0200390 EXPECT_EQ(kMinPaddingSize, rtp_sender_->TimeToSendPadding(kMinPaddingSize - 5,
391 PacedPacketInfo()));
Danil Chapovalovb3179c72018-03-22 10:13:07 +0100392}
393
minyue3a407ee2017-04-03 01:10:33 -0700394TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberSetPaddingTimestamps) {
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200395 constexpr size_t kPaddingSize = 100;
396 auto packet = rtp_sender_->AllocatePacket();
397 ASSERT_TRUE(packet);
398 packet->SetMarker(true);
399 packet->SetTimestamp(kTimestamp);
400
401 ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
philipel8aadd502017-02-23 02:56:13 -0800402 ASSERT_TRUE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200403
404 ASSERT_EQ(1u, transport_.sent_packets_.size());
danilchap12ba1862016-10-26 02:41:55 -0700405 // Verify padding packet timestamp.
406 EXPECT_EQ(kTimestamp, transport_.last_sent_packet().Timestamp());
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200407}
408
minyue3a407ee2017-04-03 01:10:33 -0700409TEST_P(RtpSenderTestWithoutPacer,
410 TransportFeedbackObserverGetsCorrectByteCount) {
411 constexpr int kRtpOverheadBytesPerPacket = 12 + 8;
412 testing::NiceMock<MockOverheadObserver> mock_overhead_observer;
413 rtp_sender_.reset(new RTPSender(
414 false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
Niels Möller949f0fd2019-01-29 09:44:24 +0100415 &feedback_observer_, nullptr, nullptr, &mock_rtc_event_log_, nullptr,
416 &retransmission_rate_limiter_, &mock_overhead_observer, false, nullptr,
417 false, false));
minyue3a407ee2017-04-03 01:10:33 -0700418 rtp_sender_->SetSSRC(kSsrc);
419 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
420 kRtpExtensionTransportSequenceNumber,
421 kTransportSequenceNumberExtensionId));
422 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
423 .WillOnce(testing::Return(kTransportSequenceNumber));
424
425 const size_t expected_bytes =
426 GetParam() ? sizeof(kPayloadData) + kGenericHeaderLength +
427 kRtpOverheadBytesPerPacket
428 : sizeof(kPayloadData) + kGenericHeaderLength;
429
430 EXPECT_CALL(feedback_observer_,
431 AddPacket(rtp_sender_->SSRC(), kTransportSequenceNumber,
432 expected_bytes, PacedPacketInfo()))
433 .Times(1);
434 EXPECT_CALL(mock_overhead_observer,
435 OnOverheadChanged(kRtpOverheadBytesPerPacket))
436 .Times(1);
437 SendGenericPayload();
438}
439
440TEST_P(RtpSenderTestWithoutPacer, SendsPacketsWithTransportSequenceNumber) {
Stefan Holmera246cfb2016-08-23 17:51:42 +0200441 rtp_sender_.reset(new RTPSender(
brandtrdbdb3f12016-11-10 05:04:48 -0800442 false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
Niels Möller949f0fd2019-01-29 09:44:24 +0100443 &feedback_observer_, nullptr, nullptr, &mock_rtc_event_log_,
Benjamin Wright192eeec2018-10-17 17:27:25 -0700444 &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
Johannes Kron9190b822018-10-29 11:22:05 +0100445 nullptr, false, false));
nisse7d59f6b2017-02-21 03:40:24 -0800446 rtp_sender_->SetSSRC(kSsrc);
Stefan Holmerf5dca482016-01-27 12:58:51 +0100447 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
448 kRtpExtensionTransportSequenceNumber,
449 kTransportSequenceNumberExtensionId));
450
Stefan Holmerf5dca482016-01-27 12:58:51 +0100451 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
452 .WillOnce(testing::Return(kTransportSequenceNumber));
asapersson35151f32016-05-02 23:44:01 -0700453 EXPECT_CALL(send_packet_observer_,
454 OnSendPacket(kTransportSequenceNumber, _, _))
455 .Times(1);
minyue3a407ee2017-04-03 01:10:33 -0700456
457 EXPECT_CALL(feedback_observer_,
458 AddPacket(rtp_sender_->SSRC(), kTransportSequenceNumber, _,
459 PacedPacketInfo()))
Stefan Holmera246cfb2016-08-23 17:51:42 +0200460 .Times(1);
asapersson35151f32016-05-02 23:44:01 -0700461
462 SendGenericPayload();
Stefan Holmerf5dca482016-01-27 12:58:51 +0100463
danilchap12ba1862016-10-26 02:41:55 -0700464 const auto& packet = transport_.last_sent_packet();
465 uint16_t transport_seq_no;
466 ASSERT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
467 EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200468 EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200469 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200470}
471
472TEST_P(RtpSenderTestWithoutPacer, PacketOptionsNoRetransmission) {
473 rtp_sender_.reset(new RTPSender(
474 false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
Niels Möller949f0fd2019-01-29 09:44:24 +0100475 &feedback_observer_, nullptr, nullptr, &mock_rtc_event_log_,
Benjamin Wright192eeec2018-10-17 17:27:25 -0700476 &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
Johannes Kron9190b822018-10-29 11:22:05 +0100477 nullptr, false, false));
Petter Strandmark26bc6692018-05-29 08:43:35 +0200478 rtp_sender_->SetSSRC(kSsrc);
479
480 SendGenericPayload();
481
482 EXPECT_FALSE(transport_.last_options_.is_retransmit);
Stefan Holmerf5dca482016-01-27 12:58:51 +0100483}
484
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200485TEST_P(RtpSenderTestWithoutPacer,
486 SetsIncludedInFeedbackWhenTransportSequenceNumberExtensionIsRegistered) {
487 SetUpRtpSender(false, false);
488 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
489 kTransportSequenceNumberExtensionId);
490 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
491 .WillOnce(testing::Return(kTransportSequenceNumber));
492 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
stefana23fc622016-07-28 07:56:38 -0700493 SendGenericPayload();
Sebastian Jansson1bca65b2018-10-10 09:58:08 +0200494 EXPECT_TRUE(transport_.last_options_.included_in_feedback);
495}
496
497TEST_P(
498 RtpSenderTestWithoutPacer,
499 SetsIncludedInAllocationWhenTransportSequenceNumberExtensionIsRegistered) {
500 SetUpRtpSender(false, false);
501 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
502 kTransportSequenceNumberExtensionId);
503 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
504 .WillOnce(testing::Return(kTransportSequenceNumber));
505 EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
506 SendGenericPayload();
507 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
508}
509
510TEST_P(RtpSenderTestWithoutPacer,
511 SetsIncludedInAllocationWhenForcedAsPartOfAllocation) {
512 SetUpRtpSender(false, false);
513 rtp_sender_->SetAsPartOfAllocation(true);
514 SendGenericPayload();
515 EXPECT_FALSE(transport_.last_options_.included_in_feedback);
516 EXPECT_TRUE(transport_.last_options_.included_in_allocation);
517}
518
519TEST_P(RtpSenderTestWithoutPacer, DoesnSetIncludedInAllocationByDefault) {
520 SetUpRtpSender(false, false);
521 SendGenericPayload();
522 EXPECT_FALSE(transport_.last_options_.included_in_feedback);
523 EXPECT_FALSE(transport_.last_options_.included_in_allocation);
stefana23fc622016-07-28 07:56:38 -0700524}
asapersson35151f32016-05-02 23:44:01 -0700525
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200526TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
527 testing::StrictMock<MockSendSideDelayObserver> send_side_delay_observer_;
Benjamin Wright192eeec2018-10-17 17:27:25 -0700528 rtp_sender_.reset(new RTPSender(
529 false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
Niels Möller949f0fd2019-01-29 09:44:24 +0100530 nullptr, &send_side_delay_observer_, &mock_rtc_event_log_, nullptr,
531 nullptr, nullptr, false, nullptr, false, false));
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200532 rtp_sender_->SetSSRC(kSsrc);
533
534 const uint8_t kPayloadType = 127;
535 const uint32_t kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock
Niels Möller8a40edd2019-01-24 18:04:44 +0100536 const char payload_name[] = "GENERIC";
Johannes Kron4a8a5e72018-09-26 09:57:48 +0200537 RTPVideoHeader video_header;
538 EXPECT_EQ(0, rtp_sender_->RegisterPayload(payload_name, kPayloadType,
539 1000 * kCaptureTimeMsToRtpTimestamp,
540 0, 1500));
541
542 // Send packet with 10 ms send-side delay. The average and max should be 10
543 // ms.
544 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(10, 10, kSsrc))
545 .Times(1);
546 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
547 fake_clock_.AdvanceTimeMilliseconds(10);
548 EXPECT_TRUE(rtp_sender_->SendOutgoingData(
549 kVideoFrameKey, kPayloadType,
550 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
551 kPayloadData, sizeof(kPayloadData), nullptr, &video_header, nullptr,
552 kDefaultExpectedRetransmissionTimeMs));
553
554 // Send another packet with 20 ms delay. The average
555 // and max should be 15 and 20 ms respectively.
556 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(15, 20, kSsrc))
557 .Times(1);
558 fake_clock_.AdvanceTimeMilliseconds(10);
559 EXPECT_TRUE(rtp_sender_->SendOutgoingData(
560 kVideoFrameKey, kPayloadType,
561 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
562 kPayloadData, sizeof(kPayloadData), nullptr, &video_header, nullptr,
563 kDefaultExpectedRetransmissionTimeMs));
564
565 // Send another packet at the same time, which replaces the last packet.
566 // Since this packet has 0 ms delay, the average is now 5 ms and max is 10 ms.
567 // TODO(terelius): Is is not clear that this is the right behavior.
568 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(5, 10, kSsrc))
569 .Times(1);
570 capture_time_ms = fake_clock_.TimeInMilliseconds();
571 EXPECT_TRUE(rtp_sender_->SendOutgoingData(
572 kVideoFrameKey, kPayloadType,
573 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
574 kPayloadData, sizeof(kPayloadData), nullptr, &video_header, nullptr,
575 kDefaultExpectedRetransmissionTimeMs));
576
577 // Send a packet 1 second later. The earlier packets should have timed
578 // out, so both max and average should be the delay of this packet.
579 fake_clock_.AdvanceTimeMilliseconds(1000);
580 capture_time_ms = fake_clock_.TimeInMilliseconds();
581 fake_clock_.AdvanceTimeMilliseconds(1);
582 EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(1, 1, kSsrc))
583 .Times(1);
584 EXPECT_TRUE(rtp_sender_->SendOutgoingData(
585 kVideoFrameKey, kPayloadType,
586 capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
587 kPayloadData, sizeof(kPayloadData), nullptr, &video_header, nullptr,
588 kDefaultExpectedRetransmissionTimeMs));
589}
590
minyue3a407ee2017-04-03 01:10:33 -0700591TEST_P(RtpSenderTestWithoutPacer, OnSendPacketUpdated) {
stefana23fc622016-07-28 07:56:38 -0700592 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
593 kRtpExtensionTransportSequenceNumber,
594 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -0700595 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
596 .WillOnce(testing::Return(kTransportSequenceNumber));
597 EXPECT_CALL(send_packet_observer_,
598 OnSendPacket(kTransportSequenceNumber, _, _))
599 .Times(1);
600
601 SendGenericPayload();
602}
603
minyue3a407ee2017-04-03 01:10:33 -0700604TEST_P(RtpSenderTest, SendsPacketsWithTransportSequenceNumber) {
michaelt4da30442016-11-17 01:38:43 -0800605 rtp_sender_.reset(new RTPSender(
606 false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr,
Niels Möller949f0fd2019-01-29 09:44:24 +0100607 &seq_num_allocator_, &feedback_observer_, nullptr, nullptr,
michaelt4da30442016-11-17 01:38:43 -0800608 &mock_rtc_event_log_, &send_packet_observer_,
Johannes Kron9190b822018-10-29 11:22:05 +0100609 &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
brandtr9dfff292016-11-14 05:14:50 -0800610 rtp_sender_->SetSequenceNumber(kSeqNum);
611 rtp_sender_->SetSSRC(kSsrc);
Stefan Holmera246cfb2016-08-23 17:51:42 +0200612 rtp_sender_->SetStorePacketsStatus(true, 10);
613 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
614 kRtpExtensionTransportSequenceNumber,
615 kTransportSequenceNumberExtensionId));
616
brandtr9dfff292016-11-14 05:14:50 -0800617 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
Stefan Holmera246cfb2016-08-23 17:51:42 +0200618 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
619 .WillOnce(testing::Return(kTransportSequenceNumber));
620 EXPECT_CALL(send_packet_observer_,
621 OnSendPacket(kTransportSequenceNumber, _, _))
622 .Times(1);
minyue3a407ee2017-04-03 01:10:33 -0700623 EXPECT_CALL(feedback_observer_,
624 AddPacket(rtp_sender_->SSRC(), kTransportSequenceNumber, _,
625 PacedPacketInfo()))
Stefan Holmera246cfb2016-08-23 17:51:42 +0200626 .Times(1);
627
628 SendGenericPayload();
philipel8aadd502017-02-23 02:56:13 -0800629 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
630 fake_clock_.TimeInMilliseconds(), false,
631 PacedPacketInfo());
Stefan Holmera246cfb2016-08-23 17:51:42 +0200632
danilchap12ba1862016-10-26 02:41:55 -0700633 const auto& packet = transport_.last_sent_packet();
634 uint16_t transport_seq_no;
635 EXPECT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
636 EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
Petter Strandmark26bc6692018-05-29 08:43:35 +0200637 EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
Stefan Holmera246cfb2016-08-23 17:51:42 +0200638}
639
Erik Språng7b52f102018-02-07 14:37:37 +0100640TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) {
ilnik04f4d122017-06-19 07:18:55 -0700641 rtp_sender_->SetStorePacketsStatus(true, 10);
642 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
643 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
644 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
645 auto packet = rtp_sender_->AllocatePacket();
646 packet->SetPayloadType(kPayload);
647 packet->SetMarker(true);
648 packet->SetTimestamp(kTimestamp);
649 packet->set_capture_time_ms(capture_time_ms);
ilnik2edc6842017-07-06 03:06:50 -0700650 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
ilnik04f4d122017-06-19 07:18:55 -0700651 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
652 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
653 size_t packet_size = packet->size();
ilnik04f4d122017-06-19 07:18:55 -0700654
655 const int kStoredTimeInMs = 100;
Erik Språng7b52f102018-02-07 14:37:37 +0100656 {
657 EXPECT_CALL(
658 mock_paced_sender_,
659 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _));
660 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
661 kAllowRetransmission,
662 RtpPacketSender::kNormalPriority));
663 }
ilnik04f4d122017-06-19 07:18:55 -0700664 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
Erik Språng7b52f102018-02-07 14:37:37 +0100665 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
666 PacedPacketInfo());
ilnik04f4d122017-06-19 07:18:55 -0700667 EXPECT_EQ(1, transport_.packets_sent());
668 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
669
danilchapce251812017-09-11 12:24:41 -0700670 VideoSendTiming video_timing;
671 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
672 &video_timing));
673 EXPECT_EQ(kStoredTimeInMs, video_timing.pacer_exit_delta_ms);
Erik Språng7b52f102018-02-07 14:37:37 +0100674}
ilnik04f4d122017-06-19 07:18:55 -0700675
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100676TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithPacer) {
677 SetUpRtpSender(/*pacer=*/true, /*populate_network2=*/true);
Erik Språng7b52f102018-02-07 14:37:37 +0100678 rtp_sender_->SetStorePacketsStatus(true, 10);
679 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
680 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
681 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
682 auto packet = rtp_sender_->AllocatePacket();
683 packet->SetPayloadType(kPayload);
684 packet->SetMarker(true);
685 packet->SetTimestamp(kTimestamp);
686 packet->set_capture_time_ms(capture_time_ms);
687 const uint16_t kPacerExitMs = 1234u;
688 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, kPacerExitMs, 0u, 0u, true};
689 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
690 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
691 size_t packet_size = packet->size();
692
693 const int kStoredTimeInMs = 100;
694 {
695 EXPECT_CALL(
696 mock_paced_sender_,
697 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _));
698 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
699 kAllowRetransmission,
700 RtpPacketSender::kNormalPriority));
701 }
ilnik04f4d122017-06-19 07:18:55 -0700702 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
703 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
704 PacedPacketInfo());
Erik Språng7b52f102018-02-07 14:37:37 +0100705 EXPECT_EQ(1, transport_.packets_sent());
ilnik04f4d122017-06-19 07:18:55 -0700706 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
707
Erik Språng7b52f102018-02-07 14:37:37 +0100708 VideoSendTiming video_timing;
danilchapce251812017-09-11 12:24:41 -0700709 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
710 &video_timing));
Erik Språng7b52f102018-02-07 14:37:37 +0100711 EXPECT_EQ(kStoredTimeInMs, video_timing.network2_timestamp_delta_ms);
712 EXPECT_EQ(kPacerExitMs, video_timing.pacer_exit_delta_ms);
ilnik04f4d122017-06-19 07:18:55 -0700713}
714
Danil Chapovalovaf52b682018-11-27 10:48:27 +0100715TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithoutPacer) {
716 SetUpRtpSender(/*pacer=*/false, /*populate_network2=*/true);
717 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
718 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
719 auto packet = rtp_sender_->AllocatePacket();
720 packet->SetMarker(true);
721 packet->set_capture_time_ms(fake_clock_.TimeInMilliseconds());
722 const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
723 packet->SetExtension<VideoTimingExtension>(kVideoTiming);
724 EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
725
726 const int kPropagateTimeMs = 10;
727 fake_clock_.AdvanceTimeMilliseconds(kPropagateTimeMs);
728
729 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
730 kAllowRetransmission,
731 RtpPacketSender::kNormalPriority));
732
733 EXPECT_EQ(1, transport_.packets_sent());
734 absl::optional<VideoSendTiming> video_timing =
735 transport_.last_sent_packet().GetExtension<VideoTimingExtension>();
736 ASSERT_TRUE(video_timing);
737 EXPECT_EQ(kPropagateTimeMs, video_timing->network2_timestamp_delta_ms);
738}
739
minyue3a407ee2017-04-03 01:10:33 -0700740TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) {
Peter Boströme23e7372015-10-08 11:44:14 +0200741 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority,
brandtr9dfff292016-11-14 05:14:50 -0800742 kSsrc, kSeqNum, _, _, _));
Elad Alon4a87e1c2017-10-03 16:11:34 +0200743 EXPECT_CALL(mock_rtc_event_log_,
744 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000745
pwestin@webrtc.orgc66e8b32012-11-07 17:01:04 +0000746 rtp_sender_->SetStorePacketsStatus(true, 10);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000747 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800748 kRtpExtensionTransmissionTimeOffset,
749 kTransmissionTimeOffsetExtensionId));
750 EXPECT_EQ(
751 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
752 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000753 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700754 auto packet =
755 BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
756 size_t packet_size = packet->size();
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000757
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000758 // Packet should be stored in a send bucket.
danilchapb6f1fb52016-10-19 06:11:39 -0700759 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
760 kAllowRetransmission,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700761 RtpPacketSender::kNormalPriority));
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000762
danilchap12ba1862016-10-26 02:41:55 -0700763 EXPECT_EQ(0, transport_.packets_sent());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000764
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000765 const int kStoredTimeInMs = 100;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000766 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000767
brandtr9dfff292016-11-14 05:14:50 -0800768 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
philipel8aadd502017-02-23 02:56:13 -0800769 PacedPacketInfo());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000770
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000771 // Process send bucket. Packet should now be sent.
danilchap12ba1862016-10-26 02:41:55 -0700772 EXPECT_EQ(1, transport_.packets_sent());
773 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
774
stefan@webrtc.orga5cb98c2013-05-29 12:12:51 +0000775 webrtc::RTPHeader rtp_header;
danilchap12ba1862016-10-26 02:41:55 -0700776 transport_.last_sent_packet().GetHeader(&rtp_header);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000777
778 // Verify transmission time offset.
779 EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000780 uint64_t expected_send_time =
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000781 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000782 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000783}
784
minyue3a407ee2017-04-03 01:10:33 -0700785TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) {
Peter Boströme23e7372015-10-08 11:44:14 +0200786 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority,
brandtr9dfff292016-11-14 05:14:50 -0800787 kSsrc, kSeqNum, _, _, _));
Elad Alon4a87e1c2017-10-03 16:11:34 +0200788 EXPECT_CALL(mock_rtc_event_log_,
789 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000790
791 rtp_sender_->SetStorePacketsStatus(true, 10);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000792 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800793 kRtpExtensionTransmissionTimeOffset,
794 kTransmissionTimeOffsetExtensionId));
795 EXPECT_EQ(
796 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
797 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000798 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700799 auto packet =
800 BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
801 size_t packet_size = packet->size();
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000802
803 // Packet should be stored in a send bucket.
danilchapb6f1fb52016-10-19 06:11:39 -0700804 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
805 kAllowRetransmission,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700806 RtpPacketSender::kNormalPriority));
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000807
danilchap12ba1862016-10-26 02:41:55 -0700808 EXPECT_EQ(0, transport_.packets_sent());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000809
terelius5d332ac2016-01-14 14:37:39 -0800810 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority,
brandtr9dfff292016-11-14 05:14:50 -0800811 kSsrc, kSeqNum, _, _, _));
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000812
813 const int kStoredTimeInMs = 100;
814 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
815
danilchapb6f1fb52016-10-19 06:11:39 -0700816 EXPECT_EQ(static_cast<int>(packet_size), rtp_sender_->ReSendPacket(kSeqNum));
danilchap12ba1862016-10-26 02:41:55 -0700817 EXPECT_EQ(0, transport_.packets_sent());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000818
brandtr9dfff292016-11-14 05:14:50 -0800819 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
philipel8aadd502017-02-23 02:56:13 -0800820 PacedPacketInfo());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000821
822 // Process send bucket. Packet should now be sent.
danilchap12ba1862016-10-26 02:41:55 -0700823 EXPECT_EQ(1, transport_.packets_sent());
824 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000825
stefan@webrtc.orga5cb98c2013-05-29 12:12:51 +0000826 webrtc::RTPHeader rtp_header;
danilchap12ba1862016-10-26 02:41:55 -0700827 transport_.last_sent_packet().GetHeader(&rtp_header);
pwestin@webrtc.orgb0061f92013-04-27 00:41:08 +0000828
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000829 // Verify transmission time offset.
830 EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000831 uint64_t expected_send_time =
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000832 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
833 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
834}
835
836// This test sends 1 regular video packet, then 4 padding packets, and then
837// 1 more regular packet.
minyue3a407ee2017-04-03 01:10:33 -0700838TEST_P(RtpSenderTest, SendPadding) {
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000839 // Make all (non-padding) packets go to send queue.
terelius5d332ac2016-01-14 14:37:39 -0800840 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority,
brandtr9dfff292016-11-14 05:14:50 -0800841 kSsrc, kSeqNum, _, _, _));
Elad Alon4a87e1c2017-10-03 16:11:34 +0200842 EXPECT_CALL(mock_rtc_event_log_,
843 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
844 .Times(1 + 4 + 1);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000845
846 uint16_t seq_num = kSeqNum;
847 uint32_t timestamp = kTimestamp;
848 rtp_sender_->SetStorePacketsStatus(true, 10);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000849 size_t rtp_header_len = kRtpHeaderSize;
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000850 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
danilchap162abd32015-12-10 02:39:40 -0800851 kRtpExtensionTransmissionTimeOffset,
852 kTransmissionTimeOffsetExtensionId));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000853 rtp_header_len += 4; // 4 bytes extension.
danilchap162abd32015-12-10 02:39:40 -0800854 EXPECT_EQ(
855 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
856 kAbsoluteSendTimeExtensionId));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000857 rtp_header_len += 4; // 4 bytes extension.
858 rtp_header_len += 4; // 4 extra bytes common to all extension headers.
859
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000860 webrtc::RTPHeader rtp_header;
861
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000862 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700863 auto packet =
864 BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
Stefan Holmer586b19b2015-09-18 11:14:31 +0200865 const uint32_t media_packet_timestamp = timestamp;
danilchapb6f1fb52016-10-19 06:11:39 -0700866 size_t packet_size = packet->size();
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000867
868 // Packet should be stored in a send bucket.
danilchapb6f1fb52016-10-19 06:11:39 -0700869 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
870 kAllowRetransmission,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700871 RtpPacketSender::kNormalPriority));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000872
873 int total_packets_sent = 0;
danilchap12ba1862016-10-26 02:41:55 -0700874 EXPECT_EQ(total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000875
876 const int kStoredTimeInMs = 100;
877 fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
brandtr9dfff292016-11-14 05:14:50 -0800878 rtp_sender_->TimeToSendPacket(kSsrc, seq_num++, capture_time_ms, false,
philipel8aadd502017-02-23 02:56:13 -0800879 PacedPacketInfo());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000880 // Packet should now be sent. This test doesn't verify the regular video
881 // packet, since it is tested in another test.
danilchap12ba1862016-10-26 02:41:55 -0700882 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000883 timestamp += 90 * kStoredTimeInMs;
884
885 // Send padding 4 times, waiting 50 ms between each.
886 for (int i = 0; i < 4; ++i) {
887 const int kPaddingPeriodMs = 50;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000888 const size_t kPaddingBytes = 100;
889 const size_t kMaxPaddingLength = 224; // Value taken from rtp_sender.cc.
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000890 // Padding will be forced to full packets.
philipelc7bf32a2017-02-17 03:59:43 -0800891 EXPECT_EQ(kMaxPaddingLength,
philipel8aadd502017-02-23 02:56:13 -0800892 rtp_sender_->TimeToSendPadding(kPaddingBytes, PacedPacketInfo()));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000893
894 // Process send bucket. Padding should now be sent.
danilchap12ba1862016-10-26 02:41:55 -0700895 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000896 EXPECT_EQ(kMaxPaddingLength + rtp_header_len,
danilchap12ba1862016-10-26 02:41:55 -0700897 transport_.last_sent_packet().size());
898
899 transport_.last_sent_packet().GetHeader(&rtp_header);
pbosbd2522a2015-07-01 05:35:53 -0700900 EXPECT_EQ(kMaxPaddingLength, rtp_header.paddingLength);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000901
Stefan Holmer586b19b2015-09-18 11:14:31 +0200902 // Verify sequence number and timestamp. The timestamp should be the same
903 // as the last media packet.
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000904 EXPECT_EQ(seq_num++, rtp_header.sequenceNumber);
Stefan Holmer586b19b2015-09-18 11:14:31 +0200905 EXPECT_EQ(media_packet_timestamp, rtp_header.timestamp);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000906 // Verify transmission time offset.
Stefan Holmer586b19b2015-09-18 11:14:31 +0200907 int offset = timestamp - media_packet_timestamp;
908 EXPECT_EQ(offset, rtp_header.extension.transmissionTimeOffset);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000909 uint64_t expected_send_time =
910 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
911 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
912 fake_clock_.AdvanceTimeMilliseconds(kPaddingPeriodMs);
913 timestamp += 90 * kPaddingPeriodMs;
914 }
915
916 // Send a regular video packet again.
917 capture_time_ms = fake_clock_.TimeInMilliseconds();
danilchapb6f1fb52016-10-19 06:11:39 -0700918 packet = BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
919 packet_size = packet->size();
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000920
brandtr9dfff292016-11-14 05:14:50 -0800921 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority,
922 kSsrc, seq_num, _, _, _));
terelius5d332ac2016-01-14 14:37:39 -0800923
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000924 // Packet should be stored in a send bucket.
danilchapb6f1fb52016-10-19 06:11:39 -0700925 EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
926 kAllowRetransmission,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700927 RtpPacketSender::kNormalPriority));
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000928
brandtr9dfff292016-11-14 05:14:50 -0800929 rtp_sender_->TimeToSendPacket(kSsrc, seq_num, capture_time_ms, false,
philipel8aadd502017-02-23 02:56:13 -0800930 PacedPacketInfo());
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000931 // Process send bucket.
danilchap12ba1862016-10-26 02:41:55 -0700932 EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
933 EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
934 transport_.last_sent_packet().GetHeader(&rtp_header);
henrik.lundin@webrtc.org6e95d7a2013-11-15 08:59:19 +0000935
936 // Verify sequence number and timestamp.
937 EXPECT_EQ(seq_num, rtp_header.sequenceNumber);
938 EXPECT_EQ(timestamp, rtp_header.timestamp);
939 // Verify transmission time offset. This packet is sent without delay.
940 EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset);
941 uint64_t expected_send_time =
942 ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
solenberg@webrtc.org7ebbea12013-05-16 11:10:31 +0000943 EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
asapersson@webrtc.org0b3c35a2012-01-16 11:06:31 +0000944}
pbos@webrtc.org8911ce42013-03-18 16:39:03 +0000945
minyue3a407ee2017-04-03 01:10:33 -0700946TEST_P(RtpSenderTest, OnSendPacketUpdated) {
stefana23fc622016-07-28 07:56:38 -0700947 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
948 kRtpExtensionTransportSequenceNumber,
949 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -0700950 rtp_sender_->SetStorePacketsStatus(true, 10);
951
952 EXPECT_CALL(send_packet_observer_,
953 OnSendPacket(kTransportSequenceNumber, _, _))
954 .Times(1);
955 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
956 .WillOnce(testing::Return(kTransportSequenceNumber));
brandtr9dfff292016-11-14 05:14:50 -0800957 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _))
958 .Times(1);
asapersson35151f32016-05-02 23:44:01 -0700959
960 SendGenericPayload(); // Packet passed to pacer.
961 const bool kIsRetransmit = false;
brandtr9dfff292016-11-14 05:14:50 -0800962 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
963 fake_clock_.TimeInMilliseconds(), kIsRetransmit,
philipel8aadd502017-02-23 02:56:13 -0800964 PacedPacketInfo());
danilchap12ba1862016-10-26 02:41:55 -0700965 EXPECT_EQ(1, transport_.packets_sent());
asapersson35151f32016-05-02 23:44:01 -0700966}
967
minyue3a407ee2017-04-03 01:10:33 -0700968TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
stefana23fc622016-07-28 07:56:38 -0700969 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
970 kRtpExtensionTransportSequenceNumber,
971 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -0700972 rtp_sender_->SetStorePacketsStatus(true, 10);
973
974 EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
975 EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
976 .WillOnce(testing::Return(kTransportSequenceNumber));
brandtr9dfff292016-11-14 05:14:50 -0800977 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _))
978 .Times(1);
asapersson35151f32016-05-02 23:44:01 -0700979
980 SendGenericPayload(); // Packet passed to pacer.
981 const bool kIsRetransmit = true;
brandtr9dfff292016-11-14 05:14:50 -0800982 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
983 fake_clock_.TimeInMilliseconds(), kIsRetransmit,
philipel8aadd502017-02-23 02:56:13 -0800984 PacedPacketInfo());
danilchap12ba1862016-10-26 02:41:55 -0700985 EXPECT_EQ(1, transport_.packets_sent());
Petter Strandmark26bc6692018-05-29 08:43:35 +0200986 EXPECT_TRUE(transport_.last_options_.is_retransmit);
asapersson35151f32016-05-02 23:44:01 -0700987}
988
minyue3a407ee2017-04-03 01:10:33 -0700989TEST_P(RtpSenderTest, OnSendPacketNotUpdatedWithoutSeqNumAllocator) {
asapersson35151f32016-05-02 23:44:01 -0700990 rtp_sender_.reset(new RTPSender(
brandtrdbdb3f12016-11-10 05:04:48 -0800991 false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr,
asapersson35151f32016-05-02 23:44:01 -0700992 nullptr /* TransportSequenceNumberAllocator */, nullptr, nullptr, nullptr,
Niels Möller949f0fd2019-01-29 09:44:24 +0100993 nullptr, &send_packet_observer_, &retransmission_rate_limiter_, nullptr,
994 false, nullptr, false, false));
brandtr9dfff292016-11-14 05:14:50 -0800995 rtp_sender_->SetSequenceNumber(kSeqNum);
996 rtp_sender_->SetSSRC(kSsrc);
stefana23fc622016-07-28 07:56:38 -0700997 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
998 kRtpExtensionTransportSequenceNumber,
999 kTransportSequenceNumberExtensionId));
asapersson35151f32016-05-02 23:44:01 -07001000 rtp_sender_->SetSequenceNumber(kSeqNum);
1001 rtp_sender_->SetStorePacketsStatus(true, 10);
1002
1003 EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
brandtr9dfff292016-11-14 05:14:50 -08001004 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _))
1005 .Times(1);
asapersson35151f32016-05-02 23:44:01 -07001006
1007 SendGenericPayload(); // Packet passed to pacer.
1008 const bool kIsRetransmit = false;
brandtr9dfff292016-11-14 05:14:50 -08001009 rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
1010 fake_clock_.TimeInMilliseconds(), kIsRetransmit,
philipel8aadd502017-02-23 02:56:13 -08001011 PacedPacketInfo());
danilchap12ba1862016-10-26 02:41:55 -07001012 EXPECT_EQ(1, transport_.packets_sent());
asapersson35151f32016-05-02 23:44:01 -07001013}
1014
minyue3a407ee2017-04-03 01:10:33 -07001015TEST_P(RtpSenderTest, SendRedundantPayloads) {
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001016 MockTransport transport;
terelius429c3452016-01-21 05:42:04 -08001017 rtp_sender_.reset(new RTPSender(
asapersson35151f32016-05-02 23:44:01 -07001018 false, &fake_clock_, &transport, &mock_paced_sender_, nullptr, nullptr,
Niels Möller949f0fd2019-01-29 09:44:24 +01001019 nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr,
Johannes Kron9190b822018-10-29 11:22:05 +01001020 &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001021 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtr9dfff292016-11-14 05:14:50 -08001022 rtp_sender_->SetSSRC(kSsrc);
Shao Changbine62202f2015-04-21 20:24:50 +08001023 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001024
1025 uint16_t seq_num = kSeqNum;
1026 rtp_sender_->SetStorePacketsStatus(true, 10);
wu@webrtc.orgebdb0e32014-03-06 23:49:08 +00001027 int32_t rtp_header_len = kRtpHeaderSize;
danilchap162abd32015-12-10 02:39:40 -08001028 EXPECT_EQ(
1029 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
1030 kAbsoluteSendTimeExtensionId));
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001031 rtp_header_len += 4; // 4 bytes extension.
1032 rtp_header_len += 4; // 4 extra bytes common to all extension headers.
1033
pbos@webrtc.org0b0c2412015-01-13 14:15:15 +00001034 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
stefan@webrtc.orgef927552014-06-05 08:25:29 +00001035 rtp_sender_->SetRtxSsrc(1234);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001036
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001037 const size_t kNumPayloadSizes = 10;
danilchap162abd32015-12-10 02:39:40 -08001038 const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700,
1039 750, 800, 850, 900, 950};
terelius5d332ac2016-01-14 14:37:39 -08001040 // Expect all packets go through the pacer.
1041 EXPECT_CALL(mock_paced_sender_,
brandtr9dfff292016-11-14 05:14:50 -08001042 InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _))
terelius5d332ac2016-01-14 14:37:39 -08001043 .Times(kNumPayloadSizes);
Elad Alon4a87e1c2017-10-03 16:11:34 +02001044 EXPECT_CALL(mock_rtc_event_log_,
1045 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
terelius429c3452016-01-21 05:42:04 -08001046 .Times(kNumPayloadSizes);
1047
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001048 // Send 10 packets of increasing size.
1049 for (size_t i = 0; i < kNumPayloadSizes; ++i) {
1050 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
stefan1d8a5062015-10-02 03:39:33 -07001051 EXPECT_CALL(transport, SendRtp(_, _, _)).WillOnce(testing::Return(true));
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001052 SendPacket(capture_time_ms, kPayloadSizes[i]);
brandtr9dfff292016-11-14 05:14:50 -08001053 rtp_sender_->TimeToSendPacket(kSsrc, seq_num++, capture_time_ms, false,
philipel8aadd502017-02-23 02:56:13 -08001054 PacedPacketInfo());
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001055 fake_clock_.AdvanceTimeMilliseconds(33);
1056 }
terelius429c3452016-01-21 05:42:04 -08001057
Elad Alon4a87e1c2017-10-03 16:11:34 +02001058 EXPECT_CALL(mock_rtc_event_log_,
1059 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
terelius429c3452016-01-21 05:42:04 -08001060 .Times(::testing::AtLeast(4));
1061
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001062 // The amount of padding to send it too small to send a payload packet.
stefan1d8a5062015-10-02 03:39:33 -07001063 EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
pbos2d566682015-09-28 09:59:31 -07001064 .WillOnce(testing::Return(true));
philipela1ed0b32016-06-01 06:31:17 -07001065 EXPECT_EQ(kMaxPaddingSize,
philipel8aadd502017-02-23 02:56:13 -08001066 rtp_sender_->TimeToSendPadding(49, PacedPacketInfo()));
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001067
Petter Strandmark26bc6692018-05-29 08:43:35 +02001068 PacketOptions options;
Peter Boströmac547a62015-09-17 23:03:57 +02001069 EXPECT_CALL(transport,
stefan1d8a5062015-10-02 03:39:33 -07001070 SendRtp(_, kPayloadSizes[0] + rtp_header_len + kRtxHeaderSize, _))
Yves Gerey665174f2018-06-19 15:03:05 +02001071 .WillOnce(
1072 testing::DoAll(testing::SaveArg<2>(&options), testing::Return(true)));
philipela1ed0b32016-06-01 06:31:17 -07001073 EXPECT_EQ(kPayloadSizes[0],
philipel8aadd502017-02-23 02:56:13 -08001074 rtp_sender_->TimeToSendPadding(500, PacedPacketInfo()));
Petter Strandmark26bc6692018-05-29 08:43:35 +02001075 EXPECT_TRUE(options.is_retransmit);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001076
Yves Gerey665174f2018-06-19 15:03:05 +02001077 EXPECT_CALL(transport, SendRtp(_,
1078 kPayloadSizes[kNumPayloadSizes - 1] +
1079 rtp_header_len + kRtxHeaderSize,
stefan1d8a5062015-10-02 03:39:33 -07001080 _))
pbos2d566682015-09-28 09:59:31 -07001081 .WillOnce(testing::Return(true));
Petter Strandmark26bc6692018-05-29 08:43:35 +02001082
1083 options.is_retransmit = false;
stefan1d8a5062015-10-02 03:39:33 -07001084 EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
Yves Gerey665174f2018-06-19 15:03:05 +02001085 .WillOnce(
1086 testing::DoAll(testing::SaveArg<2>(&options), testing::Return(true)));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001087 EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1] + kMaxPaddingSize,
philipel8aadd502017-02-23 02:56:13 -08001088 rtp_sender_->TimeToSendPadding(999, PacedPacketInfo()));
Petter Strandmark26bc6692018-05-29 08:43:35 +02001089 EXPECT_FALSE(options.is_retransmit);
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +00001090}
1091
minyue3a407ee2017-04-03 01:10:33 -07001092TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
Niels Möller8a40edd2019-01-24 18:04:44 +01001093 const char payload_name[] = "GENERIC";
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001094 const uint8_t payload_type = 127;
1095 ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000,
1096 0, 1500));
1097 uint8_t payload[] = {47, 11, 32, 93, 89};
1098
1099 // Send keyframe
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001100 RTPVideoHeader video_header;
spranga8ae6f22017-09-04 07:23:56 -07001101 ASSERT_TRUE(rtp_sender_->SendOutgoingData(
1102 kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001103 nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001104
danilchap96c15872016-11-21 01:35:29 -08001105 auto sent_payload = transport_.last_sent_packet().payload();
1106 uint8_t generic_header = sent_payload[0];
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001107 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
1108 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
danilchap96c15872016-11-21 01:35:29 -08001109 EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001110
1111 // Send delta frame
1112 payload[0] = 13;
1113 payload[1] = 42;
1114 payload[4] = 13;
1115
Sergey Ulanov525df3f2016-08-02 17:46:41 -07001116 ASSERT_TRUE(rtp_sender_->SendOutgoingData(
1117 kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001118 nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001119
danilchap96c15872016-11-21 01:35:29 -08001120 sent_payload = transport_.last_sent_packet().payload();
1121 generic_header = sent_payload[0];
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001122 EXPECT_FALSE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
1123 EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
danilchap96c15872016-11-21 01:35:29 -08001124 EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
pbos@webrtc.org8911ce42013-03-18 16:39:03 +00001125}
1126
minyue3a407ee2017-04-03 01:10:33 -07001127TEST_P(RtpSenderTest, SendFlexfecPackets) {
brandtrdbdb3f12016-11-10 05:04:48 -08001128 constexpr int kMediaPayloadType = 127;
1129 constexpr int kFlexfecPayloadType = 118;
1130 constexpr uint32_t kMediaSsrc = 1234;
1131 constexpr uint32_t kFlexfecSsrc = 5678;
1132 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001133 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
brandtrdbdb3f12016-11-10 05:04:48 -08001134 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
Steve Antonf0482ea2018-04-09 13:33:52 -07001135 kNoMid, kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001136 nullptr /* rtp_state */, &fake_clock_);
brandtrdbdb3f12016-11-10 05:04:48 -08001137
1138 // Reset |rtp_sender_| to use FlexFEC.
michaelt4da30442016-11-17 01:38:43 -08001139 rtp_sender_.reset(new RTPSender(
1140 false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
Niels Möller949f0fd2019-01-29 09:44:24 +01001141 &seq_num_allocator_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
1142 &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
1143 nullptr, false, false));
brandtrdbdb3f12016-11-10 05:04:48 -08001144 rtp_sender_->SetSSRC(kMediaSsrc);
1145 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtrdbdb3f12016-11-10 05:04:48 -08001146 rtp_sender_->SetStorePacketsStatus(true, 10);
1147
1148 // Parameters selected to generate a single FEC packet per media packet.
1149 FecProtectionParams params;
1150 params.fec_rate = 15;
1151 params.max_fec_frames = 1;
1152 params.fec_mask_type = kFecMaskRandom;
1153 rtp_sender_->SetFecParameters(params, params);
1154
brandtr9dfff292016-11-14 05:14:50 -08001155 EXPECT_CALL(mock_paced_sender_,
1156 InsertPacket(RtpPacketSender::kLowPriority, kMediaSsrc, kSeqNum,
1157 _, _, false));
1158 uint16_t flexfec_seq_num;
brandtrdbdb3f12016-11-10 05:04:48 -08001159 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
brandtr9dfff292016-11-14 05:14:50 -08001160 kFlexfecSsrc, _, _, _, false))
1161 .WillOnce(testing::SaveArg<2>(&flexfec_seq_num));
brandtrdbdb3f12016-11-10 05:04:48 -08001162 SendGenericPayload();
Elad Alon4a87e1c2017-10-03 16:11:34 +02001163 EXPECT_CALL(mock_rtc_event_log_,
1164 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1165 .Times(2);
philipel8aadd502017-02-23 02:56:13 -08001166 EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kMediaSsrc, kSeqNum,
1167 fake_clock_.TimeInMilliseconds(),
1168 false, PacedPacketInfo()));
brandtr9dfff292016-11-14 05:14:50 -08001169 EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kFlexfecSsrc, flexfec_seq_num,
1170 fake_clock_.TimeInMilliseconds(),
philipel8aadd502017-02-23 02:56:13 -08001171 false, PacedPacketInfo()));
brandtr9dfff292016-11-14 05:14:50 -08001172 ASSERT_EQ(2, transport_.packets_sent());
brandtrdbdb3f12016-11-10 05:04:48 -08001173 const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
1174 EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
brandtr9dfff292016-11-14 05:14:50 -08001175 EXPECT_EQ(kSeqNum, media_packet.SequenceNumber());
brandtrdbdb3f12016-11-10 05:04:48 -08001176 EXPECT_EQ(kMediaSsrc, media_packet.Ssrc());
brandtr9dfff292016-11-14 05:14:50 -08001177 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[1];
1178 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
1179 EXPECT_EQ(flexfec_seq_num, flexfec_packet.SequenceNumber());
1180 EXPECT_EQ(kFlexfecSsrc, flexfec_packet.Ssrc());
brandtrdbdb3f12016-11-10 05:04:48 -08001181}
1182
ilnik10894992017-06-21 08:23:19 -07001183// TODO(ilnik): because of webrtc:7859. Once FEC moved below pacer, this test
1184// should be removed.
1185TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
1186 constexpr int kMediaPayloadType = 127;
1187 constexpr int kFlexfecPayloadType = 118;
1188 constexpr uint32_t kMediaSsrc = 1234;
1189 constexpr uint32_t kFlexfecSsrc = 5678;
1190 const std::vector<RtpExtension> kNoRtpExtensions;
1191 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
ilnike4350192017-06-29 02:27:44 -07001192
ilnik10894992017-06-21 08:23:19 -07001193 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
Steve Antonf0482ea2018-04-09 13:33:52 -07001194 kNoMid, kNoRtpExtensions, kNoRtpExtensionSizes,
ilnik10894992017-06-21 08:23:19 -07001195 nullptr /* rtp_state */, &fake_clock_);
1196
1197 // Reset |rtp_sender_| to use FlexFEC.
1198 rtp_sender_.reset(new RTPSender(
1199 false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
Niels Möller949f0fd2019-01-29 09:44:24 +01001200 &seq_num_allocator_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
1201 &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
1202 nullptr, false, false));
ilnik10894992017-06-21 08:23:19 -07001203 rtp_sender_->SetSSRC(kMediaSsrc);
1204 rtp_sender_->SetSequenceNumber(kSeqNum);
ilnik10894992017-06-21 08:23:19 -07001205 rtp_sender_->SetStorePacketsStatus(true, 10);
1206
ilnike4350192017-06-29 02:27:44 -07001207 // Need extension to be registered for timing frames to be sent.
1208 ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1209 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
1210
ilnik10894992017-06-21 08:23:19 -07001211 // Parameters selected to generate a single FEC packet per media packet.
1212 FecProtectionParams params;
1213 params.fec_rate = 15;
1214 params.max_fec_frames = 1;
1215 params.fec_mask_type = kFecMaskRandom;
1216 rtp_sender_->SetFecParameters(params, params);
1217
1218 EXPECT_CALL(mock_paced_sender_,
1219 InsertPacket(RtpPacketSender::kLowPriority, kMediaSsrc, kSeqNum,
1220 _, _, false));
1221 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
1222 kFlexfecSsrc, _, _, _, false))
1223 .Times(0); // Not called because packet should not be protected.
1224
1225 const uint32_t kTimestamp = 1234;
1226 const uint8_t kPayloadType = 127;
1227 const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
Niels Möller8a40edd2019-01-24 18:04:44 +01001228 const char payload_name[] = "GENERIC";
ilnik10894992017-06-21 08:23:19 -07001229 EXPECT_EQ(0, rtp_sender_->RegisterPayload(payload_name, kPayloadType, 90000,
1230 0, 1500));
1231 RTPVideoHeader video_header;
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +02001232 video_header.video_timing.flags = VideoSendTiming::kTriggeredByTimer;
ilnik10894992017-06-21 08:23:19 -07001233 EXPECT_TRUE(rtp_sender_->SendOutgoingData(
1234 kVideoFrameKey, kPayloadType, kTimestamp, kCaptureTimeMs, kPayloadData,
spranga8ae6f22017-09-04 07:23:56 -07001235 sizeof(kPayloadData), nullptr, &video_header, nullptr,
1236 kDefaultExpectedRetransmissionTimeMs));
ilnik10894992017-06-21 08:23:19 -07001237
Elad Alon4a87e1c2017-10-03 16:11:34 +02001238 EXPECT_CALL(mock_rtc_event_log_,
1239 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1240 .Times(1);
ilnik10894992017-06-21 08:23:19 -07001241 EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kMediaSsrc, kSeqNum,
1242 fake_clock_.TimeInMilliseconds(),
1243 false, PacedPacketInfo()));
1244 ASSERT_EQ(1, transport_.packets_sent());
1245 const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
1246 EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
1247 EXPECT_EQ(kSeqNum, media_packet.SequenceNumber());
1248 EXPECT_EQ(kMediaSsrc, media_packet.Ssrc());
1249
1250 // Now try to send not a timing frame.
1251 uint16_t flexfec_seq_num;
1252 EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
1253 kFlexfecSsrc, _, _, _, false))
1254 .WillOnce(testing::SaveArg<2>(&flexfec_seq_num));
1255 EXPECT_CALL(mock_paced_sender_,
1256 InsertPacket(RtpPacketSender::kLowPriority, kMediaSsrc,
1257 kSeqNum + 1, _, _, false));
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +02001258 video_header.video_timing.flags = VideoSendTiming::kInvalid;
ilnik10894992017-06-21 08:23:19 -07001259 EXPECT_TRUE(rtp_sender_->SendOutgoingData(
1260 kVideoFrameKey, kPayloadType, kTimestamp + 1, kCaptureTimeMs + 1,
spranga8ae6f22017-09-04 07:23:56 -07001261 kPayloadData, sizeof(kPayloadData), nullptr, &video_header, nullptr,
1262 kDefaultExpectedRetransmissionTimeMs));
ilnik10894992017-06-21 08:23:19 -07001263
Elad Alon4a87e1c2017-10-03 16:11:34 +02001264 EXPECT_CALL(mock_rtc_event_log_,
1265 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1266 .Times(2);
ilnik10894992017-06-21 08:23:19 -07001267 EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kMediaSsrc, kSeqNum + 1,
1268 fake_clock_.TimeInMilliseconds(),
1269 false, PacedPacketInfo()));
1270 EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kFlexfecSsrc, flexfec_seq_num,
1271 fake_clock_.TimeInMilliseconds(),
1272 false, PacedPacketInfo()));
1273 ASSERT_EQ(3, transport_.packets_sent());
1274 const RtpPacketReceived& media_packet2 = transport_.sent_packets_[1];
1275 EXPECT_EQ(kMediaPayloadType, media_packet2.PayloadType());
1276 EXPECT_EQ(kSeqNum + 1, media_packet2.SequenceNumber());
1277 EXPECT_EQ(kMediaSsrc, media_packet2.Ssrc());
1278 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[2];
1279 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
1280 EXPECT_EQ(flexfec_seq_num, flexfec_packet.SequenceNumber());
1281 EXPECT_EQ(kFlexfecSsrc, flexfec_packet.Ssrc());
1282}
1283
minyue3a407ee2017-04-03 01:10:33 -07001284TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
brandtrdbdb3f12016-11-10 05:04:48 -08001285 constexpr int kMediaPayloadType = 127;
1286 constexpr int kFlexfecPayloadType = 118;
1287 constexpr uint32_t kMediaSsrc = 1234;
1288 constexpr uint32_t kFlexfecSsrc = 5678;
1289 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001290 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
brandtrdbdb3f12016-11-10 05:04:48 -08001291 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
Steve Antonf0482ea2018-04-09 13:33:52 -07001292 kNoMid, kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001293 nullptr /* rtp_state */, &fake_clock_);
brandtrdbdb3f12016-11-10 05:04:48 -08001294
1295 // Reset |rtp_sender_| to use FlexFEC.
Benjamin Wright192eeec2018-10-17 17:27:25 -07001296 rtp_sender_.reset(new RTPSender(
1297 false, &fake_clock_, &transport_, nullptr, &flexfec_sender,
Niels Möller949f0fd2019-01-29 09:44:24 +01001298 &seq_num_allocator_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
1299 &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
1300 nullptr, false, false));
brandtrdbdb3f12016-11-10 05:04:48 -08001301 rtp_sender_->SetSSRC(kMediaSsrc);
1302 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtrdbdb3f12016-11-10 05:04:48 -08001303
1304 // Parameters selected to generate a single FEC packet per media packet.
1305 FecProtectionParams params;
1306 params.fec_rate = 15;
1307 params.max_fec_frames = 1;
1308 params.fec_mask_type = kFecMaskRandom;
1309 rtp_sender_->SetFecParameters(params, params);
1310
Elad Alon4a87e1c2017-10-03 16:11:34 +02001311 EXPECT_CALL(mock_rtc_event_log_,
1312 LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
1313 .Times(2);
brandtrdbdb3f12016-11-10 05:04:48 -08001314 SendGenericPayload();
1315 ASSERT_EQ(2, transport_.packets_sent());
1316 const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
1317 EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
1318 EXPECT_EQ(kMediaSsrc, media_packet.Ssrc());
1319 const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[1];
1320 EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
1321 EXPECT_EQ(kFlexfecSsrc, flexfec_packet.Ssrc());
1322}
1323
Steve Anton296a0ce2018-03-22 15:17:27 -07001324// Test that the MID header extension is included on sent packets when
1325// configured.
1326TEST_P(RtpSenderTestWithoutPacer, MidIncludedOnSentPackets) {
1327 const char kMid[] = "mid";
1328
1329 // Register MID header extension and set the MID for the RTPSender.
1330 rtp_sender_->SetSendingMediaStatus(false);
1331 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionMid, kMidExtensionId);
1332 rtp_sender_->SetMid(kMid);
1333 rtp_sender_->SetSendingMediaStatus(true);
1334
1335 // Send a couple packets.
1336 SendGenericPayload();
1337 SendGenericPayload();
1338
1339 // Expect both packets to have the MID set.
1340 ASSERT_EQ(2u, transport_.sent_packets_.size());
1341 for (const RtpPacketReceived& packet : transport_.sent_packets_) {
1342 std::string mid;
1343 ASSERT_TRUE(packet.GetExtension<RtpMid>(&mid));
1344 EXPECT_EQ(kMid, mid);
1345 }
1346}
1347
Amit Hilbuch77938e62018-12-21 09:23:38 -08001348TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnSentPackets) {
1349 const char kRid[] = "f";
1350
1351 rtp_sender_->SetSendingMediaStatus(false);
1352 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
1353 kRidExtensionId);
1354 rtp_sender_->SetRid(kRid);
1355 rtp_sender_->SetSendingMediaStatus(true);
1356
1357 SendGenericPayload();
1358
1359 ASSERT_EQ(1u, transport_.sent_packets_.size());
1360 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1361 std::string rid;
1362 ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
1363 EXPECT_EQ(kRid, rid);
1364}
1365
1366TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnRtxSentPackets) {
1367 const char kRid[] = "f";
1368 const uint8_t kPayloadType = 127;
1369
1370 rtp_sender_->SetSendingMediaStatus(false);
1371 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
1372 kRidExtensionId);
1373 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRepairedRtpStreamId,
1374 kRepairedRidExtensionId);
1375 rtp_sender_->SetRid(kRid);
1376 rtp_sender_->SetSendingMediaStatus(true);
1377
1378 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
1379 rtp_sender_->SetRtxSsrc(1234);
1380 rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayloadType);
1381
1382 rtp_sender_->SetStorePacketsStatus(true, 10);
1383
1384 SendGenericPayload();
1385 ASSERT_EQ(1u, transport_.sent_packets_.size());
1386 const RtpPacketReceived& packet = transport_.sent_packets_[0];
1387 std::string rid;
1388 ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
1389 EXPECT_EQ(kRid, rid);
1390 rid = kNoRid;
1391 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&rid));
1392
1393 uint16_t packet_id = packet.SequenceNumber();
1394 rtp_sender_->ReSendPacket(packet_id);
1395 ASSERT_EQ(2u, transport_.sent_packets_.size());
1396 const RtpPacketReceived& rtx_packet = transport_.sent_packets_[1];
1397 ASSERT_TRUE(rtx_packet.GetExtension<RepairedRtpStreamId>(&rid));
1398 EXPECT_EQ(kRid, rid);
1399 EXPECT_FALSE(rtx_packet.HasExtension<RtpStreamId>());
1400}
1401
minyue3a407ee2017-04-03 01:10:33 -07001402TEST_P(RtpSenderTest, FecOverheadRate) {
brandtr81eab612017-01-24 04:06:09 -08001403 constexpr int kFlexfecPayloadType = 118;
1404 constexpr uint32_t kMediaSsrc = 1234;
1405 constexpr uint32_t kFlexfecSsrc = 5678;
1406 const std::vector<RtpExtension> kNoRtpExtensions;
erikvarga27883732017-05-17 05:08:38 -07001407 const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
brandtr81eab612017-01-24 04:06:09 -08001408 FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
Steve Antonf0482ea2018-04-09 13:33:52 -07001409 kNoMid, kNoRtpExtensions, kNoRtpExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -07001410 nullptr /* rtp_state */, &fake_clock_);
brandtr81eab612017-01-24 04:06:09 -08001411
1412 // Reset |rtp_sender_| to use FlexFEC.
1413 rtp_sender_.reset(new RTPSender(
1414 false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
Niels Möller949f0fd2019-01-29 09:44:24 +01001415 &seq_num_allocator_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
1416 &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
1417 nullptr, false, false));
brandtr81eab612017-01-24 04:06:09 -08001418 rtp_sender_->SetSSRC(kMediaSsrc);
1419 rtp_sender_->SetSequenceNumber(kSeqNum);
brandtr81eab612017-01-24 04:06:09 -08001420
1421 // Parameters selected to generate a single FEC packet per media packet.
1422 FecProtectionParams params;
1423 params.fec_rate = 15;
1424 params.max_fec_frames = 1;
1425 params.fec_mask_type = kFecMaskRandom;
1426 rtp_sender_->SetFecParameters(params, params);
1427
1428 constexpr size_t kNumMediaPackets = 10;
1429 constexpr size_t kNumFecPackets = kNumMediaPackets;
1430 constexpr int64_t kTimeBetweenPacketsMs = 10;
1431 EXPECT_CALL(mock_paced_sender_, InsertPacket(_, _, _, _, _, false))
1432 .Times(kNumMediaPackets + kNumFecPackets);
1433 for (size_t i = 0; i < kNumMediaPackets; ++i) {
1434 SendGenericPayload();
1435 fake_clock_.AdvanceTimeMilliseconds(kTimeBetweenPacketsMs);
1436 }
1437 constexpr size_t kRtpHeaderLength = 12;
1438 constexpr size_t kFlexfecHeaderLength = 20;
1439 constexpr size_t kGenericCodecHeaderLength = 1;
1440 constexpr size_t kPayloadLength = sizeof(kPayloadData);
1441 constexpr size_t kPacketLength = kRtpHeaderLength + kFlexfecHeaderLength +
1442 kGenericCodecHeaderLength + kPayloadLength;
1443 EXPECT_NEAR(kNumFecPackets * kPacketLength * 8 /
1444 (kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f),
1445 rtp_sender_->FecOverheadRate(), 500);
1446}
1447
minyue3a407ee2017-04-03 01:10:33 -07001448TEST_P(RtpSenderTest, BitrateCallbacks) {
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001449 class TestCallback : public BitrateStatisticsObserver {
1450 public:
sprangcd349d92016-07-13 09:11:28 -07001451 TestCallback()
1452 : BitrateStatisticsObserver(),
1453 num_calls_(0),
1454 ssrc_(0),
1455 total_bitrate_(0),
1456 retransmit_bitrate_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +00001457 ~TestCallback() override = default;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001458
sprangcd349d92016-07-13 09:11:28 -07001459 void Notify(uint32_t total_bitrate,
1460 uint32_t retransmit_bitrate,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001461 uint32_t ssrc) override {
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001462 ++num_calls_;
1463 ssrc_ = ssrc;
sprangcd349d92016-07-13 09:11:28 -07001464 total_bitrate_ = total_bitrate;
1465 retransmit_bitrate_ = retransmit_bitrate;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001466 }
1467
1468 uint32_t num_calls_;
1469 uint32_t ssrc_;
sprangcd349d92016-07-13 09:11:28 -07001470 uint32_t total_bitrate_;
1471 uint32_t retransmit_bitrate_;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001472 } callback;
Benjamin Wright192eeec2018-10-17 17:27:25 -07001473 rtp_sender_.reset(new RTPSender(
1474 false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
Niels Möller949f0fd2019-01-29 09:44:24 +01001475 &callback, nullptr, nullptr, nullptr, &retransmission_rate_limiter_,
1476 nullptr, false, nullptr, false, false));
nisse7d59f6b2017-02-21 03:40:24 -08001477 rtp_sender_->SetSSRC(kSsrc);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001478
sprangcd349d92016-07-13 09:11:28 -07001479 // Simulate kNumPackets sent with kPacketInterval ms intervals, with the
1480 // number of packets selected so that we fill (but don't overflow) the one
1481 // second averaging window.
1482 const uint32_t kWindowSizeMs = 1000;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001483 const uint32_t kPacketInterval = 20;
sprangcd349d92016-07-13 09:11:28 -07001484 const uint32_t kNumPackets =
1485 (kWindowSizeMs - kPacketInterval) / kPacketInterval;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001486 // Overhead = 12 bytes RTP header + 1 byte generic header.
1487 const uint32_t kPacketOverhead = 13;
1488
Niels Möller8a40edd2019-01-24 18:04:44 +01001489 const char payload_name[] = "GENERIC";
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001490 const uint8_t payload_type = 127;
danilchap162abd32015-12-10 02:39:40 -08001491 ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000,
1492 0, 1500));
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001493 uint8_t payload[] = {47, 11, 32, 93, 89};
1494 rtp_sender_->SetStorePacketsStatus(true, 1);
1495 uint32_t ssrc = rtp_sender_->SSRC();
1496
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001497 // Initial process call so we get a new time window.
1498 rtp_sender_->ProcessBitrate();
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001499
1500 // Send a few frames.
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001501 RTPVideoHeader video_header;
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001502 for (uint32_t i = 0; i < kNumPackets; ++i) {
Sergey Ulanov525df3f2016-08-02 17:46:41 -07001503 ASSERT_TRUE(rtp_sender_->SendOutgoingData(
1504 kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001505 nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001506 fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
1507 }
1508
1509 rtp_sender_->ProcessBitrate();
1510
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001511 // We get one call for every stats updated, thus two calls since both the
1512 // stream stats and the retransmit stats are updated once.
1513 EXPECT_EQ(2u, callback.num_calls_);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001514 EXPECT_EQ(ssrc, callback.ssrc_);
sprangcd349d92016-07-13 09:11:28 -07001515 const uint32_t kTotalPacketSize = kPacketOverhead + sizeof(payload);
1516 // Bitrate measured over delta between last and first timestamp, plus one.
1517 const uint32_t kExpectedWindowMs = kNumPackets * kPacketInterval + 1;
1518 const uint32_t kExpectedBitsAccumulated = kTotalPacketSize * kNumPackets * 8;
1519 const uint32_t kExpectedRateBps =
1520 (kExpectedBitsAccumulated * 1000 + (kExpectedWindowMs / 2)) /
1521 kExpectedWindowMs;
1522 EXPECT_EQ(kExpectedRateBps, callback.total_bitrate_);
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001523
andresp@webrtc.orgd11bec42014-07-08 14:32:58 +00001524 rtp_sender_.reset();
sprang@webrtc.org6811b6e2013-12-13 09:46:59 +00001525}
1526
minyue3a407ee2017-04-03 01:10:33 -07001527TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001528 class TestCallback : public StreamDataCountersCallback {
1529 public:
danilchap162abd32015-12-10 02:39:40 -08001530 TestCallback() : StreamDataCountersCallback(), ssrc_(0), counters_() {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +00001531 ~TestCallback() override = default;
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001532
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001533 void DataCountersUpdated(const StreamDataCounters& counters,
1534 uint32_t ssrc) override {
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001535 ssrc_ = ssrc;
1536 counters_ = counters;
1537 }
1538
1539 uint32_t ssrc_;
1540 StreamDataCounters counters_;
asapersson@webrtc.org44149392015-02-04 08:34:47 +00001541
1542 void MatchPacketCounter(const RtpPacketCounter& expected,
1543 const RtpPacketCounter& actual) {
1544 EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
1545 EXPECT_EQ(expected.header_bytes, actual.header_bytes);
1546 EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
1547 EXPECT_EQ(expected.packets, actual.packets);
1548 }
1549
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001550 void Matches(uint32_t ssrc, const StreamDataCounters& counters) {
1551 EXPECT_EQ(ssrc, ssrc_);
asapersson@webrtc.org44149392015-02-04 08:34:47 +00001552 MatchPacketCounter(counters.transmitted, counters_.transmitted);
1553 MatchPacketCounter(counters.retransmitted, counters_.retransmitted);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001554 EXPECT_EQ(counters.fec.packets, counters_.fec.packets);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001555 }
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001556 } callback;
1557
1558 const uint8_t kRedPayloadType = 96;
1559 const uint8_t kUlpfecPayloadType = 97;
Niels Möller8a40edd2019-01-24 18:04:44 +01001560 const char payload_name[] = "GENERIC";
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001561 const uint8_t payload_type = 127;
1562 ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000,
1563 0, 1500));
1564 uint8_t payload[] = {47, 11, 32, 93, 89};
1565 rtp_sender_->SetStorePacketsStatus(true, 1);
1566 uint32_t ssrc = rtp_sender_->SSRC();
1567
1568 rtp_sender_->RegisterRtpStatisticsCallback(&callback);
1569
1570 // Send a frame.
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001571 RTPVideoHeader video_header;
Sergey Ulanov525df3f2016-08-02 17:46:41 -07001572 ASSERT_TRUE(rtp_sender_->SendOutgoingData(
spranga8ae6f22017-09-04 07:23:56 -07001573 kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001574 nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001575 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001576 expected.transmitted.payload_bytes = 6;
1577 expected.transmitted.header_bytes = 12;
1578 expected.transmitted.padding_bytes = 0;
1579 expected.transmitted.packets = 1;
1580 expected.retransmitted.payload_bytes = 0;
1581 expected.retransmitted.header_bytes = 0;
1582 expected.retransmitted.padding_bytes = 0;
1583 expected.retransmitted.packets = 0;
1584 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001585 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001586
1587 // Retransmit a frame.
1588 uint16_t seqno = rtp_sender_->SequenceNumber() - 1;
Erik Språnga12b1d62018-03-14 12:39:24 +01001589 rtp_sender_->ReSendPacket(seqno);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001590 expected.transmitted.payload_bytes = 12;
1591 expected.transmitted.header_bytes = 24;
1592 expected.transmitted.packets = 2;
1593 expected.retransmitted.payload_bytes = 6;
1594 expected.retransmitted.header_bytes = 12;
1595 expected.retransmitted.padding_bytes = 0;
1596 expected.retransmitted.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001597 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001598
1599 // Send padding.
philipel8aadd502017-02-23 02:56:13 -08001600 rtp_sender_->TimeToSendPadding(kMaxPaddingSize, PacedPacketInfo());
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001601 expected.transmitted.payload_bytes = 12;
1602 expected.transmitted.header_bytes = 36;
1603 expected.transmitted.padding_bytes = kMaxPaddingSize;
1604 expected.transmitted.packets = 3;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001605 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001606
brandtrf1bb4762016-11-07 03:05:06 -08001607 // Send ULPFEC.
1608 rtp_sender_->SetUlpfecConfig(kRedPayloadType, kUlpfecPayloadType);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001609 FecProtectionParams fec_params;
1610 fec_params.fec_mask_type = kFecMaskRandom;
1611 fec_params.fec_rate = 1;
1612 fec_params.max_fec_frames = 1;
brandtr1743a192016-11-07 03:36:05 -08001613 rtp_sender_->SetFecParameters(fec_params, fec_params);
Sergey Ulanov525df3f2016-08-02 17:46:41 -07001614 ASSERT_TRUE(rtp_sender_->SendOutgoingData(
spranga8ae6f22017-09-04 07:23:56 -07001615 kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001616 nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001617 expected.transmitted.payload_bytes = 40;
1618 expected.transmitted.header_bytes = 60;
1619 expected.transmitted.packets = 5;
1620 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001621 callback.Matches(ssrc, expected);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001622
sprang867fb522015-08-03 04:38:41 -07001623 rtp_sender_->RegisterRtpStatisticsCallback(nullptr);
sprang@webrtc.orgebad7652013-12-05 14:29:02 +00001624}
1625
minyue3a407ee2017-04-03 01:10:33 -07001626TEST_P(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001627 const char* kPayloadName = "GENERIC";
1628 const uint8_t kPayloadType = 127;
1629 rtp_sender_->SetSSRC(1234);
1630 rtp_sender_->SetRtxSsrc(4321);
Shao Changbine62202f2015-04-21 20:24:50 +08001631 rtp_sender_->SetRtxPayloadType(kPayloadType - 1, kPayloadType);
pbos@webrtc.org0b0c2412015-01-13 14:15:15 +00001632 rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001633
danilchap162abd32015-12-10 02:39:40 -08001634 ASSERT_EQ(0, rtp_sender_->RegisterPayload(kPayloadName, kPayloadType, 90000,
1635 0, 1500));
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001636 uint8_t payload[] = {47, 11, 32, 93, 89};
1637
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001638 RTPVideoHeader video_header;
Sergey Ulanov525df3f2016-08-02 17:46:41 -07001639 ASSERT_TRUE(rtp_sender_->SendOutgoingData(
spranga8ae6f22017-09-04 07:23:56 -07001640 kVideoFrameKey, kPayloadType, 1234, 4321, payload, sizeof(payload),
Sami Kalliomäki426a80c2018-08-08 11:37:59 +02001641 nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001642
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001643 // Will send 2 full-size padding packets.
philipel8aadd502017-02-23 02:56:13 -08001644 rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
1645 rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001646
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001647 StreamDataCounters rtp_stats;
1648 StreamDataCounters rtx_stats;
1649 rtp_sender_->GetDataCounters(&rtp_stats, &rtx_stats);
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001650
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001651 // Payload + 1-byte generic header.
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +00001652 EXPECT_GT(rtp_stats.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001653 EXPECT_EQ(rtp_stats.transmitted.payload_bytes, sizeof(payload) + 1);
1654 EXPECT_EQ(rtp_stats.transmitted.header_bytes, 12u);
1655 EXPECT_EQ(rtp_stats.transmitted.padding_bytes, 0u);
1656 EXPECT_EQ(rtx_stats.transmitted.payload_bytes, 0u);
1657 EXPECT_EQ(rtx_stats.transmitted.header_bytes, 24u);
1658 EXPECT_EQ(rtx_stats.transmitted.padding_bytes, 2 * kMaxPaddingSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00001659
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001660 EXPECT_EQ(rtp_stats.transmitted.TotalBytes(),
danilchap162abd32015-12-10 02:39:40 -08001661 rtp_stats.transmitted.payload_bytes +
1662 rtp_stats.transmitted.header_bytes +
1663 rtp_stats.transmitted.padding_bytes);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001664 EXPECT_EQ(rtx_stats.transmitted.TotalBytes(),
danilchap162abd32015-12-10 02:39:40 -08001665 rtx_stats.transmitted.payload_bytes +
1666 rtx_stats.transmitted.header_bytes +
1667 rtx_stats.transmitted.padding_bytes);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +00001668
danilchap162abd32015-12-10 02:39:40 -08001669 EXPECT_EQ(
1670 transport_.total_bytes_sent_,
1671 rtp_stats.transmitted.TotalBytes() + rtx_stats.transmitted.TotalBytes());
pbos@webrtc.org72491b92014-07-10 16:24:54 +00001672}
guoweis@webrtc.org45362892015-03-04 22:55:15 +00001673
minyue3a407ee2017-04-03 01:10:33 -07001674TEST_P(RtpSenderTestWithoutPacer, RespectsNackBitrateLimit) {
sprang38778b02015-09-29 09:48:22 -07001675 const int32_t kPacketSize = 1400;
1676 const int32_t kNumPackets = 30;
1677
sprangcd349d92016-07-13 09:11:28 -07001678 retransmission_rate_limiter_.SetMaxRate(kPacketSize * kNumPackets * 8);
1679
sprang38778b02015-09-29 09:48:22 -07001680 rtp_sender_->SetStorePacketsStatus(true, kNumPackets);
sprang38778b02015-09-29 09:48:22 -07001681 const uint16_t kStartSequenceNumber = rtp_sender_->SequenceNumber();
Danil Chapovalov2800d742016-08-26 18:48:46 +02001682 std::vector<uint16_t> sequence_numbers;
sprang38778b02015-09-29 09:48:22 -07001683 for (int32_t i = 0; i < kNumPackets; ++i) {
1684 sequence_numbers.push_back(kStartSequenceNumber + i);
1685 fake_clock_.AdvanceTimeMilliseconds(1);
1686 SendPacket(fake_clock_.TimeInMilliseconds(), kPacketSize);
1687 }
danilchap12ba1862016-10-26 02:41:55 -07001688 EXPECT_EQ(kNumPackets, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001689
1690 fake_clock_.AdvanceTimeMilliseconds(1000 - kNumPackets);
1691
1692 // Resending should work - brings the bandwidth up to the limit.
1693 // NACK bitrate is capped to the same bitrate as the encoder, since the max
1694 // protection overhead is 50% (see MediaOptimization::SetTargetRates).
Danil Chapovalov2800d742016-08-26 18:48:46 +02001695 rtp_sender_->OnReceivedNack(sequence_numbers, 0);
danilchap12ba1862016-10-26 02:41:55 -07001696 EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001697
sprangcd349d92016-07-13 09:11:28 -07001698 // Must be at least 5ms in between retransmission attempts.
1699 fake_clock_.AdvanceTimeMilliseconds(5);
1700
sprang38778b02015-09-29 09:48:22 -07001701 // Resending should not work, bandwidth exceeded.
Danil Chapovalov2800d742016-08-26 18:48:46 +02001702 rtp_sender_->OnReceivedNack(sequence_numbers, 0);
danilchap12ba1862016-10-26 02:41:55 -07001703 EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
sprang38778b02015-09-29 09:48:22 -07001704}
1705
minyue3a407ee2017-04-03 01:10:33 -07001706TEST_P(RtpSenderVideoTest, KeyFrameHasCVO) {
danilchapb6f1fb52016-10-19 06:11:39 -07001707 uint8_t kFrame[kMaxPacketLength];
guoweis@webrtc.org45362892015-03-04 22:55:15 +00001708 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1709 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
guoweis@webrtc.org45362892015-03-04 22:55:15 +00001710
philipel1a4746a2018-07-09 15:52:29 +02001711 RTPVideoHeader hdr;
danilchapc1600c52016-10-26 03:33:11 -07001712 hdr.rotation = kVideoRotation_0;
Niels Möller3ea55d52019-01-24 09:44:14 +01001713 rtp_sender_video_->SendVideo(kVideoFrameKey, kPayload, kTimestamp, 0, kFrame,
1714 sizeof(kFrame), nullptr, &hdr,
1715 kDefaultExpectedRetransmissionTimeMs);
guoweis@webrtc.org45362892015-03-04 22:55:15 +00001716
danilchapc1600c52016-10-26 03:33:11 -07001717 VideoRotation rotation;
1718 EXPECT_TRUE(
1719 transport_.last_sent_packet().GetExtension<VideoOrientation>(&rotation));
1720 EXPECT_EQ(kVideoRotation_0, rotation);
1721}
guoweis@webrtc.org45362892015-03-04 22:55:15 +00001722
ilnik04f4d122017-06-19 07:18:55 -07001723TEST_P(RtpSenderVideoTest, TimingFrameHasPacketizationTimstampSet) {
1724 uint8_t kFrame[kMaxPacketLength];
1725 const int64_t kPacketizationTimeMs = 100;
1726 const int64_t kEncodeStartDeltaMs = 10;
1727 const int64_t kEncodeFinishDeltaMs = 50;
1728 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1729 kRtpExtensionVideoTiming, kVideoTimingExtensionId));
1730
1731 const int64_t kCaptureTimestamp = fake_clock_.TimeInMilliseconds();
1732
philipel1a4746a2018-07-09 15:52:29 +02001733 RTPVideoHeader hdr;
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +02001734 hdr.video_timing.flags = VideoSendTiming::kTriggeredByTimer;
ilnik04f4d122017-06-19 07:18:55 -07001735 hdr.video_timing.encode_start_delta_ms = kEncodeStartDeltaMs;
1736 hdr.video_timing.encode_finish_delta_ms = kEncodeFinishDeltaMs;
1737
1738 fake_clock_.AdvanceTimeMilliseconds(kPacketizationTimeMs);
Niels Möller3ea55d52019-01-24 09:44:14 +01001739 rtp_sender_video_->SendVideo(
1740 kVideoFrameKey, kPayload, kTimestamp, kCaptureTimestamp, kFrame,
1741 sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs);
ilnik2edc6842017-07-06 03:06:50 -07001742 VideoSendTiming timing;
ilnik04f4d122017-06-19 07:18:55 -07001743 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
1744 &timing));
1745 EXPECT_EQ(kPacketizationTimeMs, timing.packetization_finish_delta_ms);
1746 EXPECT_EQ(kEncodeStartDeltaMs, timing.encode_start_delta_ms);
1747 EXPECT_EQ(kEncodeFinishDeltaMs, timing.encode_finish_delta_ms);
1748}
1749
minyue3a407ee2017-04-03 01:10:33 -07001750TEST_P(RtpSenderVideoTest, DeltaFrameHasCVOWhenChanged) {
danilchapc1600c52016-10-26 03:33:11 -07001751 uint8_t kFrame[kMaxPacketLength];
1752 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1753 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
1754
philipel1a4746a2018-07-09 15:52:29 +02001755 RTPVideoHeader hdr;
danilchapc1600c52016-10-26 03:33:11 -07001756 hdr.rotation = kVideoRotation_90;
spranga8ae6f22017-09-04 07:23:56 -07001757 EXPECT_TRUE(rtp_sender_video_->SendVideo(
Niels Möller3ea55d52019-01-24 09:44:14 +01001758 kVideoFrameKey, kPayload, kTimestamp, 0, kFrame, sizeof(kFrame), nullptr,
1759 &hdr, kDefaultExpectedRetransmissionTimeMs));
danilchapc1600c52016-10-26 03:33:11 -07001760
1761 hdr.rotation = kVideoRotation_0;
spranga8ae6f22017-09-04 07:23:56 -07001762 EXPECT_TRUE(rtp_sender_video_->SendVideo(
Niels Möller3ea55d52019-01-24 09:44:14 +01001763 kVideoFrameDelta, kPayload, kTimestamp + 1, 0, kFrame, sizeof(kFrame),
1764 nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs));
danilchapc1600c52016-10-26 03:33:11 -07001765
1766 VideoRotation rotation;
1767 EXPECT_TRUE(
1768 transport_.last_sent_packet().GetExtension<VideoOrientation>(&rotation));
1769 EXPECT_EQ(kVideoRotation_0, rotation);
1770}
1771
minyue3a407ee2017-04-03 01:10:33 -07001772TEST_P(RtpSenderVideoTest, DeltaFrameHasCVOWhenNonZero) {
danilchapc1600c52016-10-26 03:33:11 -07001773 uint8_t kFrame[kMaxPacketLength];
1774 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
1775 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
1776
philipel1a4746a2018-07-09 15:52:29 +02001777 RTPVideoHeader hdr;
danilchapc1600c52016-10-26 03:33:11 -07001778 hdr.rotation = kVideoRotation_90;
spranga8ae6f22017-09-04 07:23:56 -07001779 EXPECT_TRUE(rtp_sender_video_->SendVideo(
Niels Möller3ea55d52019-01-24 09:44:14 +01001780 kVideoFrameKey, kPayload, kTimestamp, 0, kFrame, sizeof(kFrame), nullptr,
1781 &hdr, kDefaultExpectedRetransmissionTimeMs));
danilchapc1600c52016-10-26 03:33:11 -07001782
spranga8ae6f22017-09-04 07:23:56 -07001783 EXPECT_TRUE(rtp_sender_video_->SendVideo(
Niels Möller3ea55d52019-01-24 09:44:14 +01001784 kVideoFrameDelta, kPayload, kTimestamp + 1, 0, kFrame, sizeof(kFrame),
1785 nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs));
danilchapc1600c52016-10-26 03:33:11 -07001786
1787 VideoRotation rotation;
1788 EXPECT_TRUE(
1789 transport_.last_sent_packet().GetExtension<VideoOrientation>(&rotation));
1790 EXPECT_EQ(kVideoRotation_90, rotation);
guoweis@webrtc.org45362892015-03-04 22:55:15 +00001791}
magjed71eb61c2016-09-08 03:24:58 -07001792
1793// Make sure rotation is parsed correctly when the Camera (C) and Flip (F) bits
1794// are set in the CVO byte.
minyue3a407ee2017-04-03 01:10:33 -07001795TEST_P(RtpSenderVideoTest, SendVideoWithCameraAndFlipCVO) {
magjed71eb61c2016-09-08 03:24:58 -07001796 // Test extracting rotation when Camera (C) and Flip (F) bits are zero.
1797 EXPECT_EQ(kVideoRotation_0, ConvertCVOByteToVideoRotation(0));
1798 EXPECT_EQ(kVideoRotation_90, ConvertCVOByteToVideoRotation(1));
1799 EXPECT_EQ(kVideoRotation_180, ConvertCVOByteToVideoRotation(2));
1800 EXPECT_EQ(kVideoRotation_270, ConvertCVOByteToVideoRotation(3));
1801 // Test extracting rotation when Camera (C) and Flip (F) bits are set.
1802 const int flip_bit = 1 << 2;
1803 const int camera_bit = 1 << 3;
1804 EXPECT_EQ(kVideoRotation_0,
1805 ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 0));
1806 EXPECT_EQ(kVideoRotation_90,
1807 ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 1));
1808 EXPECT_EQ(kVideoRotation_180,
1809 ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 2));
1810 EXPECT_EQ(kVideoRotation_270,
1811 ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 3));
1812}
1813
spranga8ae6f22017-09-04 07:23:56 -07001814TEST_P(RtpSenderVideoTest, RetransmissionTypesGeneric) {
1815 RTPVideoHeader header;
Niels Möller520ca4e2018-06-04 11:14:38 +02001816 header.codec = kVideoCodecGeneric;
spranga8ae6f22017-09-04 07:23:56 -07001817
1818 EXPECT_EQ(kDontRetransmit,
1819 rtp_sender_video_->GetStorageType(
1820 header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
1821 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1822 header, kRetransmitBaseLayer,
1823 kDefaultExpectedRetransmissionTimeMs));
1824 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1825 header, kRetransmitHigherLayers,
1826 kDefaultExpectedRetransmissionTimeMs));
1827 EXPECT_EQ(kAllowRetransmission,
1828 rtp_sender_video_->GetStorageType(
1829 header, kConditionallyRetransmitHigherLayers,
1830 kDefaultExpectedRetransmissionTimeMs));
1831 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1832 header, kRetransmitAllPackets,
1833 kDefaultExpectedRetransmissionTimeMs));
1834}
1835
1836TEST_P(RtpSenderVideoTest, RetransmissionTypesH264) {
1837 RTPVideoHeader header;
philipel7d745e52018-08-02 14:03:53 +02001838 header.video_type_header.emplace<RTPVideoHeaderH264>().packetization_mode =
1839 H264PacketizationMode::NonInterleaved;
Niels Möller520ca4e2018-06-04 11:14:38 +02001840 header.codec = kVideoCodecH264;
spranga8ae6f22017-09-04 07:23:56 -07001841
1842 EXPECT_EQ(kDontRetransmit,
1843 rtp_sender_video_->GetStorageType(
1844 header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
1845 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1846 header, kRetransmitBaseLayer,
1847 kDefaultExpectedRetransmissionTimeMs));
1848 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1849 header, kRetransmitHigherLayers,
1850 kDefaultExpectedRetransmissionTimeMs));
1851 EXPECT_EQ(kAllowRetransmission,
1852 rtp_sender_video_->GetStorageType(
1853 header, kConditionallyRetransmitHigherLayers,
1854 kDefaultExpectedRetransmissionTimeMs));
1855 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1856 header, kRetransmitAllPackets,
1857 kDefaultExpectedRetransmissionTimeMs));
1858}
1859
1860TEST_P(RtpSenderVideoTest, RetransmissionTypesVP8BaseLayer) {
1861 RTPVideoHeader header;
Niels Möller520ca4e2018-06-04 11:14:38 +02001862 header.codec = kVideoCodecVP8;
Philip Eliassond52a1a62018-09-07 13:03:55 +00001863 auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
1864 vp8_header.temporalIdx = 0;
spranga8ae6f22017-09-04 07:23:56 -07001865
1866 EXPECT_EQ(kDontRetransmit,
1867 rtp_sender_video_->GetStorageType(
1868 header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
1869 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1870 header, kRetransmitBaseLayer,
1871 kDefaultExpectedRetransmissionTimeMs));
1872 EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
1873 header, kRetransmitHigherLayers,
1874 kDefaultExpectedRetransmissionTimeMs));
1875 EXPECT_EQ(kAllowRetransmission,
1876 rtp_sender_video_->GetStorageType(
1877 header, kRetransmitHigherLayers | kRetransmitBaseLayer,
1878 kDefaultExpectedRetransmissionTimeMs));
1879 EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
1880 header, kConditionallyRetransmitHigherLayers,
1881 kDefaultExpectedRetransmissionTimeMs));
1882 EXPECT_EQ(
1883 kAllowRetransmission,
1884 rtp_sender_video_->GetStorageType(
1885 header, kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers,
1886 kDefaultExpectedRetransmissionTimeMs));
1887 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1888 header, kRetransmitAllPackets,
1889 kDefaultExpectedRetransmissionTimeMs));
1890}
1891
1892TEST_P(RtpSenderVideoTest, RetransmissionTypesVP8HigherLayers) {
1893 RTPVideoHeader header;
Niels Möller520ca4e2018-06-04 11:14:38 +02001894 header.codec = kVideoCodecVP8;
spranga8ae6f22017-09-04 07:23:56 -07001895
Philip Eliassond52a1a62018-09-07 13:03:55 +00001896 auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
spranga8ae6f22017-09-04 07:23:56 -07001897 for (int tid = 1; tid <= kMaxTemporalStreams; ++tid) {
Philip Eliassond52a1a62018-09-07 13:03:55 +00001898 vp8_header.temporalIdx = tid;
spranga8ae6f22017-09-04 07:23:56 -07001899
1900 EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
1901 header, kRetransmitOff,
1902 kDefaultExpectedRetransmissionTimeMs));
1903 EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
1904 header, kRetransmitBaseLayer,
1905 kDefaultExpectedRetransmissionTimeMs));
1906 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1907 header, kRetransmitHigherLayers,
1908 kDefaultExpectedRetransmissionTimeMs));
1909 EXPECT_EQ(kAllowRetransmission,
1910 rtp_sender_video_->GetStorageType(
1911 header, kRetransmitHigherLayers | kRetransmitBaseLayer,
1912 kDefaultExpectedRetransmissionTimeMs));
1913 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1914 header, kRetransmitAllPackets,
1915 kDefaultExpectedRetransmissionTimeMs));
1916 }
1917}
1918
1919TEST_P(RtpSenderVideoTest, RetransmissionTypesVP9) {
1920 RTPVideoHeader header;
Niels Möller520ca4e2018-06-04 11:14:38 +02001921 header.codec = kVideoCodecVP9;
spranga8ae6f22017-09-04 07:23:56 -07001922
philipel29d88462018-08-08 14:26:00 +02001923 auto& vp9_header = header.video_type_header.emplace<RTPVideoHeaderVP9>();
spranga8ae6f22017-09-04 07:23:56 -07001924 for (int tid = 1; tid <= kMaxTemporalStreams; ++tid) {
philipel29d88462018-08-08 14:26:00 +02001925 vp9_header.temporal_idx = tid;
spranga8ae6f22017-09-04 07:23:56 -07001926
1927 EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
1928 header, kRetransmitOff,
1929 kDefaultExpectedRetransmissionTimeMs));
1930 EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
1931 header, kRetransmitBaseLayer,
1932 kDefaultExpectedRetransmissionTimeMs));
1933 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1934 header, kRetransmitHigherLayers,
1935 kDefaultExpectedRetransmissionTimeMs));
1936 EXPECT_EQ(kAllowRetransmission,
1937 rtp_sender_video_->GetStorageType(
1938 header, kRetransmitHigherLayers | kRetransmitBaseLayer,
1939 kDefaultExpectedRetransmissionTimeMs));
1940 EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
1941 header, kRetransmitAllPackets,
1942 kDefaultExpectedRetransmissionTimeMs));
1943 }
1944}
1945
1946TEST_P(RtpSenderVideoTest, ConditionalRetransmit) {
1947 const int64_t kFrameIntervalMs = 33;
1948 const int64_t kRttMs = (kFrameIntervalMs * 3) / 2;
1949 const uint8_t kSettings =
1950 kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers;
1951
1952 // Insert VP8 frames for all temporal layers, but stop before the final index.
1953 RTPVideoHeader header;
Niels Möller520ca4e2018-06-04 11:14:38 +02001954 header.codec = kVideoCodecVP8;
spranga8ae6f22017-09-04 07:23:56 -07001955
1956 // Fill averaging window to prevent rounding errors.
1957 constexpr int kNumRepetitions =
1958 (RTPSenderVideo::kTLRateWindowSizeMs + (kFrameIntervalMs / 2)) /
1959 kFrameIntervalMs;
1960 constexpr int kPattern[] = {0, 2, 1, 2};
Philip Eliassond52a1a62018-09-07 13:03:55 +00001961 auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
spranga8ae6f22017-09-04 07:23:56 -07001962 for (size_t i = 0; i < arraysize(kPattern) * kNumRepetitions; ++i) {
Philip Eliassond52a1a62018-09-07 13:03:55 +00001963 vp8_header.temporalIdx = kPattern[i % arraysize(kPattern)];
spranga8ae6f22017-09-04 07:23:56 -07001964 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs);
1965 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
1966 }
1967
1968 // Since we're at the start of the pattern, the next expected frame in TL0 is
1969 // right now. We will wait at most one expected retransmission time before
1970 // acknowledging that it did not arrive, which means this frame and the next
1971 // will not be retransmitted.
Philip Eliassond52a1a62018-09-07 13:03:55 +00001972 vp8_header.temporalIdx = 1;
spranga8ae6f22017-09-04 07:23:56 -07001973 EXPECT_EQ(StorageType::kDontRetransmit,
1974 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
1975 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
1976 EXPECT_EQ(StorageType::kDontRetransmit,
1977 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
1978 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
1979
1980 // The TL0 frame did not arrive. So allow retransmission.
1981 EXPECT_EQ(StorageType::kAllowRetransmission,
1982 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
1983 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
1984
1985 // Insert a frame for TL2. We just had frame in TL1, so the next one there is
1986 // in three frames away. TL0 is still too far in the past. So, allow
1987 // retransmission.
Philip Eliassond52a1a62018-09-07 13:03:55 +00001988 vp8_header.temporalIdx = 2;
spranga8ae6f22017-09-04 07:23:56 -07001989 EXPECT_EQ(StorageType::kAllowRetransmission,
1990 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
1991 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
1992
1993 // Another TL2, next in TL1 is two frames away. Allow again.
1994 EXPECT_EQ(StorageType::kAllowRetransmission,
1995 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
1996 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
1997
1998 // Yet another TL2, next in TL1 is now only one frame away, so don't store
1999 // for retransmission.
2000 EXPECT_EQ(StorageType::kDontRetransmit,
2001 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
2002}
2003
2004TEST_P(RtpSenderVideoTest, ConditionalRetransmitLimit) {
2005 const int64_t kFrameIntervalMs = 200;
2006 const int64_t kRttMs = (kFrameIntervalMs * 3) / 2;
2007 const int32_t kSettings =
2008 kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers;
2009
2010 // Insert VP8 frames for all temporal layers, but stop before the final index.
2011 RTPVideoHeader header;
Niels Möller520ca4e2018-06-04 11:14:38 +02002012 header.codec = kVideoCodecVP8;
spranga8ae6f22017-09-04 07:23:56 -07002013
2014 // Fill averaging window to prevent rounding errors.
2015 constexpr int kNumRepetitions =
2016 (RTPSenderVideo::kTLRateWindowSizeMs + (kFrameIntervalMs / 2)) /
2017 kFrameIntervalMs;
2018 constexpr int kPattern[] = {0, 2, 2, 2};
Philip Eliassond52a1a62018-09-07 13:03:55 +00002019 auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
spranga8ae6f22017-09-04 07:23:56 -07002020 for (size_t i = 0; i < arraysize(kPattern) * kNumRepetitions; ++i) {
Philip Eliassond52a1a62018-09-07 13:03:55 +00002021 vp8_header.temporalIdx = kPattern[i % arraysize(kPattern)];
spranga8ae6f22017-09-04 07:23:56 -07002022
2023 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs);
2024 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
2025 }
2026
2027 // Since we're at the start of the pattern, the next expected frame will be
2028 // right now in TL0. Put it in TL1 instead. Regular rules would dictate that
2029 // we don't store for retransmission because we expect a frame in a lower
2030 // layer, but that last frame in TL1 was a long time ago in absolute terms,
2031 // so allow retransmission anyway.
Philip Eliassond52a1a62018-09-07 13:03:55 +00002032 vp8_header.temporalIdx = 1;
spranga8ae6f22017-09-04 07:23:56 -07002033 EXPECT_EQ(StorageType::kAllowRetransmission,
2034 rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
2035}
2036
philipelb3e42a42018-09-13 10:57:14 +02002037TEST_P(RtpSenderVideoTest, PopulateGenericFrameDescriptor) {
2038 const int64_t kFrameId = 100000;
2039 uint8_t kFrame[100];
2040 EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
2041 kRtpExtensionGenericFrameDescriptor, kGenericDescriptorId));
2042
2043 RTPVideoHeader hdr;
2044 RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace();
2045 generic.frame_id = kFrameId;
2046 generic.temporal_index = 3;
2047 generic.spatial_index = 2;
2048 generic.higher_spatial_layers.push_back(4);
2049 generic.dependencies.push_back(kFrameId - 1);
2050 generic.dependencies.push_back(kFrameId - 500);
Niels Möller3ea55d52019-01-24 09:44:14 +01002051 rtp_sender_video_->SendVideo(kVideoFrameDelta, kPayload, kTimestamp, 0,
2052 kFrame, sizeof(kFrame), nullptr, &hdr,
2053 kDefaultExpectedRetransmissionTimeMs);
philipelb3e42a42018-09-13 10:57:14 +02002054
2055 RtpGenericFrameDescriptor descriptor_wire;
2056 EXPECT_EQ(1U, transport_.sent_packets_.size());
2057 EXPECT_TRUE(
2058 transport_.last_sent_packet()
2059 .GetExtension<RtpGenericFrameDescriptorExtension>(&descriptor_wire));
2060 EXPECT_EQ(static_cast<uint16_t>(generic.frame_id), descriptor_wire.FrameId());
2061 EXPECT_EQ(generic.temporal_index, descriptor_wire.TemporalLayer());
2062 EXPECT_THAT(descriptor_wire.FrameDependenciesDiffs(), ElementsAre(1, 500));
2063 uint8_t spatial_bitmask = 0x14;
2064 EXPECT_EQ(spatial_bitmask, descriptor_wire.SpatialLayersBitmask());
2065}
2066
Danil Chapovalov84ffb352018-09-25 18:59:09 +02002067TEST_P(RtpSenderVideoTest,
2068 UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed) {
2069 const int64_t kFrameId = 100000;
2070 const size_t kFrameSize = 100;
2071 uint8_t kFrame[kFrameSize];
2072 ASSERT_TRUE(rtp_sender_->RegisterRtpHeaderExtension(
2073 RtpGenericFrameDescriptorExtension::kUri, kGenericDescriptorId));
2074
2075 RTPVideoHeader hdr;
2076 hdr.codec = kVideoCodecVP8;
2077 RTPVideoHeaderVP8& vp8 = hdr.video_type_header.emplace<RTPVideoHeaderVP8>();
2078 vp8.pictureId = kFrameId % 0X7FFF;
2079 vp8.tl0PicIdx = 13;
2080 vp8.temporalIdx = 1;
2081 vp8.keyIdx = 2;
2082 RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace();
2083 generic.frame_id = kFrameId;
Niels Möller3ea55d52019-01-24 09:44:14 +01002084 rtp_sender_video_->RegisterPayloadType(kPayload, "vp8");
2085 rtp_sender_video_->SendVideo(kVideoFrameDelta, kPayload, kTimestamp, 0,
2086 kFrame, sizeof(kFrame), nullptr, &hdr,
2087 kDefaultExpectedRetransmissionTimeMs);
Danil Chapovalov84ffb352018-09-25 18:59:09 +02002088
2089 ASSERT_THAT(transport_.sent_packets_, SizeIs(1));
2090 // Expect only minimal 1-byte vp8 descriptor was generated.
2091 EXPECT_THAT(transport_.sent_packets_[0].payload_size(), 1 + kFrameSize);
2092}
2093
minyue3a407ee2017-04-03 01:10:33 -07002094TEST_P(RtpSenderTest, OnOverheadChanged) {
michaelt4da30442016-11-17 01:38:43 -08002095 MockOverheadObserver mock_overhead_observer;
Niels Möller949f0fd2019-01-29 09:44:24 +01002096 rtp_sender_.reset(new RTPSender(
2097 false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
2098 nullptr, nullptr, nullptr, nullptr, &retransmission_rate_limiter_,
2099 &mock_overhead_observer, false, nullptr, false, false));
nisse7d59f6b2017-02-21 03:40:24 -08002100 rtp_sender_->SetSSRC(kSsrc);
michaelt4da30442016-11-17 01:38:43 -08002101
michaelt4da30442016-11-17 01:38:43 -08002102 // RTP overhead is 12B.
nisse284542b2017-01-10 08:58:32 -08002103 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(12)).Times(1);
michaelt4da30442016-11-17 01:38:43 -08002104 SendGenericPayload();
2105
2106 rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
2107 kTransmissionTimeOffsetExtensionId);
2108
2109 // TransmissionTimeOffset extension has a size of 8B.
nisse284542b2017-01-10 08:58:32 -08002110 // 12B + 8B = 20B
2111 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(20)).Times(1);
michaelt4da30442016-11-17 01:38:43 -08002112 SendGenericPayload();
2113}
2114
minyue3a407ee2017-04-03 01:10:33 -07002115TEST_P(RtpSenderTest, DoesNotUpdateOverheadOnEqualSize) {
michaelt4da30442016-11-17 01:38:43 -08002116 MockOverheadObserver mock_overhead_observer;
Niels Möller949f0fd2019-01-29 09:44:24 +01002117 rtp_sender_.reset(new RTPSender(
2118 false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
2119 nullptr, nullptr, nullptr, nullptr, &retransmission_rate_limiter_,
2120 &mock_overhead_observer, false, nullptr, false, false));
nisse7d59f6b2017-02-21 03:40:24 -08002121 rtp_sender_->SetSSRC(kSsrc);
michaelt4da30442016-11-17 01:38:43 -08002122
2123 EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(_)).Times(1);
michaelt4da30442016-11-17 01:38:43 -08002124 SendGenericPayload();
2125 SendGenericPayload();
2126}
2127
sprang168794c2017-07-06 04:38:06 -07002128TEST_P(RtpSenderTest, SendsKeepAlive) {
2129 MockTransport transport;
Benjamin Wright192eeec2018-10-17 17:27:25 -07002130 rtp_sender_.reset(new RTPSender(
2131 false, &fake_clock_, &transport, nullptr, nullptr, nullptr, nullptr,
Niels Möller949f0fd2019-01-29 09:44:24 +01002132 nullptr, nullptr, &mock_rtc_event_log_, nullptr,
Johannes Kron9190b822018-10-29 11:22:05 +01002133 &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
sprang168794c2017-07-06 04:38:06 -07002134 rtp_sender_->SetSequenceNumber(kSeqNum);
2135 rtp_sender_->SetTimestampOffset(0);
2136 rtp_sender_->SetSSRC(kSsrc);
2137
2138 const uint8_t kKeepalivePayloadType = 20;
2139 RTC_CHECK_NE(kKeepalivePayloadType, kPayload);
2140
2141 EXPECT_CALL(transport, SendRtp(_, _, _))
2142 .WillOnce(
2143 Invoke([&kKeepalivePayloadType](const uint8_t* packet, size_t len,
2144 const PacketOptions& options) {
2145 webrtc::RTPHeader rtp_header;
2146 RtpUtility::RtpHeaderParser parser(packet, len);
2147 EXPECT_TRUE(parser.Parse(&rtp_header, nullptr));
2148 EXPECT_FALSE(rtp_header.markerBit);
2149 EXPECT_EQ(0U, rtp_header.paddingLength);
2150 EXPECT_EQ(kKeepalivePayloadType, rtp_header.payloadType);
2151 EXPECT_EQ(kSeqNum, rtp_header.sequenceNumber);
2152 EXPECT_EQ(kSsrc, rtp_header.ssrc);
2153 EXPECT_EQ(0u, len - rtp_header.headerLength);
2154 return true;
2155 }));
2156
2157 rtp_sender_->SendKeepAlive(kKeepalivePayloadType);
2158 EXPECT_EQ(kSeqNum + 1, rtp_sender_->SequenceNumber());
2159}
2160
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002161INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2162 RtpSenderTest,
2163 ::testing::Bool());
2164INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2165 RtpSenderTestWithoutPacer,
2166 ::testing::Bool());
2167INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
2168 RtpSenderVideoTest,
2169 ::testing::Bool());
Niels Möllera34d7762019-02-01 14:13:29 +01002170
solenberg@webrtc.orgc0352d52013-05-20 20:55:07 +00002171} // namespace webrtc