blob: d4192402bedac79636e29f7d447f160cf531b12b [file] [log] [blame]
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h"
#include <algorithm>
#include "webrtc/modules/congestion_controller/delay_based_bwe.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/rtc_base/ptr_util.h"
namespace webrtc {
namespace testing {
namespace bwe {
const int kFeedbackIntervalMs = 50;
SendSideBweSender::SendSideBweSender(int kbps,
BitrateObserver* observer,
Clock* clock)
: bitrate_controller_(
BitrateController::CreateBitrateController(clock,
observer,
&event_log_)),
acknowledged_bitrate_estimator_(
rtc::MakeUnique<AcknowledgedBitrateEstimator>()),
bwe_(new DelayBasedBwe(nullptr, clock)),
feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()),
clock_(clock),
send_time_history_(clock_, 10000),
has_received_ack_(false),
last_acked_seq_num_(0),
last_log_time_ms_(0) {
assert(kbps >= kMinBitrateKbps);
assert(kbps <= kMaxBitrateKbps);
bitrate_controller_->SetStartBitrate(1000 * kbps);
bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps,
1000 * kMaxBitrateKbps);
bwe_->SetMinBitrate(1000 * kMinBitrateKbps);
}
SendSideBweSender::~SendSideBweSender() {}
int SendSideBweSender::GetFeedbackIntervalMs() const {
return kFeedbackIntervalMs;
}
void SendSideBweSender::GiveFeedback(const FeedbackPacket& feedback) {
const SendSideBweFeedback& fb =
static_cast<const SendSideBweFeedback&>(feedback);
if (fb.packet_feedback_vector().empty())
return;
std::vector<PacketFeedback> packet_feedback_vector(
fb.packet_feedback_vector());
for (PacketFeedback& packet_feedback : packet_feedback_vector) {
if (!send_time_history_.GetFeedback(&packet_feedback, true)) {
int64_t now_ms = clock_->TimeInMilliseconds();
if (now_ms - last_log_time_ms_ > 5000) {
LOG(LS_WARNING) << "Ack arrived too late.";
last_log_time_ms_ = now_ms;
}
}
}
int64_t rtt_ms =
clock_->TimeInMilliseconds() - feedback.latest_send_time_ms();
bwe_->OnRttUpdate(rtt_ms, rtt_ms);
BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms);
std::sort(packet_feedback_vector.begin(), packet_feedback_vector.end(),
PacketFeedbackComparator());
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
packet_feedback_vector);
DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector(
packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps());
if (result.updated)
bitrate_controller_->OnDelayBasedBweResult(result);
if (has_received_ack_) {
int expected_packets = fb.packet_feedback_vector().back().sequence_number -
last_acked_seq_num_;
// Assuming no reordering for now.
if (expected_packets > 0) {
int lost_packets = expected_packets -
static_cast<int>(fb.packet_feedback_vector().size());
report_block_.fraction_lost = (lost_packets << 8) / expected_packets;
report_block_.packets_lost += lost_packets;
uint32_t unwrapped = seq_num_unwrapper_.Unwrap(
packet_feedback_vector.back().sequence_number);
report_block_.extended_highest_sequence_number =
std::max(unwrapped, report_block_.extended_highest_sequence_number);
ReportBlockList report_blocks;
report_blocks.push_back(report_block_);
feedback_observer_->OnReceivedRtcpReceiverReport(
report_blocks, rtt_ms, clock_->TimeInMilliseconds());
}
bitrate_controller_->Process();
last_acked_seq_num_ = LatestSequenceNumber(
packet_feedback_vector.back().sequence_number, last_acked_seq_num_);
} else {
last_acked_seq_num_ = packet_feedback_vector.back().sequence_number;
has_received_ack_ = true;
}
}
void SendSideBweSender::OnPacketsSent(const Packets& packets) {
for (Packet* packet : packets) {
if (packet->GetPacketType() == Packet::kMedia) {
MediaPacket* media_packet = static_cast<MediaPacket*>(packet);
// TODO(philipel): Add probe_cluster_id to Packet class in order
// to create tests for probing using cluster ids.
PacketFeedback packet_feedback(
clock_->TimeInMilliseconds(), media_packet->header().sequenceNumber,
media_packet->payload_size(), 0, 0, PacedPacketInfo());
send_time_history_.AddAndRemoveOld(packet_feedback);
send_time_history_.OnSentPacket(media_packet->header().sequenceNumber,
media_packet->sender_timestamp_ms());
}
}
}
void SendSideBweSender::OnReceiveBitrateChanged(
const std::vector<uint32_t>& ssrcs,
uint32_t bitrate) {
feedback_observer_->OnReceivedEstimatedBitrate(bitrate);
}
int64_t SendSideBweSender::TimeUntilNextProcess() {
return bitrate_controller_->TimeUntilNextProcess();
}
void SendSideBweSender::Process() {
bitrate_controller_->Process();
}
SendSideBweReceiver::SendSideBweReceiver(int flow_id)
: BweReceiver(flow_id), last_feedback_ms_(0) {
}
SendSideBweReceiver::~SendSideBweReceiver() {
}
void SendSideBweReceiver::ReceivePacket(int64_t arrival_time_ms,
const MediaPacket& media_packet) {
packet_feedback_vector_.push_back(
PacketFeedback(-1, arrival_time_ms, media_packet.sender_timestamp_ms(),
media_packet.header().sequenceNumber,
media_packet.payload_size(), 0, 0, PacedPacketInfo()));
// Log received packet information.
BweReceiver::ReceivePacket(arrival_time_ms, media_packet);
}
FeedbackPacket* SendSideBweReceiver::GetFeedback(int64_t now_ms) {
if (now_ms - last_feedback_ms_ < kFeedbackIntervalMs)
return NULL;
last_feedback_ms_ = now_ms;
int64_t corrected_send_time_ms =
packet_feedback_vector_.back().send_time_ms + now_ms -
packet_feedback_vector_.back().arrival_time_ms;
FeedbackPacket* fb = new SendSideBweFeedback(
flow_id_, now_ms * 1000, corrected_send_time_ms, packet_feedback_vector_);
packet_feedback_vector_.clear();
return fb;
}
} // namespace bwe
} // namespace testing
} // namespace webrtc