Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(382)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/flexfec_sender_unittest.cc

Issue 2441613002: Add FlexfecSender. (Closed)
Patch Set: Feedback response 2. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
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
13 #include "webrtc/config.h"
14 #include "webrtc/modules/rtp_rtcp/include/flexfec_sender.h"
15 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
16 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
17 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
18 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
19 #include "webrtc/system_wrappers/include/clock.h"
20 #include "webrtc/test/gtest.h"
21
22 namespace webrtc {
23
24 namespace {
25
26 using test::fec::AugmentedPacket;
27 using test::fec::AugmentedPacketGenerator;
28
29 constexpr int kFlexfecPayloadType = 123;
30 constexpr uint32_t kMediaSsrc = 1234;
31 constexpr uint32_t kFlexfecSsrc = 5678;
32 const std::vector<RtpExtension> kNoRtpHeaderExtensions;
33 // Assume a single protected media SSRC.
34 constexpr size_t kFlexfecMaxHeaderSize = 32;
35 constexpr size_t kPayloadLength = 50;
36
37 constexpr int64_t kInitialSimulatedClockTime = 1;
38 // These values are deterministically given by the PRNG, due to our fixed seed.
39 // They should be updated if the PRNG implementation changes.
40 constexpr uint16_t kDeterministicSequenceNumber = 17590;
41 constexpr uint32_t kDeterministicTimestamp = 3766052125;
42
43 std::unique_ptr<RtpPacketToSend> GenerateSingleFlexfecPacket(
44 FlexfecSender* sender) {
45 // Parameters selected to generate a single FEC packet.
46 FecProtectionParams params;
47 params.fec_rate = 15;
48 params.max_fec_frames = 1;
49 params.fec_mask_type = kFecMaskRandom;
50 constexpr size_t kNumPackets = 4;
51
52 sender->SetFecParameters(params);
53 AugmentedPacketGenerator packet_generator(kMediaSsrc);
54 packet_generator.NewFrame(kNumPackets);
55 for (size_t i = 0; i < kNumPackets; ++i) {
56 std::unique_ptr<AugmentedPacket> packet =
57 packet_generator.NextPacket(i, kPayloadLength);
58 RtpPacketToSend rtp_packet(nullptr); // No header extensions.
59 rtp_packet.Parse(packet->data, packet->length);
60 EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(rtp_packet));
61 }
62 EXPECT_TRUE(sender->FecAvailable());
63 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
64 sender->GetFecPackets();
65 EXPECT_FALSE(sender->FecAvailable());
66 EXPECT_EQ(1U, fec_packets.size());
67
68 return std::move(fec_packets.front());
69 }
70
71 } // namespace
72
73 TEST(FlexfecSenderTest, NoFecAvailableBeforeMediaAdded) {
74 SimulatedClock clock(kInitialSimulatedClockTime);
75 std::unique_ptr<FlexfecSender> sender =
76 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
77 kNoRtpHeaderExtensions, &clock);
78
79 EXPECT_FALSE(sender->FecAvailable());
80 auto fec_packets = sender->GetFecPackets();
81 EXPECT_EQ(0U, fec_packets.size());
82 }
83
84 TEST(FlexfecSenderTest, ProtectOneFrameWithOneFecPacket) {
85 SimulatedClock clock(kInitialSimulatedClockTime);
86 std::unique_ptr<FlexfecSender> sender =
87 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
88 kNoRtpHeaderExtensions, &clock);
89 auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
90
91 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
92 EXPECT_FALSE(fec_packet->Marker());
93 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
94 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
95 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
96 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
97 EXPECT_LE(kPayloadLength, fec_packet->payload_size());
98 }
99
100 TEST(FlexfecSenderTest, ProtectTwoFramesWithOneFecPacket) {
101 // FEC parameters selected to generate a single FEC packet per frame.
102 FecProtectionParams params;
103 params.fec_rate = 15;
104 params.max_fec_frames = 2;
105 params.fec_mask_type = kFecMaskRandom;
106 constexpr size_t kNumFrames = 2;
107 constexpr size_t kNumPacketsPerFrame = 2;
108 SimulatedClock clock(kInitialSimulatedClockTime);
109 std::unique_ptr<FlexfecSender> sender =
110 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
111 kNoRtpHeaderExtensions, &clock);
112 sender->SetFecParameters(params);
113
114 AugmentedPacketGenerator packet_generator(kMediaSsrc);
115 for (size_t i = 0; i < kNumFrames; ++i) {
116 packet_generator.NewFrame(kNumPacketsPerFrame);
117 for (size_t j = 0; j < kNumPacketsPerFrame; ++j) {
118 std::unique_ptr<AugmentedPacket> packet =
119 packet_generator.NextPacket(i, kPayloadLength);
120 RtpPacketToSend rtp_packet(nullptr);
121 rtp_packet.Parse(packet->data, packet->length);
122 EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(rtp_packet));
123 }
124 }
125 EXPECT_TRUE(sender->FecAvailable());
126 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
127 sender->GetFecPackets();
128 EXPECT_FALSE(sender->FecAvailable());
129 ASSERT_EQ(1U, fec_packets.size());
130
131 RtpPacketToSend* fec_packet = fec_packets.front().get();
132 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
133 EXPECT_FALSE(fec_packet->Marker());
134 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
135 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
136 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
137 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
138 }
139
140 TEST(FlexfecSenderTest, ProtectTwoFramesWithTwoFecPackets) {
141 // FEC parameters selected to generate a single FEC packet per frame.
142 FecProtectionParams params;
143 params.fec_rate = 30;
144 params.max_fec_frames = 1;
145 params.fec_mask_type = kFecMaskRandom;
146 constexpr size_t kNumFrames = 2;
147 constexpr size_t kNumPacketsPerFrame = 2;
148 SimulatedClock clock(kInitialSimulatedClockTime);
149 std::unique_ptr<FlexfecSender> sender =
150 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
151 kNoRtpHeaderExtensions, &clock);
152 sender->SetFecParameters(params);
153
154 AugmentedPacketGenerator packet_generator(kMediaSsrc);
155 for (size_t i = 0; i < kNumFrames; ++i) {
156 packet_generator.NewFrame(kNumPacketsPerFrame);
157 for (size_t j = 0; j < kNumPacketsPerFrame; ++j) {
158 std::unique_ptr<AugmentedPacket> packet =
159 packet_generator.NextPacket(i, kPayloadLength);
160 RtpPacketToSend rtp_packet(nullptr);
161 rtp_packet.Parse(packet->data, packet->length);
162 EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(rtp_packet));
163 }
164 EXPECT_TRUE(sender->FecAvailable());
165 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
166 sender->GetFecPackets();
167 EXPECT_FALSE(sender->FecAvailable());
168 ASSERT_EQ(1U, fec_packets.size());
169
170 RtpPacketToSend* fec_packet = fec_packets.front().get();
171 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
172 EXPECT_FALSE(fec_packet->Marker());
173 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
174 EXPECT_EQ(static_cast<uint16_t>(kDeterministicSequenceNumber + i),
175 fec_packet->SequenceNumber());
176 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
177 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
178 }
179 }
180
181 // In the tests, we only consider RTP header extensions that are useful for BWE.
182 TEST(FlexfecSenderTest, NoRtpHeaderExtensionsForBweByDefault) {
183 const std::vector<RtpExtension> kRtpHeaderExtensions{};
184 SimulatedClock clock(kInitialSimulatedClockTime);
185 std::unique_ptr<FlexfecSender> sender =
186 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
187 kRtpHeaderExtensions, &clock);
188 auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
189
190 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
191 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
192 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
193 }
194
195 TEST(FlexfecSenderTest, RegisterAbsoluteSendTimeRtpHeaderExtension) {
196 const std::vector<RtpExtension> kRtpHeaderExtensions{
197 {RtpExtension::kAbsSendTimeUri, 1}};
198 SimulatedClock clock(kInitialSimulatedClockTime);
199 std::unique_ptr<FlexfecSender> sender =
200 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
201 kRtpHeaderExtensions, &clock);
202 auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
203
204 EXPECT_TRUE(fec_packet->HasExtension<AbsoluteSendTime>());
205 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
206 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
207 }
208
209 TEST(FlexfecSenderTest, RegisterTransmissionOffsetRtpHeaderExtension) {
210 const std::vector<RtpExtension> kRtpHeaderExtensions{
211 {RtpExtension::kTimestampOffsetUri, 1}};
212 SimulatedClock clock(kInitialSimulatedClockTime);
213 std::unique_ptr<FlexfecSender> sender =
214 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
215 kRtpHeaderExtensions, &clock);
216 auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
217
218 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
219 EXPECT_TRUE(fec_packet->HasExtension<TransmissionOffset>());
220 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
221 }
222
223 TEST(FlexfecSenderTest, RegisterTransportSequenceNumberRtpHeaderExtension) {
224 const std::vector<RtpExtension> kRtpHeaderExtensions{
225 {RtpExtension::kTransportSequenceNumberUri, 1}};
226 SimulatedClock clock(kInitialSimulatedClockTime);
227 std::unique_ptr<FlexfecSender> sender =
228 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
229 kRtpHeaderExtensions, &clock);
230 auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
231
232 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
233 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
234 EXPECT_TRUE(fec_packet->HasExtension<TransportSequenceNumber>());
235 }
236
237 TEST(FlexfecSenderTest, RegisterAllRtpHeaderExtensionsForBwe) {
238 const std::vector<RtpExtension> kRtpHeaderExtensions{
239 {RtpExtension::kAbsSendTimeUri, 1},
240 {RtpExtension::kTimestampOffsetUri, 2},
241 {RtpExtension::kTransportSequenceNumberUri, 3}};
242 SimulatedClock clock(kInitialSimulatedClockTime);
243 std::unique_ptr<FlexfecSender> sender =
244 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
245 kRtpHeaderExtensions, &clock);
246 auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
247
248 EXPECT_TRUE(fec_packet->HasExtension<AbsoluteSendTime>());
249 EXPECT_TRUE(fec_packet->HasExtension<TransmissionOffset>());
250 EXPECT_TRUE(fec_packet->HasExtension<TransportSequenceNumber>());
251 }
252
253 TEST(FlexfecSenderTest, MaxPacketOverhead) {
254 SimulatedClock clock(kInitialSimulatedClockTime);
255 std::unique_ptr<FlexfecSender> sender =
256 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
257 kNoRtpHeaderExtensions, &clock);
258
259 EXPECT_EQ(kFlexfecMaxHeaderSize, sender->MaxPacketOverhead());
260 }
261
262 // TODO(brandtr): Remove this test when we support multistream protection.
263 TEST(FlexfecSenderTest, DoesNotProtectMultipleMediaStreams) {
264 // FEC parameters selected to generate a single FEC packet per frame.
265 FecProtectionParams params;
266 params.fec_rate = 15;
267 params.max_fec_frames = 1;
268 params.fec_mask_type = kFecMaskRandom;
269 constexpr size_t kNumPacketsStream1 = 4;
270 constexpr size_t kNumPacketsStream2 = 4;
271 constexpr uint32_t kMediaSsrcStream1 = kMediaSsrc;
272 constexpr uint32_t kMediaSsrcStream2 = kMediaSsrc + 1;
273 SimulatedClock clock(kInitialSimulatedClockTime);
274 std::unique_ptr<FlexfecSender> sender =
275 FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc,
276 kMediaSsrcStream2, kNoRtpHeaderExtensions, &clock);
277 sender->SetFecParameters(params);
278
279 // Feed FlexfecSender media packets from stream 1, which IS NOT protected.
280 AugmentedPacketGenerator packet_generator1(kMediaSsrcStream1);
281 packet_generator1.NewFrame(kNumPacketsStream1);
282 for (size_t i = 0; i < kNumPacketsStream1; ++i) {
283 std::unique_ptr<AugmentedPacket> packet =
284 packet_generator1.NextPacket(i, kPayloadLength);
285 RtpPacketToSend rtp_packet(nullptr);
286 rtp_packet.Parse(packet->data, packet->length);
287 EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(rtp_packet));
288 }
289 EXPECT_FALSE(sender->FecAvailable());
290
291 // Feed FlexfecSender media packets from stream 2, which IS protected.
292 AugmentedPacketGenerator packet_generator2(kMediaSsrcStream2);
293 packet_generator2.NewFrame(kNumPacketsStream2);
294 for (size_t i = 0; i < kNumPacketsStream2; ++i) {
295 std::unique_ptr<AugmentedPacket> packet =
296 packet_generator2.NextPacket(i, kPayloadLength);
297 RtpPacketToSend rtp_packet(nullptr);
298 rtp_packet.Parse(packet->data, packet->length);
299 EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(rtp_packet));
300 }
301 EXPECT_TRUE(sender->FecAvailable());
302 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
303 sender->GetFecPackets();
304 EXPECT_FALSE(sender->FecAvailable());
305 ASSERT_EQ(1U, fec_packets.size());
306
307 RtpPacketToSend* fec_packet = fec_packets.front().get();
308 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
309 EXPECT_FALSE(fec_packet->Marker());
310 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
311 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
312 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
313 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
314 EXPECT_LE(kPayloadLength, fec_packet->payload_size());
315 }
316
317 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698