/**
 * Homebridge FFmpeg transcoding, decoding, and encoding options, selecting codecs, pixel formats, and hardware acceleration for the host system.
 *
 * This module defines interfaces and classes for specifying, adapting, and generating FFmpeg command-line arguments tailored to the host system's capabilities. It
 * automates the selection of codecs, pixel formats, hardware encoders/decoders, and streaming profiles for maximum compatibility and performance.
 *
 * Key features:
 *
 * - Encapsulates all FFmpeg transcoding and streaming options (including bitrate, resolution, framerate, H.264 profiles/levels, and quality optimizations).
 * - Detects and configures hardware-accelerated encoding and decoding (macOS VideoToolbox, Intel Quick Sync Video, and Raspberry Pi 4), falling back to software
 *   processing when required.
 * - Dynamically generates the appropriate FFmpeg command-line arguments for livestreaming, HomeKit Secure Video (HKSV) event recording, and crop filters.
 * - Provides strong TypeScript types and interfaces for reliable integration and extensibility in Homebridge.
 *
 * This module is intended for plugin authors and advanced users who need precise, robust control over FFmpeg processing pipelines, with platform-aware optimizations and
 * safe fallbacks.
 *
 * @module
 */
import { AudioRecordingCodecType, H264Level, H264Profile, type Logging } from "homebridge";
import type { FfmpegCodecs } from "./codecs.js";
import type { HomebridgePluginLogging } from "../util.js";
/**
 * Configuration options for `FfmpegOptions`, defining transcoding, decoding, logging, and hardware acceleration settings.
 *
 * @property codecSupport         - FFmpeg codec capabilities and hardware support.
 * @property crop                 - Optional. Cropping rectangle for output video.
 * @property debug                - Optional. Enable debug logging.
 * @property hardwareDecoding     - Enable hardware-accelerated video decoding if available.
 * @property hardwareTranscoding  - Enable hardware-accelerated video encoding if available.
 * @property log                  - Logging interface for output and errors.
 * @property name                 - Function returning the name or label for this options set.
 *
 * @remarks The `hardwareDecoding` and `hardwareTranscoding` flags are bidirectional. On input, they express the caller's desired hardware acceleration state. During
 * `FfmpegOptions` construction, the flags are resolved against the host's actual capabilities and the config object is mutated in place to reflect what is available.
 * After construction, these flags represent the resolved state...`hardwareDecoding` or `hardwareTranscoding` may be set to `false` if the required codecs or
 * accelerators are absent, or `hardwareDecoding` may be set to `true` if Intel Quick Sync Video is detected even when not explicitly requested.
 *
 * @example
 *
 * ```ts
 * const optionsConfig: FfmpegOptionsConfig = {
 *
 *   codecSupport: ffmpegCodecs,
 *   crop: { width: 1, height: 1, x: 0, y: 0 },
 *   debug: false,
 *   hardwareDecoding: true,
 *   hardwareTranscoding: true,
 *   log,
 *   name: () => "Camera"
 * };
 * ```
 *
 * @see FfmpegOptions
 *
 * @category FFmpeg
 */
export interface FfmpegOptionsConfig {
    codecSupport: FfmpegCodecs;
    crop?: {
        height: number;
        width: number;
        x: number;
        y: number;
    };
    debug?: boolean;
    hardwareDecoding: boolean;
    hardwareTranscoding: boolean;
    log: HomebridgePluginLogging | Logging;
    name: () => string;
}
/**
 * Options used for configuring video encoding in FFmpeg operations.
 *
 * These options control output bitrate, framerate, resolution, H.264 profile and level, input framerate, and smart quality optimizations.
 *
 * @property codec               - Optional. Audio codec to encode (`AudioRecordingCodecType.AAC_ELD` or `AudioRecordingCodecType.AAC_LC`). Defaults to
 *                                 `AudioRecordingCodecType.AAC_ELD`.
 *
 * @example
 *
 * ```ts
 * const encoderOptions: AudioEncoderOptions = {
 *
 *   codec: AudioRecordingCodecType.AAC_ELD
 * };
 *
 * // Use with FfmpegOptions for transcoding.
 * const ffmpegOpts = new FfmpegOptions(optionsConfig);
 * const args = ffmpegOpts.audioEncoder(encoderOptions);
 * ```
 *
 * @see FfmpegOptions
 *
 * @category FFmpeg
 */
