Generic telemetry
Some checks failed
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Failing after 2m30s
CI / Windows Release Package (push) Has been skipped

This commit is contained in:
2026-05-22 15:32:55 +10:00
parent 64a6125c3f
commit e6faaee1ca
6 changed files with 119 additions and 2 deletions

View File

@@ -262,7 +262,7 @@ Startup order is:
If DeckLink discovery or output setup fails, the app logs a warning and continues running without starting the output scheduler or scheduled playback. This keeps render cadence, runtime shader testing, HTTP state, and logging available on machines without DeckLink hardware or drivers.
`/api/state` reports the output status in `videoIO.statusMessage`.
`/api/state` reports backend-neutral output status in `videoOutput`. Portable fields live at `videoOutput.enabled`, `videoOutput.backend`, and `videoOutput.scheduleFailures`; backend-specific counters such as DeckLink buffered depth and schedule lead live under `videoOutput.backendMetrics`. The older `videoIO` and `decklink` status objects are retained for compatibility while clients migrate.
## Optional DeckLink Input

View File

@@ -27,7 +27,7 @@ struct RuntimeStateJsonInput
inline void WriteVideoIoStatusJson(JsonWriter& writer, const RuntimeStateJsonInput& input)
{
writer.BeginObject();
writer.KeyString("backend", "decklink");
writer.KeyString("backend", input.config.videoOutputBackend);
writer.KeyNull("modelName");
writer.KeyBool("supportsInternalKeying", false);
writer.KeyBool("supportsExternalKeying", false);
@@ -38,6 +38,47 @@ inline void WriteVideoIoStatusJson(JsonWriter& writer, const RuntimeStateJsonInp
writer.EndObject();
}
inline void WriteVideoOutputBackendMetricsJson(JsonWriter& writer, const RuntimeStateJsonInput& input)
{
writer.BeginObject();
if (input.config.videoOutputBackend == "decklink")
{
writer.KeyBool("bufferedAvailable", input.telemetry.deckLinkBufferedAvailable);
writer.Key("buffered");
if (input.telemetry.deckLinkBufferedAvailable)
writer.UInt(input.telemetry.deckLinkBuffered);
else
writer.Null();
writer.KeyDouble("scheduleCallMs", input.telemetry.deckLinkScheduleCallMilliseconds);
writer.KeyBool("scheduleLeadAvailable", input.telemetry.deckLinkScheduleLeadAvailable);
writer.Key("scheduleLeadFrames");
if (input.telemetry.deckLinkScheduleLeadAvailable)
writer.Int(input.telemetry.deckLinkScheduleLeadFrames);
else
writer.Null();
writer.KeyUInt("playbackFrameIndex", input.telemetry.deckLinkPlaybackFrameIndex);
writer.KeyUInt("nextScheduleFrameIndex", input.telemetry.deckLinkNextScheduleFrameIndex);
writer.KeyInt("playbackStreamTime", input.telemetry.deckLinkPlaybackStreamTime);
writer.KeyUInt("scheduleRealignments", input.telemetry.deckLinkScheduleRealignments);
}
writer.EndObject();
}
inline void WriteVideoOutputTelemetryJson(JsonWriter& writer, const RuntimeStateJsonInput& input)
{
writer.BeginObject();
writer.KeyBool("enabled", input.videoOutputEnabled);
writer.KeyString("backend", input.config.videoOutputBackend);
writer.KeyString("statusMessage", input.videoOutputStatus);
writer.KeyUInt("scheduleFailures", input.telemetry.scheduleFailures);
writer.KeyUInt("completions", input.telemetry.completions);
writer.KeyUInt("late", input.telemetry.displayedLate);
writer.KeyUInt("dropped", input.telemetry.dropped);
writer.Key("backendMetrics");
WriteVideoOutputBackendMetricsJson(writer, input);
writer.EndObject();
}
inline void OutputDimensions(const RuntimeStateJsonInput& input, unsigned& width, unsigned& height)
{
VideoFormatDimensions(input.config.outputVideoFormat, width, height);
@@ -277,6 +318,8 @@ inline std::string RuntimeStateToJson(const RuntimeStateJsonInput& input)
writer.KeyString("modeName", input.config.outputVideoFormat + " output-only");
writer.EndObject();
writer.Key("videoOutput");
WriteVideoOutputTelemetryJson(writer, input);
writer.Key("decklink");
WriteVideoIoStatusJson(writer, input);
writer.Key("videoIO");