#pragma once #include "VideoIOTypes.h" #include #include #include #include class HealthTelemetry; class OpenGLVideoIOBridge; class RenderEngine; class RuntimeEventDispatcher; class VideoIODevice; class VideoBackend { public: VideoBackend(RenderEngine& renderEngine, HealthTelemetry& healthTelemetry, RuntimeEventDispatcher& runtimeEventDispatcher); ~VideoBackend(); void ReleaseResources(); bool DiscoverDevicesAndModes(const VideoFormatSelection& videoModes, std::string& error); bool SelectPreferredFormats(const VideoFormatSelection& videoModes, bool outputAlphaRequired, std::string& error); bool ConfigureInput(const VideoFormat& inputVideoMode, std::string& error); bool ConfigureOutput(const VideoFormat& outputVideoMode, bool externalKeyingEnabled, std::string& error); bool Start(); bool Stop(); const VideoIOState& State() const; VideoIOState& MutableState(); bool BeginOutputFrame(VideoIOOutputFrame& frame); void EndOutputFrame(VideoIOOutputFrame& frame); bool ScheduleOutputFrame(const VideoIOOutputFrame& frame); void AccountForCompletionResult(VideoIOCompletionResult result); bool HasInputDevice() const; bool HasInputSource() const; unsigned InputFrameWidth() const; unsigned InputFrameHeight() const; unsigned OutputFrameWidth() const; unsigned OutputFrameHeight() const; unsigned CaptureTextureWidth() const; unsigned OutputPackTextureWidth() const; VideoIOPixelFormat InputPixelFormat() const; const std::string& InputDisplayModeName() const; const std::string& OutputModelName() const; bool SupportsInternalKeying() const; bool SupportsExternalKeying() const; bool KeyerInterfaceAvailable() const; bool ExternalKeyingActive() const; const std::string& StatusMessage() const; void SetStatusMessage(const std::string& message); void PublishStatus(bool externalKeyingConfigured, const std::string& statusMessage = std::string()); void ReportNoInputDeviceSignalStatus(); private: void HandleInputFrame(const VideoIOFrame& frame); void HandleOutputFrameCompletion(const VideoIOCompletion& completion); void RecordFramePacing(VideoIOCompletionResult completionResult); void PublishBackendStateChanged(const std::string& state, const std::string& message); void PublishInputSignalChanged(const VideoIOFrame& frame, const VideoIOState& state); void PublishInputFrameArrived(const VideoIOFrame& frame); void PublishOutputFrameScheduled(const VideoIOOutputFrame& frame); void PublishOutputFrameCompleted(const VideoIOCompletion& completion); void PublishTimingSample(const std::string& subsystem, const std::string& metric, double value, const std::string& unit); static std::string CompletionResultName(VideoIOCompletionResult result); static std::string PixelFormatName(VideoIOPixelFormat pixelFormat); HealthTelemetry& mHealthTelemetry; RuntimeEventDispatcher& mRuntimeEventDispatcher; std::unique_ptr mVideoIODevice; std::unique_ptr mBridge; uint64_t mInputFrameIndex = 0; uint64_t mOutputFrameScheduleIndex = 0; uint64_t mOutputFrameCompletionIndex = 0; bool mHasLastInputSignal = false; bool mLastInputSignal = false; unsigned mLastInputSignalWidth = 0; unsigned mLastInputSignalHeight = 0; std::string mLastInputSignalModeName; std::chrono::steady_clock::time_point mLastPlayoutCompletionTime; double mCompletionIntervalMilliseconds = 0.0; double mSmoothedCompletionIntervalMilliseconds = 0.0; double mMaxCompletionIntervalMilliseconds = 0.0; uint64_t mLateFrameCount = 0; uint64_t mDroppedFrameCount = 0; uint64_t mFlushedFrameCount = 0; };