diff --git a/nodes/decklink-out/src/decklink_out_node.cpp b/nodes/decklink-out/src/decklink_out_node.cpp index 4ff620a..2f6ed87 100644 --- a/nodes/decklink-out/src/decklink_out_node.cpp +++ b/nodes/decklink-out/src/decklink_out_node.cpp @@ -202,7 +202,9 @@ bool DeckLinkOutNode::open_device() { void DeckLinkOutNode::close_device() { if (output_) { - output_->StopScheduledPlayback(0, nullptr, time_scale_); + if (playing_) { + output_->StopScheduledPlayback(0, nullptr, time_scale_); + } output_->DisableVideoOutput(); output_->Release(); output_ = nullptr; @@ -213,6 +215,13 @@ void DeckLinkOutNode::close_device() { } playing_ = false; callback_.reset(); + { + std::lock_guard lock(frame_pool_mutex_); + for (auto* f : frame_pool_) { + f->Release(); + } + frame_pool_.clear(); + } spdlog::info("DeckLink-out: device closed"); } @@ -229,14 +238,15 @@ void DeckLinkOutNode::schedule_frame(void* mxl_payload, long width, long height, } IDeckLinkMutableVideoFrame* frame = nullptr; - HRESULT hr = output_->CreateVideoFrame(width, height, out_row_bytes, output_format_, - bmdFrameFlagDefault, &frame); - if (hr != S_OK || !frame) { - if (create_fail_count_ < 5) { - spdlog::error("DeckLink-out: CreateVideoFrame {}x{} row_bytes={} fmt=0x{:x} hr=0x{:08x}", - width, height, out_row_bytes, static_cast(output_format_), static_cast(hr)); - create_fail_count_++; + { + std::unique_lock lock(frame_pool_mutex_); + if (frame_pool_cv_.wait_for(lock, std::chrono::milliseconds(100), [this] { return !frame_pool_.empty(); })) { + frame = frame_pool_.back(); + frame_pool_.pop_back(); } + } + + if (!frame) { return; } @@ -334,6 +344,12 @@ nlohmann::json DeckLinkOutNode::status() const { HRESULT DeckLinkOutNode::OutputCallback::ScheduledFrameCompleted( IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult result) { + if (completedFrame) { + completedFrame->AddRef(); + std::lock_guard lock(owner_.frame_pool_mutex_); + owner_.frame_pool_.push_back(static_cast(completedFrame)); + owner_.frame_pool_cv_.notify_one(); + } return S_OK; } diff --git a/nodes/decklink-out/src/decklink_out_node.hpp b/nodes/decklink-out/src/decklink_out_node.hpp index b08b675..31298a0 100644 --- a/nodes/decklink-out/src/decklink_out_node.hpp +++ b/nodes/decklink-out/src/decklink_out_node.hpp @@ -7,9 +7,11 @@ #include #include +#include #include #include #include +#include namespace dmf_node { @@ -81,6 +83,9 @@ private: }; std::unique_ptr callback_; + std::vector frame_pool_; + std::mutex frame_pool_mutex_; + std::condition_variable frame_pool_cv_; IDeckLinkMutableVideoFrame* scheduled_frame_ = nullptr; };