/*
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 rgba8Kernel = `
__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('rgba8', width, height, rgba8Kernel, 'write')
this.interlaced = interlaced
this.numBits = 8
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
}
}
}