blob: a06e9600c30da42ed834e1d25aedade5680fd63c [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
10__author__ = 'kjellander@webrtc.org (Henrik Kjellander)'
11
12import os
13import gviz_api
14import webrtc.data_helper
15
16def main():
17 """
18 This Python script displays a web page with test created with the
19 video_quality_measurement program, which is a tool in WebRTC.
20
21 The script requires on two external files and one Python library:
22 - A HTML template file with layout and references to the json variables
23 defined in this script
24 - A data file in Python format, containing the following:
25 - test_configuration - a dictionary of test configuration names and values.
26 - frame_data_types - a dictionary that maps the different metrics to their
27 data types
28 - frame_data - a list of dictionaries where each dictionary maps a metric to
29 it's value.
30 - The gviz_api.py of the Google Visualization Python API, available at
31 http://code.google.com/p/google-visualization-python/
32
33 The HTML file is shipped with the script, while the data file must be
34 generated by running video_quality_measurement with the --python flag
35 specified.
36 """
37 print 'Content-type: text/html\n' # the newline is required!
38
39 page_template_filename = '../templates/chart_page_template.html'
40 # The data files must be located in the project tree for app engine being
41 # able to access them.
42 data_filenames = [ '../data/vp8_sw.py', '../data/vp8_hw.py' ]
43 # Will contain info/error messages to be displayed on the resulting page.
44 messages = []
45 # Load the page HTML template.
46 try:
47 f = open(page_template_filename)
48 page_template = f.read()
49 f.close()
50 except IOError as e:
51 ShowErrorPage('Cannot open page template file: %s<br>Details: %s' %
52 (page_template_filename, e))
53 return
54
55 # Read data from external Python script files. First check that they exist.
56 for filename in data_filenames:
57 if not os.path.exists(filename):
58 messages.append('Cannot open data file: %s' % filename)
59 data_filenames.remove(filename)
60
61 # Read data from all existing input files.
62 data_list = []
63 test_configurations_list = []
64 names = []
65
66 for filename in data_filenames:
67 read_vars = {} # empty dictionary to load the data into.
68 execfile(filename, read_vars, read_vars)
69
70 test_configuration = read_vars['test_configuration']
71 table_description = read_vars['frame_data_types']
72 table_data = read_vars['frame_data']
73
74 # Verify the data in the file loaded properly.
75 if not table_description or not table_data:
76 messages.append('Invalid input file: %s. Missing description list or '
77 'data dictionary variables.', filename)
78 continue
79
80 # Frame numbers appear as number type in the data, but Chart API requires
81 # values of the X-axis to be of string type.
82 # Change the frame_number column data type:
83 table_description['frame_number'] = ('string', 'Frame number')
84 # Convert all the values to string types:
85 for row in table_data:
86 row['frame_number'] = str(row['frame_number'])
87
88 # Store the unique data from this file in the high level lists.
89 test_configurations_list.append(test_configuration)
90 data_list.append(table_data)
91 # Use the filenames for name; strip away directory path and extension.
92 names.append(filename[filename.rfind('/')+1:filename.rfind('.')])
93
94 # Create data helper and build data tables for each graph.
95 helper = webrtc.data_helper.DataHelper(data_list, table_description,
96 names, messages)
97
98 # Loading it into gviz_api.DataTable objects and create JSON strings.
99 description, data = helper.CreateData('ssim')
100 ssim = gviz_api.DataTable(description, data)
101 json_ssim_data = ssim.ToJSon(helper.GetOrdering(description))
102
103 description, data = helper.CreateData('psnr')
104 psnr = gviz_api.DataTable(description, data)
105 json_psnr_data = psnr.ToJSon(helper.GetOrdering(description))
106
107 description, data = helper.CreateData('packets_dropped')
108 packet_loss = gviz_api.DataTable(description, data)
109 json_packet_loss_data = packet_loss.ToJSon(helper.GetOrdering(description))
110
111 description, data = helper.CreateData('bit_rate')
112 # Add a column of data points for the desired bit rate to be plotted.
113 # (uses test configuration from the last data set, assuming it is the same
114 # for all of them)
115 desired_bit_rate = -1
116 for row in test_configuration:
117 if row['name'] == 'bit_rate_in_kbps':
118 desired_bit_rate = int(row['value'])
119 if desired_bit_rate == -1:
120 ShowErrorPage('Cannot find bit rate in the test configuration.')
121 return
122 # Add new column data type description.
123 description['desired_bit_rate'] = ('number', 'Desired bit rate (kbps)')
124 for row in data:
125 row['desired_bit_rate'] = desired_bit_rate
126 bit_rate = gviz_api.DataTable(description, data)
127 json_bit_rate_data = bit_rate.ToJSon(helper.GetOrdering(description))
128
129 # Format the messages list with newlines.
130 messages = '\n'.join(messages)
131
132 # Put the variables as JSon strings into the template.
133 print page_template % vars()
134
135def ShowErrorPage(error_message):
136 print '<html><body>%s</body></html>' % error_message
137
138if __name__ == '__main__':
139 main()