#pragma once #include #include #include // Phase 1 compatibility seam for status and timing reporting. HealthTelemetry // now owns the current operational status snapshot directly, so callers can // target it without flowing through RuntimeHost-owned backing fields. class HealthTelemetry { public: struct SignalStatusSnapshot { bool hasSignal = false; unsigned width = 0; unsigned height = 0; std::string modeName; }; struct VideoIOStatusSnapshot { std::string backendName = "decklink"; std::string modelName; bool supportsInternalKeying = false; bool supportsExternalKeying = false; bool keyerInterfaceAvailable = false; bool externalKeyingRequested = false; bool externalKeyingActive = false; std::string statusMessage; }; struct PerformanceSnapshot { double frameBudgetMilliseconds = 0.0; double renderMilliseconds = 0.0; double smoothedRenderMilliseconds = 0.0; double completionIntervalMilliseconds = 0.0; double smoothedCompletionIntervalMilliseconds = 0.0; double maxCompletionIntervalMilliseconds = 0.0; uint64_t lateFrameCount = 0; uint64_t droppedFrameCount = 0; uint64_t flushedFrameCount = 0; }; struct Snapshot { SignalStatusSnapshot signal; VideoIOStatusSnapshot videoIO; PerformanceSnapshot performance; }; HealthTelemetry() = default; void ReportSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName); bool TryReportSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName); void ReportVideoIOStatus(const std::string& backendName, const std::string& modelName, bool supportsInternalKeying, bool supportsExternalKeying, bool keyerInterfaceAvailable, bool externalKeyingRequested, bool externalKeyingActive, const std::string& statusMessage); bool TryReportVideoIOStatus(const std::string& backendName, const std::string& modelName, bool supportsInternalKeying, bool supportsExternalKeying, bool keyerInterfaceAvailable, bool externalKeyingRequested, bool externalKeyingActive, const std::string& statusMessage); void RecordPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds); bool TryRecordPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds); void RecordFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds, double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount); bool TryRecordFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds, double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount); SignalStatusSnapshot GetSignalStatusSnapshot() const; VideoIOStatusSnapshot GetVideoIOStatusSnapshot() const; PerformanceSnapshot GetPerformanceSnapshot() const; Snapshot GetSnapshot() const; private: mutable std::mutex mMutex; SignalStatusSnapshot mSignalStatus; VideoIOStatusSnapshot mVideoIOStatus; PerformanceSnapshot mPerformance; };