2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
7 // This file requires the functions defined in test_functions.js.
9 var gFingerprints
= [];
10 var gDetectorInterval
= null;
15 * Starts capturing frames from a video tag. The algorithm will fingerprint a
16 * a frame every now and then. After calling this function and running for a
17 * while (at least 200 ms) you will be able to call isVideoPlaying to see if
18 * we detected any video.
20 * @param {string} videoElementId The video element to analyze.
21 * @param {int} width The video element's width.
22 * @param {int} width The video element's height.
24 * @return {string} Returns ok-started to the test.
27 function startDetection(videoElementId
, width
, height
) {
28 var video
= document
.getElementById(videoElementId
);
30 throw failTest('Could not find video element with id ' + videoElementId
);
32 if (gDetectorInterval
)
33 throw failTest('Detector is already running.');
35 var NUM_FINGERPRINTS_TO_SAVE
= 5;
36 var canvas
= document
.createElement('canvas');
37 canvas
.style
.display
= 'none';
40 gDetectorInterval
= setInterval(function() {
41 var context
= canvas
.getContext('2d');
42 if (video
.videoWidth
== 0)
43 return; // The video element isn't playing anything.
45 captureFrame_(video
, context
, width
, height
);
46 gFingerprints
.push(fingerprint_(context
, width
, height
));
47 if (gFingerprints
.length
> NUM_FINGERPRINTS_TO_SAVE
) {
48 gFingerprints
.shift();
52 returnToTest('ok-started');
56 * Checks if we have detected any video so far.
58 * @return {string} video-playing if we detected video, otherwise
61 function isVideoPlaying() {
62 // Video is considered to be playing if at least one finger print has changed
63 // since the oldest fingerprint. Even small blips in the pixel data will cause
64 // this check to pass. We only check for rough equality though to account for
67 if (gFingerprints
.length
> 1) {
68 if (!allElementsRoughlyEqualTo_(gFingerprints
, gFingerprints
[0])) {
69 clearInterval(gDetectorInterval
);
70 gDetectorInterval
= null;
71 returnToTest('video-playing');
76 throw failTest('Failed to detect video: ' + exception
.message
);
78 returnToTest('video-not-playing');
82 * Queries for the stream size (not necessarily the size at which the video tag
85 * @param videoElementId The video element to check.
86 * @return {string} ok-<width>x<height>, e.g. ok-640x480 for VGA.
88 function getStreamSize(videoElementId
) {
89 var video
= document
.getElementById(videoElementId
);
91 throw failTest('Could not find video element with id ' + videoElementId
);
93 returnToTest('ok-' + video
.videoWidth
+ 'x' + video
.videoHeight
);
99 function allElementsRoughlyEqualTo_(elements
, element_to_compare
) {
100 if (elements
.length
== 0)
103 var PIXEL_DIFF_TOLERANCE
= 100;
104 for (var i
= 0; i
< elements
.length
; i
++) {
105 if (Math
.abs(elements
[i
] - element_to_compare
) > PIXEL_DIFF_TOLERANCE
) {
113 function captureFrame_(video
, canvasContext
, width
, height
) {
114 canvasContext
.drawImage(video
, 0, 0, width
, height
);
118 function fingerprint_(canvasContext
, width
, height
) {
119 var imageData
= canvasContext
.getImageData(0, 0, width
, height
);
120 var pixels
= imageData
.data
;
123 for (var i
= 0; i
< pixels
.length
; i
++) {
124 fingerprint
+= pixels
[i
];