flexfec_sender_unittest.cc (15301B)
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 "modules/rtp_rtcp/include/flexfec_sender.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <memory> 16 #include <string> 17 #include <utility> 18 #include <vector> 19 20 #include "api/environment/environment.h" 21 #include "api/environment/environment_factory.h" 22 #include "api/rtp_parameters.h" 23 #include "modules/include/module_fec_types.h" 24 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 25 #include "modules/rtp_rtcp/source/fec_test_helper.h" 26 #include "modules/rtp_rtcp/source/rtp_header_extension_size.h" 27 #include "modules/rtp_rtcp/source/rtp_header_extensions.h" 28 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" 29 #include "modules/rtp_rtcp/source/rtp_sender.h" 30 #include "system_wrappers/include/clock.h" 31 #include "test/gtest.h" 32 33 namespace webrtc { 34 35 namespace { 36 37 using test::fec::AugmentedPacketGenerator; 38 39 constexpr int kFlexfecPayloadType = 123; 40 constexpr uint32_t kMediaSsrc = 1234; 41 constexpr uint32_t kFlexfecSsrc = 5678; 42 constexpr char kNoMid[] = ""; 43 const std::vector<RtpExtension> kNoRtpHeaderExtensions; 44 const std::vector<RtpExtensionSize> kNoRtpHeaderExtensionSizes; 45 // Assume a single protected media SSRC. 46 constexpr size_t kFlexfecMaxHeaderSize = 32; 47 constexpr size_t kPayloadLength = 50; 48 49 constexpr int64_t kInitialSimulatedClockTime = 1; 50 // These values are deterministically given by the PRNG, due to our fixed seed. 51 // They should be updated if the PRNG implementation changes. 52 constexpr uint16_t kDeterministicSequenceNumber = 28732; 53 constexpr uint32_t kDeterministicTimestamp = 2305613085; 54 55 // Round up to the nearest size that is a multiple of 4. 56 size_t Word32Align(size_t size) { 57 uint32_t remainder = size % 4; 58 if (remainder != 0) 59 return size + 4 - remainder; 60 return size; 61 } 62 63 std::unique_ptr<RtpPacketToSend> GenerateSingleFlexfecPacket( 64 FlexfecSender* sender) { 65 // Parameters selected to generate a single FEC packet. 66 FecProtectionParams params; 67 params.fec_rate = 15; 68 params.max_fec_frames = 1; 69 params.fec_mask_type = kFecMaskRandom; 70 constexpr size_t kNumPackets = 4; 71 72 sender->SetProtectionParameters(params, params); 73 AugmentedPacketGenerator packet_generator(kMediaSsrc); 74 packet_generator.NewFrame(kNumPackets); 75 for (size_t i = 0; i < kNumPackets; ++i) { 76 RtpPacketToSend rtp_packet = 77 packet_generator.NextPacket<RtpPacketToSend>(i, kPayloadLength); 78 sender->AddPacketAndGenerateFec(rtp_packet); 79 } 80 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets = 81 sender->GetFecPackets(); 82 EXPECT_EQ(1U, fec_packets.size()); 83 EXPECT_TRUE(sender->GetFecPackets().empty()); 84 85 return std::move(fec_packets.front()); 86 } 87 88 } // namespace 89 90 TEST(FlexfecSenderTest, Ssrc) { 91 SimulatedClock clock(kInitialSimulatedClockTime); 92 const Environment env = CreateEnvironment(&clock); 93 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 94 kNoMid, kNoRtpHeaderExtensions, 95 kNoRtpHeaderExtensionSizes, nullptr /* rtp_state */); 96 97 EXPECT_EQ(kFlexfecSsrc, sender.FecSsrc()); 98 } 99 100 TEST(FlexfecSenderTest, NoFecAvailableBeforeMediaAdded) { 101 SimulatedClock clock(kInitialSimulatedClockTime); 102 const Environment env = CreateEnvironment(&clock); 103 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 104 kNoMid, kNoRtpHeaderExtensions, 105 kNoRtpHeaderExtensionSizes, nullptr /* rtp_state */); 106 107 EXPECT_TRUE(sender.GetFecPackets().empty()); 108 } 109 110 TEST(FlexfecSenderTest, ProtectOneFrameWithOneFecPacket) { 111 SimulatedClock clock(kInitialSimulatedClockTime); 112 const Environment env = CreateEnvironment(&clock); 113 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 114 kNoMid, kNoRtpHeaderExtensions, 115 kNoRtpHeaderExtensionSizes, nullptr /* rtp_state */); 116 auto fec_packet = GenerateSingleFlexfecPacket(&sender); 117 118 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size()); 119 EXPECT_FALSE(fec_packet->Marker()); 120 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType()); 121 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber()); 122 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp()); 123 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc()); 124 EXPECT_LE(kPayloadLength, fec_packet->payload_size()); 125 } 126 127 TEST(FlexfecSenderTest, ProtectTwoFramesWithOneFecPacket) { 128 SimulatedClock clock(kInitialSimulatedClockTime); 129 const Environment env = CreateEnvironment(&clock); 130 // FEC parameters selected to generate a single FEC packet per frame. 131 FecProtectionParams params; 132 params.fec_rate = 15; 133 params.max_fec_frames = 2; 134 params.fec_mask_type = kFecMaskRandom; 135 constexpr size_t kNumFrames = 2; 136 constexpr size_t kNumPacketsPerFrame = 2; 137 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 138 kNoMid, kNoRtpHeaderExtensions, 139 kNoRtpHeaderExtensionSizes, nullptr /* rtp_state */); 140 sender.SetProtectionParameters(params, params); 141 142 AugmentedPacketGenerator packet_generator(kMediaSsrc); 143 for (size_t i = 0; i < kNumFrames; ++i) { 144 packet_generator.NewFrame(kNumPacketsPerFrame); 145 for (size_t j = 0; j < kNumPacketsPerFrame; ++j) { 146 RtpPacketToSend rtp_packet = 147 packet_generator.NextPacket<RtpPacketToSend>(i, kPayloadLength); 148 sender.AddPacketAndGenerateFec(rtp_packet); 149 } 150 } 151 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets = 152 sender.GetFecPackets(); 153 ASSERT_EQ(1U, fec_packets.size()); 154 EXPECT_TRUE(sender.GetFecPackets().empty()); 155 156 RtpPacketToSend* fec_packet = fec_packets.front().get(); 157 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size()); 158 EXPECT_FALSE(fec_packet->Marker()); 159 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType()); 160 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber()); 161 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp()); 162 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc()); 163 } 164 165 TEST(FlexfecSenderTest, ProtectTwoFramesWithTwoFecPackets) { 166 SimulatedClock clock(kInitialSimulatedClockTime); 167 const Environment env = CreateEnvironment(&clock); 168 // FEC parameters selected to generate a single FEC packet per frame. 169 FecProtectionParams params; 170 params.fec_rate = 30; 171 params.max_fec_frames = 1; 172 params.fec_mask_type = kFecMaskRandom; 173 constexpr size_t kNumFrames = 2; 174 constexpr size_t kNumPacketsPerFrame = 2; 175 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 176 kNoMid, kNoRtpHeaderExtensions, 177 kNoRtpHeaderExtensionSizes, nullptr /* rtp_state */); 178 sender.SetProtectionParameters(params, params); 179 180 AugmentedPacketGenerator packet_generator(kMediaSsrc); 181 for (size_t i = 0; i < kNumFrames; ++i) { 182 packet_generator.NewFrame(kNumPacketsPerFrame); 183 for (size_t j = 0; j < kNumPacketsPerFrame; ++j) { 184 RtpPacketToSend rtp_packet = 185 packet_generator.NextPacket<RtpPacketToSend>(i, kPayloadLength); 186 sender.AddPacketAndGenerateFec(rtp_packet); 187 } 188 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets = 189 sender.GetFecPackets(); 190 ASSERT_EQ(1U, fec_packets.size()); 191 EXPECT_TRUE(sender.GetFecPackets().empty()); 192 193 RtpPacketToSend* fec_packet = fec_packets.front().get(); 194 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size()); 195 EXPECT_FALSE(fec_packet->Marker()); 196 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType()); 197 EXPECT_EQ(static_cast<uint16_t>(kDeterministicSequenceNumber + i), 198 fec_packet->SequenceNumber()); 199 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp()); 200 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc()); 201 } 202 } 203 204 // In the tests, we only consider RTP header extensions that are useful for BWE. 205 TEST(FlexfecSenderTest, NoRtpHeaderExtensionsForBweByDefault) { 206 SimulatedClock clock(kInitialSimulatedClockTime); 207 const Environment env = CreateEnvironment(&clock); 208 const std::vector<RtpExtension> kRtpHeaderExtensions{}; 209 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 210 kNoMid, kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes, 211 nullptr /* rtp_state */); 212 auto fec_packet = GenerateSingleFlexfecPacket(&sender); 213 214 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>()); 215 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>()); 216 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>()); 217 } 218 219 TEST(FlexfecSenderTest, RegisterAbsoluteSendTimeRtpHeaderExtension) { 220 SimulatedClock clock(kInitialSimulatedClockTime); 221 const Environment env = CreateEnvironment(&clock); 222 const std::vector<RtpExtension> kRtpHeaderExtensions{ 223 {RtpExtension::kAbsSendTimeUri, 1}}; 224 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 225 kNoMid, kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes, 226 nullptr /* rtp_state */); 227 auto fec_packet = GenerateSingleFlexfecPacket(&sender); 228 229 EXPECT_TRUE(fec_packet->HasExtension<AbsoluteSendTime>()); 230 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>()); 231 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>()); 232 } 233 234 TEST(FlexfecSenderTest, RegisterTransmissionOffsetRtpHeaderExtension) { 235 SimulatedClock clock(kInitialSimulatedClockTime); 236 const Environment env = CreateEnvironment(&clock); 237 const std::vector<RtpExtension> kRtpHeaderExtensions{ 238 {RtpExtension::kTimestampOffsetUri, 1}}; 239 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 240 kNoMid, kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes, 241 nullptr /* rtp_state */); 242 auto fec_packet = GenerateSingleFlexfecPacket(&sender); 243 244 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>()); 245 EXPECT_TRUE(fec_packet->HasExtension<TransmissionOffset>()); 246 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>()); 247 } 248 249 TEST(FlexfecSenderTest, RegisterTransportSequenceNumberRtpHeaderExtension) { 250 SimulatedClock clock(kInitialSimulatedClockTime); 251 const Environment env = CreateEnvironment(&clock); 252 const std::vector<RtpExtension> kRtpHeaderExtensions{ 253 {RtpExtension::kTransportSequenceNumberUri, 1}}; 254 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 255 kNoMid, kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes, 256 nullptr /* rtp_state */); 257 auto fec_packet = GenerateSingleFlexfecPacket(&sender); 258 259 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>()); 260 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>()); 261 EXPECT_TRUE(fec_packet->HasExtension<TransportSequenceNumber>()); 262 } 263 264 TEST(FlexfecSenderTest, RegisterAllRtpHeaderExtensionsForBwe) { 265 SimulatedClock clock(kInitialSimulatedClockTime); 266 const Environment env = CreateEnvironment(&clock); 267 const std::vector<RtpExtension> kRtpHeaderExtensions{ 268 {RtpExtension::kAbsSendTimeUri, 1}, 269 {RtpExtension::kTimestampOffsetUri, 2}, 270 {RtpExtension::kTransportSequenceNumberUri, 3}}; 271 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 272 kNoMid, kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes, 273 nullptr /* rtp_state */); 274 auto fec_packet = GenerateSingleFlexfecPacket(&sender); 275 276 EXPECT_TRUE(fec_packet->HasExtension<AbsoluteSendTime>()); 277 EXPECT_TRUE(fec_packet->HasExtension<TransmissionOffset>()); 278 EXPECT_TRUE(fec_packet->HasExtension<TransportSequenceNumber>()); 279 } 280 281 TEST(FlexfecSenderTest, MaxPacketOverhead) { 282 SimulatedClock clock(kInitialSimulatedClockTime); 283 const Environment env = CreateEnvironment(&clock); 284 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 285 kNoMid, kNoRtpHeaderExtensions, 286 kNoRtpHeaderExtensionSizes, nullptr /* rtp_state */); 287 288 EXPECT_EQ(kFlexfecMaxHeaderSize, sender.MaxPacketOverhead()); 289 } 290 291 TEST(FlexfecSenderTest, MaxPacketOverheadWithExtensions) { 292 SimulatedClock clock(kInitialSimulatedClockTime); 293 const Environment env = CreateEnvironment(&clock); 294 const std::vector<RtpExtension> kRtpHeaderExtensions{ 295 {RtpExtension::kAbsSendTimeUri, 1}, 296 {RtpExtension::kTimestampOffsetUri, 2}, 297 {RtpExtension::kTransportSequenceNumberUri, 3}}; 298 const size_t kExtensionHeaderLength = 1; 299 const size_t kRtpOneByteHeaderLength = 4; 300 const size_t kExtensionsTotalSize = 301 Word32Align(kRtpOneByteHeaderLength + kExtensionHeaderLength + 302 AbsoluteSendTime::kValueSizeBytes + kExtensionHeaderLength + 303 TransmissionOffset::kValueSizeBytes + kExtensionHeaderLength + 304 TransportSequenceNumber::kValueSizeBytes); 305 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 306 kNoMid, kRtpHeaderExtensions, 307 RTPSender::FecExtensionSizes(), nullptr /* rtp_state */); 308 309 EXPECT_EQ(kExtensionsTotalSize + kFlexfecMaxHeaderSize, 310 sender.MaxPacketOverhead()); 311 } 312 313 TEST(FlexfecSenderTest, MidIncludedInPacketsWhenSet) { 314 SimulatedClock clock(kInitialSimulatedClockTime); 315 const Environment env = CreateEnvironment(&clock); 316 const std::vector<RtpExtension> kRtpHeaderExtensions{ 317 {RtpExtension::kMidUri, 1}}; 318 const char kMid[] = "mid"; 319 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kMid, 320 kRtpHeaderExtensions, RTPSender::FecExtensionSizes(), 321 nullptr /* rtp_state */); 322 323 auto fec_packet = GenerateSingleFlexfecPacket(&sender); 324 325 std::string mid; 326 ASSERT_TRUE(fec_packet->GetExtension<RtpMid>(&mid)); 327 EXPECT_EQ(kMid, mid); 328 } 329 330 TEST(FlexfecSenderTest, SetsAndGetsRtpState) { 331 SimulatedClock clock(kInitialSimulatedClockTime); 332 const Environment env = CreateEnvironment(&clock); 333 RtpState initial_rtp_state; 334 initial_rtp_state.sequence_number = 100; 335 initial_rtp_state.start_timestamp = 200; 336 FlexfecSender sender(env, kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, 337 kNoMid, kNoRtpHeaderExtensions, 338 kNoRtpHeaderExtensionSizes, &initial_rtp_state); 339 340 auto fec_packet = GenerateSingleFlexfecPacket(&sender); 341 EXPECT_EQ(initial_rtp_state.sequence_number, fec_packet->SequenceNumber()); 342 EXPECT_EQ(initial_rtp_state.start_timestamp, fec_packet->Timestamp()); 343 344 clock.AdvanceTimeMilliseconds(1000); 345 fec_packet = GenerateSingleFlexfecPacket(&sender); 346 EXPECT_EQ(initial_rtp_state.sequence_number + 1, 347 fec_packet->SequenceNumber()); 348 EXPECT_EQ(initial_rtp_state.start_timestamp + 1 * kVideoPayloadTypeFrequency, 349 fec_packet->Timestamp()); 350 351 RtpState updated_rtp_state = sender.GetRtpState().value(); 352 EXPECT_EQ(initial_rtp_state.sequence_number + 2, 353 updated_rtp_state.sequence_number); 354 EXPECT_EQ(initial_rtp_state.start_timestamp, 355 updated_rtp_state.start_timestamp); 356 } 357 358 } // namespace webrtc