1 /* 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_TOOLS_EVENT_LOG_VISUALIZER_ANALYZER_H_ 12 #define WEBRTC_TOOLS_EVENT_LOG_VISUALIZER_ANALYZER_H_ 13 14 #include <map> 15 #include <memory> 16 #include <set> 17 #include <string> 18 #include <utility> 19 #include <vector> 20 21 #include "webrtc/logging/rtc_event_log/rtc_event_log_parser.h" 22 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 23 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" 24 #include "webrtc/tools/event_log_visualizer/plot_base.h" 25 26 namespace webrtc { 27 namespace plotting { 28 29 struct LoggedRtpPacket { LoggedRtpPacketLoggedRtpPacket30 LoggedRtpPacket(uint64_t timestamp, RTPHeader header, size_t total_length) 31 : timestamp(timestamp), header(header), total_length(total_length) {} 32 uint64_t timestamp; 33 // TODO(terelius): This allocates space for 15 CSRCs even if none are used. 34 RTPHeader header; 35 size_t total_length; 36 }; 37 38 struct LoggedRtcpPacket { LoggedRtcpPacketLoggedRtcpPacket39 LoggedRtcpPacket(uint64_t timestamp, 40 RTCPPacketType rtcp_type, 41 std::unique_ptr<rtcp::RtcpPacket> rtcp_packet) 42 : timestamp(timestamp), type(rtcp_type), packet(std::move(rtcp_packet)) {} 43 uint64_t timestamp; 44 RTCPPacketType type; 45 std::unique_ptr<rtcp::RtcpPacket> packet; 46 }; 47 48 struct BwePacketLossEvent { 49 uint64_t timestamp; 50 int32_t new_bitrate; 51 uint8_t fraction_loss; 52 int32_t expected_packets; 53 }; 54 55 class EventLogAnalyzer { 56 public: 57 // The EventLogAnalyzer keeps a reference to the ParsedRtcEventLog for the 58 // duration of its lifetime. The ParsedRtcEventLog must not be destroyed or 59 // modified while the EventLogAnalyzer is being used. 60 explicit EventLogAnalyzer(const ParsedRtcEventLog& log); 61 62 void CreatePacketGraph(PacketDirection desired_direction, Plot* plot); 63 64 void CreateAccumulatedPacketsGraph(PacketDirection desired_direction, 65 Plot* plot); 66 67 void CreatePlayoutGraph(Plot* plot); 68 69 void CreateAudioLevelGraph(Plot* plot); 70 71 void CreateSequenceNumberGraph(Plot* plot); 72 73 void CreateIncomingPacketLossGraph(Plot* plot); 74 75 void CreateDelayChangeGraph(Plot* plot); 76 77 void CreateAccumulatedDelayChangeGraph(Plot* plot); 78 79 void CreateFractionLossGraph(Plot* plot); 80 81 void CreateTotalBitrateGraph(PacketDirection desired_direction, Plot* plot); 82 83 void CreateStreamBitrateGraph(PacketDirection desired_direction, Plot* plot); 84 85 void CreateBweSimulationGraph(Plot* plot); 86 87 void CreateNetworkDelayFeedbackGraph(Plot* plot); 88 89 // Returns a vector of capture and arrival timestamps for the video frames 90 // of the stream with the most number of frames. 91 std::vector<std::pair<int64_t, int64_t>> GetFrameTimestamps() const; 92 93 private: 94 class StreamId { 95 public: StreamId(uint32_t ssrc,webrtc::PacketDirection direction)96 StreamId(uint32_t ssrc, webrtc::PacketDirection direction) 97 : ssrc_(ssrc), direction_(direction) {} 98 bool operator<(const StreamId& other) const { 99 return std::tie(ssrc_, direction_) < 100 std::tie(other.ssrc_, other.direction_); 101 } 102 bool operator==(const StreamId& other) const { 103 return std::tie(ssrc_, direction_) == 104 std::tie(other.ssrc_, other.direction_); 105 } GetSsrc()106 uint32_t GetSsrc() const { return ssrc_; } GetDirection()107 webrtc::PacketDirection GetDirection() const { return direction_; } 108 109 private: 110 uint32_t ssrc_; 111 webrtc::PacketDirection direction_; 112 }; 113 114 template <typename T> 115 void CreateAccumulatedPacketsTimeSeries( 116 PacketDirection desired_direction, 117 Plot* plot, 118 const std::map<StreamId, std::vector<T>>& packets, 119 const std::string& label_prefix); 120 121 bool IsRtxSsrc(StreamId stream_id) const; 122 123 bool IsVideoSsrc(StreamId stream_id) const; 124 125 bool IsAudioSsrc(StreamId stream_id) const; 126 127 std::string GetStreamName(StreamId) const; 128 129 const ParsedRtcEventLog& parsed_log_; 130 131 // A list of SSRCs we are interested in analysing. 132 // If left empty, all SSRCs will be considered relevant. 133 std::vector<uint32_t> desired_ssrc_; 134 135 // Tracks what each stream is configured for. Note that a single SSRC can be 136 // in several sets. For example, the SSRC used for sending video over RTX 137 // will appear in both video_ssrcs_ and rtx_ssrcs_. In the unlikely case that 138 // an SSRC is reconfigured to a different media type mid-call, it will also 139 // appear in multiple sets. 140 std::set<StreamId> rtx_ssrcs_; 141 std::set<StreamId> video_ssrcs_; 142 std::set<StreamId> audio_ssrcs_; 143 144 // Maps a stream identifier consisting of ssrc and direction to the parsed 145 // RTP headers in that stream. Header extensions are parsed if the stream 146 // has been configured. 147 std::map<StreamId, std::vector<LoggedRtpPacket>> rtp_packets_; 148 149 std::map<StreamId, std::vector<LoggedRtcpPacket>> rtcp_packets_; 150 151 // A list of all updates from the send-side loss-based bandwidth estimator. 152 std::vector<BwePacketLossEvent> bwe_loss_updates_; 153 154 // Window and step size used for calculating moving averages, e.g. bitrate. 155 // The generated data points will be |step_| microseconds apart. 156 // Only events occuring at most |window_duration_| microseconds before the 157 // current data point will be part of the average. 158 uint64_t window_duration_; 159 uint64_t step_; 160 161 // First and last events of the log. 162 uint64_t begin_time_; 163 uint64_t end_time_; 164 165 // Duration (in seconds) of log file. 166 float call_duration_s_; 167 }; 168 169 } // namespace plotting 170 } // namespace webrtc 171 172 #endif // WEBRTC_TOOLS_EVENT_LOG_VISUALIZER_ANALYZER_H_ 173