初始化
This commit is contained in:
66
vendor/tinyh264/YUVWebGLCanvas.ts
vendored
Normal file
66
vendor/tinyh264/YUVWebGLCanvas.ts
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* based on tinyh264 demo: https://github.com/udevbe/tinyh264/tree/master/demo
|
||||
*/
|
||||
|
||||
import YUVSurfaceShader from './YUVSurfaceShader';
|
||||
import Texture from '../h264-live-player/Texture';
|
||||
import Canvas from './Canvas';
|
||||
|
||||
export default class YUVWebGLCanvas extends Canvas {
|
||||
private yTexture: Texture;
|
||||
private uTexture: Texture;
|
||||
private vTexture: Texture;
|
||||
private yuvSurfaceShader: YUVSurfaceShader;
|
||||
|
||||
constructor(canvas: HTMLCanvasElement) {
|
||||
super(canvas);
|
||||
const gl = canvas.getContext('experimental-webgl', {
|
||||
preserveDrawingBuffer: true,
|
||||
}) as WebGLRenderingContext | null;
|
||||
if (!gl) {
|
||||
throw new Error('Unable to initialize WebGL. Your browser may not support it.');
|
||||
}
|
||||
this.yuvSurfaceShader = YUVSurfaceShader.create(gl);
|
||||
this.yTexture = Texture.create(gl, gl.LUMINANCE);
|
||||
this.uTexture = Texture.create(gl, gl.LUMINANCE);
|
||||
this.vTexture = Texture.create(gl, gl.LUMINANCE);
|
||||
}
|
||||
|
||||
decode(buffer: Uint8Array, width: number, height: number): void {
|
||||
this.canvas.width = width;
|
||||
this.canvas.height = height;
|
||||
|
||||
// the width & height returned are actually padded, so we have to use the frame size to get the real image dimension
|
||||
// when uploading to texture
|
||||
const stride = width; // stride
|
||||
// height is padded with filler rows
|
||||
|
||||
// if we knew the size of the video before encoding, we could cut out the black filler pixels. We don't, so just set
|
||||
// it to the size after encoding
|
||||
const sourceWidth = width;
|
||||
const sourceHeight = height;
|
||||
const maxXTexCoord = sourceWidth / stride;
|
||||
const maxYTexCoord = sourceHeight / height;
|
||||
|
||||
const lumaSize = stride * height;
|
||||
const chromaSize = lumaSize >> 2;
|
||||
|
||||
const yBuffer = buffer.subarray(0, lumaSize);
|
||||
const uBuffer = buffer.subarray(lumaSize, lumaSize + chromaSize);
|
||||
const vBuffer = buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize);
|
||||
|
||||
const chromaHeight = height >> 1;
|
||||
const chromaStride = stride >> 1;
|
||||
|
||||
// we upload the entire image, including stride padding & filler rows. The actual visible image will be mapped
|
||||
// from texture coordinates as to crop out stride padding & filler rows using maxXTexCoord and maxYTexCoord.
|
||||
|
||||
this.yTexture.image2dBuffer(yBuffer, stride, height);
|
||||
this.uTexture.image2dBuffer(uBuffer, chromaStride, chromaHeight);
|
||||
this.vTexture.image2dBuffer(vBuffer, chromaStride, chromaHeight);
|
||||
|
||||
this.yuvSurfaceShader.setTexture(this.yTexture, this.uTexture, this.vTexture);
|
||||
this.yuvSurfaceShader.updateShaderData({ w: width, h: height }, { maxXTexCoord, maxYTexCoord });
|
||||
this.yuvSurfaceShader.draw();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user