HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Optimizing the performance of html5 video manipulation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thevideohtml5optimizingperformancemanipulation

Problem

I've been working on an html5 canvas video player with a lot of fun little extras and ui toys, the main one being a chroma key (green screen) effect that allows the user to key out different colors or ranges of color while the video is playing.

I seem to have hit a snag in the recommended chroma key method. It works, but it is a really heavy process and can tax the cpu to the point where the video will look choppy if the user is running other applications in the background.

Here is the stripped down code I'm using for the chroma key effect:

```







var doc = document;
var sourceVid = doc.getElementById("sourceVid");
var hCanvas = doc.getElementById("hCanvas");
var dCanvas = doc.getElementById("dCanvas");
var hContext = hCanvas.getContext("2d");
var dContext = dCanvas.getContext("2d");

sourceVid.addEventListener('loadeddata', function() {
hCanvas.setAttribute('width', sourceVid.offsetWidth);
dCanvas.setAttribute('width', sourceVid.offsetWidth);
hCanvas.setAttribute('height', sourceVid.offsetHeight);
dCanvas.setAttribute('height', sourceVid.offsetHeight);
}, false);

sourceVid.addEventListener('play', function() {
runAnalysis();
});

var runAnalysis = function() {
if (sourceVid.paused || sourceVid.ended) {
return
}
frameFix();
if (window.requestAnimationFrame) {
requestAnimationFrame(runAnalysis);
} else {
setTimeout(runAnalysis, 0);
}
};

var frameFix = function() {

hContext.drawImage(sourceVid, 0, 0, sourceVid.videoWidth, sourceVid.videoHeight);

var frame = hContext.getImageData(0, 0, sourceVid.videoWidth, sourceVid.videoHeight);

var length = fra

Solution

After back and forth with ChrisW and yourself, it seems I found a glaring bug

var frameFix = function() {

        hContext.drawImage(sourceVid, 0, 0, sourceVid.videoWidth, sourceVid.videoHeight);

        var frame = hContext.getImageData(0, 0, sourceVid.videoWidth, sourceVid.videoHeight);

        var length = frame.data.length;
        for (var i = 0; i = 0 && g = 0 && r = 0 && b < 100) {
                frame.data[i * 4 + 3] = 0;
            }
        }
        dContext.putImageData(frame, 0, 0);
        return
    };


Since in frame.data you have 4 data points per pixel, you only need to go as far as frame.data.length / 4, this should make your code 4 times faster.

This observation with ChrisW's common sense observations makes for:

var frameFix = function() 
{
  hContext.drawImage(sourceVid, 0, 0, sourceVid.videoWidth, sourceVid.videoHeight);

  var frame  = hContext.getImageData(0, 0, sourceVid.videoWidth, sourceVid.videoHeight),
      data   = frame.data,
      length = data.length, i;

  for (i = 0; i < length; i += 4) 
    if (data[i] < 100 && data[i + 1] < 100 && data[i + 2] < 100) 
      data[i + 3] = 0;

  dContext.putImageData(frame, 0, 0);
};

Code Snippets

var frameFix = function() {

        hContext.drawImage(sourceVid, 0, 0, sourceVid.videoWidth, sourceVid.videoHeight);

        var frame = hContext.getImageData(0, 0, sourceVid.videoWidth, sourceVid.videoHeight);

        var length = frame.data.length;
        for (var i = 0; i < length; i++) {
            var r = frame.data[i * 4 + 0];
            var g = frame.data[i * 4 + 1];
            var b = frame.data[i * 4 + 2];

            if (g >= 0 && g < 100 && r >= 0 && r < 100 && b >= 0 && b < 100) {
                frame.data[i * 4 + 3] = 0;
            }
        }
        dContext.putImageData(frame, 0, 0);
        return
    };
var frameFix = function() 
{
  hContext.drawImage(sourceVid, 0, 0, sourceVid.videoWidth, sourceVid.videoHeight);

  var frame  = hContext.getImageData(0, 0, sourceVid.videoWidth, sourceVid.videoHeight),
      data   = frame.data,
      length = data.length, i;

  for (i = 0; i < length; i += 4) 
    if (data[i] < 100 && data[i + 1] < 100 && data[i + 2] < 100) 
      data[i + 3] = 0;

  dContext.putImageData(frame, 0, 0);
};

Context

StackExchange Code Review Q#39476, answer score: 5

Revisions (0)

No revisions yet.