dragon-iso/src/TeamsISO.Engine/Pipeline/IsoPipelineConfig.cs
Zac Gaetano 909237f454 feat(ndi): plumb NDI groups (discovery + output) through the engine
Adds an NdiGroupSettings record carrying optional comma-separated NDI group lists for the finder and the senders. Extends INdiInterop.CreateFinder / CreateSender with optional groups arguments and populates NDIlib_find_create_t.p_groups and NDIlib_send_create_t.p_groups via P/Invoke. IsoController reads the settings on construction, threads DiscoveryGroups into NdiDiscoveryService and OutputGroups into IsoPipelineConfig, and exposes SetGroupSettingsAsync for runtime updates (group changes apply on next process restart so live pipelines aren't orphaned).

This unblocks the 'transcoder' topology where Teams broadcasts NDI on a private group (e.g. teamsiso-input) and TeamsISO re-emits clean normalized streams on Public — keeping raw, wrong-framerate Teams sources off the production network.

EngineConfig schema is JSON-back-compat: existing config.json files (no NdiGroups field) deserialize with NdiGroups=null and load as NdiGroupSettings.Default. UI surface for these settings comes in a follow-up.

Tests: 72/72 passing (was 69) — added IsoController coverage that group settings are read from ConfigStore on startup, passed to the finder, threaded into per-pipeline config, and round-trip through SetGroupSettingsAsync/Save/Load.
2026-05-07 23:48:49 -04:00

30 lines
1.2 KiB
C#

using TeamsISO.Engine.Domain;
namespace TeamsISO.Engine.Pipeline;
/// <summary>
/// Per-pipeline configuration — identifies the participant, the source it captures,
/// the output it emits, and the global processing settings to apply.
/// </summary>
public sealed record IsoPipelineConfig(
Guid ParticipantId,
string SourceName,
string OutputName,
FrameProcessingSettings Settings)
{
/// <summary>Default no-signal threshold per spec §4.</summary>
public TimeSpan SlateThreshold { get; init; } = TimeSpan.FromSeconds(2.5);
/// <summary>Bounded raw-frame channel capacity (drop-oldest backpressure).</summary>
public int RawChannelCapacity { get; init; } = 4;
/// <summary>Bounded processed-frame channel capacity.</summary>
public int ProcessedChannelCapacity { get; init; } = 2;
/// <summary>
/// NDI groups (comma-separated) the output sender broadcasts on. <c>null</c> means
/// "use the NDI default" (Public). Set per pipeline so the controller can drive it
/// from the global NdiGroupSettings without changing this record's identity contract.
/// </summary>
public string? OutputGroups { get; init; }
}