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

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

Issue 2220383004: Visualize delay changes based on both abs-send-time and capture time. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Nit 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
« no previous file with comments | « webrtc/tools/event_log_visualizer/analyzer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 return true; 50 return true;
51 return std::find(desired_ssrc.begin(), desired_ssrc.end(), ssrc) != 51 return std::find(desired_ssrc.begin(), desired_ssrc.end(), ssrc) !=
52 desired_ssrc.end(); 52 desired_ssrc.end();
53 } 53 }
54 54
55 double AbsSendTimeToMicroseconds(int64_t abs_send_time) { 55 double AbsSendTimeToMicroseconds(int64_t abs_send_time) {
56 // The timestamp is a fixed point representation with 6 bits for seconds 56 // The timestamp is a fixed point representation with 6 bits for seconds
57 // and 18 bits for fractions of a second. Thus, we divide by 2^18 to get the 57 // and 18 bits for fractions of a second. Thus, we divide by 2^18 to get the
58 // time in seconds and then multiply by 1000000 to convert to microseconds. 58 // time in seconds and then multiply by 1000000 to convert to microseconds.
59 static constexpr double kTimestampToMicroSec = 59 static constexpr double kTimestampToMicroSec =
60 1000000.0 / static_cast<double>(1 << 18); 60 1000000.0 / static_cast<double>(1ul << 18);
61 return abs_send_time * kTimestampToMicroSec; 61 return abs_send_time * kTimestampToMicroSec;
62 } 62 }
63 63
64 // Computes the difference |later| - |earlier| where |later| and |earlier| 64 // Computes the difference |later| - |earlier| where |later| and |earlier|
65 // are counters that wrap at |modulus|. The difference is chosen to have the 65 // are counters that wrap at |modulus|. The difference is chosen to have the
66 // least absolute value. For example if |modulus| is 8, then the difference will 66 // least absolute value. For example if |modulus| is 8, then the difference will
67 // be chosen in the range [-3, 4]. If |modulus| is 9, then the difference will 67 // be chosen in the range [-3, 4]. If |modulus| is 9, then the difference will
68 // be in [-4, 4]. 68 // be in [-4, 4].
69 int64_t WrappingDifference(uint32_t later, uint32_t earlier, int64_t modulus) { 69 int64_t WrappingDifference(uint32_t later, uint32_t earlier, int64_t modulus) {
70 RTC_DCHECK_LE(1, modulus); 70 RTC_DCHECK_LE(1, modulus);
(...skipping 20 matching lines...) Expand all
91 extension_map->Register(webrtc::StringToRtpExtensionType(extension.uri), 91 extension_map->Register(webrtc::StringToRtpExtensionType(extension.uri),
92 extension.id); 92 extension.id);
93 } 93 }
94 } 94 }
95 95
96 constexpr float kLeftMargin = 0.01f; 96 constexpr float kLeftMargin = 0.01f;
97 constexpr float kRightMargin = 0.02f; 97 constexpr float kRightMargin = 0.02f;
98 constexpr float kBottomMargin = 0.02f; 98 constexpr float kBottomMargin = 0.02f;
99 constexpr float kTopMargin = 0.05f; 99 constexpr float kTopMargin = 0.05f;
100 100
101 class NetworkDelayDiff {
102 public:
103 class AbsSendTime {
104 public:
105 using DataType = LoggedRtpPacket;
106 using ResultType = double;
107 double operator()(const LoggedRtpPacket& old_packet,
108 const LoggedRtpPacket& new_packet) {
109 if (old_packet.header.extension.hasAbsoluteSendTime &&
110 new_packet.header.extension.hasAbsoluteSendTime) {
111 int64_t send_time_diff = WrappingDifference(
112 new_packet.header.extension.absoluteSendTime,
113 old_packet.header.extension.absoluteSendTime, 1ul << 24);
114 int64_t recv_time_diff = new_packet.timestamp - old_packet.timestamp;
115 return static_cast<double>(recv_time_diff -
116 AbsSendTimeToMicroseconds(send_time_diff)) /
117 1000;
118 } else {
119 return 0;
120 }
121 }
122 };
123
124 class CaptureTime {
125 public:
126 using DataType = LoggedRtpPacket;
127 using ResultType = double;
128 double operator()(const LoggedRtpPacket& old_packet,
129 const LoggedRtpPacket& new_packet) {
130 int64_t send_time_diff = WrappingDifference(
131 new_packet.header.timestamp, old_packet.header.timestamp, 1ull << 32);
132 int64_t recv_time_diff = new_packet.timestamp - old_packet.timestamp;
133
134 const double kVideoSampleRate = 90000;
135 // TODO(terelius): We treat all streams as video for now, even though
136 // audio might be sampled at e.g. 16kHz, because it is really difficult to
137 // figure out the true sampling rate of a stream. The effect is that the
138 // delay will be scaled incorrectly for non-video streams.
139
140 double delay_change =
141 static_cast<double>(recv_time_diff) / 1000 -
142 static_cast<double>(send_time_diff) / kVideoSampleRate * 1000;
143 return delay_change;
144 }
145 };
146 };
147
148 template <typename Extractor>
149 class Accumulated {
150 public:
151 using DataType = typename Extractor::DataType;
152 using ResultType = typename Extractor::ResultType;
153 ResultType operator()(const DataType& old_packet,
154 const DataType& new_packet) {
155 sum += extract(old_packet, new_packet);
156 return sum;
157 }
158
159 private:
160 Extractor extract;
161 ResultType sum = 0;
162 };
163
164 template <typename Extractor>
165 void Pairwise(const std::vector<typename Extractor::DataType>& data,
166 uint64_t begin_time,
167 TimeSeries* result) {
168 Extractor extract;
169 for (size_t i = 1; i < data.size(); i++) {
170 float x = static_cast<float>(data[i].timestamp - begin_time) / 1000000;
171 float y = extract(data[i - 1], data[i]);
172 result->points.emplace_back(x, y);
173 }
174 }
175
101 } // namespace 176 } // namespace
102 177
103 EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log) 178 EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
104 : parsed_log_(log), window_duration_(250000), step_(10000) { 179 : parsed_log_(log), window_duration_(250000), step_(10000) {
105 uint64_t first_timestamp = std::numeric_limits<uint64_t>::max(); 180 uint64_t first_timestamp = std::numeric_limits<uint64_t>::max();
106 uint64_t last_timestamp = std::numeric_limits<uint64_t>::min(); 181 uint64_t last_timestamp = std::numeric_limits<uint64_t>::min();
107 182
108 // Maps a stream identifier consisting of ssrc and direction 183 // Maps a stream identifier consisting of ssrc and direction
109 // to the header extensions used by that stream, 184 // to the header extensions used by that stream,
110 std::map<StreamId, RtpHeaderExtensionMap> extension_maps; 185 std::map<StreamId, RtpHeaderExtensionMap> extension_maps;
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 514
440 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); 515 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
441 plot->SetSuggestedYAxis(0, 1, "Difference since last packet", kBottomMargin, 516 plot->SetSuggestedYAxis(0, 1, "Difference since last packet", kBottomMargin,
442 kTopMargin); 517 kTopMargin);
443 plot->SetTitle("Sequence number"); 518 plot->SetTitle("Sequence number");
444 } 519 }
445 520
446 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) { 521 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) {
447 for (auto& kv : rtp_packets_) { 522 for (auto& kv : rtp_packets_) {
448 StreamId stream_id = kv.first; 523 StreamId stream_id = kv.first;
524 const std::vector<LoggedRtpPacket>& packet_stream = kv.second;
525 uint32_t ssrc = stream_id.GetSsrc();
449 // Filter on direction and SSRC. 526 // Filter on direction and SSRC.
450 if (stream_id.GetDirection() != kIncomingPacket || 527 if (stream_id.GetDirection() != kIncomingPacket ||
451 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { 528 !MatchingSsrc(ssrc, desired_ssrc_) || IsAudioSsrc(stream_id) ||
529 !IsVideoSsrc(stream_id) || IsRtxSsrc(stream_id)) {
452 continue; 530 continue;
453 } 531 }
454 532
455 TimeSeries time_series; 533 TimeSeries capture_time_data;
456 time_series.label = SsrcToString(stream_id.GetSsrc()); 534 capture_time_data.label = SsrcToString(ssrc) + " capture-time";
457 time_series.style = BAR_GRAPH; 535 capture_time_data.style = BAR_GRAPH;
458 const std::vector<LoggedRtpPacket>& packet_stream = kv.second; 536 Pairwise<NetworkDelayDiff::CaptureTime>(packet_stream, begin_time_,
459 int64_t last_abs_send_time = 0; 537 &capture_time_data);
460 int64_t last_timestamp = 0; 538 plot->series_list_.push_back(std::move(capture_time_data));
461 for (const LoggedRtpPacket& packet : packet_stream) {
462 if (packet.header.extension.hasAbsoluteSendTime) {
463 int64_t send_time_diff =
464 WrappingDifference(packet.header.extension.absoluteSendTime,
465 last_abs_send_time, 1ul << 24);
466 int64_t recv_time_diff = packet.timestamp - last_timestamp;
467 539
468 last_abs_send_time = packet.header.extension.absoluteSendTime; 540 TimeSeries send_time_data;
469 last_timestamp = packet.timestamp; 541 send_time_data.label = SsrcToString(ssrc) + " abs-send-time";
470 542 send_time_data.style = BAR_GRAPH;
471 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000; 543 Pairwise<NetworkDelayDiff::AbsSendTime>(packet_stream, begin_time_,
472 double y = 544 &send_time_data);
473 static_cast<double>(recv_time_diff - 545 plot->series_list_.push_back(std::move(send_time_data));
474 AbsSendTimeToMicroseconds(send_time_diff)) /
475 1000;
476 if (time_series.points.size() == 0) {
477 // There were no previously logged packets for this SSRC.
478 // Generate a point, but place it on the x-axis.
479 y = 0;
480 }
481 time_series.points.emplace_back(x, y);
482 }
483 }
484 // Add the data set to the plot.
485 plot->series_list_.push_back(std::move(time_series));
486 } 546 }
487 547
488 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); 548 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
489 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin, 549 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin,
490 kTopMargin); 550 kTopMargin);
491 plot->SetTitle("Network latency change between consecutive packets"); 551 plot->SetTitle("Network latency change between consecutive packets");
492 } 552 }
493 553
494 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) { 554 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) {
495 for (auto& kv : rtp_packets_) { 555 for (auto& kv : rtp_packets_) {
496 StreamId stream_id = kv.first; 556 StreamId stream_id = kv.first;
557 const std::vector<LoggedRtpPacket>& packet_stream = kv.second;
558 uint32_t ssrc = stream_id.GetSsrc();
497 // Filter on direction and SSRC. 559 // Filter on direction and SSRC.
498 if (stream_id.GetDirection() != kIncomingPacket || 560 if (stream_id.GetDirection() != kIncomingPacket ||
499 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { 561 !MatchingSsrc(ssrc, desired_ssrc_) || IsAudioSsrc(stream_id) ||
562 !IsVideoSsrc(stream_id) || IsRtxSsrc(stream_id)) {
500 continue; 563 continue;
501 } 564 }
502 TimeSeries time_series;
503 time_series.label = SsrcToString(stream_id.GetSsrc());
504 time_series.style = LINE_GRAPH;
505 const std::vector<LoggedRtpPacket>& packet_stream = kv.second;
506 int64_t last_abs_send_time = 0;
507 int64_t last_timestamp = 0;
508 double accumulated_delay_ms = 0;
509 for (const LoggedRtpPacket& packet : packet_stream) {
510 if (packet.header.extension.hasAbsoluteSendTime) {
511 int64_t send_time_diff =
512 WrappingDifference(packet.header.extension.absoluteSendTime,
513 last_abs_send_time, 1ul << 24);
514 int64_t recv_time_diff = packet.timestamp - last_timestamp;
515 565
516 last_abs_send_time = packet.header.extension.absoluteSendTime; 566 TimeSeries capture_time_data;
517 last_timestamp = packet.timestamp; 567 capture_time_data.label = SsrcToString(ssrc) + " capture-time";
568 capture_time_data.style = LINE_GRAPH;
569 Pairwise<Accumulated<NetworkDelayDiff::CaptureTime>>(
570 packet_stream, begin_time_, &capture_time_data);
571 plot->series_list_.push_back(std::move(capture_time_data));
518 572
519 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000; 573 TimeSeries send_time_data;
520 accumulated_delay_ms += 574 send_time_data.label = SsrcToString(ssrc) + " abs-send-time";
521 static_cast<double>(recv_time_diff - 575 send_time_data.style = LINE_GRAPH;
522 AbsSendTimeToMicroseconds(send_time_diff)) / 576 Pairwise<Accumulated<NetworkDelayDiff::AbsSendTime>>(
523 1000; 577 packet_stream, begin_time_, &send_time_data);
524 if (time_series.points.size() == 0) { 578 plot->series_list_.push_back(std::move(send_time_data));
525 // There were no previously logged packets for this SSRC.
526 // Generate a point, but place it on the x-axis.
527 accumulated_delay_ms = 0;
528 }
529 time_series.points.emplace_back(x, accumulated_delay_ms);
530 }
531 }
532 // Add the data set to the plot.
533 plot->series_list_.push_back(std::move(time_series));
534 } 579 }
535 580
536 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); 581 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
537 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin, 582 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin,
538 kTopMargin); 583 kTopMargin);
539 plot->SetTitle("Accumulated network latency change"); 584 plot->SetTitle("Accumulated network latency change");
540 } 585 }
541 586
542 // Plot the fraction of packets lost (as perceived by the loss-based BWE). 587 // Plot the fraction of packets lost (as perceived by the loss-based BWE).
543 void EventLogAnalyzer::CreateFractionLossGraph(Plot* plot) { 588 void EventLogAnalyzer::CreateFractionLossGraph(Plot* plot) {
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 point.y -= estimated_base_delay_ms; 944 point.y -= estimated_base_delay_ms;
900 // Add the data set to the plot. 945 // Add the data set to the plot.
901 plot->series_list_.push_back(std::move(time_series)); 946 plot->series_list_.push_back(std::move(time_series));
902 947
903 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); 948 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
904 plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin); 949 plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin);
905 plot->SetTitle("Network Delay Change."); 950 plot->SetTitle("Network Delay Change.");
906 } 951 }
907 } // namespace plotting 952 } // namespace plotting
908 } // namespace webrtc 953 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/tools/event_log_visualizer/analyzer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698