1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// FPSObserver observes a <video> and reports decoded FPS, dropped FPS, and
6// total dropped frames during the video playback.
7var FPSObserver = new function() {
8  this.video_ = null;
9  this.decodedFrames_ = 0;
10  this.droppedFrames_ = 0;
11  this.startTime_ = 0;
12  this.intID_ = null;
13}
14
15FPSObserver.observe = function(video) {
16  this.video_ = video;
17  var observer = this;
18  this.video_.addEventListener('playing', function() {
19    observer.onVideoPlaying();
20  });
21
22  this.video_.addEventListener('error', function() {
23    observer.endTest();
24  });
25
26  this.video_.addEventListener('ended', function() {
27    observer.endTest();
28  });
29};
30
31FPSObserver.onVideoPlaying = function() {
32  this.decodedFrames_ = 0;
33  this.droppedFrames_ = 0;
34  this.startTime_ = window.performance.now();
35  this.endTest(true);
36  var observer = this;
37  this.intID_ = window.setInterval(function() {
38      observer.calculateStats();}, 1000);
39};
40
41FPSObserver.calculateStats = function() {
42  if (this.video_.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA ||
43      this.video_.paused || this.video_.ended)
44    return;
45  var currentTime = window.performance.now();
46  var deltaTime = (currentTime - this.startTime_) / 1000;
47  this.startTime_ = currentTime;
48
49  // Calculate decoded frames per sec.
50  var fps = (this.video_.webkitDecodedFrameCount - this.decodedFrames_) /
51             deltaTime;
52  this.decodedFrames_ = this.video_.webkitDecodedFrameCount;
53  fps = fps.toFixed(2);
54  decodedFPSElement.innerHTML = fps;
55
56  // Calculate dropped frames per sec.
57  fps = (this.video_.webkitDroppedFrameCount - this.droppedFrames_) / deltaTime;
58  this.droppedFrames_ = this.video_.webkitDroppedFrameCount;
59  fps = fps.toFixed(2);
60  droppedFPSElement.innerHTML = fps;
61
62  droppedFramesElement.innerHTML = this.droppedFrames_;
63};
64
65FPSObserver.endTest = function() {
66  window.clearInterval(this.intID_);
67};
68