New PacketQueue2 behind WebRTC-RoundRobinPacing field trial.

To make testing easier all of PacketQueues functions have been made virtual,
and PacketQueue2 now inherits PacketQueue. This change was made to minimize
changes in PacedSender.

Bug: webrtc:8287, webrtc:8288
Change-Id: I2593340e7cc7da617370b0a33e7b9deeb46d9487
Reviewed-on: https://webrtc-review.googlesource.com/9380
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20385}
This commit is contained in:
philipel 2017-10-23 12:42:17 +02:00 committed by Commit Bot
parent 0c720505af
commit ccdfccaa6f
8 changed files with 215 additions and 209 deletions

View file

@ -60,7 +60,9 @@ PacedSender::PacedSender(const Clock* clock,
pacing_bitrate_kbps_(0), pacing_bitrate_kbps_(0),
time_last_update_us_(clock->TimeInMicroseconds()), time_last_update_us_(clock->TimeInMicroseconds()),
first_sent_packet_ms_(-1), first_sent_packet_ms_(-1),
packets_(rtc::MakeUnique<PacketQueue>(clock)), packets_(webrtc::field_trial::IsEnabled("WebRTC-RoundRobinPacing")
? rtc::MakeUnique<PacketQueue2>(clock)
: rtc::MakeUnique<PacketQueue>(clock)),
packet_counter_(0), packet_counter_(0),
pacing_factor_(kDefaultPaceMultiplier), pacing_factor_(kDefaultPaceMultiplier),
queue_time_limit(kMaxQueueLengthMs), queue_time_limit(kMaxQueueLengthMs),

View file

@ -15,7 +15,7 @@
#include "api/optional.h" #include "api/optional.h"
#include "modules/pacing/pacer.h" #include "modules/pacing/pacer.h"
#include "modules/pacing/packet_queue.h" #include "modules/pacing/packet_queue2.h"
#include "rtc_base/criticalsection.h" #include "rtc_base/criticalsection.h"
#include "rtc_base/thread_annotations.h" #include "rtc_base/thread_annotations.h"
#include "typedefs.h" // NOLINT(build/include) #include "typedefs.h" // NOLINT(build/include)

View file

@ -10,9 +10,12 @@
#include <list> #include <list>
#include <memory> #include <memory>
#include <string>
#include "modules/pacing/paced_sender.h" #include "modules/pacing/paced_sender.h"
#include "system_wrappers/include/clock.h" #include "system_wrappers/include/clock.h"
#include "system_wrappers/include/field_trial.h"
#include "test/field_trial.h"
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
@ -101,9 +104,9 @@ class PacedSenderProbing : public PacedSender::PacketSender {
int padding_sent_; int padding_sent_;
}; };
class PacedSenderTest : public ::testing::Test { class PacedSenderTest : public testing::TestWithParam<std::string> {
protected: protected:
PacedSenderTest() : clock_(123456) { PacedSenderTest() : clock_(123456), field_trial_(GetParam()) {
srand(0); srand(0);
// Need to initialize PacedSender after we initialize clock. // Need to initialize PacedSender after we initialize clock.
send_bucket_.reset(new PacedSender(&clock_, &callback_, nullptr)); send_bucket_.reset(new PacedSender(&clock_, &callback_, nullptr));
@ -134,9 +137,15 @@ class PacedSenderTest : public ::testing::Test {
SimulatedClock clock_; SimulatedClock clock_;
MockPacedSenderCallback callback_; MockPacedSenderCallback callback_;
std::unique_ptr<PacedSender> send_bucket_; std::unique_ptr<PacedSender> send_bucket_;
test::ScopedFieldTrials field_trial_;
}; };
TEST_F(PacedSenderTest, FirstSentPacketTimeIsSet) { INSTANTIATE_TEST_CASE_P(RoundRobin,
PacedSenderTest,
::testing::Values("WebRTC-RoundRobinPacing/Disabled/",
"WebRTC-RoundRobinPacing/Enabled/"));
TEST_P(PacedSenderTest, FirstSentPacketTimeIsSet) {
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
const uint32_t kSsrc = 12345; const uint32_t kSsrc = 12345;
const size_t kSizeBytes = 250; const size_t kSizeBytes = 250;
@ -155,7 +164,7 @@ TEST_F(PacedSenderTest, FirstSentPacketTimeIsSet) {
EXPECT_EQ(kStartMs, send_bucket_->FirstSentPacketTimeMs()); EXPECT_EQ(kStartMs, send_bucket_->FirstSentPacketTimeMs());
} }
TEST_F(PacedSenderTest, QueuePacket) { TEST_P(PacedSenderTest, QueuePacket) {
uint32_t ssrc = 12345; uint32_t ssrc = 12345;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
// Due to the multiplicative factor we can send 5 packets during a send // Due to the multiplicative factor we can send 5 packets during a send
@ -203,7 +212,7 @@ TEST_F(PacedSenderTest, QueuePacket) {
EXPECT_EQ(1u, send_bucket_->QueueSizePackets()); EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
} }
TEST_F(PacedSenderTest, PaceQueuedPackets) { TEST_P(PacedSenderTest, PaceQueuedPackets) {
uint32_t ssrc = 12345; uint32_t ssrc = 12345;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
@ -255,7 +264,7 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) {
EXPECT_EQ(1u, send_bucket_->QueueSizePackets()); EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
} }
TEST_F(PacedSenderTest, RepeatedRetransmissionsAllowed) { TEST_P(PacedSenderTest, RepeatedRetransmissionsAllowed) {
// Send one packet, then two retransmissions of that packet. // Send one packet, then two retransmissions of that packet.
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
constexpr uint32_t ssrc = 333; constexpr uint32_t ssrc = 333;
@ -269,7 +278,7 @@ TEST_F(PacedSenderTest, RepeatedRetransmissionsAllowed) {
send_bucket_->Process(); send_bucket_->Process();
} }
TEST_F(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) { TEST_P(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) {
uint32_t ssrc = 12345; uint32_t ssrc = 12345;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
@ -292,7 +301,7 @@ TEST_F(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) {
send_bucket_->Process(); send_bucket_->Process();
} }
TEST_F(PacedSenderTest, Padding) { TEST_P(PacedSenderTest, Padding) {
uint32_t ssrc = 12345; uint32_t ssrc = 12345;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
@ -332,7 +341,7 @@ TEST_F(PacedSenderTest, Padding) {
send_bucket_->Process(); send_bucket_->Process();
} }
TEST_F(PacedSenderTest, NoPaddingBeforeNormalPacket) { TEST_P(PacedSenderTest, NoPaddingBeforeNormalPacket) {
send_bucket_->SetEstimatedBitrate(kTargetBitrateBps); send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
send_bucket_->SetSendBitrateLimits(kTargetBitrateBps, kTargetBitrateBps); send_bucket_->SetSendBitrateLimits(kTargetBitrateBps, kTargetBitrateBps);
@ -355,7 +364,7 @@ TEST_F(PacedSenderTest, NoPaddingBeforeNormalPacket) {
send_bucket_->Process(); send_bucket_->Process();
} }
TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) { TEST_P(PacedSenderTest, VerifyPaddingUpToBitrate) {
uint32_t ssrc = 12345; uint32_t ssrc = 12345;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
int64_t capture_time_ms = 56789; int64_t capture_time_ms = 56789;
@ -380,7 +389,7 @@ TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) {
} }
} }
TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) { TEST_P(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
uint32_t ssrc = 12345; uint32_t ssrc = 12345;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
int64_t capture_time_ms = 56789; int64_t capture_time_ms = 56789;
@ -413,7 +422,7 @@ TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
1); 1);
} }
TEST_F(PacedSenderTest, Priority) { TEST_P(PacedSenderTest, Priority) {
uint32_t ssrc_low_priority = 12345; uint32_t ssrc_low_priority = 12345;
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
@ -468,7 +477,7 @@ TEST_F(PacedSenderTest, Priority) {
send_bucket_->Process(); send_bucket_->Process();
} }
TEST_F(PacedSenderTest, RetransmissionPriority) { TEST_P(PacedSenderTest, RetransmissionPriority) {
uint32_t ssrc = 12345; uint32_t ssrc = 12345;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
int64_t capture_time_ms = 45678; int64_t capture_time_ms = 45678;
@ -522,7 +531,7 @@ TEST_F(PacedSenderTest, RetransmissionPriority) {
EXPECT_EQ(0u, send_bucket_->QueueSizePackets()); EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
} }
TEST_F(PacedSenderTest, HighPrioDoesntAffectBudget) { TEST_P(PacedSenderTest, HighPrioDoesntAffectBudget) {
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
int64_t capture_time_ms = 56789; int64_t capture_time_ms = 56789;
@ -560,7 +569,7 @@ TEST_F(PacedSenderTest, HighPrioDoesntAffectBudget) {
EXPECT_EQ(0u, send_bucket_->QueueSizePackets()); EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
} }
TEST_F(PacedSenderTest, Pause) { TEST_P(PacedSenderTest, Pause) {
uint32_t ssrc_low_priority = 12345; uint32_t ssrc_low_priority = 12345;
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint32_t ssrc_high_priority = 12347; uint32_t ssrc_high_priority = 12347;
@ -674,7 +683,7 @@ TEST_F(PacedSenderTest, Pause) {
EXPECT_EQ(0, send_bucket_->QueueInMs()); EXPECT_EQ(0, send_bucket_->QueueInMs());
} }
TEST_F(PacedSenderTest, ResendPacket) { TEST_P(PacedSenderTest, ResendPacket) {
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
int64_t capture_time_ms = clock_.TimeInMilliseconds(); int64_t capture_time_ms = clock_.TimeInMilliseconds();
@ -727,7 +736,7 @@ TEST_F(PacedSenderTest, ResendPacket) {
EXPECT_EQ(0, send_bucket_->QueueInMs()); EXPECT_EQ(0, send_bucket_->QueueInMs());
} }
TEST_F(PacedSenderTest, ExpectedQueueTimeMs) { TEST_P(PacedSenderTest, ExpectedQueueTimeMs) {
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
const size_t kNumPackets = 60; const size_t kNumPackets = 60;
@ -764,7 +773,7 @@ TEST_F(PacedSenderTest, ExpectedQueueTimeMs) {
static_cast<int64_t>(1000 * kPacketSize * 8 / kMaxBitrate)); static_cast<int64_t>(1000 * kPacketSize * 8 / kMaxBitrate));
} }
TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) { TEST_P(PacedSenderTest, QueueTimeGrowsOverTime) {
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
EXPECT_EQ(0, send_bucket_->QueueInMs()); EXPECT_EQ(0, send_bucket_->QueueInMs());
@ -783,7 +792,7 @@ TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
EXPECT_EQ(0, send_bucket_->QueueInMs()); EXPECT_EQ(0, send_bucket_->QueueInMs());
} }
TEST_F(PacedSenderTest, ProbingWithInsertedPackets) { TEST_P(PacedSenderTest, ProbingWithInsertedPackets) {
const size_t kPacketSize = 1200; const size_t kPacketSize = 1200;
const int kInitialBitrateBps = 300000; const int kInitialBitrateBps = 300000;
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
@ -829,7 +838,7 @@ TEST_F(PacedSenderTest, ProbingWithInsertedPackets) {
kSecondClusterBps, kBitrateProbingError); kSecondClusterBps, kBitrateProbingError);
} }
TEST_F(PacedSenderTest, ProbingWithPaddingSupport) { TEST_P(PacedSenderTest, ProbingWithPaddingSupport) {
const size_t kPacketSize = 1200; const size_t kPacketSize = 1200;
const int kInitialBitrateBps = 300000; const int kInitialBitrateBps = 300000;
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
@ -865,7 +874,11 @@ TEST_F(PacedSenderTest, ProbingWithPaddingSupport) {
kFirstClusterBps, kBitrateProbingError); kFirstClusterBps, kBitrateProbingError);
} }
TEST_F(PacedSenderTest, PriorityInversion) { TEST_P(PacedSenderTest, PriorityInversion) {
// In this test capture timestamps are used to order packets, capture
// timestamps are not used in PacketQueue2.
if (webrtc::field_trial::IsEnabled("WebRTC-RoundRobinPacing"))
return;
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
const size_t kPacketSize = 1200; const size_t kPacketSize = 1200;
@ -916,7 +929,7 @@ TEST_F(PacedSenderTest, PriorityInversion) {
} }
} }
TEST_F(PacedSenderTest, PaddingOveruse) { TEST_P(PacedSenderTest, PaddingOveruse) {
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
const size_t kPacketSize = 1200; const size_t kPacketSize = 1200;
@ -990,7 +1003,7 @@ TEST_F(PacedSenderTest, AverageQueueTime) {
} }
#endif #endif
TEST_F(PacedSenderTest, ProbeClusterId) { TEST_P(PacedSenderTest, ProbeClusterId) {
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
const size_t kPacketSize = 1200; const size_t kPacketSize = 1200;
@ -1036,7 +1049,7 @@ TEST_F(PacedSenderTest, ProbeClusterId) {
send_bucket_->Process(); send_bucket_->Process();
} }
TEST_F(PacedSenderTest, AvoidBusyLoopOnSendFailure) { TEST_P(PacedSenderTest, AvoidBusyLoopOnSendFailure) {
uint32_t ssrc = 12346; uint32_t ssrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;
const size_t kPacketSize = kFirstClusterBps / (8000 / 10); const size_t kPacketSize = kFirstClusterBps / (8000 / 10);
@ -1094,7 +1107,7 @@ TEST_F(PacedSenderTest, QueueTimeWithPause) {
EXPECT_EQ(200, send_bucket_->AverageQueueTimeMs()); EXPECT_EQ(200, send_bucket_->AverageQueueTimeMs());
} }
TEST_F(PacedSenderTest, QueueTimePausedDuringPush) { TEST_P(PacedSenderTest, QueueTimePausedDuringPush) {
const size_t kPacketSize = 1200; const size_t kPacketSize = 1200;
const uint32_t kSsrc = 12346; const uint32_t kSsrc = 12346;
uint16_t sequence_number = 1234; uint16_t sequence_number = 1234;

View file

@ -44,6 +44,8 @@ PacketQueue::Packet::Packet(RtpPacketSender::Priority priority,
retransmission(retransmission), retransmission(retransmission),
enqueue_order(enqueue_order) {} enqueue_order(enqueue_order) {}
PacketQueue::Packet::Packet(const Packet& other) = default;
PacketQueue::Packet::~Packet() {} PacketQueue::Packet::~Packet() {}
PacketQueue::PacketQueue(const Clock* clock) PacketQueue::PacketQueue(const Clock* clock)

View file

@ -13,6 +13,7 @@
#include <list> #include <list>
#include <queue> #include <queue>
#include <set>
#include <vector> #include <vector>
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@ -34,31 +35,43 @@ class PacketQueue {
bool retransmission, bool retransmission,
uint64_t enqueue_order); uint64_t enqueue_order);
Packet(const Packet& other);
virtual ~Packet(); virtual ~Packet();
bool operator<(const Packet& other) const {
if (priority != other.priority)
return priority > other.priority;
if (retransmission != other.retransmission)
return other.retransmission;
return enqueue_order > other.enqueue_order;
}
RtpPacketSender::Priority priority; RtpPacketSender::Priority priority;
uint32_t ssrc; uint32_t ssrc;
uint16_t sequence_number; uint16_t sequence_number;
int64_t capture_time_ms; // Absolute time of frame capture. int64_t capture_time_ms; // Absolute time of frame capture.
int64_t enqueue_time_ms; // Absolute time of pacer queue entry. int64_t enqueue_time_ms; // Absolute time of pacer queue entry.
int64_t sum_paused_ms; // Sum of time spent in queue while pacer is paused. int64_t sum_paused_ms;
size_t bytes; size_t bytes;
bool retransmission; bool retransmission;
uint64_t enqueue_order; uint64_t enqueue_order;
std::list<Packet>::iterator this_it; std::list<Packet>::iterator this_it;
std::multiset<int64_t>::iterator enqueue_time_it;
}; };
void Push(const Packet& packet); virtual void Push(const Packet& packet);
const Packet& BeginPop(); virtual const Packet& BeginPop();
void CancelPop(const Packet& packet); virtual void CancelPop(const Packet& packet);
void FinalizePop(const Packet& packet); virtual void FinalizePop(const Packet& packet);
bool Empty() const; virtual bool Empty() const;
size_t SizeInPackets() const; virtual size_t SizeInPackets() const;
uint64_t SizeInBytes() const; virtual uint64_t SizeInBytes() const;
int64_t OldestEnqueueTimeMs() const; virtual int64_t OldestEnqueueTimeMs() const;
void UpdateQueueTime(int64_t timestamp_ms); virtual void UpdateQueueTime(int64_t timestamp_ms);
void SetPauseState(bool paused, int64_t timestamp_ms); virtual void SetPauseState(bool paused, int64_t timestamp_ms);
int64_t AverageQueueTimeMs() const; virtual int64_t AverageQueueTimeMs() const;
private: private:
// Try to add a packet to the set of ssrc/seqno identifiers currently in the // Try to add a packet to the set of ssrc/seqno identifiers currently in the

View file

@ -20,29 +20,10 @@ namespace webrtc {
PacketQueue2::Stream::Stream() : bytes(0) {} PacketQueue2::Stream::Stream() : bytes(0) {}
PacketQueue2::Stream::~Stream() {} PacketQueue2::Stream::~Stream() {}
PacketQueue2::Packet::Packet(RtpPacketSender::Priority priority,
uint32_t ssrc,
uint16_t seq_number,
int64_t capture_time_ms,
int64_t enqueue_time_ms,
size_t length_in_bytes,
bool retransmission,
uint64_t enqueue_order)
: priority(priority),
ssrc(ssrc),
sequence_number(seq_number),
capture_time_ms(capture_time_ms),
enqueue_time_ms(enqueue_time_ms),
bytes(length_in_bytes),
retransmission(retransmission),
enqueue_order(enqueue_order) {}
PacketQueue2::Packet::Packet(const Packet& other) = default;
PacketQueue2::Packet::~Packet() {}
PacketQueue2::PacketQueue2(const Clock* clock) PacketQueue2::PacketQueue2(const Clock* clock)
: clock_(clock), time_last_updated_(clock_->TimeInMilliseconds()) {} : PacketQueue(clock),
clock_(clock),
time_last_updated_(clock_->TimeInMilliseconds()) {}
PacketQueue2::~PacketQueue2() {} PacketQueue2::~PacketQueue2() {}
@ -89,16 +70,31 @@ void PacketQueue2::Push(const Packet& packet_to_insert) {
size_bytes_ += packet.bytes; size_bytes_ += packet.bytes;
} }
const PacketQueue2::Packet& PacketQueue2::Top() { const PacketQueue2::Packet& PacketQueue2::BeginPop() {
return GetHighestPriorityStream()->packet_queue.top(); RTC_CHECK(!pop_packet_ && !pop_stream_);
Stream* stream = GetHighestPriorityStream();
pop_stream_.emplace(stream);
pop_packet_.emplace(stream->packet_queue.top());
stream->packet_queue.pop();
return *pop_packet_;
} }
void PacketQueue2::Pop() { void PacketQueue2::CancelPop(const Packet& packet) {
RTC_CHECK(pop_packet_ && pop_stream_);
(*pop_stream_)->packet_queue.push(*pop_packet_);
pop_packet_.reset();
pop_stream_.reset();
}
void PacketQueue2::FinalizePop(const Packet& packet) {
RTC_CHECK(!paused_); RTC_CHECK(!paused_);
if (!Empty()) { if (!Empty()) {
Stream* streams_ = GetHighestPriorityStream(); RTC_CHECK(pop_packet_ && pop_stream_);
stream_priorities_.erase(streams_->priority_it); Stream* stream = *pop_stream_;
const Packet& packet = streams_->packet_queue.top(); stream_priorities_.erase(stream->priority_it);
const Packet& packet = *pop_packet_;
// Calculate the total amount of time spent by this packet in the queue // Calculate the total amount of time spent by this packet in the queue
// while in a non-paused state. Note that the |pause_time_sum_ms_| was // while in a non-paused state. Note that the |pause_time_sum_ms_| was
@ -118,25 +114,26 @@ void PacketQueue2::Pop() {
// case a "budget" will be built up for the stream sending at the lower // case a "budget" will be built up for the stream sending at the lower
// rate. To avoid building a too large budget we limit |bytes| to be within // rate. To avoid building a too large budget we limit |bytes| to be within
// kMaxLeading bytes of the stream that has sent the most amount of bytes. // kMaxLeading bytes of the stream that has sent the most amount of bytes.
streams_->bytes = stream->bytes =
std::max(streams_->bytes + packet.bytes, max_bytes_ - kMaxLeadingBytes); std::max(stream->bytes + packet.bytes, max_bytes_ - kMaxLeadingBytes);
max_bytes_ = std::max(max_bytes_, streams_->bytes); max_bytes_ = std::max(max_bytes_, stream->bytes);
size_bytes_ -= packet.bytes; size_bytes_ -= packet.bytes;
size_packets_ -= 1; size_packets_ -= 1;
RTC_CHECK(size_packets_ > 0 || queue_time_sum_ms_ == 0); RTC_CHECK(size_packets_ > 0 || queue_time_sum_ms_ == 0);
streams_->packet_queue.pop();
// If there are packets left to be sent, schedule the stream again. // If there are packets left to be sent, schedule the stream again.
RTC_CHECK(!IsSsrcScheduled(streams_->ssrc)); RTC_CHECK(!IsSsrcScheduled(stream->ssrc));
if (streams_->packet_queue.empty()) { if (stream->packet_queue.empty()) {
streams_->priority_it = stream_priorities_.end(); stream->priority_it = stream_priorities_.end();
} else { } else {
RtpPacketSender::Priority priority = RtpPacketSender::Priority priority = stream->packet_queue.top().priority;
streams_->packet_queue.top().priority; stream->priority_it = stream_priorities_.emplace(
streams_->priority_it = stream_priorities_.emplace( StreamPrioKey(priority, stream->bytes), stream->ssrc);
StreamPrioKey(priority, streams_->bytes), streams_->ssrc);
} }
pop_packet_.reset();
pop_stream_.reset();
} }
} }

View file

@ -15,61 +15,31 @@
#include <queue> #include <queue>
#include <set> #include <set>
#include "modules/pacing/packet_queue.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
namespace webrtc { namespace webrtc {
class PacketQueue2 { class PacketQueue2 : public PacketQueue {
public: public:
explicit PacketQueue2(const Clock* clock); explicit PacketQueue2(const Clock* clock);
virtual ~PacketQueue2(); ~PacketQueue2() override;
struct Packet { using Packet = PacketQueue::Packet;
Packet(RtpPacketSender::Priority priority,
uint32_t ssrc,
uint16_t seq_number,
int64_t capture_time_ms,
int64_t enqueue_time_ms,
size_t length_in_bytes,
bool retransmission,
uint64_t enqueue_order);
Packet(const Packet& other); void Push(const Packet& packet) override;
const Packet& BeginPop() override;
void CancelPop(const Packet& packet) override;
void FinalizePop(const Packet& packet) override;
virtual ~Packet(); bool Empty() const override;
size_t SizeInPackets() const override;
uint64_t SizeInBytes() const override;
bool operator<(const Packet& other) const { int64_t OldestEnqueueTimeMs() const override;
if (priority != other.priority) int64_t AverageQueueTimeMs() const override;
return priority > other.priority; void UpdateQueueTime(int64_t timestamp_ms) override;
if (retransmission != other.retransmission) void SetPauseState(bool paused, int64_t timestamp_ms) override;
return other.retransmission;
return enqueue_order > other.enqueue_order;
}
RtpPacketSender::Priority priority;
uint32_t ssrc;
uint16_t sequence_number;
int64_t capture_time_ms; // Absolute time of frame capture.
int64_t enqueue_time_ms; // Absolute time of pacer queue entry.
size_t bytes;
bool retransmission;
uint64_t enqueue_order;
std::multiset<int64_t>::iterator enqueue_time_it;
};
void Push(const Packet& packet);
const Packet& Top();
void Pop();
bool Empty() const;
size_t SizeInPackets() const;
uint64_t SizeInBytes() const;
int64_t OldestEnqueueTimeMs() const;
int64_t AverageQueueTimeMs() const;
void UpdateQueueTime(int64_t timestamp_ms);
void SetPauseState(bool paused, int64_t timestamp_ms);
struct StreamPrioKey { struct StreamPrioKey {
StreamPrioKey() = default; StreamPrioKey() = default;
@ -112,11 +82,14 @@ class PacketQueue2 {
bool IsSsrcScheduled(uint32_t ssrc) const; bool IsSsrcScheduled(uint32_t ssrc) const;
const Clock* const clock_; const Clock* const clock_;
int64_t time_last_updated_;
rtc::Optional<Packet> pop_packet_;
rtc::Optional<Stream*> pop_stream_;
bool paused_ = false; bool paused_ = false;
size_t size_packets_ = 0; size_t size_packets_ = 0;
size_t size_bytes_ = 0; size_t size_bytes_ = 0;
size_t max_bytes_ = kMaxLeadingBytes; size_t max_bytes_ = kMaxLeadingBytes;
int64_t time_last_updated_;
int64_t queue_time_sum_ms_ = 0; int64_t queue_time_sum_ms_ = 0;
int64_t pause_time_sum_ms_ = 0; int64_t pause_time_sum_ms_ = 0;

View file

@ -78,9 +78,10 @@ namespace {
constexpr int kSilenceTimeoutMs = 2000; constexpr int kSilenceTimeoutMs = 2000;
} }
class EndToEndTest : public test::CallTest { class EndToEndTest : public test::CallTest,
public testing::WithParamInterface<std::string> {
public: public:
EndToEndTest() {} EndToEndTest() : field_trial_(GetParam()) {}
virtual ~EndToEndTest() { virtual ~EndToEndTest() {
EXPECT_EQ(nullptr, video_send_stream_); EXPECT_EQ(nullptr, video_send_stream_);
@ -148,9 +149,11 @@ class EndToEndTest : public test::CallTest {
void VerifyNewVideoReceiveStreamsRespectNetworkState( void VerifyNewVideoReceiveStreamsRespectNetworkState(
MediaType network_to_bring_up, MediaType network_to_bring_up,
Transport* transport); Transport* transport);
test::ScopedFieldTrials field_trial_;
}; };
TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) { TEST_P(EndToEndTest, ReceiverCanBeStartedTwice) {
CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get())); CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
test::NullTransport transport; test::NullTransport transport;
@ -165,7 +168,7 @@ TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) {
DestroyStreams(); DestroyStreams();
} }
TEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) { TEST_P(EndToEndTest, ReceiverCanBeStoppedTwice) {
CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get())); CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
test::NullTransport transport; test::NullTransport transport;
@ -180,7 +183,7 @@ TEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) {
DestroyStreams(); DestroyStreams();
} }
TEST_F(EndToEndTest, ReceiverCanBeStoppedAndRestarted) { TEST_P(EndToEndTest, ReceiverCanBeStoppedAndRestarted) {
CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get())); CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
test::NullTransport transport; test::NullTransport transport;
@ -196,7 +199,7 @@ TEST_F(EndToEndTest, ReceiverCanBeStoppedAndRestarted) {
DestroyStreams(); DestroyStreams();
} }
TEST_F(EndToEndTest, RendersSingleDelayedFrame) { TEST_P(EndToEndTest, RendersSingleDelayedFrame) {
static const int kWidth = 320; static const int kWidth = 320;
static const int kHeight = 240; static const int kHeight = 240;
// This constant is chosen to be higher than the timeout in the video_render // This constant is chosen to be higher than the timeout in the video_render
@ -264,7 +267,7 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
}); });
} }
TEST_F(EndToEndTest, TransmitsFirstFrame) { TEST_P(EndToEndTest, TransmitsFirstFrame) {
class Renderer : public rtc::VideoSinkInterface<VideoFrame> { class Renderer : public rtc::VideoSinkInterface<VideoFrame> {
public: public:
Renderer() : event_(false, false) {} Renderer() : event_(false, false) {}
@ -381,26 +384,26 @@ class CodecObserver : public test::EndToEndTest,
int frame_counter_; int frame_counter_;
}; };
TEST_F(EndToEndTest, SendsAndReceivesVP8) { TEST_P(EndToEndTest, SendsAndReceivesVP8) {
CodecObserver test(5, kVideoRotation_0, "VP8", VP8Encoder::Create(), CodecObserver test(5, kVideoRotation_0, "VP8", VP8Encoder::Create(),
VP8Decoder::Create()); VP8Decoder::Create());
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, SendsAndReceivesVP8Rotation90) { TEST_P(EndToEndTest, SendsAndReceivesVP8Rotation90) {
CodecObserver test(5, kVideoRotation_90, "VP8", VP8Encoder::Create(), CodecObserver test(5, kVideoRotation_90, "VP8", VP8Encoder::Create(),
VP8Decoder::Create()); VP8Decoder::Create());
RunBaseTest(&test); RunBaseTest(&test);
} }
#if !defined(RTC_DISABLE_VP9) #if !defined(RTC_DISABLE_VP9)
TEST_F(EndToEndTest, SendsAndReceivesVP9) { TEST_P(EndToEndTest, SendsAndReceivesVP9) {
CodecObserver test(500, kVideoRotation_0, "VP9", VP9Encoder::Create(), CodecObserver test(500, kVideoRotation_0, "VP9", VP9Encoder::Create(),
VP9Decoder::Create()); VP9Decoder::Create());
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, SendsAndReceivesVP9VideoRotation90) { TEST_P(EndToEndTest, SendsAndReceivesVP9VideoRotation90) {
CodecObserver test(5, kVideoRotation_90, "VP9", VP9Encoder::Create(), CodecObserver test(5, kVideoRotation_90, "VP9", VP9Encoder::Create(),
VP9Decoder::Create()); VP9Decoder::Create());
RunBaseTest(&test); RunBaseTest(&test);
@ -408,21 +411,21 @@ TEST_F(EndToEndTest, SendsAndReceivesVP9VideoRotation90) {
#endif // !defined(RTC_DISABLE_VP9) #endif // !defined(RTC_DISABLE_VP9)
#if defined(WEBRTC_USE_H264) #if defined(WEBRTC_USE_H264)
TEST_F(EndToEndTest, SendsAndReceivesH264) { TEST_P(EndToEndTest, SendsAndReceivesH264) {
CodecObserver test(500, kVideoRotation_0, "H264", CodecObserver test(500, kVideoRotation_0, "H264",
H264Encoder::Create(cricket::VideoCodec("H264")), H264Encoder::Create(cricket::VideoCodec("H264")),
H264Decoder::Create()); H264Decoder::Create());
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, SendsAndReceivesH264VideoRotation90) { TEST_P(EndToEndTest, SendsAndReceivesH264VideoRotation90) {
CodecObserver test(5, kVideoRotation_90, "H264", CodecObserver test(5, kVideoRotation_90, "H264",
H264Encoder::Create(cricket::VideoCodec("H264")), H264Encoder::Create(cricket::VideoCodec("H264")),
H264Decoder::Create()); H264Decoder::Create());
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, SendsAndReceivesH264PacketizationMode0) { TEST_P(EndToEndTest, SendsAndReceivesH264PacketizationMode0) {
cricket::VideoCodec codec = cricket::VideoCodec("H264"); cricket::VideoCodec codec = cricket::VideoCodec("H264");
codec.SetParam(cricket::kH264FmtpPacketizationMode, "0"); codec.SetParam(cricket::kH264FmtpPacketizationMode, "0");
CodecObserver test(500, kVideoRotation_0, "H264", H264Encoder::Create(codec), CodecObserver test(500, kVideoRotation_0, "H264", H264Encoder::Create(codec),
@ -430,7 +433,7 @@ TEST_F(EndToEndTest, SendsAndReceivesH264PacketizationMode0) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, SendsAndReceivesH264PacketizationMode1) { TEST_P(EndToEndTest, SendsAndReceivesH264PacketizationMode1) {
cricket::VideoCodec codec = cricket::VideoCodec("H264"); cricket::VideoCodec codec = cricket::VideoCodec("H264");
codec.SetParam(cricket::kH264FmtpPacketizationMode, "1"); codec.SetParam(cricket::kH264FmtpPacketizationMode, "1");
CodecObserver test(500, kVideoRotation_0, "H264", H264Encoder::Create(codec), CodecObserver test(500, kVideoRotation_0, "H264", H264Encoder::Create(codec),
@ -440,7 +443,7 @@ TEST_F(EndToEndTest, SendsAndReceivesH264PacketizationMode1) {
#endif // defined(WEBRTC_USE_H264) #endif // defined(WEBRTC_USE_H264)
TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) { TEST_P(EndToEndTest, ReceiverUsesLocalSsrc) {
class SyncRtcpObserver : public test::EndToEndTest { class SyncRtcpObserver : public test::EndToEndTest {
public: public:
SyncRtcpObserver() : EndToEndTest(kDefaultTimeoutMs) {} SyncRtcpObserver() : EndToEndTest(kDefaultTimeoutMs) {}
@ -463,7 +466,7 @@ TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { TEST_P(EndToEndTest, ReceivesAndRetransmitsNack) {
static const int kNumberOfNacksToObserve = 2; static const int kNumberOfNacksToObserve = 2;
static const int kLossBurstSize = 2; static const int kLossBurstSize = 2;
static const int kPacketsBetweenLossBursts = 9; static const int kPacketsBetweenLossBursts = 9;
@ -546,7 +549,7 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ReceivesNackAndRetransmitsAudio) { TEST_P(EndToEndTest, ReceivesNackAndRetransmitsAudio) {
class NackObserver : public test::EndToEndTest { class NackObserver : public test::EndToEndTest {
public: public:
NackObserver() NackObserver()
@ -618,7 +621,7 @@ TEST_F(EndToEndTest, ReceivesNackAndRetransmitsAudio) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ReceivesUlpfec) { TEST_P(EndToEndTest, ReceivesUlpfec) {
class UlpfecRenderObserver : public test::EndToEndTest, class UlpfecRenderObserver : public test::EndToEndTest,
public rtc::VideoSinkInterface<VideoFrame> { public rtc::VideoSinkInterface<VideoFrame> {
public: public:
@ -892,22 +895,22 @@ class FlexfecRenderObserver : public test::EndToEndTest,
int num_packets_sent_; int num_packets_sent_;
}; };
TEST_F(EndToEndTest, RecoversWithFlexfec) { TEST_P(EndToEndTest, RecoversWithFlexfec) {
FlexfecRenderObserver test(false, false); FlexfecRenderObserver test(false, false);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, RecoversWithFlexfecAndNack) { TEST_P(EndToEndTest, RecoversWithFlexfecAndNack) {
FlexfecRenderObserver test(true, false); FlexfecRenderObserver test(true, false);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, RecoversWithFlexfecAndSendsCorrespondingRtcp) { TEST_P(EndToEndTest, RecoversWithFlexfecAndSendsCorrespondingRtcp) {
FlexfecRenderObserver test(false, true); FlexfecRenderObserver test(false, true);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) {
class UlpfecNackObserver : public test::EndToEndTest { class UlpfecNackObserver : public test::EndToEndTest {
public: public:
UlpfecNackObserver() UlpfecNackObserver()
@ -1226,19 +1229,19 @@ void EndToEndTest::DecodesRetransmittedFrame(bool enable_rtx, bool enable_red) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, DecodesRetransmittedFrame) { TEST_P(EndToEndTest, DecodesRetransmittedFrame) {
DecodesRetransmittedFrame(false, false); DecodesRetransmittedFrame(false, false);
} }
TEST_F(EndToEndTest, DecodesRetransmittedFrameOverRtx) { TEST_P(EndToEndTest, DecodesRetransmittedFrameOverRtx) {
DecodesRetransmittedFrame(true, false); DecodesRetransmittedFrame(true, false);
} }
TEST_F(EndToEndTest, DecodesRetransmittedFrameByRed) { TEST_P(EndToEndTest, DecodesRetransmittedFrameByRed) {
DecodesRetransmittedFrame(false, true); DecodesRetransmittedFrame(false, true);
} }
TEST_F(EndToEndTest, DecodesRetransmittedFrameByRedOverRtx) { TEST_P(EndToEndTest, DecodesRetransmittedFrameByRedOverRtx) {
DecodesRetransmittedFrame(true, true); DecodesRetransmittedFrame(true, true);
} }
@ -1322,15 +1325,15 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ReceivesPliAndRecoversWithNack) { TEST_P(EndToEndTest, ReceivesPliAndRecoversWithNack) {
ReceivesPliAndRecovers(1000); ReceivesPliAndRecovers(1000);
} }
TEST_F(EndToEndTest, ReceivesPliAndRecoversWithoutNack) { TEST_P(EndToEndTest, ReceivesPliAndRecoversWithoutNack) {
ReceivesPliAndRecovers(0); ReceivesPliAndRecovers(0);
} }
TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { TEST_P(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
class PacketInputObserver : public PacketReceiver { class PacketInputObserver : public PacketReceiver {
public: public:
explicit PacketInputObserver(PacketReceiver* receiver) explicit PacketInputObserver(PacketReceiver* receiver)
@ -1481,11 +1484,11 @@ void EndToEndTest::RespectsRtcpMode(RtcpMode rtcp_mode) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, UsesRtcpCompoundMode) { TEST_P(EndToEndTest, UsesRtcpCompoundMode) {
RespectsRtcpMode(RtcpMode::kCompound); RespectsRtcpMode(RtcpMode::kCompound);
} }
TEST_F(EndToEndTest, UsesRtcpReducedSizeMode) { TEST_P(EndToEndTest, UsesRtcpReducedSizeMode) {
RespectsRtcpMode(RtcpMode::kReducedSize); RespectsRtcpMode(RtcpMode::kReducedSize);
} }
@ -1636,7 +1639,7 @@ class MultiStreamTest {
// Each renderer verifies that it receives the expected resolution, and as soon // Each renderer verifies that it receives the expected resolution, and as soon
// as every renderer has received a frame, the test finishes. // as every renderer has received a frame, the test finishes.
TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) { TEST_P(EndToEndTest, SendsAndReceivesMultipleStreams) {
class VideoOutputObserver : public rtc::VideoSinkInterface<VideoFrame> { class VideoOutputObserver : public rtc::VideoSinkInterface<VideoFrame> {
public: public:
VideoOutputObserver(const MultiStreamTest::CodecSettings& settings, VideoOutputObserver(const MultiStreamTest::CodecSettings& settings,
@ -1702,7 +1705,7 @@ TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
tester.RunTest(); tester.RunTest();
} }
TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) { TEST_P(EndToEndTest, AssignsTransportSequenceNumbers) {
static const int kExtensionId = 5; static const int kExtensionId = 5;
class RtpExtensionHeaderObserver : public test::DirectTransport { class RtpExtensionHeaderObserver : public test::DirectTransport {
@ -1977,32 +1980,32 @@ class TransportFeedbackTester : public test::EndToEndTest {
Call* receiver_call_; Call* receiver_call_;
}; };
TEST_F(EndToEndTest, VideoReceivesTransportFeedback) { TEST_P(EndToEndTest, VideoReceivesTransportFeedback) {
TransportFeedbackTester test(true, 1, 0); TransportFeedbackTester test(true, 1, 0);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, VideoTransportFeedbackNotConfigured) { TEST_P(EndToEndTest, VideoTransportFeedbackNotConfigured) {
TransportFeedbackTester test(false, 1, 0); TransportFeedbackTester test(false, 1, 0);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, AudioReceivesTransportFeedback) { TEST_P(EndToEndTest, AudioReceivesTransportFeedback) {
TransportFeedbackTester test(true, 0, 1); TransportFeedbackTester test(true, 0, 1);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, AudioTransportFeedbackNotConfigured) { TEST_P(EndToEndTest, AudioTransportFeedbackNotConfigured) {
TransportFeedbackTester test(false, 0, 1); TransportFeedbackTester test(false, 0, 1);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, AudioVideoReceivesTransportFeedback) { TEST_P(EndToEndTest, AudioVideoReceivesTransportFeedback) {
TransportFeedbackTester test(true, 1, 1); TransportFeedbackTester test(true, 1, 1);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, StopsSendingMediaWithoutFeedback) { TEST_P(EndToEndTest, StopsSendingMediaWithoutFeedback) {
test::ScopedFieldTrials override_field_trials( test::ScopedFieldTrials override_field_trials(
"WebRTC-CwndExperiment/Enabled-250/"); "WebRTC-CwndExperiment/Enabled-250/");
@ -2076,7 +2079,7 @@ TEST_F(EndToEndTest, StopsSendingMediaWithoutFeedback) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ObserversEncodedFrames) { TEST_P(EndToEndTest, ObserversEncodedFrames) {
class EncodedFrameTestObserver : public EncodedFrameObserver { class EncodedFrameTestObserver : public EncodedFrameObserver {
public: public:
EncodedFrameTestObserver() EncodedFrameTestObserver()
@ -2159,7 +2162,7 @@ TEST_F(EndToEndTest, ObserversEncodedFrames) {
}); });
} }
TEST_F(EndToEndTest, ReceiveStreamSendsRemb) { TEST_P(EndToEndTest, ReceiveStreamSendsRemb) {
class RembObserver : public test::EndToEndTest { class RembObserver : public test::EndToEndTest {
public: public:
RembObserver() : EndToEndTest(kDefaultTimeoutMs) {} RembObserver() : EndToEndTest(kDefaultTimeoutMs) {}
@ -2250,12 +2253,12 @@ class BandwidthStatsTest : public test::EndToEndTest {
const bool send_side_bwe_; const bool send_side_bwe_;
}; };
TEST_F(EndToEndTest, VerifySendSideBweStats) { TEST_P(EndToEndTest, VerifySendSideBweStats) {
BandwidthStatsTest test(true); BandwidthStatsTest test(true);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, VerifyRecvSideBweStats) { TEST_P(EndToEndTest, VerifyRecvSideBweStats) {
BandwidthStatsTest test(false); BandwidthStatsTest test(false);
RunBaseTest(&test); RunBaseTest(&test);
} }
@ -2265,7 +2268,7 @@ TEST_F(EndToEndTest, VerifyRecvSideBweStats) {
// then have the test generate a REMB of 500 kbps and verify that the send BWE // then have the test generate a REMB of 500 kbps and verify that the send BWE
// is reduced to exactly 500 kbps. Then a REMB of 1000 kbps is generated and the // is reduced to exactly 500 kbps. Then a REMB of 1000 kbps is generated and the
// test verifies that the send BWE ramps back up to exactly 1000 kbps. // test verifies that the send BWE ramps back up to exactly 1000 kbps.
TEST_F(EndToEndTest, RembWithSendSideBwe) { TEST_P(EndToEndTest, RembWithSendSideBwe) {
class BweObserver : public test::EndToEndTest { class BweObserver : public test::EndToEndTest {
public: public:
BweObserver() BweObserver()
@ -2391,7 +2394,7 @@ TEST_F(EndToEndTest, RembWithSendSideBwe) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, StopSendingKeyframeRequestsForInactiveStream) { TEST_P(EndToEndTest, StopSendingKeyframeRequestsForInactiveStream) {
class KeyframeRequestObserver : public test::EndToEndTest { class KeyframeRequestObserver : public test::EndToEndTest {
public: public:
explicit KeyframeRequestObserver( explicit KeyframeRequestObserver(
@ -2460,7 +2463,7 @@ class ProbingTest : public test::EndToEndTest {
Call* sender_call_; Call* sender_call_;
}; };
TEST_F(EndToEndTest, MAYBE_InitialProbing) { TEST_P(EndToEndTest, MAYBE_InitialProbing) {
class InitialProbingTest : public ProbingTest { class InitialProbingTest : public ProbingTest {
public: public:
explicit InitialProbingTest(bool* success) explicit InitialProbingTest(bool* success)
@ -2503,12 +2506,12 @@ TEST_F(EndToEndTest, MAYBE_InitialProbing) {
// Fails on Linux MSan: bugs.webrtc.org/7428 // Fails on Linux MSan: bugs.webrtc.org/7428
#if defined(MEMORY_SANITIZER) #if defined(MEMORY_SANITIZER)
TEST_F(EndToEndTest, DISABLED_TriggerMidCallProbing) { TEST_P(EndToEndTest, DISABLED_TriggerMidCallProbing) {
// Fails on iOS bots: bugs.webrtc.org/7851 // Fails on iOS bots: bugs.webrtc.org/7851
#elif defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR #elif defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
TEST_F(EndToEndTest, DISABLED_TriggerMidCallProbing) { TEST_P(EndToEndTest, DISABLED_TriggerMidCallProbing) {
#else #else
TEST_F(EndToEndTest, TriggerMidCallProbing) { TEST_P(EndToEndTest, TriggerMidCallProbing) {
#endif #endif
class TriggerMidCallProbingTest : public ProbingTest { class TriggerMidCallProbingTest : public ProbingTest {
@ -2579,7 +2582,7 @@ TEST_F(EndToEndTest, TriggerMidCallProbing) {
<< " attempts)."; << " attempts).";
} }
TEST_F(EndToEndTest, VerifyNackStats) { TEST_P(EndToEndTest, VerifyNackStats) {
static const int kPacketNumberToDrop = 200; static const int kPacketNumberToDrop = 200;
class NackObserver : public test::EndToEndTest { class NackObserver : public test::EndToEndTest {
public: public:
@ -2928,7 +2931,7 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx,
#else #else
#define MAYBE_ContentTypeSwitches ContentTypeSwitches #define MAYBE_ContentTypeSwitches ContentTypeSwitches
#endif #endif
TEST_F(EndToEndTest, MAYBE_ContentTypeSwitches) { TEST_P(EndToEndTest, MAYBE_ContentTypeSwitches) {
class StatsObserver : public test::BaseTest, class StatsObserver : public test::BaseTest,
public rtc::VideoSinkInterface<VideoFrame> { public rtc::VideoSinkInterface<VideoFrame> {
public: public:
@ -3057,21 +3060,21 @@ TEST_F(EndToEndTest, MAYBE_ContentTypeSwitches) {
"WebRTC.Video.Screenshare.InterframeDelayMaxInMs")); "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
} }
TEST_F(EndToEndTest, VerifyHistogramStatsWithRtx) { TEST_P(EndToEndTest, VerifyHistogramStatsWithRtx) {
const bool kEnabledRtx = true; const bool kEnabledRtx = true;
const bool kEnabledRed = false; const bool kEnabledRed = false;
const bool kScreenshare = false; const bool kScreenshare = false;
VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare); VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
} }
TEST_F(EndToEndTest, VerifyHistogramStatsWithRed) { TEST_P(EndToEndTest, VerifyHistogramStatsWithRed) {
const bool kEnabledRtx = false; const bool kEnabledRtx = false;
const bool kEnabledRed = true; const bool kEnabledRed = true;
const bool kScreenshare = false; const bool kScreenshare = false;
VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare); VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
} }
TEST_F(EndToEndTest, VerifyHistogramStatsWithScreenshare) { TEST_P(EndToEndTest, VerifyHistogramStatsWithScreenshare) {
const bool kEnabledRtx = false; const bool kEnabledRtx = false;
const bool kEnabledRed = false; const bool kEnabledRed = false;
const bool kScreenshare = true; const bool kScreenshare = true;
@ -3196,7 +3199,7 @@ void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ReportsSetEncoderRates) { TEST_P(EndToEndTest, ReportsSetEncoderRates) {
class EncoderRateStatsTest : public test::EndToEndTest, class EncoderRateStatsTest : public test::EndToEndTest,
public test::FakeEncoder { public test::FakeEncoder {
public: public:
@ -3282,7 +3285,7 @@ TEST_F(EndToEndTest, ReportsSetEncoderRates) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, GetStats) { TEST_P(EndToEndTest, GetStats) {
static const int kStartBitrateBps = 3000000; static const int kStartBitrateBps = 3000000;
static const int kExpectedRenderDelayMs = 20; static const int kExpectedRenderDelayMs = 20;
@ -3628,7 +3631,7 @@ TEST_F(EndToEndTest, GetStats) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, TimingFramesAreReported) { TEST_P(EndToEndTest, TimingFramesAreReported) {
static const int kExtensionId = 5; static const int kExtensionId = 5;
class StatsObserver : public test::EndToEndTest { class StatsObserver : public test::EndToEndTest {
@ -3767,27 +3770,27 @@ class RtcpXrObserver : public test::EndToEndTest {
int sent_rtcp_dlrr_; int sent_rtcp_dlrr_;
}; };
TEST_F(EndToEndTest, TestExtendedReportsWithRrtrWithoutTargetBitrate) { TEST_P(EndToEndTest, TestExtendedReportsWithRrtrWithoutTargetBitrate) {
RtcpXrObserver test(true, false); RtcpXrObserver test(true, false);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, TestExtendedReportsWithoutRrtrWithoutTargetBitrate) { TEST_P(EndToEndTest, TestExtendedReportsWithoutRrtrWithoutTargetBitrate) {
RtcpXrObserver test(false, false); RtcpXrObserver test(false, false);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, TestExtendedReportsWithRrtrWithTargetBitrate) { TEST_P(EndToEndTest, TestExtendedReportsWithRrtrWithTargetBitrate) {
RtcpXrObserver test(true, true); RtcpXrObserver test(true, true);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, TestExtendedReportsWithoutRrtrWithTargetBitrate) { TEST_P(EndToEndTest, TestExtendedReportsWithoutRrtrWithTargetBitrate) {
RtcpXrObserver test(false, true); RtcpXrObserver test(false, true);
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, TestReceivedRtpPacketStats) { TEST_P(EndToEndTest, TestReceivedRtpPacketStats) {
static const size_t kNumRtpPacketsToSend = 5; static const size_t kNumRtpPacketsToSend = 5;
class ReceivedRtpStatsObserver : public test::EndToEndTest { class ReceivedRtpStatsObserver : public test::EndToEndTest {
public: public:
@ -3827,19 +3830,19 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, SendsSetSsrc) { TEST_P(EndToEndTest, SendsSetSsrc) {
TestSendsSetSsrcs(1, false); TestSendsSetSsrcs(1, false);
} }
TEST_F(EndToEndTest, SendsSetSimulcastSsrcs) { TEST_P(EndToEndTest, SendsSetSimulcastSsrcs) {
TestSendsSetSsrcs(kNumSsrcs, false); TestSendsSetSsrcs(kNumSsrcs, false);
} }
TEST_F(EndToEndTest, CanSwitchToUseAllSsrcs) { TEST_P(EndToEndTest, CanSwitchToUseAllSsrcs) {
TestSendsSetSsrcs(kNumSsrcs, true); TestSendsSetSsrcs(kNumSsrcs, true);
} }
TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { TEST_P(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) {
class ObserveRedundantPayloads: public test::EndToEndTest { class ObserveRedundantPayloads: public test::EndToEndTest {
public: public:
ObserveRedundantPayloads() ObserveRedundantPayloads()
@ -4193,15 +4196,15 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx,
}); });
} }
TEST_F(EndToEndTest, RestartingSendStreamPreservesRtpState) { TEST_P(EndToEndTest, RestartingSendStreamPreservesRtpState) {
TestRtpStatePreservation(false, false); TestRtpStatePreservation(false, false);
} }
TEST_F(EndToEndTest, RestartingSendStreamPreservesRtpStatesWithRtx) { TEST_P(EndToEndTest, RestartingSendStreamPreservesRtpStatesWithRtx) {
TestRtpStatePreservation(true, false); TestRtpStatePreservation(true, false);
} }
TEST_F(EndToEndTest, RestartingSendStreamKeepsRtpAndRtcpTimestampsSynced) { TEST_P(EndToEndTest, RestartingSendStreamKeepsRtpAndRtcpTimestampsSynced) {
TestRtpStatePreservation(true, true); TestRtpStatePreservation(true, true);
} }
@ -4209,12 +4212,10 @@ TEST_F(EndToEndTest, RestartingSendStreamKeepsRtpAndRtcpTimestampsSynced) {
// flakyness has been fixed. // flakyness has been fixed.
// https://bugs.chromium.org/p/webrtc/issues/detail?id=7737 // https://bugs.chromium.org/p/webrtc/issues/detail?id=7737
#if defined(WEBRTC_LINUX) #if defined(WEBRTC_LINUX)
#define MAYBE_TestFlexfecRtpStatePreservation \ TEST_P(EndToEndTest, DISABLED_TestFlexfecRtpStatePreservation) {
DISABLED_TestFlexfecRtpStatePreservation
#else #else
#define MAYBE_TestFlexfecRtpStatePreservation TestFlexfecRtpStatePreservation TEST_P(EndToEndTest, TestFlexfecRtpStatePreservation) {
#endif #endif
TEST_F(EndToEndTest, MAYBE_TestFlexfecRtpStatePreservation) {
class RtpSequenceObserver : public test::RtpRtcpObserver { class RtpSequenceObserver : public test::RtpRtcpObserver {
public: public:
RtpSequenceObserver() RtpSequenceObserver()
@ -4396,7 +4397,7 @@ TEST_F(EndToEndTest, MAYBE_TestFlexfecRtpStatePreservation) {
}); });
} }
TEST_F(EndToEndTest, RespectsNetworkState) { TEST_P(EndToEndTest, RespectsNetworkState) {
// TODO(pbos): Remove accepted downtime packets etc. when signaling network // TODO(pbos): Remove accepted downtime packets etc. when signaling network
// down blocks until no more packets will be sent. // down blocks until no more packets will be sent.
@ -4606,7 +4607,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, CallReportsRttForSender) { TEST_P(EndToEndTest, CallReportsRttForSender) {
static const int kSendDelayMs = 30; static const int kSendDelayMs = 30;
static const int kReceiveDelayMs = 70; static const int kReceiveDelayMs = 70;
@ -4716,7 +4717,7 @@ void EndToEndTest::VerifyNewVideoReceiveStreamsRespectNetworkState(
}); });
} }
TEST_F(EndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) { TEST_P(EndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) {
class UnusedEncoder : public test::FakeEncoder { class UnusedEncoder : public test::FakeEncoder {
public: public:
UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {} UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {}
@ -4742,7 +4743,7 @@ TEST_F(EndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) {
MediaType::AUDIO, &unused_encoder, &unused_transport); MediaType::AUDIO, &unused_encoder, &unused_transport);
} }
TEST_F(EndToEndTest, NewVideoSendStreamsIgnoreAudioNetworkDown) { TEST_P(EndToEndTest, NewVideoSendStreamsIgnoreAudioNetworkDown) {
class RequiredEncoder : public test::FakeEncoder { class RequiredEncoder : public test::FakeEncoder {
public: public:
RequiredEncoder() RequiredEncoder()
@ -4770,12 +4771,12 @@ TEST_F(EndToEndTest, NewVideoSendStreamsIgnoreAudioNetworkDown) {
MediaType::VIDEO, &required_encoder, &required_transport); MediaType::VIDEO, &required_encoder, &required_transport);
} }
TEST_F(EndToEndTest, NewVideoReceiveStreamsRespectVideoNetworkDown) { TEST_P(EndToEndTest, NewVideoReceiveStreamsRespectVideoNetworkDown) {
UnusedTransport transport; UnusedTransport transport;
VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport); VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport);
} }
TEST_F(EndToEndTest, NewVideoReceiveStreamsIgnoreAudioNetworkDown) { TEST_P(EndToEndTest, NewVideoReceiveStreamsIgnoreAudioNetworkDown) {
RequiredTransport transport(false /*rtp*/, true /*rtcp*/); RequiredTransport transport(false /*rtp*/, true /*rtcp*/);
VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::VIDEO, &transport); VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::VIDEO, &transport);
} }
@ -4804,7 +4805,7 @@ void VerifyEmptyFlexfecConfig(
<< "Enabling FlexFEC requires ssrc-group: FEC-FR negotiation."; << "Enabling FlexFEC requires ssrc-group: FEC-FR negotiation.";
} }
TEST_F(EndToEndTest, VerifyDefaultSendConfigParameters) { TEST_P(EndToEndTest, VerifyDefaultSendConfigParameters) {
VideoSendStream::Config default_send_config(nullptr); VideoSendStream::Config default_send_config(nullptr);
EXPECT_EQ(0, default_send_config.rtp.nack.rtp_history_ms) EXPECT_EQ(0, default_send_config.rtp.nack.rtp_history_ms)
<< "Enabling NACK require rtcp-fb: nack negotiation."; << "Enabling NACK require rtcp-fb: nack negotiation.";
@ -4818,7 +4819,7 @@ TEST_F(EndToEndTest, VerifyDefaultSendConfigParameters) {
VerifyEmptyFlexfecConfig(default_send_config.rtp.flexfec); VerifyEmptyFlexfecConfig(default_send_config.rtp.flexfec);
} }
TEST_F(EndToEndTest, VerifyDefaultVideoReceiveConfigParameters) { TEST_P(EndToEndTest, VerifyDefaultVideoReceiveConfigParameters) {
VideoReceiveStream::Config default_receive_config(nullptr); VideoReceiveStream::Config default_receive_config(nullptr);
EXPECT_EQ(RtcpMode::kCompound, default_receive_config.rtp.rtcp_mode) EXPECT_EQ(RtcpMode::kCompound, default_receive_config.rtp.rtcp_mode)
<< "Reduced-size RTCP require rtcp-rsize to be negotiated."; << "Reduced-size RTCP require rtcp-rsize to be negotiated.";
@ -4841,7 +4842,7 @@ TEST_F(EndToEndTest, VerifyDefaultVideoReceiveConfigParameters) {
<< "Enabling ULPFEC requires rtpmap: red negotiation."; << "Enabling ULPFEC requires rtpmap: red negotiation.";
} }
TEST_F(EndToEndTest, VerifyDefaultFlexfecReceiveConfigParameters) { TEST_P(EndToEndTest, VerifyDefaultFlexfecReceiveConfigParameters) {
test::NullTransport rtcp_send_transport; test::NullTransport rtcp_send_transport;
FlexfecReceiveStream::Config default_receive_config(&rtcp_send_transport); FlexfecReceiveStream::Config default_receive_config(&rtcp_send_transport);
EXPECT_EQ(-1, default_receive_config.payload_type) EXPECT_EQ(-1, default_receive_config.payload_type)
@ -4852,7 +4853,7 @@ TEST_F(EndToEndTest, VerifyDefaultFlexfecReceiveConfigParameters) {
<< "Enabling FlexFEC requires ssrc-group: FEC-FR negotiation."; << "Enabling FlexFEC requires ssrc-group: FEC-FR negotiation.";
} }
TEST_F(EndToEndTest, TransportSeqNumOnAudioAndVideo) { TEST_P(EndToEndTest, TransportSeqNumOnAudioAndVideo) {
static constexpr int kExtensionId = 8; static constexpr int kExtensionId = 8;
static constexpr size_t kMinPacketsToWaitFor = 50; static constexpr size_t kMinPacketsToWaitFor = 50;
class TransportSequenceNumberTest : public test::EndToEndTest { class TransportSequenceNumberTest : public test::EndToEndTest {
@ -4963,7 +4964,7 @@ class EndToEndLogTest : public EndToEndTest {
std::vector<std::string> paths_; std::vector<std::string> paths_;
}; };
TEST_F(EndToEndLogTest, LogsEncodedFramesWhenRequested) { TEST_P(EndToEndLogTest, LogsEncodedFramesWhenRequested) {
static const int kNumFramesToRecord = 10; static const int kNumFramesToRecord = 10;
class LogEncodingObserver : public test::EndToEndTest, class LogEncodingObserver : public test::EndToEndTest,
public EncodedFrameObserver { public EncodedFrameObserver {
@ -5025,4 +5026,9 @@ TEST_F(EndToEndLogTest, LogsEncodedFramesWhenRequested) {
RunBaseTest(&test); RunBaseTest(&test);
} }
INSTANTIATE_TEST_CASE_P(RoundRobin,
EndToEndTest,
::testing::Values("WebRTC-RoundRobinPacing/Disabled/",
"WebRTC-RoundRobinPacing/Enabled/"));
} // namespace webrtc } // namespace webrtc