import { Packet } from '../lib/packet.js';
import { Stream } from '../lib/stream.js';
import { Encoder } from './encoder.js';
import { Muxer } from './muxer.js';
import { Scheduler, SchedulerControl } from './utilities/scheduler.js';
import type { BsfName, BsfOptionsFor } from '../constants/index.js';
/**
 * Options for bitstream filter creation.
 *
 * @template N - The bitstream filter name; when a literal name is given,
 * `options` is strongly typed to that filter's known options.
 */
export interface BitstreamFilterOptions<N extends string = string> {
    /**
     * Filter-specific options.
     *
     * Key-value pairs of FFmpeg bitstream filter options, passed directly to the
     * filter via av_opt_set(). When created from a known filter name, these are
     * strongly typed to that filter's options (autocomplete + validation);
     * otherwise any string/number/boolean values are accepted.
     */
    options?: BsfOptionsFor<N>;
    /**
     * AbortSignal for cancellation.
     *
     * When aborted, async generators stop yielding and async methods throw AbortError.
     */
    signal?: AbortSignal;
}
/**
 * High-level bitstream filter for packet processing.
 *
 * Provides simplified interface for applying bitstream filters to packets.
 * Handles filter initialization, packet processing, and memory management.
 * Supports both synchronous packet-by-packet filtering and async iteration over packets.
 * Supports filters like h264_mp4toannexb, hevc_mp4toannexb, aac_adtstoasc.
 * Essential for format conversion and stream compatibility in transcoding pipelines.
 *
 * @example
 * ```typescript
 * import { BitStreamFilterAPI } from 'node-av/api';
 *
 * // Create H.264 Annex B converter
 * const filter = BitStreamFilterAPI.create('h264_mp4toannexb', stream);
 *
 * // Filter packet
 * const outputPackets = await filter.filterAll(inputPacket);
 * for (const packet of outputPackets) {
 *   await output.writePacket(packet);
 *   packet.free();
 * }
 * ```
 *
 * @example
 * ```typescript
 * // Filter packet stream
 * const filter = BitStreamFilterAPI.create('hevc_mp4toannexb', videoStream);
 *
 * for await (const packet of filter.packets(input.packets())) {
 *   await output.writePacket(packet);
 *   packet.free();
 * }
 * ```
 *
 * @see {@link BitStreamFilter} For available filters
 * @see {@link BitStreamFilterContext} For low-level API
 * @see {@link Muxer} For writing filtered packets
 */
