Index: tracing/tracing/metrics/media_metric.html |
diff --git a/tracing/tracing/metrics/media_metric.html b/tracing/tracing/metrics/media_metric.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3e86e7d26a9025fd0ad49bd7c485c5bdc9a1e564 |
--- /dev/null |
+++ b/tracing/tracing/metrics/media_metric.html |
@@ -0,0 +1,115 @@ |
+<!DOCTYPE html> |
+<!-- |
+Copyright 2017 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_metrics uses Chrome trace events to calculate metrics about video |
+and audio playback. It is meant to be used for pages with a <video> or |
+<audio> element. It is used by videostack-eng@google.com team for |
+regression testing. |
+ |
+This metric currently supports the following measurement: |
+* time_to_video_play calculates how long after a video is requested to |
+ start playing before the video actually starts. If time_to_video_play |
+ regresses, then users will click to play videos and then have |
+ to wait longer before the videos start actually playing. |
+* time_to_audio_play is similar to time_to_video_play, but measures the |
+ time delay before audio starts playing. |
+ |
+More measurements are expected to be added in the near future, such as: |
+* buffering_time |
+* seek_time |
+* dropped_frame_count |
+ |
+Please inform crouleau@chromium.org and johnchen@chromium.org about |
+changes to this file. |
+--> |
+ |
+<link rel="import" href="/tracing/metrics/metric_registry.html"> |
+<link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
+<link rel="import" href="/tracing/value/histogram.html"> |
+ |
+<script> |
+'use strict'; |
+ |
+tr.exportTo('tr.metrics', function() { |
+ function mediaMetric(histograms, model) { |
+ let playStart; |
+ let timeToAudioPlay; |
+ let timeToVideoPlay; |
+ |
+ const chromeHelper = model.getOrCreateHelper( |
+ tr.model.helpers.ChromeModelHelper); |
+ if (chromeHelper === undefined) return; |
+ |
+ for (const rendererHelper of Object.values(chromeHelper.rendererHelpers)) { |
+ // Find the threads we're interested in, and if a needed thread |
+ // is missing, no need to look further in this process. |
+ const mainThread = rendererHelper.mainThread; |
+ if (mainThread === undefined) continue; |
+ |
+ const compositorThread = rendererHelper.compositorThread; |
+ const audioThread = |
+ rendererHelper.process.findAtMostOneThreadNamed('AudioOutputDevice'); |
+ if (compositorThread === undefined && audioThread === undefined) continue; |
+ |
+ // Look for the media player DoLoad event on main thread. |
+ for (const event of mainThread.getDescendantEvents()) { |
+ if (event.title === 'WebMediaPlayerImpl::DoLoad') { |
+ // TODO(johnchen@chromium.org): Support multiple audio/video |
+ // elements per page. Currently, we only support a single |
+ // audio or video element, so we can store the start time in |
+ // a simple variable, and exit the loop. |
+ if (playStart !== undefined) { |
+ throw new Error( |
+ 'Loading multiple audio/video elements not yet supported'); |
+ } |
+ playStart = event.start; |
+ break; |
+ } |
+ } |
+ if (playStart === undefined) continue; |
+ |
+ // Look for video render event. |
+ if (compositorThread !== undefined) { |
+ for (const event of compositorThread.getDescendantEvents()) { |
+ if (event.title === 'VideoRendererImpl::Render') { |
+ timeToVideoPlay = event.start - playStart; |
+ break; |
+ } |
+ } |
+ } |
+ |
+ // Look for audio render event. |
+ if (audioThread !== undefined) { |
+ for (const event of audioThread.getDescendantEvents()) { |
+ if (event.title === 'AudioRendererImpl::Render') { |
+ timeToAudioPlay = event.start - playStart; |
+ break; |
+ } |
+ } |
+ } |
+ if (timeToVideoPlay !== undefined) break; |
+ if (timeToAudioPlay !== undefined) break; |
+ } |
+ |
+ if (timeToVideoPlay !== undefined) { |
+ histograms.createHistogram('time_to_video_play', |
+ tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, timeToVideoPlay); |
+ } |
+ if (timeToAudioPlay !== undefined) { |
+ histograms.createHistogram('time_to_audio_play', |
+ tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, timeToAudioPlay); |
+ } |
+ } |
+ |
+ tr.metrics.MetricRegistry.register(mediaMetric); |
+ |
+ return { |
+ mediaMetric, |
+ }; |
+}); |
+</script> |