• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html>
2<html>
3<head><title>GetUserMedia test</title></head>
4<body>
5  <script src="ssim.js"></script>
6  <script src="blackframe.js"></script>
7<script>
8
9var resolutions = [[640, 480],
10                   [1280, 720]];
11var results = {};
12var isTestDone = 0;
13var durationMs = 20000;
14
15function testNextResolution() {
16  var nextResolution = resolutions.shift();
17  if (nextResolution == undefined) {
18    reportTestDone();
19    return;
20  }
21  var test = new CameraTest(nextResolution);
22  test.start();
23  setTimeout(
24    function() {
25      test.stop();
26      testNextResolution();
27    },
28    durationMs);
29}
30
31function reportTestDone() {
32  console.log('tests completed');
33  isTestDone = 1;
34}
35
36function getResults() {
37  return results;
38}
39
40function resolutionMatchesIndependentOfRotation(aWidth, aHeight,
41                                                bWidth, bHeight) {
42  return (aWidth === bWidth && aHeight === bHeight) ||
43         (aWidth === bHeight && aHeight === bWidth);
44}
45
46function saveResult(resolution, verdict) {
47  results[resolution] = verdict;
48}
49
50function CameraTest(resolution) {
51  this.resolution = resolution;
52  this.localVideo = document.createElement('video');
53  this.localVideo.id = 'local-video';
54  this.localVideo.autoplay = true;
55  document.body.appendChild(this.localVideo);
56  this.localStream = null;
57  this.canvas = document.createElement('canvas');
58  this.context = this.canvas.getContext('2d');
59  this.previousFrame = [];
60  this.identicalFrameSsimThreshold = 0.985;
61  this.frameComparator = new Ssim();
62  this.results = {cameraErrors: [],
63      frameStats: {numBlackFrames: 0, numFrozenFrames:0, numFrames: 0}};
64
65  this.constraints = {
66    "audio": false,
67    "video": {
68      "mandatory" : {
69          "maxWidth": this.resolution[0].toString(),
70          "maxHeight": this.resolution[1].toString(),
71          "minWidth": this.resolution[0].toString(),
72          "minHeight": this.resolution[1].toString()
73      },
74    }
75  };
76}
77
78CameraTest.prototype = {
79
80  start: function() {
81    this.localVideo.addEventListener('play',
82        this.startCheckingVideoFrames.bind(this), false);
83    navigator.getUserMedia = navigator.getUserMedia ||
84        navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
85
86    navigator.getUserMedia(this.constraints, this.gotLocalStream.bind(this),
87        this.gotUserMediaError.bind(this));
88  },
89
90  gotLocalStream: function(stream) {
91    this.localStream = stream;
92    this.localVideo.src = window.URL.createObjectURL(stream);
93  },
94
95  gotUserMediaError: function(error) {
96    console.log('navigator.getUserMedia error: ', error);
97    this.results.cameraErrors.push('GetUserMedia error: ' + error.toString());
98  },
99
100  startCheckingVideoFrames: function() {
101    if (!resolutionMatchesIndependentOfRotation(this.localVideo.videoWidth,
102        this.localVideo.videoHeight, this.resolution[0], this.resolution[1])) {
103      this.results.cameraErrors.push('resolution', 'Got ' +
104          this.localVideo.videoWidth + 'x' + this.localVideo.videoHeight +
105          ', expected ' + this.resolution[0] + 'x' + this.resolution[1] +
106          ' or rotated version thereof');
107    }
108
109    this.videoFrameChecker = setInterval(this.checkVideoFrame.bind(this), 20);
110  },
111
112  checkVideoFrame: function() {
113    this.context.drawImage(this.localVideo, 0, 0, this.canvas.width,
114      this.canvas.height);
115    var imageData = this.context.getImageData(0, 0, this.canvas.width,
116      this.canvas.height);
117
118    if (isBlackFrame(imageData.data, imageData.data.length)) {
119      this.results.frameStats.numBlackFrames++;
120    }
121
122    if (this.frameComparator.calculate(this.previousFrame, imageData.data) >
123      this.identicalFrameSsimThreshold) {
124      this.results.frameStats.numFrozenFrames++;
125    }
126
127    this.previousFrame = imageData.data;
128    this.results.frameStats.numFrames++;
129  },
130
131  stop: function() {
132    clearInterval(this.videoFrameChecker);
133    saveResult(this.resolution, this.results);
134    this.localStream.getTracks().forEach(function(track) {
135      track.stop();
136    });
137    document.body.removeChild(this.localVideo);
138  },
139}
140
141window.onload = testNextResolution;
142window.onerror = function (message, filename, lineno, colno, error) {
143  console.log("Something went wrong, here is the stack trace --> %s",
144      error.stack);
145};
146</script>
147</body>
148</html>
149