Reland "Structured ICE logging via RtcEventLog."
This is a reland of eed5aa8904d09179971d3f4e7e10c109d7c62bfc Original change's description: > Structured ICE logging via RtcEventLog. > > This change list contains the structured logging module for ICE using > the RtcEventLog infrastructure, and also extension to the log parser > and analyzer. > > Bug: None > Change-Id: I6539cf282155c2cde4d3161c53500c0746671a02 > Reviewed-on: https://webrtc-review.googlesource.com/34622 > Commit-Queue: Qingsi Wang <qingsi@google.com> > Reviewed-by: Björn Terelius <terelius@webrtc.org> > Reviewed-by: Peter Thatcher <pthatcher@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#21816} TBR=pthatcher@webrtc.org,terelius@webrtc.org,deadbeef@webrtc.org Bug: None Change-Id: I3df585bf636315ceb0273967146111346a83be86 Reviewed-on: https://webrtc-review.googlesource.com/47545 Commit-Queue: Qingsi Wang <qingsi@google.com> Reviewed-by: Qingsi Wang <qingsi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21881}
This commit is contained in:
parent
cc7125f240
commit
8eca1ff510
@ -164,6 +164,7 @@ rtc_static_library("rtc_event_log_impl_encoder") {
|
|||||||
defines = []
|
defines = []
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
|
":ice_log",
|
||||||
":rtc_event_audio",
|
":rtc_event_audio",
|
||||||
":rtc_event_bwe",
|
":rtc_event_bwe",
|
||||||
":rtc_event_log_api",
|
":rtc_event_log_api",
|
||||||
@ -221,6 +222,7 @@ rtc_static_library("rtc_event_log_impl_base") {
|
|||||||
defines = []
|
defines = []
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
|
":ice_log",
|
||||||
":rtc_event_log_api",
|
":rtc_event_log_api",
|
||||||
":rtc_event_log_impl_encoder",
|
":rtc_event_log_impl_encoder",
|
||||||
":rtc_event_log_impl_output",
|
":rtc_event_log_impl_output",
|
||||||
@ -263,6 +265,7 @@ if (rtc_enable_protobuf) {
|
|||||||
]
|
]
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
|
":ice_log",
|
||||||
":rtc_event_bwe",
|
":rtc_event_bwe",
|
||||||
":rtc_event_log2_proto",
|
":rtc_event_log2_proto",
|
||||||
":rtc_event_log_api",
|
":rtc_event_log_api",
|
||||||
@ -400,6 +403,28 @@ if (rtc_enable_protobuf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtc_source_set("ice_log") {
|
||||||
|
sources = [
|
||||||
|
"rtc_event_log/events/rtc_event_ice_candidate_pair.cc",
|
||||||
|
"rtc_event_log/events/rtc_event_ice_candidate_pair.h",
|
||||||
|
"rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc",
|
||||||
|
"rtc_event_log/events/rtc_event_ice_candidate_pair_config.h",
|
||||||
|
"rtc_event_log/icelogger.cc",
|
||||||
|
"rtc_event_log/icelogger.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
":rtc_event_log_api",
|
||||||
|
"../api:libjingle_logging_api",
|
||||||
|
"../rtc_base:rtc_base_approved",
|
||||||
|
]
|
||||||
|
|
||||||
|
if (!build_with_chromium && is_clang) {
|
||||||
|
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
|
||||||
|
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rtc_include_tests) {
|
if (rtc_include_tests) {
|
||||||
rtc_source_set("mocks") {
|
rtc_source_set("mocks") {
|
||||||
testonly = true
|
testonly = true
|
||||||
|
|||||||
@ -17,6 +17,8 @@
|
|||||||
#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
|
#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
|
||||||
#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
|
#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
|
||||||
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
|
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
|
||||||
#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
|
#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_failure.h"
|
||||||
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
|
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
|
||||||
@ -103,6 +105,122 @@ rtclog::VideoReceiveConfig_RtcpMode ConvertRtcpMode(RtcpMode rtcp_mode) {
|
|||||||
RTC_NOTREACHED();
|
RTC_NOTREACHED();
|
||||||
return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
|
return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtclog::IceCandidatePairConfig::IceCandidatePairConfigType
|
||||||
|
ConvertIceCandidatePairConfigType(IceCandidatePairEventType type) {
|
||||||
|
switch (type) {
|
||||||
|
case IceCandidatePairEventType::kAdded:
|
||||||
|
return rtclog::IceCandidatePairConfig::ADDED;
|
||||||
|
case IceCandidatePairEventType::kUpdated:
|
||||||
|
return rtclog::IceCandidatePairConfig::UPDATED;
|
||||||
|
case IceCandidatePairEventType::kDestroyed:
|
||||||
|
return rtclog::IceCandidatePairConfig::DESTROYED;
|
||||||
|
case IceCandidatePairEventType::kSelected:
|
||||||
|
return rtclog::IceCandidatePairConfig::SELECTED;
|
||||||
|
default:
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return rtclog::IceCandidatePairConfig::ADDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtclog::IceCandidatePairConfig::IceCandidateType ConvertIceCandidateType(
|
||||||
|
IceCandidateType type) {
|
||||||
|
switch (type) {
|
||||||
|
case IceCandidateType::kLocal:
|
||||||
|
return rtclog::IceCandidatePairConfig::LOCAL;
|
||||||
|
case IceCandidateType::kStun:
|
||||||
|
return rtclog::IceCandidatePairConfig::STUN;
|
||||||
|
case IceCandidateType::kPrflx:
|
||||||
|
return rtclog::IceCandidatePairConfig::PRFLX;
|
||||||
|
case IceCandidateType::kRelay:
|
||||||
|
return rtclog::IceCandidatePairConfig::RELAY;
|
||||||
|
case IceCandidateType::kUnknown:
|
||||||
|
return rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE;
|
||||||
|
default:
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtclog::IceCandidatePairConfig::Protocol ConvertIceCandidatePairProtocol(
|
||||||
|
IceCandidatePairProtocol protocol) {
|
||||||
|
switch (protocol) {
|
||||||
|
case IceCandidatePairProtocol::kUdp:
|
||||||
|
return rtclog::IceCandidatePairConfig::UDP;
|
||||||
|
case IceCandidatePairProtocol::kTcp:
|
||||||
|
return rtclog::IceCandidatePairConfig::TCP;
|
||||||
|
case IceCandidatePairProtocol::kSsltcp:
|
||||||
|
return rtclog::IceCandidatePairConfig::SSLTCP;
|
||||||
|
case IceCandidatePairProtocol::kTls:
|
||||||
|
return rtclog::IceCandidatePairConfig::TLS;
|
||||||
|
case IceCandidatePairProtocol::kUnknown:
|
||||||
|
return rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL;
|
||||||
|
default:
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtclog::IceCandidatePairConfig::AddressFamily
|
||||||
|
ConvertIceCandidatePairAddressFamily(
|
||||||
|
IceCandidatePairAddressFamily address_family) {
|
||||||
|
switch (address_family) {
|
||||||
|
case IceCandidatePairAddressFamily::kIpv4:
|
||||||
|
return rtclog::IceCandidatePairConfig::IPV4;
|
||||||
|
case IceCandidatePairAddressFamily::kIpv6:
|
||||||
|
return rtclog::IceCandidatePairConfig::IPV6;
|
||||||
|
case IceCandidatePairAddressFamily::kUnknown:
|
||||||
|
return rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY;
|
||||||
|
default:
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtclog::IceCandidatePairConfig::NetworkType ConvertIceCandidateNetworkType(
|
||||||
|
IceCandidateNetworkType network_type) {
|
||||||
|
switch (network_type) {
|
||||||
|
case IceCandidateNetworkType::kEthernet:
|
||||||
|
return rtclog::IceCandidatePairConfig::ETHERNET;
|
||||||
|
case IceCandidateNetworkType::kLoopback:
|
||||||
|
return rtclog::IceCandidatePairConfig::LOOPBACK;
|
||||||
|
case IceCandidateNetworkType::kWifi:
|
||||||
|
return rtclog::IceCandidatePairConfig::WIFI;
|
||||||
|
case IceCandidateNetworkType::kVpn:
|
||||||
|
return rtclog::IceCandidatePairConfig::VPN;
|
||||||
|
case IceCandidateNetworkType::kCellular:
|
||||||
|
return rtclog::IceCandidatePairConfig::CELLULAR;
|
||||||
|
case IceCandidateNetworkType::kUnknown:
|
||||||
|
return rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE;
|
||||||
|
default:
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtclog::IceCandidatePairEvent::IceCandidatePairEventType
|
||||||
|
ConvertIceCandidatePairEventType(IceCandidatePairEventType type) {
|
||||||
|
switch (type) {
|
||||||
|
case IceCandidatePairEventType::kCheckSent:
|
||||||
|
return rtclog::IceCandidatePairEvent::CHECK_SENT;
|
||||||
|
case IceCandidatePairEventType::kCheckReceived:
|
||||||
|
return rtclog::IceCandidatePairEvent::CHECK_RECEIVED;
|
||||||
|
case IceCandidatePairEventType::kCheckResponseSent:
|
||||||
|
return rtclog::IceCandidatePairEvent::CHECK_RESPONSE_SENT;
|
||||||
|
case IceCandidatePairEventType::kCheckResponseReceived:
|
||||||
|
return rtclog::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED;
|
||||||
|
default:
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return rtclog::IceCandidatePairEvent::CHECK_SENT;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::string RtcEventLogEncoderLegacy::EncodeLogStart(int64_t timestamp_us) {
|
std::string RtcEventLogEncoderLegacy::EncodeLogStart(int64_t timestamp_us) {
|
||||||
@ -171,6 +289,17 @@ std::string RtcEventLogEncoderLegacy::Encode(const RtcEvent& event) {
|
|||||||
return EncodeBweUpdateLossBased(rtc_event);
|
return EncodeBweUpdateLossBased(rtc_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RtcEvent::Type::IceCandidatePairConfig: {
|
||||||
|
auto& rtc_event =
|
||||||
|
static_cast<const RtcEventIceCandidatePairConfig&>(event);
|
||||||
|
return EncodeIceCandidatePairConfig(rtc_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
case RtcEvent::Type::IceCandidatePairEvent: {
|
||||||
|
auto& rtc_event = static_cast<const RtcEventIceCandidatePair&>(event);
|
||||||
|
return EncodeIceCandidatePairEvent(rtc_event);
|
||||||
|
}
|
||||||
|
|
||||||
case RtcEvent::Type::ProbeClusterCreated: {
|
case RtcEvent::Type::ProbeClusterCreated: {
|
||||||
auto& rtc_event = static_cast<const RtcEventProbeClusterCreated&>(event);
|
auto& rtc_event = static_cast<const RtcEventProbeClusterCreated&>(event);
|
||||||
return EncodeProbeClusterCreated(rtc_event);
|
return EncodeProbeClusterCreated(rtc_event);
|
||||||
@ -343,6 +472,48 @@ std::string RtcEventLogEncoderLegacy::EncodeBweUpdateLossBased(
|
|||||||
return Serialize(&rtclog_event);
|
return Serialize(&rtclog_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string RtcEventLogEncoderLegacy::EncodeIceCandidatePairConfig(
|
||||||
|
const RtcEventIceCandidatePairConfig& event) {
|
||||||
|
rtclog::Event encoded_rtc_event;
|
||||||
|
encoded_rtc_event.set_timestamp_us(event.timestamp_us_);
|
||||||
|
encoded_rtc_event.set_type(rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG);
|
||||||
|
|
||||||
|
auto encoded_ice_event =
|
||||||
|
encoded_rtc_event.mutable_ice_candidate_pair_config();
|
||||||
|
encoded_ice_event->set_config_type(
|
||||||
|
ConvertIceCandidatePairConfigType(event.type_));
|
||||||
|
encoded_ice_event->set_candidate_pair_id(event.candidate_pair_id_);
|
||||||
|
const auto& desc = event.candidate_pair_desc_;
|
||||||
|
encoded_ice_event->set_local_candidate_type(
|
||||||
|
ConvertIceCandidateType(desc.local_candidate_type));
|
||||||
|
encoded_ice_event->set_local_relay_protocol(
|
||||||
|
ConvertIceCandidatePairProtocol(desc.local_relay_protocol));
|
||||||
|
encoded_ice_event->set_local_network_type(
|
||||||
|
ConvertIceCandidateNetworkType(desc.local_network_type));
|
||||||
|
encoded_ice_event->set_local_address_family(
|
||||||
|
ConvertIceCandidatePairAddressFamily(desc.local_address_family));
|
||||||
|
encoded_ice_event->set_remote_candidate_type(
|
||||||
|
ConvertIceCandidateType(desc.remote_candidate_type));
|
||||||
|
encoded_ice_event->set_remote_address_family(
|
||||||
|
ConvertIceCandidatePairAddressFamily(desc.remote_address_family));
|
||||||
|
encoded_ice_event->set_candidate_pair_protocol(
|
||||||
|
ConvertIceCandidatePairProtocol(desc.candidate_pair_protocol));
|
||||||
|
return Serialize(&encoded_rtc_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RtcEventLogEncoderLegacy::EncodeIceCandidatePairEvent(
|
||||||
|
const RtcEventIceCandidatePair& event) {
|
||||||
|
rtclog::Event encoded_rtc_event;
|
||||||
|
encoded_rtc_event.set_timestamp_us(event.timestamp_us_);
|
||||||
|
encoded_rtc_event.set_type(rtclog::Event::ICE_CANDIDATE_PAIR_EVENT);
|
||||||
|
|
||||||
|
auto encoded_ice_event = encoded_rtc_event.mutable_ice_candidate_pair_event();
|
||||||
|
encoded_ice_event->set_event_type(
|
||||||
|
ConvertIceCandidatePairEventType(event.type_));
|
||||||
|
encoded_ice_event->set_candidate_pair_id(event.candidate_pair_id_);
|
||||||
|
return Serialize(&encoded_rtc_event);
|
||||||
|
}
|
||||||
|
|
||||||
std::string RtcEventLogEncoderLegacy::EncodeProbeClusterCreated(
|
std::string RtcEventLogEncoderLegacy::EncodeProbeClusterCreated(
|
||||||
const RtcEventProbeClusterCreated& event) {
|
const RtcEventProbeClusterCreated& event) {
|
||||||
rtclog::Event rtclog_event;
|
rtclog::Event rtclog_event;
|
||||||
|
|||||||
@ -32,6 +32,8 @@ class RtcEventAudioReceiveStreamConfig;
|
|||||||
class RtcEventAudioSendStreamConfig;
|
class RtcEventAudioSendStreamConfig;
|
||||||
class RtcEventBweUpdateDelayBased;
|
class RtcEventBweUpdateDelayBased;
|
||||||
class RtcEventBweUpdateLossBased;
|
class RtcEventBweUpdateLossBased;
|
||||||
|
class RtcEventIceCandidatePairConfig;
|
||||||
|
class RtcEventIceCandidatePair;
|
||||||
class RtcEventLoggingStarted;
|
class RtcEventLoggingStarted;
|
||||||
class RtcEventLoggingStopped;
|
class RtcEventLoggingStopped;
|
||||||
class RtcEventProbeClusterCreated;
|
class RtcEventProbeClusterCreated;
|
||||||
@ -71,6 +73,10 @@ class RtcEventLogEncoderLegacy final : public RtcEventLogEncoder {
|
|||||||
std::string EncodeBweUpdateDelayBased(
|
std::string EncodeBweUpdateDelayBased(
|
||||||
const RtcEventBweUpdateDelayBased& event);
|
const RtcEventBweUpdateDelayBased& event);
|
||||||
std::string EncodeBweUpdateLossBased(const RtcEventBweUpdateLossBased& event);
|
std::string EncodeBweUpdateLossBased(const RtcEventBweUpdateLossBased& event);
|
||||||
|
std::string EncodeIceCandidatePairConfig(
|
||||||
|
const RtcEventIceCandidatePairConfig& event);
|
||||||
|
std::string EncodeIceCandidatePairEvent(
|
||||||
|
const RtcEventIceCandidatePair& event);
|
||||||
std::string EncodeProbeClusterCreated(
|
std::string EncodeProbeClusterCreated(
|
||||||
const RtcEventProbeClusterCreated& event);
|
const RtcEventProbeClusterCreated& event);
|
||||||
std::string EncodeProbeResultFailure(const RtcEventProbeResultFailure& event);
|
std::string EncodeProbeResultFailure(const RtcEventProbeResultFailure& event);
|
||||||
|
|||||||
@ -37,6 +37,8 @@ class RtcEvent {
|
|||||||
AudioSendStreamConfig,
|
AudioSendStreamConfig,
|
||||||
BweUpdateDelayBased,
|
BweUpdateDelayBased,
|
||||||
BweUpdateLossBased,
|
BweUpdateLossBased,
|
||||||
|
IceCandidatePairConfig,
|
||||||
|
IceCandidatePairEvent,
|
||||||
ProbeClusterCreated,
|
ProbeClusterCreated,
|
||||||
ProbeResultFailure,
|
ProbeResultFailure,
|
||||||
ProbeResultSuccess,
|
ProbeResultSuccess,
|
||||||
|
|||||||
30
logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc
Normal file
30
logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 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 "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
RtcEventIceCandidatePair::RtcEventIceCandidatePair(
|
||||||
|
IceCandidatePairEventType type,
|
||||||
|
uint32_t candidate_pair_id)
|
||||||
|
: type_(type), candidate_pair_id_(candidate_pair_id) {}
|
||||||
|
|
||||||
|
RtcEventIceCandidatePair::~RtcEventIceCandidatePair() = default;
|
||||||
|
|
||||||
|
RtcEvent::Type RtcEventIceCandidatePair::GetType() const {
|
||||||
|
return RtcEvent::Type::IceCandidatePairEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtcEventIceCandidatePair::IsConfigEvent() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
51
logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h
Normal file
51
logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 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_ICE_CANDIDATE_PAIR_H_
|
||||||
|
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_
|
||||||
|
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
enum class IceCandidatePairEventType {
|
||||||
|
// Config event types for events related to the candiate pair creation and
|
||||||
|
// life-cycle management.
|
||||||
|
kAdded,
|
||||||
|
kUpdated,
|
||||||
|
kDestroyed,
|
||||||
|
kSelected,
|
||||||
|
// Non-config event types.
|
||||||
|
kCheckSent,
|
||||||
|
kCheckReceived,
|
||||||
|
kCheckResponseSent,
|
||||||
|
kCheckResponseReceived,
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtcEventIceCandidatePair final : public RtcEvent {
|
||||||
|
public:
|
||||||
|
RtcEventIceCandidatePair(IceCandidatePairEventType type,
|
||||||
|
uint32_t candidate_pair_id);
|
||||||
|
|
||||||
|
~RtcEventIceCandidatePair() override;
|
||||||
|
|
||||||
|
Type GetType() const override;
|
||||||
|
|
||||||
|
bool IsConfigEvent() const override;
|
||||||
|
|
||||||
|
const IceCandidatePairEventType type_;
|
||||||
|
const uint32_t candidate_pair_id_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 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 "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
IceCandidatePairDescription::IceCandidatePairDescription() {
|
||||||
|
local_candidate_type = IceCandidateType::kUnknown;
|
||||||
|
local_relay_protocol = IceCandidatePairProtocol::kUnknown;
|
||||||
|
local_network_type = IceCandidateNetworkType::kUnknown;
|
||||||
|
local_address_family = IceCandidatePairAddressFamily::kUnknown;
|
||||||
|
remote_candidate_type = IceCandidateType::kUnknown;
|
||||||
|
remote_address_family = IceCandidatePairAddressFamily::kUnknown;
|
||||||
|
candidate_pair_protocol = IceCandidatePairProtocol::kUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
IceCandidatePairDescription::IceCandidatePairDescription(
|
||||||
|
const IceCandidatePairDescription& other) {
|
||||||
|
local_candidate_type = other.local_candidate_type;
|
||||||
|
local_relay_protocol = other.local_relay_protocol;
|
||||||
|
local_network_type = other.local_network_type;
|
||||||
|
local_address_family = other.local_address_family;
|
||||||
|
remote_candidate_type = other.remote_candidate_type;
|
||||||
|
remote_address_family = other.remote_address_family;
|
||||||
|
candidate_pair_protocol = other.candidate_pair_protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
IceCandidatePairDescription::~IceCandidatePairDescription() {}
|
||||||
|
|
||||||
|
RtcEventIceCandidatePairConfig::RtcEventIceCandidatePairConfig(
|
||||||
|
IceCandidatePairEventType type,
|
||||||
|
uint32_t candidate_pair_id,
|
||||||
|
const IceCandidatePairDescription& candidate_pair_desc)
|
||||||
|
: type_(type),
|
||||||
|
candidate_pair_id_(candidate_pair_id),
|
||||||
|
candidate_pair_desc_(candidate_pair_desc) {}
|
||||||
|
|
||||||
|
RtcEventIceCandidatePairConfig::~RtcEventIceCandidatePairConfig() = default;
|
||||||
|
|
||||||
|
RtcEvent::Type RtcEventIceCandidatePairConfig::GetType() const {
|
||||||
|
return RtcEvent::Type::IceCandidatePairConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The ICE candidate pair config event is not equivalent to a RtcEventLog config
|
||||||
|
// event.
|
||||||
|
bool RtcEventIceCandidatePairConfig::IsConfigEvent() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 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_ICE_CANDIDATE_PAIR_CONFIG_H_
|
||||||
|
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_
|
||||||
|
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event.h"
|
||||||
|
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// TODO(qingsi): Change the names of candidate types to "host", "srflx", "prflx"
|
||||||
|
// and "relay" after the naming is spec-compliant in the signaling part
|
||||||
|
enum class IceCandidateType {
|
||||||
|
kLocal,
|
||||||
|
kStun,
|
||||||
|
kPrflx,
|
||||||
|
kRelay,
|
||||||
|
kUnknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class IceCandidatePairProtocol {
|
||||||
|
kUdp,
|
||||||
|
kTcp,
|
||||||
|
kSsltcp,
|
||||||
|
kTls,
|
||||||
|
kUnknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class IceCandidatePairAddressFamily {
|
||||||
|
kIpv4,
|
||||||
|
kIpv6,
|
||||||
|
kUnknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class IceCandidateNetworkType {
|
||||||
|
kEthernet,
|
||||||
|
kLoopback,
|
||||||
|
kWifi,
|
||||||
|
kVpn,
|
||||||
|
kCellular,
|
||||||
|
kUnknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
class IceCandidatePairDescription {
|
||||||
|
public:
|
||||||
|
IceCandidatePairDescription();
|
||||||
|
explicit IceCandidatePairDescription(
|
||||||
|
const IceCandidatePairDescription& other);
|
||||||
|
|
||||||
|
~IceCandidatePairDescription();
|
||||||
|
|
||||||
|
IceCandidateType local_candidate_type;
|
||||||
|
IceCandidatePairProtocol local_relay_protocol;
|
||||||
|
IceCandidateNetworkType local_network_type;
|
||||||
|
IceCandidatePairAddressFamily local_address_family;
|
||||||
|
IceCandidateType remote_candidate_type;
|
||||||
|
IceCandidatePairAddressFamily remote_address_family;
|
||||||
|
IceCandidatePairProtocol candidate_pair_protocol;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtcEventIceCandidatePairConfig final : public RtcEvent {
|
||||||
|
public:
|
||||||
|
RtcEventIceCandidatePairConfig(
|
||||||
|
IceCandidatePairEventType type,
|
||||||
|
uint32_t candidate_pair_id,
|
||||||
|
const IceCandidatePairDescription& candidate_pair_desc);
|
||||||
|
|
||||||
|
~RtcEventIceCandidatePairConfig() override;
|
||||||
|
|
||||||
|
Type GetType() const override;
|
||||||
|
|
||||||
|
bool IsConfigEvent() const override;
|
||||||
|
|
||||||
|
const IceCandidatePairEventType type_;
|
||||||
|
const uint32_t candidate_pair_id_;
|
||||||
|
const IceCandidatePairDescription candidate_pair_desc_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_
|
||||||
54
logging/rtc_event_log/icelogger.cc
Normal file
54
logging/rtc_event_log/icelogger.cc
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 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 "logging/rtc_event_log/icelogger.h"
|
||||||
|
|
||||||
|
#include "logging/rtc_event_log/rtc_event_log.h"
|
||||||
|
#include "rtc_base/ptr_util.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
IceEventLog::IceEventLog() {}
|
||||||
|
IceEventLog::~IceEventLog() {}
|
||||||
|
|
||||||
|
bool IceEventLog::IsIceCandidatePairConfigEvent(
|
||||||
|
IceCandidatePairEventType type) {
|
||||||
|
return (type == IceCandidatePairEventType::kAdded) ||
|
||||||
|
(type == IceCandidatePairEventType::kUpdated) ||
|
||||||
|
(type == IceCandidatePairEventType::kDestroyed) ||
|
||||||
|
(type == IceCandidatePairEventType::kSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IceEventLog::LogCandidatePairEvent(
|
||||||
|
IceCandidatePairEventType type,
|
||||||
|
uint32_t candidate_pair_id,
|
||||||
|
const IceCandidatePairDescription& candidate_pair_desc) {
|
||||||
|
if (event_log_ == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (IsIceCandidatePairConfigEvent(type)) {
|
||||||
|
candidate_pair_desc_by_id_[candidate_pair_id] = candidate_pair_desc;
|
||||||
|
event_log_->Log(rtc::MakeUnique<RtcEventIceCandidatePairConfig>(
|
||||||
|
type, candidate_pair_id, candidate_pair_desc));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event_log_->Log(
|
||||||
|
rtc::MakeUnique<RtcEventIceCandidatePair>(type, candidate_pair_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IceEventLog::DumpCandidatePairDescriptionToMemoryAsConfigEvents() const {
|
||||||
|
for (const auto& desc_id_pair : candidate_pair_desc_by_id_) {
|
||||||
|
event_log_->Log(rtc::MakeUnique<RtcEventIceCandidatePairConfig>(
|
||||||
|
IceCandidatePairEventType::kUpdated, desc_id_pair.first,
|
||||||
|
desc_id_pair.second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
51
logging/rtc_event_log/icelogger.h
Normal file
51
logging/rtc_event_log/icelogger.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 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_ICELOGGER_H_
|
||||||
|
#define LOGGING_RTC_EVENT_LOG_ICELOGGER_H_
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
class RtcEventLog;
|
||||||
|
|
||||||
|
// IceEventLog wraps RtcEventLog and provides structural logging of ICE-specific
|
||||||
|
// events. The logged events are serialized with other RtcEvent's if protobuf is
|
||||||
|
// enabled in the build.
|
||||||
|
class IceEventLog {
|
||||||
|
public:
|
||||||
|
IceEventLog();
|
||||||
|
~IceEventLog();
|
||||||
|
void set_event_log(RtcEventLog* event_log) { event_log_ = event_log; }
|
||||||
|
void LogCandidatePairEvent(
|
||||||
|
IceCandidatePairEventType type,
|
||||||
|
uint32_t candidate_pair_id,
|
||||||
|
const IceCandidatePairDescription& candidate_pair_desc);
|
||||||
|
// This method constructs a config event for each candidate pair with their
|
||||||
|
// description and logs these config events. It is intended to be called when
|
||||||
|
// logging starts to ensure that we have at least one config for each
|
||||||
|
// candidate pair id.
|
||||||
|
void DumpCandidatePairDescriptionToMemoryAsConfigEvents() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool IsIceCandidatePairConfigEvent(IceCandidatePairEventType type);
|
||||||
|
|
||||||
|
RtcEventLog* event_log_ = nullptr;
|
||||||
|
std::unordered_map<uint32_t, IceCandidatePairDescription>
|
||||||
|
candidate_pair_desc_by_id_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // LOGGING_RTC_EVENT_LOG_ICELOGGER_H_
|
||||||
@ -41,6 +41,8 @@ message Event {
|
|||||||
BWE_PROBE_CLUSTER_CREATED_EVENT = 17;
|
BWE_PROBE_CLUSTER_CREATED_EVENT = 17;
|
||||||
BWE_PROBE_RESULT_EVENT = 18;
|
BWE_PROBE_RESULT_EVENT = 18;
|
||||||
ALR_STATE_EVENT = 19;
|
ALR_STATE_EVENT = 19;
|
||||||
|
ICE_CANDIDATE_PAIR_CONFIG = 20;
|
||||||
|
ICE_CANDIDATE_PAIR_EVENT = 21;
|
||||||
}
|
}
|
||||||
|
|
||||||
// required - Indicates the type of this event
|
// required - Indicates the type of this event
|
||||||
@ -85,6 +87,12 @@ message Event {
|
|||||||
|
|
||||||
// required if type == ALR_STATE_EVENT
|
// required if type == ALR_STATE_EVENT
|
||||||
AlrState alr_state = 19;
|
AlrState alr_state = 19;
|
||||||
|
|
||||||
|
// required if type == ICE_CANDIDATE_PAIR_CONFIG
|
||||||
|
IceCandidatePairConfig ice_candidate_pair_config = 20;
|
||||||
|
|
||||||
|
// required if type == ICE_CANDIDATE_PAIR_EVENT
|
||||||
|
IceCandidatePairEvent ice_candidate_pair_event = 21;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,3 +331,85 @@ message AlrState {
|
|||||||
// required - If we are in ALR or not.
|
// required - If we are in ALR or not.
|
||||||
optional bool in_alr = 1;
|
optional bool in_alr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message IceCandidatePairConfig {
|
||||||
|
enum IceCandidatePairConfigType {
|
||||||
|
ADDED = 0;
|
||||||
|
UPDATED = 1;
|
||||||
|
DESTROYED = 2;
|
||||||
|
SELECTED = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum IceCandidateType {
|
||||||
|
LOCAL = 0;
|
||||||
|
STUN = 1;
|
||||||
|
PRFLX = 2;
|
||||||
|
RELAY = 3;
|
||||||
|
UNKNOWN_CANDIDATE_TYPE = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Protocol {
|
||||||
|
UDP = 0;
|
||||||
|
TCP = 1;
|
||||||
|
SSLTCP = 2;
|
||||||
|
TLS = 3;
|
||||||
|
UNKNOWN_PROTOCOL = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AddressFamily {
|
||||||
|
IPV4 = 0;
|
||||||
|
IPV6 = 1;
|
||||||
|
UNKNOWN_ADDRESS_FAMILY = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NetworkType {
|
||||||
|
ETHERNET = 0;
|
||||||
|
LOOPBACK = 1;
|
||||||
|
WIFI = 2;
|
||||||
|
VPN = 3;
|
||||||
|
CELLULAR = 4;
|
||||||
|
UNKNOWN_NETWORK_TYPE = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional IceCandidatePairConfigType config_type = 1;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional uint32 candidate_pair_id = 2;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional IceCandidateType local_candidate_type = 3;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional Protocol local_relay_protocol = 4;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional NetworkType local_network_type = 5;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional AddressFamily local_address_family = 6;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional IceCandidateType remote_candidate_type = 7;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional AddressFamily remote_address_family = 8;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional Protocol candidate_pair_protocol = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IceCandidatePairEvent {
|
||||||
|
enum IceCandidatePairEventType {
|
||||||
|
CHECK_SENT = 0;
|
||||||
|
CHECK_RECEIVED = 1;
|
||||||
|
CHECK_RESPONSE_SENT = 2;
|
||||||
|
CHECK_RESPONSE_RECEIVED = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional IceCandidatePairEventType event_type = 1;
|
||||||
|
|
||||||
|
// required
|
||||||
|
optional uint32 candidate_pair_id = 2;
|
||||||
|
}
|
||||||
|
|||||||
@ -166,6 +166,10 @@ std::string EventTypeToString(webrtc::rtclog::Event::EventType event_type) {
|
|||||||
return "BWE_PROBE_RESULT";
|
return "BWE_PROBE_RESULT";
|
||||||
case webrtc::rtclog::Event::ALR_STATE_EVENT:
|
case webrtc::rtclog::Event::ALR_STATE_EVENT:
|
||||||
return "ALR_STATE_EVENT";
|
return "ALR_STATE_EVENT";
|
||||||
|
case webrtc::rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG:
|
||||||
|
return "ICE_CANDIDATE_PAIR_CONFIG";
|
||||||
|
case webrtc::rtclog::Event::ICE_CANDIDATE_PAIR_EVENT:
|
||||||
|
return "ICE_CANDIDATE_PAIR_EVENT";
|
||||||
}
|
}
|
||||||
RTC_NOTREACHED();
|
RTC_NOTREACHED();
|
||||||
return "UNKNOWN_EVENT";
|
return "UNKNOWN_EVENT";
|
||||||
|
|||||||
@ -60,6 +60,7 @@ DEFINE_bool(rtcp, true, "Use --nortcp to exclude RTCP packets.");
|
|||||||
DEFINE_bool(playout, true, "Use --noplayout to exclude audio playout events.");
|
DEFINE_bool(playout, true, "Use --noplayout to exclude audio playout events.");
|
||||||
DEFINE_bool(ana, true, "Use --noana to exclude ANA events.");
|
DEFINE_bool(ana, true, "Use --noana to exclude ANA events.");
|
||||||
DEFINE_bool(probe, true, "Use --noprobe to exclude probe events.");
|
DEFINE_bool(probe, true, "Use --noprobe to exclude probe events.");
|
||||||
|
DEFINE_bool(ice, true, "Use --noice to exclude ICE events.");
|
||||||
|
|
||||||
DEFINE_bool(print_full_packets,
|
DEFINE_bool(print_full_packets,
|
||||||
false,
|
false,
|
||||||
@ -796,6 +797,34 @@ int main(int argc, char* argv[]) {
|
|||||||
event_recognized = true;
|
event_recognized = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case webrtc::ParsedRtcEventLog::ICE_CANDIDATE_PAIR_CONFIG: {
|
||||||
|
if (FLAG_ice) {
|
||||||
|
webrtc::ParsedRtcEventLog::IceCandidatePairConfig ice_cp_config =
|
||||||
|
parsed_stream.GetIceCandidatePairConfig(i);
|
||||||
|
// TODO(qingsi): convert the numeric representation of states to text
|
||||||
|
std::cout << parsed_stream.GetTimestamp(i)
|
||||||
|
<< "\tICE_CANDIDATE_PAIR_CONFIG"
|
||||||
|
<< "\ttype=" << static_cast<int>(ice_cp_config.type)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
event_recognized = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case webrtc::ParsedRtcEventLog::ICE_CANDIDATE_PAIR_EVENT: {
|
||||||
|
if (FLAG_ice) {
|
||||||
|
webrtc::ParsedRtcEventLog::IceCandidatePairEvent ice_cp_event =
|
||||||
|
parsed_stream.GetIceCandidatePairEvent(i);
|
||||||
|
// TODO(qingsi): convert the numeric representation of states to text
|
||||||
|
std::cout << parsed_stream.GetTimestamp(i)
|
||||||
|
<< "\tICE_CANDIDATE_PAIR_EVENT"
|
||||||
|
<< "\ttype=" << static_cast<int>(ice_cp_event.type)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
event_recognized = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!event_recognized) {
|
if (!event_recognized) {
|
||||||
|
|||||||
@ -76,6 +76,10 @@ ParsedRtcEventLog::EventType GetRuntimeEventType(
|
|||||||
return ParsedRtcEventLog::EventType::BWE_PROBE_RESULT_EVENT;
|
return ParsedRtcEventLog::EventType::BWE_PROBE_RESULT_EVENT;
|
||||||
case rtclog::Event::ALR_STATE_EVENT:
|
case rtclog::Event::ALR_STATE_EVENT:
|
||||||
return ParsedRtcEventLog::EventType::ALR_STATE_EVENT;
|
return ParsedRtcEventLog::EventType::ALR_STATE_EVENT;
|
||||||
|
case rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG:
|
||||||
|
return ParsedRtcEventLog::EventType::ICE_CANDIDATE_PAIR_CONFIG;
|
||||||
|
case rtclog::Event::ICE_CANDIDATE_PAIR_EVENT:
|
||||||
|
return ParsedRtcEventLog::EventType::ICE_CANDIDATE_PAIR_EVENT;
|
||||||
}
|
}
|
||||||
return ParsedRtcEventLog::EventType::UNKNOWN_EVENT;
|
return ParsedRtcEventLog::EventType::UNKNOWN_EVENT;
|
||||||
}
|
}
|
||||||
@ -94,6 +98,108 @@ BandwidthUsage GetRuntimeDetectorState(
|
|||||||
return BandwidthUsage::kBwNormal;
|
return BandwidthUsage::kBwNormal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IceCandidatePairEventType GetRuntimeIceCandidatePairConfigType(
|
||||||
|
rtclog::IceCandidatePairConfig::IceCandidatePairConfigType type) {
|
||||||
|
switch (type) {
|
||||||
|
case rtclog::IceCandidatePairConfig::ADDED:
|
||||||
|
return IceCandidatePairEventType::kAdded;
|
||||||
|
case rtclog::IceCandidatePairConfig::UPDATED:
|
||||||
|
return IceCandidatePairEventType::kUpdated;
|
||||||
|
case rtclog::IceCandidatePairConfig::DESTROYED:
|
||||||
|
return IceCandidatePairEventType::kDestroyed;
|
||||||
|
case rtclog::IceCandidatePairConfig::SELECTED:
|
||||||
|
return IceCandidatePairEventType::kSelected;
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return IceCandidatePairEventType::kAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
IceCandidateType GetRuntimeIceCandidateType(
|
||||||
|
rtclog::IceCandidatePairConfig::IceCandidateType type) {
|
||||||
|
switch (type) {
|
||||||
|
case rtclog::IceCandidatePairConfig::LOCAL:
|
||||||
|
return IceCandidateType::kLocal;
|
||||||
|
case rtclog::IceCandidatePairConfig::STUN:
|
||||||
|
return IceCandidateType::kStun;
|
||||||
|
case rtclog::IceCandidatePairConfig::PRFLX:
|
||||||
|
return IceCandidateType::kPrflx;
|
||||||
|
case rtclog::IceCandidatePairConfig::RELAY:
|
||||||
|
return IceCandidateType::kRelay;
|
||||||
|
case rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE:
|
||||||
|
return IceCandidateType::kUnknown;
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return IceCandidateType::kUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol(
|
||||||
|
rtclog::IceCandidatePairConfig::Protocol protocol) {
|
||||||
|
switch (protocol) {
|
||||||
|
case rtclog::IceCandidatePairConfig::UDP:
|
||||||
|
return IceCandidatePairProtocol::kUdp;
|
||||||
|
case rtclog::IceCandidatePairConfig::TCP:
|
||||||
|
return IceCandidatePairProtocol::kTcp;
|
||||||
|
case rtclog::IceCandidatePairConfig::SSLTCP:
|
||||||
|
return IceCandidatePairProtocol::kSsltcp;
|
||||||
|
case rtclog::IceCandidatePairConfig::TLS:
|
||||||
|
return IceCandidatePairProtocol::kTls;
|
||||||
|
case rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL:
|
||||||
|
return IceCandidatePairProtocol::kUnknown;
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return IceCandidatePairProtocol::kUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
IceCandidatePairAddressFamily GetRuntimeIceCandidatePairAddressFamily(
|
||||||
|
rtclog::IceCandidatePairConfig::AddressFamily address_family) {
|
||||||
|
switch (address_family) {
|
||||||
|
case rtclog::IceCandidatePairConfig::IPV4:
|
||||||
|
return IceCandidatePairAddressFamily::kIpv4;
|
||||||
|
case rtclog::IceCandidatePairConfig::IPV6:
|
||||||
|
return IceCandidatePairAddressFamily::kIpv6;
|
||||||
|
case rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY:
|
||||||
|
return IceCandidatePairAddressFamily::kUnknown;
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return IceCandidatePairAddressFamily::kUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
IceCandidateNetworkType GetRuntimeIceCandidateNetworkType(
|
||||||
|
rtclog::IceCandidatePairConfig::NetworkType network_type) {
|
||||||
|
switch (network_type) {
|
||||||
|
case rtclog::IceCandidatePairConfig::ETHERNET:
|
||||||
|
return IceCandidateNetworkType::kEthernet;
|
||||||
|
case rtclog::IceCandidatePairConfig::LOOPBACK:
|
||||||
|
return IceCandidateNetworkType::kLoopback;
|
||||||
|
case rtclog::IceCandidatePairConfig::WIFI:
|
||||||
|
return IceCandidateNetworkType::kWifi;
|
||||||
|
case rtclog::IceCandidatePairConfig::VPN:
|
||||||
|
return IceCandidateNetworkType::kVpn;
|
||||||
|
case rtclog::IceCandidatePairConfig::CELLULAR:
|
||||||
|
return IceCandidateNetworkType::kCellular;
|
||||||
|
case rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE:
|
||||||
|
return IceCandidateNetworkType::kUnknown;
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return IceCandidateNetworkType::kUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
|
||||||
|
rtclog::IceCandidatePairEvent::IceCandidatePairEventType type) {
|
||||||
|
switch (type) {
|
||||||
|
case rtclog::IceCandidatePairEvent::CHECK_SENT:
|
||||||
|
return IceCandidatePairEventType::kCheckSent;
|
||||||
|
case rtclog::IceCandidatePairEvent::CHECK_RECEIVED:
|
||||||
|
return IceCandidatePairEventType::kCheckReceived;
|
||||||
|
case rtclog::IceCandidatePairEvent::CHECK_RESPONSE_SENT:
|
||||||
|
return IceCandidatePairEventType::kCheckResponseSent;
|
||||||
|
case rtclog::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED:
|
||||||
|
return IceCandidatePairEventType::kCheckResponseReceived;
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return IceCandidatePairEventType::kCheckSent;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<uint64_t, bool> ParseVarInt(std::istream& stream) {
|
std::pair<uint64_t, bool> ParseVarInt(std::istream& stream) {
|
||||||
uint64_t varint = 0;
|
uint64_t varint = 0;
|
||||||
for (size_t bytes_read = 0; bytes_read < 10; ++bytes_read) {
|
for (size_t bytes_read = 0; bytes_read < 10; ++bytes_read) {
|
||||||
@ -670,6 +776,61 @@ ParsedRtcEventLog::AlrStateEvent ParsedRtcEventLog::GetAlrState(
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParsedRtcEventLog::IceCandidatePairConfig
|
||||||
|
ParsedRtcEventLog::GetIceCandidatePairConfig(size_t index) const {
|
||||||
|
RTC_CHECK_LT(index, GetNumberOfEvents());
|
||||||
|
const rtclog::Event& rtc_event = events_[index];
|
||||||
|
RTC_CHECK(rtc_event.has_type());
|
||||||
|
RTC_CHECK_EQ(rtc_event.type(), rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG);
|
||||||
|
IceCandidatePairConfig res;
|
||||||
|
const rtclog::IceCandidatePairConfig& config =
|
||||||
|
rtc_event.ice_candidate_pair_config();
|
||||||
|
res.timestamp = GetTimestamp(index);
|
||||||
|
RTC_CHECK(config.has_config_type());
|
||||||
|
res.type = GetRuntimeIceCandidatePairConfigType(config.config_type());
|
||||||
|
RTC_CHECK(config.has_candidate_pair_id());
|
||||||
|
res.candidate_pair_id = config.candidate_pair_id();
|
||||||
|
RTC_CHECK(config.has_local_candidate_type());
|
||||||
|
res.local_candidate_type =
|
||||||
|
GetRuntimeIceCandidateType(config.local_candidate_type());
|
||||||
|
RTC_CHECK(config.has_local_relay_protocol());
|
||||||
|
res.local_relay_protocol =
|
||||||
|
GetRuntimeIceCandidatePairProtocol(config.local_relay_protocol());
|
||||||
|
RTC_CHECK(config.has_local_network_type());
|
||||||
|
res.local_network_type =
|
||||||
|
GetRuntimeIceCandidateNetworkType(config.local_network_type());
|
||||||
|
RTC_CHECK(config.has_local_address_family());
|
||||||
|
res.local_address_family =
|
||||||
|
GetRuntimeIceCandidatePairAddressFamily(config.local_address_family());
|
||||||
|
RTC_CHECK(config.has_remote_candidate_type());
|
||||||
|
res.remote_candidate_type =
|
||||||
|
GetRuntimeIceCandidateType(config.remote_candidate_type());
|
||||||
|
RTC_CHECK(config.has_remote_address_family());
|
||||||
|
res.remote_address_family =
|
||||||
|
GetRuntimeIceCandidatePairAddressFamily(config.remote_address_family());
|
||||||
|
RTC_CHECK(config.has_candidate_pair_protocol());
|
||||||
|
res.candidate_pair_protocol =
|
||||||
|
GetRuntimeIceCandidatePairProtocol(config.candidate_pair_protocol());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParsedRtcEventLog::IceCandidatePairEvent
|
||||||
|
ParsedRtcEventLog::GetIceCandidatePairEvent(size_t index) const {
|
||||||
|
RTC_CHECK_LT(index, GetNumberOfEvents());
|
||||||
|
const rtclog::Event& rtc_event = events_[index];
|
||||||
|
RTC_CHECK(rtc_event.has_type());
|
||||||
|
RTC_CHECK_EQ(rtc_event.type(), rtclog::Event::ICE_CANDIDATE_PAIR_EVENT);
|
||||||
|
IceCandidatePairEvent res;
|
||||||
|
const rtclog::IceCandidatePairEvent& event =
|
||||||
|
rtc_event.ice_candidate_pair_event();
|
||||||
|
res.timestamp = GetTimestamp(index);
|
||||||
|
RTC_CHECK(event.has_event_type());
|
||||||
|
res.type = GetRuntimeIceCandidatePairEventType(event.event_type());
|
||||||
|
RTC_CHECK(event.has_candidate_pair_id());
|
||||||
|
res.candidate_pair_id = event.candidate_pair_id();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the MediaType for registered SSRCs. Search from the end to use last
|
// Returns the MediaType for registered SSRCs. Search from the end to use last
|
||||||
// registered types first.
|
// registered types first.
|
||||||
ParsedRtcEventLog::MediaType ParsedRtcEventLog::GetMediaType(
|
ParsedRtcEventLog::MediaType ParsedRtcEventLog::GetMediaType(
|
||||||
|
|||||||
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include "call/video_receive_stream.h"
|
#include "call/video_receive_stream.h"
|
||||||
#include "call/video_send_stream.h"
|
#include "call/video_send_stream.h"
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
|
||||||
|
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
|
||||||
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
|
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
|
||||||
#include "logging/rtc_event_log/rtc_event_log.h"
|
#include "logging/rtc_event_log/rtc_event_log.h"
|
||||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||||
@ -70,6 +72,25 @@ class ParsedRtcEventLog {
|
|||||||
bool in_alr;
|
bool in_alr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IceCandidatePairConfig {
|
||||||
|
uint64_t timestamp;
|
||||||
|
IceCandidatePairEventType type;
|
||||||
|
uint32_t candidate_pair_id;
|
||||||
|
IceCandidateType local_candidate_type;
|
||||||
|
IceCandidatePairProtocol local_relay_protocol;
|
||||||
|
IceCandidateNetworkType local_network_type;
|
||||||
|
IceCandidatePairAddressFamily local_address_family;
|
||||||
|
IceCandidateType remote_candidate_type;
|
||||||
|
IceCandidatePairAddressFamily remote_address_family;
|
||||||
|
IceCandidatePairProtocol candidate_pair_protocol;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IceCandidatePairEvent {
|
||||||
|
uint64_t timestamp;
|
||||||
|
IceCandidatePairEventType type;
|
||||||
|
uint32_t candidate_pair_id;
|
||||||
|
};
|
||||||
|
|
||||||
enum EventType {
|
enum EventType {
|
||||||
UNKNOWN_EVENT = 0,
|
UNKNOWN_EVENT = 0,
|
||||||
LOG_START = 1,
|
LOG_START = 1,
|
||||||
@ -86,7 +107,9 @@ class ParsedRtcEventLog {
|
|||||||
AUDIO_NETWORK_ADAPTATION_EVENT = 16,
|
AUDIO_NETWORK_ADAPTATION_EVENT = 16,
|
||||||
BWE_PROBE_CLUSTER_CREATED_EVENT = 17,
|
BWE_PROBE_CLUSTER_CREATED_EVENT = 17,
|
||||||
BWE_PROBE_RESULT_EVENT = 18,
|
BWE_PROBE_RESULT_EVENT = 18,
|
||||||
ALR_STATE_EVENT = 19
|
ALR_STATE_EVENT = 19,
|
||||||
|
ICE_CANDIDATE_PAIR_CONFIG = 20,
|
||||||
|
ICE_CANDIDATE_PAIR_EVENT = 21,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MediaType { ANY, AUDIO, VIDEO, DATA };
|
enum class MediaType { ANY, AUDIO, VIDEO, DATA };
|
||||||
@ -188,6 +211,9 @@ class ParsedRtcEventLog {
|
|||||||
|
|
||||||
AlrStateEvent GetAlrState(size_t index) const;
|
AlrStateEvent GetAlrState(size_t index) const;
|
||||||
|
|
||||||
|
IceCandidatePairConfig GetIceCandidatePairConfig(size_t index) const;
|
||||||
|
IceCandidatePairEvent GetIceCandidatePairEvent(size_t index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rtclog::StreamConfig GetVideoReceiveConfig(const rtclog::Event& event) const;
|
rtclog::StreamConfig GetVideoReceiveConfig(const rtclog::Event& event) const;
|
||||||
std::vector<rtclog::StreamConfig> GetVideoSendConfig(
|
std::vector<rtclog::StreamConfig> GetVideoSendConfig(
|
||||||
|
|||||||
@ -62,6 +62,8 @@ namespace plotting {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const int kNumMicrosecsPerSec = 1000000;
|
||||||
|
|
||||||
void SortPacketFeedbackVector(std::vector<PacketFeedback>* vec) {
|
void SortPacketFeedbackVector(std::vector<PacketFeedback>* vec) {
|
||||||
auto pred = [](const PacketFeedback& packet_feedback) {
|
auto pred = [](const PacketFeedback& packet_feedback) {
|
||||||
return packet_feedback.arrival_time_ms == PacketFeedback::kNotReceived;
|
return packet_feedback.arrival_time_ms == PacketFeedback::kNotReceived;
|
||||||
@ -88,9 +90,10 @@ bool MatchingSsrc(uint32_t ssrc, const std::vector<uint32_t>& desired_ssrc) {
|
|||||||
double AbsSendTimeToMicroseconds(int64_t abs_send_time) {
|
double AbsSendTimeToMicroseconds(int64_t abs_send_time) {
|
||||||
// The timestamp is a fixed point representation with 6 bits for seconds
|
// The timestamp is a fixed point representation with 6 bits for seconds
|
||||||
// and 18 bits for fractions of a second. Thus, we divide by 2^18 to get the
|
// and 18 bits for fractions of a second. Thus, we divide by 2^18 to get the
|
||||||
// time in seconds and then multiply by 1000000 to convert to microseconds.
|
// time in seconds and then multiply by kNumMicrosecsPerSec to convert to
|
||||||
|
// microseconds.
|
||||||
static constexpr double kTimestampToMicroSec =
|
static constexpr double kTimestampToMicroSec =
|
||||||
1000000.0 / static_cast<double>(1ul << 18);
|
static_cast<double>(kNumMicrosecsPerSec) / static_cast<double>(1ul << 18);
|
||||||
return abs_send_time * kTimestampToMicroSec;
|
return abs_send_time * kTimestampToMicroSec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +196,9 @@ rtc::Optional<double> NetworkDelayDiff_CaptureTime(
|
|||||||
RTC_LOG(LS_WARNING) << "New capture time " << new_packet.header.timestamp
|
RTC_LOG(LS_WARNING) << "New capture time " << new_packet.header.timestamp
|
||||||
<< ", received time " << new_packet.timestamp;
|
<< ", received time " << new_packet.timestamp;
|
||||||
RTC_LOG(LS_WARNING) << "Receive time difference " << recv_time_diff << " = "
|
RTC_LOG(LS_WARNING) << "Receive time difference " << recv_time_diff << " = "
|
||||||
<< static_cast<double>(recv_time_diff) / 1000000 << "s";
|
<< static_cast<double>(recv_time_diff) /
|
||||||
|
kNumMicrosecsPerSec
|
||||||
|
<< "s";
|
||||||
RTC_LOG(LS_WARNING) << "Send time difference " << send_time_diff << " = "
|
RTC_LOG(LS_WARNING) << "Send time difference " << send_time_diff << " = "
|
||||||
<< static_cast<double>(send_time_diff) /
|
<< static_cast<double>(send_time_diff) /
|
||||||
kVideoSampleRate
|
kVideoSampleRate
|
||||||
@ -211,7 +216,8 @@ void ProcessPoints(
|
|||||||
uint64_t begin_time,
|
uint64_t begin_time,
|
||||||
TimeSeries* result) {
|
TimeSeries* result) {
|
||||||
for (size_t i = 0; i < data.size(); i++) {
|
for (size_t i = 0; i < data.size(); i++) {
|
||||||
float x = static_cast<float>(data[i].timestamp - begin_time) / 1000000;
|
float x = static_cast<float>(data[i].timestamp - begin_time) /
|
||||||
|
kNumMicrosecsPerSec;
|
||||||
rtc::Optional<float> y = get_y(data[i]);
|
rtc::Optional<float> y = get_y(data[i]);
|
||||||
if (y)
|
if (y)
|
||||||
result->points.emplace_back(x, *y);
|
result->points.emplace_back(x, *y);
|
||||||
@ -229,7 +235,8 @@ void ProcessPairs(
|
|||||||
uint64_t begin_time,
|
uint64_t begin_time,
|
||||||
TimeSeries* result) {
|
TimeSeries* result) {
|
||||||
for (size_t i = 1; i < data.size(); i++) {
|
for (size_t i = 1; i < data.size(); i++) {
|
||||||
float x = static_cast<float>(data[i].timestamp - begin_time) / 1000000;
|
float x = static_cast<float>(data[i].timestamp - begin_time) /
|
||||||
|
kNumMicrosecsPerSec;
|
||||||
rtc::Optional<ResultType> y = get_y(data[i - 1], data[i]);
|
rtc::Optional<ResultType> y = get_y(data[i - 1], data[i]);
|
||||||
if (y)
|
if (y)
|
||||||
result->points.emplace_back(x, static_cast<float>(*y));
|
result->points.emplace_back(x, static_cast<float>(*y));
|
||||||
@ -246,7 +253,8 @@ void AccumulatePoints(
|
|||||||
TimeSeries* result) {
|
TimeSeries* result) {
|
||||||
ResultType sum = 0;
|
ResultType sum = 0;
|
||||||
for (size_t i = 0; i < data.size(); i++) {
|
for (size_t i = 0; i < data.size(); i++) {
|
||||||
float x = static_cast<float>(data[i].timestamp - begin_time) / 1000000;
|
float x = static_cast<float>(data[i].timestamp - begin_time) /
|
||||||
|
kNumMicrosecsPerSec;
|
||||||
rtc::Optional<ResultType> y = extract(data[i]);
|
rtc::Optional<ResultType> y = extract(data[i]);
|
||||||
if (y) {
|
if (y) {
|
||||||
sum += *y;
|
sum += *y;
|
||||||
@ -267,7 +275,8 @@ void AccumulatePairs(
|
|||||||
TimeSeries* result) {
|
TimeSeries* result) {
|
||||||
ResultType sum = 0;
|
ResultType sum = 0;
|
||||||
for (size_t i = 1; i < data.size(); i++) {
|
for (size_t i = 1; i < data.size(); i++) {
|
||||||
float x = static_cast<float>(data[i].timestamp - begin_time) / 1000000;
|
float x = static_cast<float>(data[i].timestamp - begin_time) /
|
||||||
|
kNumMicrosecsPerSec;
|
||||||
rtc::Optional<ResultType> y = extract(data[i - 1], data[i]);
|
rtc::Optional<ResultType> y = extract(data[i - 1], data[i]);
|
||||||
if (y)
|
if (y)
|
||||||
sum += *y;
|
sum += *y;
|
||||||
@ -307,13 +316,118 @@ void MovingAverage(
|
|||||||
sum_in_window -= *value;
|
sum_in_window -= *value;
|
||||||
++window_index_begin;
|
++window_index_begin;
|
||||||
}
|
}
|
||||||
float window_duration_s = static_cast<float>(window_duration_us) / 1000000;
|
float window_duration_s =
|
||||||
float x = static_cast<float>(t - begin_time) / 1000000;
|
static_cast<float>(window_duration_us) / kNumMicrosecsPerSec;
|
||||||
|
float x = static_cast<float>(t - begin_time) / kNumMicrosecsPerSec;
|
||||||
float y = sum_in_window / window_duration_s;
|
float y = sum_in_window / window_duration_s;
|
||||||
result->points.emplace_back(x, y);
|
result->points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char kUnknownEnumValue[] = "unknown";
|
||||||
|
|
||||||
|
const char kIceCandidateTypeLocal[] = "local";
|
||||||
|
const char kIceCandidateTypeStun[] = "stun";
|
||||||
|
const char kIceCandidateTypePrflx[] = "prflx";
|
||||||
|
const char kIceCandidateTypeRelay[] = "relay";
|
||||||
|
|
||||||
|
const char kProtocolUdp[] = "udp";
|
||||||
|
const char kProtocolTcp[] = "tcp";
|
||||||
|
const char kProtocolSsltcp[] = "ssltcp";
|
||||||
|
const char kProtocolTls[] = "tls";
|
||||||
|
|
||||||
|
const char kAddressFamilyIpv4[] = "ipv4";
|
||||||
|
const char kAddressFamilyIpv6[] = "ipv6";
|
||||||
|
|
||||||
|
const char kNetworkTypeEthernet[] = "ethernet";
|
||||||
|
const char kNetworkTypeLoopback[] = "loopback";
|
||||||
|
const char kNetworkTypeWifi[] = "wifi";
|
||||||
|
const char kNetworkTypeVpn[] = "vpn";
|
||||||
|
const char kNetworkTypeCellular[] = "cellular";
|
||||||
|
|
||||||
|
std::string GetIceCandidateTypeAsString(webrtc::IceCandidateType type) {
|
||||||
|
switch (type) {
|
||||||
|
case webrtc::IceCandidateType::kLocal:
|
||||||
|
return kIceCandidateTypeLocal;
|
||||||
|
case webrtc::IceCandidateType::kStun:
|
||||||
|
return kIceCandidateTypeStun;
|
||||||
|
case webrtc::IceCandidateType::kPrflx:
|
||||||
|
return kIceCandidateTypePrflx;
|
||||||
|
case webrtc::IceCandidateType::kRelay:
|
||||||
|
return kIceCandidateTypeRelay;
|
||||||
|
default:
|
||||||
|
return kUnknownEnumValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetProtocolAsString(webrtc::IceCandidatePairProtocol protocol) {
|
||||||
|
switch (protocol) {
|
||||||
|
case webrtc::IceCandidatePairProtocol::kUdp:
|
||||||
|
return kProtocolUdp;
|
||||||
|
case webrtc::IceCandidatePairProtocol::kTcp:
|
||||||
|
return kProtocolTcp;
|
||||||
|
case webrtc::IceCandidatePairProtocol::kSsltcp:
|
||||||
|
return kProtocolSsltcp;
|
||||||
|
case webrtc::IceCandidatePairProtocol::kTls:
|
||||||
|
return kProtocolTls;
|
||||||
|
default:
|
||||||
|
return kUnknownEnumValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetAddressFamilyAsString(
|
||||||
|
webrtc::IceCandidatePairAddressFamily family) {
|
||||||
|
switch (family) {
|
||||||
|
case webrtc::IceCandidatePairAddressFamily::kIpv4:
|
||||||
|
return kAddressFamilyIpv4;
|
||||||
|
case webrtc::IceCandidatePairAddressFamily::kIpv6:
|
||||||
|
return kAddressFamilyIpv6;
|
||||||
|
default:
|
||||||
|
return kUnknownEnumValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetNetworkTypeAsString(webrtc::IceCandidateNetworkType type) {
|
||||||
|
switch (type) {
|
||||||
|
case webrtc::IceCandidateNetworkType::kEthernet:
|
||||||
|
return kNetworkTypeEthernet;
|
||||||
|
case webrtc::IceCandidateNetworkType::kLoopback:
|
||||||
|
return kNetworkTypeLoopback;
|
||||||
|
case webrtc::IceCandidateNetworkType::kWifi:
|
||||||
|
return kNetworkTypeWifi;
|
||||||
|
case webrtc::IceCandidateNetworkType::kVpn:
|
||||||
|
return kNetworkTypeVpn;
|
||||||
|
case webrtc::IceCandidateNetworkType::kCellular:
|
||||||
|
return kNetworkTypeCellular;
|
||||||
|
default:
|
||||||
|
return kUnknownEnumValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetCandidatePairLogDescriptionAsString(
|
||||||
|
const ParsedRtcEventLog::IceCandidatePairConfig& config) {
|
||||||
|
// Example: stun:wifi->relay(tcp):cellular@udp:ipv4
|
||||||
|
// represents a pair of a local server-reflexive candidate on a WiFi network
|
||||||
|
// and a remote relay candidate using TCP as the relay protocol on a cell
|
||||||
|
// network, when the candidate pair communicates over UDP using IPv4.
|
||||||
|
std::stringstream ss;
|
||||||
|
std::string local_candidate_type =
|
||||||
|
GetIceCandidateTypeAsString(config.local_candidate_type);
|
||||||
|
std::string remote_candidate_type =
|
||||||
|
GetIceCandidateTypeAsString(config.remote_candidate_type);
|
||||||
|
if (config.local_candidate_type == webrtc::IceCandidateType::kRelay) {
|
||||||
|
local_candidate_type +=
|
||||||
|
"(" + GetProtocolAsString(config.local_relay_protocol) + ")";
|
||||||
|
}
|
||||||
|
ss << local_candidate_type << ":"
|
||||||
|
<< GetNetworkTypeAsString(config.local_network_type) << ":"
|
||||||
|
<< GetAddressFamilyAsString(config.local_address_family) << "->"
|
||||||
|
<< remote_candidate_type << ":"
|
||||||
|
<< GetAddressFamilyAsString(config.remote_address_family) << "@"
|
||||||
|
<< GetProtocolAsString(config.candidate_pair_protocol);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
|
EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
|
||||||
@ -526,6 +640,16 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
|
|||||||
alr_state_events_.push_back(parsed_log_.GetAlrState(i));
|
alr_state_events_.push_back(parsed_log_.GetAlrState(i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ParsedRtcEventLog::ICE_CANDIDATE_PAIR_CONFIG: {
|
||||||
|
ice_candidate_pair_configs_.push_back(
|
||||||
|
parsed_log_.GetIceCandidatePairConfig(i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ParsedRtcEventLog::ICE_CANDIDATE_PAIR_EVENT: {
|
||||||
|
ice_candidate_pair_events_.push_back(
|
||||||
|
parsed_log_.GetIceCandidatePairEvent(i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ParsedRtcEventLog::UNKNOWN_EVENT: {
|
case ParsedRtcEventLog::UNKNOWN_EVENT: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -538,7 +662,7 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
|
|||||||
}
|
}
|
||||||
begin_time_ = first_timestamp;
|
begin_time_ = first_timestamp;
|
||||||
end_time_ = last_timestamp;
|
end_time_ = last_timestamp;
|
||||||
call_duration_s_ = static_cast<float>(end_time_ - begin_time_) / 1000000;
|
call_duration_s_ = ToCallTime(end_time_);
|
||||||
if (last_log_start) {
|
if (last_log_start) {
|
||||||
// The log was missing the last LOG_END event. Fake it.
|
// The log was missing the last LOG_END event. Fake it.
|
||||||
log_segments_.push_back(std::make_pair(*last_log_start, end_time_));
|
log_segments_.push_back(std::make_pair(*last_log_start, end_time_));
|
||||||
@ -625,7 +749,7 @@ rtc::Optional<uint32_t> EventLogAnalyzer::EstimateRtpClockFrequency(
|
|||||||
last_rtp_timestamp = unwrapper.Unwrap(packets[i].header.timestamp);
|
last_rtp_timestamp = unwrapper.Unwrap(packets[i].header.timestamp);
|
||||||
last_log_timestamp = packets[i].timestamp;
|
last_log_timestamp = packets[i].timestamp;
|
||||||
}
|
}
|
||||||
if (last_log_timestamp - first_log_timestamp < 1000000) {
|
if (last_log_timestamp - first_log_timestamp < kNumMicrosecsPerSec) {
|
||||||
RTC_LOG(LS_WARNING)
|
RTC_LOG(LS_WARNING)
|
||||||
<< "Failed to estimate RTP clock frequency: Stream too short. ("
|
<< "Failed to estimate RTP clock frequency: Stream too short. ("
|
||||||
<< packets.size() << " packets, "
|
<< packets.size() << " packets, "
|
||||||
@ -633,7 +757,8 @@ rtc::Optional<uint32_t> EventLogAnalyzer::EstimateRtpClockFrequency(
|
|||||||
return rtc::nullopt;
|
return rtc::nullopt;
|
||||||
}
|
}
|
||||||
double duration =
|
double duration =
|
||||||
static_cast<double>(last_log_timestamp - first_log_timestamp) / 1000000;
|
static_cast<double>(last_log_timestamp - first_log_timestamp) /
|
||||||
|
kNumMicrosecsPerSec;
|
||||||
double estimated_frequency =
|
double estimated_frequency =
|
||||||
(last_rtp_timestamp - first_rtp_timestamp) / duration;
|
(last_rtp_timestamp - first_rtp_timestamp) / duration;
|
||||||
for (uint32_t f : {8000, 16000, 32000, 48000, 90000}) {
|
for (uint32_t f : {8000, 16000, 32000, 48000, 90000}) {
|
||||||
@ -648,7 +773,7 @@ rtc::Optional<uint32_t> EventLogAnalyzer::EstimateRtpClockFrequency(
|
|||||||
}
|
}
|
||||||
|
|
||||||
float EventLogAnalyzer::ToCallTime(int64_t timestamp) const {
|
float EventLogAnalyzer::ToCallTime(int64_t timestamp) const {
|
||||||
return static_cast<float>(timestamp - begin_time_) / 1000000;
|
return static_cast<float>(timestamp - begin_time_) / kNumMicrosecsPerSec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction,
|
void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction,
|
||||||
@ -699,8 +824,7 @@ void EventLogAnalyzer::CreateAccumulatedPacketsTimeSeries(
|
|||||||
std::string label = label_prefix + " " + GetStreamName(stream_id);
|
std::string label = label_prefix + " " + GetStreamName(stream_id);
|
||||||
TimeSeries time_series(label, LineStyle::kStep);
|
TimeSeries time_series(label, LineStyle::kStep);
|
||||||
for (size_t i = 0; i < packet_stream.size(); i++) {
|
for (size_t i = 0; i < packet_stream.size(); i++) {
|
||||||
float x = static_cast<float>(packet_stream[i].timestamp - begin_time_) /
|
float x = ToCallTime(packet_stream[i].timestamp);
|
||||||
1000000;
|
|
||||||
time_series.points.emplace_back(x, i + 1);
|
time_series.points.emplace_back(x, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -738,7 +862,7 @@ void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) {
|
|||||||
parsed_log_.GetAudioPlayout(i, &ssrc);
|
parsed_log_.GetAudioPlayout(i, &ssrc);
|
||||||
uint64_t timestamp = parsed_log_.GetTimestamp(i);
|
uint64_t timestamp = parsed_log_.GetTimestamp(i);
|
||||||
if (MatchingSsrc(ssrc, desired_ssrc_)) {
|
if (MatchingSsrc(ssrc, desired_ssrc_)) {
|
||||||
float x = static_cast<float>(timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(timestamp);
|
||||||
float y = static_cast<float>(timestamp - last_playout[ssrc]) / 1000;
|
float y = static_cast<float>(timestamp - last_playout[ssrc]) / 1000;
|
||||||
if (time_series[ssrc].points.size() == 0) {
|
if (time_series[ssrc].points.size() == 0) {
|
||||||
// There were no previusly logged playout for this SSRC.
|
// There were no previusly logged playout for this SSRC.
|
||||||
@ -776,7 +900,7 @@ void EventLogAnalyzer::CreateAudioLevelGraph(Plot* plot) {
|
|||||||
// streams. Tracking bug: webrtc:6399
|
// streams. Tracking bug: webrtc:6399
|
||||||
for (auto& packet : packet_stream) {
|
for (auto& packet : packet_stream) {
|
||||||
if (packet.header.extension.hasAudioLevel) {
|
if (packet.header.extension.hasAudioLevel) {
|
||||||
float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(packet.timestamp);
|
||||||
// The audio level is stored in -dBov (so e.g. -10 dBov is stored as 10)
|
// The audio level is stored in -dBov (so e.g. -10 dBov is stored as 10)
|
||||||
// Here we convert it to dBov.
|
// Here we convert it to dBov.
|
||||||
float y = static_cast<float>(-packet.header.extension.audioLevel);
|
float y = static_cast<float>(-packet.header.extension.audioLevel);
|
||||||
@ -867,7 +991,7 @@ void EventLogAnalyzer::CreateIncomingPacketLossGraph(Plot* plot) {
|
|||||||
std::max(highest_prior_seq_number, sequence_number);
|
std::max(highest_prior_seq_number, sequence_number);
|
||||||
++window_index_begin;
|
++window_index_begin;
|
||||||
}
|
}
|
||||||
float x = static_cast<float>(t - begin_time_) / 1000000;
|
float x = ToCallTime(t);
|
||||||
int64_t expected_packets = highest_seq_number - highest_prior_seq_number;
|
int64_t expected_packets = highest_seq_number - highest_prior_seq_number;
|
||||||
if (expected_packets > 0) {
|
if (expected_packets > 0) {
|
||||||
int64_t received_packets = window_index_end - window_index_begin;
|
int64_t received_packets = window_index_end - window_index_begin;
|
||||||
@ -956,7 +1080,7 @@ void EventLogAnalyzer::CreateFractionLossGraph(Plot* plot) {
|
|||||||
TimeSeries time_series("Fraction lost", LineStyle::kLine,
|
TimeSeries time_series("Fraction lost", LineStyle::kLine,
|
||||||
PointStyle::kHighlight);
|
PointStyle::kHighlight);
|
||||||
for (auto& bwe_update : bwe_loss_updates_) {
|
for (auto& bwe_update : bwe_loss_updates_) {
|
||||||
float x = static_cast<float>(bwe_update.timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(bwe_update.timestamp);
|
||||||
float y = static_cast<float>(bwe_update.fraction_loss) / 255 * 100;
|
float y = static_cast<float>(bwe_update.fraction_loss) / 255 * 100;
|
||||||
time_series.points.emplace_back(x, y);
|
time_series.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1016,8 +1140,8 @@ void EventLogAnalyzer::CreateTotalBitrateGraph(
|
|||||||
++window_index_begin;
|
++window_index_begin;
|
||||||
}
|
}
|
||||||
float window_duration_in_seconds =
|
float window_duration_in_seconds =
|
||||||
static_cast<float>(window_duration_) / 1000000;
|
static_cast<float>(window_duration_) / kNumMicrosecsPerSec;
|
||||||
float x = static_cast<float>(time - begin_time_) / 1000000;
|
float x = ToCallTime(time);
|
||||||
float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
|
float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
|
||||||
bitrate_series.points.emplace_back(x, y);
|
bitrate_series.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1027,8 +1151,7 @@ void EventLogAnalyzer::CreateTotalBitrateGraph(
|
|||||||
if (desired_direction == kOutgoingPacket) {
|
if (desired_direction == kOutgoingPacket) {
|
||||||
TimeSeries loss_series("Loss-based estimate", LineStyle::kStep);
|
TimeSeries loss_series("Loss-based estimate", LineStyle::kStep);
|
||||||
for (auto& loss_update : bwe_loss_updates_) {
|
for (auto& loss_update : bwe_loss_updates_) {
|
||||||
float x =
|
float x = ToCallTime(loss_update.timestamp);
|
||||||
static_cast<float>(loss_update.timestamp - begin_time_) / 1000000;
|
|
||||||
float y = static_cast<float>(loss_update.new_bitrate) / 1000;
|
float y = static_cast<float>(loss_update.new_bitrate) / 1000;
|
||||||
loss_series.points.emplace_back(x, y);
|
loss_series.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1046,8 +1169,7 @@ void EventLogAnalyzer::CreateTotalBitrateGraph(
|
|||||||
BandwidthUsage last_detector_state = BandwidthUsage::kBwNormal;
|
BandwidthUsage last_detector_state = BandwidthUsage::kBwNormal;
|
||||||
|
|
||||||
for (auto& delay_update : bwe_delay_updates_) {
|
for (auto& delay_update : bwe_delay_updates_) {
|
||||||
float x =
|
float x = ToCallTime(delay_update.timestamp);
|
||||||
static_cast<float>(delay_update.timestamp - begin_time_) / 1000000;
|
|
||||||
float y = static_cast<float>(delay_update.bitrate_bps) / 1000;
|
float y = static_cast<float>(delay_update.bitrate_bps) / 1000;
|
||||||
|
|
||||||
if (last_detector_state != delay_update.detector_state) {
|
if (last_detector_state != delay_update.detector_state) {
|
||||||
@ -1079,7 +1201,7 @@ void EventLogAnalyzer::CreateTotalBitrateGraph(
|
|||||||
TimeSeries created_series("Probe cluster created.", LineStyle::kNone,
|
TimeSeries created_series("Probe cluster created.", LineStyle::kNone,
|
||||||
PointStyle::kHighlight);
|
PointStyle::kHighlight);
|
||||||
for (auto& cluster : bwe_probe_cluster_created_events_) {
|
for (auto& cluster : bwe_probe_cluster_created_events_) {
|
||||||
float x = static_cast<float>(cluster.timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(cluster.timestamp);
|
||||||
float y = static_cast<float>(cluster.bitrate_bps) / 1000;
|
float y = static_cast<float>(cluster.bitrate_bps) / 1000;
|
||||||
created_series.points.emplace_back(x, y);
|
created_series.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1088,7 +1210,7 @@ void EventLogAnalyzer::CreateTotalBitrateGraph(
|
|||||||
PointStyle::kHighlight);
|
PointStyle::kHighlight);
|
||||||
for (auto& result : bwe_probe_result_events_) {
|
for (auto& result : bwe_probe_result_events_) {
|
||||||
if (result.bitrate_bps) {
|
if (result.bitrate_bps) {
|
||||||
float x = static_cast<float>(result.timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(result.timestamp);
|
||||||
float y = static_cast<float>(*result.bitrate_bps) / 1000;
|
float y = static_cast<float>(*result.bitrate_bps) / 1000;
|
||||||
result_series.points.emplace_back(x, y);
|
result_series.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1150,7 +1272,7 @@ void EventLogAnalyzer::CreateTotalBitrateGraph(
|
|||||||
for (const auto& kv : remb_packets) {
|
for (const auto& kv : remb_packets) {
|
||||||
const LoggedRtcpPacket* const rtcp = kv.second;
|
const LoggedRtcpPacket* const rtcp = kv.second;
|
||||||
const rtcp::Remb* const remb = static_cast<rtcp::Remb*>(rtcp->packet.get());
|
const rtcp::Remb* const remb = static_cast<rtcp::Remb*>(rtcp->packet.get());
|
||||||
float x = static_cast<float>(rtcp->timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(rtcp->timestamp);
|
||||||
float y = static_cast<float>(remb->bitrate_bps()) / 1000;
|
float y = static_cast<float>(remb->bitrate_bps()) / 1000;
|
||||||
remb_series.points.emplace_back(x, y);
|
remb_series.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1290,8 +1412,7 @@ void EventLogAnalyzer::CreateSendSideBweSimulationGraph(Plot* plot) {
|
|||||||
acked_bitrate.Update(packet.payload_size, packet.arrival_time_ms);
|
acked_bitrate.Update(packet.payload_size, packet.arrival_time_ms);
|
||||||
bitrate_bps = acked_bitrate.Rate(feedback.back().arrival_time_ms);
|
bitrate_bps = acked_bitrate.Rate(feedback.back().arrival_time_ms);
|
||||||
}
|
}
|
||||||
float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) /
|
float x = ToCallTime(clock.TimeInMicroseconds());
|
||||||
1000000;
|
|
||||||
float y = bitrate_bps.value_or(0) / 1000;
|
float y = bitrate_bps.value_or(0) / 1000;
|
||||||
acked_time_series.points.emplace_back(x, y);
|
acked_time_series.points.emplace_back(x, y);
|
||||||
#if !(BWE_TEST_LOGGING_COMPILE_TIME_ENABLE)
|
#if !(BWE_TEST_LOGGING_COMPILE_TIME_ENABLE)
|
||||||
@ -1322,8 +1443,7 @@ void EventLogAnalyzer::CreateSendSideBweSimulationGraph(Plot* plot) {
|
|||||||
if (observer.GetAndResetBitrateUpdated() ||
|
if (observer.GetAndResetBitrateUpdated() ||
|
||||||
time_us - last_update_us >= 1e6) {
|
time_us - last_update_us >= 1e6) {
|
||||||
uint32_t y = observer.last_bitrate_bps() / 1000;
|
uint32_t y = observer.last_bitrate_bps() / 1000;
|
||||||
float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) /
|
float x = ToCallTime(clock.TimeInMicroseconds());
|
||||||
1000000;
|
|
||||||
time_series.points.emplace_back(x, y);
|
time_series.points.emplace_back(x, y);
|
||||||
last_update_us = time_us;
|
last_update_us = time_us;
|
||||||
}
|
}
|
||||||
@ -1396,15 +1516,13 @@ void EventLogAnalyzer::CreateReceiveSideBweSimulationGraph(Plot* plot) {
|
|||||||
rtc::Optional<uint32_t> bitrate_bps = acked_bitrate.Rate(arrival_time_ms);
|
rtc::Optional<uint32_t> bitrate_bps = acked_bitrate.Rate(arrival_time_ms);
|
||||||
if (bitrate_bps) {
|
if (bitrate_bps) {
|
||||||
uint32_t y = *bitrate_bps / 1000;
|
uint32_t y = *bitrate_bps / 1000;
|
||||||
float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) /
|
float x = ToCallTime(clock.TimeInMicroseconds());
|
||||||
1000000;
|
|
||||||
acked_time_series.points.emplace_back(x, y);
|
acked_time_series.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
if (packet_router.GetAndResetBitrateUpdated() ||
|
if (packet_router.GetAndResetBitrateUpdated() ||
|
||||||
clock.TimeInMicroseconds() - last_update_us >= 1e6) {
|
clock.TimeInMicroseconds() - last_update_us >= 1e6) {
|
||||||
uint32_t y = packet_router.last_bitrate_bps() / 1000;
|
uint32_t y = packet_router.last_bitrate_bps() / 1000;
|
||||||
float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) /
|
float x = ToCallTime(clock.TimeInMicroseconds());
|
||||||
1000000;
|
|
||||||
time_series.points.emplace_back(x, y);
|
time_series.points.emplace_back(x, y);
|
||||||
last_update_us = clock.TimeInMicroseconds();
|
last_update_us = clock.TimeInMicroseconds();
|
||||||
}
|
}
|
||||||
@ -1475,9 +1593,7 @@ void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) {
|
|||||||
feedback_adapter.GetTransportFeedbackVector();
|
feedback_adapter.GetTransportFeedbackVector();
|
||||||
SortPacketFeedbackVector(&feedback);
|
SortPacketFeedbackVector(&feedback);
|
||||||
for (const PacketFeedback& packet : feedback) {
|
for (const PacketFeedback& packet : feedback) {
|
||||||
float x =
|
float x = ToCallTime(clock.TimeInMicroseconds());
|
||||||
static_cast<float>(clock.TimeInMicroseconds() - begin_time_) /
|
|
||||||
1000000;
|
|
||||||
if (packet.send_time_ms == PacketFeedback::kNoSendTime) {
|
if (packet.send_time_ms == PacketFeedback::kNoSendTime) {
|
||||||
late_feedback_series.points.emplace_back(x, prev_y);
|
late_feedback_series.points.emplace_back(x, prev_y);
|
||||||
continue;
|
continue;
|
||||||
@ -1587,7 +1703,7 @@ void EventLogAnalyzer::CreatePacerDelayGraph(Plot* plot) {
|
|||||||
*estimated_frequency * 1000;
|
*estimated_frequency * 1000;
|
||||||
double send_time_ms =
|
double send_time_ms =
|
||||||
static_cast<double>(packet.timestamp - first_send_timestamp) / 1000;
|
static_cast<double>(packet.timestamp - first_send_timestamp) / 1000;
|
||||||
float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(packet.timestamp);
|
||||||
float y = send_time_ms - capture_time_ms;
|
float y = send_time_ms - capture_time_ms;
|
||||||
pacer_delay_series.points.emplace_back(x, y);
|
pacer_delay_series.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1609,7 +1725,7 @@ void EventLogAnalyzer::CreateTimestampGraph(Plot* plot) {
|
|||||||
TimeSeries timestamp_data(GetStreamName(stream_id) + " capture-time",
|
TimeSeries timestamp_data(GetStreamName(stream_id) + " capture-time",
|
||||||
LineStyle::kLine, PointStyle::kHighlight);
|
LineStyle::kLine, PointStyle::kHighlight);
|
||||||
for (LoggedRtpPacket packet : rtp_packets) {
|
for (LoggedRtpPacket packet : rtp_packets) {
|
||||||
float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(packet.timestamp);
|
||||||
float y = packet.header.timestamp;
|
float y = packet.header.timestamp;
|
||||||
timestamp_data.points.emplace_back(x, y);
|
timestamp_data.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1628,7 +1744,7 @@ void EventLogAnalyzer::CreateTimestampGraph(Plot* plot) {
|
|||||||
continue;
|
continue;
|
||||||
rtcp::SenderReport* sr;
|
rtcp::SenderReport* sr;
|
||||||
sr = static_cast<rtcp::SenderReport*>(rtcp.packet.get());
|
sr = static_cast<rtcp::SenderReport*>(rtcp.packet.get());
|
||||||
float x = static_cast<float>(rtcp.timestamp - begin_time_) / 1000000;
|
float x = ToCallTime(rtcp.timestamp);
|
||||||
float y = sr->rtp_timestamp();
|
float y = sr->rtp_timestamp();
|
||||||
timestamp_data.points.emplace_back(x, y);
|
timestamp_data.points.emplace_back(x, y);
|
||||||
}
|
}
|
||||||
@ -1986,6 +2102,81 @@ void EventLogAnalyzer::CreateAudioJitterBufferGraph(
|
|||||||
plot->SetTitle("NetEq timing");
|
plot->SetTitle("NetEq timing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventLogAnalyzer::CreateIceCandidatePairConfigGraph(Plot* plot) {
|
||||||
|
std::map<uint32_t, TimeSeries> configs_by_cp_id;
|
||||||
|
for (const auto& config : ice_candidate_pair_configs_) {
|
||||||
|
if (configs_by_cp_id.find(config.candidate_pair_id) ==
|
||||||
|
configs_by_cp_id.end()) {
|
||||||
|
const std::string candidate_pair_desc =
|
||||||
|
GetCandidatePairLogDescriptionAsString(config);
|
||||||
|
configs_by_cp_id[config.candidate_pair_id] = TimeSeries(
|
||||||
|
candidate_pair_desc, LineStyle::kNone, PointStyle::kHighlight);
|
||||||
|
candidate_pair_desc_by_id_[config.candidate_pair_id] =
|
||||||
|
candidate_pair_desc;
|
||||||
|
}
|
||||||
|
float x = ToCallTime(config.timestamp);
|
||||||
|
float y = static_cast<float>(config.type);
|
||||||
|
configs_by_cp_id[config.candidate_pair_id].points.emplace_back(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(qingsi): There can be a large number of candidate pairs generated by
|
||||||
|
// certain calls and the frontend cannot render the chart in this case due to
|
||||||
|
// the failure of generating a palette with the same number of colors.
|
||||||
|
for (auto& kv : configs_by_cp_id) {
|
||||||
|
plot->AppendTimeSeries(std::move(kv.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
|
||||||
|
plot->SetSuggestedYAxis(0, 3, "Numeric Config Type", kBottomMargin,
|
||||||
|
kTopMargin);
|
||||||
|
plot->SetTitle("[IceEventLog] ICE candidate pair configs");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string EventLogAnalyzer::GetCandidatePairLogDescriptionFromId(
|
||||||
|
uint32_t candidate_pair_id) {
|
||||||
|
if (candidate_pair_desc_by_id_.find(candidate_pair_id) !=
|
||||||
|
candidate_pair_desc_by_id_.end()) {
|
||||||
|
return candidate_pair_desc_by_id_[candidate_pair_id];
|
||||||
|
}
|
||||||
|
for (const auto& config : ice_candidate_pair_configs_) {
|
||||||
|
// TODO(qingsi): Add the handling of the "Updated" config event after the
|
||||||
|
// visualization of property change for candidate pairs is introduced.
|
||||||
|
if (candidate_pair_desc_by_id_.find(config.candidate_pair_id) ==
|
||||||
|
candidate_pair_desc_by_id_.end()) {
|
||||||
|
const std::string candidate_pair_desc =
|
||||||
|
GetCandidatePairLogDescriptionAsString(config);
|
||||||
|
candidate_pair_desc_by_id_[config.candidate_pair_id] =
|
||||||
|
candidate_pair_desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return candidate_pair_desc_by_id_[candidate_pair_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLogAnalyzer::CreateIceConnectivityCheckGraph(Plot* plot) {
|
||||||
|
std::map<uint32_t, TimeSeries> checks_by_cp_id;
|
||||||
|
for (const auto& event : ice_candidate_pair_events_) {
|
||||||
|
if (checks_by_cp_id.find(event.candidate_pair_id) ==
|
||||||
|
checks_by_cp_id.end()) {
|
||||||
|
checks_by_cp_id[event.candidate_pair_id] = TimeSeries(
|
||||||
|
GetCandidatePairLogDescriptionFromId(event.candidate_pair_id),
|
||||||
|
LineStyle::kNone, PointStyle::kHighlight);
|
||||||
|
}
|
||||||
|
float x = ToCallTime(event.timestamp);
|
||||||
|
float y = static_cast<float>(event.type);
|
||||||
|
checks_by_cp_id[event.candidate_pair_id].points.emplace_back(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(qingsi): The same issue as in CreateIceCandidatePairConfigGraph.
|
||||||
|
for (auto& kv : checks_by_cp_id) {
|
||||||
|
plot->AppendTimeSeries(std::move(kv.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
|
||||||
|
plot->SetSuggestedYAxis(0, 4, "Numeric Connectivity State", kBottomMargin,
|
||||||
|
kTopMargin);
|
||||||
|
plot->SetTitle("[IceEventLog] ICE connectivity checks");
|
||||||
|
}
|
||||||
|
|
||||||
void EventLogAnalyzer::Notification(
|
void EventLogAnalyzer::Notification(
|
||||||
std::unique_ptr<TriageNotification> notification) {
|
std::unique_ptr<TriageNotification> notification) {
|
||||||
notifications_.push_back(std::move(notification));
|
notifications_.push_back(std::move(notification));
|
||||||
|
|||||||
@ -109,6 +109,9 @@ class EventLogAnalyzer {
|
|||||||
int file_sample_rate_hz,
|
int file_sample_rate_hz,
|
||||||
Plot* plot);
|
Plot* plot);
|
||||||
|
|
||||||
|
void CreateIceCandidatePairConfigGraph(Plot* plot);
|
||||||
|
void CreateIceConnectivityCheckGraph(Plot* plot);
|
||||||
|
|
||||||
// Returns a vector of capture and arrival timestamps for the video frames
|
// Returns a vector of capture and arrival timestamps for the video frames
|
||||||
// of the stream with the most number of frames.
|
// of the stream with the most number of frames.
|
||||||
std::vector<std::pair<int64_t, int64_t>> GetFrameTimestamps() const;
|
std::vector<std::pair<int64_t, int64_t>> GetFrameTimestamps() const;
|
||||||
@ -159,6 +162,8 @@ class EventLogAnalyzer {
|
|||||||
|
|
||||||
void Notification(std::unique_ptr<TriageNotification> notification);
|
void Notification(std::unique_ptr<TriageNotification> notification);
|
||||||
|
|
||||||
|
std::string GetCandidatePairLogDescriptionFromId(uint32_t candidate_pair_id);
|
||||||
|
|
||||||
const ParsedRtcEventLog& parsed_log_;
|
const ParsedRtcEventLog& parsed_log_;
|
||||||
|
|
||||||
// A list of SSRCs we are interested in analysing.
|
// A list of SSRCs we are interested in analysing.
|
||||||
@ -204,6 +209,14 @@ class EventLogAnalyzer {
|
|||||||
|
|
||||||
std::vector<ParsedRtcEventLog::AlrStateEvent> alr_state_events_;
|
std::vector<ParsedRtcEventLog::AlrStateEvent> alr_state_events_;
|
||||||
|
|
||||||
|
std::vector<ParsedRtcEventLog::IceCandidatePairConfig>
|
||||||
|
ice_candidate_pair_configs_;
|
||||||
|
|
||||||
|
std::vector<ParsedRtcEventLog::IceCandidatePairEvent>
|
||||||
|
ice_candidate_pair_events_;
|
||||||
|
|
||||||
|
std::map<uint32_t, std::string> candidate_pair_desc_by_id_;
|
||||||
|
|
||||||
// Window and step size used for calculating moving averages, e.g. bitrate.
|
// Window and step size used for calculating moving averages, e.g. bitrate.
|
||||||
// The generated data points will be |step_| microseconds apart.
|
// The generated data points will be |step_| microseconds apart.
|
||||||
// Only events occuring at most |window_duration_| microseconds before the
|
// Only events occuring at most |window_duration_| microseconds before the
|
||||||
|
|||||||
@ -115,6 +115,12 @@ DEFINE_bool(plot_audio_encoder_num_channels,
|
|||||||
DEFINE_bool(plot_audio_jitter_buffer,
|
DEFINE_bool(plot_audio_jitter_buffer,
|
||||||
false,
|
false,
|
||||||
"Plot the audio jitter buffer delay profile.");
|
"Plot the audio jitter buffer delay profile.");
|
||||||
|
DEFINE_bool(plot_ice_candidate_pair_config,
|
||||||
|
false,
|
||||||
|
"Plot the ICE candidate pair config events.");
|
||||||
|
DEFINE_bool(plot_ice_connectivity_check,
|
||||||
|
false,
|
||||||
|
"Plot the ICE candidate pair connectivity checks.");
|
||||||
|
|
||||||
DEFINE_string(
|
DEFINE_string(
|
||||||
force_fieldtrials,
|
force_fieldtrials,
|
||||||
@ -318,6 +324,13 @@ int main(int argc, char* argv[]) {
|
|||||||
collection->AppendNewPlot());
|
collection->AppendNewPlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FLAG_plot_ice_candidate_pair_config) {
|
||||||
|
analyzer.CreateIceCandidatePairConfigGraph(collection->AppendNewPlot());
|
||||||
|
}
|
||||||
|
if (FLAG_plot_ice_connectivity_check) {
|
||||||
|
analyzer.CreateIceConnectivityCheckGraph(collection->AppendNewPlot());
|
||||||
|
}
|
||||||
|
|
||||||
collection->Draw();
|
collection->Draw();
|
||||||
|
|
||||||
if (FLAG_print_triage_notifications) {
|
if (FLAG_print_triage_notifications) {
|
||||||
@ -356,4 +369,6 @@ void SetAllPlotFlags(bool setting) {
|
|||||||
FLAG_plot_audio_encoder_dtx = setting;
|
FLAG_plot_audio_encoder_dtx = setting;
|
||||||
FLAG_plot_audio_encoder_num_channels = setting;
|
FLAG_plot_audio_encoder_num_channels = setting;
|
||||||
FLAG_plot_audio_jitter_buffer = setting;
|
FLAG_plot_audio_jitter_buffer = setting;
|
||||||
|
FLAG_plot_ice_candidate_pair_config = setting;
|
||||||
|
FLAG_plot_ice_connectivity_check = setting;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user