import { ST2110Nic } from "../system"; import { AutoSinkMediaNode, SinkNodeSettings, StreamStatisticsMixin, SourceNodeSettings, SourceMediaNode } from "./common"; import { TimeDomain } from "./types"; export type ConstrainedIp = string[]; export interface ConstrainedPortSet { constraint: "set"; ports: number[]; } export interface ConstrainedPortMinMax { constraint: "minMax"; minPort: number; maxPort: number; } export type ConstrainedPort = ConstrainedPortSet | ConstrainedPortMinMax; export interface SettingConstraint { constraint?: Constraint; default: Default; } export interface ST2110SenderConstraintsBase { destinationIp?: SettingConstraint; sourcePort?: SettingConstraint; destinationPort: SettingConstraint; } export interface ST2110SenderConstraintsInternal extends ST2110SenderConstraintsBase { sourceIp: SettingConstraint; } export type ST2110SenderConstraints = ST2110SenderConstraintsBase; /** * Norsk-internal flat enum that bundles ST 2110-20 sampling, depth and * byte-order into a single string. Each value maps to a specific * combination of the SDP `a=fmtp:` `sampling=` and `depth=` parameters * plus an implied big-endian RFC 4175 packing. * * Preferred SDK usage is the orthogonal `{ sampling, depth }` form on * {@link ST2110OutputVideoSender}, which decomposes cleanly to the * SDP fields a 2110-fluent caller is reading on the wire. This enum * remains as a `@deprecated` shorthand for the simple case. * * `YUV_422_PLANAR10_LE` is Norsk-internal experimental and has no * `{ sampling, depth }` equivalent — keep it on this enum if you need * it. */ export type ST2110VideoTransportFormat = "YUV_422_10_BE" | "YUV_422_8_BE" | "YUV_422_12_BE" | "YUV_422_16_BE" | "YUV_420_8_BE" | "YUV_420_10_BE" | "YUV_420_12_BE" | "YUV_420_16_BE" | "RGB_8_BE" | "RGB_10_BE" | "RGB_12_BE" | "RGB_16_BE" | "YUV_444_8_BE" | "YUV_444_10_BE" | "YUV_444_12_BE" | "YUV_444_16_BE" | "YUV_422_PLANAR10_LE"; /** * SDP `a=fmtp:` `sampling=` parameter (ST 2110-20 / RFC 4175). Picks * the wire colour-sampling scheme; combined with {@link ST2110ComponentDepth} * fully determines the wire byte layout for an uncompressed video * sender. */ export type ST2110ColorSampling = "YCbCr-4:2:2" | "YCbCr-4:2:0" | "YCbCr-4:4:4" | "RGB"; /** SDP `a=fmtp:` `depth=` parameter — bits per component. */ export type ST2110ComponentDepth = 8 | 10 | 12 | 16; export type ST2110AudioPacketTime = 1 | 0.125 | 0.250 | 0.333 | 4 | 0.08 | 1.09 | 0.14 | 0.09; /** * Norsk-internal performance knobs for an ST 2110 video sender. * Defaults work for typical workflows; consult Norsk support before * overriding. */ export interface ST2110OutputVideoSenderAdvanced { /** * Number of frame buffers MTL keeps in flight for this sender — a * *count*, not a byte size. Larger gives more cushion against * PS-side pacing jitter at the cost of one frame's-worth of memory * per slot and matching latency between PS push and wire emission. * Bounded by MTL's `ST20_FB_MAX_COUNT` (8); defaults to 2 (each * slot is megabytes for raw video, so the default keeps memory * low). */ frameBufferSize?: number; } /** * ST 2110-21 sender pacing profile, advertised in the outgoing SDP * `TP=` parameter. NARROW is the deterministic broadcast profile and * the default; the others relax timing requirements at the receiver's * expense. * * NARROW requires the host's NIC to use pinned scheduling — see * {@link ST2110SchedulingMode}. */ export type ST2110SenderCompliance = "narrow" | "narrowLinear" | "wide"; export interface ST2110OutputVideoSender { type: "video"; /** * SDP `a=fmtp:` `sampling=` parameter (ST 2110-20 / RFC 4175). * Combined with `depth` fully determines the wire byte layout. * * One of `{ sampling, depth }` OR the deprecated `transportFormat` * must be set; not both. */ sampling?: ST2110ColorSampling; /** * SDP `a=fmtp:` `depth=` parameter — bits per component. * See `sampling`. */ depth?: ST2110ComponentDepth; /** * @deprecated Use `sampling` + `depth`. Provided for source-level * compatibility with earlier SDK shape; will be removed in a future * release. */ transportFormat?: ST2110VideoTransportFormat; /** * ST 2110-21 pacing profile. Defaults to `"narrow"` — the * deterministic narrow-gapped profile required for full * professional-broadcast compliance. `"narrowLinear"` (TP-NL) and * `"wide"` (TP-W) relax timing at the receiver's expense. */ compliance?: ST2110SenderCompliance; /** * Optional RTP SSRC (RFC 3550) to pin on the wire. Omit to let MTL * pick a random value. Set explicitly when monitoring tooling * needs to identify a sender across restarts. */ ssrc?: number; /** * Optional RTP payload type (RFC 3550 dynamic range, 96–127). Omit * to use Norsk's default (112 for video). */ payloadType?: number; /** Norsk-internal performance knobs. See {@link ST2110OutputVideoSenderAdvanced}. */ advanced?: ST2110OutputVideoSenderAdvanced; } /** * ST 2110-30 wire-format encoding for an audio sender. Norsk-internal * audio is always PCM16; PCM24 results in zig padding each sample with * a zero LSB on the way to the wire. Defaults to PCM16 when unset. */ export type ST2110AudioFormat = "PCM16" | "PCM24"; /** * Norsk-internal performance knobs for an ST 2110 audio sender. * Defaults work for typical workflows. */ export interface ST2110OutputAudioSenderAdvanced { /** * Number of audio frame buffers MTL keeps in flight for this * sender — a *count*, not a byte size. At 4 ms ptime each slot is * ~768 bytes (PCM16 stereo), so going larger is cheap and absorbs * more PS-side pacing jitter. Defaults to 8 (32 ms cushion at 4 ms * ptime); MTL's minimum of 2 is too small for realtime PS sources, * drains the ring on any pacing dip and causes MTL to skip an * epoch. */ frameBufferSize?: number; } /** * ST 2110-40 ancillary sender. Transports SMPTE 291 VANC packets * (closed captions, SCTE-104 splice commands, AFD, SMPTE 12M * timecode, etc.) at the matching video session's frame rate. On the * wire the SDP advertises `m=video application/smpte291 90000` — the * `video` media type is per RFC 8331 even though the payload is data. * * Pair with a sibling video sender carrying the same `frameRate` so * downstream receivers can align ANC packets to the video frames * they describe. */ export interface ST2110OutputAncillarySenderAdvanced { /** * MTL ring depth for outbound ANC frames. Defaults to 8 — same * shape as the audio sender's cushion (sub-millisecond pacing * tasklet drain dips can starve a smaller ring under load). */ frameBufferSize?: number; } export interface ST2110OutputAncillarySender { type: "ancillary"; /** * Pacing rate. Must match the paired video session's frame rate; * ANC packets are stamped with PTSs in the video media clock * (90 kHz) and receivers align them to the matching video frame. * Expressed as `{ frames, seconds }` per Norsk's standard frame * rate shape (e.g. `{ frames: 50, seconds: 1 }` for 50 fps, * `{ frames: 60000, seconds: 1001 }` for 59.94). */ frameRate: { frames: number; seconds: number; }; /** Match the paired video session's interlacing. Default false. */ interlaced?: boolean; /** * Optional RTP SSRC (RFC 3550). Omit to let MTL pick a random * value. See {@link ST2110OutputVideoSender.ssrc}. */ ssrc?: number; /** * Optional RTP payload type (RFC 3550 dynamic range, 96–127). Omit * to use Norsk's default (113 for ancillary). */ payloadType?: number; /** Norsk-internal performance knobs. */ advanced?: ST2110OutputAncillarySenderAdvanced; } /** * ST 2110-40 subtitle sender. Wire-identical to {@link * ST2110OutputAncillarySender} (same SMPTE 291 / RFC 8331 framing, * same SDP) but accepts Subtitle stream inputs (CEA-708 / CEA-608 / * OP-47) instead of Ancillary. A wire stream that needs to carry * both subtitles AND ancillary today takes two separate senders. */ export interface ST2110OutputSubtitleSender { type: "subtitle"; frameRate: { frames: number; seconds: number; }; interlaced?: boolean; ssrc?: number; payloadType?: number; advanced?: ST2110OutputAncillarySenderAdvanced; } /** * ST 2110-43 TTML sender. Carries TTML2/IMSC1.2 caption documents * over RFC 8759 on a dedicated RTP session at 90 kHz. Wire is * fundamentally different from {@link ST2110OutputAncillarySender} * (different SDP, different RFC) so this is its own sender shape. * * `codecs` is the IMSC profile short code (e.g. `"im2t"` for IMSC1 * Text profile, see https://www.w3.org/TR/ttml-profile-registry/) * advertised via the SDP `a=fmtp: codecs=` parameter — * mandatory per RFC 8759 §11.2. */ export interface ST2110OutputTtmlSender { type: "ttml"; /** * Pacing rate for MTL's tasklet — typically the matching video * session's frame rate. Actual TTML emission rate is driven by * upstream cue arrival, not by this field. */ frameRate: { frames: number; seconds: number; }; /** IMSC profile short code (`"im1t"`, `"im2t"`, etc.). */ codecs: string; /** * RTP ring size; must be a power of two. Defaults to 1024 (plenty * for typical TTML cue rates, which are 1s+ apart). */ rtpRingSize?: number; ssrc?: number; /** Defaults to Norsk's TTML default (114). */ payloadType?: number; } export interface ST2110OutputAudioSender { type: "audio"; /** * SDP `a=ptime:` — packet duration in milliseconds. Sub-millisecond * values are expressed as decimals (e.g. `0.125` for 125 µs). */ ptime: ST2110AudioPacketTime; /** * Wire-format encoding (SDP `a=rtpmap:` encoding name `L16` / * `L24`). Defaults to PCM16 (L16). */ format?: ST2110AudioFormat; /** * Optional RTP SSRC (RFC 3550). Omit to let MTL pick a random * value. See {@link ST2110OutputVideoSender.ssrc}. */ ssrc?: number; /** * Optional RTP payload type (RFC 3550 dynamic range, 96–127). Omit * to use Norsk's default (111 for audio). */ payloadType?: number; /** Norsk-internal performance knobs. See {@link ST2110OutputAudioSenderAdvanced}. */ advanced?: ST2110OutputAudioSenderAdvanced; } /** * Per-sender SDP attribute overrides. Each field replaces the value * Norsk would otherwise auto-derive. Leave a field unset / empty to * keep the auto-derived value (the common case). * * Use these only for deployments where the controller / receivers * expect a specific SDP value Norsk can't infer from its own state * — e.g. an explicit `ts-refclk:ptp=...` pointing at a grandmaster * other than the one this node is synced to. */ export interface ST2110SdpOverrides { /** * SDP `a=ts-refclk:` value (no leading `ts-refclk:`). Examples: * `"ptp=IEEE1588-2008:00-1B-19-FF-FE-00-00-00:127"`, * `"localmac=00:11:22:33:44:55"`. Auto-derived from the * Node clock when omitted. */ tsRefclk?: string; /** * SDP `a=mediaclk:` value (no leading `mediaclk:`). Defaults to * `"direct=0"`. Override only if your downstream expects a * different `mediaclk` form (`sender=...` etc.). */ mediaclk?: string; } export interface ST2110OutputSender { label: string; description?: string; tags?: { [k: string]: string[]; }; nic: ST2110Nic; sdpSessionName: string; senderConstraints: C[]; mediaConfig: ST2110OutputVideoSender | ST2110OutputAudioSender | ST2110OutputAncillarySender | ST2110OutputSubtitleSender | ST2110OutputTtmlSender; /** Optional per-sender SDP attribute overrides. */ sdpOverrides?: ST2110SdpOverrides; } export interface ST2110OutputFlow { label: Pins; description?: string; tags?: { [k: string]: string[]; }; roleInGroup?: string; senders: ST2110OutputSender[]; } export interface ST2110OutputSource { label: string; description?: string; tags?: { [k: string]: string[]; }; flows: ST2110OutputFlow[]; clock: string; } /** * @public * Lifecycle event for a single sender inside an ST 2110 NMOS output * device. Fires on every transition; see * {@link ST2110OutputSettings.onSenderStateChange}. * * Sequence (per sender): * * "idle" * ↓ (controller PATCH master_enable=true) * "starting" * ↓ (server finishes per-sender setup, including any Spectrum * wire-format conversion compile) * "active" { destinations[], wirePixelFormat } * ↓ (controller PATCH master_enable=false, or switch) * "idle" * * At any time: * "failed" { reason } */ export type ST2110SenderStateEvent = { senderLabel: string; state: "idle"; } | { senderLabel: string; state: "starting"; } | { senderLabel: string; state: "active"; destinations: { ip: string; port: number; }[]; wirePixelFormat: string; } | { senderLabel: string; state: "failed"; reason: string; }; /** * @public * Lifecycle event for a single receiver inside an ST 2110 NMOS input * device. Mirror of {@link ST2110SenderStateEvent} for the input side — * fires on every transition; see * {@link ST2110InputSettings.onReceiverStateChange}. * * Sequence (per receiver): * * "idle" * ↓ (controller PATCH master_enable=true, or new SDP) * "starting" * ↓ (first valid context lands from the underlying child workflow, * i.e. multicast joined and packets are flowing) * "active" { endpoints[], wirePixelFormat } * ↓ (controller PATCH master_enable=false, or switch) * "idle" * * At any time: * "failed" { reason } — refusal at activation time (unsupported wire * transport) or unexpected child-workflow death. */ export type ST2110ReceiverStateEvent = { receiverLabel: string; state: "idle"; } | { receiverLabel: string; state: "starting"; } | { receiverLabel: string; state: "active"; endpoints: { sourceIp: string; multicastIp: string; destinationPort: number; }[]; wirePixelFormat: string; } | { receiverLabel: string; state: "failed"; reason: string; }; /** * @public * Device-wide lifecycle for an ST 2110 NMOS sender or receiver device. * Tracks how far through NMOS registration the device as a whole has * progressed. Used by both {@link ST2110OutputSettings.onDeviceStateChange} * and {@link ST2110InputSettings.onDeviceStateChange}. * * Sequence: * * "initialising" — server-side gen_server is up but no NMOS register * calls have been issued yet (transient) * "registering" — at least one resource (device / source / flow / * sender / receiver) is awaiting first-registry * confirmation * "ready" — every currently-tracked resource is registered with * at least one NMOS registry; an NMOS controller can * discover the device and PATCH its senders/receivers * "failed" — bring-up rejected; `reason` carries detail * * "ready" is sticky for the current resource set, but the device drops * back to "registering" if new resources are added later (e.g. a * contextChanged adding a flow). So "ready" always means "every resource * we have right now is discoverable". */ export type ST2110DeviceStateEvent = { state: "initialising"; } | { state: "registering"; } | { state: "ready"; } | { state: "failed"; reason: string; }; /** * @public * Settings to create an ST2110 Output * see: {@link Norsk.System.ST2110.node} * */ export interface ST2110OutputSettings extends SinkNodeSettings>, StreamStatisticsMixin { label: string; description?: string; tags?: { [k: string]: string[]; }; groupName?: string; sources: ST2110OutputSource[]; /** * Called whenever a sender transitions lifecycle state. Useful for * surfacing the in-flight startup ("starting" → "active") in a UI or * for noticing failed activations ("failed" with `reason`). */ onSenderStateChange?: (event: ST2110SenderStateEvent) => void; /** * Called whenever the device-wide NMOS-registration lifecycle * transitions. The transition to "ready" signals that an NMOS * controller can now discover this device and PATCH its senders. * Useful for gating dev-side PATCH simulation or showing * "starting up…" / "ready" in a UI. */ onDeviceStateChange?: (event: ST2110DeviceStateEvent) => void; } export declare class ST2110OutputNode extends AutoSinkMediaNode { } export interface ST2110ReceiverConstraintsBase { multicastIp?: SettingConstraint; destinationPort: SettingConstraint; } export interface ST2110ReceiverConstraintsInternal extends ST2110ReceiverConstraintsBase { sourceIp?: SettingConstraint; interfaceIp?: SettingConstraint; } export type ST2110ReceiverConstraints = ST2110ReceiverConstraintsBase; export interface NumericConstraintEnum { type: "enum"; enum: T[]; } export interface NumericConstraintMinMax { type: "minmax"; minimum: T; maximum: T; } export type NumericConstraint = NumericConstraintEnum | NumericConstraintMinMax; /** * SDP `a=fmtp:` `RANGE=` value — the signal range encoding. Default in * ST 2110-20 is NARROW (broadcast levels). */ export type ST2110Range = "NARROW" | "FULL" | "FULLPROTECT"; /** * Per-constraint-set RX caps for an ST 2110-20 video receiver. Each * field maps to the matching SDP `a=fmtp:` parameter and to a NMOS * BCP-004-01 receiver-caps `urn:x-nmos:cap:format:*` constraint — * field names follow the NMOS/SDP terminology rather than internal * Norsk vocabulary so a 2110-fluent caller reads them as they would * appear on the wire. * * Receiver-only: these constraints describe what *incoming* senders * the receiver will accept. On the send side Norsk derives the * matching values from its own pipeline state and writes them into * the outgoing SDP, so customer configurability here would be * meaningless. */ export interface VideoCapabilityConstraints { label: string; /** SDP `a=fmtp:` `sampling=` (NMOS `color_sampling`). */ colorSampling: ("YCbCr-4:2:2" | "YCbCr-4:4:4" | "YCbCr-4:2:0" | "RGB" | "RGBA")[]; /** * SDP `a=fmtp:` `colorimetry=` (NMOS `colorimetry`). Restricts which * colour-space encodings the receiver will accept from a matched * sender. */ colorimetry: ("BT709" | "BT601" | "BT2020" | "BT2100" | "BT470BG" | "ST2065-1" | "ST2065-3" | "UNSPECIFIED")[]; /** SDP `a=fmtp:` `depth=` — bits per component. */ componentDepth: (8 | 10)[]; frameHeight: NumericConstraint; frameWidth: NumericConstraint; /** NMOS `grain_rate` — the frame rate, as a rational. */ grainRate: NumericConstraint<{ numerator: number; denominator: number; }>; interlaceMode: ("interlace" | "progressive")[]; /** SDP `a=fmtp:` `TCS=` (NMOS `transfer_characteristic`). */ transferCharacteristic: ("SDR" | "PQ" | "HLG" | "LINEAR" | "BT2100LIN" | "UNSPECIFIED")[]; /** * SDP `a=fmtp:` `PAR=` — pixel aspect ratio (NMOS extension cap * `urn:x-nmos:cap:format:par`). Optional — omit to accept any PAR. */ par?: NumericConstraint<{ numerator: number; denominator: number; }>; /** * SDP `a=fmtp:` `RANGE=` — signal range (Norsk extension cap * `urn:x-nmos:cap:format:range`; not standardised by NMOS * BCP-004-01 v1.0). Empty / omitted means "accept any RANGE". */ range?: ST2110Range[]; } export interface VideoCaps { type: "video"; constraints: VideoCapabilityConstraints[]; } export interface AudioCapabilityConstraints { label: string; channelCount: NumericConstraint; sampleRate: NumericConstraint<{ numerator: number; denominator: number; }>; sampleDepth: NumericConstraint; packetTime: NumericConstraint; } export interface AudioCaps { type: "audio"; constraints: AudioCapabilityConstraints[]; } /** * Capabilities for an ST 2110-40 ancillary receiver. `media_types` * is effectively pinned to `video/smpte291`. The `subtitles` / * `ancillary` fields pick which VANC payload formats the receiver * decodes; the per-DID/SDID dispatch happens server-side. The * defaults from `defaultAncillaryMediaType()` cover the most common * case (SCTE-104 only). */ export interface AncillaryCaps { type: "ancillary"; /** VANC subtitle format to decode. Defaults to `"none"`. */ subtitles?: "none" | "teletext" | "cta708" | "cta608"; /** VANC ancillary format to decode. Defaults to `"scte104"`. */ ancillary?: "none" | "scte104"; } /** * Capabilities for an ST 2110-43 TTML receiver. `media_types` is * effectively pinned to `application/ttml+xml`. `acceptedCodecs` is * the list of IMSC profile short codes (`"im1t"`, `"im2t"`, etc.) * the receiver will decode — controllers can use the matching IS-04 * cap to pair only with senders advertising compatible profiles. * Empty list = accept any codecs= value. */ export interface TtmlCaps { type: "ttml"; acceptedCodecs?: string[]; } /** * Norsk-internal performance knobs for an ST 2110 receiver. Defaults * work for typical workflows. */ export interface ST2110InputReceiverAdvanced { /** * Number of frame buffers MTL keeps in flight on the receive side — * a *count*, not a byte size. Larger gives the downstream consumer * (zig coalescer → PS handler) more headroom against scheduling * jitter without making MTL's RX path drop packets. Defaults: 8 for * audio (cheap, ~12 KB total), 2 for video (each slot is megabytes * for raw frames). Bounded by MTL's `ST20_FB_MAX_COUNT` (8) for * video. */ frameBufferSize?: number; /** * How long MTL's RX tasklet sleeps between get-frame polls (ns). * Defaults to 1 ms; lower values reduce idle-CPU at the cost of * latency. Only tune if measuring a specific timing issue. */ threadSleepTimeNs?: number; /** * RTP ring queue size for ST 2110-43 TTML receivers (power of * two). Defaults to 1024 — plenty for typical TTML cue rates, * since each cue document is at most a handful of mbufs. Only * tune if a deployment sees per-document fragment bursts that * overflow the default. */ rtpRingSize?: number; } export interface ST2110InputReceiver { label: string; description?: string; tags?: { [k: string]: string[]; }; nic: ST2110Nic; receiverConstraints: C[]; mediaType: VideoCaps | AudioCaps | AncillaryCaps | TtmlCaps; /** * Idle-timeout override (ms). When omitted, the receiver picks a * sensible default from the SDP-advertised frame rate — 3× the * frame interval, floored at 100 ms. Set explicitly to relax the * default for slow / bursty sources, or tighten it for fast * failover. */ idleTimeoutMs?: number; /** Norsk-internal performance knobs. See {@link ST2110InputReceiverAdvanced}. */ advanced?: ST2110InputReceiverAdvanced; } export interface ST2110InputSettings extends SourceNodeSettings, StreamStatisticsMixin { sourceName: string; label: string; description?: string; tags?: { [k: string]: string[]; }; groupName?: string; receivers: ST2110InputReceiver[]; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; /** * Called whenever the device-wide NMOS-registration lifecycle * transitions. The transition to "ready" signals that an NMOS * controller can now discover this device and PATCH its receivers. * See {@link ST2110DeviceStateEvent} for the state sequence. */ onDeviceStateChange?: (event: ST2110DeviceStateEvent) => void; /** * Called whenever a receiver transitions lifecycle state. Useful for * surfacing the in-flight startup ("starting" → "active") in a UI or * for noticing failed activations ("failed" with `reason`). * Mirror of {@link ST2110OutputSettings.onSenderStateChange}. */ onReceiverStateChange?: (event: ST2110ReceiverStateEvent) => void; } export declare class ST2110InputNode extends SourceMediaNode { /** @public */ static defaultVideoMediaType(): VideoCaps; /** @public */ static defaultAudioMediaType(): AudioCaps; /** * @public * Default caps shape for an ST 2110-40 ancillary receiver: SCTE-104 * decoding on, no subtitle decoding. Override `subtitles` / * `ancillary` on the returned object to widen the kinds. */ static defaultAncillaryMediaType(): AncillaryCaps; /** * @public * Default caps shape for an ST 2110-43 TTML receiver. Accepts the * two most common IMSC profile short codes (`im1t` = IMSC1 Text, * `im2t` = IMSC1.1 Text). Pass an `acceptedCodecs` override to * tighten or widen. */ static defaultTtmlMediaType(): TtmlCaps; } //# sourceMappingURL=st2110.d.ts.map