Home | History | Annotate | Download | only in metrics
      1 # Copyright 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 import logging
      5 import os
      6 
      7 from metrics import Metric
      8 from telemetry.value import list_of_scalar_values
      9 from telemetry.value import scalar
     10 
     11 
     12 class MediaMetric(Metric):
     13   """MediaMetric class injects and calls JS responsible for recording metrics.
     14 
     15   Default media metrics are collected for every media element in the page,
     16   such as decoded_frame_count, dropped_frame_count, decoded_video_bytes, and
     17   decoded_audio_bytes.
     18   """
     19 
     20   def __init__(self, tab):
     21     super(MediaMetric, self).__init__()
     22     with open(os.path.join(os.path.dirname(__file__), 'media.js')) as f:
     23       js = f.read()
     24       tab.ExecuteJavaScript(js)
     25     self._results = None
     26     self._skip_basic_metrics = False
     27 
     28   def Start(self, page, tab):
     29     """Create the media metrics for all media elements in the document."""
     30     if hasattr(page, 'skip_basic_metrics'):
     31       self._skip_basic_metrics = page.skip_basic_metrics
     32     tab.ExecuteJavaScript('window.__createMediaMetricsForDocument()')
     33 
     34   def Stop(self, page, tab):
     35     self._results = tab.EvaluateJavaScript('window.__getAllMetrics()')
     36 
     37   def AddResults(self, tab, results):
     38     """Reports all recorded metrics as Telemetry perf results."""
     39     trace_names = []
     40     for media_metric in self._results:
     41       trace_names.append(self._AddResultsForMediaElement(media_metric, results))
     42 
     43     return '_'.join(trace_names) or tab.url
     44 
     45   def _AddResultsForMediaElement(self, media_metric, results):
     46     """Reports metrics for one media element.
     47 
     48     Media metrics contain an ID identifying the media element and values:
     49     media_metric = {
     50       'id': 'video_1',
     51       'metrics': {
     52           'time_to_play': 120,
     53           'decoded_bytes': 13233,
     54           ...
     55       }
     56     }
     57     """
     58     def AddOneResult(metric, unit):
     59       metrics = media_metric['metrics']
     60       for m in metrics:
     61         if m.startswith(metric):
     62           special_label = m[len(metric):]
     63           trace_name = '%s.%s%s' % (metric, trace, special_label)
     64           if isinstance(metrics[m], list):
     65             results.AddValue(list_of_scalar_values.ListOfScalarValues(
     66                 results.current_page, trace_name, unit,
     67                 values=[float(v) for v in metrics[m]],
     68                 important=True))
     69           else:
     70             results.AddValue(scalar.ScalarValue(
     71                 results.current_page, trace_name, unit, value=float(metrics[m]),
     72                 important=True))
     73 
     74     trace = media_metric['id']
     75     if not trace:
     76       logging.error('Metrics ID is missing in results.')
     77       return
     78 
     79     if not self._skip_basic_metrics:
     80       AddOneResult('buffering_time', 'ms')
     81       AddOneResult('decoded_audio_bytes', 'bytes')
     82       AddOneResult('decoded_video_bytes', 'bytes')
     83       AddOneResult('decoded_frame_count', 'frames')
     84       AddOneResult('dropped_frame_count', 'frames')
     85       AddOneResult('time_to_play', 'ms')
     86 
     87     AddOneResult('avg_loop_time', 'ms')
     88     AddOneResult('seek', 'ms')
     89     return trace
     90