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 23 24def GetSize(file_to_parse): 25 data = file_to_parse.read(1) 26 if data == '': 27 return 0 28 return struct.unpack('<b', data)[0] 29 30 31def ParsePacketLog(packet_log_file_to_parse): 32 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 45 46 47def GetTimeAxis(packets): 48 first_arrival_time = packets[0].arrival_timestamp 49 return [(packet.arrival_timestamp - first_arrival_time) / 1000000.0 50 for packet in packets] 51 52 53def CreateSendTimeDiffPlot(packets, plot): 54 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) 61 62 63class MovingAverageBitrate(object): 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, 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) 128 129 130def main(): 131 parser = OptionParser() 132 parser.add_option("-f", 133 "--packet_log_file", 134 dest="packet_log_file", 135 help="packet_log file to parse") 136 137 options = parser.parse_args()[0] 138 139 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() 147 148 149if __name__ == "__main__": 150 main() 151