\r
class decklink_frame : public IDeckLinkVideoFrame\r
{\r
- const std::shared_ptr<core::read_frame> frame_;\r
+ tbb::atomic<int> ref_count_;\r
+ std::shared_ptr<core::read_frame> frame_;\r
const core::video_format_desc format_desc_;\r
\r
bool key_only_;\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
key_data_.resize(frame_->image_data().size());\r
fast_memshfl(key_data_.data(), frame_->image_data().begin(), frame_->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
+ frame_.reset();\r
}\r
*buffer = key_data_.data();\r
}\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
{\r
return context_ ? context_->print() : L"decklink_consumer";\r
}\r
-\r
- virtual bool key_only() const\r
- {\r
- return config_.key_only;\r
- }\r
- \r
+ \r
virtual const core::video_format_desc& get_video_format_desc() const\r
{\r
return format_desc_;\r