Readers (ndiout, fakesink) now handle MXL_ERR_FLOW_INVALID by releasing
and recreating the flow reader, then realigning the index to current time.
This lets consumer nodes survive a producer restart without exiting.
All mxlCreateInstance/FlowWriter/FlowReader options args changed from
nullptr to "" to match MXL reference implementation style.
mxlReleaseFlowReader calls guarded with null checks so cleanup is safe
when a mid-run reconnect attempt fails.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
studio-manager: call mxlGarbageCollectFlows before launching nodes to
clean up stale flow directories left by previous crashed runs.
shared/NodeBase.hpp: add mxl_status_str(mxlStatus) — converts error
codes to readable names (e.g. MXL_ERR_OUT_OF_RANGE_TOO_LATE). All
nodes now log these names instead of raw integers.
shared/FlowDef.hpp: use "audio/float32" as media_type for 32-bit audio
flows, matching the MXL SDK examples. audio/L{n} kept for other depths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ndiout: p216_frame.FourCC was zero-initialized — NDI needs it explicitly
set to NDIlib_FourCC_video_type_P216 to send the correct format.
All three nodes: audio_rate = {sample_rate, 1} was always declared even
when has_audio is false (sample_rate = 0 in ndiout). Scoped into the
has_audio block so the bad rate can never be passed to mxlGetCurrentIndex.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
testpattern now optionally writes an audio flow when audio_flow_id is
wired in the graph. Each channel generates a sine wave at (c+1)*1000 Hz
(ch0=1kHz, ch1=2kHz, ...) at -18 dBFS broadcast reference level.
Phase is derived from the absolute audio_index so there are no clicks
at frame boundaries. One audio chunk per video frame (1920 samples at
48kHz/25fps), written via mxlFlowWriterOpenSamples with ring-buffer
fragment and channel stride handling matching ndiin.
build_graph: separate UUIDs for testpattern and ndiin flows; wire
testpattern audio_flow_id (no sink yet).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
V210.hpp: add fill_colorbars, fill_ire_ramp, fill_black, fill_white.
Shared fill_solid helper stamps the first line across all rows via
memcpy. Generic write_palette_line template handles both SMPTE and
IRE bar palettes. fill_frame kept as a backward-compat alias.
testpattern/main.cpp: read "pattern" from node config and dispatch
to the appropriate fill function (bars/ire/black/white).
build_graph: pass {"pattern","bars"} to testpattern node params.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>