blob: 90c9ba0ec34507e8d4dc99322cdad5ba4cb0b856 [file] [log] [blame]
kjellander@webrtc.org689cb302011-11-07 15:25:47 +00001#!/usr/bin/env python
2# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3#
4# Use of this source code is governed by a BSD-style license
5# that can be found in the LICENSE file in the root of the source
6# tree. An additional intellectual property rights grant can be found
7# in the file PATENTS. All contributing project authors may
8# be found in the AUTHORS file in the root of the source tree.
9
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000010import os
11import gviz_api
12import webrtc.data_helper
13
14def main():
15 """
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000016 This Python script displays a web page with test created with the
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000017 video_quality_measurement program, which is a tool in WebRTC.
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000018
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000019 The script requires on two external files and one Python library:
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000020 - A HTML template file with layout and references to the json variables
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000021 defined in this script
22 - A data file in Python format, containing the following:
23 - test_configuration - a dictionary of test configuration names and values.
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000024 - frame_data_types - a dictionary that maps the different metrics to their
kjellander@webrtc.org418bce52011-12-05 16:29:21 +000025 data types.
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000026 - frame_data - a list of dictionaries where each dictionary maps a metric to
27 it's value.
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000028 - The gviz_api.py of the Google Visualization Python API, available at
29 http://code.google.com/p/google-visualization-python/
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000030
31 The HTML file is shipped with the script, while the data file must be
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000032 generated by running video_quality_measurement with the --python flag
33 specified.
34 """
35 print 'Content-type: text/html\n' # the newline is required!
36
37 page_template_filename = '../templates/chart_page_template.html'
38 # The data files must be located in the project tree for app engine being
39 # able to access them.
40 data_filenames = [ '../data/vp8_sw.py', '../data/vp8_hw.py' ]
41 # Will contain info/error messages to be displayed on the resulting page.
42 messages = []
43 # Load the page HTML template.
44 try:
45 f = open(page_template_filename)
46 page_template = f.read()
47 f.close()
48 except IOError as e:
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000049 ShowErrorPage('Cannot open page template file: %s<br>Details: %s' %
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000050 (page_template_filename, e))
51 return
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000052
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000053 # Read data from external Python script files. First check that they exist.
54 for filename in data_filenames:
55 if not os.path.exists(filename):
56 messages.append('Cannot open data file: %s' % filename)
57 data_filenames.remove(filename)
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000058
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000059 # Read data from all existing input files.
60 data_list = []
kjellander@webrtc.org418bce52011-12-05 16:29:21 +000061 test_configurations = []
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000062 names = []
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000063
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000064 for filename in data_filenames:
65 read_vars = {} # empty dictionary to load the data into.
66 execfile(filename, read_vars, read_vars)
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000067
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000068 test_configuration = read_vars['test_configuration']
69 table_description = read_vars['frame_data_types']
70 table_data = read_vars['frame_data']
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000071
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000072 # Verify the data in the file loaded properly.
73 if not table_description or not table_data:
74 messages.append('Invalid input file: %s. Missing description list or '
kjellander@webrtc.org418bce52011-12-05 16:29:21 +000075 'data dictionary variables.' % filename)
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000076 continue
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000077
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000078 # Frame numbers appear as number type in the data, but Chart API requires
79 # values of the X-axis to be of string type.
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000080 # Change the frame_number column data type:
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000081 table_description['frame_number'] = ('string', 'Frame number')
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000082 # Convert all the values to string types:
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000083 for row in table_data:
84 row['frame_number'] = str(row['frame_number'])
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000085
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000086 # Store the unique data from this file in the high level lists.
kjellander@webrtc.org418bce52011-12-05 16:29:21 +000087 test_configurations.append(test_configuration)
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000088 data_list.append(table_data)
kjellander@webrtc.org418bce52011-12-05 16:29:21 +000089 # Name of the test run must be present.
90 test_name = FindConfiguration(test_configuration, 'name')
91 if not test_name:
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000092 messages.append('Invalid input file: %s. Missing configuration key '
kjellander@webrtc.org418bce52011-12-05 16:29:21 +000093 '"name"', filename)
94 continue
95 names.append(test_name)
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000096
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000097 # Create data helper and build data tables for each graph.
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +000098 helper = webrtc.data_helper.DataHelper(data_list, table_description,
kjellander@webrtc.org689cb302011-11-07 15:25:47 +000099 names, messages)
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000100
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000101 # Loading it into gviz_api.DataTable objects and create JSON strings.
kjellander@webrtc.org418bce52011-12-05 16:29:21 +0000102 description, data = helper.CreateConfigurationTable(test_configurations)
103 configurations = gviz_api.DataTable(description, data)
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000104 json_configurations = configurations.ToJSon() # pylint: disable=W0612
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000105
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000106 description, data = helper.CreateData('ssim')
107 ssim = gviz_api.DataTable(description, data)
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000108 # pylint: disable=W0612
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000109 json_ssim_data = ssim.ToJSon(helper.GetOrdering(description))
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000110
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000111 description, data = helper.CreateData('psnr')
112 psnr = gviz_api.DataTable(description, data)
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000113 # pylint: disable=W0612
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000114 json_psnr_data = psnr.ToJSon(helper.GetOrdering(description))
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000115
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000116 description, data = helper.CreateData('packets_dropped')
117 packet_loss = gviz_api.DataTable(description, data)
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000118 # pylint: disable=W0612
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000119 json_packet_loss_data = packet_loss.ToJSon(helper.GetOrdering(description))
120
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000121 description, data = helper.CreateData('bit_rate')
122 # Add a column of data points for the desired bit rate to be plotted.
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000123 # (uses test configuration from the last data set, assuming it is the same
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000124 # for all of them)
kjellander@webrtc.org418bce52011-12-05 16:29:21 +0000125 desired_bit_rate = FindConfiguration(test_configuration, 'bit_rate_in_kbps')
126 if not desired_bit_rate:
127 ShowErrorPage('Cannot configuration field named "bit_rate_in_kbps"')
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000128 return
kjellander@webrtc.org418bce52011-12-05 16:29:21 +0000129 desired_bit_rate = int(desired_bit_rate)
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000130 # Add new column data type description.
131 description['desired_bit_rate'] = ('number', 'Desired bit rate (kbps)')
132 for row in data:
133 row['desired_bit_rate'] = desired_bit_rate
134 bit_rate = gviz_api.DataTable(description, data)
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000135 # pylint: disable=W0612
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000136 json_bit_rate_data = bit_rate.ToJSon(helper.GetOrdering(description))
137
138 # Format the messages list with newlines.
139 messages = '\n'.join(messages)
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000140
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000141 # Put the variables as JSon strings into the template.
142 print page_template % vars()
143
kjellander@webrtc.org418bce52011-12-05 16:29:21 +0000144def FindConfiguration(configuration, name):
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000145 """ Finds a configuration value using it's name.
kjellander@webrtc.org418bce52011-12-05 16:29:21 +0000146 Returns the first configuration with a matching name. Returns None if no
147 matching configuration is found. """
148 return_value = None
149 for row in configuration:
150 if row['name'] == name:
151 return_value = row['value']
152 break
153 return return_value
154
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000155def ShowErrorPage(error_message):
156 print '<html><body>%s</body></html>' % error_message
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000157
kjellander@webrtc.org689cb302011-11-07 15:25:47 +0000158if __name__ == '__main__':
159 main()