| # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | |
| # | |
| # Use of this source code is governed by a BSD-style license | |
| # that can be found in the LICENSE file in the root of the source | |
| # tree. An additional intellectual property rights grant can be found | |
| # in the file PATENTS. All contributing project authors may | |
| # be found in the AUTHORS file in the root of the source tree. | |
| # To run this script please copy "out/<build_name>/pyproto/webrtc/rtc_tools/ | |
| # network_tester/network_tester_packet_pb2.py" next to this script. | |
| # The you can run this script with: | |
| # "python parse_packet_log.py -f packet_log.dat" | |
| # for more information call: | |
| # "python parse_packet_log.py --help" | |
| from optparse import OptionParser | |
| import struct | |
| import matplotlib.pyplot as plt | |
| import network_tester_packet_pb2 | |
| def GetSize(file_to_parse): | |
| data = file_to_parse.read(1) | |
| if data == '': | |
| return 0 | |
| return struct.unpack('<b', data)[0] | |
| def ParsePacketLog(packet_log_file_to_parse): | |
| packets = [] | |
| with open(packet_log_file_to_parse, 'rb') as file_to_parse: | |
| while True: | |
| size = GetSize(file_to_parse) | |
| if size == 0: | |
| break | |
| try: | |
| packet = network_tester_packet_pb2.NetworkTesterPacket() | |
| packet.ParseFromString(file_to_parse.read(size)) | |
| packets.append(packet) | |
| except IOError: | |
| break | |
| return packets | |
| def GetTimeAxis(packets): | |
| first_arrival_time = packets[0].arrival_timestamp | |
| return [(packet.arrival_timestamp - first_arrival_time) / 1000000.0 | |
| for packet in packets] | |
| def CreateSendTimeDiffPlot(packets, plot): | |
| first_send_time_diff = (packets[0].arrival_timestamp - | |
| packets[0].send_timestamp) | |
| y = [(packet.arrival_timestamp - packet.send_timestamp) - | |
| first_send_time_diff for packet in packets] | |
| plot.grid(True) | |
| plot.set_title("SendTime difference [us]") | |
| plot.plot(GetTimeAxis(packets), y) | |
| class MovingAverageBitrate(object): | |
| def __init__(self): | |
| self.packet_window = [] | |
| self.window_time = 1000000 | |
| self.bytes = 0 | |
| self.latest_packet_time = 0 | |
| self.send_interval = 0 | |
| def RemoveOldPackets(self): | |
| for packet in self.packet_window: | |
| if (self.latest_packet_time - packet.arrival_timestamp > | |
| self.window_time): | |
| self.bytes = self.bytes - packet.packet_size | |
| self.packet_window.remove(packet) | |
| def AddPacket(self, packet): | |
| """This functions returns bits / second""" | |
| self.send_interval = packet.arrival_timestamp - self.latest_packet_time | |
| self.latest_packet_time = packet.arrival_timestamp | |
| self.RemoveOldPackets() | |
| self.packet_window.append(packet) | |
| self.bytes = self.bytes + packet.packet_size | |
| return self.bytes * 8 | |
| def CreateReceiveBiratePlot(packets, plot): | |
| bitrate = MovingAverageBitrate() | |
| y = [bitrate.AddPacket(packet) for packet in packets] | |
| plot.grid(True) | |
| plot.set_title("Receive birate [bps]") | |
| plot.plot(GetTimeAxis(packets), y) | |
| def CreatePacketlossPlot(packets, plot): | |
| packets_look_up = {} | |
| first_sequence_number = packets[0].sequence_number | |
| last_sequence_number = packets[-1].sequence_number | |
| for packet in packets: | |
| packets_look_up[packet.sequence_number] = packet | |
| y = [] | |
| x = [] | |
| first_arrival_time = 0 | |
| last_arrival_time = 0 | |
| last_arrival_time_diff = 0 | |
| for sequence_number in range(first_sequence_number, | |
| last_sequence_number + 1): | |
| if sequence_number in packets_look_up: | |
| y.append(0) | |
| if first_arrival_time == 0: | |
| first_arrival_time = packets_look_up[ | |
| sequence_number].arrival_timestamp | |
| x_time = (packets_look_up[sequence_number].arrival_timestamp - | |
| first_arrival_time) | |
| if last_arrival_time != 0: | |
| last_arrival_time_diff = x_time - last_arrival_time | |
| last_arrival_time = x_time | |
| x.append(x_time / 1000000.0) | |
| else: | |
| if last_arrival_time != 0 and last_arrival_time_diff != 0: | |
| x.append( | |
| (last_arrival_time + last_arrival_time_diff) / 1000000.0) | |
| y.append(1) | |
| plot.grid(True) | |
| plot.set_title("Lost packets [0/1]") | |
| plot.plot(x, y) | |
| def main(): | |
| parser = OptionParser() | |
| parser.add_option("-f", | |
| "--packet_log_file", | |
| dest="packet_log_file", | |
| help="packet_log file to parse") | |
| options = parser.parse_args()[0] | |
| packets = ParsePacketLog(options.packet_log_file) | |
| f, plots = plt.subplots(3, sharex=True) | |
| plt.xlabel('time [sec]') | |
| CreateSendTimeDiffPlot(packets, plots[0]) | |
| CreateReceiveBiratePlot(packets, plots[1]) | |
| CreatePacketlossPlot(packets, plots[2]) | |
| f.subplots_adjust(hspace=0.3) | |
| plt.show() | |
| if __name__ == "__main__": | |
| main() |