Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: tracing/tracing/metrics/media_metric_test.html

Issue 3020433002: Finish migrating media metrics to TBMv2 (Closed)
Patch Set: Remove an unnecessary if Created 3 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tracing/tracing/metrics/media_metric.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <!-- 2 <!--
3 Copyright 2017 The Chromium Authors. All rights reserved. 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 4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file. 5 found in the LICENSE file.
6 --> 6 -->
7 7
8 <link rel="import" href="/tracing/core/test_utils.html"> 8 <link rel="import" href="/tracing/core/test_utils.html">
9 <link rel="import" href="/tracing/extras/importer/trace_event_importer.html"> 9 <link rel="import" href="/tracing/extras/importer/trace_event_importer.html">
10 <link rel="import" href="/tracing/metrics/media_metric.html"> 10 <link rel="import" href="/tracing/metrics/media_metric.html">
11 <link rel="import" href="/tracing/value/histogram_set.html"> 11 <link rel="import" href="/tracing/value/histogram_set.html">
12 12
13 <script> 13 <script>
14 'use strict'; 14 'use strict';
15 15
16 tr.b.unittest.testSuite(function() { 16 tr.b.unittest.testSuite(function() {
17 // Arbitrarily selected process ID and thread IDs we'll use in test data
18 const procId = 52;
19 const tidMain = 1;
20 const tidCompositor = 53;
21 const tidAudio = 55;
22
23 function doLoadEvent(timestamp) {
24 return {name: 'WebMediaPlayerImpl::DoLoad', args: {},
25 pid: procId, ts: timestamp, cat: 'media', tid: tidMain, ph: 'X'};
26 }
27
28 function videoRenderEvent(timestamp) {
29 return {name: 'VideoRendererImpl::Render', args: {},
30 pid: procId, ts: timestamp, cat: 'media', tid: tidCompositor, ph: 'X'};
31 }
32
33 function audioRenderEvent(timestamp) {
34 return {name: 'AudioRendererImpl::Render', args: {},
35 pid: procId, ts: timestamp, cat: 'media', tid: tidAudio, ph: 'X'};
36 }
37
38 function videoFramesDroppedEvent(timestamp, frameCount) {
39 return {name: 'VideoFramesDropped', args: {count: frameCount},
40 pid: procId, ts: timestamp, cat: 'media', tid: tidCompositor, ph: 'X'};
41 }
42
43 function onEndedEvent(timestamp, mediaDuration) {
44 return {name: 'WebMediaPlayerImpl::OnEnded',
45 args: {'duration': mediaDuration},
46 pid: procId, ts: timestamp, cat: 'media', tid: tidMain, ph: 'X'};
47 }
48
49 function doSeekEvent(timestamp, targetTime) {
50 return {name: 'WebMediaPlayerImpl::DoSeek', args: {target: targetTime},
51 pid: procId, ts: timestamp, cat: 'media', tid: tidMain, ph: 'X'};
52 }
53
54 function seekedEvent(timestamp, targetTime) {
55 return {name: 'WebMediaPlayerImpl::OnPipelineSeeked',
56 args: {target: targetTime},
57 pid: procId, ts: timestamp, cat: 'media', tid: tidMain, ph: 'X'};
58 }
59
60 function threadMarker(threadName, threadId) {
61 return {name: 'thread_name', args: {name: threadName},
62 pid: procId, ts: 0, cat: '__metadata', tid: threadId, ph: 'M'};
63 }
64
65 const mainThreadMarker = threadMarker('CrRendererMain', tidMain);
66 const compositorThreadMarker = threadMarker('Compositor', tidCompositor);
67 const audioThreadMarker = threadMarker('AudioOutputDevice', tidAudio);
68
17 function makeModel(events) { 69 function makeModel(events) {
18 return tr.c.TestUtils.newModelWithEvents([events]); 70 return tr.c.TestUtils.newModelWithEvents([events]);
19 } 71 }
20 72
73 function checkCloseTo(histograms, histogramName, expectedValue) {
74 assert.isDefined(histograms.getHistogramNamed(histogramName));
75 const value = histograms.getHistogramNamed(histogramName);
76 const statistics = value.running;
77 assert.strictEqual(statistics.count, 1);
78 assert.closeTo(statistics.mean, expectedValue, 1e-5);
79 }
80
81 function checkEqual(histograms, histogramName, expectedValue) {
82 assert.isDefined(histograms.getHistogramNamed(histogramName));
83 const value = histograms.getHistogramNamed(histogramName);
84 const statistics = value.running;
85 assert.strictEqual(statistics.count, 1);
86 assert.strictEqual(statistics.mean, expectedValue);
87 }
88
21 test('mediaMetric_noData', function() { 89 test('mediaMetric_noData', function() {
22 const histograms = new tr.v.HistogramSet(); 90 const histograms = new tr.v.HistogramSet();
23 const events = [ 91 const events = [];
24 {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'},
25 {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'}
26 ];
27 tr.metrics.mediaMetric(histograms, makeModel(events)); 92 tr.metrics.mediaMetric(histograms, makeModel(events));
28 assert.lengthOf(histograms, 0); 93 assert.lengthOf(histograms, 0);
29 }); 94 });
30 95
31 test('mediaMetric_videoTimeToPlay', function() { 96 test('mediaMetric_videoTimeToPlay', function() {
32 const histograms = new tr.v.HistogramSet(); 97 const histograms = new tr.v.HistogramSet();
33 const events = [ 98 const events = [
34 {name: 'WebMediaPlayerImpl::DoLoad', args: {}, 99 doLoadEvent(100),
35 pid: 52, ts: 524, cat: 'media', tid: 1, ph: 'X'}, 100 videoRenderEvent(300),
36 {name: 'VideoRendererImpl::Render', args: {}, 101 // Video renderer always generate multiple render events,
37 pid: 52, ts: 560, cat: 'media', tid: 53, ph: 'X'}, 102 // one for each frame. For calculation of time-to-play,
38 {name: 'VideoRendererImpl::Render', args: {}, 103 // only the first render event is relevant. Here we put in
39 pid: 52, ts: 580, cat: 'media', tid: 53, ph: 'X'}, 104 // a second render event to make sure it's ignored by the
40 {name: 'thread_name', args: {name: 'CrRendererMain'}, 105 // metric computation code.
41 pid: 52, ts: 0, cat: '__metadata', tid: 1, ph: 'M'}, 106 videoRenderEvent(400),
42 {name: 'thread_name', args: {name: 'Compositor'}, 107 mainThreadMarker,
43 pid: 52, ts: 0, cat: '__metadata', tid: 53, ph: 'M'}, 108 compositorThreadMarker,
44 ]; 109 ];
45 tr.metrics.mediaMetric(histograms, makeModel(events)); 110 tr.metrics.mediaMetric(histograms, makeModel(events));
46 111 checkCloseTo(histograms, 'time_to_video_play', 0.2);
47 assert.isDefined(histograms.getHistogramNamed('time_to_video_play'));
48 const ttpValue = histograms.getHistogramNamed('time_to_video_play');
49 const ttpStatistics = ttpValue.running;
50 assert.strictEqual(ttpStatistics.count, 1);
51 assert.closeTo(ttpStatistics.mean, 0.036, 1e-5);
52 assert.closeTo(ttpStatistics.max, 0.036, 1e-5);
53 }); 112 });
54 113
55 test('mediaMetric_audioTimeToPlay', function() { 114 test('mediaMetric_audioTimeToPlay', function() {
56 const histograms = new tr.v.HistogramSet(); 115 const histograms = new tr.v.HistogramSet();
57 const events = [ 116 const events = [
58 {name: 'thread_name', args: {name: 'CrRendererMain'}, 117 mainThreadMarker,
59 pid: 52, ts: 0, cat: '__metadata', tid: 1, ph: 'M'}, 118 audioThreadMarker,
60 {name: 'thread_name', args: {name: 'AudioOutputDevice'}, 119 doLoadEvent(1000),
61 pid: 52, ts: 0, cat: '__metadata', tid: 53, ph: 'M'}, 120 audioRenderEvent(1100),
62 {name: 'WebMediaPlayerImpl::DoLoad', args: {},
63 pid: 52, ts: 1234, cat: 'media', tid: 1, ph: 'X'},
64 {name: 'AudioRendererImpl::Render', args: {},
65 pid: 52, ts: 4321, cat: 'media', tid: 53, ph: 'X'},
66 ]; 121 ];
67 tr.metrics.mediaMetric(histograms, makeModel(events)); 122 tr.metrics.mediaMetric(histograms, makeModel(events));
123 checkCloseTo(histograms, 'time_to_audio_play', 0.1);
124 });
68 125
69 assert.isDefined(histograms.getHistogramNamed('time_to_audio_play')); 126 test('mediaMetric_bufferingTimeVideo', function() {
70 const ttpValue = histograms.getHistogramNamed('time_to_audio_play'); 127 const histograms = new tr.v.HistogramSet();
71 const ttpStatistics = ttpValue.running; 128 const events = [
72 assert.strictEqual(ttpStatistics.count, 1); 129 doLoadEvent(1000),
73 assert.closeTo(ttpStatistics.mean, 3.087, 1e-5); 130 videoRenderEvent(1500),
74 assert.closeTo(ttpStatistics.max, 3.087, 1e-5); 131 videoRenderEvent(1600),
132 onEndedEvent(10051500, 10),
133 mainThreadMarker,
134 compositorThreadMarker,
135 ];
136 tr.metrics.mediaMetric(histograms, makeModel(events));
137 checkCloseTo(histograms, 'buffering_time', 50);
138 });
139
140 test('mediaMetric_bufferingTimeAudio', function() {
141 const histograms = new tr.v.HistogramSet();
142 const events = [
143 mainThreadMarker,
144 audioThreadMarker,
145 doLoadEvent(1000),
146 audioRenderEvent(1500),
147 onEndedEvent(5002500, 5),
148 ];
149 tr.metrics.mediaMetric(histograms, makeModel(events));
150 checkCloseTo(histograms, 'buffering_time', 1);
151 });
152
153 // With seek, no buffering time should be reported
154 test('mediaMetric_noBufferingTime', function() {
155 const histograms = new tr.v.HistogramSet();
156 const events = [
157 doLoadEvent(1000),
158 videoRenderEvent(1500),
159 videoRenderEvent(1600),
160 onEndedEvent(10066666, 10),
161 doSeekEvent(525, 1.2),
162 seekedEvent(719, 1.2),
163 mainThreadMarker,
164 compositorThreadMarker,
165 ];
166 tr.metrics.mediaMetric(histograms, makeModel(events));
167 assert.isUndefined(histograms.getHistogramNamed('buffering_time'));
168 });
169
170 test('mediaMetric_droppedFrameCount', function() {
171 const histograms = new tr.v.HistogramSet();
172 const events = [
173 doLoadEvent(1000),
174 videoRenderEvent(1500),
175 videoFramesDroppedEvent(123456, 3),
176 videoFramesDroppedEvent(234567, 6),
177 videoFramesDroppedEvent(345678, 1),
178 mainThreadMarker,
179 compositorThreadMarker,
180 ];
181 tr.metrics.mediaMetric(histograms, makeModel(events));
182 checkEqual(histograms, 'dropped_frame_count', 10);
183 });
184
185 test('mediaMetric_seekTime', function() {
186 const histograms = new tr.v.HistogramSet();
187 const events = [
188 doLoadEvent(1000),
189 videoRenderEvent(1500),
190 doSeekEvent(2000, 1.2),
191 seekedEvent(2500, 1.2),
192 doSeekEvent(15000, 3.7),
193 seekedEvent(75000, 3.7),
194 mainThreadMarker,
195 compositorThreadMarker,
196 ];
197 tr.metrics.mediaMetric(histograms, makeModel(events));
198 checkCloseTo(histograms, 'seek_time_1.2', 0.5);
199 checkCloseTo(histograms, 'seek_time_3.7', 60);
200 });
201
202 // Scenario: Play mixed audio/video from start to finish
203 test('mediaMetric_playVideoScenario', function() {
204 const histograms = new tr.v.HistogramSet();
205 const events = [
206 doLoadEvent(2000),
207 videoRenderEvent(3000),
208 audioRenderEvent(3200),
209 videoRenderEvent(3300),
210 videoFramesDroppedEvent(123456, 4),
211 videoFramesDroppedEvent(234567, 2),
212 onEndedEvent(10013000, 10),
213 mainThreadMarker,
214 compositorThreadMarker,
215 audioThreadMarker,
216 ];
217 tr.metrics.mediaMetric(histograms, makeModel(events));
218 checkCloseTo(histograms, 'time_to_video_play', 1);
219 checkCloseTo(histograms, 'time_to_audio_play', 1.2);
220 checkCloseTo(histograms, 'buffering_time', 10);
221 checkEqual(histograms, 'dropped_frame_count', 6);
222 });
223
224 // Scenario: Play audio from start to finish
225 test('mediaMetric_playAudioScenario', function() {
226 const histograms = new tr.v.HistogramSet();
227 const events = [
228 doLoadEvent(1000),
229 audioRenderEvent(1500),
230 onEndedEvent(10002500, 10),
231 mainThreadMarker,
232 audioThreadMarker,
233 ];
234 tr.metrics.mediaMetric(histograms, makeModel(events));
235 assert.isUndefined(histograms.getHistogramNamed('time_to_video_play'));
236 checkCloseTo(histograms, 'time_to_audio_play', 0.5);
237 checkCloseTo(histograms, 'buffering_time', 1);
238 assert.isUndefined(histograms.getHistogramNamed('dropped_frame_count'));
239 });
240
241 // Scenario: Play audio/video with two seeks
242 test('mediaMetric_seekScenario', function() {
243 const histograms = new tr.v.HistogramSet();
244 const events = [
245 doLoadEvent(1000),
246 videoRenderEvent(2000),
247 audioRenderEvent(2020),
248 videoRenderEvent(2040),
249 doSeekEvent(5000, 0.5),
250 seekedEvent(5200, 0.5),
251 videoFramesDroppedEvent(123456, 4),
252 doSeekEvent(200000, 9),
253 seekedEvent(210000, 9),
254 videoFramesDroppedEvent(234567, 2),
255 onEndedEvent(300000, 10),
256 mainThreadMarker,
257 compositorThreadMarker,
258 audioThreadMarker,
259 ];
260 tr.metrics.mediaMetric(histograms, makeModel(events));
261 checkCloseTo(histograms, 'time_to_video_play', 1);
262 checkCloseTo(histograms, 'time_to_audio_play', 1.02);
263 assert.isUndefined(histograms.getHistogramNamed('buffering_time'));
264 checkEqual(histograms, 'dropped_frame_count', 6);
265 checkCloseTo(histograms, 'seek_time_0.5', 0.2);
266 checkCloseTo(histograms, 'seek_time_9', 10);
75 }); 267 });
76 }); 268 });
77 </script> 269 </script>
OLDNEW
« no previous file with comments | « tracing/tracing/metrics/media_metric.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698