gpu.js/examples/video/index.html
Robert Plummer ed1cd94448 feat: Added features and fixes for the following issues:
...it kind of snowballed from some needs
Fixes #521 - If `tactic` is not set, check precision allowed from WebGL, and automatically change based off needs, otherwise use value from `tactic`.
Fixes #535 - Internally check if texture from argument is the same as output, if so, clone this texture, and then clean it up after the kernel runs.
Fixes #536 - Normalize all declarations to non-destructured, and then parse
Fixes #537 - Change logic
Fixes #538 - Found the GL script that would work, and reduced the methods to use it
Fixes #539 - Found a better way of testing random, and this gives me an error for 1 in 10 runs, acceptable

Some refactoring for less duplicate code and documentation
2019-11-26 10:55:28 -05:00

102 lines
3.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Video input with GPU.js</title>
<script src="../../dist/gpu-browser.min.js"></script>
</head>
<body>
<h1>Video input (and output) with GPU.js</h1>
<!-- ty https://commons.wikimedia.org/wiki/File:Jellyfish_in_Vr%C3%A5ngo.webm -->
<div style="text-align: center">
<label><input type="checkbox" id="flip-xy" /> Flip XY</label><br />
<label><input type="checkbox" id="alter-colors" /> Alter colors</label><br />
<label><input type="checkbox" id="gpu-enabled" checked /> GPU enabled</label><br />
<label><input type="checkbox" id="pause-gpu" /> Pause GPU</label><br />
</div>
<style>
.grid-container {
display: grid;
grid-template-columns: auto auto;
}
.grid-item {
padding: 20px;
text-align: center;
}
</style>
<div class="grid-container">
<div class="grid-item">
<h3>Video</h3>
<video src="../../test/jellyfish.webm" controls width="337" height="599" loop></video>
</div>
<div id="canvas-parent" class="grid-item">
<h3>GPU.js Graphical Output <span id="fps-number">0</span><span> fps</span></h3>
</div>
</div>
<script src="dist/gpu-browser.js"></script>
<script>
const canvasParent = document.getElementById('canvas-parent');
const flipXY = document.getElementById('flip-xy');
const alterColors = document.getElementById('alter-colors');
const gpuEnabled = document.getElementById('gpu-enabled');
const pauseGPU = document.getElementById('pause-gpu');
const fpsNumber = document.getElementById('fps-number');
let lastCalledTime = Date.now();
let fps;
let delta;
let dispose = setup();
gpuEnabled.onchange = () => {
if (dispose) dispose();
dispose = setup();
};
function setup() {
let disposed = false;
const gpu = new GPU({ mode: gpuEnabled.checked ? 'gpu' : 'cpu' });
// THIS IS THE IMPORTANT STUFF
const kernel = gpu.createKernel(function (frame, flipXY, alterColors) {
// NOTE: better to do alterColors and flipXY out of the kernel, but showing here for brevity
const pixel = flipXY
? frame[this.output.y - 1 - this.thread.y][this.output.x - 1 - this.thread.x]
: frame[this.thread.y][this.thread.x];
if (alterColors) {
this.color(pixel.b, pixel.g, pixel.r, pixel.a);
} else {
this.color(pixel.r, pixel.g, pixel.b, pixel.a);
}
}, {
output: [337, 599],
graphical: true,
tactic: 'precision'
});
canvasParent.appendChild(kernel.canvas);
const videoElement = document.querySelector('video');
function render() {
if (disposed) {
return;
}
if (pauseGPU.checked) return setTimeout(render, 100); // save a little resources when paused
kernel(videoElement, flipXY.checked, alterColors.checked);
window.requestAnimationFrame(render);
calcFPS();
}
render();
return () => {
canvasParent.removeChild(kernel.canvas);
gpu.destroy();
disposed = true;
};
}
function calcFPS() {
delta = (Date.now() - lastCalledTime) / 1000;
lastCalledTime = Date.now();
fps = 1 / delta;
fpsNumber.innerHTML = fps.toFixed(0);
}
</script>
</body>
</html>