\r
namespace caspar { namespace core {\r
\r
-class key_read_frame_muxer : public core::read_frame\r
+class deferred_key_read_Frame : public core::read_frame\r
{\r
ogl_device& ogl_;\r
safe_ptr<read_frame> fill_;\r
std::shared_ptr<host_buffer> key_;\r
tbb::mutex mutex_;\r
public:\r
- key_read_frame_muxer(ogl_device& ogl, const safe_ptr<read_frame>& fill)\r
+ deferred_key_read_Frame(ogl_device& ogl, const safe_ptr<read_frame>& fill)\r
: ogl_(ogl)\r
, fill_(fill)\r
{\r
timer_.tick(1.0/channel_.get_format_desc().fps);\r
\r
auto fill = frame;\r
- auto key = make_safe<key_read_frame_muxer>(channel_.ogl(), frame);\r
+ auto key = make_safe<deferred_key_read_Frame>(channel_.ogl(), frame);\r
\r
auto it = consumers_.begin();\r
while(it != consumers_.end())\r
try\r
{\r
yield();\r
- BOOST_FOREACH(auto& pools, device_pools_)\r
- {\r
- BOOST_FOREACH(auto& pool, pools)\r
- pool.second->clear();\r
- }\r
+ gc().wait();\r
\r
// Try again\r
buffer.reset(new device_buffer(width, height, stride));\r
try\r
{\r
yield();\r
- BOOST_FOREACH(auto& pools, host_pools_)\r
- {\r
- BOOST_FOREACH(auto& pool, pools)\r
- pool.second->clear();\r
- }\r
+ gc().wait();\r
\r
// Try again\r
buffer.reset(new host_buffer(size, usage));\r
write_buffer_ = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 4);\r
layer_key_buffer_ = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 1);\r
draw_buffer_[0] = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 4);\r
- draw_buffer_[1] = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 4);\r
+ //draw_buffer_[1] = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 4);\r
local_key_buffer_[0] = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 1);\r
- local_key_buffer_[1] = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 1);\r
+ //local_key_buffer_[1] = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 1);\r
channel_.ogl().gc();\r
}\r
\r
\r
layer_key_buffer_->clear();\r
draw_buffer_[0]->clear();\r
- draw_buffer_[1]->clear();\r
+ //draw_buffer_[1]->clear();\r
local_key_buffer_[0]->clear();\r
- local_key_buffer_[1]->clear();\r
+ //local_key_buffer_[1]->clear();\r
\r
bool layer_key = false;\r
\r
decltype(mix_image(frames)) image;\r
decltype(mix_audio(frames)) audio;\r
\r
- tbb::parallel_invoke(\r
- [&]{image = mix_image(frames);}, \r
- [&]{audio = mix_audio(frames);});\r
+ tbb::parallel_invoke\r
+ (\r
+ [&]{image = mix_image(frames);}, \r
+ [&]{audio = mix_audio(frames);}\r
+ );\r
\r
buffer_.push(std::make_pair(std::move(image), audio));\r
\r
if(producer == frame_producer::empty())\r
return basic_frame::eof();\r
\r
- auto frame = basic_frame::eof();\r
- try\r
- {\r
- frame = producer->receive(hints);\r
- }\r
- catch(...)\r
- {\r
- try\r
- {\r
- // Producer will be removed since frame == basic_frame::eof.\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- CASPAR_LOG(warning) << producer->print() << " Failed to receive frame. Removing producer.";\r
- }\r
- catch(...){}\r
- }\r
-\r
+ auto frame = producer->receive(hints);\r
if(frame == basic_frame::eof())\r
{\r
CASPAR_LOG(info) << producer->print() << " End Of File.";\r
\r
safe_ptr<basic_frame> receive()\r
{ \r
- if(is_paused_)\r
- return foreground_->last_frame();\r
+ try\r
+ {\r
+ if(is_paused_)\r
+ return foreground_->last_frame();\r
\r
- const auto frames_left = foreground_->nb_frames() - (++frame_number_) - auto_play_delta_;\r
+ const auto frames_left = foreground_->nb_frames() - (++frame_number_) - auto_play_delta_;\r
\r
- auto frame = receive_and_follow(foreground_, frame_producer::NO_HINT);\r
- if(frame == core::basic_frame::late())\r
- return foreground_->last_frame();\r
+ auto frame = receive_and_follow(foreground_, frame_producer::NO_HINT);\r
+ if(frame == core::basic_frame::late())\r
+ return foreground_->last_frame();\r
\r
- if(auto_play_delta_ >= 0)\r
- {\r
- if(frames_left <= 0 || frame == core::basic_frame::eof())\r
+ if(auto_play_delta_ >= 0)\r
{\r
- //CASPAR_ASSERT(frame != core::basic_frame::eof() && "Received early EOF. Media duration metadata incorrect.");\r
+ if(frames_left <= 0 || frame == core::basic_frame::eof())\r
+ {\r
+ //CASPAR_ASSERT(frame != core::basic_frame::eof() && "Received early EOF. Media duration metadata incorrect.");\r
\r
- CASPAR_LOG(info) << L"Automatically playing next clip with " << auto_play_delta_ << " frames offset. Frames left: " << frames_left;\r
+ CASPAR_LOG(info) << L"Automatically playing next clip with " << auto_play_delta_ << " frames offset. Frames left: " << frames_left;\r
\r
- play();\r
- frame = receive();\r
+ play();\r
+ frame = receive();\r
+ }\r
}\r
- }\r
\r
- return frame;\r
+ return frame;\r
+ }\r
+ catch(...)\r
+ {\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ stop();\r
+ return core::basic_frame::empty();\r
+ }\r
}\r
\r
bool empty() const\r
std::map<int, safe_ptr<basic_frame>> execute()\r
{ \r
std::map<int, safe_ptr<basic_frame>> frames;\r
+ \r
+ BOOST_FOREACH(auto& layer, layers_) \r
+ frames[layer.first] = basic_frame::empty(); \r
\r
- try\r
- { \r
- BOOST_FOREACH(auto& layer, layers_) \r
- frames[layer.first] = basic_frame::empty(); \r
-\r
- tbb::parallel_for_each(layers_.begin(), layers_.end(), [&](std::map<int, layer>::value_type& layer) \r
- {\r
- frames[layer.first] = layer.second.receive(); \r
- });\r
- }\r
- catch(...)\r
+ tbb::parallel_for_each(layers_.begin(), layers_.end(), [&](std::map<int, layer>::value_type& layer) \r
{\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- }\r
+ frames[layer.first] = layer.second.receive(); \r
+ });\r
\r
return frames;\r
}\r