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

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

Issue 2179223003: Convenience functions to set axis properties in visualization tool. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Change literal type to avoid VC++ compile warning Created 4 years, 4 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
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 14 matching lines...) Expand all
25 #include "webrtc/common_types.h" 25 #include "webrtc/common_types.h"
26 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" 26 #include "webrtc/modules/congestion_controller/include/congestion_controller.h"
27 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 27 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
28 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 28 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
29 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 29 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
30 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" 30 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
31 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" 31 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
32 #include "webrtc/video_receive_stream.h" 32 #include "webrtc/video_receive_stream.h"
33 #include "webrtc/video_send_stream.h" 33 #include "webrtc/video_send_stream.h"
34 34
35 namespace webrtc {
36 namespace plotting {
37
35 namespace { 38 namespace {
36 39
37 std::string SsrcToString(uint32_t ssrc) { 40 std::string SsrcToString(uint32_t ssrc) {
38 std::stringstream ss; 41 std::stringstream ss;
39 ss << "SSRC " << ssrc; 42 ss << "SSRC " << ssrc;
40 return ss.str(); 43 return ss.str();
41 } 44 }
42 45
43 // Checks whether an SSRC is contained in the list of desired SSRCs. 46 // Checks whether an SSRC is contained in the list of desired SSRCs.
44 // Note that an empty SSRC list matches every SSRC. 47 // Note that an empty SSRC list matches every SSRC.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 void RegisterHeaderExtensions( 86 void RegisterHeaderExtensions(
84 const std::vector<webrtc::RtpExtension>& extensions, 87 const std::vector<webrtc::RtpExtension>& extensions,
85 webrtc::RtpHeaderExtensionMap* extension_map) { 88 webrtc::RtpHeaderExtensionMap* extension_map) {
86 extension_map->Erase(); 89 extension_map->Erase();
87 for (const webrtc::RtpExtension& extension : extensions) { 90 for (const webrtc::RtpExtension& extension : extensions) {
88 extension_map->Register(webrtc::StringToRtpExtensionType(extension.uri), 91 extension_map->Register(webrtc::StringToRtpExtensionType(extension.uri),
89 extension.id); 92 extension.id);
90 } 93 }
91 } 94 }
92 95
93 const double kXMargin = 1.02; 96 constexpr float kLeftMargin = 0.01f;
94 const double kYMargin = 1.1; 97 constexpr float kRightMargin = 0.02f;
95 const double kDefaultXMin = -1; 98 constexpr float kBottomMargin = 0.02f;
96 const double kDefaultYMin = -1; 99 constexpr float kTopMargin = 0.05f;
97 100
98 } // namespace 101 } // namespace
99 102
100 namespace webrtc {
101 namespace plotting {
102
103
104 bool EventLogAnalyzer::StreamId::operator<(const StreamId& other) const { 103 bool EventLogAnalyzer::StreamId::operator<(const StreamId& other) const {
105 if (ssrc_ < other.ssrc_) { 104 if (ssrc_ < other.ssrc_) {
106 return true; 105 return true;
107 } 106 }
108 if (ssrc_ == other.ssrc_) { 107 if (ssrc_ == other.ssrc_) {
109 if (direction_ < other.direction_) { 108 if (direction_ < other.direction_) {
110 return true; 109 return true;
111 } 110 }
112 } 111 }
113 return false; 112 return false;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 264 }
266 } 265 }
267 } 266 }
268 267
269 if (last_timestamp < first_timestamp) { 268 if (last_timestamp < first_timestamp) {
270 // No useful events in the log. 269 // No useful events in the log.
271 first_timestamp = last_timestamp = 0; 270 first_timestamp = last_timestamp = 0;
272 } 271 }
273 begin_time_ = first_timestamp; 272 begin_time_ = first_timestamp;
274 end_time_ = last_timestamp; 273 end_time_ = last_timestamp;
274 call_duration_s_ = static_cast<float>(end_time_ - begin_time_) / 1000000;
275 } 275 }
276 276
277 class BitrateObserver : public CongestionController::Observer, 277 class BitrateObserver : public CongestionController::Observer,
278 public RemoteBitrateObserver { 278 public RemoteBitrateObserver {
279 public: 279 public:
280 BitrateObserver() : last_bitrate_bps_(0), bitrate_updated_(false) {} 280 BitrateObserver() : last_bitrate_bps_(0), bitrate_updated_(false) {}
281 281
282 void OnNetworkChanged(uint32_t bitrate_bps, 282 void OnNetworkChanged(uint32_t bitrate_bps,
283 uint8_t fraction_loss, 283 uint8_t fraction_loss,
284 int64_t rtt_ms) override { 284 int64_t rtt_ms) override {
(...skipping 17 matching lines...) Expand all
302 }; 302 };
303 303
304 void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction, 304 void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction,
305 Plot* plot) { 305 Plot* plot) {
306 std::map<uint32_t, TimeSeries> time_series; 306 std::map<uint32_t, TimeSeries> time_series;
307 307
308 PacketDirection direction; 308 PacketDirection direction;
309 MediaType media_type; 309 MediaType media_type;
310 uint8_t header[IP_PACKET_SIZE]; 310 uint8_t header[IP_PACKET_SIZE];
311 size_t header_length, total_length; 311 size_t header_length, total_length;
312 float max_y = 0;
313 312
314 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 313 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) {
315 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 314 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i);
316 if (event_type == ParsedRtcEventLog::RTP_EVENT) { 315 if (event_type == ParsedRtcEventLog::RTP_EVENT) {
317 parsed_log_.GetRtpHeader(i, &direction, &media_type, header, 316 parsed_log_.GetRtpHeader(i, &direction, &media_type, header,
318 &header_length, &total_length); 317 &header_length, &total_length);
319 if (direction == desired_direction) { 318 if (direction == desired_direction) {
320 // Parse header to get SSRC. 319 // Parse header to get SSRC.
321 RtpUtility::RtpHeaderParser rtp_parser(header, header_length); 320 RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
322 RTPHeader parsed_header; 321 RTPHeader parsed_header;
323 rtp_parser.Parse(&parsed_header); 322 rtp_parser.Parse(&parsed_header);
324 // Filter on SSRC. 323 // Filter on SSRC.
325 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) { 324 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) {
326 uint64_t timestamp = parsed_log_.GetTimestamp(i); 325 uint64_t timestamp = parsed_log_.GetTimestamp(i);
327 float x = static_cast<float>(timestamp - begin_time_) / 1000000; 326 float x = static_cast<float>(timestamp - begin_time_) / 1000000;
328 float y = total_length; 327 float y = total_length;
329 max_y = std::max(max_y, y);
330 time_series[parsed_header.ssrc].points.push_back( 328 time_series[parsed_header.ssrc].points.push_back(
331 TimeSeriesPoint(x, y)); 329 TimeSeriesPoint(x, y));
332 } 330 }
333 } 331 }
334 } 332 }
335 } 333 }
336 334
337 // Set labels and put in graph. 335 // Set labels and put in graph.
338 for (auto& kv : time_series) { 336 for (auto& kv : time_series) {
339 kv.second.label = SsrcToString(kv.first); 337 kv.second.label = SsrcToString(kv.first);
340 kv.second.style = BAR_GRAPH; 338 kv.second.style = BAR_GRAPH;
341 plot->series.push_back(std::move(kv.second)); 339 plot->series_list_.push_back(std::move(kv.second));
342 } 340 }
343 341
344 plot->xaxis_min = kDefaultXMin; 342 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
345 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 343 plot->SetSuggestedYAxis(0, 1, "Packet size (bytes)", kBottomMargin,
346 plot->xaxis_label = "Time (s)"; 344 kTopMargin);
347 plot->yaxis_min = kDefaultYMin;
348 plot->yaxis_max = max_y * kYMargin;
349 plot->yaxis_label = "Packet size (bytes)";
350 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 345 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
351 plot->title = "Incoming RTP packets"; 346 plot->SetTitle("Incoming RTP packets");
352 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 347 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
353 plot->title = "Outgoing RTP packets"; 348 plot->SetTitle("Outgoing RTP packets");
354 } 349 }
355 } 350 }
356 351
357 // For each SSRC, plot the time between the consecutive playouts. 352 // For each SSRC, plot the time between the consecutive playouts.
358 void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) { 353 void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) {
359 std::map<uint32_t, TimeSeries> time_series; 354 std::map<uint32_t, TimeSeries> time_series;
360 std::map<uint32_t, uint64_t> last_playout; 355 std::map<uint32_t, uint64_t> last_playout;
361 356
362 uint32_t ssrc; 357 uint32_t ssrc;
363 float max_y = 0;
364 358
365 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 359 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) {
366 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 360 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i);
367 if (event_type == ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT) { 361 if (event_type == ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT) {
368 parsed_log_.GetAudioPlayout(i, &ssrc); 362 parsed_log_.GetAudioPlayout(i, &ssrc);
369 uint64_t timestamp = parsed_log_.GetTimestamp(i); 363 uint64_t timestamp = parsed_log_.GetTimestamp(i);
370 if (MatchingSsrc(ssrc, desired_ssrc_)) { 364 if (MatchingSsrc(ssrc, desired_ssrc_)) {
371 float x = static_cast<float>(timestamp - begin_time_) / 1000000; 365 float x = static_cast<float>(timestamp - begin_time_) / 1000000;
372 float y = static_cast<float>(timestamp - last_playout[ssrc]) / 1000; 366 float y = static_cast<float>(timestamp - last_playout[ssrc]) / 1000;
373 if (time_series[ssrc].points.size() == 0) { 367 if (time_series[ssrc].points.size() == 0) {
374 // There were no previusly logged playout for this SSRC. 368 // There were no previusly logged playout for this SSRC.
375 // Generate a point, but place it on the x-axis. 369 // Generate a point, but place it on the x-axis.
376 y = 0; 370 y = 0;
377 } 371 }
378 max_y = std::max(max_y, y);
379 time_series[ssrc].points.push_back(TimeSeriesPoint(x, y)); 372 time_series[ssrc].points.push_back(TimeSeriesPoint(x, y));
380 last_playout[ssrc] = timestamp; 373 last_playout[ssrc] = timestamp;
381 } 374 }
382 } 375 }
383 } 376 }
384 377
385 // Set labels and put in graph. 378 // Set labels and put in graph.
386 for (auto& kv : time_series) { 379 for (auto& kv : time_series) {
387 kv.second.label = SsrcToString(kv.first); 380 kv.second.label = SsrcToString(kv.first);
388 kv.second.style = BAR_GRAPH; 381 kv.second.style = BAR_GRAPH;
389 plot->series.push_back(std::move(kv.second)); 382 plot->series_list_.push_back(std::move(kv.second));
390 } 383 }
391 384
392 plot->xaxis_min = kDefaultXMin; 385 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
393 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 386 plot->SetSuggestedYAxis(0, 1, "Time since last playout (ms)", kBottomMargin,
394 plot->xaxis_label = "Time (s)"; 387 kTopMargin);
395 plot->yaxis_min = kDefaultYMin; 388 plot->SetTitle("Audio playout");
396 plot->yaxis_max = max_y * kYMargin;
397 plot->yaxis_label = "Time since last playout (ms)";
398 plot->title = "Audio playout";
399 } 389 }
400 390
401 // For each SSRC, plot the time between the consecutive playouts. 391 // For each SSRC, plot the time between the consecutive playouts.
402 void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) { 392 void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) {
403 std::map<uint32_t, TimeSeries> time_series; 393 std::map<uint32_t, TimeSeries> time_series;
404 std::map<uint32_t, uint16_t> last_seqno; 394 std::map<uint32_t, uint16_t> last_seqno;
405 395
406 PacketDirection direction; 396 PacketDirection direction;
407 MediaType media_type; 397 MediaType media_type;
408 uint8_t header[IP_PACKET_SIZE]; 398 uint8_t header[IP_PACKET_SIZE];
409 size_t header_length, total_length; 399 size_t header_length, total_length;
410 400
411 int max_y = 1;
412 int min_y = 0;
413
414 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 401 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) {
415 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 402 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i);
416 if (event_type == ParsedRtcEventLog::RTP_EVENT) { 403 if (event_type == ParsedRtcEventLog::RTP_EVENT) {
417 parsed_log_.GetRtpHeader(i, &direction, &media_type, header, 404 parsed_log_.GetRtpHeader(i, &direction, &media_type, header,
418 &header_length, &total_length); 405 &header_length, &total_length);
419 uint64_t timestamp = parsed_log_.GetTimestamp(i); 406 uint64_t timestamp = parsed_log_.GetTimestamp(i);
420 if (direction == PacketDirection::kIncomingPacket) { 407 if (direction == PacketDirection::kIncomingPacket) {
421 // Parse header to get SSRC. 408 // Parse header to get SSRC.
422 RtpUtility::RtpHeaderParser rtp_parser(header, header_length); 409 RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
423 RTPHeader parsed_header; 410 RTPHeader parsed_header;
424 rtp_parser.Parse(&parsed_header); 411 rtp_parser.Parse(&parsed_header);
425 // Filter on SSRC. 412 // Filter on SSRC.
426 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) { 413 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) {
427 float x = static_cast<float>(timestamp - begin_time_) / 1000000; 414 float x = static_cast<float>(timestamp - begin_time_) / 1000000;
428 int y = WrappingDifference(parsed_header.sequenceNumber, 415 int y = WrappingDifference(parsed_header.sequenceNumber,
429 last_seqno[parsed_header.ssrc], 1ul << 16); 416 last_seqno[parsed_header.ssrc], 1ul << 16);
430 if (time_series[parsed_header.ssrc].points.size() == 0) { 417 if (time_series[parsed_header.ssrc].points.size() == 0) {
431 // There were no previusly logged playout for this SSRC. 418 // There were no previusly logged playout for this SSRC.
432 // Generate a point, but place it on the x-axis. 419 // Generate a point, but place it on the x-axis.
433 y = 0; 420 y = 0;
434 } 421 }
435 max_y = std::max(max_y, y);
436 min_y = std::min(min_y, y);
437 time_series[parsed_header.ssrc].points.push_back( 422 time_series[parsed_header.ssrc].points.push_back(
438 TimeSeriesPoint(x, y)); 423 TimeSeriesPoint(x, y));
439 last_seqno[parsed_header.ssrc] = parsed_header.sequenceNumber; 424 last_seqno[parsed_header.ssrc] = parsed_header.sequenceNumber;
440 } 425 }
441 } 426 }
442 } 427 }
443 } 428 }
444 429
445 // Set labels and put in graph. 430 // Set labels and put in graph.
446 for (auto& kv : time_series) { 431 for (auto& kv : time_series) {
447 kv.second.label = SsrcToString(kv.first); 432 kv.second.label = SsrcToString(kv.first);
448 kv.second.style = BAR_GRAPH; 433 kv.second.style = BAR_GRAPH;
449 plot->series.push_back(std::move(kv.second)); 434 plot->series_list_.push_back(std::move(kv.second));
450 } 435 }
451 436
452 plot->xaxis_min = kDefaultXMin; 437 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
453 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 438 plot->SetSuggestedYAxis(0, 1, "Difference since last packet", kBottomMargin,
454 plot->xaxis_label = "Time (s)"; 439 kTopMargin);
455 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 440 plot->SetTitle("Sequence number");
456 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
457 plot->yaxis_label = "Difference since last packet";
458 plot->title = "Sequence number";
459 } 441 }
460 442
461 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) { 443 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) {
462 double max_y = 10;
463 double min_y = 0;
464
465 for (auto& kv : rtp_packets_) { 444 for (auto& kv : rtp_packets_) {
466 StreamId stream_id = kv.first; 445 StreamId stream_id = kv.first;
467 // Filter on direction and SSRC. 446 // Filter on direction and SSRC.
468 if (stream_id.GetDirection() != kIncomingPacket || 447 if (stream_id.GetDirection() != kIncomingPacket ||
469 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { 448 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) {
470 continue; 449 continue;
471 } 450 }
472 451
473 TimeSeries time_series; 452 TimeSeries time_series;
474 time_series.label = SsrcToString(stream_id.GetSsrc()); 453 time_series.label = SsrcToString(stream_id.GetSsrc());
(...skipping 14 matching lines...) Expand all
489 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000; 468 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
490 double y = 469 double y =
491 static_cast<double>(recv_time_diff - 470 static_cast<double>(recv_time_diff -
492 AbsSendTimeToMicroseconds(send_time_diff)) / 471 AbsSendTimeToMicroseconds(send_time_diff)) /
493 1000; 472 1000;
494 if (time_series.points.size() == 0) { 473 if (time_series.points.size() == 0) {
495 // There were no previously logged packets for this SSRC. 474 // There were no previously logged packets for this SSRC.
496 // Generate a point, but place it on the x-axis. 475 // Generate a point, but place it on the x-axis.
497 y = 0; 476 y = 0;
498 } 477 }
499 max_y = std::max(max_y, y);
500 min_y = std::min(min_y, y);
501 time_series.points.emplace_back(x, y); 478 time_series.points.emplace_back(x, y);
502 } 479 }
503 } 480 }
504 // Add the data set to the plot. 481 // Add the data set to the plot.
505 plot->series.push_back(std::move(time_series)); 482 plot->series_list_.push_back(std::move(time_series));
506 } 483 }
507 484
508 plot->xaxis_min = kDefaultXMin; 485 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
509 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 486 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin,
510 plot->xaxis_label = "Time (s)"; 487 kTopMargin);
511 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 488 plot->SetTitle("Network latency change between consecutive packets");
512 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
513 plot->yaxis_label = "Latency change (ms)";
514 plot->title = "Network latency change between consecutive packets";
515 } 489 }
516 490
517 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) { 491 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) {
518 double max_y = 10;
519 double min_y = 0;
520
521 for (auto& kv : rtp_packets_) { 492 for (auto& kv : rtp_packets_) {
522 StreamId stream_id = kv.first; 493 StreamId stream_id = kv.first;
523 // Filter on direction and SSRC. 494 // Filter on direction and SSRC.
524 if (stream_id.GetDirection() != kIncomingPacket || 495 if (stream_id.GetDirection() != kIncomingPacket ||
525 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { 496 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) {
526 continue; 497 continue;
527 } 498 }
528 TimeSeries time_series; 499 TimeSeries time_series;
529 time_series.label = SsrcToString(stream_id.GetSsrc()); 500 time_series.label = SsrcToString(stream_id.GetSsrc());
530 time_series.style = LINE_GRAPH; 501 time_series.style = LINE_GRAPH;
(...skipping 14 matching lines...) Expand all
545 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000; 516 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
546 accumulated_delay_ms += 517 accumulated_delay_ms +=
547 static_cast<double>(recv_time_diff - 518 static_cast<double>(recv_time_diff -
548 AbsSendTimeToMicroseconds(send_time_diff)) / 519 AbsSendTimeToMicroseconds(send_time_diff)) /
549 1000; 520 1000;
550 if (time_series.points.size() == 0) { 521 if (time_series.points.size() == 0) {
551 // There were no previously logged packets for this SSRC. 522 // There were no previously logged packets for this SSRC.
552 // Generate a point, but place it on the x-axis. 523 // Generate a point, but place it on the x-axis.
553 accumulated_delay_ms = 0; 524 accumulated_delay_ms = 0;
554 } 525 }
555 max_y = std::max(max_y, accumulated_delay_ms);
556 min_y = std::min(min_y, accumulated_delay_ms);
557 time_series.points.emplace_back(x, accumulated_delay_ms); 526 time_series.points.emplace_back(x, accumulated_delay_ms);
558 } 527 }
559 } 528 }
560 // Add the data set to the plot. 529 // Add the data set to the plot.
561 plot->series.push_back(std::move(time_series)); 530 plot->series_list_.push_back(std::move(time_series));
562 } 531 }
563 532
564 plot->xaxis_min = kDefaultXMin; 533 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
565 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 534 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin,
566 plot->xaxis_label = "Time (s)"; 535 kTopMargin);
567 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 536 plot->SetTitle("Accumulated network latency change");
568 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
569 plot->yaxis_label = "Latency change (ms)";
570 plot->title = "Accumulated network latency change";
571 } 537 }
572 538
573 // Plot the total bandwidth used by all RTP streams. 539 // Plot the total bandwidth used by all RTP streams.
574 void EventLogAnalyzer::CreateTotalBitrateGraph( 540 void EventLogAnalyzer::CreateTotalBitrateGraph(
575 PacketDirection desired_direction, 541 PacketDirection desired_direction,
576 Plot* plot) { 542 Plot* plot) {
577 struct TimestampSize { 543 struct TimestampSize {
578 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {} 544 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {}
579 uint64_t timestamp; 545 uint64_t timestamp;
580 size_t size; 546 size_t size;
(...skipping 12 matching lines...) Expand all
593 if (direction == desired_direction) { 559 if (direction == desired_direction) {
594 uint64_t timestamp = parsed_log_.GetTimestamp(i); 560 uint64_t timestamp = parsed_log_.GetTimestamp(i);
595 packets.push_back(TimestampSize(timestamp, total_length)); 561 packets.push_back(TimestampSize(timestamp, total_length));
596 } 562 }
597 } 563 }
598 } 564 }
599 565
600 size_t window_index_begin = 0; 566 size_t window_index_begin = 0;
601 size_t window_index_end = 0; 567 size_t window_index_end = 0;
602 size_t bytes_in_window = 0; 568 size_t bytes_in_window = 0;
603 float max_y = 0;
604 569
605 // Calculate a moving average of the bitrate and store in a TimeSeries. 570 // Calculate a moving average of the bitrate and store in a TimeSeries.
606 plot->series.push_back(TimeSeries()); 571 plot->series_list_.push_back(TimeSeries());
607 for (uint64_t time = begin_time_; time < end_time_ + step_; time += step_) { 572 for (uint64_t time = begin_time_; time < end_time_ + step_; time += step_) {
608 while (window_index_end < packets.size() && 573 while (window_index_end < packets.size() &&
609 packets[window_index_end].timestamp < time) { 574 packets[window_index_end].timestamp < time) {
610 bytes_in_window += packets[window_index_end].size; 575 bytes_in_window += packets[window_index_end].size;
611 window_index_end++; 576 window_index_end++;
612 } 577 }
613 while (window_index_begin < packets.size() && 578 while (window_index_begin < packets.size() &&
614 packets[window_index_begin].timestamp < time - window_duration_) { 579 packets[window_index_begin].timestamp < time - window_duration_) {
615 RTC_DCHECK_LE(packets[window_index_begin].size, bytes_in_window); 580 RTC_DCHECK_LE(packets[window_index_begin].size, bytes_in_window);
616 bytes_in_window -= packets[window_index_begin].size; 581 bytes_in_window -= packets[window_index_begin].size;
617 window_index_begin++; 582 window_index_begin++;
618 } 583 }
619 float window_duration_in_seconds = 584 float window_duration_in_seconds =
620 static_cast<float>(window_duration_) / 1000000; 585 static_cast<float>(window_duration_) / 1000000;
621 float x = static_cast<float>(time - begin_time_) / 1000000; 586 float x = static_cast<float>(time - begin_time_) / 1000000;
622 float y = bytes_in_window * 8 / window_duration_in_seconds / 1000; 587 float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
623 max_y = std::max(max_y, y); 588 plot->series_list_.back().points.push_back(TimeSeriesPoint(x, y));
624 plot->series.back().points.push_back(TimeSeriesPoint(x, y));
625 } 589 }
626 590
627 // Set labels. 591 // Set labels.
628 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 592 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
629 plot->series.back().label = "Incoming bitrate"; 593 plot->series_list_.back().label = "Incoming bitrate";
630 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 594 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
631 plot->series.back().label = "Outgoing bitrate"; 595 plot->series_list_.back().label = "Outgoing bitrate";
632 } 596 }
633 plot->series.back().style = LINE_GRAPH; 597 plot->series_list_.back().style = LINE_GRAPH;
634 598
635 // Overlay the send-side bandwidth estimate over the outgoing bitrate. 599 // Overlay the send-side bandwidth estimate over the outgoing bitrate.
636 if (desired_direction == kOutgoingPacket) { 600 if (desired_direction == kOutgoingPacket) {
637 plot->series.push_back(TimeSeries()); 601 plot->series_list_.push_back(TimeSeries());
638 for (auto& bwe_update : bwe_loss_updates_) { 602 for (auto& bwe_update : bwe_loss_updates_) {
639 float x = 603 float x =
640 static_cast<float>(bwe_update.timestamp - begin_time_) / 1000000; 604 static_cast<float>(bwe_update.timestamp - begin_time_) / 1000000;
641 float y = static_cast<float>(bwe_update.new_bitrate) / 1000; 605 float y = static_cast<float>(bwe_update.new_bitrate) / 1000;
642 max_y = std::max(max_y, y); 606 plot->series_list_.back().points.emplace_back(x, y);
643 plot->series.back().points.emplace_back(x, y);
644 } 607 }
645 plot->series.back().label = "Loss-based estimate"; 608 plot->series_list_.back().label = "Loss-based estimate";
646 plot->series.back().style = LINE_GRAPH; 609 plot->series_list_.back().style = LINE_GRAPH;
647 } 610 }
648 611 plot->series_list_.back().style = LINE_GRAPH;
649 plot->xaxis_min = kDefaultXMin; 612 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
650 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 613 plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);
651 plot->xaxis_label = "Time (s)";
652 plot->yaxis_min = kDefaultYMin;
653 plot->yaxis_max = max_y * kYMargin;
654 plot->yaxis_label = "Bitrate (kbps)";
655 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 614 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
656 plot->title = "Incoming RTP bitrate"; 615 plot->SetTitle("Incoming RTP bitrate");
657 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 616 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
658 plot->title = "Outgoing RTP bitrate"; 617 plot->SetTitle("Outgoing RTP bitrate");
659 } 618 }
660 } 619 }
661 620
662 // For each SSRC, plot the bandwidth used by that stream. 621 // For each SSRC, plot the bandwidth used by that stream.
663 void EventLogAnalyzer::CreateStreamBitrateGraph( 622 void EventLogAnalyzer::CreateStreamBitrateGraph(
664 PacketDirection desired_direction, 623 PacketDirection desired_direction,
665 Plot* plot) { 624 Plot* plot) {
666 struct TimestampSize { 625 struct TimestampSize {
667 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {} 626 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {}
668 uint64_t timestamp; 627 uint64_t timestamp;
(...skipping 20 matching lines...) Expand all
689 // Filter on SSRC. 648 // Filter on SSRC.
690 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) { 649 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) {
691 uint64_t timestamp = parsed_log_.GetTimestamp(i); 650 uint64_t timestamp = parsed_log_.GetTimestamp(i);
692 packets[parsed_header.ssrc].push_back( 651 packets[parsed_header.ssrc].push_back(
693 TimestampSize(timestamp, total_length)); 652 TimestampSize(timestamp, total_length));
694 } 653 }
695 } 654 }
696 } 655 }
697 } 656 }
698 657
699 float max_y = 0;
700
701 for (auto& kv : packets) { 658 for (auto& kv : packets) {
702 size_t window_index_begin = 0; 659 size_t window_index_begin = 0;
703 size_t window_index_end = 0; 660 size_t window_index_end = 0;
704 size_t bytes_in_window = 0; 661 size_t bytes_in_window = 0;
705 662
706 // Calculate a moving average of the bitrate and store in a TimeSeries. 663 // Calculate a moving average of the bitrate and store in a TimeSeries.
707 plot->series.push_back(TimeSeries()); 664 plot->series_list_.push_back(TimeSeries());
708 for (uint64_t time = begin_time_; time < end_time_ + step_; time += step_) { 665 for (uint64_t time = begin_time_; time < end_time_ + step_; time += step_) {
709 while (window_index_end < kv.second.size() && 666 while (window_index_end < kv.second.size() &&
710 kv.second[window_index_end].timestamp < time) { 667 kv.second[window_index_end].timestamp < time) {
711 bytes_in_window += kv.second[window_index_end].size; 668 bytes_in_window += kv.second[window_index_end].size;
712 window_index_end++; 669 window_index_end++;
713 } 670 }
714 while (window_index_begin < kv.second.size() && 671 while (window_index_begin < kv.second.size() &&
715 kv.second[window_index_begin].timestamp < 672 kv.second[window_index_begin].timestamp <
716 time - window_duration_) { 673 time - window_duration_) {
717 RTC_DCHECK_LE(kv.second[window_index_begin].size, bytes_in_window); 674 RTC_DCHECK_LE(kv.second[window_index_begin].size, bytes_in_window);
718 bytes_in_window -= kv.second[window_index_begin].size; 675 bytes_in_window -= kv.second[window_index_begin].size;
719 window_index_begin++; 676 window_index_begin++;
720 } 677 }
721 float window_duration_in_seconds = 678 float window_duration_in_seconds =
722 static_cast<float>(window_duration_) / 1000000; 679 static_cast<float>(window_duration_) / 1000000;
723 float x = static_cast<float>(time - begin_time_) / 1000000; 680 float x = static_cast<float>(time - begin_time_) / 1000000;
724 float y = bytes_in_window * 8 / window_duration_in_seconds / 1000; 681 float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
725 max_y = std::max(max_y, y); 682 plot->series_list_.back().points.push_back(TimeSeriesPoint(x, y));
726 plot->series.back().points.push_back(TimeSeriesPoint(x, y));
727 } 683 }
728 684
729 // Set labels. 685 // Set labels.
730 plot->series.back().label = SsrcToString(kv.first); 686 plot->series_list_.back().label = SsrcToString(kv.first);
731 plot->series.back().style = LINE_GRAPH; 687 plot->series_list_.back().style = LINE_GRAPH;
732 } 688 }
733 689
734 plot->xaxis_min = kDefaultXMin; 690 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
735 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 691 plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);
736 plot->xaxis_label = "Time (s)";
737 plot->yaxis_min = kDefaultYMin;
738 plot->yaxis_max = max_y * kYMargin;
739 plot->yaxis_label = "Bitrate (kbps)";
740 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 692 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
741 plot->title = "Incoming bitrate per stream"; 693 plot->SetTitle("Incoming bitrate per stream");
742 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 694 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
743 plot->title = "Outgoing bitrate per stream"; 695 plot->SetTitle("Outgoing bitrate per stream");
744 } 696 }
745 } 697 }
746 698
747 void EventLogAnalyzer::CreateBweGraph(Plot* plot) { 699 void EventLogAnalyzer::CreateBweGraph(Plot* plot) {
748 std::map<uint64_t, const LoggedRtpPacket*> outgoing_rtp; 700 std::map<uint64_t, const LoggedRtpPacket*> outgoing_rtp;
749 std::map<uint64_t, const LoggedRtcpPacket*> incoming_rtcp; 701 std::map<uint64_t, const LoggedRtcpPacket*> incoming_rtcp;
750 702
751 for (const auto& kv : rtp_packets_) { 703 for (const auto& kv : rtp_packets_) {
752 if (kv.first.GetDirection() == PacketDirection::kOutgoingPacket) { 704 if (kv.first.GetDirection() == PacketDirection::kOutgoingPacket) {
753 for (const LoggedRtpPacket& rtp_packet : kv.second) 705 for (const LoggedRtpPacket& rtp_packet : kv.second)
(...skipping 13 matching lines...) Expand all
767 BitrateObserver observer; 719 BitrateObserver observer;
768 RtcEventLogNullImpl null_event_log; 720 RtcEventLogNullImpl null_event_log;
769 CongestionController cc(&clock, &observer, &observer, &null_event_log); 721 CongestionController cc(&clock, &observer, &observer, &null_event_log);
770 // TODO(holmer): Log the call config and use that here instead. 722 // TODO(holmer): Log the call config and use that here instead.
771 static const uint32_t kDefaultStartBitrateBps = 300000; 723 static const uint32_t kDefaultStartBitrateBps = 300000;
772 cc.SetBweBitrates(0, kDefaultStartBitrateBps, -1); 724 cc.SetBweBitrates(0, kDefaultStartBitrateBps, -1);
773 725
774 TimeSeries time_series; 726 TimeSeries time_series;
775 time_series.label = "BWE"; 727 time_series.label = "BWE";
776 time_series.style = LINE_DOT_GRAPH; 728 time_series.style = LINE_DOT_GRAPH;
777 uint32_t max_y = 10;
778 uint32_t min_y = 0;
779 729
780 auto rtp_iterator = outgoing_rtp.begin(); 730 auto rtp_iterator = outgoing_rtp.begin();
781 auto rtcp_iterator = incoming_rtcp.begin(); 731 auto rtcp_iterator = incoming_rtcp.begin();
782 732
783 auto NextRtpTime = [&]() { 733 auto NextRtpTime = [&]() {
784 if (rtp_iterator != outgoing_rtp.end()) 734 if (rtp_iterator != outgoing_rtp.end())
785 return static_cast<int64_t>(rtp_iterator->first); 735 return static_cast<int64_t>(rtp_iterator->first);
786 return std::numeric_limits<int64_t>::max(); 736 return std::numeric_limits<int64_t>::max();
787 }; 737 };
788 738
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 rtc::SentPacket sent_packet( 775 rtc::SentPacket sent_packet(
826 rtp.header.extension.transportSequenceNumber, rtp.timestamp / 1000); 776 rtp.header.extension.transportSequenceNumber, rtp.timestamp / 1000);
827 cc.OnSentPacket(sent_packet); 777 cc.OnSentPacket(sent_packet);
828 } 778 }
829 ++rtp_iterator; 779 ++rtp_iterator;
830 } 780 }
831 if (clock.TimeInMicroseconds() >= NextProcessTime()) 781 if (clock.TimeInMicroseconds() >= NextProcessTime())
832 cc.Process(); 782 cc.Process();
833 if (observer.GetAndResetBitrateUpdated()) { 783 if (observer.GetAndResetBitrateUpdated()) {
834 uint32_t y = observer.last_bitrate_bps() / 1000; 784 uint32_t y = observer.last_bitrate_bps() / 1000;
835 max_y = std::max(max_y, y);
836 min_y = std::min(min_y, y);
837 float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / 785 float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) /
838 1000000; 786 1000000;
839 time_series.points.emplace_back(x, y); 787 time_series.points.emplace_back(x, y);
840 } 788 }
841 time_us = std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()}); 789 time_us = std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()});
842 } 790 }
843 // Add the data set to the plot. 791 // Add the data set to the plot.
844 plot->series.push_back(std::move(time_series)); 792 plot->series_list_.push_back(std::move(time_series));
845 793
846 plot->xaxis_min = kDefaultXMin; 794 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
847 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 795 plot->SetSuggestedYAxis(0, 10, "Bitrate (kbps)", kBottomMargin, kTopMargin);
848 plot->xaxis_label = "Time (s)"; 796 plot->SetTitle("Simulated BWE behavior");
849 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y);
850 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
851 plot->yaxis_label = "Bitrate (kbps)";
852 plot->title = "BWE";
853 } 797 }
854 798
855 } // namespace plotting 799 } // namespace plotting
856 } // namespace webrtc 800 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/tools/event_log_visualizer/analyzer.h ('k') | webrtc/tools/event_log_visualizer/generate_timeseries.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698