
A table on the top of the page displays the test configurations of the input files present. The displayed string in the legend of each graph is now fetched from test configuration name instead of using the filename. Review URL: http://webrtc-codereview.appspot.com/279006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1104 4adac7df-926f-26a2-2b94-8c16560cd09d
158 lines
6.1 KiB
Python
158 lines
6.1 KiB
Python
#!/usr/bin/env python
|
|
# Copyright (c) 2011 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.
|
|
|
|
__author__ = 'kjellander@webrtc.org (Henrik Kjellander)'
|
|
|
|
import os
|
|
import gviz_api
|
|
import webrtc.data_helper
|
|
|
|
def main():
|
|
"""
|
|
This Python script displays a web page with test created with the
|
|
video_quality_measurement program, which is a tool in WebRTC.
|
|
|
|
The script requires on two external files and one Python library:
|
|
- A HTML template file with layout and references to the json variables
|
|
defined in this script
|
|
- A data file in Python format, containing the following:
|
|
- test_configuration - a dictionary of test configuration names and values.
|
|
- frame_data_types - a dictionary that maps the different metrics to their
|
|
data types.
|
|
- frame_data - a list of dictionaries where each dictionary maps a metric to
|
|
it's value.
|
|
- The gviz_api.py of the Google Visualization Python API, available at
|
|
http://code.google.com/p/google-visualization-python/
|
|
|
|
The HTML file is shipped with the script, while the data file must be
|
|
generated by running video_quality_measurement with the --python flag
|
|
specified.
|
|
"""
|
|
print 'Content-type: text/html\n' # the newline is required!
|
|
|
|
page_template_filename = '../templates/chart_page_template.html'
|
|
# The data files must be located in the project tree for app engine being
|
|
# able to access them.
|
|
data_filenames = [ '../data/vp8_sw.py', '../data/vp8_hw.py' ]
|
|
# Will contain info/error messages to be displayed on the resulting page.
|
|
messages = []
|
|
# Load the page HTML template.
|
|
try:
|
|
f = open(page_template_filename)
|
|
page_template = f.read()
|
|
f.close()
|
|
except IOError as e:
|
|
ShowErrorPage('Cannot open page template file: %s<br>Details: %s' %
|
|
(page_template_filename, e))
|
|
return
|
|
|
|
# Read data from external Python script files. First check that they exist.
|
|
for filename in data_filenames:
|
|
if not os.path.exists(filename):
|
|
messages.append('Cannot open data file: %s' % filename)
|
|
data_filenames.remove(filename)
|
|
|
|
# Read data from all existing input files.
|
|
data_list = []
|
|
test_configurations = []
|
|
names = []
|
|
|
|
for filename in data_filenames:
|
|
read_vars = {} # empty dictionary to load the data into.
|
|
execfile(filename, read_vars, read_vars)
|
|
|
|
test_configuration = read_vars['test_configuration']
|
|
table_description = read_vars['frame_data_types']
|
|
table_data = read_vars['frame_data']
|
|
|
|
# Verify the data in the file loaded properly.
|
|
if not table_description or not table_data:
|
|
messages.append('Invalid input file: %s. Missing description list or '
|
|
'data dictionary variables.' % filename)
|
|
continue
|
|
|
|
# Frame numbers appear as number type in the data, but Chart API requires
|
|
# values of the X-axis to be of string type.
|
|
# Change the frame_number column data type:
|
|
table_description['frame_number'] = ('string', 'Frame number')
|
|
# Convert all the values to string types:
|
|
for row in table_data:
|
|
row['frame_number'] = str(row['frame_number'])
|
|
|
|
# Store the unique data from this file in the high level lists.
|
|
test_configurations.append(test_configuration)
|
|
data_list.append(table_data)
|
|
# Name of the test run must be present.
|
|
test_name = FindConfiguration(test_configuration, 'name')
|
|
if not test_name:
|
|
messages.append('Invalid input file: %s. Missing configuration key '
|
|
'"name"', filename)
|
|
continue
|
|
names.append(test_name)
|
|
|
|
# Create data helper and build data tables for each graph.
|
|
helper = webrtc.data_helper.DataHelper(data_list, table_description,
|
|
names, messages)
|
|
|
|
# Loading it into gviz_api.DataTable objects and create JSON strings.
|
|
description, data = helper.CreateConfigurationTable(test_configurations)
|
|
configurations = gviz_api.DataTable(description, data)
|
|
json_configurations = configurations.ToJSon()
|
|
|
|
description, data = helper.CreateData('ssim')
|
|
ssim = gviz_api.DataTable(description, data)
|
|
json_ssim_data = ssim.ToJSon(helper.GetOrdering(description))
|
|
|
|
description, data = helper.CreateData('psnr')
|
|
psnr = gviz_api.DataTable(description, data)
|
|
json_psnr_data = psnr.ToJSon(helper.GetOrdering(description))
|
|
|
|
description, data = helper.CreateData('packets_dropped')
|
|
packet_loss = gviz_api.DataTable(description, data)
|
|
json_packet_loss_data = packet_loss.ToJSon(helper.GetOrdering(description))
|
|
|
|
description, data = helper.CreateData('bit_rate')
|
|
# Add a column of data points for the desired bit rate to be plotted.
|
|
# (uses test configuration from the last data set, assuming it is the same
|
|
# for all of them)
|
|
desired_bit_rate = FindConfiguration(test_configuration, 'bit_rate_in_kbps')
|
|
if not desired_bit_rate:
|
|
ShowErrorPage('Cannot configuration field named "bit_rate_in_kbps"')
|
|
return
|
|
desired_bit_rate = int(desired_bit_rate)
|
|
# Add new column data type description.
|
|
description['desired_bit_rate'] = ('number', 'Desired bit rate (kbps)')
|
|
for row in data:
|
|
row['desired_bit_rate'] = desired_bit_rate
|
|
bit_rate = gviz_api.DataTable(description, data)
|
|
json_bit_rate_data = bit_rate.ToJSon(helper.GetOrdering(description))
|
|
|
|
# Format the messages list with newlines.
|
|
messages = '\n'.join(messages)
|
|
|
|
# Put the variables as JSon strings into the template.
|
|
print page_template % vars()
|
|
|
|
def FindConfiguration(configuration, name):
|
|
""" Finds a configuration value using it's name.
|
|
Returns the first configuration with a matching name. Returns None if no
|
|
matching configuration is found. """
|
|
return_value = None
|
|
for row in configuration:
|
|
if row['name'] == name:
|
|
return_value = row['value']
|
|
break
|
|
return return_value
|
|
|
|
def ShowErrorPage(error_message):
|
|
print '<html><body>%s</body></html>' % error_message
|
|
|
|
if __name__ == '__main__':
|
|
main()
|