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

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

Issue 2179223003: Convenience functions to set axis properties in visualization tool. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Comments from Danil 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
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 10 matching lines...) Expand all
21 #include "webrtc/audio_send_stream.h" 21 #include "webrtc/audio_send_stream.h"
22 #include "webrtc/base/checks.h" 22 #include "webrtc/base/checks.h"
23 #include "webrtc/call.h" 23 #include "webrtc/call.h"
24 #include "webrtc/common_types.h" 24 #include "webrtc/common_types.h"
25 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 25 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
26 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 26 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
27 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 27 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
28 #include "webrtc/video_receive_stream.h" 28 #include "webrtc/video_receive_stream.h"
29 #include "webrtc/video_send_stream.h" 29 #include "webrtc/video_send_stream.h"
30 30
31 namespace webrtc {
32 namespace plotting {
33
31 namespace { 34 namespace {
32 35
33 std::string SsrcToString(uint32_t ssrc) { 36 std::string SsrcToString(uint32_t ssrc) {
34 std::stringstream ss; 37 std::stringstream ss;
35 ss << "SSRC " << ssrc; 38 ss << "SSRC " << ssrc;
36 return ss.str(); 39 return ss.str();
37 } 40 }
38 41
39 // Checks whether an SSRC is contained in the list of desired SSRCs. 42 // Checks whether an SSRC is contained in the list of desired SSRCs.
40 // Note that an empty SSRC list matches every SSRC. 43 // Note that an empty SSRC list matches every SSRC.
(...skipping 28 matching lines...) Expand all
69 int64_t min_difference = max_difference - modulus + 1; 72 int64_t min_difference = max_difference - modulus + 1;
70 if (difference > max_difference) { 73 if (difference > max_difference) {
71 difference -= modulus; 74 difference -= modulus;
72 } 75 }
73 if (difference < min_difference) { 76 if (difference < min_difference) {
74 difference += modulus; 77 difference += modulus;
75 } 78 }
76 return difference; 79 return difference;
77 } 80 }
78 81
79 const double kXMargin = 1.02; 82 constexpr float kLeftMargin = 0.01;
80 const double kYMargin = 1.1; 83 constexpr float kRightMargin = 0.02;
81 const double kDefaultXMin = -1; 84 constexpr float kBottomMargin = 0.02;
82 const double kDefaultYMin = -1; 85 constexpr float kTopMargin = 0.05;
83 86
84 } // namespace 87 } // namespace
85 88
86 namespace webrtc {
87 namespace plotting {
88
89
90 bool EventLogAnalyzer::StreamId::operator<(const StreamId& other) const { 89 bool EventLogAnalyzer::StreamId::operator<(const StreamId& other) const {
91 if (ssrc_ < other.ssrc_) { 90 if (ssrc_ < other.ssrc_) {
92 return true; 91 return true;
93 } 92 }
94 if (ssrc_ == other.ssrc_) { 93 if (ssrc_ == other.ssrc_) {
95 if (media_type_ < other.media_type_) { 94 if (media_type_ < other.media_type_) {
96 return true; 95 return true;
97 } 96 }
98 if (media_type_ == other.media_type_) { 97 if (media_type_ == other.media_type_) {
99 if (direction_ < other.direction_) { 98 if (direction_ < other.direction_) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } 222 }
224 } 223 }
225 } 224 }
226 225
227 if (last_timestamp < first_timestamp) { 226 if (last_timestamp < first_timestamp) {
228 // No useful events in the log. 227 // No useful events in the log.
229 first_timestamp = last_timestamp = 0; 228 first_timestamp = last_timestamp = 0;
230 } 229 }
231 begin_time_ = first_timestamp; 230 begin_time_ = first_timestamp;
232 end_time_ = last_timestamp; 231 end_time_ = last_timestamp;
232 call_duration_s_ = static_cast<float>(end_time_ - begin_time_) / 1000000;
233 } 233 }
234 234
235 void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction, 235 void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction,
236 Plot* plot) { 236 Plot* plot) {
237 std::map<uint32_t, TimeSeries> time_series; 237 std::map<uint32_t, TimeSeries> time_series;
238 238
239 PacketDirection direction; 239 PacketDirection direction;
240 MediaType media_type; 240 MediaType media_type;
241 uint8_t header[IP_PACKET_SIZE]; 241 uint8_t header[IP_PACKET_SIZE];
242 size_t header_length, total_length; 242 size_t header_length, total_length;
243 float max_y = 0;
244 243
245 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 244 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) {
246 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 245 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i);
247 if (event_type == ParsedRtcEventLog::RTP_EVENT) { 246 if (event_type == ParsedRtcEventLog::RTP_EVENT) {
248 parsed_log_.GetRtpHeader(i, &direction, &media_type, header, 247 parsed_log_.GetRtpHeader(i, &direction, &media_type, header,
249 &header_length, &total_length); 248 &header_length, &total_length);
250 if (direction == desired_direction) { 249 if (direction == desired_direction) {
251 // Parse header to get SSRC. 250 // Parse header to get SSRC.
252 RtpUtility::RtpHeaderParser rtp_parser(header, header_length); 251 RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
253 RTPHeader parsed_header; 252 RTPHeader parsed_header;
254 rtp_parser.Parse(&parsed_header); 253 rtp_parser.Parse(&parsed_header);
255 // Filter on SSRC. 254 // Filter on SSRC.
256 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) { 255 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) {
257 uint64_t timestamp = parsed_log_.GetTimestamp(i); 256 uint64_t timestamp = parsed_log_.GetTimestamp(i);
258 float x = static_cast<float>(timestamp - begin_time_) / 1000000; 257 float x = static_cast<float>(timestamp - begin_time_) / 1000000;
259 float y = total_length; 258 float y = total_length;
260 max_y = std::max(max_y, y);
261 time_series[parsed_header.ssrc].points.push_back( 259 time_series[parsed_header.ssrc].points.push_back(
262 TimeSeriesPoint(x, y)); 260 TimeSeriesPoint(x, y));
263 } 261 }
264 } 262 }
265 } 263 }
266 } 264 }
267 265
268 // Set labels and put in graph. 266 // Set labels and put in graph.
269 for (auto& kv : time_series) { 267 for (auto& kv : time_series) {
270 kv.second.label = SsrcToString(kv.first); 268 kv.second.label = SsrcToString(kv.first);
271 kv.second.style = BAR_GRAPH; 269 kv.second.style = BAR_GRAPH;
272 plot->series.push_back(std::move(kv.second)); 270 plot->series_list_.push_back(std::move(kv.second));
273 } 271 }
274 272
275 plot->xaxis_min = kDefaultXMin; 273 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
276 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 274 plot->SetSuggestedYAxis(0, 1, "Packet size (bytes)", kBottomMargin,
277 plot->xaxis_label = "Time (s)"; 275 kTopMargin);
278 plot->yaxis_min = kDefaultYMin;
279 plot->yaxis_max = max_y * kYMargin;
280 plot->yaxis_label = "Packet size (bytes)";
281 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 276 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
282 plot->title = "Incoming RTP packets"; 277 plot->SetTitle("Incoming RTP packets");
283 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 278 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
284 plot->title = "Outgoing RTP packets"; 279 plot->SetTitle("Outgoing RTP packets");
285 } 280 }
286 } 281 }
287 282
288 // For each SSRC, plot the time between the consecutive playouts. 283 // For each SSRC, plot the time between the consecutive playouts.
289 void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) { 284 void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) {
290 std::map<uint32_t, TimeSeries> time_series; 285 std::map<uint32_t, TimeSeries> time_series;
291 std::map<uint32_t, uint64_t> last_playout; 286 std::map<uint32_t, uint64_t> last_playout;
292 287
293 uint32_t ssrc; 288 uint32_t ssrc;
294 float max_y = 0;
295 289
296 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 290 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) {
297 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 291 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i);
298 if (event_type == ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT) { 292 if (event_type == ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT) {
299 parsed_log_.GetAudioPlayout(i, &ssrc); 293 parsed_log_.GetAudioPlayout(i, &ssrc);
300 uint64_t timestamp = parsed_log_.GetTimestamp(i); 294 uint64_t timestamp = parsed_log_.GetTimestamp(i);
301 if (MatchingSsrc(ssrc, desired_ssrc_)) { 295 if (MatchingSsrc(ssrc, desired_ssrc_)) {
302 float x = static_cast<float>(timestamp - begin_time_) / 1000000; 296 float x = static_cast<float>(timestamp - begin_time_) / 1000000;
303 float y = static_cast<float>(timestamp - last_playout[ssrc]) / 1000; 297 float y = static_cast<float>(timestamp - last_playout[ssrc]) / 1000;
304 if (time_series[ssrc].points.size() == 0) { 298 if (time_series[ssrc].points.size() == 0) {
305 // There were no previusly logged playout for this SSRC. 299 // There were no previusly logged playout for this SSRC.
306 // Generate a point, but place it on the x-axis. 300 // Generate a point, but place it on the x-axis.
307 y = 0; 301 y = 0;
308 } 302 }
309 max_y = std::max(max_y, y);
310 time_series[ssrc].points.push_back(TimeSeriesPoint(x, y)); 303 time_series[ssrc].points.push_back(TimeSeriesPoint(x, y));
311 last_playout[ssrc] = timestamp; 304 last_playout[ssrc] = timestamp;
312 } 305 }
313 } 306 }
314 } 307 }
315 308
316 // Set labels and put in graph. 309 // Set labels and put in graph.
317 for (auto& kv : time_series) { 310 for (auto& kv : time_series) {
318 kv.second.label = SsrcToString(kv.first); 311 kv.second.label = SsrcToString(kv.first);
319 kv.second.style = BAR_GRAPH; 312 kv.second.style = BAR_GRAPH;
320 plot->series.push_back(std::move(kv.second)); 313 plot->series_list_.push_back(std::move(kv.second));
321 } 314 }
322 315
323 plot->xaxis_min = kDefaultXMin; 316 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
324 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 317 plot->SetSuggestedYAxis(0, 1, "Time since last playout (ms)", kBottomMargin,
325 plot->xaxis_label = "Time (s)"; 318 kTopMargin);
326 plot->yaxis_min = kDefaultYMin; 319 plot->SetTitle("Audio playout");
327 plot->yaxis_max = max_y * kYMargin;
328 plot->yaxis_label = "Time since last playout (ms)";
329 plot->title = "Audio playout";
330 } 320 }
331 321
332 // For each SSRC, plot the time between the consecutive playouts. 322 // For each SSRC, plot the time between the consecutive playouts.
333 void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) { 323 void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) {
334 std::map<uint32_t, TimeSeries> time_series; 324 std::map<uint32_t, TimeSeries> time_series;
335 std::map<uint32_t, uint16_t> last_seqno; 325 std::map<uint32_t, uint16_t> last_seqno;
336 326
337 PacketDirection direction; 327 PacketDirection direction;
338 MediaType media_type; 328 MediaType media_type;
339 uint8_t header[IP_PACKET_SIZE]; 329 uint8_t header[IP_PACKET_SIZE];
340 size_t header_length, total_length; 330 size_t header_length, total_length;
341 331
342 int max_y = 1;
343 int min_y = 0;
344
345 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { 332 for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) {
346 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); 333 ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i);
347 if (event_type == ParsedRtcEventLog::RTP_EVENT) { 334 if (event_type == ParsedRtcEventLog::RTP_EVENT) {
348 parsed_log_.GetRtpHeader(i, &direction, &media_type, header, 335 parsed_log_.GetRtpHeader(i, &direction, &media_type, header,
349 &header_length, &total_length); 336 &header_length, &total_length);
350 uint64_t timestamp = parsed_log_.GetTimestamp(i); 337 uint64_t timestamp = parsed_log_.GetTimestamp(i);
351 if (direction == PacketDirection::kIncomingPacket) { 338 if (direction == PacketDirection::kIncomingPacket) {
352 // Parse header to get SSRC. 339 // Parse header to get SSRC.
353 RtpUtility::RtpHeaderParser rtp_parser(header, header_length); 340 RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
354 RTPHeader parsed_header; 341 RTPHeader parsed_header;
355 rtp_parser.Parse(&parsed_header); 342 rtp_parser.Parse(&parsed_header);
356 // Filter on SSRC. 343 // Filter on SSRC.
357 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) { 344 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) {
358 float x = static_cast<float>(timestamp - begin_time_) / 1000000; 345 float x = static_cast<float>(timestamp - begin_time_) / 1000000;
359 int y = WrappingDifference(parsed_header.sequenceNumber, 346 int y = WrappingDifference(parsed_header.sequenceNumber,
360 last_seqno[parsed_header.ssrc], 1ul << 16); 347 last_seqno[parsed_header.ssrc], 1ul << 16);
361 if (time_series[parsed_header.ssrc].points.size() == 0) { 348 if (time_series[parsed_header.ssrc].points.size() == 0) {
362 // There were no previusly logged playout for this SSRC. 349 // There were no previusly logged playout for this SSRC.
363 // Generate a point, but place it on the x-axis. 350 // Generate a point, but place it on the x-axis.
364 y = 0; 351 y = 0;
365 } 352 }
366 max_y = std::max(max_y, y);
367 min_y = std::min(min_y, y);
368 time_series[parsed_header.ssrc].points.push_back( 353 time_series[parsed_header.ssrc].points.push_back(
369 TimeSeriesPoint(x, y)); 354 TimeSeriesPoint(x, y));
370 last_seqno[parsed_header.ssrc] = parsed_header.sequenceNumber; 355 last_seqno[parsed_header.ssrc] = parsed_header.sequenceNumber;
371 } 356 }
372 } 357 }
373 } 358 }
374 } 359 }
375 360
376 // Set labels and put in graph. 361 // Set labels and put in graph.
377 for (auto& kv : time_series) { 362 for (auto& kv : time_series) {
378 kv.second.label = SsrcToString(kv.first); 363 kv.second.label = SsrcToString(kv.first);
379 kv.second.style = BAR_GRAPH; 364 kv.second.style = BAR_GRAPH;
380 plot->series.push_back(std::move(kv.second)); 365 plot->series_list_.push_back(std::move(kv.second));
381 } 366 }
382 367
383 plot->xaxis_min = kDefaultXMin; 368 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
384 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 369 plot->SetSuggestedYAxis(0, 1, "Difference since last packet", kBottomMargin,
385 plot->xaxis_label = "Time (s)"; 370 kTopMargin);
386 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 371 plot->SetTitle("Sequence number");
387 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
388 plot->yaxis_label = "Difference since last packet";
389 plot->title = "Sequence number";
390 } 372 }
391 373
392 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) { 374 void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) {
393 double max_y = 10;
394 double min_y = 0;
395
396 for (auto& kv : rtp_packets_) { 375 for (auto& kv : rtp_packets_) {
397 StreamId stream_id = kv.first; 376 StreamId stream_id = kv.first;
398 // Filter on direction and SSRC. 377 // Filter on direction and SSRC.
399 if (stream_id.GetDirection() != kIncomingPacket || 378 if (stream_id.GetDirection() != kIncomingPacket ||
400 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { 379 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) {
401 continue; 380 continue;
402 } 381 }
403 382
404 TimeSeries time_series; 383 TimeSeries time_series;
405 time_series.label = SsrcToString(stream_id.GetSsrc()); 384 time_series.label = SsrcToString(stream_id.GetSsrc());
(...skipping 14 matching lines...) Expand all
420 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000; 399 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
421 double y = 400 double y =
422 static_cast<double>(recv_time_diff - 401 static_cast<double>(recv_time_diff -
423 AbsSendTimeToMicroseconds(send_time_diff)) / 402 AbsSendTimeToMicroseconds(send_time_diff)) /
424 1000; 403 1000;
425 if (time_series.points.size() == 0) { 404 if (time_series.points.size() == 0) {
426 // There were no previously logged packets for this SSRC. 405 // There were no previously logged packets for this SSRC.
427 // Generate a point, but place it on the x-axis. 406 // Generate a point, but place it on the x-axis.
428 y = 0; 407 y = 0;
429 } 408 }
430 max_y = std::max(max_y, y);
431 min_y = std::min(min_y, y);
432 time_series.points.emplace_back(x, y); 409 time_series.points.emplace_back(x, y);
433 } 410 }
434 } 411 }
435 // Add the data set to the plot. 412 // Add the data set to the plot.
436 plot->series.push_back(std::move(time_series)); 413 plot->series_list_.push_back(std::move(time_series));
437 } 414 }
438 415
439 plot->xaxis_min = kDefaultXMin; 416 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
440 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 417 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin,
441 plot->xaxis_label = "Time (s)"; 418 kTopMargin);
442 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 419 plot->SetTitle("Network latency change between consecutive packets");
443 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
444 plot->yaxis_label = "Latency change (ms)";
445 plot->title = "Network latency change between consecutive packets";
446 } 420 }
447 421
448 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) { 422 void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) {
449 double max_y = 10;
450 double min_y = 0;
451
452 for (auto& kv : rtp_packets_) { 423 for (auto& kv : rtp_packets_) {
453 StreamId stream_id = kv.first; 424 StreamId stream_id = kv.first;
454 // Filter on direction and SSRC. 425 // Filter on direction and SSRC.
455 if (stream_id.GetDirection() != kIncomingPacket || 426 if (stream_id.GetDirection() != kIncomingPacket ||
456 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { 427 !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) {
457 continue; 428 continue;
458 } 429 }
459 TimeSeries time_series; 430 TimeSeries time_series;
460 time_series.label = SsrcToString(stream_id.GetSsrc()); 431 time_series.label = SsrcToString(stream_id.GetSsrc());
461 time_series.style = LINE_GRAPH; 432 time_series.style = LINE_GRAPH;
(...skipping 14 matching lines...) Expand all
476 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000; 447 float x = static_cast<float>(packet.timestamp - begin_time_) / 1000000;
477 accumulated_delay_ms += 448 accumulated_delay_ms +=
478 static_cast<double>(recv_time_diff - 449 static_cast<double>(recv_time_diff -
479 AbsSendTimeToMicroseconds(send_time_diff)) / 450 AbsSendTimeToMicroseconds(send_time_diff)) /
480 1000; 451 1000;
481 if (time_series.points.size() == 0) { 452 if (time_series.points.size() == 0) {
482 // There were no previously logged packets for this SSRC. 453 // There were no previously logged packets for this SSRC.
483 // Generate a point, but place it on the x-axis. 454 // Generate a point, but place it on the x-axis.
484 accumulated_delay_ms = 0; 455 accumulated_delay_ms = 0;
485 } 456 }
486 max_y = std::max(max_y, accumulated_delay_ms);
487 min_y = std::min(min_y, accumulated_delay_ms);
488 time_series.points.emplace_back(x, accumulated_delay_ms); 457 time_series.points.emplace_back(x, accumulated_delay_ms);
489 } 458 }
490 } 459 }
491 // Add the data set to the plot. 460 // Add the data set to the plot.
492 plot->series.push_back(std::move(time_series)); 461 plot->series_list_.push_back(std::move(time_series));
493 } 462 }
494 463
495 plot->xaxis_min = kDefaultXMin; 464 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
496 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 465 plot->SetSuggestedYAxis(0, 1, "Latency change (ms)", kBottomMargin,
497 plot->xaxis_label = "Time (s)"; 466 kTopMargin);
498 plot->yaxis_min = min_y - (kYMargin - 1) / 2 * (max_y - min_y); 467 plot->SetTitle("Accumulated network latency change");
499 plot->yaxis_max = max_y + (kYMargin - 1) / 2 * (max_y - min_y);
500 plot->yaxis_label = "Latency change (ms)";
501 plot->title = "Accumulated network latency change";
502 } 468 }
503 469
504 // Plot the total bandwidth used by all RTP streams. 470 // Plot the total bandwidth used by all RTP streams.
505 void EventLogAnalyzer::CreateTotalBitrateGraph( 471 void EventLogAnalyzer::CreateTotalBitrateGraph(
506 PacketDirection desired_direction, 472 PacketDirection desired_direction,
507 Plot* plot) { 473 Plot* plot) {
508 struct TimestampSize { 474 struct TimestampSize {
509 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {} 475 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {}
510 uint64_t timestamp; 476 uint64_t timestamp;
511 size_t size; 477 size_t size;
(...skipping 12 matching lines...) Expand all
524 if (direction == desired_direction) { 490 if (direction == desired_direction) {
525 uint64_t timestamp = parsed_log_.GetTimestamp(i); 491 uint64_t timestamp = parsed_log_.GetTimestamp(i);
526 packets.push_back(TimestampSize(timestamp, total_length)); 492 packets.push_back(TimestampSize(timestamp, total_length));
527 } 493 }
528 } 494 }
529 } 495 }
530 496
531 size_t window_index_begin = 0; 497 size_t window_index_begin = 0;
532 size_t window_index_end = 0; 498 size_t window_index_end = 0;
533 size_t bytes_in_window = 0; 499 size_t bytes_in_window = 0;
534 float max_y = 0;
535 500
536 // Calculate a moving average of the bitrate and store in a TimeSeries. 501 // Calculate a moving average of the bitrate and store in a TimeSeries.
537 plot->series.push_back(TimeSeries()); 502 plot->series_list_.push_back(TimeSeries());
538 for (uint64_t time = begin_time_; time < end_time_ + step_; time += step_) { 503 for (uint64_t time = begin_time_; time < end_time_ + step_; time += step_) {
539 while (window_index_end < packets.size() && 504 while (window_index_end < packets.size() &&
540 packets[window_index_end].timestamp < time) { 505 packets[window_index_end].timestamp < time) {
541 bytes_in_window += packets[window_index_end].size; 506 bytes_in_window += packets[window_index_end].size;
542 window_index_end++; 507 window_index_end++;
543 } 508 }
544 while (window_index_begin < packets.size() && 509 while (window_index_begin < packets.size() &&
545 packets[window_index_begin].timestamp < time - window_duration_) { 510 packets[window_index_begin].timestamp < time - window_duration_) {
546 RTC_DCHECK_LE(packets[window_index_begin].size, bytes_in_window); 511 RTC_DCHECK_LE(packets[window_index_begin].size, bytes_in_window);
547 bytes_in_window -= packets[window_index_begin].size; 512 bytes_in_window -= packets[window_index_begin].size;
548 window_index_begin++; 513 window_index_begin++;
549 } 514 }
550 float window_duration_in_seconds = 515 float window_duration_in_seconds =
551 static_cast<float>(window_duration_) / 1000000; 516 static_cast<float>(window_duration_) / 1000000;
552 float x = static_cast<float>(time - begin_time_) / 1000000; 517 float x = static_cast<float>(time - begin_time_) / 1000000;
553 float y = bytes_in_window * 8 / window_duration_in_seconds / 1000; 518 float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
554 max_y = std::max(max_y, y); 519 plot->series_list_.back().points.push_back(TimeSeriesPoint(x, y));
555 plot->series.back().points.push_back(TimeSeriesPoint(x, y));
556 } 520 }
557 521
558 // Set labels. 522 // Set labels.
559 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 523 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
560 plot->series.back().label = "Incoming bitrate"; 524 plot->series_list_.back().label = "Incoming bitrate";
561 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 525 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
562 plot->series.back().label = "Outgoing bitrate"; 526 plot->series_list_.back().label = "Outgoing bitrate";
563 } 527 }
564 plot->series.back().style = LINE_GRAPH; 528 plot->series_list_.back().style = LINE_GRAPH;
565 529
566 // Overlay the send-side bandwidth estimate over the outgoing bitrate. 530 // Overlay the send-side bandwidth estimate over the outgoing bitrate.
567 if (desired_direction == kOutgoingPacket) { 531 if (desired_direction == kOutgoingPacket) {
568 plot->series.push_back(TimeSeries()); 532 plot->series_list_.push_back(TimeSeries());
569 for (auto& bwe_update : bwe_loss_updates_) { 533 for (auto& bwe_update : bwe_loss_updates_) {
570 float x = 534 float x =
571 static_cast<float>(bwe_update.timestamp - begin_time_) / 1000000; 535 static_cast<float>(bwe_update.timestamp - begin_time_) / 1000000;
572 float y = static_cast<float>(bwe_update.new_bitrate) / 1000; 536 float y = static_cast<float>(bwe_update.new_bitrate) / 1000;
573 max_y = std::max(max_y, y); 537 plot->series_list_.back().points.emplace_back(x, y);
574 plot->series.back().points.emplace_back(x, y);
575 } 538 }
576 plot->series.back().label = "Loss-based estimate"; 539 plot->series_list_.back().label = "Loss-based estimate";
577 plot->series.back().style = LINE_GRAPH; 540 plot->series_list_.back().style = LINE_GRAPH;
578 } 541 }
579 542 plot->series_list_.back().style = LINE_GRAPH;
580 plot->xaxis_min = kDefaultXMin; 543 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
581 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 544 plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);
582 plot->xaxis_label = "Time (s)";
583 plot->yaxis_min = kDefaultYMin;
584 plot->yaxis_max = max_y * kYMargin;
585 plot->yaxis_label = "Bitrate (kbps)";
586 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 545 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
587 plot->title = "Incoming RTP bitrate"; 546 plot->SetTitle("Incoming RTP bitrate");
588 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 547 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
589 plot->title = "Outgoing RTP bitrate"; 548 plot->SetTitle("Outgoing RTP bitrate");
590 } 549 }
591 } 550 }
592 551
593 // For each SSRC, plot the bandwidth used by that stream. 552 // For each SSRC, plot the bandwidth used by that stream.
594 void EventLogAnalyzer::CreateStreamBitrateGraph( 553 void EventLogAnalyzer::CreateStreamBitrateGraph(
595 PacketDirection desired_direction, 554 PacketDirection desired_direction,
596 Plot* plot) { 555 Plot* plot) {
597 struct TimestampSize { 556 struct TimestampSize {
598 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {} 557 TimestampSize(uint64_t t, size_t s) : timestamp(t), size(s) {}
599 uint64_t timestamp; 558 uint64_t timestamp;
(...skipping 20 matching lines...) Expand all
620 // Filter on SSRC. 579 // Filter on SSRC.
621 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) { 580 if (MatchingSsrc(parsed_header.ssrc, desired_ssrc_)) {
622 uint64_t timestamp = parsed_log_.GetTimestamp(i); 581 uint64_t timestamp = parsed_log_.GetTimestamp(i);
623 packets[parsed_header.ssrc].push_back( 582 packets[parsed_header.ssrc].push_back(
624 TimestampSize(timestamp, total_length)); 583 TimestampSize(timestamp, total_length));
625 } 584 }
626 } 585 }
627 } 586 }
628 } 587 }
629 588
630 float max_y = 0;
631
632 for (auto& kv : packets) { 589 for (auto& kv : packets) {
633 size_t window_index_begin = 0; 590 size_t window_index_begin = 0;
634 size_t window_index_end = 0; 591 size_t window_index_end = 0;
635 size_t bytes_in_window = 0; 592 size_t bytes_in_window = 0;
636 593
637 // Calculate a moving average of the bitrate and store in a TimeSeries. 594 // Calculate a moving average of the bitrate and store in a TimeSeries.
638 plot->series.push_back(TimeSeries()); 595 plot->series_list_.push_back(TimeSeries());
639 for (uint64_t time = begin_time_; time < end_time_ + step_; time += step_) { 596 for (uint64_t time = begin_time_; time < end_time_ + step_; time += step_) {
640 while (window_index_end < kv.second.size() && 597 while (window_index_end < kv.second.size() &&
641 kv.second[window_index_end].timestamp < time) { 598 kv.second[window_index_end].timestamp < time) {
642 bytes_in_window += kv.second[window_index_end].size; 599 bytes_in_window += kv.second[window_index_end].size;
643 window_index_end++; 600 window_index_end++;
644 } 601 }
645 while (window_index_begin < kv.second.size() && 602 while (window_index_begin < kv.second.size() &&
646 kv.second[window_index_begin].timestamp < 603 kv.second[window_index_begin].timestamp <
647 time - window_duration_) { 604 time - window_duration_) {
648 RTC_DCHECK_LE(kv.second[window_index_begin].size, bytes_in_window); 605 RTC_DCHECK_LE(kv.second[window_index_begin].size, bytes_in_window);
649 bytes_in_window -= kv.second[window_index_begin].size; 606 bytes_in_window -= kv.second[window_index_begin].size;
650 window_index_begin++; 607 window_index_begin++;
651 } 608 }
652 float window_duration_in_seconds = 609 float window_duration_in_seconds =
653 static_cast<float>(window_duration_) / 1000000; 610 static_cast<float>(window_duration_) / 1000000;
654 float x = static_cast<float>(time - begin_time_) / 1000000; 611 float x = static_cast<float>(time - begin_time_) / 1000000;
655 float y = bytes_in_window * 8 / window_duration_in_seconds / 1000; 612 float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
656 max_y = std::max(max_y, y); 613 plot->series_list_.back().points.push_back(TimeSeriesPoint(x, y));
657 plot->series.back().points.push_back(TimeSeriesPoint(x, y));
658 } 614 }
659 615
660 // Set labels. 616 // Set labels.
661 plot->series.back().label = SsrcToString(kv.first); 617 plot->series_list_.back().label = SsrcToString(kv.first);
662 plot->series.back().style = LINE_GRAPH; 618 plot->series_list_.back().style = LINE_GRAPH;
663 } 619 }
664 620
665 plot->xaxis_min = kDefaultXMin; 621 plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
666 plot->xaxis_max = (end_time_ - begin_time_) / 1000000 * kXMargin; 622 plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);
667 plot->xaxis_label = "Time (s)";
668 plot->yaxis_min = kDefaultYMin;
669 plot->yaxis_max = max_y * kYMargin;
670 plot->yaxis_label = "Bitrate (kbps)";
671 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { 623 if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
672 plot->title = "Incoming bitrate per stream"; 624 plot->SetTitle("Incoming bitrate per stream");
673 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) { 625 } else if (desired_direction == webrtc::PacketDirection::kOutgoingPacket) {
674 plot->title = "Outgoing bitrate per stream"; 626 plot->SetTitle("Outgoing bitrate per stream");
675 } 627 }
676 } 628 }
677 629
678 } // namespace plotting 630 } // namespace plotting
679 } // namespace webrtc 631 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698