int consumer_index_;\r
tbb::atomic<bool> is_running_;\r
tbb::atomic<int64_t> current_age_;\r
+ boost::promise<void> first_frame_promise_;\r
+ boost::unique_future<void> first_frame_available_;\r
+ bool first_frame_reported_;\r
\r
public:\r
channel_consumer()\r
: consumer_index_(next_consumer_index())\r
+ , first_frame_available_(first_frame_promise_.get_future())\r
+ , first_frame_reported_(false)\r
{\r
is_running_ = true;\r
current_age_ = 0;\r
\r
virtual boost::unique_future<bool> send(const safe_ptr<read_frame>& frame) override\r
{\r
- frame_buffer_.try_push(frame);\r
+ bool pushed = frame_buffer_.try_push(frame);\r
+\r
+ if (pushed && !first_frame_reported_)\r
+ {\r
+ first_frame_promise_.set_value();\r
+ first_frame_reported_ = true;\r
+ }\r
+\r
return caspar::wrap_as_future(is_running_.load());\r
}\r
\r
return format_desc_;\r
}\r
\r
+ void block_until_first_frame_available()\r
+ {\r
+ if (!first_frame_available_.timed_wait(boost::posix_time::seconds(2)))\r
+ CASPAR_LOG(warning)\r
+ << print() << L" Timed out while waiting for first frame";\r
+ }\r
+\r
std::shared_ptr<read_frame> receive()\r
{\r
if(!is_running_)\r
, frame_number_(0)\r
{\r
channel->output()->add(consumer_);\r
+ consumer_->block_until_first_frame_available();\r
CASPAR_LOG(info) << print() << L" Initialized";\r
}\r
\r
{\r
auto format_desc = consumer_->get_video_format_desc();\r
\r
- if(frame_buffer_.size() > 1)\r
+ if(frame_buffer_.size() > 0)\r
{\r
auto frame = frame_buffer_.front();\r
frame_buffer_.pop();\r
class layer_consumer : public write_frame_consumer
{
tbb::concurrent_bounded_queue<safe_ptr<basic_frame>> frame_buffer_;
+ boost::promise<void> first_frame_promise_;
+ boost::unique_future<void> first_frame_available_;
+ bool first_frame_reported_;
public:
- layer_consumer()
+ layer_consumer()
+ : first_frame_available_(first_frame_promise_.get_future())
+ , first_frame_reported_(false)
{
frame_buffer_.set_capacity(2);
}
virtual void send(const safe_ptr<basic_frame>& src_frame) override
{
- frame_buffer_.try_push(src_frame);
+ bool pushed = frame_buffer_.try_push(src_frame);
+
+ if (pushed && !first_frame_reported_)
+ {
+ first_frame_promise_.set_value();
+ first_frame_reported_ = true;
+ }
}
virtual std::wstring print() const override
}
return frame;
}
+
+ void block_until_first_frame_available()
+ {
+ if (!first_frame_available_.timed_wait(boost::posix_time::seconds(2)))
+ CASPAR_LOG(warning)
+ << print() << L" Timed out while waiting for first frame";
+ }
};
class layer_producer : public frame_producer
, frame_number_(0)
{
stage_->add_layer_consumer(this, layer_, consumer_);
+ consumer_->block_until_first_frame_available();
CASPAR_LOG(info) << print() << L" Initialized";
}