// This Source Code Form is subject to the terms of the Mozilla Public
// License, v2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/
import { fromMicros } from "@foxglove/rostime";
import { estimateObjectSize } from "@foxglove/studio-base/players/messageMemoryEstimation.js";
import { ensureWebCodecsSupported } from "../../../utils/compatibility.js";
import { parseMessage, parsePixelFormat } from "../../utils.js";
function createVideoDecoder({ topic, callback, topicDecoders }) {
    return new VideoDecoder({
        output: async (frame) => {
            const buffer = new Uint8Array(frame.allocationSize());
            await frame.copyTo(buffer);
            const receiveTime = topicDecoders.get(topic)?.timing.get(frame.timestamp)
                ??
                    fromMicros(frame.timestamp);
            const [encoding, step] = parsePixelFormat(frame.format);
            const foxgloveMessage = {
                timestamp: receiveTime,
                frame_id: `h265-${topic}-frame`,
                width: frame.displayWidth,
                height: frame.displayHeight,
                data: buffer,
                encoding,
                step: frame.displayWidth * step
            };
            callback({
                topic,
                receiveTime,
                message: foxgloveMessage,
                sizeInBytes: estimateObjectSize(foxgloveMessage),
                schemaName: "foxglove.RawImage"
            });
            frame.close();
        },
        error: console.error
    });
}
export async function deserializeEncodedFrameH265({ topic, message, topicDecoders, callback }) {
    const { receiveTime } = parseMessage(message);
    const supported = ensureWebCodecsSupported("VideoDecoder");
    if (!supported) {
        return;
    }
    if (!topicDecoders.has(topic)) {
        const decoder = createVideoDecoder({ topic, callback, topicDecoders });
        decoder.configure({
            codec: "hev1.1.6.L93.B0",
            optimizeForLatency: true
        });
        topicDecoders.set(topic, {
            decoder,
            timing: new Map()
        });
    }
    const decoderInfo = topicDecoders.get(topic);
    if (!decoderInfo) {
        return;
    }
    if (decoderInfo.decoder.decodeQueueSize > 60) {
        decoderInfo.decoder.reset();
        return;
    }
    const microTimestamp = receiveTime.sec * 1_000_000 + Math.floor(receiveTime.nsec / 1_000);
    decoderInfo.timing.set(microTimestamp, receiveTime);
    const frame = {
        type: 'key',
        data: message.data,
        timestamp: microTimestamp
    };
    try {
        const chunk = new EncodedVideoChunk(frame);
        decoderInfo.decoder.decode(chunk);
    }
    catch {
        topicDecoders.delete(topic);
    }
}
//# sourceMappingURL=h265.js.map