diff --git a/call/BUILD.gn b/call/BUILD.gn index ffb38ee9e3..1924e26780 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -240,7 +240,6 @@ rtc_source_set("fake_network") { "..:webrtc_common", "../api:transport_api", "../modules:module_api", - "../modules/rtp_rtcp", "../rtc_base:rtc_base_approved", "../rtc_base:sequenced_task_checker", "../system_wrappers", diff --git a/call/fake_network_pipe.cc b/call/fake_network_pipe.cc index 6562f549e1..e3f5393e35 100644 --- a/call/fake_network_pipe.cc +++ b/call/fake_network_pipe.cc @@ -18,7 +18,6 @@ #include "call/call.h" #include "call/fake_network_pipe.h" -#include "modules/rtp_rtcp/include/rtp_header_parser.h" #include "rtc_base/logging.h" #include "system_wrappers/include/clock.h" @@ -69,52 +68,21 @@ NetworkPacket& NetworkPacket::operator=(NetworkPacket&& o) { return *this; } -DemuxerImpl::DemuxerImpl(const std::map& payload_type_map) - : packet_receiver_(nullptr), payload_type_map_(payload_type_map) {} - -void DemuxerImpl::SetReceiver(PacketReceiver* receiver) { - packet_receiver_ = receiver; -} - -void DemuxerImpl::DeliverPacket(const NetworkPacket* packet, - const PacketTime& packet_time) { - // No packet receiver means that this demuxer will terminate the flow of - // packets. - if (!packet_receiver_) - return; - const uint8_t* const packet_data = packet->data(); - const size_t packet_length = packet->data_length(); - MediaType media_type = MediaType::ANY; - if (!RtpHeaderParser::IsRtcp(packet_data, packet_length)) { - RTC_CHECK_GE(packet_length, 2); - const uint8_t payload_type = packet_data[1] & 0x7f; - std::map::const_iterator it = - payload_type_map_.find(payload_type); - RTC_CHECK(it != payload_type_map_.end()) - << "payload type " << static_cast(payload_type) << " unknown."; - media_type = it->second; - } - packet_receiver_->DeliverPacket( - media_type, rtc::CopyOnWriteBuffer(packet_data, packet_length), - packet_time); -} - FakeNetworkPipe::FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config) : FakeNetworkPipe(clock, config, nullptr, 1) {} FakeNetworkPipe::FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config, - std::unique_ptr demuxer) - : FakeNetworkPipe(clock, config, std::move(demuxer), 1) {} + PacketReceiver* receiver) + : FakeNetworkPipe(clock, config, receiver, 1) {} FakeNetworkPipe::FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config, - std::unique_ptr demuxer, + PacketReceiver* receiver, uint64_t seed) : clock_(clock), - demuxer_(std::move(demuxer)), - receiver_(nullptr), + receiver_(receiver), transport_(nullptr), random_(seed), clock_offset_ms_(0), @@ -150,8 +118,6 @@ FakeNetworkPipe::~FakeNetworkPipe() = default; void FakeNetworkPipe::SetReceiver(PacketReceiver* receiver) { rtc::CritScope crit(&config_lock_); - if (demuxer_) - demuxer_->SetReceiver(receiver); receiver_ = receiver; } @@ -209,13 +175,6 @@ void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) { } } -void FakeNetworkPipe::SendPacket(const uint8_t* data, size_t data_length) { - RTC_DCHECK(HasDemuxer()); - PacketTime packet_time(clock_->TimeInMicroseconds(), 0); - EnqueuePacket(rtc::CopyOnWriteBuffer(data, data_length), rtc::nullopt, false, - MediaType::ANY, packet_time); -} - bool FakeNetworkPipe::EnqueuePacket(rtc::CopyOnWriteBuffer packet, rtc::Optional options, bool is_rtcp, @@ -389,14 +348,13 @@ void FakeNetworkPipe::Process() { void FakeNetworkPipe::DeliverPacket(NetworkPacket* packet) { if (transport_) { RTC_DCHECK(!receiver_); - RTC_DCHECK(!demuxer_); if (packet->is_rtcp()) { transport_->SendRtcp(packet->data(), packet->data_length()); } else { transport_->SendRtp(packet->data(), packet->data_length(), packet->packet_options()); } - } else { + } else if (receiver_) { PacketTime packet_time = packet->packet_time(); if (packet_time.timestamp != -1) { int64_t queue_time = packet->arrival_time() - packet->send_time(); @@ -404,12 +362,8 @@ void FakeNetworkPipe::DeliverPacket(NetworkPacket* packet) { packet_time.timestamp += (queue_time * 1000); packet_time.timestamp += (clock_offset_ms_ * 1000); } - if (demuxer_) { - demuxer_->DeliverPacket(packet, packet_time); - } else if (receiver_) { - receiver_->DeliverPacket(packet->media_type(), - std::move(*packet->raw_packet()), packet_time); - } + receiver_->DeliverPacket(packet->media_type(), + std::move(*packet->raw_packet()), packet_time); } } @@ -423,10 +377,9 @@ bool FakeNetworkPipe::HasTransport() const { rtc::CritScope crit(&config_lock_); return transport_ != nullptr; } - -bool FakeNetworkPipe::HasDemuxer() const { +bool FakeNetworkPipe::HasReceiver() const { rtc::CritScope crit(&config_lock_); - return demuxer_ != nullptr; + return receiver_ != nullptr; } void FakeNetworkPipe::DeliverPacketWithLock(NetworkPacket* packet) { diff --git a/call/fake_network_pipe.h b/call/fake_network_pipe.h index 3c6cfdd6b1..7331068d2a 100644 --- a/call/fake_network_pipe.h +++ b/call/fake_network_pipe.h @@ -82,29 +82,6 @@ class NetworkPacket { rtc::Optional packet_time_; }; -class Demuxer { - public: - virtual ~Demuxer() = default; - virtual void SetReceiver(PacketReceiver* receiver) = 0; - virtual void DeliverPacket(const NetworkPacket* packet, - const PacketTime& packet_time) = 0; -}; - -// This class doesn't have any internal thread safety, so caller must make sure -// SetReceiver and DeliverPacket aren't called in a racy manner. -class DemuxerImpl final : public Demuxer { - public: - explicit DemuxerImpl(const std::map& payload_type_map); - - void SetReceiver(PacketReceiver* receiver) override; - void DeliverPacket(const NetworkPacket* packet, - const PacketTime& packet_time) override; - - private: - PacketReceiver* packet_receiver_; - const std::map payload_type_map_; - RTC_DISALLOW_COPY_AND_ASSIGN(DemuxerImpl); -}; // Class faking a network link. This is a simple and naive solution just faking // capacity and adding an extra transport delay in addition to the capacity @@ -130,16 +107,14 @@ class FakeNetworkPipe : public Transport, public PacketReceiver, public Module { int avg_burst_loss_length = -1; }; - // Use this constructor if you plan to insert packets using DeliverPacket(). + // Use these constructors if you plan to insert packets using DeliverPacket(). FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config); - - // Use these constructors if you plan to insert packets using SendPacket(). FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config, - std::unique_ptr demuxer); + PacketReceiver* receiver); FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config, - std::unique_ptr demuxer, + PacketReceiver* receiver, uint64_t seed); // Use this constructor if you plan to insert packets using SendRt[c?]p(). @@ -154,12 +129,7 @@ class FakeNetworkPipe : public Transport, public PacketReceiver, public Module { // Sets a new configuration. This won't affect packets already in the pipe. void SetConfig(const FakeNetworkPipe::Config& config); - // Sends a new packet to the link. When/if packets are delivered, they will - // be passed to the receiver instance given in SetReceiver(). This method - // should only be used if a Demuxer was provided in the constructor. - void SendPacket(const uint8_t* packet, size_t packet_length); - - // Must not be called in parallel with SendPacket or Process. + // Must not be called in parallel with DeliverPacket or Process. void SetReceiver(PacketReceiver* receiver); // Implements Transport interface. When/if packets are delivered, they will @@ -214,12 +184,11 @@ class FakeNetworkPipe : public Transport, public PacketReceiver, public Module { void DeliverPacket(NetworkPacket* packet) RTC_EXCLUSIVE_LOCKS_REQUIRED(config_lock_); bool HasTransport() const; - bool HasDemuxer() const; + bool HasReceiver() const; Clock* const clock_; // |config_lock| guards the mostly constant things like the callbacks. rtc::CriticalSection config_lock_; - const std::unique_ptr demuxer_ RTC_GUARDED_BY(config_lock_); PacketReceiver* receiver_ RTC_GUARDED_BY(config_lock_); Transport* const transport_ RTC_GUARDED_BY(config_lock_); diff --git a/call/test/fake_network_pipe_unittest.cc b/call/test/fake_network_pipe_unittest.cc index e63b7ed762..14288c6f6e 100644 --- a/call/test/fake_network_pipe_unittest.cc +++ b/call/test/fake_network_pipe_unittest.cc @@ -25,36 +25,27 @@ using ::testing::Invoke; namespace webrtc { -class TestDemuxer : public Demuxer { - public: - void IncomingPacket(NetworkPacket* packet) { - DeliverPacket(packet, PacketTime()); - } - - MOCK_METHOD1(SetReceiver, void(PacketReceiver* receiver)); - MOCK_METHOD2(DeliverPacket, - void(const NetworkPacket* packet, - const PacketTime& packet_time)); -}; - -class ReorderTestDemuxer : public TestDemuxer { - public: - void DeliverPacket(const NetworkPacket* packet, - const PacketTime& packet_time) override { - RTC_DCHECK_GE(packet->data_length(), sizeof(int)); - int seq_num; - memcpy(&seq_num, packet->data(), sizeof(int)); - delivered_sequence_numbers_.push_back(seq_num); - } - std::vector delivered_sequence_numbers_; -}; - class MockReceiver : public PacketReceiver { public: MOCK_METHOD3(DeliverPacket, DeliveryStatus(MediaType, rtc::CopyOnWriteBuffer, const PacketTime&)); + virtual ~MockReceiver() = default; +}; + +class ReorderTestReceiver : public MockReceiver { + public: + DeliveryStatus DeliverPacket(MediaType media_type, + rtc::CopyOnWriteBuffer packet, + const PacketTime& packet_time) override { + RTC_DCHECK_GE(packet.size(), sizeof(int)); + int seq_num; + memcpy(&seq_num, packet.data(), sizeof(int)); + delivered_sequence_numbers_.push_back(seq_num); + return DeliveryStatus::DELIVERY_OK; + } + std::vector delivered_sequence_numbers_; }; class FakeNetworkPipeTest : public ::testing::Test { @@ -69,7 +60,8 @@ class FakeNetworkPipeTest : public ::testing::Test { // Set a sequence number for the packets by // using the first bytes in the packet. memcpy(packet.get(), &i, sizeof(int)); - pipe->SendPacket(packet.get(), packet_size); + rtc::CopyOnWriteBuffer buffer(packet.get(), packet_size); + pipe->DeliverPacket(MediaType::ANY, buffer, PacketTime()); } } @@ -85,9 +77,9 @@ TEST_F(FakeNetworkPipeTest, CapacityTest) { FakeNetworkPipe::Config config; config.queue_length_packets = 20; config.link_capacity_kbps = 80; - TestDemuxer* demuxer = new TestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); + MockReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to // get through the pipe. @@ -100,22 +92,22 @@ TEST_F(FakeNetworkPipeTest, CapacityTest) { PacketTimeMs(config.link_capacity_kbps, kPacketSize); // Time haven't increased yet, so we souldn't get any packets. - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0); pipe->Process(); // Advance enough time to release one packet. fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); pipe->Process(); // Release all but one packet fake_clock_.AdvanceTimeMilliseconds(9 * kPacketTimeMs - 1); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(8); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(8); pipe->Process(); // And the last one. fake_clock_.AdvanceTimeMilliseconds(1); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); pipe->Process(); } @@ -125,9 +117,9 @@ TEST_F(FakeNetworkPipeTest, ExtraDelayTest) { config.queue_length_packets = 20; config.queue_delay_ms = 100; config.link_capacity_kbps = 80; - TestDemuxer* demuxer = new TestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); + MockReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); const int kNumPackets = 2; const int kPacketSize = 1000; @@ -139,17 +131,17 @@ TEST_F(FakeNetworkPipeTest, ExtraDelayTest) { // Increase more than kPacketTimeMs, but not more than the extra delay. fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0); pipe->Process(); // Advance the network delay to get the first packet. fake_clock_.AdvanceTimeMilliseconds(config.queue_delay_ms); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); pipe->Process(); // Advance one more kPacketTimeMs to get the last packet. fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); pipe->Process(); } @@ -159,9 +151,9 @@ TEST_F(FakeNetworkPipeTest, QueueLengthTest) { FakeNetworkPipe::Config config; config.queue_length_packets = 2; config.link_capacity_kbps = 80; - TestDemuxer* demuxer = new TestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); + MockReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); const int kPacketSize = 1000; const int kPacketTimeMs = @@ -173,7 +165,7 @@ TEST_F(FakeNetworkPipeTest, QueueLengthTest) { // Increase time enough to deliver all three packets, verify only two are // delivered. fake_clock_.AdvanceTimeMilliseconds(3 * kPacketTimeMs); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(2); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(2); pipe->Process(); } @@ -183,9 +175,9 @@ TEST_F(FakeNetworkPipeTest, StatisticsTest) { config.queue_length_packets = 2; config.queue_delay_ms = 20; config.link_capacity_kbps = 80; - TestDemuxer* demuxer = new TestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); + MockReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); const int kPacketSize = 1000; const int kPacketTimeMs = @@ -196,7 +188,7 @@ TEST_F(FakeNetworkPipeTest, StatisticsTest) { fake_clock_.AdvanceTimeMilliseconds(3 * kPacketTimeMs + config.queue_delay_ms); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(2); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(2); pipe->Process(); // Packet 1: kPacketTimeMs + config.queue_delay_ms, @@ -213,9 +205,9 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) { FakeNetworkPipe::Config config; config.queue_length_packets = 20; config.link_capacity_kbps = 80; - TestDemuxer* demuxer = new TestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); + MockReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to // get through the pipe. @@ -227,13 +219,13 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) { int packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize); // Time hasn't increased yet, so we souldn't get any packets. - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0); pipe->Process(); // Advance time in steps to release one packet at a time. for (int i = 0; i < kNumPackets; ++i) { fake_clock_.AdvanceTimeMilliseconds(packet_time_ms); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); pipe->Process(); } @@ -249,20 +241,20 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) { packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize); // Time hasn't increased yet, so we souldn't get any packets. - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0); pipe->Process(); // Advance time in steps to release one packet at a time. for (int i = 0; i < kNumPackets; ++i) { fake_clock_.AdvanceTimeMilliseconds(packet_time_ms); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); pipe->Process(); } // Check that all the packets were sent. EXPECT_EQ(static_cast(2 * kNumPackets), pipe->SentPackets()); fake_clock_.AdvanceTimeMilliseconds(pipe->TimeUntilNextProcess()); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0); pipe->Process(); } @@ -272,9 +264,9 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithPacketsInPipeTest) { FakeNetworkPipe::Config config; config.queue_length_packets = 20; config.link_capacity_kbps = 80; - TestDemuxer* demuxer = new TestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); + MockReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); // Add 10 packets of 1000 bytes, = 80 kb. const int kNumPackets = 10; @@ -296,27 +288,27 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithPacketsInPipeTest) { int packet_time_2_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize); // Time hasn't increased yet, so we souldn't get any packets. - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0); pipe->Process(); // Advance time in steps to release one packet at a time. for (int i = 0; i < kNumPackets; ++i) { fake_clock_.AdvanceTimeMilliseconds(packet_time_1_ms); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); pipe->Process(); } // Advance time in steps to release one packet at a time. for (int i = 0; i < kNumPackets; ++i) { fake_clock_.AdvanceTimeMilliseconds(packet_time_2_ms); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); pipe->Process(); } // Check that all the packets were sent. EXPECT_EQ(static_cast(2 * kNumPackets), pipe->SentPackets()); fake_clock_.AdvanceTimeMilliseconds(pipe->TimeUntilNextProcess()); - EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0); pipe->Process(); } @@ -327,9 +319,9 @@ TEST_F(FakeNetworkPipeTest, DisallowReorderingThenAllowReordering) { config.link_capacity_kbps = 800; config.queue_delay_ms = 100; config.delay_standard_deviation_ms = 10; - ReorderTestDemuxer* demuxer = new ReorderTestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); + ReorderTestReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); const uint32_t kNumPackets = 100; const int kPacketSize = 10; @@ -338,9 +330,9 @@ TEST_F(FakeNetworkPipeTest, DisallowReorderingThenAllowReordering) { pipe->Process(); // Confirm that all packets have been delivered in order. - EXPECT_EQ(kNumPackets, demuxer->delivered_sequence_numbers_.size()); + EXPECT_EQ(kNumPackets, receiver.delivered_sequence_numbers_.size()); int last_seq_num = -1; - for (int seq_num : demuxer->delivered_sequence_numbers_) { + for (int seq_num : receiver.delivered_sequence_numbers_) { EXPECT_GT(seq_num, last_seq_num); last_seq_num = seq_num; } @@ -349,15 +341,15 @@ TEST_F(FakeNetworkPipeTest, DisallowReorderingThenAllowReordering) { pipe->SetConfig(config); SendPackets(pipe.get(), kNumPackets, kPacketSize); fake_clock_.AdvanceTimeMilliseconds(1000); - demuxer->delivered_sequence_numbers_.clear(); + receiver.delivered_sequence_numbers_.clear(); pipe->Process(); // Confirm that all packets have been delivered // and that reordering has occured. - EXPECT_EQ(kNumPackets, demuxer->delivered_sequence_numbers_.size()); + EXPECT_EQ(kNumPackets, receiver.delivered_sequence_numbers_.size()); bool reordering_has_occured = false; last_seq_num = -1; - for (int seq_num : demuxer->delivered_sequence_numbers_) { + for (int seq_num : receiver.delivered_sequence_numbers_) { if (last_seq_num > seq_num) { reordering_has_occured = true; break; @@ -377,26 +369,26 @@ TEST_F(FakeNetworkPipeTest, BurstLoss) { config.queue_length_packets = kNumPackets; config.loss_percent = kLossPercent; config.avg_burst_loss_length = kAvgBurstLength; - ReorderTestDemuxer* demuxer = new ReorderTestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); + ReorderTestReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); SendPackets(pipe.get(), kNumPackets, kPacketSize); fake_clock_.AdvanceTimeMilliseconds(1000); pipe->Process(); // Check that the average loss is |kLossPercent| percent. - int lost_packets = kNumPackets - demuxer->delivered_sequence_numbers_.size(); + int lost_packets = kNumPackets - receiver.delivered_sequence_numbers_.size(); double loss_fraction = lost_packets / static_cast(kNumPackets); EXPECT_NEAR(kLossPercent / 100.0, loss_fraction, 0.05); // Find the number of bursts that has occurred. - size_t received_packets = demuxer->delivered_sequence_numbers_.size(); + size_t received_packets = receiver.delivered_sequence_numbers_.size(); int num_bursts = 0; for (size_t i = 0; i < received_packets - 1; ++i) { - int diff = demuxer->delivered_sequence_numbers_[i + 1] - - demuxer->delivered_sequence_numbers_[i]; + int diff = receiver.delivered_sequence_numbers_[i + 1] - + receiver.delivered_sequence_numbers_[i]; if (diff > 1) ++num_bursts; } @@ -408,41 +400,27 @@ TEST_F(FakeNetworkPipeTest, BurstLoss) { TEST_F(FakeNetworkPipeTest, SetReceiver) { FakeNetworkPipe::Config config; - TestDemuxer* demuxer = new TestDemuxer(); - std::unique_ptr pipe(new FakeNetworkPipe( - &fake_clock_, config, std::unique_ptr(demuxer))); - MockReceiver packet_receiver; - EXPECT_CALL(*demuxer, SetReceiver(&packet_receiver)).Times(1); - pipe->SetReceiver(&packet_receiver); -} + config.link_capacity_kbps = 800; + MockReceiver receiver; + std::unique_ptr pipe( + new FakeNetworkPipe(&fake_clock_, config, &receiver)); -TEST(DemuxerImplTest, Demuxing) { - constexpr uint8_t kVideoPayloadType = 100; - constexpr uint8_t kAudioPayloadType = 101; - constexpr int64_t kTimeNow = 12345; - constexpr int64_t kArrivalTime = kTimeNow - 1; - constexpr size_t kPacketSize = 10; - DemuxerImpl demuxer({{kVideoPayloadType, MediaType::VIDEO}, - {kAudioPayloadType, MediaType::AUDIO}}); + const int kPacketSize = 1000; + const int kPacketTimeMs = + PacketTimeMs(config.link_capacity_kbps, kPacketSize); + SendPackets(pipe.get(), 1, kPacketSize); + fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1); + pipe->Process(); - MockReceiver mock_receiver; - demuxer.SetReceiver(&mock_receiver); + MockReceiver new_receiver; + pipe->SetReceiver(&new_receiver); - rtc::CopyOnWriteBuffer data(kPacketSize); - data[1] = kVideoPayloadType; - std::unique_ptr packet( - new NetworkPacket(data, kTimeNow, kArrivalTime, rtc::nullopt, false, - MediaType::ANY, rtc::nullopt)); - EXPECT_CALL(mock_receiver, DeliverPacket(MediaType::VIDEO, _, _)) - .WillOnce(Return(PacketReceiver::DELIVERY_OK)); - demuxer.DeliverPacket(packet.get(), PacketTime()); - - data[1] = kAudioPayloadType; - packet.reset(new NetworkPacket(data, kTimeNow, kArrivalTime, rtc::nullopt, - false, MediaType::ANY, rtc::nullopt)); - EXPECT_CALL(mock_receiver, DeliverPacket(MediaType::AUDIO, _, _)) - .WillOnce(Return(PacketReceiver::DELIVERY_OK)); - demuxer.DeliverPacket(packet.get(), PacketTime()); + SendPackets(pipe.get(), 1, kPacketSize); + fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs); + EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0); + EXPECT_CALL(new_receiver, DeliverPacket(_, _, _)).Times(1); + pipe->Process(); } } // namespace webrtc diff --git a/test/BUILD.gn b/test/BUILD.gn index ece4003acb..c69ad08eb8 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -310,6 +310,7 @@ if (rtc_include_tests) { rtc_test("test_support_unittests") { deps = [ + ":direct_transport", ":fileutils", ":perf_test", ":rtp_test_utils", @@ -325,6 +326,7 @@ if (rtc_include_tests) { "//testing/gtest", ] sources = [ + "direct_transport_unittest.cc", "frame_generator_unittest.cc", "rtp_file_reader_unittest.cc", "rtp_file_writer_unittest.cc", diff --git a/test/direct_transport.cc b/test/direct_transport.cc index 971130fe9e..4b2fd0463e 100644 --- a/test/direct_transport.cc +++ b/test/direct_transport.cc @@ -10,6 +10,7 @@ #include "test/direct_transport.h" #include "call/call.h" +#include "modules/rtp_rtcp/include/rtp_header_parser.h" #include "rtc_base/ptr_util.h" #include "system_wrappers/include/clock.h" #include "test/single_threaded_task_queue.h" @@ -17,6 +18,23 @@ namespace webrtc { namespace test { +Demuxer::Demuxer(const std::map& payload_type_map) + : payload_type_map_(payload_type_map) {} + +MediaType Demuxer::GetMediaType(const uint8_t* packet_data, + const size_t packet_length) const { + if (!RtpHeaderParser::IsRtcp(packet_data, packet_length)) { + RTC_CHECK_GE(packet_length, 2); + const uint8_t payload_type = packet_data[1] & 0x7f; + std::map::const_iterator it = + payload_type_map_.find(payload_type); + RTC_CHECK(it != payload_type_map_.end()) + << "payload type " << static_cast(payload_type) << " unknown."; + return it->second; + } + return MediaType::ANY; +} + DirectTransport::DirectTransport( SingleThreadedTaskQueueForTesting* task_queue, Call* send_call, @@ -32,31 +50,23 @@ DirectTransport::DirectTransport( const FakeNetworkPipe::Config& config, Call* send_call, const std::map& payload_type_map) - : DirectTransport( - task_queue, - config, - send_call, - std::unique_ptr(new DemuxerImpl(payload_type_map))) { -} - -DirectTransport::DirectTransport(SingleThreadedTaskQueueForTesting* task_queue, - const FakeNetworkPipe::Config& config, - Call* send_call, - std::unique_ptr demuxer) : send_call_(send_call), clock_(Clock::GetRealTimeClock()), task_queue_(task_queue), - fake_network_(rtc::MakeUnique(clock_, config, - std::move(demuxer))) { + demuxer_(payload_type_map), + fake_network_(rtc::MakeUnique(clock_, config)) { Start(); } -DirectTransport::DirectTransport(SingleThreadedTaskQueueForTesting* task_queue, - std::unique_ptr pipe, - Call* send_call) +DirectTransport::DirectTransport( + SingleThreadedTaskQueueForTesting* task_queue, + std::unique_ptr pipe, + Call* send_call, + const std::map& payload_type_map) : send_call_(send_call), clock_(Clock::GetRealTimeClock()), task_queue_(task_queue), + demuxer_(payload_type_map), fake_network_(std::move(pipe)) { Start(); } @@ -94,15 +104,22 @@ bool DirectTransport::SendRtp(const uint8_t* data, clock_->TimeInMilliseconds()); send_call_->OnSentPacket(sent_packet); } - fake_network_->SendPacket(data, length); + SendPacket(data, length); return true; } bool DirectTransport::SendRtcp(const uint8_t* data, size_t length) { - fake_network_->SendPacket(data, length); + SendPacket(data, length); return true; } +void DirectTransport::SendPacket(const uint8_t* data, size_t length) { + MediaType media_type = demuxer_.GetMediaType(data, length); + int64_t send_time = clock_->TimeInMicroseconds(); + fake_network_->DeliverPacket(media_type, rtc::CopyOnWriteBuffer(data, length), + PacketTime(send_time, -1)); +} + int DirectTransport::GetAverageDelayMs() { return fake_network_->AverageDelay(); } diff --git a/test/direct_transport.h b/test/direct_transport.h index d61282aae7..2d473073e9 100644 --- a/test/direct_transport.h +++ b/test/direct_transport.h @@ -27,6 +27,15 @@ class Clock; class PacketReceiver; namespace test { +class Demuxer { + public: + explicit Demuxer(const std::map& payload_type_map); + ~Demuxer() = default; + MediaType GetMediaType(const uint8_t* packet_data, + const size_t packet_length) const; + const std::map payload_type_map_; + RTC_DISALLOW_COPY_AND_ASSIGN(Demuxer); +}; // Objects of this class are expected to be allocated and destroyed on the // same task-queue - the one that's passed in via the constructor. @@ -42,12 +51,9 @@ class DirectTransport : public Transport { const std::map& payload_type_map); DirectTransport(SingleThreadedTaskQueueForTesting* task_queue, - const FakeNetworkPipe::Config& config, + std::unique_ptr pipe, Call* send_call, - std::unique_ptr demuxer); - - DirectTransport(SingleThreadedTaskQueueForTesting* task_queue, - std::unique_ptr pipe, Call* send_call); + const std::map& payload_type_map); ~DirectTransport() override; @@ -69,6 +75,7 @@ class DirectTransport : public Transport { private: void SendPackets(); + void SendPacket(const uint8_t* data, size_t length); void Start(); Call* const send_call_; @@ -78,7 +85,8 @@ class DirectTransport : public Transport { SingleThreadedTaskQueueForTesting::TaskId next_scheduled_task_ RTC_GUARDED_BY(&sequence_checker_); - std::unique_ptr fake_network_; + const Demuxer demuxer_; + const std::unique_ptr fake_network_; rtc::SequencedTaskChecker sequence_checker_; }; diff --git a/test/direct_transport_unittest.cc b/test/direct_transport_unittest.cc new file mode 100644 index 0000000000..d35c4a4c03 --- /dev/null +++ b/test/direct_transport_unittest.cc @@ -0,0 +1,30 @@ +/* + * Copyright 2018 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 "test/direct_transport.h" +#include "test/gtest.h" + +namespace webrtc { +namespace test { +TEST(DemuxerTest, Demuxing) { + constexpr uint8_t kVideoPayloadType = 100; + constexpr uint8_t kAudioPayloadType = 101; + constexpr size_t kPacketSize = 10; + Demuxer demuxer({{kVideoPayloadType, MediaType::VIDEO}, + {kAudioPayloadType, MediaType::AUDIO}}); + + uint8_t data[kPacketSize]; + memset(data, 0, kPacketSize); + data[1] = kVideoPayloadType; + EXPECT_EQ(demuxer.GetMediaType(data, kPacketSize), MediaType::VIDEO); + data[1] = kAudioPayloadType; + EXPECT_EQ(demuxer.GetMediaType(data, kPacketSize), MediaType::AUDIO); +} +} // namespace test +} // namespace webrtc diff --git a/test/layer_filtering_transport.cc b/test/layer_filtering_transport.cc index 4cf1ccadf4..c28110ca04 100644 --- a/test/layer_filtering_transport.cc +++ b/test/layer_filtering_transport.cc @@ -48,9 +48,10 @@ LayerFilteringTransport::LayerFilteringTransport( uint8_t vp9_video_payload_type, int selected_tl, int selected_sl, + const std::map& payload_type_map, uint32_t ssrc_to_filter_min, uint32_t ssrc_to_filter_max) - : DirectTransport(task_queue, std::move(pipe), send_call), + : DirectTransport(task_queue, std::move(pipe), send_call, payload_type_map), vp8_video_payload_type_(vp8_video_payload_type), vp9_video_payload_type_(vp9_video_payload_type), selected_tl_(selected_tl), @@ -84,8 +85,9 @@ LayerFilteringTransport::LayerFilteringTransport( uint8_t vp8_video_payload_type, uint8_t vp9_video_payload_type, int selected_tl, - int selected_sl) - : DirectTransport(task_queue, std::move(pipe), send_call), + int selected_sl, + const std::map& payload_type_map) + : DirectTransport(task_queue, std::move(pipe), send_call, payload_type_map), vp8_video_payload_type_(vp8_video_payload_type), vp9_video_payload_type_(vp9_video_payload_type), selected_tl_(selected_tl), diff --git a/test/layer_filtering_transport.h b/test/layer_filtering_transport.h index b63dc29fab..8835b89463 100644 --- a/test/layer_filtering_transport.h +++ b/test/layer_filtering_transport.h @@ -48,6 +48,7 @@ class LayerFilteringTransport : public test::DirectTransport { uint8_t vp9_video_payload_type, int selected_tl, int selected_sl, + const std::map& payload_type_map, uint32_t ssrc_to_filter_min, uint32_t ssrc_to_filter_max); LayerFilteringTransport(SingleThreadedTaskQueueForTesting* task_queue, @@ -56,7 +57,8 @@ class LayerFilteringTransport : public test::DirectTransport { uint8_t vp8_video_payload_type, uint8_t vp9_video_payload_type, int selected_tl, - int selected_sl); + int selected_sl, + const std::map& payload_type_map); bool DiscardedLastPacket() const; bool SendRtp(const uint8_t* data, size_t length, diff --git a/test/rtp_rtcp_observer.h b/test/rtp_rtcp_observer.h index 5163d2248e..1f213b475c 100644 --- a/test/rtp_rtcp_observer.h +++ b/test/rtp_rtcp_observer.h @@ -106,10 +106,15 @@ class PacketTransport : public test::DirectTransport { transport_type_(transport_type) {} PacketTransport(SingleThreadedTaskQueueForTesting* task_queue, - Call* send_call, RtpRtcpObserver* observer, + Call* send_call, + RtpRtcpObserver* observer, TransportType transport_type, + const std::map& payload_type_map, std::unique_ptr nw_pipe) - : test::DirectTransport(task_queue, std::move(nw_pipe), send_call), + : test::DirectTransport(task_queue, + std::move(nw_pipe), + send_call, + payload_type_map), observer_(observer), transport_type_(transport_type) {}