1 // Copyright (c) 2011 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 cr.define('media', function() { 6 'use strict'; 7 8 // A set of parameter names. An entry of 'abc' allows metrics to specify 9 // events with specific values of 'abc'. 10 var metricProperties = { 11 'pipeline_state': true, 12 }; 13 14 // A set of metrics to measure. The user will see the most recent and average 15 // measurement of the time between each metric's start and end events. 16 var metrics = { 17 'seek': { 18 'start': 'SEEK', 19 'end': 'pipeline_state=started' 20 }, 21 'first frame': { 22 'start': 'WEBMEDIAPLAYER_CREATED', 23 'end': 'pipeline_state=started' 24 }, 25 }; 26 27 /** 28 * This class measures times between the events specified above. It inherits 29 * <li> and contains a table that displays the measurements. 30 */ 31 var Metrics = cr.ui.define('li'); 32 33 Metrics.prototype = { 34 __proto__: HTMLLIElement.prototype, 35 36 /** 37 * Decorate this <li> as a Metrics. 38 */ 39 decorate: function() { 40 this.table_ = document.createElement('table'); 41 var details = document.createElement('details'); 42 var summary = media.makeElement('summary', 'Metrics:'); 43 details.appendChild(summary); 44 details.appendChild(this.table_); 45 this.appendChild(details); 46 47 var hRow = document.createElement('tr'); 48 hRow.appendChild(media.makeElement('th', 'Metric:')); 49 hRow.appendChild(media.makeElement('th', 'Last Measure:')); 50 hRow.appendChild(media.makeElement('th', 'Average:')); 51 var header = document.createElement('thead'); 52 header.appendChild(hRow); 53 this.table_.appendChild(header); 54 55 for (var metric in metrics) { 56 var last = document.createElement('td'); 57 var avg = document.createElement('td'); 58 this[metric] = { 59 count: 0, 60 total: 0, 61 start: null, 62 last: last, 63 avg: avg 64 }; 65 var row = document.createElement('tr'); 66 row.appendChild(media.makeElement('td', metric + ':')); 67 row.appendChild(last); 68 row.appendChild(avg); 69 this.table_.appendChild(row); 70 } 71 }, 72 73 /** 74 * An event has occurred. Update any metrics that refer to this type 75 * of event. Can be called multiple times by addEvent below if the metrics 76 * refer to specific parameters. 77 * @param {Object} event The MediaLogEvent that has occurred. 78 * @param {string} type The type of event. 79 */ 80 addEventInternal: function(event, type) { 81 for (var metric in metrics) { 82 var m = this[metric]; 83 if (type == metrics[metric].start && !m.start) { 84 m.start = event.ticksMillis; 85 } else if (type == metrics[metric].end && m.start != null) { 86 var last = event.ticksMillis - m.start; 87 m.last.textContent = last.toFixed(1); 88 m.total += last; 89 m.count++; 90 if (m.count > 1) 91 m.avg.textContent = (m.total / m.count).toFixed(1); 92 m.start = null; 93 } 94 } 95 }, 96 97 /** 98 * An event has occurred. Update any metrics that refer to events of this 99 * type or with this event's parameters. 100 * @param {Object} event The MediaLogEvent that has occurred. 101 */ 102 addEvent: function(event) { 103 this.addEventInternal(event, event.type); 104 for (var p in event.params) { 105 if (p in metricProperties) { 106 var type = p + '=' + event.params[p]; 107 this.addEventInternal(event, type); 108 } 109 } 110 }, 111 }; 112 113 return { 114 Metrics: Metrics, 115 }; 116 }); 117