OLD | NEW |
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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 bool bitrate_updated = bitrate_updated_; | 452 bool bitrate_updated = bitrate_updated_; |
453 bitrate_updated_ = false; | 453 bitrate_updated_ = false; |
454 return bitrate_updated; | 454 return bitrate_updated; |
455 } | 455 } |
456 | 456 |
457 private: | 457 private: |
458 uint32_t last_bitrate_bps_; | 458 uint32_t last_bitrate_bps_; |
459 bool bitrate_updated_; | 459 bool bitrate_updated_; |
460 }; | 460 }; |
461 | 461 |
462 bool EventLogAnalyzer::IsRtxSsrc(StreamId stream_id) { | 462 bool EventLogAnalyzer::IsRtxSsrc(StreamId stream_id) const { |
463 return rtx_ssrcs_.count(stream_id) == 1; | 463 return rtx_ssrcs_.count(stream_id) == 1; |
464 } | 464 } |
465 | 465 |
466 bool EventLogAnalyzer::IsVideoSsrc(StreamId stream_id) { | 466 bool EventLogAnalyzer::IsVideoSsrc(StreamId stream_id) const { |
467 return video_ssrcs_.count(stream_id) == 1; | 467 return video_ssrcs_.count(stream_id) == 1; |
468 } | 468 } |
469 | 469 |
470 bool EventLogAnalyzer::IsAudioSsrc(StreamId stream_id) { | 470 bool EventLogAnalyzer::IsAudioSsrc(StreamId stream_id) const { |
471 return audio_ssrcs_.count(stream_id) == 1; | 471 return audio_ssrcs_.count(stream_id) == 1; |
472 } | 472 } |
473 | 473 |
| 474 std::string EventLogAnalyzer::GetStreamName(StreamId stream_id) const { |
| 475 std::stringstream name; |
| 476 if (IsAudioSsrc(stream_id)) { |
| 477 name << "Audio "; |
| 478 } else if (IsVideoSsrc(stream_id)) { |
| 479 name << "Video "; |
| 480 } else { |
| 481 name << "Unknown "; |
| 482 } |
| 483 if (IsRtxSsrc(stream_id)) |
| 484 name << "RTX "; |
| 485 name << SsrcToString(stream_id.GetSsrc()); |
| 486 return name.str(); |
| 487 } |
| 488 |
474 void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction, | 489 void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction, |
475 Plot* plot) { | 490 Plot* plot) { |
476 for (auto& kv : rtp_packets_) { | 491 for (auto& kv : rtp_packets_) { |
477 StreamId stream_id = kv.first; | 492 StreamId stream_id = kv.first; |
478 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; | 493 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; |
479 // Filter on direction and SSRC. | 494 // Filter on direction and SSRC. |
480 if (stream_id.GetDirection() != desired_direction || | 495 if (stream_id.GetDirection() != desired_direction || |
481 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { | 496 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { |
482 continue; | 497 continue; |
483 } | 498 } |
484 | 499 |
485 TimeSeries time_series; | 500 TimeSeries time_series; |
486 time_series.label = SsrcToString(stream_id.GetSsrc()); | 501 time_series.label = GetStreamName(stream_id); |
487 time_series.style = BAR_GRAPH; | 502 time_series.style = BAR_GRAPH; |
488 Pointwise<PacketSizeBytes>(packet_stream, begin_time_, &time_series); | 503 Pointwise<PacketSizeBytes>(packet_stream, begin_time_, &time_series); |
489 plot->series_list_.push_back(std::move(time_series)); | 504 plot->series_list_.push_back(std::move(time_series)); |
490 } | 505 } |
491 | 506 |
492 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 507 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
493 plot->SetSuggestedYAxis(0, 1, "Packet size (bytes)", kBottomMargin, | 508 plot->SetSuggestedYAxis(0, 1, "Packet size (bytes)", kBottomMargin, |
494 kTopMargin); | 509 kTopMargin); |
495 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { | 510 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { |
496 plot->SetTitle("Incoming RTP packets"); | 511 plot->SetTitle("Incoming RTP packets"); |
(...skipping 11 matching lines...) Expand all Loading... |
508 for (auto& kv : packets) { | 523 for (auto& kv : packets) { |
509 StreamId stream_id = kv.first; | 524 StreamId stream_id = kv.first; |
510 const std::vector<T>& packet_stream = kv.second; | 525 const std::vector<T>& packet_stream = kv.second; |
511 // Filter on direction and SSRC. | 526 // Filter on direction and SSRC. |
512 if (stream_id.GetDirection() != desired_direction || | 527 if (stream_id.GetDirection() != desired_direction || |
513 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { | 528 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { |
514 continue; | 529 continue; |
515 } | 530 } |
516 | 531 |
517 TimeSeries time_series; | 532 TimeSeries time_series; |
518 time_series.label = label_prefix + " " + SsrcToString(stream_id.GetSsrc()); | 533 time_series.label = label_prefix + " " + GetStreamName(stream_id); |
519 time_series.style = LINE_GRAPH; | 534 time_series.style = LINE_GRAPH; |
520 | 535 |
521 for (size_t i = 0; i < packet_stream.size(); i++) { | 536 for (size_t i = 0; i < packet_stream.size(); i++) { |
522 float x = static_cast<float>(packet_stream[i].timestamp - begin_time_) / | 537 float x = static_cast<float>(packet_stream[i].timestamp - begin_time_) / |
523 1000000; | 538 1000000; |
524 time_series.points.emplace_back(x, i); | 539 time_series.points.emplace_back(x, i); |
525 time_series.points.emplace_back(x, i + 1); | 540 time_series.points.emplace_back(x, i + 1); |
526 } | 541 } |
527 | 542 |
528 plot->series_list_.push_back(std::move(time_series)); | 543 plot->series_list_.push_back(std::move(time_series)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 for (auto& kv : rtp_packets_) { | 605 for (auto& kv : rtp_packets_) { |
591 StreamId stream_id = kv.first; | 606 StreamId stream_id = kv.first; |
592 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; | 607 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; |
593 // Filter on direction and SSRC. | 608 // Filter on direction and SSRC. |
594 if (stream_id.GetDirection() != kIncomingPacket || | 609 if (stream_id.GetDirection() != kIncomingPacket || |
595 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { | 610 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { |
596 continue; | 611 continue; |
597 } | 612 } |
598 | 613 |
599 TimeSeries time_series; | 614 TimeSeries time_series; |
600 time_series.label = SsrcToString(stream_id.GetSsrc()); | 615 time_series.label = GetStreamName(stream_id); |
601 time_series.style = BAR_GRAPH; | 616 time_series.style = BAR_GRAPH; |
602 Pairwise<SequenceNumberDiff>(packet_stream, begin_time_, &time_series); | 617 Pairwise<SequenceNumberDiff>(packet_stream, begin_time_, &time_series); |
603 plot->series_list_.push_back(std::move(time_series)); | 618 plot->series_list_.push_back(std::move(time_series)); |
604 } | 619 } |
605 | 620 |
606 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 621 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
607 plot->SetSuggestedYAxis(0, 1, "Difference since last packet", kBottomMargin, | 622 plot->SetSuggestedYAxis(0, 1, "Difference since last packet", kBottomMargin, |
608 kTopMargin); | 623 kTopMargin); |
609 plot->SetTitle("Sequence number"); | 624 plot->SetTitle("Sequence number"); |
610 } | 625 } |
611 | 626 |
| 627 void EventLogAnalyzer::CreateIncomingPacketLossGraph(Plot* plot) { |
| 628 for (auto& kv : rtp_packets_) { |
| 629 StreamId stream_id = kv.first; |
| 630 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; |
| 631 // Filter on direction and SSRC. |
| 632 if (stream_id.GetDirection() != kIncomingPacket || |
| 633 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { |
| 634 continue; |
| 635 } |
| 636 |
| 637 TimeSeries time_series; |
| 638 time_series.label = GetStreamName(stream_id); |
| 639 time_series.style = LINE_DOT_GRAPH; |
| 640 const uint64_t kWindowUs = 1000000; |
| 641 const LoggedRtpPacket* first_in_window = &packet_stream.front(); |
| 642 const LoggedRtpPacket* last_in_window = &packet_stream.front(); |
| 643 int packets_in_window = 0; |
| 644 for (const LoggedRtpPacket& packet : packet_stream) { |
| 645 if (packet.timestamp > first_in_window->timestamp + kWindowUs) { |
| 646 uint16_t expected_num_packets = last_in_window->header.sequenceNumber - |
| 647 first_in_window->header.sequenceNumber + 1; |
| 648 float fraction_lost = (expected_num_packets - packets_in_window) / |
| 649 static_cast<float>(expected_num_packets); |
| 650 float y = fraction_lost * 100; |
| 651 float x = |
| 652 static_cast<float>(last_in_window->timestamp - begin_time_) / |
| 653 1000000; |
| 654 time_series.points.emplace_back(x, y); |
| 655 first_in_window = &packet; |
| 656 last_in_window = &packet; |
| 657 packets_in_window = 1; |
| 658 continue; |
| 659 } |
| 660 ++packets_in_window; |
| 661 last_in_window = &packet; |
| 662 } |
| 663 plot->series_list_.push_back(std::move(time_series)); |
| 664 } |
| 665 |
| 666 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
| 667 plot->SetSuggestedYAxis(0, 1, "Estimated loss rate (%)", kBottomMargin, |
| 668 kTopMargin); |
| 669 plot->SetTitle("Estimated incoming loss rate"); |
| 670 } |
| 671 |
612 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) { | 672 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) { |
613 for (auto& kv : rtp_packets_) { | 673 for (auto& kv : rtp_packets_) { |
614 StreamId stream_id = kv.first; | 674 StreamId stream_id = kv.first; |
615 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; | 675 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; |
616 uint32_t ssrc = stream_id.GetSsrc(); | |
617 // Filter on direction and SSRC. | 676 // Filter on direction and SSRC. |
618 if (stream_id.GetDirection() != kIncomingPacket || | 677 if (stream_id.GetDirection() != kIncomingPacket || |
619 !MatchingSsrc(ssrc, desired_ssrc_) || IsAudioSsrc(stream_id) || | 678 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_) || |
620 !IsVideoSsrc(stream_id) || IsRtxSsrc(stream_id)) { | 679 IsAudioSsrc(stream_id) || !IsVideoSsrc(stream_id) || |
| 680 IsRtxSsrc(stream_id)) { |
621 continue; | 681 continue; |
622 } | 682 } |
623 | 683 |
624 TimeSeries capture_time_data; | 684 TimeSeries capture_time_data; |
625 capture_time_data.label = SsrcToString(ssrc) + " capture-time"; | 685 capture_time_data.label = GetStreamName(stream_id) + " capture-time"; |
626 capture_time_data.style = BAR_GRAPH; | 686 capture_time_data.style = BAR_GRAPH; |
627 Pairwise<NetworkDelayDiff::CaptureTime>(packet_stream, begin_time_, | 687 Pairwise<NetworkDelayDiff::CaptureTime>(packet_stream, begin_time_, |
628 &capture_time_data); | 688 &capture_time_data); |
629 plot->series_list_.push_back(std::move(capture_time_data)); | 689 plot->series_list_.push_back(std::move(capture_time_data)); |
630 | 690 |
631 TimeSeries send_time_data; | 691 TimeSeries send_time_data; |
632 send_time_data.label = SsrcToString(ssrc) + " abs-send-time"; | 692 send_time_data.label = GetStreamName(stream_id) + " abs-send-time"; |
633 send_time_data.style = BAR_GRAPH; | 693 send_time_data.style = BAR_GRAPH; |
634 Pairwise<NetworkDelayDiff::AbsSendTime>(packet_stream, begin_time_, | 694 Pairwise<NetworkDelayDiff::AbsSendTime>(packet_stream, begin_time_, |
635 &send_time_data); | 695 &send_time_data); |
636 plot->series_list_.push_back(std::move(send_time_data)); | 696 plot->series_list_.push_back(std::move(send_time_data)); |
637 } | 697 } |
638 | 698 |
639 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 699 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
640 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin, | 700 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin, |
641 kTopMargin); | 701 kTopMargin); |
642 plot->SetTitle("Network latency change between consecutive packets"); | 702 plot->SetTitle("Network latency change between consecutive packets"); |
643 } | 703 } |
644 | 704 |
645 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) { | 705 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) { |
646 for (auto& kv : rtp_packets_) { | 706 for (auto& kv : rtp_packets_) { |
647 StreamId stream_id = kv.first; | 707 StreamId stream_id = kv.first; |
648 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; | 708 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; |
649 uint32_t ssrc = stream_id.GetSsrc(); | |
650 // Filter on direction and SSRC. | 709 // Filter on direction and SSRC. |
651 if (stream_id.GetDirection() != kIncomingPacket || | 710 if (stream_id.GetDirection() != kIncomingPacket || |
652 !MatchingSsrc(ssrc, desired_ssrc_) || IsAudioSsrc(stream_id) || | 711 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_) || |
653 !IsVideoSsrc(stream_id) || IsRtxSsrc(stream_id)) { | 712 IsAudioSsrc(stream_id) || !IsVideoSsrc(stream_id) || |
| 713 IsRtxSsrc(stream_id)) { |
654 continue; | 714 continue; |
655 } | 715 } |
656 | 716 |
657 TimeSeries capture_time_data; | 717 TimeSeries capture_time_data; |
658 capture_time_data.label = SsrcToString(ssrc) + " capture-time"; | 718 capture_time_data.label = GetStreamName(stream_id) + " capture-time"; |
659 capture_time_data.style = LINE_GRAPH; | 719 capture_time_data.style = LINE_GRAPH; |
660 Pairwise<Accumulated<NetworkDelayDiff::CaptureTime>>( | 720 Pairwise<Accumulated<NetworkDelayDiff::CaptureTime>>( |
661 packet_stream, begin_time_, &capture_time_data); | 721 packet_stream, begin_time_, &capture_time_data); |
662 plot->series_list_.push_back(std::move(capture_time_data)); | 722 plot->series_list_.push_back(std::move(capture_time_data)); |
663 | 723 |
664 TimeSeries send_time_data; | 724 TimeSeries send_time_data; |
665 send_time_data.label = SsrcToString(ssrc) + " abs-send-time"; | 725 send_time_data.label = GetStreamName(stream_id) + " abs-send-time"; |
666 send_time_data.style = LINE_GRAPH; | 726 send_time_data.style = LINE_GRAPH; |
667 Pairwise<Accumulated<NetworkDelayDiff::AbsSendTime>>( | 727 Pairwise<Accumulated<NetworkDelayDiff::AbsSendTime>>( |
668 packet_stream, begin_time_, &send_time_data); | 728 packet_stream, begin_time_, &send_time_data); |
669 plot->series_list_.push_back(std::move(send_time_data)); | 729 plot->series_list_.push_back(std::move(send_time_data)); |
670 } | 730 } |
671 | 731 |
672 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 732 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
673 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin, | 733 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin, |
674 kTopMargin); | 734 kTopMargin); |
675 plot->SetTitle("Accumulated network latency change"); | 735 plot->SetTitle("Accumulated network latency change"); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 for (auto& kv : rtp_packets_) { | 841 for (auto& kv : rtp_packets_) { |
782 StreamId stream_id = kv.first; | 842 StreamId stream_id = kv.first; |
783 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; | 843 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; |
784 // Filter on direction and SSRC. | 844 // Filter on direction and SSRC. |
785 if (stream_id.GetDirection() != desired_direction || | 845 if (stream_id.GetDirection() != desired_direction || |
786 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { | 846 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { |
787 continue; | 847 continue; |
788 } | 848 } |
789 | 849 |
790 TimeSeries time_series; | 850 TimeSeries time_series; |
791 time_series.label = SsrcToString(stream_id.GetSsrc()); | 851 time_series.label = GetStreamName(stream_id); |
792 time_series.style = LINE_GRAPH; | 852 time_series.style = LINE_GRAPH; |
793 double bytes_to_kilobits = 8.0 / 1000; | 853 double bytes_to_kilobits = 8.0 / 1000; |
794 MovingAverage<PacketSizeBytes>(packet_stream, begin_time_, end_time_, | 854 MovingAverage<PacketSizeBytes>(packet_stream, begin_time_, end_time_, |
795 window_duration_, step_, bytes_to_kilobits, | 855 window_duration_, step_, bytes_to_kilobits, |
796 &time_series); | 856 &time_series); |
797 plot->series_list_.push_back(std::move(time_series)); | 857 plot->series_list_.push_back(std::move(time_series)); |
798 } | 858 } |
799 | 859 |
800 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 860 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
801 plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin); | 861 plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 point.y -= estimated_base_delay_ms; | 1072 point.y -= estimated_base_delay_ms; |
1013 // Add the data set to the plot. | 1073 // Add the data set to the plot. |
1014 plot->series_list_.push_back(std::move(time_series)); | 1074 plot->series_list_.push_back(std::move(time_series)); |
1015 | 1075 |
1016 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 1076 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
1017 plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin); | 1077 plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin); |
1018 plot->SetTitle("Network Delay Change."); | 1078 plot->SetTitle("Network Delay Change."); |
1019 } | 1079 } |
1020 } // namespace plotting | 1080 } // namespace plotting |
1021 } // namespace webrtc | 1081 } // namespace webrtc |
OLD | NEW |