OLD | NEW |
---|---|
(Empty) | |
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 """Media measurement class gathers media related metrics on a page set. | |
6 | |
7 Default media metrics are collected for every media element in the page, such as | |
8 decoded_frame_count, dropped_frame_count, decoded_video_bytes, and | |
9 decoded_audio_bytes. | |
10 """ | |
11 | |
12 import os | |
13 | |
14 from telemetry.page import page_measurement | |
15 | |
16 | |
17 class MediaMeasurement(page_measurement.PageMeasurement): | |
18 """Provide general video and audio metrics.""" | |
19 | |
20 def __init__(self): | |
21 super(MediaMeasurement, self).__init__('media_metrics') | |
22 | |
23 def results_are_the_same_on_every_page(self): | |
24 """Results can vary from page to page based on media events taking place.""" | |
25 return False | |
26 | |
27 def ReportCollectedMetrics(self, tab, results): | |
28 """Reports all recorded metrics as Telemetry perf results. | |
29 | |
30 Metrics are recorded for each media element in the page. Each metric result | |
31 has media info + metric values as a map, for example: | |
32 Media metric = { | |
33 'info': { | |
34 'src': 'file.webm', | |
35 'id': 'video1', | |
36 ... | |
37 }, | |
38 'metrics': { | |
39 'ttp': [120, 'ms'], | |
40 'decoded_bytes': [13233, 'bytes'], | |
41 ... | |
42 } | |
43 } | |
44 """ | |
45 media_metrics = tab.EvaluateJavaScript('window.__getAllMetrics()') | |
46 for media_metric in media_metrics: | |
47 self.AddResult(media_metric, results) | |
48 | |
49 def AddResult(self, media_metric, results): | |
50 """Adds the media metric result to global results, needed for graphing.""" | |
51 info = media_metric['info'] | |
52 metrics = media_metric['metrics'] | |
53 for metric in metrics: | |
54 value, units = GetValueUnit(metrics[metric]) | |
55 trace = GetTraceName(info) | |
56 results.Add(trace, units, value, chart_name=metric, | |
57 data_type='default') | |
58 | |
59 def LoadDepsJS(self, tab): | |
60 """Loads the JS files needed for media metrics, if not already loaded.""" | |
61 # 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
| |
62 deps_found = tab.EvaluateJavaScript('window.__mediaRecorders != undefined') | |
63 if not deps_found: | |
64 with open( | |
65 os.path.join(os.path.dirname(__file__), 'media_metrics.js')) as f: | |
66 js = f.read() | |
67 tab.ExecuteJavaScript(js) | |
68 | |
69 def MeasurePage(self, page, tab, results): | |
70 """Measure the page's performance.""" | |
71 self.LoadDepsJS(tab) | |
72 self.ReportCollectedMetrics(tab, results) | |
73 | |
74 | |
75 def GetValueUnit(metric): | |
76 """Returns a (value, units) pair stored in a metric if available.""" | |
77 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
| |
78 if len(metric) > 1: | |
79 return (metric[0], metric[1]) | |
80 else: | |
81 return (metric[0], 'no_unit') | |
82 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.
| |
83 | |
84 | |
85 def GetTraceName(info): | |
86 """Returns a media trace name based on the metric info map. | |
87 | |
88 In order, returns the first available: | |
89 - 'id' key value. | |
90 - file name based on 'src' key value. | |
91 - the first key value available. | |
92 - 'no_trace'. | |
93 """ | |
94 if 'id' in info: | |
95 return info['id'] | |
96 elif 'src' in info: | |
97 # Return only file name in src. | |
98 src = info['src'] | |
99 return src[src.rfind('/') + 1:] | |
100 else: | |
101 for key in info: | |
102 return info[key] | |
103 return 'no_trace' | |
OLD | NEW |