export interface AudioEncoderOptions {
    codec?: AudioRecordingCodecType;
}
/**
 * Options used for configuring video encoding in FFmpeg operations.
 *
 * These options control output bitrate, framerate, resolution, H.264 profile and level, input framerate, and smart quality optimizations.
 *
 * @property bitrate             - Target video bitrate, in kilobits per second.
 * @property fps                 - Target output frames per second.
 * @property hardwareDecoding    - Optional. If `true`, encoder options will account for hardware decoding (primarily for Intel QSV scenarios). Defaults to `true`.
 * @property height              - Output video height, in pixels.
 * @property idrInterval         - Interval (in seconds) between keyframes (IDR frames).
 * @property inputFps            - Input (source) frames per second.
 * @property level               - H.264 profile level for output.
 * @property profile             - H.264 profile for output.
 * @property smartQuality        - Optional and applicable only when not using hardware acceleration. If `true`, enables smart quality and variable bitrate optimizations.
 *                                 Defaults to `true`.
 * @property width               - Output video width, in pixels.
 *
 * @example
 *
 * ```ts
 * const encoderOptions: VideoEncoderOptions = {
 *
 *   bitrate: 3000,
 *   fps: 30,
 *   hardwareDecoding: true,
 *   hardwareTranscoding: true,
 *   height: 1080,
 *   idrInterval: 2,
 *   inputFps: 30,
 *   level: H264Level.LEVEL4_0,
 *   profile: H264Profile.HIGH,
 *   smartQuality: true,
 *   width: 1920
 * };
 *
 * // Use with FfmpegOptions for transcoding or streaming.
 * const ffmpegOpts = new FfmpegOptions(optionsConfig);
 * const args = ffmpegOpts.streamEncoder(encoderOptions);
 * ```
 *
 * @see FfmpegOptions
 * @see {@link https://ffmpeg.org/ffmpeg-codecs.html | FFmpeg Codecs Documentation}
 *
 * @category FFmpeg
 */
export interface VideoEncoderOptions {
    bitrate: number;
    fps: number;
    hardwareDecoding?: boolean;
    hardwareTranscoding?: boolean;
    height: number;
    idrInterval: number;
    inputFps: number;
    level: H264Level;
    profile: H264Profile;
    smartQuality?: boolean;
    width: number;
}
/**
 * Provides Homebridge FFmpeg transcoding, decoding, and encoding options, selecting codecs, pixel formats, and hardware acceleration for the host system.
 *
 * This class generates and adapts FFmpeg command-line arguments for livestreaming and event recording, optimizing for system hardware and codec availability.
 *
 * @example
 *
 * ```ts
 * const ffmpegOpts = new FfmpegOptions(optionsConfig);
 *
 * // Generate video encoder arguments for streaming.
 * const encoderOptions: VideoEncoderOptions = {
 *
 *   bitrate: 3000,
 *   fps: 30,
 *   hardwareDecoding: true,
 *   hardwareTranscoding: true,
 *   height: 1080,
 *   idrInterval: 2,
 *   inputFps: 30,
 *   level: H264Level.LEVEL4_0,
 *   profile: H264Profile.HIGH,
 *   smartQuality: true,
 *   width: 1920
 * };
 * const args = ffmpegOpts.streamEncoder(encoderOptions);
 *
 * // Generate crop filter string, if cropping is enabled.
 * const crop = ffmpegOpts.cropFilter;
 * ```
 *
 * @see AudioEncoderOptions
 * @see VideoEncoderOptions
 * @see FfmpegCodecs
 * @see {@link https://ffmpeg.org/ffmpeg.html | FFmpeg Documentation}
 *
 * @category FFmpeg
 */
