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 |
(...skipping 10 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |