| 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 |