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

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

Powered by Google App Engine
This is Rietveld 408576698