/*
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 { clContext as nodenCLContext, OpenCLBuffer, ImageDims } from 'nodencl'
import { Loader, Saver } from './loadSave'
import { PackImpl, Interlace } from './packer'
import { ClJobs } from '../clJobQueue'
export class ToRGBA {
private readonly clContext: nodenCLContext
private readonly loader: Loader
private readonly numBytes: Array
private readonly numBytesRGBA: number
private readonly totalBytes: number
constructor(
clContext: nodenCLContext,
colSpecRead: string,
colSpecWrite: string,
readImpl: PackImpl,
clJobs: ClJobs
) {
this.clContext = clContext
this.loader = new Loader(this.clContext, colSpecRead, colSpecWrite, readImpl, clJobs)
this.numBytes = readImpl.getNumBytes()
this.numBytesRGBA = readImpl.getNumBytesRGBA()
this.totalBytes = readImpl.getTotalBytes()
}
async init(): Promise {
await this.loader.init()
}
getNumBytes(): Array {
return this.numBytes
}
getNumBytesRGBA(): number {
return this.numBytesRGBA
}
getTotalBytes(): number {
return this.totalBytes
}
async createSources(): Promise> {
return Promise.all(
this.numBytes.map((bytes) =>
this.clContext.createBuffer(bytes, 'readonly', 'coarse', undefined, 'ToRGBA src')
)
)
}
async createDest(imageDims: ImageDims): Promise {
return this.clContext.createBuffer(this.numBytesRGBA, 'readonly', 'coarse', imageDims, 'ToRGBA')
}
async loadFrame(
input: Buffer | Array,
sources: Array,
clQueue?: number | undefined
): Promise {
const inputs = Array.isArray(input) ? input : [input]
if (sources.length !== inputs.length)
throw new Error(`Expected buffer array of ${sources.length} sources, found ${inputs.length}`)
for (let i = 0; i < inputs.length; ++i) {
await sources[i].hostAccess(
'writeonly',
clQueue ? clQueue : 0,
inputs[i].slice(0, this.numBytes[i])
)
await sources[i].hostAccess('none', clQueue ? clQueue : 0)
}
return Promise.resolve()
}
processFrame(sourceID: string, sources: Array, dest: OpenCLBuffer): void {
return this.loader.run(
{ sources: sources, dest: dest },
{
source: sourceID,
timestamp: sources[0].timestamp
},
() => sources.forEach((s) => s.release())
)
}
finish(): void {
this.loader.releaseRefs()
}
}
export class FromRGBA {
private readonly clContext: nodenCLContext
private readonly saver: Saver
private readonly numBytes: Array
private readonly numBytesRGBA: number
private readonly totalBytes: number
constructor(clContext: nodenCLContext, colSpecRead: string, writeImpl: PackImpl, clJobs: ClJobs) {
this.clContext = clContext
this.saver = new Saver(this.clContext, colSpecRead, writeImpl, clJobs)
this.numBytes = writeImpl.getNumBytes()
this.numBytesRGBA = writeImpl.getNumBytesRGBA()
this.totalBytes = writeImpl.getTotalBytes()
}
async init(): Promise {
await this.saver.init()
}
getNumBytes(): Array {
return this.numBytes
}
getNumBytesRGBA(): number {
return this.numBytesRGBA
}
getTotalBytes(): number {
return this.totalBytes
}
async createDests(): Promise> {
return Promise.all(
this.numBytes.map((bytes) =>
this.clContext.createBuffer(bytes, 'writeonly', 'coarse', undefined, 'FromRGBA')
)
)
}
processFrame(
sourceID: string,
source: OpenCLBuffer,
dests: Array,
interlace?: Interlace
): void {
this.saver.run(
{ source: source, dests: dests, interlace: interlace },
{ source: sourceID, timestamp: source.timestamp },
() => source.release()
)
}
async saveFrame(
output: OpenCLBuffer | Array,
clQueue?: number | undefined
): Promise {
const outputs = Array.isArray(output) ? output : [output]
for (let o = 0; o < outputs.length; ++o)
await outputs[o].hostAccess('readonly', clQueue ? clQueue : 0)
return Promise.resolve()
}
finish(): void {
this.saver.releaseRefs()
}
}