OLD | NEW |
---|---|
(Empty) | |
1 <!DOCTYPE html> | |
2 <html> | |
3 <head> | |
4 <title>Canvas Capture FPS Test</title> | |
5 </head> | |
6 <body> | |
7 <div> Canvas capture FPS test.</div> | |
8 <video id='local_video' muted='true' hidden loop autoplay> | |
phoglund_chromium
2016/02/12 08:38:53
In javascript, IDs should be on the form local-vid
cpaulin (no longer in chrome)
2016/02/12 20:14:32
Done.
| |
9 <source src='bear-640x360.webm' type='video/webm'> | |
10 </video> | |
11 <br></br> | |
12 <label>Canvas</label> | |
13 <canvas id='canvas' width=640 height=360></canvas> | |
14 <br></br> | |
15 <label>Captured canvas stream</label> | |
16 <video id='captured_video' autoplay></video> | |
17 <script> | |
18 | |
19 'use strict'; | |
20 | |
21 var DEFAULT_FRAME_RATE = 10; | |
22 var ERROR_RATE = 15 / 100; | |
phoglund_chromium
2016/02/12 08:38:53
TOLERANCE_PERCENT would be a better name for this
cpaulin (no longer in chrome)
2016/02/12 20:14:32
Done.
| |
23 | |
24 // Define video event listener when document is loaded. | |
25 document.addEventListener('DOMContentLoaded', function() { | |
phoglund_chromium
2016/02/12 08:38:53
It's more common to use document.onload for this (
cpaulin (no longer in chrome)
2016/02/12 20:14:32
I am using window.onload now
Done.
| |
26 var video = document.getElementById('local_video'); | |
27 var canvas = document.getElementById('canvas'); | |
28 var context = canvas.getContext('2d'); | |
29 video.addEventListener('play', function() { | |
30 draw(this, context, canvas.clientWidth, canvas.clientHeight); | |
31 }, false); | |
32 }, false); | |
33 | |
34 // This function draws the video frame on the canvas. | |
35 function draw(video, context, width, height) { | |
36 if (video.paused || video.ended) return false; | |
37 context.drawImage(video, 0, 0, width, height); | |
38 setTimeout(draw, 20, video, context, width, height); | |
phoglund_chromium
2016/02/12 08:38:53
Is it important for the fps computations that the
cpaulin (no longer in chrome)
2016/02/12 20:14:32
Thanks for the tip, I am using requestAnimationFra
| |
39 } | |
40 | |
41 // Test class that measures the frame rate of a stream originated from | |
42 // canvas capture. | |
43 function CanvasFpsTest() { | |
44 this.theCanvasStream = null; | |
45 this.decodedFrames = 0; | |
46 this.droppedFrames = 0; | |
47 this.decodedFPS = []; | |
48 this.droppedFPS = []; | |
49 this.startTime = {}; | |
50 this.interval = {}; | |
51 this.targetFPS = 0; | |
52 } | |
53 | |
54 // This function starts the canvas capture of the local video stream. | |
55 CanvasFpsTest.prototype.startCanvasCapture = function(frameRate) { | |
56 var test = this; | |
57 test.targetFPS = frameRate ? frameRate : DEFAULT_FRAME_RATE; | |
58 test.theCanvasStream = document.getElementById('canvas').captureStream( | |
59 test.targetFPS); | |
60 var testVideo = document.getElementById('captured_video'); | |
61 testVideo.addEventListener('play', function(event) { | |
62 test.startTime = new Date().getTime(); | |
63 test.interval = setInterval(test.calculateStats.bind(test, testVideo), | |
64 1000); | |
65 }); | |
66 testVideo.src = URL.createObjectURL(test.theCanvasStream); | |
67 }; | |
68 | |
69 // This functi0on calculates the FPS for decoded frames and dropped frames. | |
phoglund_chromium
2016/02/12 08:38:53
Nit: function
cpaulin (no longer in chrome)
2016/02/12 20:14:32
Done.
| |
70 CanvasFpsTest.prototype.calculateStats = function(video) { | |
71 // We calculate stats on 6 seconds worth of video, that should be | |
72 // reasonable. | |
73 if (this.decodedFPS.length == 6) { | |
74 clearInterval(this.interval); | |
75 return this.validateResults(); | |
76 } | |
77 if (video.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA || | |
78 video.paused || video.ended) | |
79 return; | |
80 var currentTime = new Date().getTime(); | |
81 var deltaTime = (currentTime - this.startTime) / 1000; | |
82 | |
83 this.startTime = currentTime; | |
84 | |
85 // Calculate decoded frames per second. | |
86 var fps = (video.webkitDecodedFrameCount - this.decodedFrames) / deltaTime; | |
87 this.decodedFrames = video.webkitDecodedFrameCount; | |
88 this.decodedFPS.push(fps); | |
89 | |
90 // Calculate dropped frames per second. | |
91 fps = (video.webkitDroppedFrameCount - this.droppedFrames) / deltaTime; | |
92 this.droppedFrames = video.webkitDroppedFrameCount; | |
93 this.droppedFPS.push(fps); | |
94 }; | |
95 | |
96 // This function validates the frameRate against accepted error tolerance. | |
97 CanvasFpsTest.prototype.validateResults = function() { | |
98 // Pop out the first value as it could be a bit off. | |
99 this.decodedFPS.shift; | |
100 this.droppedFPS.shift; | |
101 var averageFPS = average(this.decodedFPS); | |
102 var averageDroppedFPS = average(this.droppedFPS); | |
103 var errorFPS = Math.abs(averageFPS - this.targetFPS) / this.targetFPS; | |
104 if (errorFPS > ERROR_RATE) { | |
105 reportResult('FAIL', 'ERROR: FPS value error beyond acceptable value'); | |
phoglund_chromium
2016/02/12 08:38:53
Simplify this. It's better to just return the seco
cpaulin (no longer in chrome)
2016/02/12 20:14:32
That's true, I fixed it.
Done.
| |
106 } else if (averageDroppedFPS != 0) { | |
107 console.log('ERROR: Some frames where dropped'); | |
108 reportResult('FAIL', 'ERROR: Some frames where dropped'); | |
109 } else { | |
110 reportResult('OK', 'Test Passed'); | |
111 } | |
112 }; | |
113 | |
114 // This function calculates average of array values. | |
115 function average(array) { | |
116 var count = array.length; | |
117 var total = 0; | |
118 for (var i = 0; i < count; i++) { | |
119 total += parseInt(array[i]); | |
120 } | |
121 return Math.floor(total / count); | |
122 } | |
123 | |
124 // This function logs and reports result to Test Environment. | |
125 function reportResult(verdict, message) { | |
126 console.log(verdict, message); | |
127 if (!window.domAutomationController) | |
128 throw 'Expected to run in an automated context.'; | |
129 window.domAutomationController.send(verdict); | |
130 } | |
131 | |
132 // Tests that canvas capture will approximately honor the given frame rate. | |
133 function testFrameRateOfCanvasCapture(frameRate) { | |
134 var fpsTest = new CanvasFpsTest(); | |
135 fpsTest.startCanvasCapture(frameRate); | |
136 } | |
137 | |
138 </script> | |
139 </body> | |
140 </html> | |
OLD | NEW |