<!DOCTYPE html>
<html>
<head><title>GetUserMedia test</title></head>
<body>
  <script src="ssim.js"></script>
  <script src="blackframe.js"></script>
<script>

var resolutions = [[640, 480],
                   [1280, 720]];
var results = {};
var isTestDone = 0;
var durationMs = 20000;

function testNextResolution() {
  var nextResolution = resolutions.shift();
  if (nextResolution == undefined) {
    reportTestDone();
    return;
  }
  var test = new CameraTest(nextResolution);
  test.start();
  setTimeout(
    function() {
      test.stop();
      testNextResolution();
    },
    durationMs);
}

function reportTestDone() {
  console.log('tests completed');
  isTestDone = 1;
}

function getResults() {
  return results;
}

function resolutionMatchesIndependentOfRotation(aWidth, aHeight,
                                                bWidth, bHeight) {
  return (aWidth === bWidth && aHeight === bHeight) ||
         (aWidth === bHeight && aHeight === bWidth);
}

function saveResult(resolution, verdict) {
  results[resolution] = verdict;
}

function CameraTest(resolution) {
  this.resolution = resolution;
  this.localVideo = document.createElement('video');
  this.localVideo.id = 'local-video';
  this.localVideo.autoplay = true;
  document.body.appendChild(this.localVideo);
  this.localStream = null;
  this.canvas = document.createElement('canvas');
  this.context = this.canvas.getContext('2d');
  this.previousFrame = [];
  this.identicalFrameSsimThreshold = 0.985;
  this.frameComparator = new Ssim();
  this.results = {cameraErrors: [],
      frameStats: {numBlackFrames: 0, numFrozenFrames:0, numFrames: 0}};

  this.constraints = {
    "audio": false,
    "video": {
      "mandatory" : {
          "maxWidth": this.resolution[0].toString(),
          "maxHeight": this.resolution[1].toString(),
          "minWidth": this.resolution[0].toString(),
          "minHeight": this.resolution[1].toString()
      },
    }
  };
}

CameraTest.prototype = {

  start: function() {
    this.localVideo.addEventListener('play',
        this.startCheckingVideoFrames.bind(this), false);
    navigator.getUserMedia = navigator.getUserMedia ||
        navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    navigator.getUserMedia(this.constraints, this.gotLocalStream.bind(this),
        this.gotUserMediaError.bind(this));
  },

  gotLocalStream: function(stream) {
    this.localStream = stream;
    this.localVideo.src = window.URL.createObjectURL(stream);
  },

  gotUserMediaError: function(error) {
    console.log('navigator.getUserMedia error: ', error);
    this.results.cameraErrors.push('GetUserMedia error: ' + error.toString());
  },

  startCheckingVideoFrames: function() {
    if (!resolutionMatchesIndependentOfRotation(this.localVideo.videoWidth,
        this.localVideo.videoHeight, this.resolution[0], this.resolution[1])) {
      this.results.cameraErrors.push('resolution', 'Got ' +
          this.localVideo.videoWidth + 'x' + this.localVideo.videoHeight +
          ', expected ' + this.resolution[0] + 'x' + this.resolution[1] +
          ' or rotated version thereof');
    }

    this.videoFrameChecker = setInterval(this.checkVideoFrame.bind(this), 20);
  },

  checkVideoFrame: function() {
    this.context.drawImage(this.localVideo, 0, 0, this.canvas.width,
      this.canvas.height);
    var imageData = this.context.getImageData(0, 0, this.canvas.width,
      this.canvas.height);

    if (isBlackFrame(imageData.data, imageData.data.length)) {
      this.results.frameStats.numBlackFrames++;
    }

    if (this.frameComparator.calculate(this.previousFrame, imageData.data) >
      this.identicalFrameSsimThreshold) {
      this.results.frameStats.numFrozenFrames++;
    }

    this.previousFrame = imageData.data;
    this.results.frameStats.numFrames++;
  },

  stop: function() {
    clearInterval(this.videoFrameChecker);
    saveResult(this.resolution, this.results);
    this.localStream.getTracks().forEach(function(track) {
      track.stop();
    });
    document.body.removeChild(this.localVideo);
  },
}

window.onload = testNextResolution;
window.onerror = function (message, filename, lineno, colno, error) {
  console.log("Something went wrong, here is the stack trace --> %s",
      error.stack);
};
</script>
</body>
</html>
