Enable bitrate probing by default in PacedSender.
BUG=crbug:425925 R=mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/33359004 Cr-Commit-Position: refs/heads/master@{#8379} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8379 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
fbc347f2ef
commit
e9f0f591b5
@ -81,7 +81,7 @@ int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
|
|||||||
}
|
}
|
||||||
if (probe_bitrates_.empty()) {
|
if (probe_bitrates_.empty()) {
|
||||||
// No probe started, or waiting for next probe.
|
// No probe started, or waiting for next probe.
|
||||||
return std::numeric_limits<int>::max();
|
return -1;
|
||||||
}
|
}
|
||||||
int64_t elapsed_time_ms = now_ms - time_last_send_ms_;
|
int64_t elapsed_time_ms = now_ms - time_last_send_ms_;
|
||||||
// We will send the first probe packet immediately if no packet has been
|
// We will send the first probe packet immediately if no packet has been
|
||||||
|
@ -19,7 +19,7 @@ TEST(BitrateProberTest, VerifyStatesAndTimeBetweenProbes) {
|
|||||||
BitrateProber prober;
|
BitrateProber prober;
|
||||||
EXPECT_FALSE(prober.IsProbing());
|
EXPECT_FALSE(prober.IsProbing());
|
||||||
int64_t now_ms = 0;
|
int64_t now_ms = 0;
|
||||||
EXPECT_EQ(std::numeric_limits<int>::max(), prober.TimeUntilNextProbe(now_ms));
|
EXPECT_EQ(-1, prober.TimeUntilNextProbe(now_ms));
|
||||||
|
|
||||||
prober.SetEnabled(true);
|
prober.SetEnabled(true);
|
||||||
EXPECT_FALSE(prober.IsProbing());
|
EXPECT_FALSE(prober.IsProbing());
|
||||||
@ -45,7 +45,7 @@ TEST(BitrateProberTest, VerifyStatesAndTimeBetweenProbes) {
|
|||||||
prober.PacketSent(now_ms, 1000);
|
prober.PacketSent(now_ms, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(std::numeric_limits<int>::max(), prober.TimeUntilNextProbe(now_ms));
|
EXPECT_EQ(-1, prober.TimeUntilNextProbe(now_ms));
|
||||||
EXPECT_FALSE(prober.IsProbing());
|
EXPECT_FALSE(prober.IsProbing());
|
||||||
}
|
}
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -87,6 +87,11 @@ class PacedSender : public Module {
|
|||||||
// Resume sending packets.
|
// Resume sending packets.
|
||||||
void Resume();
|
void Resume();
|
||||||
|
|
||||||
|
// Enable bitrate probing. Enabled by default, mostly here to simplify
|
||||||
|
// testing. Must be called before any packets are being sent to have an
|
||||||
|
// effect.
|
||||||
|
void SetProbingEnabled(bool enabled);
|
||||||
|
|
||||||
// Set target bitrates for the pacer.
|
// Set target bitrates for the pacer.
|
||||||
// We will pace out bursts of packets at a bitrate of |max_bitrate_kbps|.
|
// We will pace out bursts of packets at a bitrate of |max_bitrate_kbps|.
|
||||||
// |bitrate_kbps| is our estimate of what we are allowed to send on average.
|
// |bitrate_kbps| is our estimate of what we are allowed to send on average.
|
||||||
@ -121,9 +126,6 @@ class PacedSender : public Module {
|
|||||||
// Process any pending packets in the queue(s).
|
// Process any pending packets in the queue(s).
|
||||||
virtual int32_t Process() OVERRIDE;
|
virtual int32_t Process() OVERRIDE;
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool ProbingExperimentIsEnabled() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Updates the number of bytes that can be sent for the next time interval.
|
// Updates the number of bytes that can be sent for the next time interval.
|
||||||
void UpdateBytesPerInterval(int64_t delta_time_in_ms)
|
void UpdateBytesPerInterval(int64_t delta_time_in_ms)
|
||||||
@ -139,6 +141,7 @@ class PacedSender : public Module {
|
|||||||
scoped_ptr<CriticalSectionWrapper> critsect_;
|
scoped_ptr<CriticalSectionWrapper> critsect_;
|
||||||
bool enabled_ GUARDED_BY(critsect_);
|
bool enabled_ GUARDED_BY(critsect_);
|
||||||
bool paused_ GUARDED_BY(critsect_);
|
bool paused_ GUARDED_BY(critsect_);
|
||||||
|
bool probing_enabled_;
|
||||||
// This is the media budget, keeping track of how many bits of media
|
// This is the media budget, keeping track of how many bits of media
|
||||||
// we can pace out during the current interval.
|
// we can pace out during the current interval.
|
||||||
scoped_ptr<paced_sender::IntervalBudget> media_budget_ GUARDED_BY(critsect_);
|
scoped_ptr<paced_sender::IntervalBudget> media_budget_ GUARDED_BY(critsect_);
|
||||||
@ -154,7 +157,7 @@ class PacedSender : public Module {
|
|||||||
int64_t time_last_update_us_ GUARDED_BY(critsect_);
|
int64_t time_last_update_us_ GUARDED_BY(critsect_);
|
||||||
|
|
||||||
scoped_ptr<paced_sender::PacketQueue> packets_ GUARDED_BY(critsect_);
|
scoped_ptr<paced_sender::PacketQueue> packets_ GUARDED_BY(critsect_);
|
||||||
uint64_t packet_counter_ GUARDED_BY(critsect_);
|
uint64_t packet_counter_;
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
#endif // WEBRTC_MODULES_PACING_INCLUDE_PACED_SENDER_H_
|
#endif // WEBRTC_MODULES_PACING_INCLUDE_PACED_SENDER_H_
|
||||||
|
@ -90,9 +90,9 @@ class PacketQueue {
|
|||||||
virtual ~PacketQueue() {}
|
virtual ~PacketQueue() {}
|
||||||
|
|
||||||
void Push(const Packet& packet) {
|
void Push(const Packet& packet) {
|
||||||
if (!AddToDupeSet(packet))
|
if (!AddToDupeSet(packet)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// Store packet in list, use pointers in priority queue for cheaper moves.
|
// Store packet in list, use pointers in priority queue for cheaper moves.
|
||||||
// Packets have a handle to its own iterator in the list, for easy removal
|
// Packets have a handle to its own iterator in the list, for easy removal
|
||||||
// when popping from queue.
|
// when popping from queue.
|
||||||
@ -215,6 +215,7 @@ PacedSender::PacedSender(Clock* clock,
|
|||||||
critsect_(CriticalSectionWrapper::CreateCriticalSection()),
|
critsect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
enabled_(true),
|
enabled_(true),
|
||||||
paused_(false),
|
paused_(false),
|
||||||
|
probing_enabled_(true),
|
||||||
media_budget_(new paced_sender::IntervalBudget(max_bitrate_kbps)),
|
media_budget_(new paced_sender::IntervalBudget(max_bitrate_kbps)),
|
||||||
padding_budget_(new paced_sender::IntervalBudget(min_bitrate_kbps)),
|
padding_budget_(new paced_sender::IntervalBudget(min_bitrate_kbps)),
|
||||||
prober_(new BitrateProber()),
|
prober_(new BitrateProber()),
|
||||||
@ -237,6 +238,11 @@ void PacedSender::Resume() {
|
|||||||
paused_ = false;
|
paused_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PacedSender::SetProbingEnabled(bool enabled) {
|
||||||
|
assert(packet_counter_ == 0);
|
||||||
|
probing_enabled_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void PacedSender::SetStatus(bool enable) {
|
void PacedSender::SetStatus(bool enable) {
|
||||||
CriticalSectionScoped cs(critsect_.get());
|
CriticalSectionScoped cs(critsect_.get());
|
||||||
enabled_ = enable;
|
enabled_ = enable;
|
||||||
@ -264,8 +270,7 @@ bool PacedSender::SendPacket(Priority priority, uint32_t ssrc,
|
|||||||
if (!enabled_) {
|
if (!enabled_) {
|
||||||
return true; // We can send now.
|
return true; // We can send now.
|
||||||
}
|
}
|
||||||
// Enable probing if the probing experiment is enabled.
|
if (probing_enabled_ && !prober_->IsProbing()) {
|
||||||
if (!prober_->IsProbing() && ProbingExperimentIsEnabled()) {
|
|
||||||
prober_->SetEnabled(true);
|
prober_->SetEnabled(true);
|
||||||
}
|
}
|
||||||
prober_->MaybeInitializeProbe(bitrate_bps_);
|
prober_->MaybeInitializeProbe(bitrate_bps_);
|
||||||
@ -305,7 +310,10 @@ int64_t PacedSender::QueueInMs() const {
|
|||||||
int64_t PacedSender::TimeUntilNextProcess() {
|
int64_t PacedSender::TimeUntilNextProcess() {
|
||||||
CriticalSectionScoped cs(critsect_.get());
|
CriticalSectionScoped cs(critsect_.get());
|
||||||
if (prober_->IsProbing()) {
|
if (prober_->IsProbing()) {
|
||||||
return prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds());
|
int64_t ret = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds());
|
||||||
|
if (ret >= 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_;
|
int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_;
|
||||||
int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000;
|
int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000;
|
||||||
@ -325,10 +333,10 @@ int32_t PacedSender::Process() {
|
|||||||
int64_t delta_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms);
|
int64_t delta_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms);
|
||||||
UpdateBytesPerInterval(delta_time_ms);
|
UpdateBytesPerInterval(delta_time_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!packets_->Empty()) {
|
while (!packets_->Empty()) {
|
||||||
if (media_budget_->bytes_remaining() <= 0 && !prober_->IsProbing())
|
if (media_budget_->bytes_remaining() <= 0 && !prober_->IsProbing()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Since we need to release the lock in order to send, we first pop the
|
// Since we need to release the lock in order to send, we first pop the
|
||||||
// element from the priority queue but keep it in storage, so that we can
|
// element from the priority queue but keep it in storage, so that we can
|
||||||
@ -337,8 +345,9 @@ int32_t PacedSender::Process() {
|
|||||||
if (SendPacket(packet)) {
|
if (SendPacket(packet)) {
|
||||||
// Send succeeded, remove it from the queue.
|
// Send succeeded, remove it from the queue.
|
||||||
packets_->FinalizePop(packet);
|
packets_->FinalizePop(packet);
|
||||||
if (prober_->IsProbing())
|
if (prober_->IsProbing()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Send failed, put it back into the queue.
|
// Send failed, put it back into the queue.
|
||||||
packets_->CancelPop(packet);
|
packets_->CancelPop(packet);
|
||||||
@ -386,9 +395,4 @@ void PacedSender::UpdateBytesPerInterval(int64_t delta_time_ms) {
|
|||||||
media_budget_->IncreaseBudget(delta_time_ms);
|
media_budget_->IncreaseBudget(delta_time_ms);
|
||||||
padding_budget_->IncreaseBudget(delta_time_ms);
|
padding_budget_->IncreaseBudget(delta_time_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PacedSender::ProbingExperimentIsEnabled() const {
|
|
||||||
return webrtc::field_trial::FindFullName("WebRTC-BitrateProbing") ==
|
|
||||||
"Enabled";
|
|
||||||
}
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -108,6 +108,10 @@ class PacedSenderTest : public ::testing::Test {
|
|||||||
kTargetBitrate,
|
kTargetBitrate,
|
||||||
kPaceMultiplier * kTargetBitrate,
|
kPaceMultiplier * kTargetBitrate,
|
||||||
0));
|
0));
|
||||||
|
// Default to bitrate probing disabled for testing purposes. Probing tests
|
||||||
|
// have to enable probing, either by creating a new PacedSender instance or
|
||||||
|
// by calling SetProbingEnabled(true).
|
||||||
|
send_bucket_->SetProbingEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendAndExpectPacket(PacedSender::Priority priority,
|
void SendAndExpectPacket(PacedSender::Priority priority,
|
||||||
@ -418,6 +422,7 @@ TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
|
|||||||
PacedSenderPadding callback;
|
PacedSenderPadding callback;
|
||||||
send_bucket_.reset(new PacedSender(
|
send_bucket_.reset(new PacedSender(
|
||||||
&clock_, &callback, kTargetBitrate, kPaceMultiplier * kTargetBitrate, 0));
|
&clock_, &callback, kTargetBitrate, kPaceMultiplier * kTargetBitrate, 0));
|
||||||
|
send_bucket_->SetProbingEnabled(false);
|
||||||
send_bucket_->UpdateBitrate(
|
send_bucket_->UpdateBitrate(
|
||||||
kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
|
kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
|
||||||
int64_t start_time = clock_.TimeInMilliseconds();
|
int64_t start_time = clock_.TimeInMilliseconds();
|
||||||
@ -697,22 +702,6 @@ TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
|
|||||||
EXPECT_EQ(0, send_bucket_->QueueInMs());
|
EXPECT_EQ(0, send_bucket_->QueueInMs());
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProbingPacedSender : public PacedSender {
|
|
||||||
public:
|
|
||||||
ProbingPacedSender(Clock* clock,
|
|
||||||
Callback* callback,
|
|
||||||
int bitrate_kbps,
|
|
||||||
int max_bitrate_kbps,
|
|
||||||
int min_bitrate_kbps)
|
|
||||||
: PacedSender(clock,
|
|
||||||
callback,
|
|
||||||
bitrate_kbps,
|
|
||||||
max_bitrate_kbps,
|
|
||||||
min_bitrate_kbps) {}
|
|
||||||
|
|
||||||
virtual bool ProbingExperimentIsEnabled() const OVERRIDE { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(PacedSenderTest, ProbingWithInitialFrame) {
|
TEST_F(PacedSenderTest, ProbingWithInitialFrame) {
|
||||||
const int kNumPackets = 11;
|
const int kNumPackets = 11;
|
||||||
const int kNumDeltas = kNumPackets - 1;
|
const int kNumDeltas = kNumPackets - 1;
|
||||||
@ -725,12 +714,15 @@ TEST_F(PacedSenderTest, ProbingWithInitialFrame) {
|
|||||||
std::list<int> expected_deltas_list(expected_deltas,
|
std::list<int> expected_deltas_list(expected_deltas,
|
||||||
expected_deltas + kNumPackets - 1);
|
expected_deltas + kNumPackets - 1);
|
||||||
PacedSenderProbing callback(expected_deltas_list, &clock_);
|
PacedSenderProbing callback(expected_deltas_list, &clock_);
|
||||||
|
// Probing implicitly enabled by creating a new PacedSender which defaults to
|
||||||
|
// probing on.
|
||||||
send_bucket_.reset(
|
send_bucket_.reset(
|
||||||
new ProbingPacedSender(&clock_,
|
new PacedSender(&clock_,
|
||||||
&callback,
|
&callback,
|
||||||
kInitialBitrateKbps,
|
kInitialBitrateKbps,
|
||||||
kPaceMultiplier * kInitialBitrateKbps,
|
kPaceMultiplier * kInitialBitrateKbps,
|
||||||
0));
|
0));
|
||||||
|
|
||||||
for (int i = 0; i < kNumPackets; ++i) {
|
for (int i = 0; i < kNumPackets; ++i) {
|
||||||
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
|
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
|
||||||
ssrc,
|
ssrc,
|
||||||
|
@ -85,27 +85,11 @@ class PacedVideoSender : public PacketSender, public PacedSender::Callback {
|
|||||||
int64_t rtt) OVERRIDE;
|
int64_t rtt) OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ProbingPacedSender : public PacedSender {
|
|
||||||
public:
|
|
||||||
ProbingPacedSender(Clock* clock,
|
|
||||||
Callback* callback,
|
|
||||||
int bitrate_kbps,
|
|
||||||
int max_bitrate_kbps,
|
|
||||||
int min_bitrate_kbps)
|
|
||||||
: PacedSender(clock,
|
|
||||||
callback,
|
|
||||||
bitrate_kbps,
|
|
||||||
max_bitrate_kbps,
|
|
||||||
min_bitrate_kbps) {}
|
|
||||||
|
|
||||||
virtual bool ProbingExperimentIsEnabled() const OVERRIDE { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
int64_t TimeUntilNextProcess(const std::list<Module*>& modules);
|
int64_t TimeUntilNextProcess(const std::list<Module*>& modules);
|
||||||
void CallProcess(const std::list<Module*>& modules);
|
void CallProcess(const std::list<Module*>& modules);
|
||||||
void QueuePackets(Packets* batch, int64_t end_of_batch_time_us);
|
void QueuePackets(Packets* batch, int64_t end_of_batch_time_us);
|
||||||
|
|
||||||
ProbingPacedSender pacer_;
|
PacedSender pacer_;
|
||||||
Packets queue_;
|
Packets queue_;
|
||||||
Packets pacer_queue_;
|
Packets pacer_queue_;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user