#include <common/exception/exceptions.h>\r
#include <common/concurrency/executor.h>\r
#include <common/utility/tweener.h>\r
+#include <common/env.h>\r
+#include <common/gl/gl_check.h>\r
\r
#include <core/mixer/read_frame.h>\r
#include <core/mixer/write_frame.h>\r
boost::fusion::map<boost::fusion::pair<core::image_transform, image_transforms>,\r
boost::fusion::pair<core::audio_transform, audio_transforms>> transforms_;\r
\r
+ std::queue<std::pair<boost::unique_future<safe_ptr<host_buffer>>, std::vector<int16_t>>> buffer_;\r
+ \r
+ const size_t buffer_size_;\r
+\r
public:\r
implementation(video_channel_context& video_channel) \r
: channel_(video_channel)\r
, audio_mixer_(channel_.get_format_desc())\r
, image_mixer_(channel_)\r
+ , buffer_size_(env::properties().get("configuration.producers.buffer-depth", 1))\r
{ \r
- CASPAR_LOG(info) << print() << L" Successfully initialized."; \r
+ CASPAR_LOG(info) << print() << L" Successfully initialized . Buffer-depth: " << buffer_size_; \r
}\r
\r
safe_ptr<read_frame> execute(const std::map<int, safe_ptr<core::basic_frame>>& frames)\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
- return make_safe<read_frame>(channel_.ogl(), channel_.get_format_desc().size, std::move(image.get()), std::move(audio));\r
+ buffer_.push(std::make_pair(std::move(image), audio));\r
+\r
+ if(buffer_.size()-1 < buffer_size_) \r
+ return make_safe<read_frame>();\r
+ \r
+ auto res = std::move(buffer_.front());\r
+ buffer_.pop();\r
+\r
+ return make_safe<read_frame>(channel_.ogl(), channel_.get_format_desc().size, std::move(res.first.get()), std::move(res.second)); \r
}\r
catch(...)\r
{\r
- channel_.ogl().gc().wait();\r
- image_mixer_ = image_mixer(channel_);\r
- audio_mixer_ = audio_mixer(channel_.get_format_desc());\r
- channel_.ogl().gc().wait();\r
-\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- return make_safe<read_frame>();\r
- }\r
+ CASPAR_LOG(error) << L"[mixer] Error detected.";\r
+ throw;\r
+ } \r
}\r
- \r
+ \r
safe_ptr<core::write_frame> create_frame(const void* tag, const core::pixel_format_desc& desc)\r
{ \r
return image_mixer_.create_frame(tag, desc);\r