3.4 KiB
TeamsISO Phase B-2 — Real NDI Interop Plan
Goal: Production INdiInterop implementation in TeamsISO.Engine.NdiInterop against NDI SDK 6, a managed BGRA scaler with aspect modes, an NDI version constant, and a TeamsISO.Console headless smoke runner that wires up the engine end-to-end. After this phase the engine can drive real Teams NDI streams once run on a Windows box with the NDI runtime installed.
Architecture: P/Invoke against Processing.NDI.Lib.x64.dll. Frame marshalling translates NDI's video_frame_v2_t to/from our managed RawFrame/ProcessedFrame. Receive in BGRA color space (NDIlib_recv_color_format_e_BGRX_BGRA) so the scaler doesn't need to handle UYVY in v1.0. Memory management: every captured frame is freed via NDIlib_recv_free_video_v2 once we've copied its pixels into a managed buffer.
Tech Stack: .NET 8, System.Runtime.InteropServices, plain C# scaler (managed BGRA nearest-neighbor; libyuv is a v1.5 perf optimization). The console runner uses the existing EngineLogging.CreateConsole.
Source spec: docs/superpowers/specs/2026-05-07-teamsiso-v1-design.md
Tasks
- NDI native bindings:
NdiNative.cswith all[DllImport]declarations needed (initialize,destroy,find_create_v2/destroy/get_current_sources,recv_create_v3/destroy/capture_v3/free_video_v2,send_create/destroy/send_video_v2,version). DefineNDIlib_video_frame_v2_t,NDIlib_source_t,NDIlib_recv_create_v3_t,NDIlib_send_create_tstructs with explicit layout. - Handles:
NdiPInvokeFindHandle,NdiPInvokeReceiverHandle,NdiPInvokeSenderHandlederiving from the abstract Phase A handles, owning the unmanaged pointers. - NdiInteropPInvoke: the production
INdiInteropimplementation. Initializes NDI on construction; destroys on dispose. Marshals between native and managed frame structs. Allocates managed pixel buffers and copies; frees the native frame immediately. - NdiVersion: a constants class exposing the version string the engine probe compares against.
- ManagedNearestNeighborFrameScaler: managed BGRA scaler with
Pillarbox,Letterbox,Stretchaspect modes. Fully unit-tested. - TeamsISO.Console: a small console host. Constructs
IsoControlleragainstNdiInteropPInvoke+ManagedNearestNeighborFrameScaler, prints participant updates, listens forq\nto quit. Useful for headless validation. - Wire-up tests: integration scaffold uses
RuntimeInformation.IsOSPlatform(OSPlatform.Windows)to skip cleanly on non-Windows. Add a smoke integration test that constructs the interop and probes the version. - Wrap-up: tag
phase-b-2-complete.
What this phase intentionally does NOT include
- libyuv-backed scaler (deferred to v1.5 per spec — managed scaler is functionally complete).
- Actual integration test suite running against an NDI Test Pattern source. Those tests need the NDI runtime; they're authored here but stay tagged
requires=ndiand skip in the Linux CI. - Audio handling (passthrough video only in this phase; audio support added later if v1.0 needs it before ship).
Self-review
Spec coverage: §4 NdiReceiver/NdiSender/IsoController already done in B-1; this phase fills in the actual NDI SDK calls under INdiInterop. §6 startup preflight via NdiVersion + the existing NdiRuntimeProbe. §8 console smoke runner is a Phase B-2 deliverable for first end-to-end Windows validation before WPF.