1# 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 9# To run this script please copy "out/<build_name>/pyproto/webrtc/rtc_tools/ 10# 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 23def GetSize(file_to_parse): 24 data = file_to_parse.read(1) 25 if data == '': 26 return 0 27 return struct.unpack('<b', data)[0] 28 29 30def ParsePacketLog(packet_log_file_to_parse): 31 packets = [] 32 with open(packet_log_file_to_parse, 'rb') as file_to_parse: 33 while True: 34 size = GetSize(file_to_parse) 35 if size == 0: 36 break 37 try: 38 packet = network_tester_packet_pb2.NetworkTesterPacket() 39 packet.ParseFromString(file_to_parse.read(size)) 40 packets.append(packet) 41 except IOError: 42 break 43 return packets 44 45 46def GetTimeAxis(packets): 47 first_arrival_time = packets[0].arrival_timestamp 48 return [(packet.arrival_timestamp - first_arrival_time) / 1000000.0 49 for packet in packets] 50 51 52def CreateSendTimeDiffPlot(packets, plot): 53 first_send_time_diff = ( 54 packets[0].arrival_timestamp - packets[0].send_timestamp) 55 y = [(packet.arrival_timestamp - packet.send_timestamp) - first_send_time_diff 56 for packet in packets] 57 plot.grid(True) 58 plot.set_title("SendTime difference [us]") 59 plot.plot(GetTimeAxis(packets), y) 60 61 62class MovingAverageBitrate(object): 63 64 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 70 71 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) 77 78 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 86 87 88def CreateReceiveBiratePlot(packets, plot): 89 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) 94 95 96def CreatePacketlossPlot(packets, plot): 97 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, last_sequence_number + 1): 108 if sequence_number in packets_look_up: 109 y.append(0) 110 if first_arrival_time == 0: 111 first_arrival_time = packets_look_up[sequence_number].arrival_timestamp 112 x_time = (packets_look_up[sequence_number].arrival_timestamp - 113 first_arrival_time) 114 if last_arrival_time != 0: 115 last_arrival_time_diff = x_time - last_arrival_time 116 last_arrival_time = x_time 117 x.append(x_time / 1000000.0) 118 else: 119 if last_arrival_time != 0 and last_arrival_time_diff != 0: 120 x.append((last_arrival_time + last_arrival_time_diff) / 1000000.0) 121 y.append(1) 122 plot.grid(True) 123 plot.set_title("Lost packets [0/1]") 124 plot.plot(x, y) 125 126 127def main(): 128 parser = OptionParser() 129 parser.add_option("-f", 130 "--packet_log_file", 131 dest="packet_log_file", 132 help="packet_log file to parse") 133 134 options = parser.parse_args()[0] 135 136 packets = ParsePacketLog(options.packet_log_file) 137 f, plots = plt.subplots(3, sharex=True) 138 plt.xlabel('time [sec]') 139 CreateSendTimeDiffPlot(packets, plots[0]) 140 CreateReceiveBiratePlot(packets, plots[1]) 141 CreatePacketlossPlot(packets, plots[2]) 142 f.subplots_adjust(hspace=0.3) 143 plt.show() 144 145 146if __name__ == "__main__": 147 main() 148