blob: be86e0c88d657697bbef7cb3e2281eeb61eed76e [file] [log] [blame]
michaelt7be9e422017-05-16 09:22:221# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
2#
3# Use of this source code is governed by a BSD-style license
4# that can be found in the LICENSE file in the root of the source
5# tree. An additional intellectual property rights grant can be found
6# in the file PATENTS. All contributing project authors may
7# be found in the AUTHORS file in the root of the source tree.
8
kjellanderd2b63cf2017-06-30 10:04:599# To run this script please copy "out/<build_name>/pyproto/webrtc/rtc_tools/
michaelt7be9e422017-05-16 09:22:2210# network_tester/network_tester_packet_pb2.py" next to this script.
11# The you can run this script with:
12# "python parse_packet_log.py -f packet_log.dat"
13# for more information call:
14# "python parse_packet_log.py --help"
15
16from optparse import OptionParser
17import struct
18
19import matplotlib.pyplot as plt
20
21import network_tester_packet_pb2
22
Mirko Bonadei8cc66952020-10-30 09:13:4523
michaelt7be9e422017-05-16 09:22:2224def GetSize(file_to_parse):
Mirko Bonadei8cc66952020-10-30 09:13:4525 data = file_to_parse.read(1)
26 if data == '':
27 return 0
28 return struct.unpack('<b', data)[0]
michaelt7be9e422017-05-16 09:22:2229
30
31def ParsePacketLog(packet_log_file_to_parse):
Mirko Bonadei8cc66952020-10-30 09:13:4532 packets = []
33 with open(packet_log_file_to_parse, 'rb') as file_to_parse:
34 while True:
35 size = GetSize(file_to_parse)
36 if size == 0:
37 break
38 try:
39 packet = network_tester_packet_pb2.NetworkTesterPacket()
40 packet.ParseFromString(file_to_parse.read(size))
41 packets.append(packet)
42 except IOError:
43 break
44 return packets
michaelt7be9e422017-05-16 09:22:2245
46
47def GetTimeAxis(packets):
Mirko Bonadei8cc66952020-10-30 09:13:4548 first_arrival_time = packets[0].arrival_timestamp
49 return [(packet.arrival_timestamp - first_arrival_time) / 1000000.0
50 for packet in packets]
michaelt7be9e422017-05-16 09:22:2251
52
53def CreateSendTimeDiffPlot(packets, plot):
Mirko Bonadei8cc66952020-10-30 09:13:4554 first_send_time_diff = (packets[0].arrival_timestamp -
55 packets[0].send_timestamp)
56 y = [(packet.arrival_timestamp - packet.send_timestamp) -
57 first_send_time_diff for packet in packets]
58 plot.grid(True)
59 plot.set_title("SendTime difference [us]")
60 plot.plot(GetTimeAxis(packets), y)
michaelt7be9e422017-05-16 09:22:2261
62
63class MovingAverageBitrate(object):
Mirko Bonadei8cc66952020-10-30 09:13:4564 def __init__(self):
65 self.packet_window = []
66 self.window_time = 1000000
67 self.bytes = 0
68 self.latest_packet_time = 0
69 self.send_interval = 0
michaelt7be9e422017-05-16 09:22:2270
Mirko Bonadei8cc66952020-10-30 09:13:4571 def RemoveOldPackets(self):
72 for packet in self.packet_window:
73 if (self.latest_packet_time - packet.arrival_timestamp >
74 self.window_time):
75 self.bytes = self.bytes - packet.packet_size
76 self.packet_window.remove(packet)
michaelt7be9e422017-05-16 09:22:2277
Mirko Bonadei8cc66952020-10-30 09:13:4578 def AddPacket(self, packet):
79 """This functions returns bits / second"""
80 self.send_interval = packet.arrival_timestamp - self.latest_packet_time
81 self.latest_packet_time = packet.arrival_timestamp
82 self.RemoveOldPackets()
83 self.packet_window.append(packet)
84 self.bytes = self.bytes + packet.packet_size
85 return self.bytes * 8
michaelt7be9e422017-05-16 09:22:2286
87
88def CreateReceiveBiratePlot(packets, plot):
Mirko Bonadei8cc66952020-10-30 09:13:4589 bitrate = MovingAverageBitrate()
90 y = [bitrate.AddPacket(packet) for packet in packets]
91 plot.grid(True)
92 plot.set_title("Receive birate [bps]")
93 plot.plot(GetTimeAxis(packets), y)
michaelt7be9e422017-05-16 09:22:2294
95
96def CreatePacketlossPlot(packets, plot):
Mirko Bonadei8cc66952020-10-30 09:13:4597 packets_look_up = {}
98 first_sequence_number = packets[0].sequence_number
99 last_sequence_number = packets[-1].sequence_number
100 for packet in packets:
101 packets_look_up[packet.sequence_number] = packet
102 y = []
103 x = []
104 first_arrival_time = 0
105 last_arrival_time = 0
106 last_arrival_time_diff = 0
107 for sequence_number in range(first_sequence_number,
108 last_sequence_number + 1):
109 if sequence_number in packets_look_up:
110 y.append(0)
111 if first_arrival_time == 0:
112 first_arrival_time = packets_look_up[
113 sequence_number].arrival_timestamp
114 x_time = (packets_look_up[sequence_number].arrival_timestamp -
115 first_arrival_time)
116 if last_arrival_time != 0:
117 last_arrival_time_diff = x_time - last_arrival_time
118 last_arrival_time = x_time
119 x.append(x_time / 1000000.0)
120 else:
121 if last_arrival_time != 0 and last_arrival_time_diff != 0:
122 x.append(
123 (last_arrival_time + last_arrival_time_diff) / 1000000.0)
124 y.append(1)
125 plot.grid(True)
126 plot.set_title("Lost packets [0/1]")
127 plot.plot(x, y)
michaelt7be9e422017-05-16 09:22:22128
129
130def main():
Mirko Bonadei8cc66952020-10-30 09:13:45131 parser = OptionParser()
132 parser.add_option("-f",
133 "--packet_log_file",
134 dest="packet_log_file",
135 help="packet_log file to parse")
michaelt7be9e422017-05-16 09:22:22136
Mirko Bonadei8cc66952020-10-30 09:13:45137 options = parser.parse_args()[0]
michaelt7be9e422017-05-16 09:22:22138
Mirko Bonadei8cc66952020-10-30 09:13:45139 packets = ParsePacketLog(options.packet_log_file)
140 f, plots = plt.subplots(3, sharex=True)
141 plt.xlabel('time [sec]')
142 CreateSendTimeDiffPlot(packets, plots[0])
143 CreateReceiveBiratePlot(packets, plots[1])
144 CreatePacketlossPlot(packets, plots[2])
145 f.subplots_adjust(hspace=0.3)
146 plt.show()
michaelt7be9e422017-05-16 09:22:22147
148
149if __name__ == "__main__":
Mirko Bonadei8cc66952020-10-30 09:13:45150 main()