diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.h | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.h')
-rw-r--r-- | third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.h | 941 |
1 files changed, 941 insertions, 0 deletions
diff --git a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.h b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.h new file mode 100644 index 0000000000..9ad96274d3 --- /dev/null +++ b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.h @@ -0,0 +1,941 @@ +/* + * 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" +#include "rtc_base/ignore_wundef.h" + +// Files generated at build-time by the protobuf compiler. +RTC_PUSH_IGNORING_WUNDEF() +#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 +RTC_POP_IGNORING_WUNDEF() + +namespace webrtc { + +enum PacketDirection { kIncomingPacket = 0, kOutgoingPacket }; + +enum class LoggedMediaType : uint8_t { kUnknown, kAudio, kVideo }; + +struct 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(); +}; + +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_ |