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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tracing/tracing/metrics/media_metric.html ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tracing/tracing/metrics/media_metric_test.html
diff --git a/tracing/tracing/metrics/media_metric_test.html b/tracing/tracing/metrics/media_metric_test.html
index 64ea02b4b2ea74c171096660d8a55d7b914f8704..dd65671ceddf52a33fd1069713e67816b10791a3 100644
--- a/tracing/tracing/metrics/media_metric_test.html
+++ b/tracing/tracing/metrics/media_metric_test.html
@@ -14,16 +14,81 @@ found in the LICENSE file.
'use strict';
tr.b.unittest.testSuite(function() {
+ // Arbitrarily selected process ID and thread IDs we'll use in test data
+ const procId = 52;
+ const tidMain = 1;
+ const tidCompositor = 53;
+ const tidAudio = 55;
+
+ function doLoadEvent(timestamp) {
+ return {name: 'WebMediaPlayerImpl::DoLoad', args: {},
+ pid: procId, ts: timestamp, cat: 'media', tid: tidMain, ph: 'X'};
+ }
+
+ function videoRenderEvent(timestamp) {
+ return {name: 'VideoRendererImpl::Render', args: {},
+ pid: procId, ts: timestamp, cat: 'media', tid: tidCompositor, ph: 'X'};
+ }
+
+ function audioRenderEvent(timestamp) {
+ return {name: 'AudioRendererImpl::Render', args: {},
+ pid: procId, ts: timestamp, cat: 'media', tid: tidAudio, ph: 'X'};
+ }
+
+ function videoFramesDroppedEvent(timestamp, frameCount) {
+ return {name: 'VideoFramesDropped', args: {count: frameCount},
+ pid: procId, ts: timestamp, cat: 'media', tid: tidCompositor, ph: 'X'};
+ }
+
+ function onEndedEvent(timestamp, mediaDuration) {
+ return {name: 'WebMediaPlayerImpl::OnEnded',
+ args: {'duration': mediaDuration},
+ pid: procId, ts: timestamp, cat: 'media', tid: tidMain, ph: 'X'};
+ }
+
+ function doSeekEvent(timestamp, targetTime) {
+ return {name: 'WebMediaPlayerImpl::DoSeek', args: {target: targetTime},
+ pid: procId, ts: timestamp, cat: 'media', tid: tidMain, ph: 'X'};
+ }
+
+ function seekedEvent(timestamp, targetTime) {
+ return {name: 'WebMediaPlayerImpl::OnPipelineSeeked',
+ args: {target: targetTime},
+ pid: procId, ts: timestamp, cat: 'media', tid: tidMain, ph: 'X'};
+ }
+
+ function threadMarker(threadName, threadId) {
+ return {name: 'thread_name', args: {name: threadName},
+ pid: procId, ts: 0, cat: '__metadata', tid: threadId, ph: 'M'};
+ }
+
+ const mainThreadMarker = threadMarker('CrRendererMain', tidMain);
+ const compositorThreadMarker = threadMarker('Compositor', tidCompositor);
+ const audioThreadMarker = threadMarker('AudioOutputDevice', tidAudio);
+
function makeModel(events) {
return tr.c.TestUtils.newModelWithEvents([events]);
}
+ function checkCloseTo(histograms, histogramName, expectedValue) {
+ assert.isDefined(histograms.getHistogramNamed(histogramName));
+ const value = histograms.getHistogramNamed(histogramName);
+ const statistics = value.running;
+ assert.strictEqual(statistics.count, 1);
+ assert.closeTo(statistics.mean, expectedValue, 1e-5);
+ }
+
+ function checkEqual(histograms, histogramName, expectedValue) {
+ assert.isDefined(histograms.getHistogramNamed(histogramName));
+ const value = histograms.getHistogramNamed(histogramName);
+ const statistics = value.running;
+ assert.strictEqual(statistics.count, 1);
+ assert.strictEqual(statistics.mean, expectedValue);
+ }
+
test('mediaMetric_noData', function() {
const histograms = new tr.v.HistogramSet();
- const events = [
- {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'},
- {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'}
- ];
+ const events = [];
tr.metrics.mediaMetric(histograms, makeModel(events));
assert.lengthOf(histograms, 0);
});
@@ -31,47 +96,174 @@ tr.b.unittest.testSuite(function() {
test('mediaMetric_videoTimeToPlay', function() {
const histograms = new tr.v.HistogramSet();
const events = [
- {name: 'WebMediaPlayerImpl::DoLoad', args: {},
- pid: 52, ts: 524, cat: 'media', tid: 1, ph: 'X'},
- {name: 'VideoRendererImpl::Render', args: {},
- pid: 52, ts: 560, cat: 'media', tid: 53, ph: 'X'},
- {name: 'VideoRendererImpl::Render', args: {},
- pid: 52, ts: 580, cat: 'media', tid: 53, ph: 'X'},
- {name: 'thread_name', args: {name: 'CrRendererMain'},
- pid: 52, ts: 0, cat: '__metadata', tid: 1, ph: 'M'},
- {name: 'thread_name', args: {name: 'Compositor'},
- pid: 52, ts: 0, cat: '__metadata', tid: 53, ph: 'M'},
+ doLoadEvent(100),
+ videoRenderEvent(300),
+ // Video renderer always generate multiple render events,
+ // one for each frame. For calculation of time-to-play,
+ // only the first render event is relevant. Here we put in
+ // a second render event to make sure it's ignored by the
+ // metric computation code.
+ videoRenderEvent(400),
+ mainThreadMarker,
+ compositorThreadMarker,
];
tr.metrics.mediaMetric(histograms, makeModel(events));
-
- assert.isDefined(histograms.getHistogramNamed('time_to_video_play'));
- const ttpValue = histograms.getHistogramNamed('time_to_video_play');
- const ttpStatistics = ttpValue.running;
- assert.strictEqual(ttpStatistics.count, 1);
- assert.closeTo(ttpStatistics.mean, 0.036, 1e-5);
- assert.closeTo(ttpStatistics.max, 0.036, 1e-5);
+ checkCloseTo(histograms, 'time_to_video_play', 0.2);
});
test('mediaMetric_audioTimeToPlay', function() {
const histograms = new tr.v.HistogramSet();
const events = [
- {name: 'thread_name', args: {name: 'CrRendererMain'},
- pid: 52, ts: 0, cat: '__metadata', tid: 1, ph: 'M'},
- {name: 'thread_name', args: {name: 'AudioOutputDevice'},
- pid: 52, ts: 0, cat: '__metadata', tid: 53, ph: 'M'},
- {name: 'WebMediaPlayerImpl::DoLoad', args: {},
- pid: 52, ts: 1234, cat: 'media', tid: 1, ph: 'X'},
- {name: 'AudioRendererImpl::Render', args: {},
- pid: 52, ts: 4321, cat: 'media', tid: 53, ph: 'X'},
+ mainThreadMarker,
+ audioThreadMarker,
+ doLoadEvent(1000),
+ audioRenderEvent(1100),
+ ];
+ tr.metrics.mediaMetric(histograms, makeModel(events));
+ checkCloseTo(histograms, 'time_to_audio_play', 0.1);
+ });
+
+ test('mediaMetric_bufferingTimeVideo', function() {
+ const histograms = new tr.v.HistogramSet();
+ const events = [
+ doLoadEvent(1000),
+ videoRenderEvent(1500),
+ videoRenderEvent(1600),
+ onEndedEvent(10051500, 10),
+ mainThreadMarker,
+ compositorThreadMarker,
+ ];
+ tr.metrics.mediaMetric(histograms, makeModel(events));
+ checkCloseTo(histograms, 'buffering_time', 50);
+ });
+
+ test('mediaMetric_bufferingTimeAudio', function() {
+ const histograms = new tr.v.HistogramSet();
+ const events = [
+ mainThreadMarker,
+ audioThreadMarker,
+ doLoadEvent(1000),
+ audioRenderEvent(1500),
+ onEndedEvent(5002500, 5),
+ ];
+ tr.metrics.mediaMetric(histograms, makeModel(events));
+ checkCloseTo(histograms, 'buffering_time', 1);
+ });
+
+ // With seek, no buffering time should be reported
+ test('mediaMetric_noBufferingTime', function() {
+ const histograms = new tr.v.HistogramSet();
+ const events = [
+ doLoadEvent(1000),
+ videoRenderEvent(1500),
+ videoRenderEvent(1600),
+ onEndedEvent(10066666, 10),
+ doSeekEvent(525, 1.2),
+ seekedEvent(719, 1.2),
+ mainThreadMarker,
+ compositorThreadMarker,
+ ];
+ tr.metrics.mediaMetric(histograms, makeModel(events));
+ assert.isUndefined(histograms.getHistogramNamed('buffering_time'));
+ });
+
+ test('mediaMetric_droppedFrameCount', function() {
+ const histograms = new tr.v.HistogramSet();
+ const events = [
+ doLoadEvent(1000),
+ videoRenderEvent(1500),
+ videoFramesDroppedEvent(123456, 3),
+ videoFramesDroppedEvent(234567, 6),
+ videoFramesDroppedEvent(345678, 1),
+ mainThreadMarker,
+ compositorThreadMarker,
+ ];
+ tr.metrics.mediaMetric(histograms, makeModel(events));
+ checkEqual(histograms, 'dropped_frame_count', 10);
+ });
+
+ test('mediaMetric_seekTime', function() {
+ const histograms = new tr.v.HistogramSet();
+ const events = [
+ doLoadEvent(1000),
+ videoRenderEvent(1500),
+ doSeekEvent(2000, 1.2),
+ seekedEvent(2500, 1.2),
+ doSeekEvent(15000, 3.7),
+ seekedEvent(75000, 3.7),
+ mainThreadMarker,
+ compositorThreadMarker,
+ ];
+ tr.metrics.mediaMetric(histograms, makeModel(events));
+ checkCloseTo(histograms, 'seek_time_1.2', 0.5);
+ checkCloseTo(histograms, 'seek_time_3.7', 60);
+ });
+
+ // Scenario: Play mixed audio/video from start to finish
+ test('mediaMetric_playVideoScenario', function() {
+ const histograms = new tr.v.HistogramSet();
+ const events = [
+ doLoadEvent(2000),
+ videoRenderEvent(3000),
+ audioRenderEvent(3200),
+ videoRenderEvent(3300),
+ videoFramesDroppedEvent(123456, 4),
+ videoFramesDroppedEvent(234567, 2),
+ onEndedEvent(10013000, 10),
+ mainThreadMarker,
+ compositorThreadMarker,
+ audioThreadMarker,
+ ];
+ tr.metrics.mediaMetric(histograms, makeModel(events));
+ checkCloseTo(histograms, 'time_to_video_play', 1);
+ checkCloseTo(histograms, 'time_to_audio_play', 1.2);
+ checkCloseTo(histograms, 'buffering_time', 10);
+ checkEqual(histograms, 'dropped_frame_count', 6);
+ });
+
+ // Scenario: Play audio from start to finish
+ test('mediaMetric_playAudioScenario', function() {
+ const histograms = new tr.v.HistogramSet();
+ const events = [
+ doLoadEvent(1000),
+ audioRenderEvent(1500),
+ onEndedEvent(10002500, 10),
+ mainThreadMarker,
+ audioThreadMarker,
];
tr.metrics.mediaMetric(histograms, makeModel(events));
+ assert.isUndefined(histograms.getHistogramNamed('time_to_video_play'));
+ checkCloseTo(histograms, 'time_to_audio_play', 0.5);
+ checkCloseTo(histograms, 'buffering_time', 1);
+ assert.isUndefined(histograms.getHistogramNamed('dropped_frame_count'));
+ });
- assert.isDefined(histograms.getHistogramNamed('time_to_audio_play'));
- const ttpValue = histograms.getHistogramNamed('time_to_audio_play');
- const ttpStatistics = ttpValue.running;
- assert.strictEqual(ttpStatistics.count, 1);
- assert.closeTo(ttpStatistics.mean, 3.087, 1e-5);
- assert.closeTo(ttpStatistics.max, 3.087, 1e-5);
+ // Scenario: Play audio/video with two seeks
+ test('mediaMetric_seekScenario', function() {
+ const histograms = new tr.v.HistogramSet();
+ const events = [
+ doLoadEvent(1000),
+ videoRenderEvent(2000),
+ audioRenderEvent(2020),
+ videoRenderEvent(2040),
+ doSeekEvent(5000, 0.5),
+ seekedEvent(5200, 0.5),
+ videoFramesDroppedEvent(123456, 4),
+ doSeekEvent(200000, 9),
+ seekedEvent(210000, 9),
+ videoFramesDroppedEvent(234567, 2),
+ onEndedEvent(300000, 10),
+ mainThreadMarker,
+ compositorThreadMarker,
+ audioThreadMarker,
+ ];
+ tr.metrics.mediaMetric(histograms, makeModel(events));
+ checkCloseTo(histograms, 'time_to_video_play', 1);
+ checkCloseTo(histograms, 'time_to_audio_play', 1.02);
+ assert.isUndefined(histograms.getHistogramNamed('buffering_time'));
+ checkEqual(histograms, 'dropped_frame_count', 6);
+ checkCloseTo(histograms, 'seek_time_0.5', 0.2);
+ checkCloseTo(histograms, 'seek_time_9', 10);
});
});
</script>
« 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