#include <boost/lexical_cast.hpp>\r
\r
#include <tbb/parallel_for.h>\r
+#include <tbb/spin_mutex.h>\r
\r
#include <array>\r
#include <memory>\r
{ \r
std::array<layer, frame_producer_device::MAX_LAYER> layers_; \r
\r
- const output_func output_;\r
+ tbb::spin_mutex output_mutex_;\r
+ output_func output_;\r
+\r
const safe_ptr<frame_factory> factory_;\r
\r
mutable executor executor_;\r
\r
void tick()\r
{ \r
- output_(draw());\r
+ auto frame = draw();\r
+ {\r
+ tbb::spin_mutex::scoped_lock lock(output_mutex_);\r
+ output_(frame);\r
+ }\r
executor_.begin_invoke([=]{tick();});\r
}\r
\r
});\r
} \r
\r
- void swap(size_t index, size_t other_index)\r
+ void swap_layer(size_t index, size_t other_index)\r
{\r
check_bounds(index);\r
check_bounds(other_index);\r
});\r
}\r
\r
- void swap(size_t index, size_t other_index, frame_producer_device& other)\r
+ void swap_layer(size_t index, size_t other_index, frame_producer_device& other)\r
{\r
check_bounds(index);\r
check_bounds(other_index);\r
});\r
}\r
\r
- void check_bounds(size_t index)\r
+ void swap_output(frame_producer_device& other)\r
+ {\r
+ tbb::spin_mutex::scoped_lock lock1(output_mutex_); \r
+ tbb::spin_mutex::scoped_lock lock2(other.impl_->output_mutex_);\r
+ output_.swap(other.impl_->output_);\r
+ }\r
+\r
+ void check_bounds(size_t index) const\r
{\r
if(index < 0 || index >= frame_producer_device::MAX_LAYER)\r
BOOST_THROW_EXCEPTION(out_of_range() << msg_info("Valid range is [0..100]") << arg_name_info("index") << arg_value_info(boost::lexical_cast<std::string>(index)));\r
\r
boost::unique_future<safe_ptr<frame_producer>> foreground(size_t index) const\r
{\r
+ check_bounds(index);\r
return executor_.begin_invoke([=]() -> safe_ptr<frame_producer>\r
{ \r
return layers_[index].foreground();\r
void frame_producer_device::stop(size_t index){impl_->stop(index);}\r
void frame_producer_device::clear(size_t index){impl_->clear(index);}\r
void frame_producer_device::clear(){impl_->clear();}\r
-void frame_producer_device::swap(size_t index, size_t other_index){impl_->swap(index, other_index);}\r
-void frame_producer_device::swap(size_t index, size_t other_index, frame_producer_device& other){impl_->swap(index, other_index, other);}\r
+void frame_producer_device::swap_layer(size_t index, size_t other_index){impl_->swap_layer(index, other_index);}\r
+void frame_producer_device::swap_layer(size_t index, size_t other_index, frame_producer_device& other){impl_->swap_layer(index, other_index, other);}\r
+void frame_producer_device::swap_output(frame_producer_device& other){impl_->swap_output(other);}\r
boost::unique_future<safe_ptr<frame_producer>> frame_producer_device::foreground(size_t index) const{ return impl_->foreground(index);}\r
}}
\ No newline at end of file
void stop(size_t index);\r
void clear(size_t index);\r
void clear(); \r
- void swap(size_t index, size_t other_index);\r
- void swap(size_t index, size_t other_index, frame_producer_device& other);\r
+ void swap_layer(size_t index, size_t other_index);\r
+ void swap_layer(size_t index, size_t other_index, frame_producer_device& other);\r
+ void swap_output(frame_producer_device& other);\r
boost::unique_future<safe_ptr<frame_producer>> foreground(size_t index) const;\r
\r
private:\r
//Perform loading of the clip\r
try\r
{\r
- std::vector<std::string> strs;\r
- boost::split(strs, _parameters[0], boost::is_any_of("-"));\r
+ if(GetLayerIndex(-1) != -1)\r
+ {\r
+ std::vector<std::string> strs;\r
+ boost::split(strs, _parameters[0], boost::is_any_of("-"));\r
\r
- auto ch1 = GetChannel();\r
- auto ch2 = GetChannels().at(boost::lexical_cast<int>(strs.at(0))-1);\r
+ auto ch1 = GetChannel();\r
+ auto ch2 = GetChannels().at(boost::lexical_cast<int>(strs.at(0))-1);\r
\r
- int l1 = GetLayerIndex();\r
- int l2 = boost::lexical_cast<int>(strs.at(1));\r
+ int l1 = GetLayerIndex();\r
+ int l2 = boost::lexical_cast<int>(strs.at(1));\r
\r
- ch1->producer().swap(l1, l2, ch2->producer());\r
+ ch1->producer().swap_layer(l1, l2, ch2->producer());\r
+ }\r
+ else\r
+ {\r
+ auto ch1 = GetChannel();\r
+ auto ch2 = GetChannels().at(boost::lexical_cast<int>(_parameters[0])-1);\r
+ ch1->producer().swap_output(ch2->producer());\r
+ }\r
\r
CASPAR_LOG(info) << "Swapped successfully";\r
\r
SetReplyString(TEXT("202 SWAP OK\r\n"));\r
\r
- return false;\r
+ return true;\r
}\r
catch(file_not_found&)\r
{\r