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 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 BitrateObserver observer; | 782 BitrateObserver observer; |
782 RtcEventLogNullImpl null_event_log; | 783 RtcEventLogNullImpl null_event_log; |
783 CongestionController cc(&clock, &observer, &observer, &null_event_log); | 784 CongestionController cc(&clock, &observer, &observer, &null_event_log); |
784 // TODO(holmer): Log the call config and use that here instead. | 785 // TODO(holmer): Log the call config and use that here instead. |
785 static const uint32_t kDefaultStartBitrateBps = 300000; | 786 static const uint32_t kDefaultStartBitrateBps = 300000; |
786 cc.SetBweBitrates(0, kDefaultStartBitrateBps, -1); | 787 cc.SetBweBitrates(0, kDefaultStartBitrateBps, -1); |
787 | 788 |
788 TimeSeries time_series; | 789 TimeSeries time_series; |
789 time_series.label = "Delay-based estimate"; | 790 time_series.label = "Delay-based estimate"; |
790 time_series.style = LINE_DOT_GRAPH; | 791 time_series.style = LINE_DOT_GRAPH; |
792 TimeSeries acked_time_series; | |
793 acked_time_series.label = "Acked bitrate"; | |
794 acked_time_series.style = LINE_DOT_GRAPH; | |
791 | 795 |
792 auto rtp_iterator = outgoing_rtp.begin(); | 796 auto rtp_iterator = outgoing_rtp.begin(); |
793 auto rtcp_iterator = incoming_rtcp.begin(); | 797 auto rtcp_iterator = incoming_rtcp.begin(); |
794 | 798 |
795 auto NextRtpTime = [&]() { | 799 auto NextRtpTime = [&]() { |
796 if (rtp_iterator != outgoing_rtp.end()) | 800 if (rtp_iterator != outgoing_rtp.end()) |
797 return static_cast<int64_t>(rtp_iterator->first); | 801 return static_cast<int64_t>(rtp_iterator->first); |
798 return std::numeric_limits<int64_t>::max(); | 802 return std::numeric_limits<int64_t>::max(); |
799 }; | 803 }; |
800 | 804 |
801 auto NextRtcpTime = [&]() { | 805 auto NextRtcpTime = [&]() { |
802 if (rtcp_iterator != incoming_rtcp.end()) | 806 if (rtcp_iterator != incoming_rtcp.end()) |
803 return static_cast<int64_t>(rtcp_iterator->first); | 807 return static_cast<int64_t>(rtcp_iterator->first); |
804 return std::numeric_limits<int64_t>::max(); | 808 return std::numeric_limits<int64_t>::max(); |
805 }; | 809 }; |
806 | 810 |
807 auto NextProcessTime = [&]() { | 811 auto NextProcessTime = [&]() { |
808 if (rtcp_iterator != incoming_rtcp.end() || | 812 if (rtcp_iterator != incoming_rtcp.end() || |
809 rtp_iterator != outgoing_rtp.end()) { | 813 rtp_iterator != outgoing_rtp.end()) { |
810 return clock.TimeInMicroseconds() + | 814 return clock.TimeInMicroseconds() + |
811 std::max<int64_t>(cc.TimeUntilNextProcess() * 1000, 0); | 815 std::max<int64_t>(cc.TimeUntilNextProcess() * 1000, 0); |
812 } | 816 } |
813 return std::numeric_limits<int64_t>::max(); | 817 return std::numeric_limits<int64_t>::max(); |
814 }; | 818 }; |
815 | 819 |
820 RateStatistics acked_bitrate(1000, 8000); | |
821 | |
816 int64_t time_us = std::min(NextRtpTime(), NextRtcpTime()); | 822 int64_t time_us = std::min(NextRtpTime(), NextRtcpTime()); |
817 while (time_us != std::numeric_limits<int64_t>::max()) { | 823 while (time_us != std::numeric_limits<int64_t>::max()) { |
818 clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds()); | 824 clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds()); |
819 if (clock.TimeInMicroseconds() >= NextRtcpTime()) { | 825 if (clock.TimeInMicroseconds() >= NextRtcpTime()) { |
820 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime()); | 826 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime()); |
821 const LoggedRtcpPacket& rtcp = *rtcp_iterator->second; | 827 const LoggedRtcpPacket& rtcp = *rtcp_iterator->second; |
822 if (rtcp.type == kRtcpTransportFeedback) { | 828 if (rtcp.type == kRtcpTransportFeedback) { |
823 cc.GetTransportFeedbackObserver()->OnTransportFeedback( | 829 std::vector<PacketInfo> feedback = |
824 *static_cast<rtcp::TransportFeedback*>(rtcp.packet.get())); | 830 cc.GetTransportFeedbackObserver()->OnTransportFeedback( |
philipel
2016/09/05 13:30:05
I think it's cleaner if you call both TransportFee
stefan-webrtc
2016/09/05 14:03:39
Done.
philipel
2016/09/05 14:56:25
Maybe something even cleaner would be to add a Get
stefan-webrtc
2016/09/06 11:53:11
I want to get rid of the GetBitrateEstimator() api
| |
831 *static_cast<rtcp::TransportFeedback*>(rtcp.packet.get())); | |
832 rtc::Optional<uint32_t> bitrate_bps; | |
833 if (!feedback.empty()) { | |
834 for (const PacketInfo& packet : feedback) | |
835 acked_bitrate.Update(packet.payload_size, packet.arrival_time_ms); | |
836 bitrate_bps = acked_bitrate.Rate(feedback.back().arrival_time_ms); | |
837 } | |
838 uint32_t y = 0; | |
839 if (bitrate_bps) | |
840 y = *bitrate_bps / 1000; | |
841 float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / | |
842 1000000; | |
843 acked_time_series.points.emplace_back(x, y); | |
825 } | 844 } |
826 ++rtcp_iterator; | 845 ++rtcp_iterator; |
827 } | 846 } |
828 if (clock.TimeInMicroseconds() >= NextRtpTime()) { | 847 if (clock.TimeInMicroseconds() >= NextRtpTime()) { |
829 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtpTime()); | 848 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtpTime()); |
830 const LoggedRtpPacket& rtp = *rtp_iterator->second; | 849 const LoggedRtpPacket& rtp = *rtp_iterator->second; |
831 if (rtp.header.extension.hasTransportSequenceNumber) { | 850 if (rtp.header.extension.hasTransportSequenceNumber) { |
832 RTC_DCHECK(rtp.header.extension.hasTransportSequenceNumber); | 851 RTC_DCHECK(rtp.header.extension.hasTransportSequenceNumber); |
833 cc.GetTransportFeedbackObserver()->AddPacket( | 852 cc.GetTransportFeedbackObserver()->AddPacket( |
834 rtp.header.extension.transportSequenceNumber, rtp.total_length, | 853 rtp.header.extension.transportSequenceNumber, rtp.total_length, |
(...skipping 11 matching lines...) Expand all Loading... | |
846 if (observer.GetAndResetBitrateUpdated()) { | 865 if (observer.GetAndResetBitrateUpdated()) { |
847 uint32_t y = observer.last_bitrate_bps() / 1000; | 866 uint32_t y = observer.last_bitrate_bps() / 1000; |
848 float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / | 867 float x = static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / |
849 1000000; | 868 1000000; |
850 time_series.points.emplace_back(x, y); | 869 time_series.points.emplace_back(x, y); |
851 } | 870 } |
852 time_us = std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()}); | 871 time_us = std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()}); |
853 } | 872 } |
854 // Add the data set to the plot. | 873 // Add the data set to the plot. |
855 plot->series_list_.push_back(std::move(time_series)); | 874 plot->series_list_.push_back(std::move(time_series)); |
875 plot->series_list_.push_back(std::move(acked_time_series)); | |
856 | 876 |
857 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 877 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
858 plot->SetSuggestedYAxis(0, 10, "Bitrate (kbps)", kBottomMargin, kTopMargin); | 878 plot->SetSuggestedYAxis(0, 10, "Bitrate (kbps)", kBottomMargin, kTopMargin); |
859 plot->SetTitle("Simulated BWE behavior"); | 879 plot->SetTitle("Simulated BWE behavior"); |
860 } | 880 } |
861 | 881 |
862 void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) { | 882 void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) { |
863 std::map<uint64_t, const LoggedRtpPacket*> outgoing_rtp; | 883 std::map<uint64_t, const LoggedRtpPacket*> outgoing_rtp; |
864 std::map<uint64_t, const LoggedRtcpPacket*> incoming_rtcp; | 884 std::map<uint64_t, const LoggedRtcpPacket*> incoming_rtcp; |
865 | 885 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
902 }; | 922 }; |
903 | 923 |
904 int64_t time_us = std::min(NextRtpTime(), NextRtcpTime()); | 924 int64_t time_us = std::min(NextRtpTime(), NextRtcpTime()); |
905 while (time_us != std::numeric_limits<int64_t>::max()) { | 925 while (time_us != std::numeric_limits<int64_t>::max()) { |
906 clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds()); | 926 clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds()); |
907 if (clock.TimeInMicroseconds() >= NextRtcpTime()) { | 927 if (clock.TimeInMicroseconds() >= NextRtcpTime()) { |
908 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime()); | 928 RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime()); |
909 const LoggedRtcpPacket& rtcp = *rtcp_iterator->second; | 929 const LoggedRtcpPacket& rtcp = *rtcp_iterator->second; |
910 if (rtcp.type == kRtcpTransportFeedback) { | 930 if (rtcp.type == kRtcpTransportFeedback) { |
911 std::vector<PacketInfo> feedback = | 931 std::vector<PacketInfo> feedback = |
912 feedback_adapter.GetPacketFeedbackVector( | 932 feedback_adapter.OnTransportFeedback( |
913 *static_cast<rtcp::TransportFeedback*>(rtcp.packet.get())); | 933 *static_cast<rtcp::TransportFeedback*>(rtcp.packet.get())); |
914 for (const PacketInfo& packet : feedback) { | 934 for (const PacketInfo& packet : feedback) { |
915 int64_t y = packet.arrival_time_ms - packet.send_time_ms; | 935 int64_t y = packet.arrival_time_ms - packet.send_time_ms; |
916 float x = | 936 float x = |
917 static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / | 937 static_cast<float>(clock.TimeInMicroseconds() - begin_time_) / |
918 1000000; | 938 1000000; |
919 estimated_base_delay_ms = std::min(y, estimated_base_delay_ms); | 939 estimated_base_delay_ms = std::min(y, estimated_base_delay_ms); |
920 time_series.points.emplace_back(x, y); | 940 time_series.points.emplace_back(x, y); |
921 } | 941 } |
922 } | 942 } |
(...skipping 19 matching lines...) Expand all Loading... | |
942 point.y -= estimated_base_delay_ms; | 962 point.y -= estimated_base_delay_ms; |
943 // Add the data set to the plot. | 963 // Add the data set to the plot. |
944 plot->series_list_.push_back(std::move(time_series)); | 964 plot->series_list_.push_back(std::move(time_series)); |
945 | 965 |
946 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); | 966 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); |
947 plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin); | 967 plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin); |
948 plot->SetTitle("Network Delay Change."); | 968 plot->SetTitle("Network Delay Change."); |
949 } | 969 } |
950 } // namespace plotting | 970 } // namespace plotting |
951 } // namespace webrtc | 971 } // namespace webrtc |
OLD | NEW |