\r
struct mixer::impl : boost::noncopyable\r
{ \r
+ safe_ptr<mixer::target_t> target_;\r
+\r
safe_ptr<diagnostics::graph> graph_;\r
- boost::timer mix_timer_;\r
- \r
- std::list<std::weak_ptr<mixer::target_t>> targets_;\r
+ boost::timer mix_timer_; \r
\r
mutable tbb::spin_mutex format_desc_mutex_;\r
video_format_desc format_desc_;\r
executor executor_;\r
\r
public:\r
- impl(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl) \r
- : graph_(graph)\r
+ impl(const safe_ptr<mixer::target_t>& target, const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl) \r
+ : target_(target)\r
+ , graph_(graph)\r
, format_desc_(format_desc)\r
, ogl_(ogl)\r
, image_mixer_(ogl)\r
\r
graph_->set_value("mix-time", mix_timer_.elapsed()*format_desc_.fps*0.5);\r
\r
- boost::range::remove_erase_if(targets_, [](const std::weak_ptr<target_t>& target)\r
- {\r
- return target.lock() == nullptr;\r
- });\r
-\r
- BOOST_FOREACH(auto target, targets_)\r
- target.lock()->send(std::make_pair(make_safe<read_frame>(ogl_, format_desc_.width, format_desc_.height, std::move(image.get()), std::move(audio)), packet.second)); \r
+ target_->send(std::make_pair(make_safe<read_frame>(ogl_, format_desc_.width, format_desc_.height, std::move(image.get()), std::move(audio)), packet.second)); \r
}\r
catch(...)\r
{\r
} \r
}); \r
}\r
- \r
- void link_target(const std::weak_ptr<mixer::target_t>& target)\r
- {\r
- executor_.begin_invoke([=]\r
- {\r
- targets_.push_back(target);\r
- }, high_priority);\r
- }\r
- \r
+ \r
void set_blend_mode(int index, blend_mode::type value)\r
{\r
executor_.begin_invoke([=]\r
}\r
};\r
\r
-mixer::mixer(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl) \r
- : impl_(new impl(graph, format_desc, ogl)){}\r
+mixer::mixer(const safe_ptr<target_t>& target, const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl) \r
+ : impl_(new impl(target, graph, format_desc, ogl)){}\r
void mixer::send(const std::pair<std::map<int, safe_ptr<core::basic_frame>>, std::shared_ptr<void>>& frames){ impl_->send(frames);}\r
-void mixer::link_target(const std::weak_ptr<target_t>& target){impl_->link_target(target);}\r
core::video_format_desc mixer::get_video_format_desc() const { return impl_->get_video_format_desc(); }\r
void mixer::set_blend_mode(int index, blend_mode::type value){impl_->set_blend_mode(index, value);}\r
void mixer::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);}\r
public: \r
typedef target<std::pair<safe_ptr<read_frame>, std::shared_ptr<void>>> target_t;\r
\r
- explicit mixer(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl);\r
+ explicit mixer(const safe_ptr<target_t>& target, const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl);\r
\r
// target\r
\r
virtual void send(const std::pair<std::map<int, safe_ptr<basic_frame>>, std::shared_ptr<void>>& frames) override; \r
\r
// mixer\r
-\r
- void link_target(const std::weak_ptr<target_t>& target);\r
- \r
+ \r
core::video_format_desc get_video_format_desc() const; // nothrow\r
void set_video_format_desc(const video_format_desc& format_desc);\r
\r
};\r
\r
struct stage::impl : public std::enable_shared_from_this<impl>\r
- , boost::noncopyable\r
+ , boost::noncopyable\r
{ \r
- safe_ptr<diagnostics::graph> graph_;\r
-\r
- std::vector<std::weak_ptr<stage::target_t>> targets_;\r
+ safe_ptr<stage::target_t> target_;\r
video_format_desc format_desc_;\r
+ \r
+ safe_ptr<diagnostics::graph> graph_;\r
\r
boost::timer produce_timer_;\r
boost::timer tick_timer_;\r
\r
executor executor_;\r
public:\r
- impl(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc) \r
- : graph_(graph)\r
+ impl(const safe_ptr<stage::target_t>& target, const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc) \r
+ : target_(target)\r
+ , graph_(graph)\r
, format_desc_(format_desc)\r
, executor_(L"stage")\r
{\r
std::weak_ptr<impl> self = shared_from_this();\r
executor_.begin_invoke([=]{tick(self);});\r
}\r
-\r
- void link_target(const std::weak_ptr<stage::target_t>& target)\r
- {\r
- targets_.push_back(target);\r
- }\r
-\r
+ \r
void tick(const std::weak_ptr<impl>& self)\r
{ \r
try\r
if(self2) \r
self2->executor_.begin_invoke([=]{tick(self);}); \r
});\r
- \r
- boost::range::remove_erase_if(targets_, [](const std::weak_ptr<target_t>& target)\r
- {\r
- return target.lock() == nullptr;\r
- });\r
-\r
- BOOST_FOREACH(auto target, targets_)\r
- target.lock()->send(std::make_pair(frames, ticket));\r
+ \r
+ target_->send(std::make_pair(frames, ticket));\r
\r
graph_->set_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5);\r
tick_timer_.restart();\r
}\r
};\r
\r
-stage::stage(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc) : impl_(new impl(graph, format_desc)){}\r
-void stage::link_target(const std::weak_ptr<target_t>& target){impl_->link_target(target);}\r
+stage::stage(const safe_ptr<stage::target_t>& target,const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc) : impl_(new impl(target, graph, format_desc)){}\r
void stage::set_frame_transform(int index, const core::frame_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform(index, transform, mix_duration, tween);}\r
void stage::apply_frame_transform(int index, const std::function<core::frame_transform(core::frame_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform(index, transform, mix_duration, tween);}\r
void stage::clear_transforms(int index){impl_->clear_transforms(index);}\r
public:\r
typedef target<std::pair<std::map<int, safe_ptr<basic_frame>>, std::shared_ptr<void>>> target_t;\r
\r
- explicit stage(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc);\r
+ explicit stage(const safe_ptr<target_t>& target, const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc);\r
\r
// stage\r
- void link_target(const std::weak_ptr<target_t>& target);\r
\r
void set_frame_transform(int index, const frame_transform& transform, unsigned int mix_duration = 0, const std::wstring& tween = L"linear");\r
void apply_frame_transform(int index, const std::function<frame_transform(frame_transform)>& transform, unsigned int mix_duration = 0, const std::wstring& tween = L"linear");\r
, format_desc_(format_desc)\r
, ogl_(ogl)\r
, output_(new caspar::core::output(graph_, format_desc, index))\r
- , mixer_(new caspar::core::mixer(graph_, format_desc, ogl))\r
- , stage_(new caspar::core::stage(graph_, format_desc)) \r
+ , mixer_(new caspar::core::mixer(output_, graph_, format_desc, ogl))\r
+ , stage_(new caspar::core::stage(mixer_, graph_, format_desc)) \r
{\r
- mixer_->link_target(output_);\r
- stage_->link_target(mixer_);\r
-\r
graph_->set_text(print());\r
diagnostics::register_graph(graph_);\r
\r