\r
class decklink_frame : public IDeckLinkVideoFrame\r
{\r
+ tbb::atomic<int> ref_count_;\r
std::shared_ptr<core::read_frame> frame_;\r
const core::video_format_desc format_desc_;\r
\r
decklink_frame(const safe_ptr<core::read_frame>& frame, const core::video_format_desc& format_desc, bool key_only)\r
: frame_(frame)\r
, format_desc_(format_desc)\r
- , key_only_(key_only){}\r
+ , key_only_(key_only)\r
+ {\r
+ ref_count_ = 0;\r
+ }\r
\r
STDMETHOD (QueryInterface(REFIID, LPVOID*)) {return E_NOINTERFACE;}\r
- STDMETHOD_(ULONG, AddRef()) {return 1;}\r
- STDMETHOD_(ULONG, Release()) {return 1;}\r
+ STDMETHOD_(ULONG, AddRef()) \r
+ {\r
+ return ++ref_count_;\r
+ }\r
+ STDMETHOD_(ULONG, Release()) \r
+ {\r
+ --ref_count_;\r
+ if(ref_count_ == 0)\r
+ delete this;\r
+ return ref_count_;\r
+ }\r
\r
STDMETHOD_(long, GetWidth()) {return format_desc_.width;} \r
STDMETHOD_(long, GetHeight()) {return format_desc_.height;} \r
\r
size_t preroll_count_;\r
\r
- std::list<std::shared_ptr<IDeckLinkVideoFrame>> frame_container_; // Must be std::list in order to guarantee that pointers are always valid.\r
boost::circular_buffer<std::vector<int16_t>> audio_container_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<core::read_frame>> video_frame_buffer_;\r
else if(result == bmdOutputFrameFlushed)\r
graph_->add_tag("flushed-frame");\r
\r
- frame_container_.erase(std::find_if(frame_container_.begin(), frame_container_.end(), [&](const std::shared_ptr<IDeckLinkVideoFrame>& frame)\r
- {\r
- return frame.get() == completed_frame;\r
- }));\r
-\r
std::shared_ptr<core::read_frame> frame; \r
video_frame_buffer_.pop(frame); \r
schedule_next_video(make_safe(frame)); \r
\r
void schedule_next_video(const safe_ptr<core::read_frame>& frame)\r
{\r
- frame_container_.push_back(std::make_shared<decklink_frame>(frame, format_desc_, config_.key_only));\r
- if(FAILED(output_->ScheduleVideoFrame(frame_container_.back().get(), (frames_scheduled_++) * format_desc_.duration, format_desc_.duration, format_desc_.time_scale)))\r
+ CComPtr<IDeckLinkVideoFrame> frame2(new decklink_frame(frame, format_desc_, config_.key_only));\r
+ if(FAILED(output_->ScheduleVideoFrame(frame2, (frames_scheduled_++) * format_desc_.duration, format_desc_.duration, format_desc_.time_scale)))\r
CASPAR_LOG(error) << print() << L" Failed to schedule video.";\r
\r
graph_->update_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5);\r