blob: aa729ed0b87d5eb4e151ea9a2d42efc7d95e3c26 [file] [log] [blame]
brandtrc295e002016-11-03 09:22:33 -07001/*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <vector>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "api/rtpparameters.h"
14#include "modules/rtp_rtcp/include/flexfec_sender.h"
15#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
16#include "modules/rtp_rtcp/source/fec_test_helper.h"
17#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
18#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
19#include "modules/rtp_rtcp/source/rtp_sender.h"
20#include "modules/rtp_rtcp/source/rtp_utility.h"
21#include "system_wrappers/include/clock.h"
22#include "test/gtest.h"
brandtrc295e002016-11-03 09:22:33 -070023
24namespace webrtc {
25
26namespace {
27
erikvarga27883732017-05-17 05:08:38 -070028using RtpUtility::Word32Align;
brandtrc295e002016-11-03 09:22:33 -070029using test::fec::AugmentedPacket;
30using test::fec::AugmentedPacketGenerator;
31
32constexpr int kFlexfecPayloadType = 123;
33constexpr uint32_t kMediaSsrc = 1234;
34constexpr uint32_t kFlexfecSsrc = 5678;
35const std::vector<RtpExtension> kNoRtpHeaderExtensions;
erikvarga27883732017-05-17 05:08:38 -070036const std::vector<RtpExtensionSize> kNoRtpHeaderExtensionSizes;
brandtrc295e002016-11-03 09:22:33 -070037// Assume a single protected media SSRC.
38constexpr size_t kFlexfecMaxHeaderSize = 32;
39constexpr size_t kPayloadLength = 50;
40
41constexpr int64_t kInitialSimulatedClockTime = 1;
42// These values are deterministically given by the PRNG, due to our fixed seed.
43// They should be updated if the PRNG implementation changes.
44constexpr uint16_t kDeterministicSequenceNumber = 28732;
45constexpr uint32_t kDeterministicTimestamp = 2305613085;
46
47std::unique_ptr<RtpPacketToSend> GenerateSingleFlexfecPacket(
48 FlexfecSender* sender) {
49 // Parameters selected to generate a single FEC packet.
50 FecProtectionParams params;
51 params.fec_rate = 15;
52 params.max_fec_frames = 1;
53 params.fec_mask_type = kFecMaskRandom;
54 constexpr size_t kNumPackets = 4;
55
56 sender->SetFecParameters(params);
57 AugmentedPacketGenerator packet_generator(kMediaSsrc);
58 packet_generator.NewFrame(kNumPackets);
59 for (size_t i = 0; i < kNumPackets; ++i) {
60 std::unique_ptr<AugmentedPacket> packet =
61 packet_generator.NextPacket(i, kPayloadLength);
62 RtpPacketToSend rtp_packet(nullptr); // No header extensions.
63 rtp_packet.Parse(packet->data, packet->length);
64 EXPECT_TRUE(sender->AddRtpPacketAndGenerateFec(rtp_packet));
65 }
66 EXPECT_TRUE(sender->FecAvailable());
67 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
68 sender->GetFecPackets();
69 EXPECT_FALSE(sender->FecAvailable());
70 EXPECT_EQ(1U, fec_packets.size());
71
72 return std::move(fec_packets.front());
73}
74
75} // namespace
76
brandtr9dfff292016-11-14 05:14:50 -080077TEST(FlexfecSenderTest, Ssrc) {
78 SimulatedClock clock(kInitialSimulatedClockTime);
79 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -070080 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -070081 nullptr /* rtp_state */, &clock);
brandtr9dfff292016-11-14 05:14:50 -080082
83 EXPECT_EQ(kFlexfecSsrc, sender.ssrc());
84}
85
brandtrc295e002016-11-03 09:22:33 -070086TEST(FlexfecSenderTest, NoFecAvailableBeforeMediaAdded) {
87 SimulatedClock clock(kInitialSimulatedClockTime);
88 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -070089 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -070090 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -070091
92 EXPECT_FALSE(sender.FecAvailable());
93 auto fec_packets = sender.GetFecPackets();
94 EXPECT_EQ(0U, fec_packets.size());
95}
96
97TEST(FlexfecSenderTest, ProtectOneFrameWithOneFecPacket) {
98 SimulatedClock clock(kInitialSimulatedClockTime);
99 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700100 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700101 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700102 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
103
104 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
105 EXPECT_FALSE(fec_packet->Marker());
106 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
107 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
108 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
109 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
110 EXPECT_LE(kPayloadLength, fec_packet->payload_size());
111}
112
113TEST(FlexfecSenderTest, ProtectTwoFramesWithOneFecPacket) {
114 // FEC parameters selected to generate a single FEC packet per frame.
115 FecProtectionParams params;
116 params.fec_rate = 15;
117 params.max_fec_frames = 2;
118 params.fec_mask_type = kFecMaskRandom;
119 constexpr size_t kNumFrames = 2;
120 constexpr size_t kNumPacketsPerFrame = 2;
121 SimulatedClock clock(kInitialSimulatedClockTime);
122 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700123 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700124 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700125 sender.SetFecParameters(params);
126
127 AugmentedPacketGenerator packet_generator(kMediaSsrc);
128 for (size_t i = 0; i < kNumFrames; ++i) {
129 packet_generator.NewFrame(kNumPacketsPerFrame);
130 for (size_t j = 0; j < kNumPacketsPerFrame; ++j) {
131 std::unique_ptr<AugmentedPacket> packet =
132 packet_generator.NextPacket(i, kPayloadLength);
133 RtpPacketToSend rtp_packet(nullptr);
134 rtp_packet.Parse(packet->data, packet->length);
135 EXPECT_TRUE(sender.AddRtpPacketAndGenerateFec(rtp_packet));
136 }
137 }
138 EXPECT_TRUE(sender.FecAvailable());
139 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
140 sender.GetFecPackets();
141 EXPECT_FALSE(sender.FecAvailable());
142 ASSERT_EQ(1U, fec_packets.size());
143
144 RtpPacketToSend* fec_packet = fec_packets.front().get();
145 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
146 EXPECT_FALSE(fec_packet->Marker());
147 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
148 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
149 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
150 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
151}
152
153TEST(FlexfecSenderTest, ProtectTwoFramesWithTwoFecPackets) {
154 // FEC parameters selected to generate a single FEC packet per frame.
155 FecProtectionParams params;
156 params.fec_rate = 30;
157 params.max_fec_frames = 1;
158 params.fec_mask_type = kFecMaskRandom;
159 constexpr size_t kNumFrames = 2;
160 constexpr size_t kNumPacketsPerFrame = 2;
161 SimulatedClock clock(kInitialSimulatedClockTime);
162 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700163 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700164 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700165 sender.SetFecParameters(params);
166
167 AugmentedPacketGenerator packet_generator(kMediaSsrc);
168 for (size_t i = 0; i < kNumFrames; ++i) {
169 packet_generator.NewFrame(kNumPacketsPerFrame);
170 for (size_t j = 0; j < kNumPacketsPerFrame; ++j) {
171 std::unique_ptr<AugmentedPacket> packet =
172 packet_generator.NextPacket(i, kPayloadLength);
173 RtpPacketToSend rtp_packet(nullptr);
174 rtp_packet.Parse(packet->data, packet->length);
175 EXPECT_TRUE(sender.AddRtpPacketAndGenerateFec(rtp_packet));
176 }
177 EXPECT_TRUE(sender.FecAvailable());
178 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
179 sender.GetFecPackets();
180 EXPECT_FALSE(sender.FecAvailable());
181 ASSERT_EQ(1U, fec_packets.size());
182
183 RtpPacketToSend* fec_packet = fec_packets.front().get();
184 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
185 EXPECT_FALSE(fec_packet->Marker());
186 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
187 EXPECT_EQ(static_cast<uint16_t>(kDeterministicSequenceNumber + i),
188 fec_packet->SequenceNumber());
189 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
190 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
191 }
192}
193
194// In the tests, we only consider RTP header extensions that are useful for BWE.
195TEST(FlexfecSenderTest, NoRtpHeaderExtensionsForBweByDefault) {
196 const std::vector<RtpExtension> kRtpHeaderExtensions{};
197 SimulatedClock clock(kInitialSimulatedClockTime);
198 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700199 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700200 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700201 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
202
203 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
204 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
205 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
206}
207
208TEST(FlexfecSenderTest, RegisterAbsoluteSendTimeRtpHeaderExtension) {
209 const std::vector<RtpExtension> kRtpHeaderExtensions{
210 {RtpExtension::kAbsSendTimeUri, 1}};
211 SimulatedClock clock(kInitialSimulatedClockTime);
212 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700213 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700214 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700215 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
216
217 EXPECT_TRUE(fec_packet->HasExtension<AbsoluteSendTime>());
218 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
219 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
220}
221
222TEST(FlexfecSenderTest, RegisterTransmissionOffsetRtpHeaderExtension) {
223 const std::vector<RtpExtension> kRtpHeaderExtensions{
224 {RtpExtension::kTimestampOffsetUri, 1}};
225 SimulatedClock clock(kInitialSimulatedClockTime);
226 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700227 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700228 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700229 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
230
231 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
232 EXPECT_TRUE(fec_packet->HasExtension<TransmissionOffset>());
233 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
234}
235
236TEST(FlexfecSenderTest, RegisterTransportSequenceNumberRtpHeaderExtension) {
237 const std::vector<RtpExtension> kRtpHeaderExtensions{
238 {RtpExtension::kTransportSequenceNumberUri, 1}};
239 SimulatedClock clock(kInitialSimulatedClockTime);
240 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700241 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700242 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700243 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
244
245 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
246 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
247 EXPECT_TRUE(fec_packet->HasExtension<TransportSequenceNumber>());
248}
249
250TEST(FlexfecSenderTest, RegisterAllRtpHeaderExtensionsForBwe) {
251 const std::vector<RtpExtension> kRtpHeaderExtensions{
252 {RtpExtension::kAbsSendTimeUri, 1},
253 {RtpExtension::kTimestampOffsetUri, 2},
254 {RtpExtension::kTransportSequenceNumberUri, 3}};
255 SimulatedClock clock(kInitialSimulatedClockTime);
256 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700257 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700258 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700259 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
260
261 EXPECT_TRUE(fec_packet->HasExtension<AbsoluteSendTime>());
262 EXPECT_TRUE(fec_packet->HasExtension<TransmissionOffset>());
263 EXPECT_TRUE(fec_packet->HasExtension<TransportSequenceNumber>());
264}
265
266TEST(FlexfecSenderTest, MaxPacketOverhead) {
267 SimulatedClock clock(kInitialSimulatedClockTime);
268 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
erikvarga27883732017-05-17 05:08:38 -0700269 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
brandtr48d21a22017-05-30 02:32:12 -0700270 nullptr /* rtp_state */, &clock);
brandtrc295e002016-11-03 09:22:33 -0700271
272 EXPECT_EQ(kFlexfecMaxHeaderSize, sender.MaxPacketOverhead());
273}
274
erikvarga27883732017-05-17 05:08:38 -0700275TEST(FlexfecSenderTest, MaxPacketOverheadWithExtensions) {
276 const std::vector<RtpExtension> kRtpHeaderExtensions{
277 {RtpExtension::kAbsSendTimeUri, 1},
278 {RtpExtension::kTimestampOffsetUri, 2},
279 {RtpExtension::kTransportSequenceNumberUri, 3}};
280 SimulatedClock clock(kInitialSimulatedClockTime);
281 const size_t kExtensionHeaderLength = 1;
282 const size_t kRtpOneByteHeaderLength = 4;
283 const size_t kExtensionsTotalSize = Word32Align(
284 kRtpOneByteHeaderLength +
285 kExtensionHeaderLength + AbsoluteSendTime::kValueSizeBytes +
286 kExtensionHeaderLength + TransmissionOffset::kValueSizeBytes +
287 kExtensionHeaderLength + TransportSequenceNumber::kValueSizeBytes);
288 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
289 kRtpHeaderExtensions, RTPSender::FecExtensionSizes(),
brandtr48d21a22017-05-30 02:32:12 -0700290 nullptr /* rtp_state */, &clock);
erikvarga27883732017-05-17 05:08:38 -0700291
292 EXPECT_EQ(kExtensionsTotalSize + kFlexfecMaxHeaderSize,
293 sender.MaxPacketOverhead());
294}
295
brandtr48d21a22017-05-30 02:32:12 -0700296TEST(FlexfecSenderTest, SetsAndGetsRtpState) {
297 RtpState initial_rtp_state;
298 initial_rtp_state.sequence_number = 100;
299 initial_rtp_state.start_timestamp = 200;
300 SimulatedClock clock(kInitialSimulatedClockTime);
301 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
302 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
303 &initial_rtp_state, &clock);
304
305 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
306 EXPECT_EQ(initial_rtp_state.sequence_number, fec_packet->SequenceNumber());
307 EXPECT_EQ(initial_rtp_state.start_timestamp, fec_packet->Timestamp());
308
309 clock.AdvanceTimeMilliseconds(1000);
310 fec_packet = GenerateSingleFlexfecPacket(&sender);
311 EXPECT_EQ(initial_rtp_state.sequence_number + 1,
312 fec_packet->SequenceNumber());
313 EXPECT_EQ(initial_rtp_state.start_timestamp + 1 * kVideoPayloadTypeFrequency,
314 fec_packet->Timestamp());
315
316 RtpState updated_rtp_state = sender.GetRtpState();
317 EXPECT_EQ(initial_rtp_state.sequence_number + 2,
318 updated_rtp_state.sequence_number);
319 EXPECT_EQ(initial_rtp_state.start_timestamp,
320 updated_rtp_state.start_timestamp);
321}
322
brandtrc295e002016-11-03 09:22:33 -0700323} // namespace webrtc