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

Unified Diff: webrtc/modules/rtp_rtcp/source/flexfec_sender_unittest.cc

Issue 2441613002: Add FlexfecSender. (Closed)
Patch Set: Created 4 years, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
diff --git a/webrtc/modules/rtp_rtcp/source/flexfec_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ddaffc47801a53bd139c01d0c965c0424df9b9eb
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <vector>
+
+#include "webrtc/config.h"
+#include "webrtc/modules/rtp_rtcp/include/flexfec_sender.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "webrtc/system_wrappers/include/clock.h"
+#include "webrtc/test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+
+using test::fec::AugmentedPacket;
+using test::fec::AugmentedPacketGenerator;
+
+constexpr int kFlexfecPayloadType = 123;
+constexpr uint32_t kMediaSsrc = 1234;
+constexpr uint32_t kFlexfecSsrc = 5678;
+const std::vector<RtpExtension> kNoRtpHeaderExtensions;
+// Assume a single protected media SSRC.
+constexpr size_t kFlexfecMaxHeaderSize = 32;
+constexpr size_t kPayloadLength = 50;
+
+constexpr int64_t kInitialSimulatedClockTime = 1;
+// These values are deterministically given by the PRNG, due to our fixed seed.
+// They should be updated if the PRNG implementation changes.
+constexpr uint16_t kDeterministicSequenceNumber = 17590;
+constexpr uint32_t kDeterministicTimestamp = 3016887581;
+
+std::unique_ptr<RtpPacketToSend> GenerateSingleFlexfecPacket(
+ FlexfecSender* sender) {
+ // Parameters selected to generate a single FEC packet.
+ constexpr size_t kNumPackets = 4;
+ FecProtectionParams params = {15, 3, kFecMaskRandom};
+
+ sender->SetFecParameters(&params);
+ AugmentedPacketGenerator packet_generator(kMediaSsrc);
+ packet_generator.NewFrame(kNumPackets);
+ for (size_t i = 0; i < kNumPackets; ++i) {
+ std::unique_ptr<AugmentedPacket> packet =
+ packet_generator.NextPacket(i, kPayloadLength);
+ RtpPacketToSend rtp_packet(nullptr); // No header extensions.
+ rtp_packet.Parse(packet->data, packet->length);
+ EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(&rtp_packet));
+ }
+ EXPECT_TRUE(sender->FecAvailable());
+ std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
+ sender->GetFecPackets();
+ EXPECT_FALSE(sender->FecAvailable());
+ EXPECT_EQ(1U, fec_packets.size());
+
+ return std::move(fec_packets.front());
+}
+
+} // namespace
+
+TEST(FlexfecSenderTest, NoFecAvailableBeforeMediaAdded) {
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kNoRtpHeaderExtensions, &clock);
+
+ EXPECT_FALSE(sender->FecAvailable());
+ auto fec_packets = sender->GetFecPackets();
+ EXPECT_EQ(0U, fec_packets.size());
+}
+
+TEST(FlexfecSenderTest, ProtectOneFrameWithOneFecPacket) {
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kNoRtpHeaderExtensions, &clock);
+ auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
+
+ EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
+ EXPECT_FALSE(fec_packet->Marker());
+ EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
+ EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
+ EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
+ EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
+ EXPECT_GE(fec_packet->payload_size(), kPayloadLength);
danilchap 2016/10/20 15:12:58 constant 1st for EXPECT macros (i.e. EXPECT_LE(kPa
brandtr 2016/10/24 12:52:08 Done.
+}
+
+TEST(FlexfecSenderTest, ProtectTwoFramesWithOneFecPacket) {
+ // Parameters selected to generate a single FEC packet per frame.
+ constexpr size_t kNumFrames = 2;
+ constexpr size_t kNumPacketsPerFrame = 2;
+ FecProtectionParams params = {15, 3, kFecMaskRandom};
danilchap 2016/10/20 15:12:58 Are values 15 and 3 important? If they are, may be
brandtr 2016/10/24 12:52:08 Yes, they are important. Clarified according to yo
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kNoRtpHeaderExtensions, &clock);
+ sender->SetFecParameters(&params);
+
+ AugmentedPacketGenerator packet_generator(kMediaSsrc);
+ for (size_t i = 0; i < kNumFrames; ++i) {
+ packet_generator.NewFrame(kNumPacketsPerFrame);
+ for (size_t j = 0; j < kNumPacketsPerFrame; ++j) {
+ std::unique_ptr<AugmentedPacket> packet =
+ packet_generator.NextPacket(i, kPayloadLength);
+ RtpPacketToSend rtp_packet(nullptr);
+ rtp_packet.Parse(packet->data, packet->length);
+ EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(&rtp_packet));
+ }
+ }
+ EXPECT_TRUE(sender->FecAvailable());
+ std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
+ sender->GetFecPackets();
+ EXPECT_FALSE(sender->FecAvailable());
+ EXPECT_EQ(1U, fec_packets.size());
+
+ RtpPacketToSend* fec_packet = fec_packets.front().get();
+ EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
+ EXPECT_FALSE(fec_packet->Marker());
+ EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
+ EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
+ EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
+ EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
+}
+
+TEST(FlexfecSenderTest, ProtectTwoFramesWithTwoFecPackets) {
+ // Parameters selected to generate a single FEC packet per frame.
+ constexpr size_t kNumFrames = 2;
+ constexpr size_t kNumPacketsPerFrame = 4;
+ FecProtectionParams params = {15, 3, kFecMaskRandom};
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kNoRtpHeaderExtensions, &clock);
+ sender->SetFecParameters(&params);
+
+ AugmentedPacketGenerator packet_generator(kMediaSsrc);
+ for (size_t i = 0; i < kNumFrames; ++i) {
+ packet_generator.NewFrame(kNumPacketsPerFrame);
+ for (size_t j = 0; j < kNumPacketsPerFrame; ++j) {
+ std::unique_ptr<AugmentedPacket> packet =
+ packet_generator.NextPacket(i, kPayloadLength);
+ RtpPacketToSend rtp_packet(nullptr);
+ rtp_packet.Parse(packet->data, packet->length);
+ EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(&rtp_packet));
+ }
+ EXPECT_TRUE(sender->FecAvailable());
+ std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
+ sender->GetFecPackets();
+ EXPECT_FALSE(sender->FecAvailable());
+ EXPECT_EQ(1U, fec_packets.size());
+
+ RtpPacketToSend* fec_packet = fec_packets.front().get();
+ EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
+ EXPECT_FALSE(fec_packet->Marker());
+ EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
+ EXPECT_EQ(static_cast<uint16_t>(kDeterministicSequenceNumber + i),
+ fec_packet->SequenceNumber());
+ EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
+ EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
+ }
+}
+
+// In the tests, we only consider RTP header extensions that are useful for BWE.
+TEST(FlexfecSenderTest, NoRtpHeaderExtensionsForBweByDefault) {
+ const std::vector<RtpExtension> kRtpHeaderExtensions{};
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kRtpHeaderExtensions, &clock);
+ auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
+
+ EXPECT_FALSE(fec_packet->ReserveExtension<AbsoluteSendTime>());
+ EXPECT_FALSE(fec_packet->ReserveExtension<TransmissionOffset>());
+ EXPECT_FALSE(fec_packet->ReserveExtension<TransportSequenceNumber>());
+}
+
+TEST(FlexfecSenderTest, RegisterAbsoluteSendTimeRtpHeaderExtension) {
+ const std::vector<RtpExtension> kRtpHeaderExtensions{
+ {RtpExtension::kAbsSendTimeUri, 1}};
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kRtpHeaderExtensions, &clock);
+ auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
+
+ EXPECT_TRUE(fec_packet->ReserveExtension<AbsoluteSendTime>());
danilchap 2016/10/20 15:12:58 may be fec_packet->HasExtension<AbsoluteSendTime>(
brandtr 2016/10/24 12:52:08 Of course! Fixed.
+ EXPECT_FALSE(fec_packet->ReserveExtension<TransmissionOffset>());
+ EXPECT_FALSE(fec_packet->ReserveExtension<TransportSequenceNumber>());
+}
+
+TEST(FlexfecSenderTest, RegisterTransmissionOffsetRtpHeaderExtension) {
+ const std::vector<RtpExtension> kRtpHeaderExtensions{
+ {RtpExtension::kTimestampOffsetUri, 1}};
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kRtpHeaderExtensions, &clock);
+ auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
+
+ EXPECT_FALSE(fec_packet->ReserveExtension<AbsoluteSendTime>());
+ EXPECT_TRUE(fec_packet->ReserveExtension<TransmissionOffset>());
+ EXPECT_FALSE(fec_packet->ReserveExtension<TransportSequenceNumber>());
+}
+
+TEST(FlexfecSenderTest, RegisterTransportSequenceNumberRtpHeaderExtension) {
+ const std::vector<RtpExtension> kRtpHeaderExtensions{
+ {RtpExtension::kTransportSequenceNumberUri, 1}};
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kRtpHeaderExtensions, &clock);
+ auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
+
+ EXPECT_FALSE(fec_packet->ReserveExtension<AbsoluteSendTime>());
+ EXPECT_FALSE(fec_packet->ReserveExtension<TransmissionOffset>());
+ EXPECT_TRUE(fec_packet->ReserveExtension<TransportSequenceNumber>());
+}
+
+TEST(FlexfecSenderTest, RegisterAllRtpHeaderExtensionsForBwe) {
+ const std::vector<RtpExtension> kRtpHeaderExtensions{
+ {RtpExtension::kAbsSendTimeUri, 1},
+ {RtpExtension::kTimestampOffsetUri, 2},
+ {RtpExtension::kTransportSequenceNumberUri, 3}};
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kRtpHeaderExtensions, &clock);
+ auto fec_packet = GenerateSingleFlexfecPacket(sender.get());
+
+ EXPECT_TRUE(fec_packet->ReserveExtension<AbsoluteSendTime>());
+ EXPECT_TRUE(fec_packet->ReserveExtension<TransmissionOffset>());
+ EXPECT_TRUE(fec_packet->ReserveExtension<TransportSequenceNumber>());
+}
+
+TEST(FlexfecSenderTest, MaxPacketOverhead) {
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ kNoRtpHeaderExtensions, &clock);
+
+ EXPECT_EQ(kFlexfecMaxHeaderSize, sender->MaxPacketOverhead());
+}
+
+// TODO(brandtr): Remove this test when we support multistream protection.
+TEST(FlexfecSenderTest, DoesNotProtectMultipleMediaStreams) {
+ // Parameters selected to generate a single FEC packet.
+ constexpr size_t kNumPacketsStream1 = 4;
+ constexpr size_t kNumPacketsStream2 = 4;
+ constexpr uint32_t kMediaSsrcStream1 = kMediaSsrc;
+ constexpr uint32_t kMediaSsrcStream2 = kMediaSsrc + 1;
+ FecProtectionParams params = {15, 3, kFecMaskRandom};
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ std::unique_ptr<FlexfecSender> sender =
+ FlexfecSender::Create(kFlexfecPayloadType, kFlexfecSsrc,
+ kMediaSsrcStream2, kNoRtpHeaderExtensions, &clock);
+ sender->SetFecParameters(&params);
+
+ // Feed FlexfecSender media packets from stream 1, which IS NOT protected.
+ AugmentedPacketGenerator packet_generator1(kMediaSsrcStream1);
+ packet_generator1.NewFrame(kNumPacketsStream1);
+ for (size_t i = 0; i < kNumPacketsStream1; ++i) {
+ std::unique_ptr<AugmentedPacket> packet =
+ packet_generator1.NextPacket(i, kPayloadLength);
+ RtpPacketToSend rtp_packet(nullptr);
+ rtp_packet.Parse(packet->data, packet->length);
+ EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(&rtp_packet));
+ }
+ EXPECT_FALSE(sender->FecAvailable());
+
+ // Feed FlexfecSender media packets from stream 2, which IS protected.
+ AugmentedPacketGenerator packet_generator2(kMediaSsrcStream2);
+ packet_generator2.NewFrame(kNumPacketsStream2);
+ for (size_t i = 0; i < kNumPacketsStream2; ++i) {
+ std::unique_ptr<AugmentedPacket> packet =
+ packet_generator2.NextPacket(i, kPayloadLength);
+ RtpPacketToSend rtp_packet(nullptr);
+ rtp_packet.Parse(packet->data, packet->length);
+ EXPECT_EQ(0, sender->AddRtpPacketAndGenerateFec(&rtp_packet));
+ }
+ EXPECT_TRUE(sender->FecAvailable());
+ std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
+ sender->GetFecPackets();
+ EXPECT_FALSE(sender->FecAvailable());
+ EXPECT_EQ(1U, fec_packets.size());
+
+ RtpPacketToSend* fec_packet = fec_packets.front().get();
+ EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
+ EXPECT_FALSE(fec_packet->Marker());
+ EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
+ EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
+ EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
+ EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
+ EXPECT_GE(fec_packet->payload_size(), kPayloadLength);
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698