Chromium Code Reviews| Index: tools/perf/perf_tools/media_measurement.py |
| diff --git a/tools/perf/perf_tools/media_measurement.py b/tools/perf/perf_tools/media_measurement.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..29e4a0598eb5bf91192c0a9fb62358543f264f6b |
| --- /dev/null |
| +++ b/tools/perf/perf_tools/media_measurement.py |
| @@ -0,0 +1,103 @@ |
| +# Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +"""Media measurement class gathers media related metrics on a page set. |
| + |
| +Default media metrics are collected for every media element in the page, such as |
| +decoded_frame_count, dropped_frame_count, decoded_video_bytes, and |
| +decoded_audio_bytes. |
| +""" |
| + |
| +import os |
| + |
| +from telemetry.page import page_measurement |
| + |
| + |
| +class MediaMeasurement(page_measurement.PageMeasurement): |
| + """Provide general video and audio metrics.""" |
| + |
| + def __init__(self): |
| + super(MediaMeasurement, self).__init__('media_metrics') |
| + |
| + def results_are_the_same_on_every_page(self): |
| + """Results can vary from page to page based on media events taking place.""" |
| + return False |
| + |
| + def ReportCollectedMetrics(self, tab, results): |
| + """Reports all recorded metrics as Telemetry perf results. |
| + |
| + Metrics are recorded for each media element in the page. Each metric result |
| + has media info + metric values as a map, for example: |
| + Media metric = { |
| + 'info': { |
| + 'src': 'file.webm', |
| + 'id': 'video1', |
| + ... |
| + }, |
| + 'metrics': { |
| + 'ttp': [120, 'ms'], |
| + 'decoded_bytes': [13233, 'bytes'], |
| + ... |
| + } |
| + } |
| + """ |
| + media_metrics = tab.EvaluateJavaScript('window.__getAllMetrics()') |
| + for media_metric in media_metrics: |
| + self.AddResult(media_metric, results) |
| + |
| + def AddResult(self, media_metric, results): |
| + """Adds the media metric result to global results, needed for graphing.""" |
| + info = media_metric['info'] |
| + metrics = media_metric['metrics'] |
| + for metric in metrics: |
| + value, units = GetValueUnit(metrics[metric]) |
| + trace = GetTraceName(info) |
| + results.Add(trace, units, value, chart_name=metric, |
| + data_type='default') |
| + |
| + def LoadDepsJS(self, tab): |
| + """Loads the JS files needed for media metrics, if not already loaded.""" |
| + # Media actions could have already loaded the JS file. |
|
scherkus (not reviewing)
2013/06/14 20:50:45
is it possible to always have actions load the JS?
shadi
2013/06/17 19:13:59
The problem is that we might run a media measureme
|
| + deps_found = tab.EvaluateJavaScript('window.__mediaRecorders != undefined') |
| + if not deps_found: |
| + with open( |
| + os.path.join(os.path.dirname(__file__), 'media_metrics.js')) as f: |
| + js = f.read() |
| + tab.ExecuteJavaScript(js) |
| + |
| + def MeasurePage(self, page, tab, results): |
| + """Measure the page's performance.""" |
| + self.LoadDepsJS(tab) |
| + self.ReportCollectedMetrics(tab, results) |
| + |
| + |
| +def GetValueUnit(metric): |
| + """Returns a (value, units) pair stored in a metric if available.""" |
| + if isinstance(metric, (list, tuple)): |
|
scherkus (not reviewing)
2013/06/14 20:50:45
what's an example of a metric that has no units? d
shadi
2013/06/17 19:13:59
We don't generate unitless metrics. We can enforce
|
| + if len(metric) > 1: |
| + return (metric[0], metric[1]) |
| + else: |
| + return (metric[0], 'no_unit') |
| + return (metric, 'no_unit') |
|
scherkus (not reviewing)
2013/06/14 20:50:45
is no_unit a special unit from telemetry's perspec
shadi
2013/06/17 19:13:59
No it is not.
|
| + |
| + |
| +def GetTraceName(info): |
| + """Returns a media trace name based on the metric info map. |
| + |
| + In order, returns the first available: |
| + - 'id' key value. |
| + - file name based on 'src' key value. |
| + - the first key value available. |
| + - 'no_trace'. |
| + """ |
| + if 'id' in info: |
| + return info['id'] |
| + elif 'src' in info: |
| + # Return only file name in src. |
| + src = info['src'] |
| + return src[src.rfind('/') + 1:] |
| + else: |
| + for key in info: |
| + return info[key] |
| + return 'no_trace' |