#pragma once #include "video/core/VideoIOEdges.h" #include #include #include #include namespace RenderCadenceCompositor { using NdiOutputMetrics = VideoOutputEdgeMetrics; class NdiOutput final : public IVideoOutputEdge { public: explicit NdiOutput(std::string senderName); NdiOutput(const NdiOutput&) = delete; NdiOutput& operator=(const NdiOutput&) = delete; ~NdiOutput() override; bool Initialize(const VideoOutputEdgeConfig& config, CompletionCallback completionCallback, std::string& error) override; bool StartScheduledPlayback(std::string& error) override; bool ScheduleFrame(const VideoIOOutputFrame& frame) override; bool RequiresPreroll() const override { return false; } void Stop() override; void ReleaseResources() override; const VideoIOState& State() const override { return mState; } NdiOutputMetrics Metrics() const override; private: void CompleteBuffer(void* buffer, VideoIOCompletionResult result); static void PopulateState(VideoIOState& state, const VideoOutputEdgeConfig& config, const std::string& senderName); std::string mSenderName; CompletionCallback mCompletionCallback; mutable std::mutex mMutex; mutable std::mutex mSdkMutex; void* mSender = nullptr; void* mPendingBuffer = nullptr; VideoOutputEdgeConfig mConfig; VideoIOState mState; std::atomic mInitialized{ false }; std::atomic mRunning{ false }; std::atomic mCompletions{ 0 }; std::atomic mDropped{ 0 }; std::atomic mFlushed{ 0 }; std::atomic mScheduleFailures{ 0 }; std::atomic mScheduleCallMilliseconds{ 0.0 }; }; }