Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: webrtc/tools/event_log_visualizer/analyzer.cc

Issue 2145153002: Event log visualization tool keeps a map from SSRC to parsed headers (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Nit Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/tools/event_log_visualizer/analyzer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 int64_t min_difference = max_difference - modulus + 1; 69 int64_t min_difference = max_difference - modulus + 1;
70 if (difference > max_difference) { 70 if (difference > max_difference) {
71 difference -= modulus; 71 difference -= modulus;
72 } 72 }
73 if (difference < min_difference) { 73 if (difference < min_difference) {
74 difference += modulus; 74 difference += modulus;
75 } 75 }
76 return difference; 76 return difference;
77 } 77 }
78 78
79 class StreamId {
80 public:
81 StreamId(uint32_t ssrc,
82 webrtc::PacketDirection direction,
83 webrtc::MediaType media_type)
84 : ssrc_(ssrc), direction_(direction), media_type_(media_type) {}
85
86 bool operator<(const StreamId& other) const {
87 if (ssrc_ < other.ssrc_) {
88 return true;
89 }
90 if (ssrc_ == other.ssrc_) {
91 if (media_type_ < other.media_type_) {
92 return true;
93 }
94 if (media_type_ == other.media_type_) {
95 if (direction_ < other.direction_) {
96 return true;
97 }
98 }
99 }
100 return false;
101 }
102
103 bool operator==(const StreamId& other) const {
104 return ssrc_ == other.ssrc_ && direction_ == other.direction_ &&
105 media_type_ == other.media_type_;
106 }
107
108 uint32_t GetSsrc() const { return ssrc_; }
109
110 private:
111 uint32_t ssrc_;
112 webrtc::PacketDirection direction_;
113 webrtc::MediaType media_type_;
114 };
115
116 const double kXMargin = 1.02; 79 const double kXMargin = 1.02;
117 const double kYMargin = 1.1; 80 const double kYMargin = 1.1;
118 const double kDefaultXMin = -1; 81 const double kDefaultXMin = -1;
119 const double kDefaultYMin = -1; 82 const double kDefaultYMin = -1;
120 83
121 } // namespace 84 } // namespace
122 85
123 namespace webrtc { 86 namespace webrtc {
124 namespace plotting { 87 namespace plotting {
125 88
89
90 bool EventLogAnalyzer::StreamId::operator<(const StreamId& other) const {
91 if (ssrc_ < other.ssrc_) {
92 return true;
93 }
94 if (ssrc_ == other.ssrc_) {
95 if (media_type_ < other.media_type_) {
96 return true;
97 }
98 if (media_type_ == other.media_type_) {
99 if (direction_ < other.direction_) {
100 return true;
101 }
102 }
103 }
104 return false;
105 }
106
107 bool EventLogAnalyzer::StreamId::operator==(const StreamId& other) const {
108 return ssrc_ == other.ssrc_ && direction_ == other.direction_ &&
109 media_type_ == other.media_type_;
110 }
111
112
126 EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log) 113 EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
127 : parsed_log_(log), window_duration_(250000), step_(10000) { 114 : parsed_log_(log), window_duration_(250000), step_(10000) {
128 uint64_t first_timestamp = std::numeric_limits<uint64_t>::max(); 115 uint64_t first_timestamp = std::numeric_limits<uint64_t>::max();
129 uint64_t last_timestamp = std::numeric_limits<uint64_t>::min(); 116 uint64_t last_timestamp = std::numeric_limits<uint64_t>::min();
117
118 // Maps a stream identifier consisting of ssrc, direction and MediaType
119 // to the header extensions used by that stream,
120 std::map<StreamId, RtpHeaderExtensionMap> extension_maps;
121
122 PacketDirection direction;
123 MediaType media_type;
124 uint8_t header[IP_PACKET_SIZE];
125 size_t header_length;
126 size_t total_length;
127
130 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 128 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) {
131 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 129 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i);
132 if (event_type == ParsedRtcEventLog::EventType::VIDEO_RECEIVER_CONFIG_EVENT) 130 if (event_type != ParsedRtcEventLog::VIDEO_RECEIVER_CONFIG_EVENT &&
133 continue; 131 event_type != ParsedRtcEventLog::VIDEO_SENDER_CONFIG_EVENT &&
134 if (event_type == ParsedRtcEventLog::EventType::VIDEO_SENDER_CONFIG_EVENT) 132 event_type != ParsedRtcEventLog::AUDIO_RECEIVER_CONFIG_EVENT &&
135 continue; 133 event_type != ParsedRtcEventLog::AUDIO_SENDER_CONFIG_EVENT) {
136 if (event_type == ParsedRtcEventLog::EventType::AUDIO_RECEIVER_CONFIG_EVENT) 134 uint64_t timestamp = parsed_log_.GetTimestamp(i);
137 continue; 135 first_timestamp = std::min(first_timestamp, timestamp);
138 if (event_type == ParsedRtcEventLog::EventType::AUDIO_SENDER_CONFIG_EVENT) 136 last_timestamp = std::max(last_timestamp, timestamp);
139 continue; 137 }
140 uint64_t timestamp = parsed_log_.GetTimestamp(i); 138
141 first_timestamp = std::min(first_timestamp, timestamp); 139 switch (parsed_log_.GetEventType(i)) {
142 last_timestamp = std::max(last_timestamp, timestamp); 140 case ParsedRtcEventLog::VIDEO_RECEIVER_CONFIG_EVENT: {
141 VideoReceiveStream::Config config(nullptr);
142 parsed_log_.GetVideoReceiveConfig(i, &config);
143 StreamId stream(config.rtp.remote_ssrc, kIncomingPacket,
144 MediaType::VIDEO);
145 extension_maps[stream].Erase();
146 for (size_t j = 0; j < config.rtp.extensions.size(); ++j) {
147 const std::string& extension = config.rtp.extensions[j].uri;
148 int id = config.rtp.extensions[j].id;
149 extension_maps[stream].Register(StringToRtpExtensionType(extension),
150 id);
151 }
152 break;
153 }
154 case ParsedRtcEventLog::VIDEO_SENDER_CONFIG_EVENT: {
155 VideoSendStream::Config config(nullptr);
156 parsed_log_.GetVideoSendConfig(i, &config);
157 for (auto ssrc : config.rtp.ssrcs) {
158 StreamId stream(ssrc, kOutgoingPacket, MediaType::VIDEO);
159 extension_maps[stream].Erase();
160 for (size_t j = 0; j < config.rtp.extensions.size(); ++j) {
161 const std::string& extension = config.rtp.extensions[j].uri;
162 int id = config.rtp.extensions[j].id;
163 extension_maps[stream].Register(StringToRtpExtensionType(extension),
164 id);
165 }
166 }
167 break;
168 }
169 case ParsedRtcEventLog::AUDIO_RECEIVER_CONFIG_EVENT: {
170 AudioReceiveStream::Config config;
171 // TODO(terelius): Parse the audio configs once we have them.
172 break;
173 }
174 case ParsedRtcEventLog::AUDIO_SENDER_CONFIG_EVENT: {
175 AudioSendStream::Config config(nullptr);
176 // TODO(terelius): Parse the audio configs once we have them.
177 break;
178 }
179 case ParsedRtcEventLog::RTP_EVENT: {
180 parsed_log_.GetRtpHeader(i, &direction, &media_type, header,
181 &header_length, &total_length);
182 // Parse header to get SSRC.
183 RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
184 RTPHeader parsed_header;
185 rtp_parser.Parse(&parsed_header);
186 StreamId stream(parsed_header.ssrc, direction, media_type);
187 // Look up the extension_map and parse it again to get the extensions.
188 if (extension_maps.count(stream) == 1) {
189 RtpHeaderExtensionMap* extension_map = &extension_maps[stream];
190 rtp_parser.Parse(&parsed_header, extension_map);
191 }
192 uint64_t timestamp = parsed_log_.GetTimestamp(i);
193 rtp_packets_[stream].push_back(
194 LoggedRtpPacket(timestamp, parsed_header));
195 break;
196 }
197 case ParsedRtcEventLog::RTCP_EVENT: {
198 break;
199 }
200 case ParsedRtcEventLog::LOG_START: {
201 break;
202 }
203 case ParsedRtcEventLog::LOG_END: {
204 break;
205 }
206 case ParsedRtcEventLog::BWE_PACKET_LOSS_EVENT: {
207 break;
208 }
209 case ParsedRtcEventLog::BWE_PACKET_DELAY_EVENT: {
210 break;
211 }
212 case ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT: {
213 break;
214 }
215 case ParsedRtcEventLog::UNKNOWN_EVENT: {
216 break;
217 }
218 }
143 } 219 }
220
144 if (last_timestamp < first_timestamp) { 221 if (last_timestamp < first_timestamp) {
145 // No useful events in the log. 222 // No useful events in the log.
146 first_timestamp = last_timestamp = 0; 223 first_timestamp = last_timestamp = 0;
147 } 224 }
148 begin_time_ = first_timestamp; 225 begin_time_ = first_timestamp;
149 end_time_ = last_timestamp; 226 end_time_ = last_timestamp;
150 } 227 }
151 228
152 void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction, 229 void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction,
153 Plot* plot) { 230 Plot* plot) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 plot->xaxis_min = kDefaultXMin; 377 plot->xaxis_min = kDefaultXMin;
301 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 378 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin;
302 plot->xaxis_label = "Time (s)"; 379 plot->xaxis_label = "Time (s)";
303 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 380 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y);
304 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y); 381 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
305 plot->yaxis_label = "Difference since last packet"; 382 plot->yaxis_label = "Difference since last packet";
306 plot->title = "Sequence number"; 383 plot->title = "Sequence number";
307 } 384 }
308 385
309 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) { 386 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) {
310 // Maps a stream identifier consisting of ssrc, direction and MediaType
311 // to the header extensions used by that stream,
312 std::map<StreamId, RtpHeaderExtensionMap> extension_maps;
313
314 struct SendReceiveTime {
315 SendReceiveTime() = default;
316 SendReceiveTime(uint32_t send_time, uint64_t recv_time)
317 : absolute_send_time(send_time), receive_timestamp(recv_time) {}
318 uint32_t absolute_send_time; // 24-bit value in units of 2^-18 seconds.
319 uint64_t receive_timestamp; // In microseconds.
320 };
321 std::map<StreamId, SendReceiveTime> last_packet;
322 std::map<StreamId, TimeSeries> time_series;
323
324 PacketDirection direction;
325 MediaType media_type;
326 uint8_t header[IP_PACKET_SIZE];
327 size_t header_length, total_length;
328
329 double max_y = 10; 387 double max_y = 10;
330 double min_y = 0; 388 double min_y = 0;
331 389
332 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 390 for (auto& kv : rtp_packets_) {
333 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 391 StreamId stream_id = kv.first;
334 if (event_type == ParsedRtcEventLog::VIDEO_RECEIVER_CONFIG_EVENT) { 392 // Filter on direction and SSRC.
335 VideoReceiveStream::Config config(nullptr); 393 if (stream_id.GetDirection() != kIncomingPacket ||
336 parsed_log_.GetVideoReceiveConfig(i, &config); 394 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) {
337 StreamId stream(config.rtp.remote_ssrc, kIncomingPacket, 395 continue;
338 MediaType::VIDEO); 396 }
339 extension_maps[stream].Erase(); 397
340 for (size_t j = 0; j < config.rtp.extensions.size(); ++j) { 398 TimeSeries time_series;
341 const std::string& extension = config.rtp.extensions[j].uri; 399 time_series.label = SsrcToString(stream_id.GetSsrc());
342 int id = config.rtp.extensions[j].id; 400 time_series.style = BAR_GRAPH;
343 extension_maps[stream].Register(StringToRtpExtensionType(extension), 401 const std::vector<LoggedRtpPacket>& packet_stream = kv.second;
344 id); 402 int64_t last_abs_send_time = 0;
345 } 403 int64_t last_timestamp = 0;
346 } else if (event_type == ParsedRtcEventLog::VIDEO_SENDER_CONFIG_EVENT) { 404 for (const LoggedRtpPacket& packet : packet_stream) {
347 VideoSendStream::Config config(nullptr); 405 if (packet.header.extension.hasAbsoluteSendTime) {
348 parsed_log_.GetVideoSendConfig(i, &config); 406 int64_t send_time_diff =
349 for (auto ssrc : config.rtp.ssrcs) { 407 WrappingDifference(packet.header.extension.absoluteSendTime,
350 StreamId stream(ssrc, kIncomingPacket, MediaType::VIDEO); 408 last_abs_send_time, 1ul << 24);
351 extension_maps[stream].Erase(); 409 int64_t recv_time_diff = packet.timestamp - last_timestamp;
352 for (size_t j = 0; j < config.rtp.extensions.size(); ++j) { 410
353 const std::string& extension = config.rtp.extensions[j].uri; 411 last_abs_send_time = packet.header.extension.absoluteSendTime;
354 int id = config.rtp.extensions[j].id; 412 last_timestamp = packet.timestamp;
355 extension_maps[stream].Register(StringToRtpExtensionType(extension), 413
356 id); 414 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
415 double y =
416 static_cast<double>(recv_time_diff -
417 AbsSendTimeToMicroseconds(send_time_diff)) /
418 1000;
419 if (time_series.points.size() == 0) {
420 // There were no previously logged packets for this SSRC.
421 // Generate a point, but place it on the x-axis.
422 y = 0;
357 } 423 }
358 } 424 max_y = std::max(max_y, y);
359 } else if (event_type == ParsedRtcEventLog::AUDIO_RECEIVER_CONFIG_EVENT) { 425 min_y = std::min(min_y, y);
360 AudioReceiveStream::Config config; 426 time_series.points.emplace_back(x, y);
361 // TODO(terelius): Parse the audio configs once we have them
362 } else if (event_type == ParsedRtcEventLog::AUDIO_SENDER_CONFIG_EVENT) {
363 AudioSendStream::Config config(nullptr);
364 // TODO(terelius): Parse the audio configs once we have them
365 } else if (event_type == ParsedRtcEventLog::RTP_EVENT) {
366 parsed_log_.GetRtpHeader(i, &direction, &media_type, header,
367 &header_length, &total_length);
368 if (direction == kIncomingPacket) {
369 // Parse header to get SSRC.
370 RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
371 RTPHeader parsed_header;
372 rtp_parser.Parse(&parsed_header);
373 // Filter on SSRC.
374 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) {
375 StreamId stream(parsed_header.ssrc, direction, media_type);
376 // Look up the extension_map and parse it again to get the extensions.
377 if (extension_maps.count(stream) == 1) {
378 RtpHeaderExtensionMap* extension_map = &extension_maps[stream];
379 rtp_parser.Parse(&parsed_header, extension_map);
380 if (parsed_header.extension.hasAbsoluteSendTime) {
381 uint64_t timestamp = parsed_log_.GetTimestamp(i);
382 int64_t send_time_diff = WrappingDifference(
383 parsed_header.extension.absoluteSendTime,
384 last_packet[stream].absolute_send_time, 1ul << 24);
385 int64_t recv_time_diff =
386 timestamp - last_packet[stream].receive_timestamp;
387
388 float x = static_cast<float>(timestamp - begin_time_) / 1000000;
389 double y = static_cast<double>(
390 recv_time_diff -
391 AbsSendTimeToMicroseconds(send_time_diff)) /
392 1000;
393 if (time_series[stream].points.size() == 0) {
394 // There were no previusly logged playout for this SSRC.
395 // Generate a point, but place it on the x-axis.
396 y = 0;
397 }
398 max_y = std::max(max_y, y);
399 min_y = std::min(min_y, y);
400 time_series[stream].points.push_back(TimeSeriesPoint(x, y));
401 last_packet[stream] = SendReceiveTime(
402 parsed_header.extension.absoluteSendTime, timestamp);
403 }
404 }
405 }
406 } 427 }
407 } 428 }
408 } 429 // Add the data set to the plot.
409 430 plot->series.push_back(std::move(time_series));
410 // Set labels and put in graph.
411 for (auto& kv : time_series) {
412 kv.second.label = SsrcToString(kv.first.GetSsrc());
413 kv.second.style = BAR_GRAPH;
414 plot->series.push_back(std::move(kv.second));
415 } 431 }
416 432
417 plot->xaxis_min = kDefaultXMin; 433 plot->xaxis_min = kDefaultXMin;
418 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 434 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin;
419 plot->xaxis_label = "Time (s)"; 435 plot->xaxis_label = "Time (s)";
420 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 436 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y);
421 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y); 437 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
422 plot->yaxis_label = "Latency change (ms)"; 438 plot->yaxis_label = "Latency change (ms)";
423 plot->title = "Network latency change between consecutive packets"; 439 plot->title = "Network latency change between consecutive packets";
424 } 440 }
425 441
426 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) { 442 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) {
427 // TODO(terelius): Refactor
428
429 // Maps a stream identifier consisting of ssrc, direction and MediaType
430 // to the header extensions used by that stream.
431 std::map<StreamId, RtpHeaderExtensionMap> extension_maps;
432
433 struct SendReceiveTime {
434 SendReceiveTime() = default;
435 SendReceiveTime(uint32_t send_time, uint64_t recv_time, double accumulated)
436 : absolute_send_time(send_time),
437 receive_timestamp(recv_time),
438 accumulated_delay(accumulated) {}
439 uint32_t absolute_send_time; // 24-bit value in units of 2^-18 seconds.
440 uint64_t receive_timestamp; // In microseconds.
441 double accumulated_delay; // In milliseconds.
442 };
443 std::map<StreamId, SendReceiveTime> last_packet;
444 std::map<StreamId, TimeSeries> time_series;
445
446 PacketDirection direction;
447 MediaType media_type;
448 uint8_t header[IP_PACKET_SIZE];
449 size_t header_length, total_length;
450
451 double max_y = 10; 443 double max_y = 10;
452 double min_y = 0; 444 double min_y = 0;
453 445
454 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 446 for (auto& kv : rtp_packets_) {
455 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 447 StreamId stream_id = kv.first;
456 if (event_type == ParsedRtcEventLog::VIDEO_RECEIVER_CONFIG_EVENT) { 448 // Filter on direction and SSRC.
457 VideoReceiveStream::Config config(nullptr); 449 if (stream_id.GetDirection() != kIncomingPacket ||
458 parsed_log_.GetVideoReceiveConfig(i, &config); 450 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) {
459 StreamId stream(config.rtp.remote_ssrc, kIncomingPacket, 451 continue;
460 MediaType::VIDEO); 452 }
461 extension_maps[stream].Erase(); 453 TimeSeries time_series;
462 for (size_t j = 0; j < config.rtp.extensions.size(); ++j) { 454 time_series.label = SsrcToString(stream_id.GetSsrc());
463 const std::string& extension = config.rtp.extensions[j].uri; 455 time_series.style = LINE_GRAPH;
464 int id = config.rtp.extensions[j].id; 456 const std::vector<LoggedRtpPacket>& packet_stream = kv.second;
465 extension_maps[stream].Register(StringToRtpExtensionType(extension), 457 int64_t last_abs_send_time = 0;
466 id); 458 int64_t last_timestamp = 0;
467 } 459 double accumulated_delay_ms = 0;
468 } else if (event_type == ParsedRtcEventLog::VIDEO_SENDER_CONFIG_EVENT) { 460 for (const LoggedRtpPacket& packet : packet_stream) {
469 VideoSendStream::Config config(nullptr); 461 if (packet.header.extension.hasAbsoluteSendTime) {
470 parsed_log_.GetVideoSendConfig(i, &config); 462 int64_t send_time_diff =
471 for (auto ssrc : config.rtp.ssrcs) { 463 WrappingDifference(packet.header.extension.absoluteSendTime,
472 StreamId stream(ssrc, kIncomingPacket, MediaType::VIDEO); 464 last_abs_send_time, 1ul << 24);
473 extension_maps[stream].Erase(); 465 int64_t recv_time_diff = packet.timestamp - last_timestamp;
474 for (size_t j = 0; j < config.rtp.extensions.size(); ++j) { 466
475 const std::string& extension = config.rtp.extensions[j].uri; 467 last_abs_send_time = packet.header.extension.absoluteSendTime;
476 int id = config.rtp.extensions[j].id; 468 last_timestamp = packet.timestamp;
477 extension_maps[stream].Register(StringToRtpExtensionType(extension), 469
478 id); 470 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
471 accumulated_delay_ms +=
472 static_cast<double>(recv_time_diff -
473 AbsSendTimeToMicroseconds(send_time_diff)) /
474 1000;
475 if (time_series.points.size() == 0) {
476 // There were no previously logged packets for this SSRC.
477 // Generate a point, but place it on the x-axis.
478 accumulated_delay_ms = 0;
479 } 479 }
480 } 480 max_y = std::max(max_y, accumulated_delay_ms);
481 } else if (event_type == ParsedRtcEventLog::AUDIO_RECEIVER_CONFIG_EVENT) { 481 min_y = std::min(min_y, accumulated_delay_ms);
482 AudioReceiveStream::Config config; 482 time_series.points.emplace_back(x, accumulated_delay_ms);
483 // TODO(terelius): Parse the audio configs once we have them
484 } else if (event_type == ParsedRtcEventLog::AUDIO_SENDER_CONFIG_EVENT) {
485 AudioSendStream::Config config(nullptr);
486 // TODO(terelius): Parse the audio configs once we have them
487 } else if (event_type == ParsedRtcEventLog::RTP_EVENT) {
488 parsed_log_.GetRtpHeader(i, &direction, &media_type, header,
489 &header_length, &total_length);
490 if (direction == kIncomingPacket) {
491 // Parse header to get SSRC.
492 RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
493 RTPHeader parsed_header;
494 rtp_parser.Parse(&parsed_header);
495 // Filter on SSRC.
496 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) {
497 StreamId stream(parsed_header.ssrc, direction, media_type);
498 // Look up the extension_map and parse it again to get the extensions.
499 if (extension_maps.count(stream) == 1) {
500 RtpHeaderExtensionMap* extension_map = &extension_maps[stream];
501 rtp_parser.Parse(&parsed_header, extension_map);
502 if (parsed_header.extension.hasAbsoluteSendTime) {
503 uint64_t timestamp = parsed_log_.GetTimestamp(i);
504 int64_t send_time_diff = WrappingDifference(
505 parsed_header.extension.absoluteSendTime,
506 last_packet[stream].absolute_send_time, 1ul << 24);
507 int64_t recv_time_diff =
508 timestamp - last_packet[stream].receive_timestamp;
509
510 float x = static_cast<float>(timestamp - begin_time_) / 1000000;
511 double y = last_packet[stream].accumulated_delay +
512 static_cast<double>(
513 recv_time_diff -
514 AbsSendTimeToMicroseconds(send_time_diff)) /
515 1000;
516 if (time_series[stream].points.size() == 0) {
517 // There were no previusly logged playout for this SSRC.
518 // Generate a point, but place it on the x-axis.
519 y = 0;
520 }
521 max_y = std::max(max_y, y);
522 min_y = std::min(min_y, y);
523 time_series[stream].points.push_back(TimeSeriesPoint(x, y));
524 last_packet[stream] = SendReceiveTime(
525 parsed_header.extension.absoluteSendTime, timestamp, y);
526 }
527 }
528 }
529 } 483 }
530 } 484 }
531 } 485 // Add the data set to the plot.
532 486 plot->series.push_back(std::move(time_series));
533 // Set labels and put in graph.
534 for (auto& kv : time_series) {
535 kv.second.label = SsrcToString(kv.first.GetSsrc());
536 kv.second.style = LINE_GRAPH;
537 plot->series.push_back(std::move(kv.second));
538 } 487 }
539 488
540 plot->xaxis_min = kDefaultXMin; 489 plot->xaxis_min = kDefaultXMin;
541 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 490 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin;
542 plot->xaxis_label = "Time (s)"; 491 plot->xaxis_label = "Time (s)";
543 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 492 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y);
544 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y); 493 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
545 plot->yaxis_label = "Latency change (ms)"; 494 plot->yaxis_label = "Latency change (ms)";
546 plot->title = "Accumulated network latency change"; 495 plot->title = "Accumulated network latency change";
547 } 496 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 572
624 // For each SSRC, plot the bandwidth used by that stream. 573 // For each SSRC, plot the bandwidth used by that stream.
625 void EventLogAnalyzer::CreateStreamBitrateGraph( 574 void EventLogAnalyzer::CreateStreamBitrateGraph(
626 PacketDirection desired_direction, 575 PacketDirection desired_direction,
627 Plot* plot) { 576 Plot* plot) {
628 struct TimestampSize { 577 struct TimestampSize {
629 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {} 578 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {}
630 uint64_t timestamp; 579 uint64_t timestamp;
631 size_t size; 580 size_t size;
632 }; 581 };
633 std::map<uint32_t, std::vector<TimestampSize> > packets; 582 std::map<uint32_t, std::vector<TimestampSize>> packets;
634 583
635 PacketDirection direction; 584 PacketDirection direction;
636 MediaType media_type; 585 MediaType media_type;
637 uint8_t header[IP_PACKET_SIZE]; 586 uint8_t header[IP_PACKET_SIZE];
638 size_t header_length, total_length; 587 size_t header_length, total_length;
639 588
640 // Extract timestamps and sizes for the relevant packets. 589 // Extract timestamps and sizes for the relevant packets.
641 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 590 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) {
642 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 591 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i);
643 if (event_type == ParsedRtcEventLog::RTP_EVENT) { 592 if (event_type == ParsedRtcEventLog::RTP_EVENT) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 plot->yaxis_label = "Bitrate (kbps)"; 650 plot->yaxis_label = "Bitrate (kbps)";
702 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 651 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
703 plot->title = "Incoming bitrate per stream"; 652 plot->title = "Incoming bitrate per stream";
704 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 653 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
705 plot->title = "Outgoing bitrate per stream"; 654 plot->title = "Outgoing bitrate per stream";
706 } 655 }
707 } 656 }
708 657
709 } // namespace plotting 658 } // namespace plotting
710 } // namespace webrtc 659 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/tools/event_log_visualizer/analyzer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698