export declare class FfmpegOptions {
    /**
     * FFmpeg codec and hardware capabilities for the current host.
     *
     */
    readonly codecSupport: FfmpegCodecs;
    /**
     * The configuration options used to initialize this instance.
     */
    readonly config: FfmpegOptionsConfig;
    /**
     * Indicates if debug logging is enabled.
     */
    readonly debug: boolean;
    /**
     * Logging interface for output and errors.
     */
    readonly log: HomebridgePluginLogging | Logging;
    /**
     * Function returning the name for this options instance to be used for logging.
     */
    readonly name: () => string;
    /**
     * Creates an instance of Homebridge FFmpeg encoding and decoding options.
     *
     * @param options          - FFmpeg options configuration.
     *
     * @example
     *
     * ```ts
     * const ffmpegOpts = new FfmpegOptions(optionsConfig);
     * ```
     */
    constructor(options: FfmpegOptionsConfig);
    /**
     * Determines and configures hardware-accelerated video decoding and transcoding for the host system.
     *
     * This internal method checks for the availability of hardware codecs and accelerators based on the host platform and updates
     * FFmpeg options to use the best available hardware or falls back to software processing when necessary.
     * It logs warnings or errors if required codecs or hardware acceleration are unavailable.
     *
     * This method is called automatically by the `FfmpegOptions` constructor and is not intended to be called directly.
     *
     * @returns `true` if hardware-accelerated transcoding is enabled after configuration, otherwise `false`.
     *
     * @example
     *
     * ```ts
     * // This method is invoked by the FfmpegOptions constructor:
     * const ffmpegOpts = new FfmpegOptions(optionsConfig);
     *
     * // Hardware acceleration configuration occurs automatically.
     * // Developers typically do not need to call configureHwAccel() directly.
     * ```
     *
     * @see FfmpegCodecs
     * @see FfmpegOptions
     */
    private configureHwAccel;
    /**
     * Determines the required hardware transfer filters based on the decoding and encoding configuration.
     *
     * This method manages the transition between software and hardware processing contexts. When video data needs to move between the CPU and GPU for processing, we
     * provide the appropriate FFmpeg filters to handle that transfer efficiently.
     *
     * @param options - Video encoder options including hardware decoding and transcoding state.
     * @returns Array of filter strings for hardware upload or download operations.
     */
    private getHardwareTransferFilters;
    /**
     * Gets hardware device initialization options for encoders that need them.
     *
     * When we're using hardware encoding without hardware decoding, we need to initialize the hardware device context explicitly. This method provides the
     * platform-specific initialization arguments required by FFmpeg.
     *
     * @param options - Video encoder options.
     * @returns Array of FFmpeg arguments for hardware device initialization.
     */
    private getHardwareDeviceInit;
    /**
     * Returns the audio encoder arguments to use when transcoding.
     *
     * @param options  - Optional. The encoder options to use for generating FFmpeg arguments.
     * @returns Array of FFmpeg command-line arguments for audio encoding.
     *
     * @example
     *
     * ```ts
     * const args = ffmpegOpts.audioEncoder();
     * ```
     */
    audioEncoder(options?: AudioEncoderOptions): string[];
    /**
     * Returns the audio decoder to use when decoding.
     *
     * @returns The FFmpeg audio decoder string.
     */
    readonly audioDecoder: string;
    /**
     * Returns the video decoder arguments to use for decoding video.
     *
     * @param codec            - Optional. Codec to decode (`"av1"`, `"h264"` (default), or `"hevc"`).
     * @returns Array of FFmpeg command-line arguments for video decoding or an empty array if the codec isn't supported.
     *
     * @example
     *
     * ```ts
     * const args = ffmpegOpts.videoDecoder("h264");
     * ```
     */
    videoDecoder(codec?: string): string[];
    /**
     * Returns the platform-appropriate FFmpeg video filters needed to transfer hardware-decoded frames to system memory. When hardware decoding is active, decoded frames
     * may reside on the GPU and require explicit download before CPU-based filters (crop, scale, format conversion) can operate on them. Returns an empty array when
     * hardware decoding is disabled or when the platform handles the transfer implicitly (e.g. Raspberry Pi).
     *
     * @returns An array of FFmpeg filter strings to prepend to a video filter chain, or an empty array if no transfer is needed.
     */
    get hardwareDownloadFilters(): string[];
    /**
     * Returns the FFmpeg crop filter string, or a default no-op filter if cropping is disabled.
     *
     * @returns The crop filter string for FFmpeg.
     */
    get cropFilter(): string;
    /**
     * Generate the appropriate scale filter for the current platform. This method returns platform-specific scale filters to leverage hardware acceleration capabilities
     * where available.
     */
    private getScaleFilter;
    /**
     * Generates the default set of FFmpeg video encoder arguments for software transcoding using libx264.
     *
     * This method builds command-line options for the FFmpeg libx264 encoder based on the provided encoder options, including bitrate, H.264 profile and level, pixel
     * format, frame rate, buffer size, and optional smart quality settings. It is used internally when hardware-accelerated transcoding is not enabled or supported.
     *
     * @param options            - The encoder options to use for generating FFmpeg arguments.
     *
     * @returns An array of FFmpeg command-line arguments for software video encoding.
     *
     * @example
     *
     * ```ts
     * const encoderOptions: VideoEncoderOptions = {
     *
     *   bitrate: 2000,
     *   fps: 30,
     *   height: 720,
     *   idrInterval: 2,
     *   inputFps: 30,
     *   level: H264Level.LEVEL3_1,
     *   profile: H264Profile.MAIN,
     *   smartQuality: true,
     *   width: 1280
     * };
     *
     * const args = ffmpegOpts['defaultVideoEncoderOptions'](encoderOptions);
     * ```
     *
     * @see VideoEncoderOptions
     */
    private defaultVideoEncoderOptions;
    /**
     * Returns the video encoder options to use for HomeKit Secure Video (HKSV) event recording.
     *
     * @param options          - Encoder options to use.
     * @returns Array of FFmpeg command-line arguments for video encoding.
     */
    recordEncoder(options: VideoEncoderOptions): string[];
    /**
     * Returns the video encoder options to use when transcoding for livestreaming.
     *
     * @param options          - Encoder options to use.
     * @returns Array of FFmpeg command-line arguments for video encoding.
     *
     * @example
     *
     * ```ts
     * const args = ffmpegOpts.streamEncoder(encoderOptions);
     * ```
     */
    streamEncoder(options: VideoEncoderOptions): string[];
    /**
     * Returns the maximum pixel count supported by a specific hardware encoder on the host system, or `Infinity` if not limited.
     *
     * @returns Maximum supported pixel count.
     */
    get hostSystemMaxPixels(): number;
    /**
     * Converts a HomeKit H.264 level enum value to the corresponding FFmpeg string or numeric representation.
     *
     * This helper is used to translate between HomeKit's `H264Level` enum and the string or numeric format expected by FFmpeg's `-level:v` argument.
     *
     * @param level        - The H.264 level to translate.
     * @param numeric      - Optional. If `true`, returns the numeric representation (e.g., "31"). If `false` or omitted, returns the standard string format (e.g., "3.1").
     *
     * @returns The FFmpeg-compatible H.264 level string or numeric value.
     *
     * @example
     *
     * ```ts
     * ffmpegOpts['getH264Level'](H264Level.LEVEL3_1);      // "3.1"
     *
     * ffmpegOpts['getH264Level'](H264Level.LEVEL4_0, true); // "40"
     * ```
     *
     * @see H264Level
     */
    private getH264Level;
    /**
     * Converts a HomeKit H.264 profile enum value to the corresponding FFmpeg string or numeric representation.
     *
     * This helper is used to translate between HomeKit's `H264Profile` enum and the string or numeric format expected by FFmpeg's `-profile:v` argument.
     *
     * @param profile - The H.264 profile to translate.
     * @param numeric - Optional. If `true`, returns the numeric representation (e.g., "100"). If `false` or omitted, returns the standard string format (e.g., "high").
     *
     * @returns The FFmpeg-compatible H.264 profile string or numeric value.
     *
     * @example
     *
     * ```ts
     * ffmpegOpts['getH264Profile'](H264Profile.HIGH);      // "high"
     *
     * ffmpegOpts['getH264Profile'](H264Profile.BASELINE, true); // "66"
     * ```
     *
     * @see H264Profile
     */
    private getH264Profile;
}
