Revert of Add functionality which limits the number of bytes on the network. (patchset #26 id:500001 of https://codereview.webrtc.org/2918323002/ )

Reason for revert:
Speculative revert to see if this caused regressions in android perf tests.

Original issue's description:
> Add functionality which limits the number of bytes on the network.
>
> The limit is based on the bandwidth delay product, but also adds some additional slack to compensate for the sawtooth-like BWE pattern and the slowness of the encoder rate control. The delay is estimated based on the time from sending a packet until an ack is received. Since acks are received in bursts (feedback is only sent periodically), a min filter is used to estimate the rtt.
>
> Whenever the in flight bytes reaches the congestion window, the pacer is paused, which in turn will result in send-side queues growing. Eventually the encoders will be paused as the pacer queue grows large (currently 2 seconds).
>
> BUG=webrtc:7926
>
> Review-Url: https://codereview.webrtc.org/2918323002
> Cr-Commit-Position: refs/heads/master@{#19289}
> Committed: 8497fdde43

TBR=terelius@webrtc.org,philipel@webrtc.org,tschumim@webrtc.org,gnish@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7926

Review-Url: https://codereview.webrtc.org/3001653002
Cr-Commit-Position: refs/heads/master@{#19339}
This commit is contained in:
stefan
2017-08-14 08:03:17 -07:00
committed by Commit Bot
parent 5d6891000f
commit 64136af364
10 changed files with 38 additions and 269 deletions

View File

@ -435,20 +435,17 @@ Call::Call(const Call::Config& config,
call_stats_->RegisterStatsObserver(&receive_side_cc_);
call_stats_->RegisterStatsObserver(transport_send_->send_side_cc());
// We have to attach the pacer to the pacer thread before starting the
// module process thread to avoid a race accessing the process thread
// both from the process thread and the pacer thread.
pacer_thread_->RegisterModule(transport_send_->send_side_cc()->pacer(),
RTC_FROM_HERE);
pacer_thread_->RegisterModule(
receive_side_cc_.GetRemoteBitrateEstimator(true), RTC_FROM_HERE);
pacer_thread_->Start();
module_process_thread_->Start();
module_process_thread_->RegisterModule(call_stats_.get(), RTC_FROM_HERE);
module_process_thread_->RegisterModule(&receive_side_cc_, RTC_FROM_HERE);
module_process_thread_->RegisterModule(transport_send_->send_side_cc(),
RTC_FROM_HERE);
module_process_thread_->Start();
pacer_thread_->RegisterModule(transport_send_->send_side_cc()->pacer(),
RTC_FROM_HERE);
pacer_thread_->RegisterModule(
receive_side_cc_.GetRemoteBitrateEstimator(true), RTC_FROM_HERE);
pacer_thread_->Start();
}
Call::~Call() {
@ -460,15 +457,11 @@ Call::~Call() {
RTC_CHECK(audio_receive_streams_.empty());
RTC_CHECK(video_receive_streams_.empty());
// The send-side congestion controller must be de-registered prior to
// the pacer thread being stopped to avoid a race when accessing the
// pacer thread object on the module process thread at the same time as
// the pacer thread is stopped.
module_process_thread_->DeRegisterModule(transport_send_->send_side_cc());
pacer_thread_->Stop();
pacer_thread_->DeRegisterModule(transport_send_->send_side_cc()->pacer());
pacer_thread_->DeRegisterModule(
receive_side_cc_.GetRemoteBitrateEstimator(true));
module_process_thread_->DeRegisterModule(transport_send_->send_side_cc());
module_process_thread_->DeRegisterModule(&receive_side_cc_);
module_process_thread_->DeRegisterModule(call_stats_.get());
module_process_thread_->Stop();

View File

@ -136,7 +136,6 @@ class SendSideCongestionController : public CallStatsObserver,
bool HasNetworkParametersToReportChanged(uint32_t bitrate_bps,
uint8_t fraction_loss,
int64_t rtt);
void LimitOutstandingBytes(size_t num_outstanding_bytes);
const Clock* const clock_;
rtc::CriticalSection observer_lock_;
Observer* observer_ GUARDED_BY(observer_lock_);
@ -152,15 +151,9 @@ class SendSideCongestionController : public CallStatsObserver,
uint8_t last_reported_fraction_loss_ GUARDED_BY(network_state_lock_);
int64_t last_reported_rtt_ GUARDED_BY(network_state_lock_);
NetworkState network_state_ GUARDED_BY(network_state_lock_);
bool pause_pacer_ GUARDED_BY(network_state_lock_);
// Duplicate the pacer paused state to avoid grabbing a lock when
// pausing the pacer. This can be removed when we move this class
// over to the task queue.
bool pacer_paused_;
rtc::CriticalSection bwe_lock_;
int min_bitrate_bps_ GUARDED_BY(bwe_lock_);
std::unique_ptr<DelayBasedBwe> delay_based_bwe_ GUARDED_BY(bwe_lock_);
const bool in_cwnd_experiment_;
bool was_in_alr_;
rtc::RaceChecker worker_race_;

View File

@ -25,20 +25,10 @@
#include "webrtc/rtc_base/rate_limiter.h"
#include "webrtc/rtc_base/socket.h"
#include "webrtc/rtc_base/timeutils.h"
#include "webrtc/system_wrappers/include/field_trial.h"
namespace webrtc {
namespace {
const char kCwndExperiment[] = "WebRTC-CwndExperiment";
bool CwndExperimentEnabled() {
std::string experiment_string =
webrtc::field_trial::FindFullName(kCwndExperiment);
// The experiment is enabled iff the field trial string begins with "Enabled".
return experiment_string.find("Enabled") == 0;
}
static const int64_t kRetransmitWindowSizeMs = 500;
// Makes sure that the bitrate and the min, max values are in valid range.
@ -110,11 +100,8 @@ SendSideCongestionController::SendSideCongestionController(
last_reported_fraction_loss_(0),
last_reported_rtt_(0),
network_state_(kNetworkUp),
pause_pacer_(false),
pacer_paused_(false),
min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)),
in_cwnd_experiment_(CwndExperimentEnabled()),
was_in_alr_(0) {
delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
}
@ -232,9 +219,13 @@ SendSideCongestionController::GetTransportFeedbackObserver() {
void SendSideCongestionController::SignalNetworkState(NetworkState state) {
LOG(LS_INFO) << "SignalNetworkState "
<< (state == kNetworkUp ? "Up" : "Down");
if (state == kNetworkUp) {
pacer_->Resume();
} else {
pacer_->Pause();
}
{
rtc::CritScope cs(&network_state_lock_);
pause_pacer_ = state == kNetworkDown;
network_state_ = state;
}
probe_controller_->OnNetworkStateChanged(state);
@ -255,7 +246,6 @@ void SendSideCongestionController::OnSentPacket(
return;
transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id,
sent_packet.send_time_ms);
LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
}
void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
@ -269,20 +259,6 @@ int64_t SendSideCongestionController::TimeUntilNextProcess() {
}
void SendSideCongestionController::Process() {
bool pause_pacer;
// TODO(holmer): Once this class is running on a task queue we should
// replace this with a task instead.
{
rtc::CritScope lock(&network_state_lock_);
pause_pacer = pause_pacer_;
}
if (pause_pacer && !pacer_paused_) {
pacer_->Pause();
pacer_paused_ = true;
} else if (!pause_pacer && pacer_paused_) {
pacer_->Resume();
pacer_paused_ = false;
}
bitrate_controller_->Process();
probe_controller_->Process();
MaybeTriggerOnNetworkChanged();
@ -329,35 +305,6 @@ void SendSideCongestionController::OnTransportFeedback(
}
if (result.recovered_from_overuse)
probe_controller_->RequestProbe();
LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
}
void SendSideCongestionController::LimitOutstandingBytes(
size_t num_outstanding_bytes) {
if (!in_cwnd_experiment_)
return;
{
rtc::CritScope lock(&network_state_lock_);
rtc::Optional<int64_t> min_rtt_ms =
transport_feedback_adapter_.GetMinFeedbackLoopRtt();
// No valid RTT. Could be because send-side BWE isn't used, in which case
// we don't try to limit the outstanding packets.
if (!min_rtt_ms)
return;
const int64_t kAcceptedQueueMs = 250;
const size_t kMinCwndBytes = 2 * 1500;
size_t max_outstanding_bytes =
std::max<size_t>((*min_rtt_ms + kAcceptedQueueMs) *
last_reported_bitrate_bps_ / 1000 / 8,
kMinCwndBytes);
LOG(LS_INFO) << clock_->TimeInMilliseconds()
<< " Outstanding bytes: " << num_outstanding_bytes
<< " pacer queue: " << pacer_->QueueInMs()
<< " max outstanding: " << max_outstanding_bytes;
LOG(LS_INFO) << "Feedback rtt: " << *min_rtt_ms
<< " Bitrate: " << last_reported_bitrate_bps_;
pause_pacer_ = num_outstanding_bytes > max_outstanding_bytes;
}
}
std::vector<PacketFeedback>

View File

@ -10,8 +10,6 @@
#include "webrtc/modules/congestion_controller/transport_feedback_adapter.h"
#include <algorithm>
#include "webrtc/modules/congestion_controller/delay_based_bwe.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "webrtc/rtc_base/checks.h"
@ -105,12 +103,11 @@ void TransportFeedbackAdapter::SetNetworkIds(uint16_t local_id,
std::vector<PacketFeedback> TransportFeedbackAdapter::GetPacketFeedbackVector(
const rtcp::TransportFeedback& feedback) {
int64_t timestamp_us = feedback.GetBaseTimeUs();
int64_t now_ms = clock_->TimeInMilliseconds();
// Add timestamp deltas to a local time base selected on first packet arrival.
// This won't be the true time base, but makes it easier to manually inspect
// time stamps.
if (last_timestamp_us_ == kNoTimestamp) {
current_offset_ms_ = now_ms;
current_offset_ms_ = clock_->TimeInMilliseconds();
} else {
int64_t delta = timestamp_us - last_timestamp_us_;
@ -131,7 +128,7 @@ std::vector<PacketFeedback> TransportFeedbackAdapter::GetPacketFeedbackVector(
return packet_feedback_vector;
}
packet_feedback_vector.reserve(feedback.GetPacketStatusCount());
int64_t feedback_rtt = -1;
{
rtc::CritScope cs(&lock_);
size_t failed_lookups = 0;
@ -161,12 +158,6 @@ std::vector<PacketFeedback> TransportFeedbackAdapter::GetPacketFeedbackVector(
++failed_lookups;
if (packet_feedback.local_net_id == local_net_id_ &&
packet_feedback.remote_net_id == remote_net_id_) {
if (packet_feedback.send_time_ms >= 0) {
int64_t rtt = now_ms - packet_feedback.send_time_ms;
// max() is used to account for feedback being delayed by the
// receiver.
feedback_rtt = std::max(rtt, feedback_rtt);
}
packet_feedback_vector.push_back(packet_feedback);
}
@ -178,14 +169,6 @@ std::vector<PacketFeedback> TransportFeedbackAdapter::GetPacketFeedbackVector(
<< " packet" << (failed_lookups > 1 ? "s" : "")
<< ". Send time history too small?";
}
if (feedback_rtt > -1) {
feedback_rtts_.push_back(feedback_rtt);
const size_t kFeedbackRttWindow = 32;
if (feedback_rtts_.size() > kFeedbackRttWindow)
feedback_rtts_.pop_front();
min_feedback_rtt_.emplace(
*std::min_element(feedback_rtts_.begin(), feedback_rtts_.end()));
}
}
return packet_feedback_vector;
}
@ -205,14 +188,4 @@ std::vector<PacketFeedback>
TransportFeedbackAdapter::GetTransportFeedbackVector() const {
return last_packet_feedback_vector_;
}
rtc::Optional<int64_t> TransportFeedbackAdapter::GetMinFeedbackLoopRtt() const {
rtc::CritScope cs(&lock_);
return min_feedback_rtt_;
}
size_t TransportFeedbackAdapter::GetOutstandingBytes() const {
rtc::CritScope cs(&lock_);
return send_time_history_.GetOutstandingBytes(local_net_id_, remote_net_id_);
}
} // namespace webrtc

View File

@ -11,7 +11,6 @@
#ifndef WEBRTC_MODULES_CONGESTION_CONTROLLER_TRANSPORT_FEEDBACK_ADAPTER_H_
#define WEBRTC_MODULES_CONGESTION_CONTROLLER_TRANSPORT_FEEDBACK_ADAPTER_H_
#include <deque>
#include <vector>
#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
@ -47,14 +46,11 @@ class TransportFeedbackAdapter {
// to the CongestionController interface.
void OnTransportFeedback(const rtcp::TransportFeedback& feedback);
std::vector<PacketFeedback> GetTransportFeedbackVector() const;
rtc::Optional<int64_t> GetMinFeedbackLoopRtt() const;
void SetTransportOverhead(int transport_overhead_bytes_per_packet);
void SetNetworkIds(uint16_t local_id, uint16_t remote_id);
size_t GetOutstandingBytes() const;
private:
std::vector<PacketFeedback> GetPacketFeedbackVector(
const rtcp::TransportFeedback& feedback);
@ -69,8 +65,6 @@ class TransportFeedbackAdapter {
std::vector<PacketFeedback> last_packet_feedback_vector_;
uint16_t local_net_id_ GUARDED_BY(&lock_);
uint16_t remote_net_id_ GUARDED_BY(&lock_);
std::deque<int64_t> feedback_rtts_ GUARDED_BY(&lock_);
rtc::Optional<int64_t> min_feedback_rtt_ GUARDED_BY(&lock_);
rtc::CriticalSection observers_lock_;
std::vector<PacketFeedbackObserver*> observers_ GUARDED_BY(&observers_lock_);

View File

@ -29,7 +29,6 @@
namespace {
// Time limit in milliseconds between packet bursts.
const int64_t kMinPacketLimitMs = 5;
const int64_t kPausedPacketIntervalMs = 500;
// Upper cap on process interval, in case process has not been called in a long
// time.
@ -240,10 +239,9 @@ void PacedSender::CreateProbeCluster(int bitrate_bps) {
}
void PacedSender::Pause() {
LOG(LS_INFO) << "PacedSender paused.";
{
rtc::CritScope cs(&critsect_);
if (!paused_)
LOG(LS_INFO) << "PacedSender paused.";
paused_ = true;
}
// Tell the process thread to call our TimeUntilNextProcess() method to get
@ -253,10 +251,9 @@ void PacedSender::Pause() {
}
void PacedSender::Resume() {
LOG(LS_INFO) << "PacedSender resumed.";
{
rtc::CritScope cs(&critsect_);
if (paused_)
LOG(LS_INFO) << "PacedSender resumed.";
paused_ = false;
}
// Tell the process thread to call our TimeUntilNextProcess() method to
@ -358,18 +355,16 @@ int64_t PacedSender::AverageQueueTimeMs() {
int64_t PacedSender::TimeUntilNextProcess() {
rtc::CritScope cs(&critsect_);
int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_;
int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000;
// When paused we wake up every 500 ms to send a padding packet to ensure
// we won't get stuck in the paused state due to no feedback being received.
if (paused_)
return std::max<int64_t>(kPausedPacketIntervalMs - elapsed_time_ms, 0);
return 1000 * 60 * 60;
if (prober_->IsProbing()) {
int64_t ret = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds());
if (ret > 0 || (ret == 0 && !probing_send_failure_))
return ret;
}
int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_;
int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000;
return std::max<int64_t>(kMinPacketLimitMs - elapsed_time_ms, 0);
}
@ -377,21 +372,9 @@ void PacedSender::Process() {
int64_t now_us = clock_->TimeInMicroseconds();
rtc::CritScope cs(&critsect_);
int64_t elapsed_time_ms = (now_us - time_last_update_us_ + 500) / 1000;
time_last_update_us_ = now_us;
int target_bitrate_kbps = pacing_bitrate_kbps_;
if (paused_) {
PacedPacketInfo pacing_info;
time_last_update_us_ = now_us;
// We can not send padding unless a normal packet has first been sent. If we
// do, timestamps get messed up.
if (packet_counter_ == 0)
return;
size_t bytes_sent = SendPadding(1, pacing_info);
alr_detector_->OnBytesSent(bytes_sent, now_us / 1000);
return;
}
if (elapsed_time_ms > 0) {
if (!paused_ && elapsed_time_ms > 0) {
size_t queue_size_bytes = packets_->SizeInBytes();
if (queue_size_bytes > 0) {
// Assuming equal size packets and input/output rate, the average packet
@ -412,8 +395,6 @@ void PacedSender::Process() {
UpdateBudgetWithElapsedTime(elapsed_time_ms);
}
time_last_update_us_ = now_us;
bool is_probing = prober_->IsProbing();
PacedPacketInfo pacing_info;
size_t bytes_sent = 0;
@ -443,13 +424,14 @@ void PacedSender::Process() {
}
}
if (packets_->Empty()) {
if (packets_->Empty() && !paused_) {
// We can not send padding unless a normal packet has first been sent. If we
// do, timestamps get messed up.
if (packet_counter_ > 0) {
int padding_needed =
static_cast<int>(is_probing ? (recommended_probe_size - bytes_sent)
: padding_budget_->bytes_remaining());
if (padding_needed > 0)
bytes_sent += SendPadding(padding_needed, pacing_info);
}
@ -469,7 +451,8 @@ void PacedSender::ProcessThreadAttached(ProcessThread* process_thread) {
bool PacedSender::SendPacket(const paced_sender::Packet& packet,
const PacedPacketInfo& pacing_info) {
RTC_DCHECK(!paused_);
if (paused_)
return false;
if (media_budget_->bytes_remaining() == 0 &&
pacing_info.probe_cluster_id == PacedPacketInfo::kNotAProbe) {
return false;
@ -499,7 +482,6 @@ bool PacedSender::SendPacket(const paced_sender::Packet& packet,
size_t PacedSender::SendPadding(size_t padding_needed,
const PacedPacketInfo& pacing_info) {
RTC_DCHECK_GT(packet_counter_, 0);
critsect_.Leave();
size_t bytes_sent =
packet_sender_->TimeToSendPadding(padding_needed, pacing_info);

View File

@ -651,20 +651,12 @@ TEST_F(PacedSenderTest, Pause) {
EXPECT_EQ(second_capture_time_ms - capture_time_ms,
send_bucket_->QueueInMs());
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
EXPECT_CALL(callback_, TimeToSendPadding(1, _)).Times(1);
send_bucket_->Process();
int64_t expected_time_until_send = 500;
EXPECT_CALL(callback_, TimeToSendPadding(1, _)).Times(1);
while (expected_time_until_send >= 0) {
for (int i = 0; i < 10; ++i) {
clock_.AdvanceTimeMilliseconds(5);
// TimeUntilNextProcess must not return 0 when paused. If it does,
// we risk running a busy loop, so ideally it should return a large value.
EXPECT_EQ(expected_time_until_send, send_bucket_->TimeUntilNextProcess());
if (expected_time_until_send == 0)
send_bucket_->Process();
clock_.AdvanceTimeMilliseconds(5);
expected_time_until_send -= 5;
EXPECT_GE(send_bucket_->TimeUntilNextProcess(), 1000);
send_bucket_->Process();
}
// Expect high prio packets to come out first followed by normal
@ -707,10 +699,10 @@ TEST_F(PacedSenderTest, Pause) {
send_bucket_->Resume();
for (size_t i = 0; i < 4; i++) {
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
send_bucket_->Process();
EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
clock_.AdvanceTimeMilliseconds(5);
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
send_bucket_->Process();
}
EXPECT_EQ(0, send_bucket_->QueueInMs());

View File

@ -38,15 +38,11 @@ class SendTimeHistory {
// thus be non-null and have the sequence_number field set.
bool GetFeedback(PacketFeedback* packet_feedback, bool remove);
size_t GetOutstandingBytes(uint16_t local_net_id,
uint16_t remote_net_id) const;
private:
const Clock* const clock_;
const int64_t packet_age_limit_ms_;
SequenceNumberUnwrapper seq_num_unwrapper_;
std::map<int64_t, PacketFeedback> history_;
rtc::Optional<int64_t> latest_acked_seq_num_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SendTimeHistory);
};

View File

@ -52,9 +52,6 @@ bool SendTimeHistory::GetFeedback(PacketFeedback* packet_feedback,
RTC_DCHECK(packet_feedback);
int64_t unwrapped_seq_num =
seq_num_unwrapper_.Unwrap(packet_feedback->sequence_number);
latest_acked_seq_num_.emplace(
std::max(unwrapped_seq_num, latest_acked_seq_num_.value_or(0)));
RTC_DCHECK_GE(*latest_acked_seq_num_, 0);
auto it = history_.find(unwrapped_seq_num);
if (it == history_.end())
return false;
@ -69,21 +66,4 @@ bool SendTimeHistory::GetFeedback(PacketFeedback* packet_feedback,
return true;
}
size_t SendTimeHistory::GetOutstandingBytes(uint16_t local_net_id,
uint16_t remote_net_id) const {
size_t outstanding_bytes = 0;
auto unacked_it = history_.begin();
if (latest_acked_seq_num_) {
unacked_it = history_.lower_bound(*latest_acked_seq_num_);
}
for (; unacked_it != history_.end(); ++unacked_it) {
if (unacked_it->second.local_net_id == local_net_id &&
unacked_it->second.remote_net_id == remote_net_id &&
unacked_it->second.send_time_ms >= 0) {
outstanding_bytes += unacked_it->second.payload_size;
}
}
return outstanding_bytes;
}
} // namespace webrtc

View File

@ -1831,9 +1831,9 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
class TransportFeedbackTester : public test::EndToEndTest {
public:
TransportFeedbackTester(bool feedback_enabled,
size_t num_video_streams,
size_t num_audio_streams)
explicit TransportFeedbackTester(bool feedback_enabled,
size_t num_video_streams,
size_t num_audio_streams)
: EndToEndTest(::webrtc::EndToEndTest::kDefaultTimeoutMs),
feedback_enabled_(feedback_enabled),
num_video_streams_(num_video_streams),
@ -1928,80 +1928,6 @@ TEST_F(EndToEndTest, AudioVideoReceivesTransportFeedback) {
RunBaseTest(&test);
}
TEST_F(EndToEndTest, StopsSendingMediaWithoutFeedback) {
test::ScopedFieldTrials override_field_trials(
"WebRTC-CwndExperiment/Enabled/");
class TransportFeedbackTester : public test::EndToEndTest {
public:
TransportFeedbackTester(size_t num_video_streams, size_t num_audio_streams)
: EndToEndTest(::webrtc::EndToEndTest::kDefaultTimeoutMs),
num_video_streams_(num_video_streams),
num_audio_streams_(num_audio_streams),
media_sent_(0),
padding_sent_(0) {
// Only one stream of each supported for now.
EXPECT_LE(num_video_streams, 1u);
EXPECT_LE(num_audio_streams, 1u);
}
protected:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
const bool only_padding =
header.headerLength + header.paddingLength == length;
rtc::CritScope lock(&crit_);
if (only_padding) {
++padding_sent_;
} else {
++media_sent_;
EXPECT_LT(media_sent_, 40) << "Media sent without feedback.";
}
return SEND_PACKET;
}
Action OnReceiveRtcp(const uint8_t* data, size_t length) override {
rtc::CritScope lock(&crit_);
if (media_sent_ > 20 && HasTransportFeedback(data, length)) {
return DROP_PACKET;
}
return SEND_PACKET;
}
bool HasTransportFeedback(const uint8_t* data, size_t length) const {
test::RtcpPacketParser parser;
EXPECT_TRUE(parser.Parse(data, length));
return parser.transport_feedback()->num_packets() > 0;
}
Call::Config GetSenderCallConfig() override {
Call::Config config = EndToEndTest::GetSenderCallConfig();
config.bitrate_config.max_bitrate_bps = 300000;
return config;
}
void PerformTest() override {
const int64_t kDisabledFeedbackTimeoutMs = 10000;
observation_complete_.Wait(kDisabledFeedbackTimeoutMs);
rtc::CritScope lock(&crit_);
EXPECT_GT(padding_sent_, 0);
}
size_t GetNumVideoStreams() const override { return num_video_streams_; }
size_t GetNumAudioStreams() const override { return num_audio_streams_; }
private:
const size_t num_video_streams_;
const size_t num_audio_streams_;
rtc::CriticalSection crit_;
int media_sent_ GUARDED_BY(crit_);
int padding_sent_ GUARDED_BY(crit_);
} test(1, 0);
RunBaseTest(&test);
}
TEST_F(EndToEndTest, ObserversEncodedFrames) {
class EncodedFrameTestObserver : public EncodedFrameObserver {
public:
@ -2484,8 +2410,8 @@ TEST_F(EndToEndTest, TriggerMidCallProbing) {
if (success)
return;
}
EXPECT_TRUE(success) << "Failed to perform mid call probing (" << kMaxAttempts
<< " attempts).";
RTC_DCHECK(success) << "Failed to perform mid call probing (" << kMaxAttempts
<< " attempts).";
}
TEST_F(EndToEndTest, VerifyNackStats) {
@ -4270,17 +4196,12 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
receiver_call_(nullptr),
sender_state_(kNetworkUp),
sender_rtp_(0),
sender_padding_(0),
sender_rtcp_(0),
receiver_rtcp_(0),
down_frames_(0) {}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&test_crit_);
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
if (length == header.headerLength + header.paddingLength)
++sender_padding_;
++sender_rtp_;
packet_event_.Set();
return SEND_PACKET;
@ -4405,8 +4326,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
int64_t time_now_ms = clock_->TimeInMilliseconds();
rtc::CritScope lock(&test_crit_);
if (sender_down) {
ASSERT_LE(sender_rtp_ - initial_sender_rtp - sender_padding_,
kNumAcceptedDowntimeRtp)
ASSERT_LE(sender_rtp_ - initial_sender_rtp, kNumAcceptedDowntimeRtp)
<< "RTP sent during sender-side downtime.";
ASSERT_LE(sender_rtcp_ - initial_sender_rtcp,
kNumAcceptedDowntimeRtcp)
@ -4441,7 +4361,6 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
Call* receiver_call_;
NetworkState sender_state_ GUARDED_BY(test_crit_);
int sender_rtp_ GUARDED_BY(test_crit_);
int sender_padding_ GUARDED_BY(test_crit_);
int sender_rtcp_ GUARDED_BY(test_crit_);
int receiver_rtcp_ GUARDED_BY(test_crit_);
int down_frames_ GUARDED_BY(test_crit_);