From 4b8670855c7c2e8b7f55679399227c7d39f1d129 Mon Sep 17 00:00:00 2001 From: Julian Waller Date: Thu, 15 Aug 2024 22:24:15 +0100 Subject: [PATCH] wip: downloadStill --- src/atem.ts | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/atem.ts b/src/atem.ts index f912ba4f..f0b699ca 100644 --- a/src/atem.ts +++ b/src/atem.ts @@ -19,7 +19,7 @@ import { InputChannel } from './state/input' import { DownstreamKeyerGeneral, DownstreamKeyerMask } from './state/video/downstreamKeyers' import * as DT from './dataTransfer' import * as Util from './lib/atemUtil' -import { getVideoModeInfo } from './lib/videoMode' +import { VideoModeInfo, getVideoModeInfo } from './lib/videoMode' import * as Enums from './enums' import { ClassicAudioMonitorChannel, @@ -56,6 +56,8 @@ import { TimeInfo } from './state/info' import { SomeAtemAudioLevels } from './state/levels' import { generateUploadBufferInfo, UploadBufferInfo } from './dataTransfer/dataTransferUploadBuffer' import { convertWAVToRaw } from './lib/converters/wavAudio' +import { decodeRLE } from './lib/converters/rle' +import { convertYUV422ToRGBA } from './lib/converters/yuv422ToRgba' export interface AtemOptions { address?: string @@ -147,6 +149,12 @@ export class BasicAtem extends EventEmitter { return this._state } + get videoMode(): Readonly | undefined { + if (!this.state) return undefined + + return getVideoModeInfo(this.state.settings.videoMode) + } + public async connect(address: string, port?: number): Promise { return this.socket.connect(address, port) } @@ -758,18 +766,24 @@ export class Atem extends BasicAtem { } public async downloadStill(index: number, format: 'raw' | 'rgba' | 'yuv' = 'rgba'): Promise { - const rawBuffer = this.dataTransferManager.downloadStill(index) + let rawBuffer = await this.dataTransferManager.downloadStill(index) + + if (format === 'raw') { + return rawBuffer + } + + if (!this.state) throw new Error('Unable to check current resolution') + const resolution = getVideoModeInfo(this.state.settings.videoMode) + if (!resolution) throw new Error('Failed to determine required resolution') + + rawBuffer = decodeRLE(rawBuffer, resolution.width * resolution.height * 4) switch (format) { - case 'raw': - return rawBuffer case 'yuv': - // TODO - decode rle return rawBuffer case 'rgba': default: - // TODO - decode rle and convert to rgba - return rawBuffer + return convertYUV422ToRGBA(resolution.width, resolution.height, rawBuffer) } }