Add Parser to analyse the results of the network tester.

BUG=webrtc:7426

Review-Url: https://codereview.webrtc.org/2833353003
Cr-Commit-Position: refs/heads/master@{#18159}
diff --git a/webrtc/tools/network_tester/parse_packet_log.py b/webrtc/tools/network_tester/parse_packet_log.py
new file mode 100755
index 0000000..3b263e0
--- /dev/null
+++ b/webrtc/tools/network_tester/parse_packet_log.py
@@ -0,0 +1,147 @@
+#  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/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()