feat: garbage collection on startup, readable status strings, audio/float32

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>
This commit is contained in:
JohannesItten
2026-07-03 10:20:53 +03:00
parent 39ba8add1a
commit 21a8ee4ba0
7 changed files with 52 additions and 12 deletions
+2 -2
View File
@@ -25,7 +25,7 @@ class FakeSinkNode : public dmf::NodeBase {
mxlFlowReader reader{};
mxlStatus st = mxlCreateFlowReader(instance(), flow_id.c_str(), nullptr, &reader);
if (st != MXL_STATUS_OK) {
log("mxlCreateFlowReader failed (status=%d)", st);
log("mxlCreateFlowReader failed (%s)", dmf::mxl_status_str(st));
return;
}
@@ -60,7 +60,7 @@ class FakeSinkNode : public dmf::NodeBase {
index = ri.headIndex;
} else {
log("unexpected status=%d on index=%llu", st, index);
log("unexpected status (%s) on index=%llu", dmf::mxl_status_str(st), index);
break;
}
+3 -3
View File
@@ -42,7 +42,7 @@ class NDIInNode : public dmf::NodeBase {
instance(),
dmf::make_video_flow_def(video_flow_id, node_id(), width, height, fps_num, fps_den).c_str(),
nullptr, &video_writer, &video_cfg, &created);
if (st != MXL_STATUS_OK) { log("video mxlCreateFlowWriter failed (status=%d)", st); return; }
if (st != MXL_STATUS_OK) { log("video mxlCreateFlowWriter failed (%s)", dmf::mxl_status_str(st)); return; }
const uint32_t video_stride = video_cfg.discrete.sliceSizes[0];
log("video stride=%u B/line grain=%u B ring=%u grains",
@@ -71,7 +71,7 @@ class NDIInNode : public dmf::NodeBase {
fps_num, fps_den).c_str(),
nullptr, &audio_writer, &audio_cfg, &created);
if (ast != MXL_STATUS_OK) {
log("audio mxlCreateFlowWriter failed (status=%d) — continuing without audio", ast);
log("audio mxlCreateFlowWriter failed (%s) — continuing without audio", dmf::mxl_status_str(ast));
has_audio = false;
} else {
log("audio channels=%u buffer=%u samples",
@@ -146,7 +146,7 @@ class NDIInNode : public dmf::NodeBase {
grain.validSlices = grain.totalSlices;
mxlFlowWriterCommitGrain(video_writer, &grain);
} else {
log("video OpenGrain failed (status=%d) at index=%llu", st, video_index);
log("video OpenGrain failed (%s) at index=%llu", dmf::mxl_status_str(st), video_index);
}
video_index = current + 1;
}
+3 -3
View File
@@ -65,7 +65,7 @@ class NDIOutNode : public dmf::NodeBase {
mxlFlowConfigInfo video_cfg{};
mxlStatus vst = mxlCreateFlowReader(instance(), flow_id.c_str(), nullptr, &video_reader);
if (vst != MXL_STATUS_OK) { log("video mxlCreateFlowReader failed (status=%d)", vst); return; }
if (vst != MXL_STATUS_OK) { log("video mxlCreateFlowReader failed (%s)", dmf::mxl_status_str(vst)); return; }
mxlFlowReaderGetConfigInfo(video_reader, &video_cfg);
video_stride = video_cfg.discrete.sliceSizes[0];
}
@@ -90,7 +90,7 @@ class NDIOutNode : public dmf::NodeBase {
mxlStatus ast = mxlCreateFlowReader(instance(), audio_flow_id.c_str(), nullptr, &audio_reader);
if (ast != MXL_STATUS_OK) {
log("audio mxlCreateFlowReader failed (status=%d) — continuing without audio", ast);
log("audio mxlCreateFlowReader failed (%s) — continuing without audio", dmf::mxl_status_str(ast));
has_audio = false;
} else {
mxlFlowReaderGetConfigInfo(audio_reader, &audio_cfg);
@@ -224,7 +224,7 @@ class NDIOutNode : public dmf::NodeBase {
video_index = ri.headIndex;
} else {
log("unexpected video status=%d on index=%llu", vst, video_index);
log("unexpected video status (%s) on index=%llu", dmf::mxl_status_str(vst), video_index);
break;
}
+3 -3
View File
@@ -28,7 +28,7 @@ class TestPatternNode : public dmf::NodeBase {
instance(),
dmf::make_video_flow_def(flow_id, node_id(), width, height, fps_num, fps_den).c_str(),
nullptr, &video_writer, &video_cfg, &created);
if (vst != MXL_STATUS_OK) { log("video mxlCreateFlowWriter failed (status=%d)", vst); return; }
if (vst != MXL_STATUS_OK) { log("video mxlCreateFlowWriter failed (%s)", dmf::mxl_status_str(vst)); return; }
const uint32_t video_stride = video_cfg.discrete.sliceSizes[0];
log("video stride=%u B/line grain=%u B ring=%u grains",
@@ -55,7 +55,7 @@ class TestPatternNode : public dmf::NodeBase {
fps_num, fps_den).c_str(),
nullptr, &audio_writer, &audio_cfg, &created);
if (ast != MXL_STATUS_OK) {
log("audio mxlCreateFlowWriter failed (status=%d) — continuing without audio", ast);
log("audio mxlCreateFlowWriter failed (%s) — continuing without audio", dmf::mxl_status_str(ast));
has_audio = false;
} else {
log("audio channels=%u buffer=%u samples",
@@ -85,7 +85,7 @@ class TestPatternNode : public dmf::NodeBase {
uint8_t* video_buf = nullptr;
vst = mxlFlowWriterOpenGrain(video_writer, video_index, &video_grain, &video_buf);
if (vst != MXL_STATUS_OK) {
log("OpenGrain failed (status=%d), skipping index=%llu", vst, video_index);
log("OpenGrain failed (%s) at index=%llu", dmf::mxl_status_str(vst), video_index);
video_index++;
continue;
}