/* Phaneron - Clustered, accelerated and cloud-fit video server, pre-assembled and in kit form. Copyright (C) 2020 Streampunk Media Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . https://www.streampunk.media/ mailto:furnace@streampunk.media 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K. */ import { PackImpl, Interlace } from './packer' import { KernelParams, OpenCLBuffer } from 'nodencl' const bgra8Kernel = ` __kernel void read(__global uchar4* restrict input, __global float4* restrict output, __private unsigned int width, __global float* restrict gammaLut, __constant float4* restrict gamutMatrix) { uint item = get_global_id(0); bool lastItemOnLine = get_local_id(0) == get_local_size(0) - 1; // 64 output pixels per workItem uint numPixels = lastItemOnLine && (0 != width % 64) ? width % 64 : 64; uint numLoops = numPixels; uint inOff = 64 * item; uint outOff = width * get_group_id(0) + get_local_id(0) * 64; // optimise loading of the 3x3 gamut matrix float4 gamutMat0 = gamutMatrix[0]; float4 gamutMat1 = gamutMatrix[1]; float4 gamutMat2 = gamutMatrix[2]; float3 gamutMatR = (float3)(gamutMat0.s0, gamutMat0.s1, gamutMat0.s2); float3 gamutMatG = (float3)(gamutMat0.s3, gamutMat1.s0, gamutMat1.s1); float3 gamutMatB = (float3)(gamutMat1.s2, gamutMat1.s3, gamutMat2.s0); for (uint i=0; i = params.sources as Array if (srcArray.length !== 1) throw new Error(`Reader for ${this.name} requires 'sources' parameter with 1 OpenCL buffer`) return { input: srcArray[0], output: params.dest, width: this.width, gammaLut: params.gammaLut, gamutMatrix: params.gamutMatrix } } } export class Writer extends PackImpl { constructor(width: number, height: number, interlaced: boolean) { super('bgra8', width, height, bgra8Kernel, 'write') this.interlaced = interlaced this.numBits = 8 this.lumaBlack = 16 this.lumaWhite = 235 this.chromaRange = 224 this.numBytes = [getPitchBytes(this.width) * this.height] this.workItemsPerGroup = getPitch(this.width) / pixelsPerWorkItem this.globalWorkItems = (this.workItemsPerGroup * this.height) / (this.interlaced ? 2 : 1) } getKernelParams(params: KernelParams): KernelParams { const dstArray: Array = params.dests as Array if (dstArray.length !== 1) throw new Error(`Writer for ${this.name} requires 'dests' parameter with 1 OpenCL buffer`) return { input: params.source, output: dstArray[0], width: this.width, interlace: this.interlaced ? (params.interlace as Interlace) : Interlace.Progressive, gammaLut: params.gammaLut } } }