Skip to content
This repository was archived by the owner on May 13, 2024. It is now read-only.

Commit 85f3aff

Browse files
committed
move videoframechecker to separate file and export as module
moves the videoframechecker to a separate file and allows requiring videoframechecker and ssim as modules
1 parent 0f8646e commit 85f3aff

File tree

5 files changed

+96
-76
lines changed

5 files changed

+96
-76
lines changed

.eslintrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,13 @@
6666
"arrayMin": true,
6767
"TURN_URL": true,
6868
"Ssim": true,
69+
"VideoFrameChecker": true,
6970
"StatisticsAggregate": true,
7071
"API_KEY": true,
7172
"doGetUserMedia": true,
7273
"Call": true,
7374
"setTimeoutWithProgressBar": true,
7475
"ga": true,
76+
"module": true,
7577
}
7678
}

src/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
<script src="js/call.js"></script>
5252
<script src="js/stats.js"></script>
5353
<script src="js/ssim.js"></script>
54+
<script src="js/videoframechecker.js"></script>
5455
<script src="js/util.js"></script>
5556
<script src="js/testcasename.js"></script>
5657
<script src="js/testsuitename.js"></script>

src/js/camresolutionstest.js

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -289,79 +289,3 @@ CamResolutionsTest.prototype = {
289289
}
290290
};
291291

292-
// TODO: Move this to a separate file.
293-
function VideoFrameChecker(videoElement) {
294-
this.frameStats = {
295-
numFrozenFrames: 0,
296-
numBlackFrames: 0,
297-
numFrames: 0
298-
};
299-
300-
this.running_ = true;
301-
302-
this.nonBlackPixelLumaThreshold = 20;
303-
this.previousFrame_ = [];
304-
this.identicalFrameSsimThreshold = 0.985;
305-
this.frameComparator = new Ssim();
306-
307-
this.canvas_ = document.createElement('canvas');
308-
this.videoElement_ = videoElement;
309-
this.listener_ = this.checkVideoFrame_.bind(this);
310-
this.videoElement_.addEventListener('play', this.listener_, false);
311-
}
312-
313-
VideoFrameChecker.prototype = {
314-
stop: function() {
315-
this.videoElement_.removeEventListener('play' , this.listener_);
316-
this.running_ = false;
317-
},
318-
319-
getCurrentImageData_: function() {
320-
this.canvas_.width = this.videoElement_.width;
321-
this.canvas_.height = this.videoElement_.height;
322-
323-
var context = this.canvas_.getContext('2d');
324-
context.drawImage(this.videoElement_, 0, 0, this.canvas_.width,
325-
this.canvas_.height);
326-
return context.getImageData(0, 0, this.canvas_.width, this.canvas_.height);
327-
},
328-
329-
checkVideoFrame_: function() {
330-
if (!this.running_) {
331-
return;
332-
}
333-
if (this.videoElement_.ended) {
334-
return;
335-
}
336-
337-
var imageData = this.getCurrentImageData_();
338-
339-
if (this.isBlackFrame_(imageData.data, imageData.data.length)) {
340-
this.frameStats.numBlackFrames++;
341-
}
342-
343-
if (this.frameComparator.calculate(this.previousFrame_, imageData.data) >
344-
this.identicalFrameSsimThreshold) {
345-
this.frameStats.numFrozenFrames++;
346-
}
347-
this.previousFrame_ = imageData.data;
348-
349-
this.frameStats.numFrames++;
350-
setTimeout(this.checkVideoFrame_.bind(this), 20);
351-
},
352-
353-
isBlackFrame_: function(data, length) {
354-
// TODO: Use a statistical, histogram-based detection.
355-
var thresh = this.nonBlackPixelLumaThreshold;
356-
var accuLuma = 0;
357-
for (var i = 4; i < length; i += 4) {
358-
// Use Luma as in Rec. 709: Y′709 = 0.21R + 0.72G + 0.07B;
359-
accuLuma += 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];
360-
// Early termination if the average Luma so far is bright enough.
361-
if (accuLuma > (thresh * i / 4)) {
362-
return false;
363-
}
364-
}
365-
return true;
366-
}
367-
};

src/js/ssim.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,7 @@ Ssim.prototype = {
8787
return luminance * contrast * structure;
8888
}
8989
};
90+
91+
if (typeof exports === 'object') {
92+
module.exports = Ssim;
93+
}

src/js/videoframechecker.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3+
*
4+
* Use of this source code is governed by a BSD-style license
5+
* that can be found in the LICENSE file in the root of the source
6+
* tree.
7+
*/
8+
9+
/* More information about these options at jshint.com/docs/options */
10+
'use strict';
11+
function VideoFrameChecker(videoElement) {
12+
this.frameStats = {
13+
numFrozenFrames: 0,
14+
numBlackFrames: 0,
15+
numFrames: 0
16+
};
17+
18+
this.running_ = true;
19+
20+
this.nonBlackPixelLumaThreshold = 20;
21+
this.previousFrame_ = [];
22+
this.identicalFrameSsimThreshold = 0.985;
23+
this.frameComparator = new Ssim();
24+
25+
this.canvas_ = document.createElement('canvas');
26+
this.videoElement_ = videoElement;
27+
this.listener_ = this.checkVideoFrame_.bind(this);
28+
this.videoElement_.addEventListener('play', this.listener_, false);
29+
}
30+
31+
VideoFrameChecker.prototype = {
32+
stop: function() {
33+
this.videoElement_.removeEventListener('play' , this.listener_);
34+
this.running_ = false;
35+
},
36+
37+
getCurrentImageData_: function() {
38+
this.canvas_.width = this.videoElement_.width;
39+
this.canvas_.height = this.videoElement_.height;
40+
41+
var context = this.canvas_.getContext('2d');
42+
context.drawImage(this.videoElement_, 0, 0, this.canvas_.width,
43+
this.canvas_.height);
44+
return context.getImageData(0, 0, this.canvas_.width, this.canvas_.height);
45+
},
46+
47+
checkVideoFrame_: function() {
48+
if (!this.running_) {
49+
return;
50+
}
51+
if (this.videoElement_.ended) {
52+
return;
53+
}
54+
55+
var imageData = this.getCurrentImageData_();
56+
57+
if (this.isBlackFrame_(imageData.data, imageData.data.length)) {
58+
this.frameStats.numBlackFrames++;
59+
}
60+
61+
if (this.frameComparator.calculate(this.previousFrame_, imageData.data) >
62+
this.identicalFrameSsimThreshold) {
63+
this.frameStats.numFrozenFrames++;
64+
}
65+
this.previousFrame_ = imageData.data;
66+
67+
this.frameStats.numFrames++;
68+
setTimeout(this.checkVideoFrame_.bind(this), 20);
69+
},
70+
71+
isBlackFrame_: function(data, length) {
72+
// TODO: Use a statistical, histogram-based detection.
73+
var thresh = this.nonBlackPixelLumaThreshold;
74+
var accuLuma = 0;
75+
for (var i = 4; i < length; i += 4) {
76+
// Use Luma as in Rec. 709: Y′709 = 0.21R + 0.72G + 0.07B;
77+
accuLuma += 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];
78+
// Early termination if the average Luma so far is bright enough.
79+
if (accuLuma > (thresh * i / 4)) {
80+
return false;
81+
}
82+
}
83+
return true;
84+
}
85+
};
86+
87+
if (typeof exports === 'object') {
88+
module.exports = VideoFrameChecker;
89+
}

0 commit comments

Comments
 (0)