mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00

Bug: b/318801494 Change-Id: Ie063ac3a63276f5fbc14794b6aba8e7b839cc910 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338740 Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Commit-Queue: Björn Terelius <terelius@webrtc.org> Cr-Commit-Position: refs/heads/main@{#41705}
947 lines
33 KiB
C++
947 lines
33 KiB
C++
/*
|
|
* Copyright 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_RTC_EVENT_LOG_PARSER_H_
|
|
#define LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_PARSER_H_
|
|
|
|
#include <iterator>
|
|
#include <limits>
|
|
#include <map>
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "absl/base/attributes.h"
|
|
#include "absl/strings/string_view.h"
|
|
#include "api/rtc_event_log/rtc_event_log.h"
|
|
#include "call/video_receive_stream.h"
|
|
#include "call/video_send_stream.h"
|
|
#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_alr_state.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_begin_log.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_dtls_transport_state.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_end_log.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_frame_decoded.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.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_neteq_set_minimum_delay.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_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"
|
|
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
|
|
#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
|
|
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
|
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
|
|
|
|
// Files generated at build-time by the protobuf compiler.
|
|
#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
|
|
#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h"
|
|
#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h"
|
|
#else
|
|
#include "logging/rtc_event_log/rtc_event_log.pb.h"
|
|
#include "logging/rtc_event_log/rtc_event_log2.pb.h"
|
|
#endif
|
|
|
|
namespace webrtc {
|
|
|
|
enum PacketDirection { kIncomingPacket = 0, kOutgoingPacket };
|
|
|
|
enum class LoggedMediaType : uint8_t { kUnknown, kAudio, kVideo };
|
|
|
|
struct LoggedPacketInfo {
|
|
static LoggedPacketInfo CreateEmptyForTesting() { return LoggedPacketInfo(); }
|
|
|
|
LoggedPacketInfo(const LoggedRtpPacket& rtp,
|
|
LoggedMediaType media_type,
|
|
bool rtx,
|
|
Timestamp capture_time);
|
|
LoggedPacketInfo(const LoggedPacketInfo&);
|
|
~LoggedPacketInfo();
|
|
|
|
int64_t log_time_ms() const { return log_packet_time.ms(); }
|
|
int64_t log_time_us() const { return log_packet_time.us(); }
|
|
uint32_t ssrc;
|
|
uint16_t stream_seq_no;
|
|
uint16_t size;
|
|
uint16_t payload_size;
|
|
uint16_t padding_size;
|
|
uint16_t overhead = 0;
|
|
uint8_t payload_type;
|
|
LoggedMediaType media_type = LoggedMediaType::kUnknown;
|
|
bool rtx = false;
|
|
bool marker_bit = false;
|
|
bool has_transport_seq_no = false;
|
|
bool last_in_feedback = false;
|
|
uint16_t transport_seq_no = 0;
|
|
// The RTP header timestamp unwrapped and converted from tick count to seconds
|
|
// based timestamp.
|
|
Timestamp capture_time;
|
|
// The time the packet was logged. This is the receive time for incoming
|
|
// packets and send time for outgoing.
|
|
Timestamp log_packet_time;
|
|
// Send time as reported by abs-send-time extension, For outgoing packets this
|
|
// corresponds to log_packet_time, but might be measured using another clock.
|
|
Timestamp reported_send_time;
|
|
// The receive time that was reported in feedback. For incoming packets this
|
|
// corresponds to log_packet_time, but might be measured using another clock.
|
|
// PlusInfinity indicates that the packet was lost.
|
|
Timestamp reported_recv_time = Timestamp::MinusInfinity();
|
|
// The time feedback message was logged. This is the feedback send time for
|
|
// incoming packets and feedback receive time for outgoing.
|
|
// PlusInfinity indicates that feedback was expected but not received.
|
|
Timestamp log_feedback_time = Timestamp::MinusInfinity();
|
|
// The delay betweeen receiving an RTP packet and sending feedback for
|
|
// incoming packets. For outgoing packets we don't know the feedback send
|
|
// time, and this is instead calculated as the difference in reported receive
|
|
// time between this packet and the last packet in the same feedback message.
|
|
TimeDelta feedback_hold_duration = TimeDelta::MinusInfinity();
|
|
|
|
private:
|
|
LoggedPacketInfo()
|
|
: capture_time(Timestamp::MinusInfinity()),
|
|
log_packet_time(Timestamp::MinusInfinity()),
|
|
reported_send_time(Timestamp::MinusInfinity()) {}
|
|
};
|
|
|
|
struct InferredRouteChangeEvent {
|
|
int64_t log_time_ms() const { return log_time.ms(); }
|
|
int64_t log_time_us() const { return log_time.us(); }
|
|
uint32_t route_id;
|
|
Timestamp log_time = Timestamp::MinusInfinity();
|
|
uint16_t send_overhead;
|
|
uint16_t return_overhead;
|
|
};
|
|
|
|
enum class LoggedIceEventType {
|
|
kAdded,
|
|
kUpdated,
|
|
kDestroyed,
|
|
kSelected,
|
|
kCheckSent,
|
|
kCheckReceived,
|
|
kCheckResponseSent,
|
|
kCheckResponseReceived,
|
|
};
|
|
|
|
struct LoggedIceEvent {
|
|
uint32_t candidate_pair_id;
|
|
Timestamp log_time;
|
|
LoggedIceEventType event_type;
|
|
};
|
|
|
|
// This class is used to process lists of LoggedRtpPacketIncoming
|
|
// and LoggedRtpPacketOutgoing without duplicating the code.
|
|
// TODO(terelius): Remove this class. Instead use e.g. a vector of pointers
|
|
// to LoggedRtpPacket or templatize the surrounding code.
|
|
template <typename T>
|
|
class DereferencingVector {
|
|
public:
|
|
template <bool IsConst>
|
|
class DereferencingIterator {
|
|
public:
|
|
// Standard iterator traits.
|
|
using difference_type = std::ptrdiff_t;
|
|
using value_type = T;
|
|
using pointer = typename std::conditional_t<IsConst, const T*, T*>;
|
|
using reference = typename std::conditional_t<IsConst, const T&, T&>;
|
|
using iterator_category = std::bidirectional_iterator_tag;
|
|
|
|
using representation =
|
|
typename std::conditional_t<IsConst, const T* const*, T**>;
|
|
|
|
explicit DereferencingIterator(representation ptr) : ptr_(ptr) {}
|
|
|
|
DereferencingIterator(const DereferencingIterator& other)
|
|
: ptr_(other.ptr_) {}
|
|
DereferencingIterator(const DereferencingIterator&& other)
|
|
: ptr_(other.ptr_) {}
|
|
~DereferencingIterator() = default;
|
|
|
|
DereferencingIterator& operator=(const DereferencingIterator& other) {
|
|
ptr_ = other.ptr_;
|
|
return *this;
|
|
}
|
|
DereferencingIterator& operator=(const DereferencingIterator&& other) {
|
|
ptr_ = other.ptr_;
|
|
return *this;
|
|
}
|
|
|
|
bool operator==(const DereferencingIterator& other) const {
|
|
return ptr_ == other.ptr_;
|
|
}
|
|
bool operator!=(const DereferencingIterator& other) const {
|
|
return ptr_ != other.ptr_;
|
|
}
|
|
|
|
DereferencingIterator& operator++() {
|
|
++ptr_;
|
|
return *this;
|
|
}
|
|
DereferencingIterator& operator--() {
|
|
--ptr_;
|
|
return *this;
|
|
}
|
|
DereferencingIterator operator++(int) {
|
|
DereferencingIterator iter_copy(ptr_);
|
|
++ptr_;
|
|
return iter_copy;
|
|
}
|
|
DereferencingIterator operator--(int) {
|
|
DereferencingIterator iter_copy(ptr_);
|
|
--ptr_;
|
|
return iter_copy;
|
|
}
|
|
|
|
template <bool _IsConst = IsConst>
|
|
std::enable_if_t<!_IsConst, reference> operator*() {
|
|
return **ptr_;
|
|
}
|
|
|
|
template <bool _IsConst = IsConst>
|
|
std::enable_if_t<_IsConst, reference> operator*() const {
|
|
return **ptr_;
|
|
}
|
|
|
|
template <bool _IsConst = IsConst>
|
|
std::enable_if_t<!_IsConst, pointer> operator->() {
|
|
return *ptr_;
|
|
}
|
|
|
|
template <bool _IsConst = IsConst>
|
|
std::enable_if_t<_IsConst, pointer> operator->() const {
|
|
return *ptr_;
|
|
}
|
|
|
|
private:
|
|
representation ptr_;
|
|
};
|
|
|
|
using value_type = T;
|
|
using reference = value_type&;
|
|
using const_reference = const value_type&;
|
|
|
|
using iterator = DereferencingIterator<false>;
|
|
using const_iterator = DereferencingIterator<true>;
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
|
|
|
iterator begin() { return iterator(elems_.data()); }
|
|
iterator end() { return iterator(elems_.data() + elems_.size()); }
|
|
|
|
const_iterator begin() const { return const_iterator(elems_.data()); }
|
|
const_iterator end() const {
|
|
return const_iterator(elems_.data() + elems_.size());
|
|
}
|
|
|
|
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
|
reverse_iterator rend() { return reverse_iterator(begin()); }
|
|
|
|
const_reverse_iterator rbegin() const {
|
|
return const_reverse_iterator(end());
|
|
}
|
|
const_reverse_iterator rend() const {
|
|
return const_reverse_iterator(begin());
|
|
}
|
|
|
|
size_t size() const { return elems_.size(); }
|
|
|
|
bool empty() const { return elems_.empty(); }
|
|
|
|
T& operator[](size_t i) {
|
|
RTC_DCHECK_LT(i, elems_.size());
|
|
return *elems_[i];
|
|
}
|
|
|
|
const T& operator[](size_t i) const {
|
|
RTC_DCHECK_LT(i, elems_.size());
|
|
return *elems_[i];
|
|
}
|
|
|
|
void push_back(T* elem) {
|
|
RTC_DCHECK(elem != nullptr);
|
|
elems_.push_back(elem);
|
|
}
|
|
|
|
private:
|
|
std::vector<T*> elems_;
|
|
};
|
|
|
|
// Conversion functions for version 2 of the wire format.
|
|
BandwidthUsage GetRuntimeDetectorState(
|
|
rtclog2::DelayBasedBweUpdates::DetectorState detector_state);
|
|
|
|
ProbeFailureReason GetRuntimeProbeFailureReason(
|
|
rtclog2::BweProbeResultFailure::FailureReason failure);
|
|
|
|
DtlsTransportState GetRuntimeDtlsTransportState(
|
|
rtclog2::DtlsTransportStateEvent::DtlsTransportState state);
|
|
|
|
IceCandidatePairConfigType GetRuntimeIceCandidatePairConfigType(
|
|
rtclog2::IceCandidatePairConfig::IceCandidatePairConfigType type);
|
|
|
|
IceCandidateType GetRuntimeIceCandidateType(
|
|
rtclog2::IceCandidatePairConfig::IceCandidateType type);
|
|
|
|
IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol(
|
|
rtclog2::IceCandidatePairConfig::Protocol protocol);
|
|
|
|
IceCandidatePairAddressFamily GetRuntimeIceCandidatePairAddressFamily(
|
|
rtclog2::IceCandidatePairConfig::AddressFamily address_family);
|
|
|
|
IceCandidateNetworkType GetRuntimeIceCandidateNetworkType(
|
|
rtclog2::IceCandidatePairConfig::NetworkType network_type);
|
|
|
|
IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
|
|
rtclog2::IceCandidatePairEvent::IceCandidatePairEventType type);
|
|
|
|
std::vector<RtpExtension> GetRuntimeRtpHeaderExtensionConfig(
|
|
const rtclog2::RtpHeaderExtensionConfig& proto_header_extensions);
|
|
// End of conversion functions.
|
|
|
|
class ParsedRtcEventLog {
|
|
public:
|
|
enum class MediaType { ANY, AUDIO, VIDEO, DATA };
|
|
enum class UnconfiguredHeaderExtensions {
|
|
kDontParse,
|
|
kAttemptWebrtcDefaultConfig
|
|
};
|
|
|
|
using ParseStatus = RtcEventLogParseStatus;
|
|
|
|
template <typename T>
|
|
using ParseStatusOr = RtcEventLogParseStatusOr<T>;
|
|
|
|
struct LoggedRtpStreamIncoming {
|
|
LoggedRtpStreamIncoming();
|
|
LoggedRtpStreamIncoming(const LoggedRtpStreamIncoming&);
|
|
~LoggedRtpStreamIncoming();
|
|
uint32_t ssrc;
|
|
std::vector<LoggedRtpPacketIncoming> incoming_packets;
|
|
};
|
|
|
|
struct LoggedRtpStreamOutgoing {
|
|
LoggedRtpStreamOutgoing();
|
|
LoggedRtpStreamOutgoing(const LoggedRtpStreamOutgoing&);
|
|
~LoggedRtpStreamOutgoing();
|
|
uint32_t ssrc;
|
|
std::vector<LoggedRtpPacketOutgoing> outgoing_packets;
|
|
};
|
|
|
|
struct LoggedRtpStreamView {
|
|
LoggedRtpStreamView(uint32_t ssrc,
|
|
const std::vector<LoggedRtpPacketIncoming>& packets);
|
|
LoggedRtpStreamView(uint32_t ssrc,
|
|
const std::vector<LoggedRtpPacketOutgoing>& packets);
|
|
LoggedRtpStreamView(const LoggedRtpStreamView&);
|
|
uint32_t ssrc;
|
|
DereferencingVector<const LoggedRtpPacket> packet_view;
|
|
};
|
|
|
|
class LogSegment {
|
|
public:
|
|
LogSegment(int64_t start_time_us, int64_t stop_time_us)
|
|
: start_time_us_(start_time_us), stop_time_us_(stop_time_us) {}
|
|
int64_t start_time_ms() const { return start_time_us_ / 1000; }
|
|
int64_t start_time_us() const { return start_time_us_; }
|
|
int64_t stop_time_ms() const { return stop_time_us_ / 1000; }
|
|
int64_t stop_time_us() const { return stop_time_us_; }
|
|
|
|
private:
|
|
int64_t start_time_us_;
|
|
int64_t stop_time_us_;
|
|
};
|
|
|
|
static webrtc::RtpHeaderExtensionMap GetDefaultHeaderExtensionMap();
|
|
|
|
explicit ParsedRtcEventLog(
|
|
UnconfiguredHeaderExtensions parse_unconfigured_header_extensions =
|
|
UnconfiguredHeaderExtensions::kDontParse,
|
|
bool allow_incomplete_log = false);
|
|
|
|
~ParsedRtcEventLog();
|
|
|
|
// Clears previously parsed events and resets the ParsedRtcEventLogNew to an
|
|
// empty state.
|
|
void Clear();
|
|
|
|
// Reads an RtcEventLog file and returns success if parsing was successful.
|
|
ParseStatus ParseFile(absl::string_view file_name);
|
|
|
|
// Reads an RtcEventLog from a string and returns success if successful.
|
|
ParseStatus ParseString(absl::string_view s);
|
|
|
|
// Reads an RtcEventLog from an string and returns success if successful.
|
|
ParseStatus ParseStream(absl::string_view s);
|
|
|
|
MediaType GetMediaType(uint32_t ssrc, PacketDirection direction) const;
|
|
|
|
// Configured SSRCs.
|
|
const std::set<uint32_t>& incoming_rtx_ssrcs() const {
|
|
return incoming_rtx_ssrcs_;
|
|
}
|
|
|
|
const std::set<uint32_t>& incoming_video_ssrcs() const {
|
|
return incoming_video_ssrcs_;
|
|
}
|
|
|
|
const std::set<uint32_t>& incoming_audio_ssrcs() const {
|
|
return incoming_audio_ssrcs_;
|
|
}
|
|
|
|
const std::set<uint32_t>& outgoing_rtx_ssrcs() const {
|
|
return outgoing_rtx_ssrcs_;
|
|
}
|
|
|
|
const std::set<uint32_t>& outgoing_video_ssrcs() const {
|
|
return outgoing_video_ssrcs_;
|
|
}
|
|
|
|
const std::set<uint32_t>& outgoing_audio_ssrcs() const {
|
|
return outgoing_audio_ssrcs_;
|
|
}
|
|
|
|
// Stream configurations.
|
|
const std::vector<LoggedAudioRecvConfig>& audio_recv_configs() const {
|
|
return audio_recv_configs_;
|
|
}
|
|
|
|
const std::vector<LoggedAudioSendConfig>& audio_send_configs() const {
|
|
return audio_send_configs_;
|
|
}
|
|
|
|
const std::vector<LoggedVideoRecvConfig>& video_recv_configs() const {
|
|
return video_recv_configs_;
|
|
}
|
|
|
|
const std::vector<LoggedVideoSendConfig>& video_send_configs() const {
|
|
return video_send_configs_;
|
|
}
|
|
|
|
// Beginning and end of log segments.
|
|
const std::vector<LoggedStartEvent>& start_log_events() const {
|
|
return start_log_events_;
|
|
}
|
|
|
|
const std::vector<LoggedStopEvent>& stop_log_events() const {
|
|
return stop_log_events_;
|
|
}
|
|
|
|
const std::vector<LoggedAlrStateEvent>& alr_state_events() const {
|
|
return alr_state_events_;
|
|
}
|
|
|
|
// Audio
|
|
const std::map<uint32_t, std::vector<LoggedAudioPlayoutEvent>>&
|
|
audio_playout_events() const {
|
|
return audio_playout_events_;
|
|
}
|
|
|
|
const std::map<uint32_t, std::vector<LoggedNetEqSetMinimumDelayEvent>>&
|
|
neteq_set_minimum_delay_events() const {
|
|
return neteq_set_minimum_delay_events_;
|
|
}
|
|
|
|
const std::vector<LoggedAudioNetworkAdaptationEvent>&
|
|
audio_network_adaptation_events() const {
|
|
return audio_network_adaptation_events_;
|
|
}
|
|
|
|
// Bandwidth estimation
|
|
const std::vector<LoggedBweProbeClusterCreatedEvent>&
|
|
bwe_probe_cluster_created_events() const {
|
|
return bwe_probe_cluster_created_events_;
|
|
}
|
|
|
|
const std::vector<LoggedBweProbeFailureEvent>& bwe_probe_failure_events()
|
|
const {
|
|
return bwe_probe_failure_events_;
|
|
}
|
|
|
|
const std::vector<LoggedBweProbeSuccessEvent>& bwe_probe_success_events()
|
|
const {
|
|
return bwe_probe_success_events_;
|
|
}
|
|
|
|
const std::vector<LoggedBweDelayBasedUpdate>& bwe_delay_updates() const {
|
|
return bwe_delay_updates_;
|
|
}
|
|
|
|
const std::vector<LoggedBweLossBasedUpdate>& bwe_loss_updates() const {
|
|
return bwe_loss_updates_;
|
|
}
|
|
|
|
// DTLS
|
|
const std::vector<LoggedDtlsTransportState>& dtls_transport_states() const {
|
|
return dtls_transport_states_;
|
|
}
|
|
|
|
const std::vector<LoggedDtlsWritableState>& dtls_writable_states() const {
|
|
return dtls_writable_states_;
|
|
}
|
|
|
|
// ICE events
|
|
const std::vector<LoggedIceCandidatePairConfig>& ice_candidate_pair_configs()
|
|
const {
|
|
return ice_candidate_pair_configs_;
|
|
}
|
|
|
|
const std::vector<LoggedIceCandidatePairEvent>& ice_candidate_pair_events()
|
|
const {
|
|
return ice_candidate_pair_events_;
|
|
}
|
|
|
|
const std::vector<LoggedRouteChangeEvent>& route_change_events() const {
|
|
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 {
|
|
return incoming_rtp_packets_by_ssrc_;
|
|
}
|
|
|
|
const std::vector<LoggedRtpStreamOutgoing>& outgoing_rtp_packets_by_ssrc()
|
|
const {
|
|
return outgoing_rtp_packets_by_ssrc_;
|
|
}
|
|
|
|
const std::vector<LoggedRtpStreamView>& rtp_packets_by_ssrc(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket)
|
|
return incoming_rtp_packet_views_by_ssrc_;
|
|
else
|
|
return outgoing_rtp_packet_views_by_ssrc_;
|
|
}
|
|
|
|
// RTCP
|
|
const std::vector<LoggedRtcpPacketIncoming>& incoming_rtcp_packets() const {
|
|
return incoming_rtcp_packets_;
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketOutgoing>& outgoing_rtcp_packets() const {
|
|
return outgoing_rtcp_packets_;
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketReceiverReport>& receiver_reports(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_rr_;
|
|
} else {
|
|
return outgoing_rr_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketSenderReport>& sender_reports(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_sr_;
|
|
} else {
|
|
return outgoing_sr_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketExtendedReports>& extended_reports(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_xr_;
|
|
} else {
|
|
return outgoing_xr_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketNack>& nacks(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_nack_;
|
|
} else {
|
|
return outgoing_nack_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketRemb>& rembs(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_remb_;
|
|
} else {
|
|
return outgoing_remb_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketFir>& firs(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_fir_;
|
|
} else {
|
|
return outgoing_fir_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketPli>& plis(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_pli_;
|
|
} else {
|
|
return outgoing_pli_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketBye>& byes(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_bye_;
|
|
} else {
|
|
return outgoing_bye_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketTransportFeedback>& transport_feedbacks(
|
|
PacketDirection direction) const {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_transport_feedback_;
|
|
} else {
|
|
return outgoing_transport_feedback_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedRtcpPacketLossNotification>& loss_notifications(
|
|
PacketDirection direction) {
|
|
if (direction == kIncomingPacket) {
|
|
return incoming_loss_notification_;
|
|
} else {
|
|
return outgoing_loss_notification_;
|
|
}
|
|
}
|
|
|
|
const std::vector<LoggedGenericPacketReceived>& generic_packets_received()
|
|
const {
|
|
return generic_packets_received_;
|
|
}
|
|
const std::vector<LoggedGenericPacketSent>& generic_packets_sent() const {
|
|
return generic_packets_sent_;
|
|
}
|
|
|
|
const std::vector<LoggedGenericAckReceived>& generic_acks_received() const {
|
|
return generic_acks_received_;
|
|
}
|
|
|
|
// Media
|
|
const std::map<uint32_t, std::vector<LoggedFrameDecoded>>& decoded_frames()
|
|
const {
|
|
return decoded_frames_;
|
|
}
|
|
|
|
Timestamp first_timestamp() const { return first_timestamp_; }
|
|
Timestamp last_timestamp() const { return last_timestamp_; }
|
|
|
|
const LogSegment& first_log_segment() const { return first_log_segment_; }
|
|
|
|
std::vector<LoggedPacketInfo> GetPacketInfos(PacketDirection direction) const;
|
|
std::vector<LoggedPacketInfo> GetIncomingPacketInfos() const {
|
|
return GetPacketInfos(kIncomingPacket);
|
|
}
|
|
std::vector<LoggedPacketInfo> GetOutgoingPacketInfos() const {
|
|
return GetPacketInfos(kOutgoingPacket);
|
|
}
|
|
std::vector<LoggedIceCandidatePairConfig> GetIceCandidates() const;
|
|
std::vector<LoggedIceEvent> GetIceEvents() const;
|
|
|
|
std::vector<InferredRouteChangeEvent> GetRouteChanges() const;
|
|
|
|
private:
|
|
ABSL_MUST_USE_RESULT ParseStatus ParseStreamInternal(absl::string_view s);
|
|
ABSL_MUST_USE_RESULT ParseStatus ParseStreamInternalV3(absl::string_view s);
|
|
|
|
ABSL_MUST_USE_RESULT ParseStatus
|
|
StoreParsedLegacyEvent(const rtclog::Event& event);
|
|
|
|
template <typename T>
|
|
void StoreFirstAndLastTimestamp(const std::vector<T>& v);
|
|
|
|
// Returns: a pointer to a header extensions map acquired from parsing
|
|
// corresponding Audio/Video Sender/Receiver config events.
|
|
// Warning: if the same SSRC is reused by both video and audio streams during
|
|
// call, extensions maps may be incorrect (the last one would be returned).
|
|
const RtpHeaderExtensionMap* GetRtpHeaderExtensionMap(bool incoming,
|
|
uint32_t ssrc);
|
|
|
|
// Reads packet, direction and packet length from the RTCP event at `index`,
|
|
// and stores the values in the corresponding output parameters.
|
|
// Each output parameter can be set to nullptr if that value isn't needed.
|
|
// NB: The packet must have space for at least IP_PACKET_SIZE bytes.
|
|
ParseStatus GetRtcpPacket(const rtclog::Event& event,
|
|
PacketDirection* incoming,
|
|
std::vector<uint8_t>* packet) const;
|
|
|
|
ParseStatusOr<rtclog::StreamConfig> GetVideoReceiveConfig(
|
|
const rtclog::Event& event) const;
|
|
ParseStatusOr<rtclog::StreamConfig> GetVideoSendConfig(
|
|
const rtclog::Event& event) const;
|
|
ParseStatusOr<rtclog::StreamConfig> GetAudioReceiveConfig(
|
|
const rtclog::Event& event) const;
|
|
ParseStatusOr<rtclog::StreamConfig> GetAudioSendConfig(
|
|
const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedAudioPlayoutEvent> GetAudioPlayout(
|
|
const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedBweLossBasedUpdate>
|
|
GetLossBasedBweUpdate(const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedBweDelayBasedUpdate>
|
|
GetDelayBasedBweUpdate(const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedAudioNetworkAdaptationEvent>
|
|
GetAudioNetworkAdaptation(const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeClusterCreatedEvent>
|
|
GetBweProbeClusterCreated(const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeFailureEvent>
|
|
GetBweProbeFailure(const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeSuccessEvent>
|
|
GetBweProbeSuccess(const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedAlrStateEvent> GetAlrState(
|
|
const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairConfig>
|
|
GetIceCandidatePairConfig(const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairEvent>
|
|
GetIceCandidatePairEvent(const rtclog::Event& event) const;
|
|
|
|
ParsedRtcEventLog::ParseStatusOr<LoggedRemoteEstimateEvent>
|
|
GetRemoteEstimateEvent(const rtclog::Event& event) const;
|
|
|
|
// Parsing functions for new format.
|
|
ParseStatus StoreAlrStateEvent(const rtclog2::AlrState& proto);
|
|
ParseStatus StoreAudioNetworkAdaptationEvent(
|
|
const rtclog2::AudioNetworkAdaptations& proto);
|
|
ParseStatus StoreAudioPlayoutEvent(const rtclog2::AudioPlayoutEvents& proto);
|
|
ParseStatus StoreAudioRecvConfig(const rtclog2::AudioRecvStreamConfig& proto);
|
|
ParseStatus StoreAudioSendConfig(const rtclog2::AudioSendStreamConfig& proto);
|
|
ParseStatus StoreBweDelayBasedUpdate(
|
|
const rtclog2::DelayBasedBweUpdates& proto);
|
|
ParseStatus StoreBweLossBasedUpdate(
|
|
const rtclog2::LossBasedBweUpdates& proto);
|
|
ParseStatus StoreBweProbeClusterCreated(
|
|
const rtclog2::BweProbeCluster& proto);
|
|
ParseStatus StoreBweProbeFailureEvent(
|
|
const rtclog2::BweProbeResultFailure& proto);
|
|
ParseStatus StoreBweProbeSuccessEvent(
|
|
const rtclog2::BweProbeResultSuccess& proto);
|
|
ParseStatus StoreDtlsTransportState(
|
|
const rtclog2::DtlsTransportStateEvent& proto);
|
|
ParseStatus StoreDtlsWritableState(const rtclog2::DtlsWritableState& proto);
|
|
ParsedRtcEventLog::ParseStatus StoreFrameDecodedEvents(
|
|
const rtclog2::FrameDecodedEvents& proto);
|
|
ParseStatus StoreGenericAckReceivedEvent(
|
|
const rtclog2::GenericAckReceived& proto);
|
|
ParseStatus StoreGenericPacketReceivedEvent(
|
|
const rtclog2::GenericPacketReceived& proto);
|
|
ParseStatus StoreGenericPacketSentEvent(
|
|
const rtclog2::GenericPacketSent& proto);
|
|
ParseStatus StoreIceCandidateEvent(
|
|
const rtclog2::IceCandidatePairEvent& proto);
|
|
ParseStatus StoreIceCandidatePairConfig(
|
|
const rtclog2::IceCandidatePairConfig& proto);
|
|
ParseStatus StoreIncomingRtcpPackets(
|
|
const rtclog2::IncomingRtcpPackets& proto);
|
|
ParseStatus StoreIncomingRtpPackets(const rtclog2::IncomingRtpPackets& proto);
|
|
ParseStatus StoreNetEqSetMinimumDelay(
|
|
const rtclog2::NetEqSetMinimumDelay& proto);
|
|
ParseStatus StoreOutgoingRtcpPackets(
|
|
const rtclog2::OutgoingRtcpPackets& proto);
|
|
ParseStatus StoreOutgoingRtpPackets(const rtclog2::OutgoingRtpPackets& proto);
|
|
ParseStatus StoreParsedNewFormatEvent(const rtclog2::EventStream& event);
|
|
ParseStatus StoreRouteChangeEvent(const rtclog2::RouteChange& proto);
|
|
ParseStatus StoreRemoteEstimateEvent(const rtclog2::RemoteEstimates& proto);
|
|
ParseStatus StoreStartEvent(const rtclog2::BeginLogEvent& proto);
|
|
ParseStatus StoreStopEvent(const rtclog2::EndLogEvent& proto);
|
|
ParseStatus StoreVideoRecvConfig(const rtclog2::VideoRecvStreamConfig& proto);
|
|
ParseStatus StoreVideoSendConfig(const rtclog2::VideoSendStreamConfig& proto);
|
|
// End of new parsing functions.
|
|
|
|
struct Stream {
|
|
Stream(uint32_t ssrc,
|
|
MediaType media_type,
|
|
PacketDirection direction,
|
|
webrtc::RtpHeaderExtensionMap map)
|
|
: ssrc(ssrc),
|
|
media_type(media_type),
|
|
direction(direction),
|
|
rtp_extensions_map(map) {}
|
|
uint32_t ssrc;
|
|
MediaType media_type;
|
|
PacketDirection direction;
|
|
webrtc::RtpHeaderExtensionMap rtp_extensions_map;
|
|
};
|
|
|
|
const UnconfiguredHeaderExtensions parse_unconfigured_header_extensions_;
|
|
const bool allow_incomplete_logs_;
|
|
|
|
// Make a default extension map for streams without configuration information.
|
|
// TODO(ivoc): Once configuration of audio streams is stored in the event log,
|
|
// this can be removed. Tracking bug: webrtc:6399
|
|
RtpHeaderExtensionMap default_extension_map_;
|
|
|
|
// Tracks what each stream is configured for. Note that a single SSRC can be
|
|
// in several sets. For example, the SSRC used for sending video over RTX
|
|
// will appear in both video_ssrcs_ and rtx_ssrcs_. In the unlikely case that
|
|
// an SSRC is reconfigured to a different media type mid-call, it will also
|
|
// appear in multiple sets.
|
|
std::set<uint32_t> incoming_rtx_ssrcs_;
|
|
std::set<uint32_t> incoming_video_ssrcs_;
|
|
std::set<uint32_t> incoming_audio_ssrcs_;
|
|
std::set<uint32_t> outgoing_rtx_ssrcs_;
|
|
std::set<uint32_t> outgoing_video_ssrcs_;
|
|
std::set<uint32_t> outgoing_audio_ssrcs_;
|
|
|
|
// Maps an SSRC to the parsed RTP headers in that stream. Header extensions
|
|
// are parsed if the stream has been configured. This is only used for
|
|
// grouping the events by SSRC during parsing; the events are moved to
|
|
// incoming_rtp_packets_by_ssrc_ once the parsing is done.
|
|
std::map<uint32_t, std::vector<LoggedRtpPacketIncoming>>
|
|
incoming_rtp_packets_map_;
|
|
std::map<uint32_t, std::vector<LoggedRtpPacketOutgoing>>
|
|
outgoing_rtp_packets_map_;
|
|
|
|
// RTP headers.
|
|
std::vector<LoggedRtpStreamIncoming> incoming_rtp_packets_by_ssrc_;
|
|
std::vector<LoggedRtpStreamOutgoing> outgoing_rtp_packets_by_ssrc_;
|
|
std::vector<LoggedRtpStreamView> incoming_rtp_packet_views_by_ssrc_;
|
|
std::vector<LoggedRtpStreamView> outgoing_rtp_packet_views_by_ssrc_;
|
|
|
|
// Raw RTCP packets.
|
|
std::vector<LoggedRtcpPacketIncoming> incoming_rtcp_packets_;
|
|
std::vector<LoggedRtcpPacketOutgoing> outgoing_rtcp_packets_;
|
|
|
|
// Parsed RTCP messages. Currently not separated based on SSRC.
|
|
std::vector<LoggedRtcpPacketReceiverReport> incoming_rr_;
|
|
std::vector<LoggedRtcpPacketReceiverReport> outgoing_rr_;
|
|
std::vector<LoggedRtcpPacketSenderReport> incoming_sr_;
|
|
std::vector<LoggedRtcpPacketSenderReport> outgoing_sr_;
|
|
std::vector<LoggedRtcpPacketExtendedReports> incoming_xr_;
|
|
std::vector<LoggedRtcpPacketExtendedReports> outgoing_xr_;
|
|
std::vector<LoggedRtcpPacketNack> incoming_nack_;
|
|
std::vector<LoggedRtcpPacketNack> outgoing_nack_;
|
|
std::vector<LoggedRtcpPacketRemb> incoming_remb_;
|
|
std::vector<LoggedRtcpPacketRemb> outgoing_remb_;
|
|
std::vector<LoggedRtcpPacketFir> incoming_fir_;
|
|
std::vector<LoggedRtcpPacketFir> outgoing_fir_;
|
|
std::vector<LoggedRtcpPacketPli> incoming_pli_;
|
|
std::vector<LoggedRtcpPacketPli> outgoing_pli_;
|
|
std::vector<LoggedRtcpPacketBye> incoming_bye_;
|
|
std::vector<LoggedRtcpPacketBye> outgoing_bye_;
|
|
std::vector<LoggedRtcpPacketTransportFeedback> incoming_transport_feedback_;
|
|
std::vector<LoggedRtcpPacketTransportFeedback> outgoing_transport_feedback_;
|
|
std::vector<LoggedRtcpPacketLossNotification> incoming_loss_notification_;
|
|
std::vector<LoggedRtcpPacketLossNotification> outgoing_loss_notification_;
|
|
|
|
std::vector<LoggedStartEvent> start_log_events_;
|
|
std::vector<LoggedStopEvent> stop_log_events_;
|
|
|
|
std::vector<LoggedAlrStateEvent> alr_state_events_;
|
|
|
|
std::map<uint32_t, std::vector<LoggedAudioPlayoutEvent>>
|
|
audio_playout_events_;
|
|
std::map<uint32_t, std::vector<LoggedNetEqSetMinimumDelayEvent>>
|
|
neteq_set_minimum_delay_events_;
|
|
|
|
std::vector<LoggedAudioNetworkAdaptationEvent>
|
|
audio_network_adaptation_events_;
|
|
|
|
std::vector<LoggedBweProbeClusterCreatedEvent>
|
|
bwe_probe_cluster_created_events_;
|
|
|
|
std::vector<LoggedBweProbeFailureEvent> bwe_probe_failure_events_;
|
|
std::vector<LoggedBweProbeSuccessEvent> bwe_probe_success_events_;
|
|
|
|
std::vector<LoggedBweDelayBasedUpdate> bwe_delay_updates_;
|
|
std::vector<LoggedBweLossBasedUpdate> bwe_loss_updates_;
|
|
|
|
std::vector<LoggedDtlsTransportState> dtls_transport_states_;
|
|
std::vector<LoggedDtlsWritableState> dtls_writable_states_;
|
|
|
|
std::map<uint32_t, std::vector<LoggedFrameDecoded>> decoded_frames_;
|
|
|
|
std::vector<LoggedIceCandidatePairConfig> ice_candidate_pair_configs_;
|
|
std::vector<LoggedIceCandidatePairEvent> ice_candidate_pair_events_;
|
|
|
|
std::vector<LoggedAudioRecvConfig> audio_recv_configs_;
|
|
std::vector<LoggedAudioSendConfig> audio_send_configs_;
|
|
std::vector<LoggedVideoRecvConfig> video_recv_configs_;
|
|
std::vector<LoggedVideoSendConfig> video_send_configs_;
|
|
|
|
std::vector<LoggedGenericPacketReceived> generic_packets_received_;
|
|
std::vector<LoggedGenericPacketSent> generic_packets_sent_;
|
|
std::vector<LoggedGenericAckReceived> generic_acks_received_;
|
|
|
|
std::vector<LoggedRouteChangeEvent> route_change_events_;
|
|
std::vector<LoggedRemoteEstimateEvent> remote_estimate_events_;
|
|
|
|
std::vector<uint8_t> last_incoming_rtcp_packet_;
|
|
|
|
Timestamp first_timestamp_ = Timestamp::PlusInfinity();
|
|
Timestamp last_timestamp_ = Timestamp::MinusInfinity();
|
|
|
|
LogSegment first_log_segment_ =
|
|
LogSegment(0, std::numeric_limits<int64_t>::max());
|
|
|
|
// The extension maps are mutable to allow us to insert the default
|
|
// configuration when parsing an RTP header for an unconfigured stream.
|
|
// TODO(terelius): This is only used for the legacy format. Remove once we've
|
|
// fully transitioned to the new format.
|
|
mutable std::map<uint32_t, webrtc::RtpHeaderExtensionMap>
|
|
incoming_rtp_extensions_maps_;
|
|
mutable std::map<uint32_t, webrtc::RtpHeaderExtensionMap>
|
|
outgoing_rtp_extensions_maps_;
|
|
};
|
|
|
|
struct MatchedSendArrivalTimes {
|
|
static constexpr int64_t kNotReceived = -1;
|
|
|
|
MatchedSendArrivalTimes(int64_t fb, int64_t tx, int64_t rx, int64_t ps)
|
|
: feedback_arrival_time_ms(fb),
|
|
send_time_ms(tx),
|
|
arrival_time_ms(rx),
|
|
payload_size(ps) {}
|
|
|
|
int64_t feedback_arrival_time_ms;
|
|
int64_t send_time_ms;
|
|
int64_t arrival_time_ms; // kNotReceived for lost packets.
|
|
int64_t payload_size;
|
|
};
|
|
const std::vector<MatchedSendArrivalTimes> GetNetworkTrace(
|
|
const ParsedRtcEventLog& parsed_log);
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_PARSER_H_
|