/**
 * RTP and RTCP packet demultiplexer and UDP port management for FFmpeg-based HomeKit livestreaming.
 *
 * This module supplies classes and helpers to support realtime streaming via FFmpeg in Homebridge and similar HomeKit environments. It enables the demultiplexing of RTP
 * and RTCP packets on a single UDP port, as required by HomeKit and RFC 5761, working around FFmpeg’s lack of native support for RTP/RTCP multiplexing. It also manages
 * the allocation and tracking of UDP ports for RTP and RTCP, helping prevent conflicts in dynamic, multi-session streaming scenarios.
 *
 * Key features:
 *
 * - Demultiplexes RTP and RTCP packets received on a single UDP port, forwarding them to the correct FFmpeg destinations for HomeKit livestream compatibility.
 * - Injects periodic heartbeat messages to keep two-way audio streams alive with FFmpeg’s strict timeout requirements.
 * - Dynamically allocates and reserves UDP ports for RTP/RTCP, supporting consecutive port pairing for correct FFmpeg operation.
 * - Event-driven architecture for integration with plugin or automation logic.
 *
 * Designed for plugin developers and advanced users implementing HomeKit livestreaming, audio/video bridging, or similar applications requiring precise RTP/RTCP handling
 * with FFmpeg.
 *
 * @module
 */
import { EventEmitter } from "node:events";
import type { HomebridgePluginLogging } from "../util.js";
/**
 * Utility for demultiplexing RTP and RTCP packets on a single UDP port for HomeKit compatibility.
 *
 * FFmpeg does not support multiplexing RTP and RTCP data on a single UDP port (RFC 5761) and HomeKit requires this for livestreaming. This class listens on a UDP port
 * and demultiplexes RTP and RTCP traffic, forwarding them to separate RTP and RTCP ports as required by FFmpeg.
 *
 * Credit to [dgreif](https://github.com/dgreif), [brandawg93](https://github.com/brandawg93), and [Sunoo](https://github.com/Sunoo) for foundational ideas and
 * collaboration.
 *
 * @example
 *
 * ```ts
 * // Create an RtpDemuxer to split packets for FFmpeg compatibility.
 * const demuxer = new RtpDemuxer("ipv4", 50000, 50002, 50004, log);
 *
 * // Close the demuxer when finished.
 * demuxer.close();
 * ```
 *
 * @see {@link https://tools.ietf.org/html/rfc5761 | RFC 5761}
 * @see {@link https://github.com/homebridge/homebridge-camera-ffmpeg | homebridge-camera-ffmpeg}
 *
 * @category FFmpeg
 */
export declare class RtpDemuxer extends EventEmitter {
    private heartbeatTimer?;
    private heartbeatMsg?;
    private _isRunning;
    private log?;
    private inputPort;
    readonly socket: import("node:dgram").Socket;
    /**
     * Constructs a new RtpDemuxer for a specified IP family and port set.
     *
     * @param ipFamily         - The IP family: "ipv4" or "ipv6".
     * @param inputPort        - The UDP port to listen on for incoming packets.
     * @param rtcpPort         - The UDP port to forward RTCP packets to.
     * @param rtpPort          - The UDP port to forward RTP packets to.
     * @param log              - Logger instance for debug and error messages.
     *
     * @example
     *
     * ```ts
     * const demuxer = new RtpDemuxer("ipv4", 50000, 50002, 50004, log);
     * ```
     */
    constructor(ipFamily: ("ipv4" | "ipv6"), inputPort: number, rtcpPort: number, rtpPort: number, log: HomebridgePluginLogging);
    /**
     * Sends periodic heartbeat messages to the RTP port to keep the FFmpeg process alive.
     *
     * This is necessary because FFmpeg times out input streams if it does not receive data for more than five seconds.
     *
     * @param port - The RTP port to send the heartbeat to.
     */
    private heartbeat;
    /**
     * Closes the demuxer, its socket, and any heartbeat timers.
     *
     * @example
     *
     * ```ts
     * demuxer.close();
     * ```
     */
    close(): void;
    /**
     * Extracts the RTP payload type from a UDP packet.
     *
     * Used internally to distinguish RTP from RTCP messages.
     *
     * @param message - The UDP packet buffer.
     *
     * @returns The RTP payload type as a number.
     */
    private getPayloadType;
    /**
     * Determines if the provided UDP packet is an RTP message.
     *
     * @param message - The UDP packet buffer.
     *
     * @returns `true` if the packet is RTP, `false` if RTCP.
     */
    private isRtpMessage;
    /**
     * Indicates if the demuxer is running and accepting packets.
     *
     * @returns `true` if running, otherwise `false`.
     *
     * @example
     *
     * ```ts
     * if(demuxer.isRunning) {
     *   // Demuxer is active.
     * }
     * ```
     */
    get isRunning(): boolean;
}
/**
 * Allocates and tracks UDP ports for RTP and RTCP to avoid port conflicts in environments with high network activity.
 *
 * This utility class is used to find and reserve available UDP ports for demuxing FFmpeg streams or other network activities.
 *
 * @example
 *
 * ```ts
 * const allocator = new RtpPortAllocator();
 *
 * // Reserve two consecutive ports for RTP and RTCP.
 * const rtpPort = await allocator.reserve("ipv4", 2);
 *
 * // Cancel reservation if not needed.
 * allocator.cancel(rtpPort);
 * ```
 *
 * @category FFmpeg
 */
