mirror of
https://gitlab.com/Shinobi-Systems/ShinobiCE.git
synced 2025-03-09 15:40:15 +00:00
Shinobi CE officially lands on Gitlab
This commit is contained in:
commit
f1406d4eec
431 changed files with 118157 additions and 0 deletions
|
@ -0,0 +1,71 @@
|
|||
"use strict";
|
||||
|
||||
var Class = require('uclass');
|
||||
|
||||
|
||||
var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", `
|
||||
attribute vec3 aVertexPosition;
|
||||
attribute vec2 aTextureCoord;
|
||||
uniform mat4 uMVMatrix;
|
||||
uniform mat4 uPMatrix;
|
||||
varying highp vec2 vTextureCoord;
|
||||
void main(void) {
|
||||
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
|
||||
vTextureCoord = aTextureCoord;
|
||||
}
|
||||
`);
|
||||
|
||||
var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", [
|
||||
precision highp float;
|
||||
varying highp vec2 vTextureCoord;
|
||||
uniform sampler2D FTexture;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = texture2D(FTexture, vTextureCoord);
|
||||
}
|
||||
`);
|
||||
|
||||
|
||||
var FilterWebGLCanvas = new Class({
|
||||
Extends : WebGLCanvas,
|
||||
|
||||
initialize : function(canvas, size, useFrameBuffer) {
|
||||
FilterWebGLCanvas.parent.initialize.call(this, canvas, size, useFrameBuffer);
|
||||
},
|
||||
|
||||
onInitShaders: function() {
|
||||
this.program = new Program(this.gl);
|
||||
this.program.attach(new Shader(this.gl, vertexShaderScript));
|
||||
this.program.attach(new Shader(this.gl, fragmentShaderScript));
|
||||
this.program.link();
|
||||
this.program.use();
|
||||
this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition");
|
||||
this.gl.enableVertexAttribArray(this.vertexPositionAttribute);
|
||||
this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");
|
||||
this.gl.enableVertexAttribArray(this.textureCoordAttribute);
|
||||
},
|
||||
|
||||
onInitTextures: function () {
|
||||
console.log("creatingTextures: size: " + this.size);
|
||||
this.FTexture = new Texture(this.gl, this.size, this.gl.RGBA);
|
||||
},
|
||||
|
||||
onInitSceneTextures: function () {
|
||||
this.FTexture.bind(0, this.program, "FTexture");
|
||||
},
|
||||
|
||||
process: function(buffer, output) {
|
||||
this.FTexture.fill(buffer);
|
||||
this.drawScene();
|
||||
this.readPixels(output);
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return "FilterWebGLCanvas Size: " + this.size;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
module.exports = FilterWebGLCanvas;
|
||||
|
32
tools/ffmpegToWeb/Player/broadway/canvas/Program.js
Normal file
32
tools/ffmpegToWeb/Player/broadway/canvas/Program.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
"use strict";
|
||||
var assert = require('../utils/assert');
|
||||
|
||||
|
||||
function Program(gl) {
|
||||
this.gl = gl;
|
||||
this.program = this.gl.createProgram();
|
||||
}
|
||||
|
||||
Program.prototype = {
|
||||
attach: function (shader) {
|
||||
this.gl.attachShader(this.program, shader.shader);
|
||||
},
|
||||
link: function () {
|
||||
this.gl.linkProgram(this.program);
|
||||
// If creating the shader program failed, alert.
|
||||
assert(this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS),
|
||||
"Unable to initialize the shader program.");
|
||||
},
|
||||
use: function () {
|
||||
this.gl.useProgram(this.program);
|
||||
},
|
||||
getAttributeLocation: function(name) {
|
||||
return this.gl.getAttribLocation(this.program, name);
|
||||
},
|
||||
setMatrixUniform: function(name, array) {
|
||||
var uniform = this.gl.getUniformLocation(this.program, name);
|
||||
this.gl.uniformMatrix4fv(uniform, false, array);
|
||||
}
|
||||
};
|
||||
module.exports = Program;
|
||||
|
4
tools/ffmpegToWeb/Player/broadway/canvas/README.md
Normal file
4
tools/ffmpegToWeb/Player/broadway/canvas/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
/*
|
||||
* Those files wraps several WebGL constructs and provides a simple, single texture based WebGLCanvas as well as a
|
||||
* specialized YUVWebGLCanvas that can handle YUV->RGB conversion.
|
||||
*/
|
41
tools/ffmpegToWeb/Player/broadway/canvas/Script.js
Normal file
41
tools/ffmpegToWeb/Player/broadway/canvas/Script.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
|
||||
var assert = require('../utils/assert');
|
||||
|
||||
/**
|
||||
* Represents a WebGL shader script.
|
||||
*/
|
||||
|
||||
function Script() {}
|
||||
|
||||
Script.createFromElementId = function(id) {
|
||||
var script = document.getElementById(id);
|
||||
|
||||
// Didn't find an element with the specified ID, abort.
|
||||
assert(script , "Could not find shader with ID: " + id);
|
||||
|
||||
// Walk through the source element's children, building the shader source string.
|
||||
var source = "";
|
||||
var currentChild = script .firstChild;
|
||||
while(currentChild) {
|
||||
if (currentChild.nodeType == 3) {
|
||||
source += currentChild.textContent;
|
||||
}
|
||||
currentChild = currentChild.nextSibling;
|
||||
}
|
||||
|
||||
var res = new Scriptor();
|
||||
res.type = script.type;
|
||||
res.source = source;
|
||||
return res;
|
||||
};
|
||||
|
||||
Script.createFromSource = function(type, source) {
|
||||
var res = new Script();
|
||||
res.type = type;
|
||||
res.source = source;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
module.exports = Script;
|
38
tools/ffmpegToWeb/Player/broadway/canvas/Shader.js
Normal file
38
tools/ffmpegToWeb/Player/broadway/canvas/Shader.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
"use strict";
|
||||
|
||||
var error = require('../utils/error');
|
||||
|
||||
/**
|
||||
* Represents a WebGL shader object and provides a mechanism to load shaders from HTML
|
||||
* script tags.
|
||||
*/
|
||||
|
||||
|
||||
function Shader(gl, script) {
|
||||
|
||||
// Now figure out what type of shader script we have, based on its MIME type.
|
||||
if (script.type == "x-shader/x-fragment") {
|
||||
this.shader = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
} else if (script.type == "x-shader/x-vertex") {
|
||||
this.shader = gl.createShader(gl.VERTEX_SHADER);
|
||||
} else {
|
||||
error("Unknown shader type: " + script.type);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the source to the shader object.
|
||||
gl.shaderSource(this.shader, script.source);
|
||||
|
||||
// Compile the shader program.
|
||||
gl.compileShader(this.shader);
|
||||
|
||||
// See if it compiled successfully.
|
||||
if (!gl.getShaderParameter(this.shader, gl.COMPILE_STATUS)) {
|
||||
error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(this.shader));
|
||||
return;
|
||||
}
|
||||
}
|
||||
module.exports = Shader;
|
||||
|
||||
|
||||
|
47
tools/ffmpegToWeb/Player/broadway/canvas/Texture.js
Normal file
47
tools/ffmpegToWeb/Player/broadway/canvas/Texture.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
"use strict";
|
||||
|
||||
var assert = require('../utils/assert');
|
||||
|
||||
/**
|
||||
* Represents a WebGL texture object.
|
||||
*/
|
||||
|
||||
function Texture(gl, size, format) {
|
||||
this.gl = gl;
|
||||
this.size = size;
|
||||
this.texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.texture);
|
||||
this.format = format ? format : gl.LUMINANCE;
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, size.w, size.h, 0, this.format, gl.UNSIGNED_BYTE, null);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
var textureIDs = null;
|
||||
Texture.prototype = {
|
||||
fill: function(textureData, useTexSubImage2D) {
|
||||
var gl = this.gl;
|
||||
assert(textureData.length >= this.size.w * this.size.h,
|
||||
"Texture size mismatch, data:" + textureData.length + ", texture: " + this.size.w * this.size.h);
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.texture);
|
||||
if (useTexSubImage2D) {
|
||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.size.w , this.size.h, this.format, gl.UNSIGNED_BYTE, textureData);
|
||||
} else {
|
||||
// texImage2D seems to be faster, thus keeping it as the default
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.size.w, this.size.h, 0, this.format, gl.UNSIGNED_BYTE, textureData);
|
||||
}
|
||||
},
|
||||
bind: function(n, program, name) {
|
||||
var gl = this.gl;
|
||||
if (!textureIDs) {
|
||||
textureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2];
|
||||
}
|
||||
gl.activeTexture(textureIDs[n]);
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.texture);
|
||||
gl.uniform1i(gl.getUniformLocation(program.program, name), n);
|
||||
}
|
||||
};
|
||||
module.exports = Texture;
|
||||
|
261
tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js
Normal file
261
tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js
Normal file
|
@ -0,0 +1,261 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Generic WebGL backed canvas that sets up: a quad to paint a texture on, appropriate vertex/fragment shaders,
|
||||
* scene parameters and other things. Specialized versions of this class can be created by overriding several
|
||||
* initialization methods.
|
||||
|
||||
*/
|
||||
|
||||
var Script = require('./Script');
|
||||
var error = require('../utils/error');
|
||||
var makePerspective = require('../utils/glUtils').makePerspective;
|
||||
var Matrix = require('sylvester.js').Matrix;
|
||||
var Class = require('uclass');
|
||||
|
||||
|
||||
var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", `
|
||||
attribute vec3 aVertexPosition;
|
||||
attribute vec2 aTextureCoord;
|
||||
uniform mat4 uMVMatrix;
|
||||
uniform mat4 uPMatrix;
|
||||
varying highp vec2 vTextureCoord;
|
||||
void main(void) {
|
||||
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
|
||||
vTextureCoord = aTextureCoord;
|
||||
}
|
||||
`);
|
||||
|
||||
var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", `
|
||||
precision highp float;
|
||||
varying highp vec2 vTextureCoord;
|
||||
uniform sampler2D texture;
|
||||
void main(void) {
|
||||
gl_FragColor = texture2D(texture, vTextureCoord);
|
||||
}
|
||||
`);
|
||||
|
||||
var WebGLCanvas = new Class({
|
||||
|
||||
initialize : function(canvas, size, useFrameBuffer) {
|
||||
|
||||
this.canvas = canvas;
|
||||
this.size = size;
|
||||
this.canvas.width = size.w;
|
||||
this.canvas.height = size.h;
|
||||
|
||||
this.onInitWebGL();
|
||||
this.onInitShaders();
|
||||
this.initBuffers();
|
||||
|
||||
if (useFrameBuffer)
|
||||
this.initFramebuffer();
|
||||
|
||||
this.onInitTextures();
|
||||
this.initScene();
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a frame buffer so that we can render off-screen.
|
||||
*/
|
||||
initFramebuffer : function() {
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
// Create framebuffer object and texture.
|
||||
this.framebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
|
||||
this.framebufferTexture = new Texture(this.gl, this.size, gl.RGBA);
|
||||
|
||||
// Create and allocate renderbuffer for depth data.
|
||||
var renderbuffer = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.w, this.size.h);
|
||||
|
||||
// Attach texture and renderbuffer to the framebuffer.
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.framebufferTexture.texture, 0);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer);
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize vertex and texture coordinate buffers for a plane.
|
||||
*/
|
||||
initBuffers : function () {
|
||||
var tmp;
|
||||
var gl = this.gl;
|
||||
|
||||
// Create vertex position buffer.
|
||||
this.quadVPBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer);
|
||||
tmp = [
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
1.0, -1.0, 0.0,
|
||||
-1.0, -1.0, 0.0];
|
||||
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW);
|
||||
this.quadVPBuffer.itemSize = 3;
|
||||
this.quadVPBuffer.numItems = 4;
|
||||
|
||||
/*
|
||||
+--------------------+
|
||||
| -1,1 (1) | 1,1 (0)
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| -1,-1 (3) | 1,-1 (2)
|
||||
+--------------------+
|
||||
*/
|
||||
|
||||
var scaleX = 1.0;
|
||||
var scaleY = 1.0;
|
||||
|
||||
// Create vertex texture coordinate buffer.
|
||||
this.quadVTCBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer);
|
||||
tmp = [
|
||||
scaleX, 0.0,
|
||||
0.0, 0.0,
|
||||
scaleX, scaleY,
|
||||
0.0, scaleY,
|
||||
];
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW);
|
||||
},
|
||||
|
||||
|
||||
mvIdentity : function () {
|
||||
this.mvMatrix = Matrix.I(4);
|
||||
},
|
||||
|
||||
mvMultiply : function(m) {
|
||||
this.mvMatrix = this.mvMatrix.x(m);
|
||||
},
|
||||
|
||||
mvTranslate : function (m) {
|
||||
this.mvMultiply(Matrix.Translation($V([m[0], m[1], m[2]])).ensure4x4());
|
||||
},
|
||||
|
||||
setMatrixUniforms : function () {
|
||||
this.program.setMatrixUniform("uPMatrix", new Float32Array(this.perspectiveMatrix.flatten()));
|
||||
this.program.setMatrixUniform("uMVMatrix", new Float32Array(this.mvMatrix.flatten()));
|
||||
},
|
||||
|
||||
initScene : function() {
|
||||
var gl = this.gl;
|
||||
|
||||
// Establish the perspective with which we want to view the
|
||||
// scene. Our field of view is 45 degrees, with a width/height
|
||||
// ratio of 640:480, and we only want to see objects between 0.1 units
|
||||
// and 100 units away from the camera.
|
||||
|
||||
this.perspectiveMatrix = makePerspective(45, 1, 0.1, 100.0);
|
||||
|
||||
// Set the drawing position to the "identity" point, which is
|
||||
// the center of the scene.
|
||||
this.mvIdentity();
|
||||
|
||||
// Now move the drawing position a bit to where we want to start
|
||||
// drawing the square.
|
||||
this.mvTranslate([0.0, 0.0, -2.4]);
|
||||
|
||||
// Draw the cube by binding the array buffer to the cube's vertices
|
||||
// array, setting attributes, and pushing it to GL.
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer);
|
||||
gl.vertexAttribPointer(this.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Set the texture coordinates attribute for the vertices.
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer);
|
||||
gl.vertexAttribPointer(this.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
this.onInitSceneTextures();
|
||||
|
||||
this.setMatrixUniforms();
|
||||
|
||||
if (this.framebuffer) {
|
||||
console.log("Bound Frame Buffer");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
toString: function() {
|
||||
return "WebGLCanvas Size: " + this.size;
|
||||
},
|
||||
|
||||
checkLastError: function (operation) {
|
||||
var err = this.gl.getError();
|
||||
if (err != this.gl.NO_ERROR) {
|
||||
var name = this.glNames[err];
|
||||
name = (name !== undefined) ? name + "(" + err + ")":
|
||||
("Unknown WebGL ENUM (0x" + value.toString(16) + ")");
|
||||
if (operation) {
|
||||
console.log("WebGL Error: %s, %s", operation, name);
|
||||
} else {
|
||||
console.log("WebGL Error: %s", name);
|
||||
}
|
||||
console.trace();
|
||||
}
|
||||
},
|
||||
|
||||
onInitWebGL: function () {
|
||||
try {
|
||||
this.gl = this.canvas.getContext("experimental-webgl");
|
||||
} catch(e) {}
|
||||
|
||||
if (!this.gl) {
|
||||
error("Unable to initialize WebGL. Your browser may not support it.");
|
||||
}
|
||||
if (this.glNames) {
|
||||
return;
|
||||
}
|
||||
this.glNames = {};
|
||||
for (var propertyName in this.gl) {
|
||||
if (typeof this.gl[propertyName] == 'number') {
|
||||
this.glNames[this.gl[propertyName]] = propertyName;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onInitShaders: function() {
|
||||
this.program = new Program(this.gl);
|
||||
this.program.attach(new Shader(this.gl, vertexShaderScript));
|
||||
this.program.attach(new Shader(this.gl, fragmentShaderScript));
|
||||
this.program.link();
|
||||
this.program.use();
|
||||
this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition");
|
||||
this.gl.enableVertexAttribArray(this.vertexPositionAttribute);
|
||||
this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");;
|
||||
this.gl.enableVertexAttribArray(this.textureCoordAttribute);
|
||||
},
|
||||
|
||||
onInitTextures: function () {
|
||||
var gl = this.gl;
|
||||
this.texture = new Texture(gl, this.size, gl.RGBA);
|
||||
},
|
||||
|
||||
onInitSceneTextures: function () {
|
||||
this.texture.bind(0, this.program, "texture");
|
||||
},
|
||||
|
||||
drawScene: function() {
|
||||
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
||||
},
|
||||
|
||||
readPixels: function(buffer) {
|
||||
var gl = this.gl;
|
||||
gl.readPixels(0, 0, this.size.w, this.size.h, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
|
||||
},
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
module.exports = WebGLCanvas;
|
51
tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js
Normal file
51
tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
"use strict";
|
||||
var Class = require('uclass');
|
||||
|
||||
var YUVCanvas = new Class({
|
||||
|
||||
Binds : ['decode'],
|
||||
|
||||
initialize : function(canvas, size) {
|
||||
this.canvas = canvas;
|
||||
this.canvasCtx = this.canvas.getContext("2d");
|
||||
this.canvasBuffer = this.canvasCtx.createImageData(size.w, size.h);
|
||||
},
|
||||
|
||||
decode : function (buffer, width, height) {
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
var lumaSize = width * height;
|
||||
var chromaSize = lumaSize >> 2;
|
||||
|
||||
var ybuf = buffer.subarray(0, lumaSize);
|
||||
var ubuf = buffer.subarray(lumaSize, lumaSize + chromaSize);
|
||||
var vbuf = buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize);
|
||||
|
||||
for (var y = 0; y < height; y++) {
|
||||
for (var x = 0; x < width; x++) {
|
||||
var yIndex = x + y * width;
|
||||
var uIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2);
|
||||
var vIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2);
|
||||
var R = 1.164 * (ybuf[yIndex] - 16) + 1.596 * (vbuf[vIndex] - 128);
|
||||
var G = 1.164 * (ybuf[yIndex] - 16) - 0.813 * (vbuf[vIndex] - 128) - 0.391 * (ubuf[uIndex] - 128);
|
||||
var B = 1.164 * (ybuf[yIndex] - 16) + 2.018 * (ubuf[uIndex] - 128);
|
||||
|
||||
var rgbIndex = yIndex * 4;
|
||||
this.canvasBuffer.data[rgbIndex+0] = R;
|
||||
this.canvasBuffer.data[rgbIndex+1] = G;
|
||||
this.canvasBuffer.data[rgbIndex+2] = B;
|
||||
this.canvasBuffer.data[rgbIndex+3] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
this.canvasCtx.putImageData(this.canvasBuffer, 0, 0);
|
||||
|
||||
var date = new Date();
|
||||
//console.log("WSAvcPlayer: Decode time: " + (date.getTime() - this.rcvtime) + " ms");
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
module.exports = YUVCanvas;
|
108
tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js
Normal file
108
tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
"use strict";
|
||||
|
||||
var Program = require('./Program');
|
||||
var Shader = require('./Shader');
|
||||
var Texture = require('./Texture');
|
||||
var Script = require('./Script');
|
||||
var WebGLCanvas = require('./WebGLCanvas');
|
||||
|
||||
var Class = require('uclass');
|
||||
|
||||
var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", `
|
||||
attribute vec3 aVertexPosition;
|
||||
attribute vec2 aTextureCoord;
|
||||
uniform mat4 uMVMatrix;
|
||||
uniform mat4 uPMatrix;
|
||||
varying highp vec2 vTextureCoord;
|
||||
void main(void) {
|
||||
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
|
||||
vTextureCoord = aTextureCoord;
|
||||
}
|
||||
`);
|
||||
|
||||
|
||||
var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", `
|
||||
precision highp float;
|
||||
varying highp vec2 vTextureCoord;
|
||||
uniform sampler2D YTexture;
|
||||
uniform sampler2D UTexture;
|
||||
uniform sampler2D VTexture;
|
||||
const mat4 YUV2RGB = mat4
|
||||
(
|
||||
1.1643828125, 0, 1.59602734375, -.87078515625,
|
||||
1.1643828125, -.39176171875, -.81296875, .52959375,
|
||||
1.1643828125, 2.017234375, 0, -1.081390625,
|
||||
0, 0, 0, 1
|
||||
);
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB;
|
||||
}
|
||||
`);
|
||||
|
||||
|
||||
|
||||
|
||||
var YUVWebGLCanvas = new Class({
|
||||
Extends : WebGLCanvas,
|
||||
Binds : ['decode'],
|
||||
|
||||
initialize : function(canvas, size) {
|
||||
YUVWebGLCanvas.parent.initialize.call(this, canvas, size);
|
||||
},
|
||||
|
||||
onInitShaders: function() {
|
||||
this.program = new Program(this.gl);
|
||||
this.program.attach(new Shader(this.gl, vertexShaderScript));
|
||||
this.program.attach(new Shader(this.gl, fragmentShaderScript));
|
||||
this.program.link();
|
||||
this.program.use();
|
||||
this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition");
|
||||
this.gl.enableVertexAttribArray(this.vertexPositionAttribute);
|
||||
this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");;
|
||||
this.gl.enableVertexAttribArray(this.textureCoordAttribute);
|
||||
},
|
||||
|
||||
onInitTextures: function () {
|
||||
console.log("creatingTextures: size: " + this.size);
|
||||
this.YTexture = new Texture(this.gl, this.size);
|
||||
this.UTexture = new Texture(this.gl, this.size.getHalfSize());
|
||||
this.VTexture = new Texture(this.gl, this.size.getHalfSize());
|
||||
},
|
||||
|
||||
onInitSceneTextures: function () {
|
||||
this.YTexture.bind(0, this.program, "YTexture");
|
||||
this.UTexture.bind(1, this.program, "UTexture");
|
||||
this.VTexture.bind(2, this.program, "VTexture");
|
||||
},
|
||||
|
||||
fillYUVTextures: function(y, u, v) {
|
||||
this.YTexture.fill(y);
|
||||
this.UTexture.fill(u);
|
||||
this.VTexture.fill(v);
|
||||
},
|
||||
|
||||
decode: function(buffer, width, height) {
|
||||
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
var lumaSize = width * height;
|
||||
var chromaSize = lumaSize >> 2;
|
||||
|
||||
this.YTexture.fill(buffer.subarray(0, lumaSize));
|
||||
this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize));
|
||||
this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize));
|
||||
this.drawScene();
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return "YUVCanvas Size: " + this.size;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = YUVWebGLCanvas;
|
Loading…
Add table
Add a link
Reference in a new issue