Adds remote estimates to rtc event log.

Bug: webrtc:10742
Change-Id: I0db998a05492603fcdeedca780d9ee3d64aa00d4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/151651
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29233}
This commit is contained in:
Sebastian Jansson 2019-09-18 15:37:31 +02:00 committed by Commit Bot
parent 6ed60e39dc
commit 0a5ed896e2
15 changed files with 274 additions and 1 deletions

View File

@ -30,6 +30,7 @@ class RtcEvent {
enum class Type {
AlrStateEvent,
RouteChangeEvent,
RemoteEstimateEvent,
AudioNetworkAdaptation,
AudioPlayout,
AudioReceiveStreamConfig,

View File

@ -20,6 +20,7 @@
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "call/rtp_video_sender.h"
#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
#include "logging/rtc_event_log/events/rtc_event_route_change.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
@ -472,6 +473,10 @@ void RtpTransportControllerSend::OnTransportFeedback(
void RtpTransportControllerSend::OnRemoteNetworkEstimate(
NetworkStateEstimate estimate) {
if (event_log_) {
event_log_->Log(std::make_unique<RtcEventRemoteEstimate>(
estimate.link_capacity_lower, estimate.link_capacity_upper));
}
estimate.update_time = Timestamp::ms(clock_->TimeInMilliseconds());
task_queue_.PostTask([this, estimate] {
RTC_DCHECK_RUN_ON(&task_queue_);

View File

@ -95,6 +95,7 @@ rtc_source_set("rtc_event_bwe") {
"rtc_event_log/events/rtc_event_probe_result_failure.h",
"rtc_event_log/events/rtc_event_probe_result_success.cc",
"rtc_event_log/events/rtc_event_probe_result_success.h",
"rtc_event_log/events/rtc_event_remote_estimate.h",
"rtc_event_log/events/rtc_event_route_change.cc",
"rtc_event_log/events/rtc_event_route_change.h",
]
@ -102,8 +103,10 @@ rtc_source_set("rtc_event_bwe") {
deps = [
"../api:scoped_refptr",
"../api/rtc_event_log",
"../api/units:data_rate",
"../modules/remote_bitrate_estimator",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",
]
}

View File

@ -363,6 +363,7 @@ std::string RtcEventLogEncoderLegacy::Encode(const RtcEvent& event) {
return EncodeVideoSendStreamConfig(rtc_event);
}
case RtcEvent::Type::RouteChangeEvent:
case RtcEvent::Type::RemoteEstimateEvent:
case RtcEvent::Type::GenericPacketReceived:
case RtcEvent::Type::GenericPacketSent:
case RtcEvent::Type::GenericAckReceived:

View File

@ -32,6 +32,7 @@
#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
#include "logging/rtc_event_log/events/rtc_event_route_change.h"
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
@ -686,6 +687,7 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch(
std::vector<const RtcEventProbeResultFailure*> probe_result_failure_events;
std::vector<const RtcEventProbeResultSuccess*> probe_result_success_events;
std::vector<const RtcEventRouteChange*> route_change_events;
std::vector<const RtcEventRemoteEstimate*> remote_estimate_events;
std::vector<const RtcEventRtcpPacketIncoming*> incoming_rtcp_packets;
std::vector<const RtcEventRtcpPacketOutgoing*> outgoing_rtcp_packets;
std::map<uint32_t /* SSRC */, std::vector<const RtcEventRtpPacketIncoming*>>
@ -779,6 +781,12 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch(
route_change_events.push_back(rtc_event);
break;
}
case RtcEvent::Type::RemoteEstimateEvent: {
auto* rtc_event =
static_cast<const RtcEventRemoteEstimate* const>(it->get());
remote_estimate_events.push_back(rtc_event);
break;
}
case RtcEvent::Type::RtcpPacketIncoming: {
auto* rtc_event =
static_cast<const RtcEventRtcpPacketIncoming* const>(it->get());
@ -873,6 +881,7 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch(
EncodeProbeResultFailure(probe_result_failure_events, &event_stream);
EncodeProbeResultSuccess(probe_result_success_events, &event_stream);
EncodeRouteChange(route_change_events, &event_stream);
EncodeRemoteEstimate(remote_estimate_events, &event_stream);
EncodeRtcpPacketIncoming(incoming_rtcp_packets, &event_stream);
EncodeRtcpPacketOutgoing(outgoing_rtcp_packets, &event_stream);
EncodeRtpPacketIncoming(incoming_rtp_packets, &event_stream);
@ -1322,6 +1331,78 @@ void RtcEventLogEncoderNewFormat::EncodeRouteChange(
// TODO(terelius): Should we delta-compress this event type?
}
void RtcEventLogEncoderNewFormat::EncodeRemoteEstimate(
rtc::ArrayView<const RtcEventRemoteEstimate*> batch,
rtclog2::EventStream* event_stream) {
if (batch.empty())
return;
// Base event
const auto* const base_event = batch[0];
rtclog2::RemoteEstimates* proto_batch = event_stream->add_remote_estimates();
proto_batch->set_timestamp_ms(base_event->timestamp_ms());
absl::optional<uint64_t> base_link_capacity_lower;
if (base_event->link_capacity_lower_.IsFinite()) {
base_link_capacity_lower =
base_event->link_capacity_lower_.kbps<uint32_t>();
proto_batch->set_link_capacity_lower_kbps(*base_link_capacity_lower);
}
absl::optional<uint64_t> base_link_capacity_upper;
if (base_event->link_capacity_upper_.IsFinite()) {
base_link_capacity_upper =
base_event->link_capacity_upper_.kbps<uint32_t>();
proto_batch->set_link_capacity_upper_kbps(*base_link_capacity_upper);
}
if (batch.size() == 1)
return;
// Delta encoding
proto_batch->set_number_of_deltas(batch.size() - 1);
std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
std::string encoded_deltas;
// timestamp_ms
for (size_t i = 0; i < values.size(); ++i) {
const auto* event = batch[i + 1];
values[i] = ToUnsigned(event->timestamp_ms());
}
encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
if (!encoded_deltas.empty()) {
proto_batch->set_timestamp_ms_deltas(encoded_deltas);
}
// link_capacity_lower_kbps
for (size_t i = 0; i < values.size(); ++i) {
const auto* event = batch[i + 1];
if (base_event->link_capacity_lower_.IsFinite()) {
values[i] = event->link_capacity_lower_.kbps<uint32_t>();
} else {
values[i].reset();
}
}
encoded_deltas = EncodeDeltas(base_link_capacity_lower, values);
if (!encoded_deltas.empty()) {
proto_batch->set_link_capacity_lower_kbps_deltas(encoded_deltas);
}
// link_capacity_upper_kbps
for (size_t i = 0; i < values.size(); ++i) {
const auto* event = batch[i + 1];
if (base_event->link_capacity_upper_.IsFinite()) {
values[i] = event->link_capacity_upper_.kbps<uint32_t>();
} else {
values[i].reset();
}
}
encoded_deltas = EncodeDeltas(base_link_capacity_upper, values);
if (!encoded_deltas.empty()) {
proto_batch->set_link_capacity_upper_kbps_deltas(encoded_deltas);
}
}
void RtcEventLogEncoderNewFormat::EncodeRtcpPacketIncoming(
rtc::ArrayView<const RtcEventRtcpPacketIncoming*> batch,
rtclog2::EventStream* event_stream) {

View File

@ -28,6 +28,7 @@ class EventStream; // Auto-generated from protobuf.
class RtcEventAlrState;
class RtcEventRouteChange;
class RtcEventRemoteEstimate;
class RtcEventAudioNetworkAdaptation;
class RtcEventAudioPlayout;
class RtcEventAudioReceiveStreamConfig;
@ -123,6 +124,8 @@ class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder {
rtclog2::EventStream* event_stream);
void EncodeRouteChange(rtc::ArrayView<const RtcEventRouteChange*> batch,
rtclog2::EventStream* event_stream);
void EncodeRemoteEstimate(rtc::ArrayView<const RtcEventRemoteEstimate*> batch,
rtclog2::EventStream* event_stream);
void EncodeRtcpPacketIncoming(
rtc::ArrayView<const RtcEventRtcpPacketIncoming*> batch,
rtclog2::EventStream* event_stream);

View File

@ -239,6 +239,28 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRouteChange) {
}
}
TEST_P(RtcEventLogEncoderTest, RtcEventRemoteEstimate) {
if (!new_encoding_) {
return;
}
std::vector<std::unique_ptr<RtcEventRemoteEstimate>> events(event_count_);
for (size_t i = 0; i < event_count_; ++i) {
events[i] = (i == 0 || !force_repeated_fields_)
? gen_.NewRemoteEstimate()
: std::make_unique<RtcEventRemoteEstimate>(*events[0]);
history_.push_back(std::make_unique<RtcEventRemoteEstimate>(*events[i]));
}
std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
ASSERT_TRUE(parsed_log_.ParseString(encoded));
const auto& parsed_events = parsed_log_.remote_estimate_events();
ASSERT_EQ(parsed_events.size(), event_count_);
for (size_t i = 0; i < event_count_; ++i) {
verifier_.VerifyLoggedRemoteEstimateEvent(*events[i], parsed_events[i]);
}
}
TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationBitrate) {
std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> events(
event_count_);

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2019 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.
*/
#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_
#include <memory>
#include "absl/types/optional.h"
#include "api/rtc_event_log/rtc_event.h"
#include "api/units/data_rate.h"
namespace webrtc {
class RtcEventRemoteEstimate final : public RtcEvent {
public:
RtcEventRemoteEstimate(DataRate link_capacity_lower,
DataRate link_capacity_upper)
: link_capacity_lower_(link_capacity_lower),
link_capacity_upper_(link_capacity_upper) {}
Type GetType() const override { return RtcEvent::Type::RemoteEstimateEvent; }
bool IsConfigEvent() const override { return false; }
const DataRate link_capacity_lower_;
const DataRate link_capacity_upper_;
};
} // namespace webrtc
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_

View File

@ -239,6 +239,17 @@ struct LoggedRouteChangeEvent {
uint32_t overhead;
};
struct LoggedRemoteEstimateEvent {
LoggedRemoteEstimateEvent() = default;
int64_t log_time_us() const { return timestamp_ms * 1000; }
int64_t log_time_ms() const { return timestamp_ms; }
int64_t timestamp_ms;
absl::optional<DataRate> link_capacity_lower;
absl::optional<DataRate> link_capacity_upper;
};
struct LoggedRtpPacket {
LoggedRtpPacket(uint64_t timestamp_us,
RTPHeader header,

View File

@ -38,6 +38,7 @@ message EventStream {
repeated GenericPacketReceived generic_packets_received = 30;
repeated GenericAckReceived generic_acks_received = 31;
repeated RouteChange route_changes = 32;
repeated RemoteEstimates remote_estimates = 33;
repeated AudioRecvStreamConfig audio_recv_stream_configs = 101;
repeated AudioSendStreamConfig audio_send_stream_configs = 102;
@ -664,3 +665,20 @@ message RouteChange {
// required - The per packet data overhead for this route.
optional uint32 overhead = 3;
}
message RemoteEstimates {
// required
optional int64 timestamp_ms = 1;
// optional - value used as a safe measure of available capacity.
optional uint32 link_capacity_lower_kbps = 2;
// optional - value used as limit for increasing bitrate.
optional uint32 link_capacity_upper_kbps = 3;
// optional - required if the batch contains delta encoded events.
optional uint32 number_of_deltas = 4;
// Delta encodings.
optional bytes timestamp_ms_deltas = 101;
optional bytes link_capacity_lower_kbps_deltas = 102;
optional bytes link_capacity_upper_kbps_deltas = 103;
}

View File

@ -2147,7 +2147,8 @@ void ParsedRtcEventLog::StoreParsedNewFormatEvent(
stream.audio_network_adaptations_size() +
stream.probe_clusters_size() + stream.probe_success_size() +
stream.probe_failure_size() + stream.alr_states_size() +
stream.route_changes_size() + stream.ice_candidate_configs_size() +
stream.route_changes_size() + stream.remote_estimates_size() +
stream.ice_candidate_configs_size() +
stream.ice_candidate_events_size() +
stream.audio_recv_stream_configs_size() +
stream.audio_send_stream_configs_size() +
@ -2192,6 +2193,8 @@ void ParsedRtcEventLog::StoreParsedNewFormatEvent(
StoreAlrStateEvent(stream.alr_states(0));
} else if (stream.route_changes_size() == 1) {
StoreRouteChangeEvent(stream.route_changes(0));
} else if (stream.remote_estimates_size() == 1) {
StoreRemoteEstimateEvent(stream.remote_estimates(0));
} else if (stream.ice_candidate_configs_size() == 1) {
StoreIceCandidatePairConfig(stream.ice_candidate_configs(0));
} else if (stream.ice_candidate_events_size() == 1) {
@ -2240,6 +2243,68 @@ void ParsedRtcEventLog::StoreRouteChangeEvent(
// TODO(terelius): Should we delta encode this event type?
}
void ParsedRtcEventLog::StoreRemoteEstimateEvent(
const rtclog2::RemoteEstimates& proto) {
RTC_CHECK(proto.has_timestamp_ms());
// Base event
LoggedRemoteEstimateEvent base_event;
base_event.timestamp_ms = proto.timestamp_ms();
absl::optional<uint64_t> base_link_capacity_lower_kbps;
if (proto.has_link_capacity_lower_kbps()) {
base_link_capacity_lower_kbps = proto.link_capacity_lower_kbps();
base_event.link_capacity_lower =
DataRate::kbps(proto.link_capacity_lower_kbps());
}
absl::optional<uint64_t> base_link_capacity_upper_kbps;
if (proto.has_link_capacity_upper_kbps()) {
base_link_capacity_upper_kbps = proto.link_capacity_upper_kbps();
base_event.link_capacity_upper =
DataRate::kbps(proto.link_capacity_upper_kbps());
}
remote_estimate_events_.push_back(base_event);
const size_t number_of_deltas =
proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
if (number_of_deltas == 0) {
return;
}
// timestamp_ms
auto timestamp_ms_values =
DecodeDeltas(proto.timestamp_ms_deltas(),
ToUnsigned(proto.timestamp_ms()), number_of_deltas);
RTC_CHECK_EQ(timestamp_ms_values.size(), number_of_deltas);
// link_capacity_lower_kbps
auto link_capacity_lower_kbps_values =
DecodeDeltas(proto.link_capacity_lower_kbps_deltas(),
base_link_capacity_lower_kbps, number_of_deltas);
RTC_CHECK_EQ(link_capacity_lower_kbps_values.size(), number_of_deltas);
// link_capacity_upper_kbps
auto link_capacity_upper_kbps_values =
DecodeDeltas(proto.link_capacity_upper_kbps_deltas(),
base_link_capacity_upper_kbps, number_of_deltas);
RTC_CHECK_EQ(link_capacity_upper_kbps_values.size(), number_of_deltas);
// Delta decoding
for (size_t i = 0; i < number_of_deltas; ++i) {
LoggedRemoteEstimateEvent event;
RTC_CHECK(timestamp_ms_values[i].has_value());
event.timestamp_ms = *timestamp_ms_values[i];
if (link_capacity_lower_kbps_values[i])
event.link_capacity_lower =
DataRate::kbps(*link_capacity_lower_kbps_values[i]);
if (link_capacity_upper_kbps_values[i])
event.link_capacity_upper =
DataRate::kbps(*link_capacity_upper_kbps_values[i]);
remote_estimate_events_.push_back(event);
}
}
void ParsedRtcEventLog::StoreAudioPlayoutEvent(
const rtclog2::AudioPlayoutEvents& proto) {
RTC_CHECK(proto.has_timestamp_ms());

View File

@ -426,6 +426,10 @@ class ParsedRtcEventLog {
return route_change_events_;
}
const std::vector<LoggedRemoteEstimateEvent>& remote_estimate_events() const {
return remote_estimate_events_;
}
// RTP
const std::vector<LoggedRtpStreamIncoming>& incoming_rtp_packets_by_ssrc()
const {
@ -656,6 +660,7 @@ class ParsedRtcEventLog {
void StoreOutgoingRtpPackets(const rtclog2::OutgoingRtpPackets& proto);
void StoreParsedNewFormatEvent(const rtclog2::EventStream& event);
void StoreRouteChangeEvent(const rtclog2::RouteChange& proto);
void StoreRemoteEstimateEvent(const rtclog2::RemoteEstimates& proto);
void StoreStartEvent(const rtclog2::BeginLogEvent& proto);
void StoreStopEvent(const rtclog2::EndLogEvent& proto);
void StoreVideoRecvConfig(const rtclog2::VideoRecvStreamConfig& proto);
@ -771,6 +776,7 @@ class ParsedRtcEventLog {
std::vector<LoggedGenericAckReceived> generic_acks_received_;
std::vector<LoggedRouteChangeEvent> route_change_events_;
std::vector<LoggedRemoteEstimateEvent> remote_estimate_events_;
uint8_t last_incoming_rtcp_packet_[IP_PACKET_SIZE];
uint8_t last_incoming_rtcp_packet_length_;

View File

@ -177,6 +177,7 @@ class RtcEventLogSession
std::vector<std::unique_ptr<RtcEventProbeResultFailure>> probe_failure_list_;
std::vector<std::unique_ptr<RtcEventProbeResultSuccess>> probe_success_list_;
std::vector<std::unique_ptr<RtcEventRouteChange>> route_change_list_;
std::vector<std::unique_ptr<RtcEventRemoteEstimate>> remote_estimate_list_;
std::vector<std::unique_ptr<RtcEventRtcpPacketIncoming>> incoming_rtcp_list_;
std::vector<std::unique_ptr<RtcEventRtcpPacketOutgoing>> outgoing_rtcp_list_;
std::map<uint32_t, std::vector<std::unique_ptr<RtcEventRtpPacketIncoming>>>

View File

@ -355,6 +355,12 @@ std::unique_ptr<RtcEventRouteChange> EventGenerator::NewRouteChange() {
prng_.Rand(0, 128));
}
std::unique_ptr<RtcEventRemoteEstimate> EventGenerator::NewRemoteEstimate() {
return std::make_unique<RtcEventRemoteEstimate>(
DataRate::kbps(prng_.Rand(0, 100000)),
DataRate::kbps(prng_.Rand(0, 100000)));
}
std::unique_ptr<RtcEventRtcpPacketIncoming>
EventGenerator::NewRtcpPacketIncoming() {
enum class SupportedRtcpTypes {
@ -932,6 +938,16 @@ void EventVerifier::VerifyLoggedRouteChangeEvent(
EXPECT_EQ(original_event.overhead(), logged_event.overhead);
}
void EventVerifier::VerifyLoggedRemoteEstimateEvent(
const RtcEventRemoteEstimate& original_event,
const LoggedRemoteEstimateEvent& logged_event) const {
EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms());
EXPECT_EQ(original_event.link_capacity_lower_,
logged_event.link_capacity_lower);
EXPECT_EQ(original_event.link_capacity_upper_,
logged_event.link_capacity_upper);
}
void EventVerifier::VerifyLoggedRtpPacketIncoming(
const RtcEventRtpPacketIncoming& original_event,
const LoggedRtpPacketIncoming& logged_event) const {

View File

@ -33,6 +33,7 @@
#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
#include "logging/rtc_event_log/events/rtc_event_route_change.h"
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
@ -79,6 +80,7 @@ class EventGenerator {
std::unique_ptr<RtcEventProbeResultFailure> NewProbeResultFailure();
std::unique_ptr<RtcEventProbeResultSuccess> NewProbeResultSuccess();
std::unique_ptr<RtcEventRouteChange> NewRouteChange();
std::unique_ptr<RtcEventRemoteEstimate> NewRemoteEstimate();
std::unique_ptr<RtcEventRtcpPacketIncoming> NewRtcpPacketIncoming();
std::unique_ptr<RtcEventRtcpPacketOutgoing> NewRtcpPacketOutgoing();
@ -199,6 +201,10 @@ class EventVerifier {
const RtcEventRouteChange& original_event,
const LoggedRouteChangeEvent& logged_event) const;
void VerifyLoggedRemoteEstimateEvent(
const RtcEventRemoteEstimate& original_event,
const LoggedRemoteEstimateEvent& logged_event) const;
void VerifyLoggedRtpPacketIncoming(
const RtcEventRtpPacketIncoming& original_event,
const LoggedRtpPacketIncoming& logged_event) const;