export declare class RtpPortAllocator {
    private portsInUse;
    /**
     * Instantiates a new RTP port allocator and tracker.
     */
    constructor();
    /**
     * Finds an available UDP port by attempting to bind a new socket.
     *
     * Loops until an available port not already marked as in use is found.
     *
     * @param ipFamily         - "ipv4" or "ipv6".
     * @param port             - Optional. The port to try to bind to. If 0, selects a random port.
     *
     * @returns A promise resolving to the available port number, or `-1` on error.
     */
    private getPort;
    /**
     * Internal method to reserve one or two consecutive UDP ports for FFmpeg or network use.
     *
     * If two ports are reserved, ensures they are consecutive for RTP and RTCP usage. Returns the first port in the sequence, or `-1` if we're unable to allocate.
     *
     * @param ipFamily         - Optional. "ipv4" or "ipv6". Defaults to "ipv4".
     * @param portCount        - Optional. The number of consecutive ports to reserve (1 or 2). Defaults to 1.
     * @param attempts         - Internal. The number of allocation attempts. Used for recursion.
     *
     * @returns A promise resolving to the first reserved port, or `-1` if unavailable.
     */
    private _reserve;
    /**
     * Reserves one or two consecutive UDP ports for FFmpeg or network use.
     *
     * If two ports are reserved, ensures they are consecutive for RTP and RTCP usage. Returns the first port in the sequence, or `-1` if we're unable to allocate.
     *
     * @param ipFamily         - Optional. "ipv4" or "ipv6". Defaults to "ipv4".
     * @param portCount        - Optional. The number of consecutive ports to reserve (1 or 2). Defaults to 1.
     *
     * @returns A promise resolving to the first reserved port, or `-1` if unavailable.
     *
     * @remarks FFmpeg currently lacks the ability to specify both the RTP and RTCP ports. FFmpeg always assumes, by convention, that when you specify an RTP port, the RTCP
     * port is the RTP port + 1. In order to work around that challenge, we need to always ensure that when we reserve multiple ports for RTP (primarily for two-way audio
     * use cases) that we we are reserving consecutive ports only.
     *
     * @example
     *
     * ```ts
     * // Reserve a single port.
     * const port = await allocator.reserve();
     *
     * // Reserve two consecutive ports for RTP/RTCP.
     * const rtpPort = await allocator.reserve("ipv4", 2);
     * ```
     */
    reserve(ipFamily?: ("ipv4" | "ipv6"), portCount?: (1 | 2)): Promise<number>;
    /**
     * Cancels and releases a previously reserved port, making it available for future use.
     *
     * @param port - The port number to release.
     *
     * @example
     *
     * ```ts
     * allocator.cancel(50000);
     * ```
     */
    cancel(port: number): void;
}
