/**
 * Streaming Encoder Service
 *
 * Pipes frame screenshot buffers directly to FFmpeg's stdin via `-f image2pipe`
 * instead of writing them to disk and reading them back in a separate encode
 * stage. Inspired by Remotion's approach to browser-based video rendering.
 *
 * Two building blocks:
 *   1. Frame reorder buffer – ensures out-of-order parallel workers feed
 *      frames to FFmpeg stdin in sequential order.
 *   2. Streaming FFmpeg encoder – spawns FFmpeg with `-f image2pipe` and
 *      exposes an async `writeFrame(buffer)` + `close()` API.
 */
import { type GpuEncoder } from "../utils/gpuEncoder.js";
import { type EngineConfig } from "../config.js";
import { type Fps } from "@hyperframes/core";
export type { EncoderOptions } from "./chunkEncoder.types.js";
export interface FrameReorderBuffer {
    waitForFrame: (frame: number) => Promise<void>;
    advanceTo: (frame: number) => void;
    waitForAllDone: () => Promise<void>;
    /**
     * Reject every parked and future waiter with `err`. Required by the
     * interleaved parallel drain: when one worker fails (e.g. drawElement
     * self-verification), its frames will never be written — peers parked in
     * waitForFrame would otherwise deadlock the whole capture (the worker pool
     * awaits ALL workers before surfacing the failure).
     */
    abort: (err: Error) => void;
}
export declare function createFrameReorderBuffer(startFrame: number, endFrame: number): FrameReorderBuffer;
export interface StreamingEncoderOptions {
    /** Frame rate as an exact rational; see `Fps` in @hyperframes/core. */
    fps: Fps;
    width: number;
    height: number;
    codec?: "h264" | "h265" | "vp9" | "prores";
    preset?: string;
    quality?: number;
    bitrate?: string;
    pixelFormat?: string;
    /** libvpx-vp9 -cpu-used value. Defaults to the engine VP9 setting. */
    vp9CpuUsed?: number;
    useGpu?: boolean;
    imageFormat?: "jpeg" | "png";
    hdr?: {
        transfer: import("../utils/hdr.js").HdrTransfer;
    };
    /** When set, use rawvideo input instead of image2pipe. For HDR PQ-encoded frames. */
    rawInputFormat?: "rgb48le";
}
export interface StreamingEncoderResult {
    success: boolean;
    durationMs: number;
    fileSize: number;
    error?: string;
}
export interface StreamingEncoder {
    /**
     * Write one frame to FFmpeg stdin, awaiting `drain` when the pipe is full
     * so back-pressure propagates to the caller. Resolves `false` when FFmpeg
     * is already gone. Callers must serialize calls — one in-flight writeFrame
     * per encoder (the frame reorder buffer provides this ordering); concurrent
     * calls would interleave frame bytes on the pipe and race the drain wait.
     */
    writeFrame: (buffer: Buffer) => Promise<boolean>;
    close: () => Promise<StreamingEncoderResult>;
    getExitStatus: () => "running" | "success" | "error";
    /**
     * The FFmpeg failure reason (exit code + tail of stderr), or `undefined`
     * while the process is still running / exited cleanly. Lets a `writeFrame`
     * that returned `false` because FFmpeg died surface WHY it died (bad args,
     * unsupported codec, disk full) instead of a bare "encoder exited" message.
     */
    getExitError: () => string | undefined;
}
/**
 * Build FFmpeg args for streaming (image2pipe) input.
 * Reuses the same codec/quality/GPU logic as chunkEncoder's buildEncoderArgs
 * but with `-f image2pipe` instead of `-i <pattern>`.
 *
 * Exported so unit tests can assert on the constructed CLI without spawning
 * FFmpeg — see streamingEncoder.test.ts.
 */
export declare function buildStreamingArgs(options: StreamingEncoderOptions, outputPath: string, gpuEncoder?: GpuEncoder): string[];
/**
 * Spawn a streaming FFmpeg encoder that accepts frame buffers on stdin.
 */
export declare function spawnStreamingEncoder(outputPath: string, options: StreamingEncoderOptions, signal?: AbortSignal, config?: Partial<Pick<EngineConfig, "ffmpegStreamingTimeout">>): Promise<StreamingEncoder>;
//# sourceMappingURL=streamingEncoder.d.ts.map