export declare class BitStreamFilterAPI implements Disposable {
    private ctx;
    private bsf;
    private source;
    private initialized;
    private packet;
    private isClosed;
    private inputQueue;
    private outputQueue;
    private workerPromise;
    private nextComponent;
    private pipeToPromise;
    private signal?;
    /**
     * @param bsf - Bitstream filter
     *
     * @param ctx - Filter context
     *
     * @param source - Input source for lazy parameter resolution
     *
     * @internal
     */
    private constructor();
    /**
     * Create a bitstream filter.
     *
     * The input source provides the codec parameters the filter is configured with.
     * Pass a {@link Stream} to filter its packets directly (stream copy), or an
     * {@link Encoder} to filter that encoder's output (transcode) - parameters are
     * derived from the encoder once it is open. Another {@link BitStreamFilterAPI}
     * may be passed to chain filters.
     *
     * Initialization is lazy: filter options are validated immediately, but the
     * input parameters are bound and the filter is initialized on the first packet,
     * so an `Encoder` source (opened lazily on its first frame) is ready in time.
     *
     * Direct mapping to av_bsf_get_by_name() and av_bsf_alloc().
     *
     * @param filterName - Name of the bitstream filter
     *
     * @param source - Input source: a `Stream` (copy), `Encoder` (transcode), or upstream filter (chain)
     *
     * @param filterOptions - Optional filter-specific options
     *
     * @returns Configured bitstream filter
     *
     * @throws {FFmpegError} If the filter is not found, allocation fails, or an option is invalid
     *
     * @example
     * ```typescript
     * // Stream copy: H.264 MP4 to Annex B conversion
     * const filter = BitStreamFilterAPI.create('h264_mp4toannexb', videoStream);
     * ```
     *
     * @example
     * ```typescript
     * // Transcode: derive parameters from the encoder's output
     * const filter = BitStreamFilterAPI.create('h264_metadata', encoder, {
     *   options: { aud: 'remove', level: '4.1' },
     * });
     * pipeline(input, decoder, encoder, filter, output);
     * ```
     *
     * @see {@link BitStreamFilter.getByName} For filter discovery
     * @see {@link BitstreamFilterOptions} For available options
     */
    static create<const N extends BsfName | (string & {}) = BsfName | (string & {})>(filterName: N, source: Stream | Encoder | BitStreamFilterAPI, filterOptions?: BitstreamFilterOptions<N>): BitStreamFilterAPI;
    /**
     * Get filter name.
     *
     * @example
     * ```typescript
     * console.log(`Using filter: ${filter.name}`);
     * ```
     */
    get name(): string;
    /**
     * Get output codec parameters.
     *
     * Parameters after filter processing.
     * May differ from input parameters.
     *
     * @example
     * ```typescript
     * const outputParams = filter.outputCodecParameters;
     * console.log(`Output codec: ${outputParams?.codecId}`);
     * ```
     */
    get outputCodecParameters(): import("../index.js").CodecParameters | null;
    /**
     * Get output time base.
     *
     * Time base after filter processing.
     *
     * @example
     * ```typescript
     * const tb = filter.outputTimeBase;
     * console.log(`Output timebase: ${tb?.num}/${tb?.den}`);
     * ```
     */
    get outputTimeBase(): import("../index.js").Rational | null;
    /**
     * Check if filter is open.
     *
     * @example
     * ```typescript
     * if (filter.isBitstreamFilterOpen) {
     *   const packet = await filter.process(frame);
     * }
     * ```
     */
    get isBitstreamFilterOpen(): boolean;
    /**
     * Check if the filter has been initialized.
     *
     * Initialization is lazy and happens on the first processed packet, after
     * which {@link outputCodecParameters} reflect the filter's output.
     *
     * @example
     * ```typescript
     * if (filter.isInitialized) {
     *   const params = filter.outputCodecParameters;
     * }
     * ```
     */
    get isInitialized(): boolean;
    /**
     * Get associated stream.
     *
     * Returns the stream this filter was created for. Only available when the
     * filter was created from a {@link Stream}; filters created from an `Encoder`
     * derive their parameters from the encoder's output instead.
     *
     * @returns Associated stream
     *
     * @throws {Error} If the filter was not created from a stream
     *
     * @example
     * ```typescript
     * const stream = filter.getStream();
     * console.log(`Filtering stream ${stream.index}`);
     * ```
     */
    getStream(): Stream;
    /**
     * Send a packet to the filter.
     *
     * Sends a packet to the filter for processing.
     * Does not return filtered packets - use {@link receive} to retrieve packets.
     * A single packet can produce zero, one, or multiple packets depending on filter.
     *
     * **Important**: This method only SENDS the packet to the filter.
     * You must call {@link receive} separately (potentially multiple times) to get filtered packets.
     *
     * Direct mapping to av_bsf_send_packet().
     *
     * @param packet - Packet to send to filter, or null to flush
     *
     * @throws {FFmpegError} If sending fails
     *
     * @example
     * ```typescript
     * // Send packet and receive filtered packets
     * await filter.filter(inputPacket);
     *
     * // Receive all available filtered packets
     * while (true) {
     *   const outPacket = await filter.receive();
     *   if (!outPacket) break;
     *   console.log(`Filtered packet with PTS: ${outPacket.pts}`);
     *   await output.writePacket(outPacket);
     *   outPacket.free();
     * }
     * ```
     *
     * @example
     * ```typescript
     * for await (const packet of input.packets()) {
     *   // packet is null at end of stream - automatically flushes filter
     *   await filter.filter(packet);
     *
     *   // Receive available filtered packets
     *   let outPacket;
     *   while ((outPacket = await filter.receive())) {
     *     await output.writePacket(outPacket);
     *     outPacket.free();
     *   }
     * }
     * ```
     *
     * @see {@link receive} For receiving filtered packets
     * @see {@link filterAll} For combined send+receive operation
     * @see {@link packets} For automatic packet iteration
     * @see {@link flush} For end-of-stream handling
     * @see {@link filterSync} For synchronous version
     */
    filter(packet: Packet | null): Promise<void>;
    /**
     * Send a packet to the filter synchronously.
     * Synchronous version of filter.
     *
     * Sends a packet to the filter for processing.
     * Does not return filtered packets - use {@link receiveSync} to retrieve packets.
     * A single packet can produce zero, one, or multiple packets depending on filter.
     *
     * **Important**: This method only SENDS the packet to the filter.
     * You must call {@link receiveSync} separately (potentially multiple times) to get filtered packets.
     *
     * Direct mapping to av_bsf_send_packet().
     *
     * @param packet - Packet to send to filter, or null to flush
     *
     * @throws {FFmpegError} If sending fails
     *
     * @example
     * ```typescript
     * // Send packet and receive filtered packets
     * filter.filterSync(inputPacket);
     *
     * // Receive all available filtered packets
     * while (true) {
     *   const outPacket = filter.receiveSync();
     *   if (!outPacket) break;
     *   console.log(`Filtered packet with PTS: ${outPacket.pts}`);
     *   output.writePacketSync(outPacket);
     *   outPacket.free();
     * }
     * ```
     *
     * @example
     * ```typescript
     * for (const packet of packets) {
     *   // packet is null at end of stream - automatically flushes filter
     *   filter.filterSync(packet);
     *
     *   // Receive available filtered packets
     *   let outPacket;
     *   while ((outPacket = filter.receiveSync())) {
     *     output.writePacketSync(outPacket);
     *     outPacket.free();
     *   }
     * }
     * ```
     *
     * @see {@link receiveSync} For receiving filtered packets
     * @see {@link filterAllSync} For combined send+receive operation
     * @see {@link packetsSync} For automatic packet iteration
     * @see {@link flushSync} For end-of-stream handling
     * @see {@link filter} For async version
     */
    filterSync(packet: Packet | null): void;
    /**
     * Filter a packet to packets.
     *
     * Sends a packet to the filter and receives all available filtered packets.
     * Returns array of packets - may be empty if filter needs more data.
     * One packet can produce zero, one, or multiple packets depending on filter.
     *
     * Direct mapping to av_bsf_send_packet() and av_bsf_receive_packet().
     *
     * @param packet - Packet to filter, or null to flush
     *
     * @returns Array of filtered packets (empty if more data needed or filter is closed)
     *
     * @throws {FFmpegError} If filtering fails
     *
     * @example
     * ```typescript
     * const outputPackets = await filter.filterAll(inputPacket);
     * for (const packet of outputPackets) {
     *   console.log(`Filtered packet: pts=${packet.pts}`);
     *   await output.writePacket(packet);
     *   packet.free();
     * }
     * ```
     *
     * @example
     * ```typescript
     * // Flush remaining packets at end of stream
     * const remaining = await filter.filterAll(null);
     * for (const packet of remaining) {
     *   await output.writePacket(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link filter} For single packet filtering
     * @see {@link packets} For stream processing
     * @see {@link flush} For end-of-stream handling
     * @see {@link filterAllSync} For synchronous version
     */
    filterAll(packet: Packet | null): Promise<Packet[]>;
    /**
     * Filter a packet to packets synchronously.
     * Synchronous version of filterAll.
     *
     * Sends a packet to the filter and receives all available filtered packets.
     * Returns array of packets - may be empty if filter needs more data.
     * One packet can produce zero, one, or multiple packets depending on filter.
     *
     * Direct mapping to av_bsf_send_packet() and av_bsf_receive_packet().
     *
     * @param packet - Packet to filter, or null to flush
     *
     * @returns Array of filtered packets (empty if more data needed or filter is closed)
     *
     * @throws {FFmpegError} If filtering fails
     *
     * @example
     * ```typescript
     * const outputPackets = filter.filterAllSync(inputPacket);
     * for (const packet of outputPackets) {
     *   console.log(`Filtered packet: pts=${packet.pts}`);
     *   output.writePacketSync(packet);
     *   packet.free();
     * }
     * ```
     *
     * @example
     * ```typescript
     * // Flush remaining packets at end of stream
     * const remaining = filter.filterAllSync(null);
     * for (const packet of remaining) {
     *   output.writePacketSync(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link filterSync} For single packet filtering
     * @see {@link packetsSync} For stream processing
     * @see {@link flushSync} For end-of-stream handling
     * @see {@link filterAll} For async version
     */
    filterAllSync(packet: Packet | null): Packet[];
    /**
     * Filter packet stream to filtered packet stream.
     *
     * High-level async generator for complete filtering pipeline.
     * Filter is only flushed when EOF (null) signal is explicitly received.
     * Primary interface for stream-based filtering.
     *
     * **EOF Handling:**
     * - Send null to flush filter and get remaining buffered packets
     * - Generator yields null after flushing when null is received
     * - No automatic flushing - filter stays open until EOF or close()
     *
     * @param packets - Async iterable of packets, single packet, or null to flush
     *
     * @yields {Packet | null} Filtered packets, followed by null when explicitly flushed
     *
     * @throws {FFmpegError} If filtering fails
     *
     * @example
     * ```typescript
     * // Stream of packets with automatic EOF propagation
     * for await (const packet of filter.packets(input.packets())) {
     *   if (packet === null) {
     *     console.log('Filter flushed');
     *     break;
     *   }
     *   await output.writePacket(packet);
     *   packet.free(); // Must free output packets
     * }
     * ```
     *
     * @example
     * ```typescript
     * // Single packet - no automatic flush
     * for await (const packet of filter.packets(singlePacket)) {
     *   await output.writePacket(packet);
     *   packet.free();
     * }
     * // Filter remains open, buffered packets not flushed
     * ```
     *
     * @example
     * ```typescript
     * // Explicit flush with EOF
     * for await (const packet of filter.packets(null)) {
     *   if (packet === null) {
     *     console.log('All buffered packets flushed');
     *     break;
     *   }
     *   console.log('Buffered packet:', packet.pts);
     *   await output.writePacket(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link filter} For single packet filtering
     * @see {@link Demuxer.packets} For packet source
     * @see {@link packetsSync} For sync version
     */
    packets(packets: AsyncIterable<Packet | null> | Packet | null): AsyncGenerator<Packet | null>;
    /**
     * Filter packet stream to filtered packet stream synchronously.
     * Synchronous version of packets.
     *
     * High-level sync generator for complete filtering pipeline.
     * Filter is only flushed when EOF (null) signal is explicitly received.
     * Primary interface for stream-based filtering.
     *
     * **EOF Handling:**
     * - Send null to flush filter and get remaining buffered packets
     * - Generator yields null after flushing when null is received
     * - No automatic flushing - filter stays open until EOF or close()
     *
     * @param packets - Iterable of packets, single packet, or null to flush
     *
     * @yields {Packet | null} Filtered packets, followed by null when explicitly flushed
     *
     * @throws {FFmpegError} If filtering fails
     *
     * @example
     * ```typescript
     * // Stream of packets with automatic EOF propagation
     * for (const packet of filter.packetsSync(inputPackets)) {
     *   if (packet === null) {
     *     console.log('Filter flushed');
     *     break;
     *   }
     *   output.writePacketSync(packet);
     *   packet.free(); // Must free output packets
     * }
     * ```
     *
     * @example
     * ```typescript
     * // Single packet - no automatic flush
     * for (const packet of filter.packetsSync(singlePacket)) {
     *   output.writePacketSync(packet);
     *   packet.free();
     * }
     * // Filter remains open, buffered packets not flushed
     * ```
     *
     * @example
     * ```typescript
     * // Explicit flush with EOF
     * for (const packet of filter.packetsSync(null)) {
     *   if (packet === null) {
     *     console.log('All buffered packets flushed');
     *     break;
     *   }
     *   console.log('Buffered packet:', packet.pts);
     *   output.writePacketSync(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link filterSync} For single packet filtering
     * @see {@link packets} For async version
     */
    packetsSync(packets: Iterable<Packet | null> | Packet | null): Generator<Packet | null>;
    /**
     * Flush filter and signal end-of-stream.
     *
     * Sends null packet to filter to signal end-of-stream.
     * Does nothing if filter is closed.
     * Must call receive() or flushPackets() to get remaining buffered packets.
     *
     * Direct mapping to av_bsf_send_packet(NULL) and av_bsf_flush().
     *
     * @throws {FFmpegError} If flush fails
     *
     * @example
     * ```typescript
     * // Signal end of stream
     * await filter.flush();
     *
     * // Then get remaining packets
     * let packet;
     * while ((packet = await filter.receive()) !== null) {
     *   console.log('Got buffered packet');
     *   await output.writePacket(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link flushPackets} For async iteration
     * @see {@link receive} For getting buffered packets
     * @see {@link reset} For state reset only
     * @see {@link flushSync} For synchronous version
     */
    flush(): Promise<void>;
    /**
     * Flush filter and signal end-of-stream synchronously.
     * Synchronous version of flush.
     *
     * Sends null packet to filter to signal end-of-stream.
     * Does nothing if filter is closed.
     * Must call receiveSync() or flushPacketsSync() to get remaining buffered packets.
     *
     * Direct mapping to av_bsf_send_packet(NULL) and av_bsf_flush().
     *
     * @throws {FFmpegError} If flush fails
     *
     * @example
     * ```typescript
     * // Signal end of stream
     * filter.flushSync();
     *
     * // Then get remaining packets
     * let packet;
     * while ((packet = filter.receiveSync()) !== null) {
     *   console.log('Got buffered packet');
     *   output.writePacketSync(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link flushPacketsSync} For sync iteration
     * @see {@link receiveSync} For getting buffered packets
     * @see {@link reset} For state reset only
     * @see {@link flush} For async version
     */
    flushSync(): void;
    /**
     * Receive packet from filter.
     *
     * Gets filtered packets from the filter's internal buffer.
     * Handles packet allocation and error checking.
     * Returns null if filter is closed or no packets available.
     * Call repeatedly until null to drain all buffered packets.
     *
     * Direct mapping to av_bsf_receive_packet().
     *
     * @returns Cloned packet or null if no packets available
     *
     * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
     *
     * @throws {Error} If packet cloning fails (out of memory)
     *
     * @example
     * ```typescript
     * const packet = await filter.receive();
     * if (packet) {
     *   console.log('Got filtered packet');
     *   await output.writePacket(packet);
     *   packet.free();
     * }
     * ```
     *
     * @example
     * ```typescript
     * // Drain all buffered packets
     * let packet;
     * while ((packet = await filter.receive()) !== null) {
     *   console.log(`Packet PTS: ${packet.pts}`);
     *   await output.writePacket(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link filter} For filtering packets
     * @see {@link flush} For signaling end-of-stream
     * @see {@link receiveSync} For synchronous version
     */
    receive(): Promise<Packet | null>;
    /**
     * Receive packet from filter synchronously.
     * Synchronous version of receive.
     *
     * Gets filtered packets from the filter's internal buffer.
     * Handles packet allocation and error checking.
     * Returns null if filter is closed or no packets available.
     * Call repeatedly until null to drain all buffered packets.
     *
     * Direct mapping to av_bsf_receive_packet().
     *
     * @returns Cloned packet or null if no packets available
     *
     * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
     *
     * @throws {Error} If packet cloning fails (out of memory)
     *
     * @example
     * ```typescript
     * const packet = filter.receiveSync();
     * if (packet) {
     *   console.log('Got filtered packet');
     *   output.writePacketSync(packet);
     *   packet.free();
     * }
     * ```
     *
     * @example
     * ```typescript
     * // Drain all buffered packets
     * let packet;
     * while ((packet = filter.receiveSync()) !== null) {
     *   console.log(`Packet PTS: ${packet.pts}`);
     *   output.writePacketSync(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link filterSync} For filtering packets
     * @see {@link flushSync} For signaling end-of-stream
     * @see {@link receive} For async version
     */
    receiveSync(): Packet | null;
    /**
     * Pipe output to another bitstream filter.
     *
     * Starts background worker for packet processing.
     * Packets flow through: input → this filter → target filter.
     *
     * @param target - Target bitstream filter
     *
     * @returns Scheduler for continued chaining
     *
     * @example
     * ```typescript
     * const filter1 = BitStreamFilterAPI.create('h264_mp4toannexb', stream);
     * const filter2 = BitStreamFilterAPI.create('dump_extra', stream);
     * filter1.pipeTo(filter2).pipeTo(output, 0);
     * ```
     */
    pipeTo(target: BitStreamFilterAPI): Scheduler<Packet>;
    /**
     * Pipe output to muxer.
     *
     * Terminal stage - writes filtered packets to output file.
     *
     * @param output - Muxer to write to
     *
     * @param streamIndex - Stream index in output
     *
     * @returns Control interface for pipeline
     *
     * @example
     * ```typescript
     * const filter = BitStreamFilterAPI.create('h264_mp4toannexb', stream);
     * const control = filter.pipeTo(output, 0);
     * await control.send(packet);
     * ```
     */
    pipeTo(output: Muxer, streamIndex: number): SchedulerControl<Packet>;
    /**
     * Flush all buffered packets as async generator.
     *
     * Convenient async iteration over remaining packets.
     * Automatically sends flush signal and retrieves buffered packets.
     * Useful for end-of-stream processing.
     *
     * @yields {Packet} Buffered packets
     *
     * @example
     * ```typescript
     * // Flush at end of filtering
     * for await (const packet of filter.flushPackets()) {
     *   console.log('Processing buffered packet');
     *   await output.writePacket(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link filter} For filtering packets
     * @see {@link flush} For signaling end-of-stream
     * @see {@link flushPacketsSync} For synchronous version
     */
    flushPackets(): AsyncGenerator<Packet>;
    /**
     * Flush all buffered packets as generator synchronously.
     * Synchronous version of flushPackets.
     *
     * Convenient sync iteration over remaining packets.
     * Automatically retrieves buffered packets after flush.
     * Useful for end-of-stream processing.
     *
     * @yields {Packet} Buffered packets
     *
     * @example
     * ```typescript
     * // Flush at end of filtering
     * for (const packet of filter.flushPacketsSync()) {
     *   console.log('Processing buffered packet');
     *   output.writePacketSync(packet);
     *   packet.free();
     * }
     * ```
     *
     * @see {@link filterSync} For filtering packets
     * @see {@link flushSync} For signaling end-of-stream
     * @see {@link flushPackets} For async version
     */
    flushPacketsSync(): Generator<Packet>;
    /**
     * Reset filter state.
     *
     * Clears internal buffers and resets filter.
     * Does not dispose resources.
     *
     * Direct mapping to av_bsf_flush().
     *
     * @example
     * ```typescript
     * // Reset for new segment
     * filter.reset();
     * ```
     *
     * @see {@link flush} For reset with packet retrieval
     */
    reset(): void;
    /**
     * Close filter and free resources.
     *
     * Releases filter context and marks as closed.
     * Safe to call multiple times.
     *
     * @example
     * ```typescript
     * filter.close();
     * ```
     *
     * @see {@link Symbol.dispose} For automatic cleanup
     */
    close(): void;
    /**
     * Dispose of filter.
     *
     * Implements Disposable interface for automatic cleanup.
     * Equivalent to calling dispose().
     *
     * @example
     * ```typescript
     * {
     *   using filter = BitStreamFilterAPI.create('h264_mp4toannexb', stream);
     *   // Use filter...
     * } // Automatically disposed
     * ```
     *
     * @see {@link close} For manual cleanup
     */
    [Symbol.dispose](): void;
    /**
     * Bind input parameters from the source and initialize the filter.
     *
     * @internal
     */
    private ensureInitialized;
    /**
     * Send packet to input queue or flush the pipeline.
     *
     * When packet is provided, queues it for filtering.
     * When null is provided, triggers flush sequence:
     * - Closes input queue
     * - Waits for worker completion
     * - Closes output queue (no buffering, bitstream filters are stateless)
     * - Waits for pipeTo task completion
     * - Propagates flush to next component (if any)
     *
     * Used by scheduler system for pipeline control.
     *
     * @param packet - Packet to send, or null to flush
     *
     * @internal
     */
    private sendToQueue;
    /**
     * Receive packet from output queue.
     *
     * @returns Packet from queue or null if closed
     *
     * @internal
     */
    private receiveFromQueue;
    /**
     * Worker loop for push-based processing.
     *
     * @internal
     */
    private runWorker;
}
