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 { | 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |