OLD | NEW |
(Empty) | |
| 1 <!DOCTYPE html> |
| 2 <!-- |
| 3 Copyright 2017 The Chromium Authors. All rights reserved. |
| 4 Use of this source code is governed by a BSD-style license that can be |
| 5 found in the LICENSE file. |
| 6 --> |
| 7 |
| 8 <!-- |
| 9 media_metrics uses Chrome trace events to calculate metrics about video |
| 10 and audio playback. It is meant to be used for pages with a <video> or |
| 11 <audio> element. It is used by videostack-eng@google.com team for |
| 12 regression testing. |
| 13 |
| 14 This metric currently supports the following measurement: |
| 15 * time_to_video_play calculates how long after a video is requested to |
| 16 start playing before the video actually starts. If time_to_video_play |
| 17 regresses, then users will click to play videos and then have |
| 18 to wait longer before the videos start actually playing. |
| 19 * time_to_audio_play is similar to time_to_video_play, but measures the |
| 20 time delay before audio starts playing. |
| 21 |
| 22 More measurements are expected to be added in the near future, such as: |
| 23 * buffering_time |
| 24 * seek_time |
| 25 * dropped_frame_count |
| 26 |
| 27 Please inform crouleau@chromium.org and johnchen@chromium.org about |
| 28 changes to this file. |
| 29 --> |
| 30 |
| 31 <link rel="import" href="/tracing/metrics/metric_registry.html"> |
| 32 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
| 33 <link rel="import" href="/tracing/value/histogram.html"> |
| 34 |
| 35 <script> |
| 36 'use strict'; |
| 37 |
| 38 tr.exportTo('tr.metrics', function() { |
| 39 function mediaMetric(histograms, model) { |
| 40 let playStart; |
| 41 let timeToAudioPlay; |
| 42 let timeToVideoPlay; |
| 43 |
| 44 const chromeHelper = model.getOrCreateHelper( |
| 45 tr.model.helpers.ChromeModelHelper); |
| 46 if (chromeHelper === undefined) return; |
| 47 |
| 48 for (const rendererHelper of Object.values(chromeHelper.rendererHelpers)) { |
| 49 // Find the threads we're interested in, and if a needed thread |
| 50 // is missing, no need to look further in this process. |
| 51 const mainThread = rendererHelper.mainThread; |
| 52 if (mainThread === undefined) continue; |
| 53 |
| 54 const compositorThread = rendererHelper.compositorThread; |
| 55 const audioThread = |
| 56 rendererHelper.process.findAtMostOneThreadNamed('AudioOutputDevice'); |
| 57 if (compositorThread === undefined && audioThread === undefined) continue; |
| 58 |
| 59 // Look for the media player DoLoad event on main thread. |
| 60 for (const event of mainThread.getDescendantEvents()) { |
| 61 if (event.title === 'WebMediaPlayerImpl::DoLoad') { |
| 62 // TODO(johnchen@chromium.org): Support multiple audio/video |
| 63 // elements per page. Currently, we only support a single |
| 64 // audio or video element, so we can store the start time in |
| 65 // a simple variable, and exit the loop. |
| 66 if (playStart !== undefined) { |
| 67 throw new Error( |
| 68 'Loading multiple audio/video elements not yet supported'); |
| 69 } |
| 70 playStart = event.start; |
| 71 break; |
| 72 } |
| 73 } |
| 74 if (playStart === undefined) continue; |
| 75 |
| 76 // Look for video render event. |
| 77 if (compositorThread !== undefined) { |
| 78 for (const event of compositorThread.getDescendantEvents()) { |
| 79 if (event.title === 'VideoRendererImpl::Render') { |
| 80 timeToVideoPlay = event.start - playStart; |
| 81 break; |
| 82 } |
| 83 } |
| 84 } |
| 85 |
| 86 // Look for audio render event. |
| 87 if (audioThread !== undefined) { |
| 88 for (const event of audioThread.getDescendantEvents()) { |
| 89 if (event.title === 'AudioRendererImpl::Render') { |
| 90 timeToAudioPlay = event.start - playStart; |
| 91 break; |
| 92 } |
| 93 } |
| 94 } |
| 95 if (timeToVideoPlay !== undefined) break; |
| 96 if (timeToAudioPlay !== undefined) break; |
| 97 } |
| 98 |
| 99 if (timeToVideoPlay !== undefined) { |
| 100 histograms.createHistogram('time_to_video_play', |
| 101 tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, timeToVideoPlay); |
| 102 } |
| 103 if (timeToAudioPlay !== undefined) { |
| 104 histograms.createHistogram('time_to_audio_play', |
| 105 tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, timeToAudioPlay); |
| 106 } |
| 107 } |
| 108 |
| 109 tr.metrics.MetricRegistry.register(mediaMetric); |
| 110 |
| 111 return { |
| 112 mediaMetric, |
| 113 }; |
| 114 }); |
| 115 </script> |
OLD | NEW |