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 |
11 #include "webrtc/tools/event_log_visualizer/analyzer.h" | 11 #include "webrtc/tools/event_log_visualizer/analyzer.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <limits> | 14 #include <limits> |
15 #include <map> | 15 #include <map> |
16 #include <sstream> | 16 #include <sstream> |
17 #include <string> | 17 #include <string> |
18 #include <utility> | 18 #include <utility> |
19 | 19 |
20 #include "webrtc/api/call/audio_receive_stream.h" | 20 #include "webrtc/api/call/audio_receive_stream.h" |
21 #include "webrtc/api/call/audio_send_stream.h" | 21 #include "webrtc/api/call/audio_send_stream.h" |
22 #include "webrtc/base/checks.h" | 22 #include "webrtc/base/checks.h" |
23 #include "webrtc/base/logging.h" | 23 #include "webrtc/base/logging.h" |
| 24 #include "webrtc/base/rate_statistics.h" |
24 #include "webrtc/call.h" | 25 #include "webrtc/call.h" |
25 #include "webrtc/common_types.h" | 26 #include "webrtc/common_types.h" |
26 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" | 27 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" |
27 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | 28 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
28 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 29 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
29 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | 30 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
30 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" | 31 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
31 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 32 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
32 #include "webrtc/video_receive_stream.h" | 33 #include "webrtc/video_receive_stream.h" |
33 #include "webrtc/video_send_stream.h" | 34 #include "webrtc/video_send_stream.h" |
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 BitrateObserver observer; | 829 BitrateObserver observer; |
829 RtcEventLogNullImpl null_event_log; | 830 RtcEventLogNullImpl null_event_log; |
830 CongestionController cc(&clock, &observer, &observer, &null_event_log); | 831 CongestionController cc(&clock, &observer, &observer, &null_event_log); |
831 // TODO(holmer): Log the call config and use that here instead. | 832 // TODO(holmer): Log the call config and use that here instead. |
832 static const uint32_t kDefaultStartBitrateBps = 300000; | 833 static const uint32_t kDefaultStartBitrateBps = 300000; |
833 cc.SetBweBitrates(0, kDefaultStartBitrateBps, -1); | 834 cc.SetBweBitrates(0, kDefaultStartBitrateBps, -1); |
834 | 835 |
835 TimeSeries time_series; | 836 TimeSeries time_series; |
836 time_series.label = "Delay-based estimate"; | 837 time_series.label = "Delay-based estimate"; |
837 time_series.style = LINE_DOT_GRAPH; | 838 time_series.style = LINE_DOT_GRAPH; |
| 839 TimeSeries acked_time_series; |
| 840 acked_time_series.label = "Acked bitrate"; |
| 841 acked_time_series.style = LINE_DOT_GRAPH; |
838 | 842 |
839 auto rtp_iterator = outgoing_rtp.begin(); | 843 auto rtp_iterator = outgoing_rtp.begin(); |
840 auto rtcp_iterator = incoming_rtcp.begin(); | 844 auto rtcp_iterator = incoming_rtcp.begin(); |
841 | 845 |
842 auto NextRtpTime = [&]() { | 846 auto NextRtpTime = [&]() { |
843 if (rtp_iterator != outgoing_rtp.end()) | 847 if (rtp_iterator != outgoing_rtp.end()) |
844 return static_cast<int64_t>(rtp_iterator->first); | 848 return static_cast<int64_t>(rtp_iterator->first); |
845 return std::numeric_limits<int64_t>::max(); | 849 return std::numeric_limits<int64_t>::max(); |
846 }; | 850 }; |
847 | 851 |
848 auto NextRtcpTime = [&]() { | 852 auto NextRtcpTime = [&]() { |
849 if (rtcp_iterator != incoming_rtcp.end()) | 853 if (rtcp_iterator != incoming_rtcp.end()) |
850 return static_cast<int64_t>(rtcp_iterator->first); | 854 return static_cast<int64_t>(rtcp_iterator->first); |
851 return std::numeric_limits<int64_t>::max(); | 855 return std::numeric_limits<int64_t>::max(); |
852 }; | 856 }; |
853 | 857 |
854 auto NextProcessTime = [&]() { | 858 auto NextProcessTime = [&]() { |
855 if (rtcp_iterator != incoming_rtcp.end() || | 859 if (rtcp_iterator != incoming_rtcp.end() || |
856 rtp_iterator != outgoing_rtp.end()) { | 860 rtp_iterator != outgoing_rtp.end()) { |
857 return clock.TimeInMicroseconds() + | 861 return clock.TimeInMicroseconds() + |
858 std::max<int64_t>(cc.TimeUntilNextProcess() * 1000, 0); | 862 std::max<int64_t>(cc.TimeUntilNextProcess() * 1000, 0); |
859 } | 863 } |
860 return std::numeric_limits<int64_t>::max(); | 864 return std::numeric_limits<int64_t>::max(); |
861 }; | 865 }; |
862 | 866 |
| 867 RateStatistics acked_bitrate(1000, 8000); |
| 868 |
863 int64_t time_us = std::min(NextRtpTime(), NextRtcpTime()); | 869 int64_t time_us = std::min(NextRtpTime(), NextRtcpTime()); |
864 while (time_us != std::numeric_limits<int64_t>::max()) { | 870 while (time_us != std::numeric_limits<int64_t>::max()) { |
865 clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds()); | 871 clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds()); |
866 if (clock.TimeInMicroseconds() >= NextRtcpTime()) { | 872 if (clock.TimeInMicroseconds() >= NextRtcpTime()) { |
867 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime()); | 873 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime()); |
868 const LoggedRtcpPacket& rtcp = *rtcp_iterator->second; | 874 const LoggedRtcpPacket& rtcp = *rtcp_iterator->second; |
869 if (rtcp.type == kRtcpTransportFeedback) { | 875 if (rtcp.type == kRtcpTransportFeedback) { |
870 cc.GetTransportFeedbackObserver()->OnTransportFeedback( | 876 TransportFeedbackObserver* observer = cc.GetTransportFeedbackObserver(); |
871 *static_cast<rtcp::TransportFeedback*>(rtcp.packet.get())); | 877 observer->OnTransportFeedback(*static_cast<rtcp::TransportFeedback*>( |
| 878 rtcp.packet.get())); |
| 879 std::vector<PacketInfo> feedback = |
| 880 observer->GetTransportFeedbackVector(); |
| 881 rtc::Optional<uint32_t> bitrate_bps; |
| 882 if (!feedback.empty()) { |
| 883 for (const PacketInfo& packet : feedback) |
| 884 acked_bitrate.Update(packet.payload_size, packet.arrival_time_ms); |
| 885 bitrate_bps = acked_bitrate.Rate(feedback.back().arrival_time_ms); |
| 886 } |
| 887 uint32_t y = 0; |
| 888 if (bitrate_bps) |
| 889 y = *bitrate_bps / 1000; |
| 890 float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / |
| 891 1000000; |
| 892 acked_time_series.points.emplace_back(x, y); |
872 } | 893 } |
873 ++rtcp_iterator; | 894 ++rtcp_iterator; |
874 } | 895 } |
875 if (clock.TimeInMicroseconds() >= NextRtpTime()) { | 896 if (clock.TimeInMicroseconds() >= NextRtpTime()) { |
876 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtpTime()); | 897 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtpTime()); |
877 const LoggedRtpPacket& rtp = *rtp_iterator->second; | 898 const LoggedRtpPacket& rtp = *rtp_iterator->second; |
878 if (rtp.header.extension.hasTransportSequenceNumber) { | 899 if (rtp.header.extension.hasTransportSequenceNumber) { |
879 RTC_DCHECK(rtp.header.extension.hasTransportSequenceNumber); | 900 RTC_DCHECK(rtp.header.extension.hasTransportSequenceNumber); |
880 cc.GetTransportFeedbackObserver()->AddPacket( | 901 cc.GetTransportFeedbackObserver()->AddPacket( |
881 rtp.header.extension.transportSequenceNumber, rtp.total_length, | 902 rtp.header.extension.transportSequenceNumber, rtp.total_length, |
(...skipping 11 matching lines...) Expand all Loading... |
893 if (observer.GetAndResetBitrateUpdated()) { | 914 if (observer.GetAndResetBitrateUpdated()) { |
894 uint32_t y = observer.last_bitrate_bps() / 1000; | 915 uint32_t y = observer.last_bitrate_bps() / 1000; |
895 float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / | 916 float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / |
896 1000000; | 917 1000000; |
897 time_series.points.emplace_back(x, y); | 918 time_series.points.emplace_back(x, y); |
898 } | 919 } |
899 time_us = std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()}); | 920 time_us = std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()}); |
900 } | 921 } |
901 // Add the data set to the plot. | 922 // Add the data set to the plot. |
902 plot->series_list_.push_back(std::move(time_series)); | 923 plot->series_list_.push_back(std::move(time_series)); |
| 924 plot->series_list_.push_back(std::move(acked_time_series)); |
903 | 925 |
904 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 926 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
905 plot->SetSuggestedYAxis(0, 10, "Bitrate (kbps)", kBottomMargin, kTopMargin); | 927 plot->SetSuggestedYAxis(0, 10, "Bitrate (kbps)", kBottomMargin, kTopMargin); |
906 plot->SetTitle("Simulated BWE behavior"); | 928 plot->SetTitle("Simulated BWE behavior"); |
907 } | 929 } |
908 | 930 |
909 void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) { | 931 void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) { |
910 std::map<uint64_t, const LoggedRtpPacket*> outgoing_rtp; | 932 std::map<uint64_t, const LoggedRtpPacket*> outgoing_rtp; |
911 std::map<uint64_t, const LoggedRtcpPacket*> incoming_rtcp; | 933 std::map<uint64_t, const LoggedRtcpPacket*> incoming_rtcp; |
912 | 934 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 return std::numeric_limits<int64_t>::max(); | 970 return std::numeric_limits<int64_t>::max(); |
949 }; | 971 }; |
950 | 972 |
951 int64_t time_us = std::min(NextRtpTime(), NextRtcpTime()); | 973 int64_t time_us = std::min(NextRtpTime(), NextRtcpTime()); |
952 while (time_us != std::numeric_limits<int64_t>::max()) { | 974 while (time_us != std::numeric_limits<int64_t>::max()) { |
953 clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds()); | 975 clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds()); |
954 if (clock.TimeInMicroseconds() >= NextRtcpTime()) { | 976 if (clock.TimeInMicroseconds() >= NextRtcpTime()) { |
955 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime()); | 977 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime()); |
956 const LoggedRtcpPacket& rtcp = *rtcp_iterator->second; | 978 const LoggedRtcpPacket& rtcp = *rtcp_iterator->second; |
957 if (rtcp.type == kRtcpTransportFeedback) { | 979 if (rtcp.type == kRtcpTransportFeedback) { |
| 980 feedback_adapter.OnTransportFeedback( |
| 981 *static_cast<rtcp::TransportFeedback*>(rtcp.packet.get())); |
958 std::vector<PacketInfo> feedback = | 982 std::vector<PacketInfo> feedback = |
959 feedback_adapter.GetPacketFeedbackVector( | 983 feedback_adapter.GetTransportFeedbackVector(); |
960 *static_cast<rtcp::TransportFeedback*>(rtcp.packet.get())); | |
961 for (const PacketInfo& packet : feedback) { | 984 for (const PacketInfo& packet : feedback) { |
962 int64_t y = packet.arrival_time_ms - packet.send_time_ms; | 985 int64_t y = packet.arrival_time_ms - packet.send_time_ms; |
963 float x = | 986 float x = |
964 static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / | 987 static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / |
965 1000000; | 988 1000000; |
966 estimated_base_delay_ms = std::min(y, estimated_base_delay_ms); | 989 estimated_base_delay_ms = std::min(y, estimated_base_delay_ms); |
967 time_series.points.emplace_back(x, y); | 990 time_series.points.emplace_back(x, y); |
968 } | 991 } |
969 } | 992 } |
970 ++rtcp_iterator; | 993 ++rtcp_iterator; |
(...skipping 18 matching lines...) Expand all Loading... |
989 point.y -= estimated_base_delay_ms; | 1012 point.y -= estimated_base_delay_ms; |
990 // Add the data set to the plot. | 1013 // Add the data set to the plot. |
991 plot->series_list_.push_back(std::move(time_series)); | 1014 plot->series_list_.push_back(std::move(time_series)); |
992 | 1015 |
993 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 1016 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
994 plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin); | 1017 plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin); |
995 plot->SetTitle("Network Delay Change."); | 1018 plot->SetTitle("Network Delay Change."); |
996 } | 1019 } |
997 } // namespace plotting | 1020 } // namespace plotting |
998 } // namespace webrtc | 1021 } // namespace webrtc |
OLD | NEW |