const int index_;\r
video_format_desc format_desc_;\r
\r
- std::shared_ptr<frame_mixer_device> mixer_;\r
- std::shared_ptr<frame_consumer_device> consumer_;\r
- std::shared_ptr<frame_producer_device> producer_;\r
+ safe_ptr<frame_mixer_device> mixer_;\r
+ safe_ptr<frame_consumer_device> consumer_;\r
+ safe_ptr<frame_producer_device> producer_;\r
\r
boost::signals2::scoped_connection mixer_connection_;\r
boost::signals2::scoped_connection producer_connection_;\r
, format_desc_(format_desc)\r
, consumer_(new frame_consumer_device(format_desc))\r
, mixer_(new frame_mixer_device(format_desc))\r
- , producer_(new frame_producer_device(safe_ptr<frame_factory>(mixer_))) \r
+ , producer_(new frame_producer_device(format_desc_)) \r
, mixer_connection_(mixer_->connect([=](const safe_ptr<const read_frame>& frame){consumer_->send(frame);}))\r
, producer_connection_(producer_->connect([=](const std::vector<safe_ptr<basic_frame>>& frames){mixer_->send(frames);}))\r
{}\r
mixer_connection_.disconnect();\r
\r
consumer_->set_video_format_desc(format_desc_);\r
- mixer_.reset(new frame_mixer_device(format_desc_));\r
- producer_.reset(new frame_producer_device(safe_ptr<frame_factory>(mixer_)));\r
+ mixer_ = make_safe<frame_mixer_device>(format_desc_);\r
+ producer_ = make_safe<frame_producer_device>(format_desc_);\r
\r
mixer_connection_ = mixer_->connect([=](const safe_ptr<const read_frame>& frame){consumer_->send(frame);});\r
producer_connection_ = producer_->connect([=](const std::vector<safe_ptr<basic_frame>>& frames){mixer_->send(frames);});\r
\r
channel::channel(int index, const video_format_desc& format_desc) : impl_(new implementation(index, format_desc)){}\r
channel::channel(channel&& other) : impl_(std::move(other.impl_)){}\r
-frame_producer_device& channel::producer() { return *impl_->producer_;} \r
-frame_mixer_device& channel::mixer() { return *impl_->mixer_;} \r
-frame_consumer_device& channel::consumer() { return *impl_->consumer_;} \r
+const safe_ptr<frame_producer_device>& channel::producer() { return impl_->producer_;} \r
+const safe_ptr<frame_mixer_device>& channel::mixer() { return impl_->mixer_;} \r
+const safe_ptr<frame_consumer_device>& channel::consumer() { return impl_->consumer_;} \r
const video_format_desc& channel::get_video_format_desc() const{return impl_->format_desc_;}\r
void channel::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);}\r
std::wstring channel::print() const { return impl_->print();}\r
explicit channel(int index, const video_format_desc& format_desc);\r
channel(channel&& other);\r
\r
- frame_producer_device& producer();\r
- frame_mixer_device& mixer();\r
- frame_consumer_device& consumer();\r
+ const safe_ptr<frame_producer_device>& producer();\r
+ const safe_ptr<frame_mixer_device>& mixer();\r
+ const safe_ptr<frame_consumer_device>& consumer();\r
\r
const video_format_desc& get_video_format_desc() const;\r
void set_video_format_desc(const video_format_desc& format_desc);\r
std::wstring color_str_;\r
\r
public:\r
- explicit color_producer(const std::wstring& color) \r
+ explicit color_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& color) \r
: color_str_(color)\r
, frame_(basic_frame::empty())\r
{\r
if(color.length() != 9 || color[0] != '#')\r
BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("color") << arg_value_info(narrow(color)) << msg_info("Invalid color code"));\r
- }\r
\r
- virtual void set_frame_factory(const safe_ptr<frame_factory>& frame_factory)\r
- {\r
auto frame = frame_factory->create_frame(1, 1, pixel_format::bgra);\r
auto& value = *reinterpret_cast<unsigned long*>(frame->image_data().begin());\r
std::wstringstream str(color_str_.substr(1));\r
str >> std::hex >> value; \r
frame_ = std::move(frame);\r
}\r
- \r
+ \r
virtual safe_ptr<basic_frame> receive() { return frame_; }\r
\r
virtual std::wstring print() const { return L"color[" + color_str_ + L"]"; }\r
};\r
\r
-safe_ptr<frame_producer> create_color_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<frame_producer> create_color_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
{\r
if(params.empty() || params[0].at(0) != '#')\r
return frame_producer::empty();\r
- return make_safe<color_producer>(params[0]);\r
+ return make_safe<color_producer>(frame_factory, params[0]);\r
}\r
\r
}}
\ No newline at end of file
\r
namespace caspar { namespace core {\r
\r
-safe_ptr<frame_producer> create_color_producer(const std::vector<std::wstring>& params);\r
+ safe_ptr<frame_producer> create_color_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
\r
}}\r
std::vector<const producer_factory_t> p_factories;\r
tbb::spin_rw_mutex p_factories_mutex;\r
\r
+safe_ptr<basic_frame> receive(safe_ptr<frame_producer>& producer)\r
+{\r
+ auto frame = basic_frame::eof();\r
+ try\r
+ {\r
+ frame = producer->receive();\r
+ }\r
+ catch(...)\r
+ {\r
+ try\r
+ {\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ CASPAR_LOG(warning) << producer->print() << " Failed to receive frame. Removing producer.";\r
+ }\r
+ catch(...){}\r
+ }\r
+\r
+ if(frame == basic_frame::eof())\r
+ {\r
+ auto following = producer->get_following_producer();\r
+ if(following == frame_producer::empty())\r
+ producer = frame_producer::eof();\r
+ else\r
+ {\r
+ following->set_leading_producer(producer);\r
+ producer = std::move(following);\r
+ return receive(producer);\r
+ }\r
+ }\r
+ return frame;\r
+}\r
+\r
+std::wostream& operator<<(std::wostream& out, const frame_producer& producer)\r
+{\r
+ out << producer.print().c_str();\r
+ return out;\r
+}\r
+\r
+std::wostream& operator<<(std::wostream& out, const safe_ptr<const frame_producer>& producer)\r
+{\r
+ out << producer->print().c_str();\r
+ return out;\r
+}\r
+\r
void register_producer_factory(const producer_factory_t& factory)\r
{\r
tbb::spin_rw_mutex::scoped_lock(p_factories_mutex, true);\r
p_factories.push_back(factory);\r
}\r
\r
-safe_ptr<core::frame_producer> create_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& params)\r
{\r
if(params.empty())\r
BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("params") << arg_value_info(""));\r
{\r
try\r
{\r
- producer = factory(params);\r
+ producer = factory(my_frame_factory, params);\r
}\r
catch(...)\r
{\r
});\r
\r
if(producer == frame_producer::empty())\r
- producer = create_color_producer(params);\r
+ producer = create_color_producer(my_frame_factory, params);\r
\r
if(producer == frame_producer::empty())\r
BOOST_THROW_EXCEPTION(file_not_found() << msg_info("No match found for supplied commands. Check syntax."));\r
public:\r
virtual ~frame_producer(){} \r
\r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual basic_frame :::receive() = 0;\r
- ///\r
- /// \brief Renders a frame.\r
- /// \r
- /// \note This function is run in through the tbb task_schedular and shall be *non blocking*.\r
- ///\r
- /// \return The frame. \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
virtual safe_ptr<basic_frame> receive() = 0;\r
-\r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual std::shared_ptr<frame_producer> :::get_following_producer() const\r
- ///\r
- /// \brief Gets the producer which will replace the current producer on EOF. \r
- ///\r
- /// \return The following producer, or nullptr if there is no following producer. \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
virtual safe_ptr<frame_producer> get_following_producer() const {return frame_producer::empty();} // nothrow\r
- \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual void :::set_leading_producer(const std::shared_ptr<frame_producer>& producer)\r
- ///\r
- /// \brief Sets the producer which was run before the current producer. \r
- ///\r
- /// \param producer The leading producer.\r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
virtual void set_leading_producer(const safe_ptr<frame_producer>& /*producer*/) {} // nothrow\r
- \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual void :::set_frame_factory(const safe_ptr<frame_factory>& frame_factory) = 0;\r
- ///\r
- /// \brief Sets the frame frame_factory used to create frames. \r
- ///\r
- /// \param frame_factory The frame frame_factory. \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- virtual void set_frame_factory(const safe_ptr<frame_factory>& frame_factory) = 0;\r
-\r
virtual void param(const std::wstring&){}\r
\r
virtual std::wstring print() const = 0;\r
};\r
static safe_ptr<frame_producer> producer = make_safe<empty_frame_producer>();\r
return producer;\r
+ } \r
+\r
+ static const safe_ptr<frame_producer>& eof() // nothrow\r
+ {\r
+ struct eof_frame_producer : public frame_producer\r
+ {\r
+ virtual safe_ptr<basic_frame> receive(){return basic_frame::eof();}\r
+ virtual void set_frame_factory(const safe_ptr<frame_factory>&){}\r
+ virtual std::wstring print() const { return L"eof";}\r
+ };\r
+ static safe_ptr<frame_producer> producer = make_safe<eof_frame_producer>();\r
+ return producer;\r
}\r
};\r
\r
-inline std::wostream& operator<<(std::wostream& out, const frame_producer& producer)\r
-{\r
- out << producer.print().c_str();\r
- return out;\r
-}\r
+safe_ptr<basic_frame> receive(safe_ptr<frame_producer>& producer);\r
\r
-inline std::wostream& operator<<(std::wostream& out, const safe_ptr<const frame_producer>& producer)\r
-{\r
- out << producer->print().c_str();\r
- return out;\r
-}\r
+std::wostream& operator<<(std::wostream& out, const frame_producer& producer);\r
+std::wostream& operator<<(std::wostream& out, const safe_ptr<const frame_producer>& producer);\r
\r
-typedef std::function<safe_ptr<core::frame_producer>(const std::vector<std::wstring>&)> producer_factory_t;\r
+typedef std::function<safe_ptr<core::frame_producer>(const safe_ptr<frame_factory>&, const std::vector<std::wstring>&)> producer_factory_t;\r
\r
void register_producer_factory(const producer_factory_t& factory);\r
-safe_ptr<core::frame_producer> create_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>&, const std::vector<std::wstring>& params);\r
\r
\r
}}\r
{ \r
std::map<int, layer> layers_; \r
\r
- const safe_ptr<frame_factory> factory_;\r
+ const video_format_desc format_desc_;\r
\r
output_t output_;\r
\r
mutable executor executor_;\r
public:\r
- implementation(const safe_ptr<frame_factory>& factory) \r
- : factory_(factory)\r
+ implementation(const video_format_desc& format_desc) \r
+ : format_desc_(format_desc)\r
, executor_(L"frame_producer_device")\r
{\r
executor_.start();\r
}\r
}); \r
boost::range::remove_erase(frames, basic_frame::empty());\r
+ boost::range::remove_erase(frames, basic_frame::eof());\r
return frames;\r
}\r
\r
void load(int index, const safe_ptr<frame_producer>& producer, bool play_on_load, bool preview)\r
{\r
- producer->set_frame_factory(factory_);\r
executor_.invoke([&]{get_layer(index).load(producer, play_on_load, preview);});\r
}\r
\r
swap_layer(index, other_index);\r
else\r
{\r
- if(factory_->get_video_format_desc() != other.impl_->factory_->get_video_format_desc())\r
+ if(format_desc_ != other.impl_->format_desc_)\r
BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Cannot swap between channels with different formats."));\r
\r
auto func = [&]\r
if(other.impl_.get() == this)\r
return;\r
\r
- if(factory_->get_video_format_desc() != other.impl_->factory_->get_video_format_desc())\r
+ if(format_desc_ != other.impl_->format_desc_)\r
BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Cannot swap between channels with different formats."));\r
\r
auto func = [&]\r
}\r
};\r
\r
-frame_producer_device::frame_producer_device(const safe_ptr<frame_factory>& factory) : impl_(new implementation(factory)){}\r
+frame_producer_device::frame_producer_device(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
frame_producer_device::frame_producer_device(frame_producer_device&& other) : impl_(std::move(other.impl_)){}\r
boost::signals2::connection frame_producer_device::connect(const output_t::slot_type& subscriber){return impl_->connect(subscriber);}\r
void frame_producer_device::swap(frame_producer_device& other){impl_->swap(other);}\r
\r
boost::signals2::connection connect(const output_t::slot_type& subscriber);\r
\r
- explicit frame_producer_device(const safe_ptr<frame_factory>& factory);\r
+ explicit frame_producer_device(const video_format_desc& format_desc);\r
frame_producer_device(frame_producer_device&& other);\r
void swap(frame_producer_device& other);\r
\r
return last_frame_;\r
}\r
\r
- try\r
- {\r
- last_frame_ = foreground_->receive(); \r
- if(last_frame_ == basic_frame::eof())\r
- {\r
- CASPAR_VERIFY(foreground_ != frame_producer::empty());\r
-\r
- auto following = foreground_->get_following_producer();\r
- following->set_leading_producer(foreground_);\r
- g_remover.remove(std::move(foreground_));\r
- foreground_ = following;\r
- CASPAR_LOG(info) << foreground_->print() << L" Added.";\r
-\r
- last_frame_ = receive();\r
- }\r
- }\r
- catch(...)\r
- {\r
- CASPAR_LOG(error) << print() << L" Unhandled Exception: ";\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- stop();\r
- }\r
+ auto keep_alive = foreground_;\r
+ last_frame_ = core::receive(foreground_);\r
+\r
+ if(keep_alive != foreground_)\r
+ g_remover.remove(std::move(keep_alive));\r
\r
return last_frame_;\r
}\r
\r
namespace caspar { namespace core { \r
\r
-struct transition_producer::implementation : boost::noncopyable\r
+struct transition_producer : public frame_producer\r
{ \r
- const transition_producer* self_;\r
+ const video_format_desc format_desc_;\r
unsigned short current_frame_;\r
\r
const transition_info info_;\r
\r
safe_ptr<frame_producer> dest_producer_;\r
safe_ptr<frame_producer> source_producer_;\r
-\r
- std::shared_ptr<frame_factory> frame_factory_;\r
-\r
+ \r
std::vector<safe_ptr<basic_frame>> frame_buffer_;\r
\r
- implementation(const transition_producer* self, const safe_ptr<frame_producer>& dest, const transition_info& info) \r
- : self_(self)\r
+ transition_producer(const video_format_desc& format_desc, const safe_ptr<frame_producer>& dest, const transition_info& info) \r
+ : format_desc_(format_desc)\r
, current_frame_(0)\r
, info_(info)\r
, dest_producer_(dest)\r
{\r
frame_buffer_.push_back(basic_frame::empty());\r
}\r
- \r
- void set_frame_factory(const safe_ptr<frame_factory>& frame_factory)\r
- {\r
- dest_producer_->set_frame_factory(frame_factory);\r
- frame_factory_ = frame_factory;\r
- }\r
- \r
+ \r
safe_ptr<frame_producer> get_following_producer() const\r
{\r
return dest_producer_;\r
\r
tbb::parallel_invoke\r
(\r
- [&]{dest = render_sub_frame(dest_producer_);},\r
- [&]{source = render_sub_frame(source_producer_);}\r
+ [&]{dest = core::receive(dest_producer_);},\r
+ [&]{source = core::receive(source_producer_);}\r
);\r
\r
return compose(dest, source);\r
}\r
- \r
- safe_ptr<basic_frame> render_sub_frame(safe_ptr<frame_producer>& producer)\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();\r
- }\r
- catch(...)\r
- {\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- producer = frame_producer::empty();\r
- CASPAR_LOG(warning) << self_->print() << " Failed to receive frame. Removed producer from transition.";\r
- }\r
-\r
- if(frame == basic_frame::eof())\r
- {\r
- try\r
- {\r
- auto following = producer->get_following_producer();\r
- following->set_frame_factory(safe_ptr<frame_factory>(frame_factory_));\r
- following->set_leading_producer(producer);\r
- producer = std::move(following);\r
- }\r
- catch(...)\r
- {\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- producer = frame_producer::empty();\r
- CASPAR_LOG(warning) << self_->print() << " Failed to initialize following producer.";\r
- }\r
-\r
- return render_sub_frame(producer);\r
- }\r
- return frame;\r
- }\r
- \r
+ \r
safe_ptr<basic_frame> compose(const safe_ptr<basic_frame>& dest_frame, const safe_ptr<basic_frame>& src_frame) \r
{ \r
if(dest_frame == basic_frame::eof() && src_frame == basic_frame::eof())\r
d_frame2->get_image_transform().set_key_scale(delta2, 1.0); \r
}\r
\r
- auto mode = frame_factory_->get_video_format_desc().mode;\r
- auto s_frame = s_frame1->get_image_transform() == s_frame2->get_image_transform() ? s_frame2 : basic_frame::interlace(s_frame1, s_frame2, mode);\r
- auto d_frame = basic_frame::interlace(d_frame1, d_frame2, mode);\r
+ auto s_frame = s_frame1->get_image_transform() == s_frame2->get_image_transform() ? s_frame2 : basic_frame::interlace(s_frame1, s_frame2, format_desc_.mode);\r
+ auto d_frame = basic_frame::interlace(d_frame1, d_frame2, format_desc_.mode);\r
\r
return basic_frame(s_frame, d_frame);\r
}\r
\r
std::wstring print() const\r
{\r
- return L"transition[" + info_.name() + L":" + boost::lexical_cast<std::wstring>(info_.duration) + L"]";\r
+ return L"transition[" + transition::print(info_.type) + L":" + boost::lexical_cast<std::wstring>(info_.duration) + L"]";\r
}\r
\r
std::wstring source_print() const { return print() + L"/source";}\r
std::wstring dest_print() const { return print() + L"/dest";}\r
};\r
\r
-transition_producer::transition_producer(const safe_ptr<frame_producer>& dest, const transition_info& info) : impl_(new implementation(this, dest, info)){}\r
-transition_producer::transition_producer(transition_producer&& other) : impl_(std::move(other.impl_)){}\r
-safe_ptr<basic_frame> transition_producer::receive(){return impl_->receive();}\r
-safe_ptr<frame_producer> transition_producer::get_following_producer() const{return impl_->get_following_producer();}\r
-void transition_producer::set_leading_producer(const safe_ptr<frame_producer>& producer) { impl_->set_leading_producer(producer); }\r
-void transition_producer::set_frame_factory(const safe_ptr<frame_factory>& frame_factory) { impl_->set_frame_factory(frame_factory);}\r
-std::wstring transition_producer::print() const { return impl_->print();}\r
+safe_ptr<frame_producer> create_transition_producer(const video_format_desc& format_desc, const safe_ptr<frame_producer>& destination, const transition_info& info)\r
+{\r
+ return make_safe<transition_producer>(format_desc, destination, info);\r
+}\r
\r
}}\r
\r
slide,\r
wipe\r
};\r
+\r
+ static std::wstring print(type t)\r
+ {\r
+ switch(t)\r
+ {\r
+ case transition::cut: return L"cut";\r
+ case transition::mix: return L"mix";\r
+ case transition::push: return L"push";\r
+ case transition::slide: return L"slide";\r
+ case transition::wipe: return L"wipe";\r
+ default: return L"";\r
+ }\r
+ }\r
};\r
\r
struct transition_direction\r
, duration(0)\r
, direction(transition_direction::from_left)\r
, tweener(get_tweener(L"linear")){}\r
-\r
- std::wstring name() const\r
- {\r
- switch(type)\r
- {\r
- case transition::cut: return L"cut";\r
- case transition::mix: return L"mix";\r
- case transition::push: return L"push";\r
- case transition::slide: return L"slide";\r
- case transition::wipe: return L"wipe";\r
- default: return L"";\r
- }\r
- }\r
- \r
+ \r
size_t duration;\r
transition_direction::type direction;\r
transition::type type;\r
tweener_t tweener;\r
};\r
\r
-class transition_producer : public frame_producer\r
-{\r
-public:\r
- explicit transition_producer(const safe_ptr<frame_producer>& destination, const transition_info& info);\r
- transition_producer(transition_producer&& other);\r
-\r
- // frame_producer\r
- virtual safe_ptr<basic_frame> receive();\r
- virtual safe_ptr<frame_producer> get_following_producer() const;\r
- virtual void set_leading_producer(const safe_ptr<frame_producer>& producer);\r
- virtual void set_frame_factory(const safe_ptr<frame_factory>& frame_factory);\r
- virtual std::wstring print() const;\r
-private:\r
- struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
-};\r
+safe_ptr<frame_producer> create_transition_producer(const video_format_desc& format_desc, const safe_ptr<frame_producer>& destination, const transition_info& info);\r
\r
}}
\ No newline at end of file
executor executor_;\r
public:\r
\r
- explicit decklink_producer(const core::video_format_desc& format_desc, size_t device_index)\r
+ explicit decklink_producer(const safe_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index)\r
: format_desc_(format_desc) \r
, device_index_(device_index)\r
- , executor_(L"decklink_producer"){}\r
+ , executor_(L"decklink_producer")\r
+ {\r
+ executor_.start();\r
+ executor_.invoke([=]\r
+ {\r
+ input_.reset(new decklink_input(format_desc_, device_index_, frame_factory));\r
+ });\r
+ }\r
\r
~decklink_producer()\r
{ \r
input_ = nullptr;\r
});\r
}\r
-\r
- virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
- {\r
- executor_.start();\r
- executor_.invoke([=]\r
- {\r
- input_.reset(new decklink_input(format_desc_, device_index_, frame_factory));\r
- });\r
- }\r
- \r
+ \r
virtual safe_ptr<core::basic_frame> receive()\r
{\r
return input_->get_frame();\r
}\r
};\r
\r
-safe_ptr<core::frame_producer> create_decklink_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_decklink_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
{\r
if(params.empty() || !boost::iequals(params[0], "decklink"))\r
return core::frame_producer::empty();\r
format_desc = format_desc.format != core::video_format::invalid ? format_desc : core::video_format_desc::get(L"PAL");\r
}\r
\r
- return make_safe<decklink_producer>(format_desc, device_index);\r
+ return make_safe<decklink_producer>(frame_factory, format_desc, device_index);\r
}\r
\r
}
\ No newline at end of file
\r
namespace caspar { \r
\r
-safe_ptr<core::frame_producer> create_decklink_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_decklink_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
\r
}\r
\r
std::unique_ptr<input> input_; \r
public:\r
- explicit ffmpeg_producer(const std::wstring& filename, bool loop) \r
+ explicit ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, bool loop) \r
: filename_(filename)\r
, loop_(loop) \r
, last_frame_(core::basic_frame(core::basic_frame::empty()))\r
- \r
+ , frame_factory_(frame_factory) \r
{\r
graph_ = diagnostics::create_graph(boost::bind(&ffmpeg_producer::print, this)); \r
graph_->add_guide("frame-time", 0.5);\r
graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
- }\r
- \r
- virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
- {\r
- frame_factory_ = frame_factory;\r
+\r
input_.reset(new input(safe_ptr<diagnostics::graph>(graph_), filename_, loop_));\r
video_decoder_.reset(input_->get_video_codec_context().get() ? new video_decoder(input_->get_video_codec_context().get(), frame_factory) : nullptr);\r
audio_decoder_.reset(input_->get_audio_codec_context().get() ? new audio_decoder(input_->get_audio_codec_context().get(), frame_factory->get_video_format_desc().fps) : nullptr);\r
double format_frame_time = 1.0/frame_factory->get_video_format_desc().fps;\r
if(abs(frame_time - format_frame_time) > 0.0001)\r
CASPAR_LOG(warning) << print() << L" Invalid framerate detected. This may cause distorted audio during playback. frame-time: " << frame_time;\r
-\r
}\r
- \r
+ \r
virtual safe_ptr<core::basic_frame> receive()\r
{\r
perf_timer_.reset();\r
\r
if(audio_decoder_) \r
{\r
- if(!frame)\r
+ if(!frame) // If there is no video create a dummy frame.\r
{\r
frame = frame_factory_->create_frame(1, 1);\r
std::fill(frame->image_data().begin(), frame->image_data().end(), 0);\r
graph_->update_value("frame-time", static_cast<float>(perf_timer_.elapsed()/frame_factory_->get_video_format_desc().interval*0.5));\r
\r
auto result = last_frame_;\r
- if(!ouput_channel_.empty())\r
- {\r
- result = get_frame();\r
-\r
- bool interlace = abs(input_->fps()/2.0 - frame_factory_->get_video_format_desc().fps) < 0.001;\r
- if(interlace && !ouput_channel_.empty())\r
- result = core::basic_frame::interlace(result, get_frame(), frame_factory_->get_video_format_desc().mode);\r
- }\r
+ if(!ouput_channel_.empty()) \r
+ result = get_frame(); // TODO: Support 50p \r
else if(input_->is_eof())\r
result = core::basic_frame::eof();\r
\r
}\r
};\r
\r
-safe_ptr<core::frame_producer> create_ffmpeg_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
{ \r
static const std::vector<std::wstring> extensions = boost::assign::list_of\r
(L"mpg")(L"mpeg")(L"avi")(L"mov")(L"qt")(L"webm")(L"dv")(L"mp4")(L"f4v")(L"flv")(L"mkv")(L"mka")(L"wmw")(L"wma")(L"ogg")(L"divx")(L"wav")(L"mp3");\r
std::wstring path = filename + L"." + *ext;\r
bool loop = std::find(params.begin(), params.end(), L"LOOP") != params.end();\r
\r
- return make_safe<ffmpeg_producer>(path, loop);\r
+ return make_safe<ffmpeg_producer>(frame_factory, path, loop);\r
}\r
\r
}
\ No newline at end of file
\r
namespace caspar {\r
\r
-safe_ptr<core::frame_producer> create_ffmpeg_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
\r
}
\ No newline at end of file
void init_flash()\r
{\r
core::register_producer_factory(create_ct_producer);\r
-\r
- try\r
- {\r
- create_flash_producer(boost::assign::list_of(env::template_host()));\r
- }\r
- catch(...){}\r
}\r
\r
std::wstring get_cg_version()\r
\r
struct cg_producer::implementation : boost::noncopyable\r
{\r
- const cg_producer* self_;\r
+ safe_ptr<core::frame_factory> frame_factory_;\r
safe_ptr<core::frame_producer> flash_producer_;\r
- std::shared_ptr<core::frame_factory> frame_factory_;\r
public:\r
- implementation(const cg_producer* self) \r
- : self_(self)\r
- , flash_producer_(create_flash_producer(boost::assign::list_of(env::template_host())))\r
+ implementation(const safe_ptr<core::frame_factory>& frame_factory) \r
+ : frame_factory_(frame_factory)\r
+ , flash_producer_(create_flash_producer(frame_factory_, boost::assign::list_of(env::template_host())))\r
{}\r
-\r
- void clear()\r
- {\r
- flash_producer_ = create_flash_producer(boost::assign::list_of(env::template_host()));\r
- flash_producer_->set_frame_factory(safe_ptr<core::frame_factory>(frame_factory_));\r
- }\r
-\r
+ \r
void add(int layer, const std::wstring& filename, bool play_on_load, const std::wstring& label, const std::wstring& data)\r
{\r
CASPAR_LOG(info) << flash_producer_->print() << " Invoking add-command";\r
{\r
return flash_producer_->receive();\r
}\r
- \r
- void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
- {\r
- frame_factory_ = frame_factory;\r
- flash_producer_->set_frame_factory(frame_factory);\r
- }\r
- \r
+ \r
std::wstring print() const\r
{\r
return flash_producer_->print();\r
{ \r
try\r
{\r
- return dynamic_pointer_cast<cg_producer>(channel->producer().foreground(render_layer).get());\r
+ return dynamic_pointer_cast<cg_producer>(channel->producer()->foreground(render_layer).get());\r
}\r
catch(std::bad_cast&)\r
{\r
- auto producer = make_safe<cg_producer>(); \r
- channel->producer().load(render_layer, producer, true); \r
+ safe_ptr<core::frame_factory> factory = channel->mixer();\r
+ auto producer = make_safe<cg_producer>(factory); \r
+ channel->producer()->load(render_layer, producer, true); \r
return producer;\r
}\r
}\r
\r
-safe_ptr<core::frame_producer> create_ct_producer(const std::vector<std::wstring>& params) \r
+safe_ptr<core::frame_producer> create_ct_producer(const safe_ptr<core::frame_factory> frame_factory, const std::vector<std::wstring>& params) \r
{\r
std::wstring filename = env::media_folder() + L"\\" + params[0] + L".ct";\r
if(!boost::filesystem::exists(filename))\r
return core::frame_producer::empty();\r
\r
- auto producer = make_safe<cg_producer>();\r
+ auto producer = make_safe<cg_producer>(frame_factory);\r
producer->add(0, filename, 1);\r
\r
return producer;\r
}\r
\r
-cg_producer::cg_producer() : impl_(new implementation(this)){}\r
+cg_producer::cg_producer(const safe_ptr<core::frame_factory>& frame_factory) : impl_(new implementation(frame_factory)){}\r
cg_producer::cg_producer(cg_producer&& other) : impl_(std::move(other.impl_)){}\r
safe_ptr<core::basic_frame> cg_producer::receive(){return impl_->receive();}\r
-void cg_producer::clear(){impl_->clear();}\r
void cg_producer::add(int layer, const std::wstring& template_name, bool play_on_load, const std::wstring& startFromLabel, const std::wstring& data){impl_->add(layer, template_name, play_on_load, startFromLabel, data);}\r
void cg_producer::remove(int layer){impl_->remove(layer);}\r
void cg_producer::play(int layer){impl_->play(layer);}\r
void cg_producer::next(int layer){impl_->next(layer);}\r
void cg_producer::update(int layer, const std::wstring& data){impl_->update(layer, data);}\r
void cg_producer::invoke(int layer, const std::wstring& label){impl_->invoke(layer, label);}\r
-void cg_producer::set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory){impl_->set_frame_factory(frame_factory);}\r
std::wstring cg_producer::print() const{return impl_->print();}\r
\r
}
\ No newline at end of file
public:\r
static const unsigned int DEFAULT_LAYER = 9999;\r
\r
- explicit cg_producer();\r
+ explicit cg_producer(const safe_ptr<core::frame_factory>& frame_factory);\r
cg_producer(cg_producer&& other);\r
\r
- void clear();\r
void add(int layer, const std::wstring& template_name, bool play_on_load, const std::wstring& start_from_label = TEXT(""), const std::wstring& data = TEXT(""));\r
void remove(int layer);\r
void play(int layer);\r
\r
// frame_producer\r
virtual safe_ptr<core::basic_frame> receive();\r
- virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory);\r
virtual std::wstring print() const;\r
\r
private:\r
};\r
safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::channel>& channel, int layer_index = cg_producer::DEFAULT_LAYER);\r
\r
-safe_ptr<core::frame_producer> create_ct_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_ct_producer(const safe_ptr<core::frame_factory> frame_factory, const std::vector<std::wstring>& params);\r
\r
}
\ No newline at end of file
tbb::concurrent_bounded_queue<safe_ptr<core::basic_frame>> frame_buffer_;\r
\r
std::shared_ptr<flash_renderer> renderer_;\r
- std::shared_ptr<core::frame_factory> frame_factory_;\r
- core::video_format_desc format_desc_;\r
+ safe_ptr<core::frame_factory> frame_factory_;\r
+ const core::video_format_desc format_desc_;\r
\r
executor executor_;\r
\r
public:\r
- flash_producer(const std::wstring& filename) \r
+ flash_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) \r
: filename_(filename) \r
, tail_(core::basic_frame::empty()) \r
+ , frame_factory_(frame_factory)\r
+ , format_desc_(frame_factory->get_video_format_desc())\r
, executor_(L"flash_producer")\r
{ \r
if(!boost::filesystem::exists(filename))\r
BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename))); \r
\r
+ frame_buffer_.set_capacity(4);\r
+ graph_ = diagnostics::create_graph([this]{return print();});\r
+ graph_->set_color("output-buffer", diagnostics::color(0.0f, 1.0f, 0.0f));\r
+ \r
+ executor_.begin_invoke([=]\r
+ {\r
+ init_renderer();\r
+ });\r
+\r
fps_ = 0;\r
executor_.start();\r
}\r
renderer_ = nullptr;\r
}); \r
}\r
- \r
- virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
- { \r
- frame_factory_ = frame_factory;\r
- format_desc_ = frame_factory->get_video_format_desc();\r
- frame_buffer_.set_capacity(4);\r
- graph_ = diagnostics::create_graph([this]{return print();});\r
- graph_->set_color("output-buffer", diagnostics::color(0.0f, 1.0f, 0.0f));\r
\r
- executor_.begin_invoke([=]\r
- {\r
- init_renderer();\r
- });\r
- }\r
- \r
virtual safe_ptr<core::basic_frame> receive()\r
{ \r
if(!renderer_)\r
}\r
};\r
\r
-safe_ptr<core::frame_producer> create_flash_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_flash_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
{\r
std::wstring filename = env::template_folder() + L"\\" + params[0];\r
\r
- return make_safe<flash_producer>(filename);\r
+ return make_safe<flash_producer>(frame_factory, filename);\r
}\r
\r
std::wstring find_flash_template(const std::wstring& template_name)\r
\r
namespace caspar {\r
\r
-safe_ptr<core::frame_producer> create_flash_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_flash_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
\r
std::wstring find_flash_template(const std::wstring& templateName);\r
\r
\r
struct image_producer : public core::frame_producer\r
{ \r
- std::shared_ptr<core::frame_factory> frame_factory_;\r
std::wstring filename_;\r
safe_ptr<core::basic_frame> frame_;\r
- decltype(load_image(L"")) bitmap_;\r
\r
- explicit image_producer(const std::wstring& filename) \r
+ explicit image_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) \r
: filename_(filename)\r
, frame_(core::basic_frame::empty()) \r
- , bitmap_(load_image(filename_))\r
{\r
- FreeImage_FlipVertical(bitmap_.get());\r
+ auto bitmap = load_image(filename_);\r
+ FreeImage_FlipVertical(bitmap.get());\r
+ auto frame = frame_factory->create_frame(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()));\r
+ std::copy_n(FreeImage_GetBits(bitmap.get()), frame->image_data().size(), frame->image_data().begin());\r
+ frame_ = std::move(frame);\r
}\r
\r
virtual safe_ptr<core::basic_frame> receive(){return frame_;}\r
\r
- virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
- {\r
- frame_factory_ = frame_factory;\r
- auto frame = frame_factory->create_frame(FreeImage_GetWidth(bitmap_.get()), FreeImage_GetHeight(bitmap_.get()));\r
- std::copy_n(FreeImage_GetBits(bitmap_.get()), frame->image_data().size(), frame->image_data().begin());\r
- bitmap_.reset();\r
- frame_ = std::move(frame);\r
- }\r
\r
virtual std::wstring print() const\r
{\r
}\r
};\r
\r
-safe_ptr<core::frame_producer> create_image_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_image_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
{\r
static const std::vector<std::wstring> extensions = list_of(L"png")(L"tga")(L"bmp")(L"jpg")(L"jpeg");\r
std::wstring filename = env::media_folder() + L"\\" + params[0];\r
if(ext == extensions.end())\r
return core::frame_producer::empty();\r
\r
- return make_safe<image_producer>(filename + L"." + *ext);\r
+ return make_safe<image_producer>(frame_factory, filename + L"." + *ext);\r
}\r
\r
\r
\r
namespace caspar { \r
\r
-safe_ptr<core::frame_producer> create_image_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_image_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
\r
}
\ No newline at end of file
executor executor_;\r
public:\r
\r
- silverlight_producer() : executor_(L"silverlight"){}\r
- \r
- virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
+ silverlight_producer(const safe_ptr<core::frame_factory>& frame_factory) : executor_(L"silverlight")\r
{\r
executor_.start();\r
executor_.invoke([=]\r
renderer_.reset(new silverlight_renderer(frame_factory));\r
});\r
}\r
- \r
+ \r
virtual safe_ptr<core::basic_frame> receive()\r
{\r
executor_.begin_invoke([=]\r
std::wstring print() const{ return L"silverlight"; } \r
};\r
\r
-safe_ptr<core::frame_producer> create_silverlight_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_silverlight_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
{\r
//std::wstring filename = env::template_folder() + L"\\" + params[0] + L".xap";\r
//if(!boost::filesystem::exists(filename))\r
if(params[0] != L"SILVER")\r
return core::frame_producer::empty();\r
\r
- return make_safe<silverlight_producer>();\r
+ return make_safe<silverlight_producer>(frame_factory);\r
}\r
\r
}
\ No newline at end of file
\r
namespace caspar {\r
\r
-safe_ptr<core::frame_producer> create_silverlight_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_silverlight_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
\r
}\r
\r
void AMCPCommand::Clear() \r
{\r
- pChannel_->producer().clear();\r
+ pChannel_->producer()->clear();\r
pClientInfo_.reset();\r
channelIndex_ = 0;\r
_parameters.clear();\r
\r
int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
if(layer != std::numeric_limits<int>::min()) \r
- GetChannel()->mixer().apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
else\r
- GetChannel()->mixer().apply_image_transform(transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(transform, duration, tween);\r
}\r
else if(_parameters[1] == L"GAIN")\r
{\r
\r
int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
if(layer != std::numeric_limits<int>::min())\r
- GetChannel()->mixer().apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
else\r
- GetChannel()->mixer().apply_image_transform(transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(transform, duration, tween);\r
}\r
else if(_parameters[1] == L"FILL_RECT")\r
{\r
\r
int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
if(layer != std::numeric_limits<int>::min())\r
- GetChannel()->mixer().apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
else\r
- GetChannel()->mixer().apply_image_transform(transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(transform, duration, tween);\r
}\r
else if(_parameters[1] == L"KEY_RECT")\r
{\r
\r
int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
if(layer != std::numeric_limits<int>::min())\r
- GetChannel()->mixer().apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
else\r
- GetChannel()->mixer().apply_image_transform(transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(transform, duration, tween);\r
}\r
else if(_parameters[1] == L"GRID")\r
{\r
transform.set_key_scale(delta, delta);\r
return transform;\r
};\r
- GetChannel()->mixer().apply_image_transform(index, transform, duration, tween);\r
+ GetChannel()->mixer()->apply_image_transform(index, transform, duration, tween);\r
}\r
}\r
}\r
else if(_parameters[1] == L"RESET")\r
{\r
int duration = _parameters.size() > 1 ? lexical_cast_or_default(_parameters[2], 0) : 0;\r
- GetChannel()->mixer().reset_image_transform(duration);\r
+ GetChannel()->mixer()->reset_image_transform(duration);\r
}\r
}\r
else if(_parameters[0] == L"AUDIO")\r
\r
int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
if(layer != std::numeric_limits<int>::min())\r
- GetChannel()->mixer().apply_audio_transform(GetLayerIndex(), transform, duration);\r
+ GetChannel()->mixer()->apply_audio_transform(GetLayerIndex(), transform, duration);\r
else\r
- GetChannel()->mixer().apply_audio_transform(transform, duration);\r
+ GetChannel()->mixer()->apply_audio_transform(transform, duration);\r
}\r
else if(_parameters[1] == L"RESET")\r
{\r
int duration = _parameters.size() > 1 ? lexical_cast_or_default(_parameters[2], 0) : 0;\r
- GetChannel()->mixer().reset_audio_transform(duration);\r
+ GetChannel()->mixer()->reset_audio_transform(duration);\r
}\r
}\r
else if(_parameters[0] == L"RESET")\r
{\r
int duration = _parameters.size() > 1 ? lexical_cast_or_default(_parameters[2], 0) : 0;\r
- GetChannel()->mixer().reset_image_transform(duration);\r
- GetChannel()->mixer().reset_audio_transform(duration);\r
+ GetChannel()->mixer()->reset_image_transform(duration);\r
+ GetChannel()->mixer()->reset_audio_transform(duration);\r
}\r
\r
SetReplyString(TEXT("202 MIXER OK\r\n"));\r
int l1 = GetLayerIndex();\r
int l2 = boost::lexical_cast<int>(strs.at(1));\r
\r
- ch1->producer().swap_layer(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(ch2->producer());\r
+ ch1->producer()->swap(*ch2->producer());\r
}\r
\r
CASPAR_LOG(info) << "Swapped successfully";\r
//Perform loading of the clip\r
try\r
{\r
- GetChannel()->consumer().add(GetLayerIndex(), create_consumer(_parameters));\r
+ GetChannel()->consumer()->add(GetLayerIndex(), create_consumer(_parameters));\r
\r
CASPAR_LOG(info) << "Added " << _parameters[0] << TEXT(" successfully");\r
\r
//Perform loading of the clip\r
try\r
{\r
- GetChannel()->consumer().remove(GetLayerIndex());\r
+ GetChannel()->consumer()->remove(GetLayerIndex());\r
\r
SetReplyString(TEXT("202 REMOVE OK\r\n"));\r
\r
try\r
{\r
_parameters[0] = _parameters[0];\r
- auto pFP = create_producer(_parameters); \r
- GetChannel()->producer().load(GetLayerIndex(), pFP, false, true);\r
+ auto pFP = create_producer(GetChannel()->mixer(), _parameters); \r
+ GetChannel()->producer()->load(GetLayerIndex(), pFP, false, true);\r
\r
CASPAR_LOG(info) << "Loaded " << _parameters[0] << TEXT(" successfully");\r
\r
try\r
{\r
_parameters[0] = _parameters[0];\r
- auto pFP = create_producer(_parameters);\r
+ auto pFP = create_producer(GetChannel()->mixer(), _parameters);\r
if(pFP == frame_producer::empty())\r
BOOST_THROW_EXCEPTION(file_not_found() << msg_info(_parameters.size() > 0 ? narrow(_parameters[0]) : ""));\r
\r
- auto pFP2 = make_safe<core::transition_producer>(pFP, transitionInfo);\r
+ auto pFP2 = create_transition_producer(GetChannel()->get_video_format_desc(), pFP, transitionInfo);\r
bool autoPlay = std::find(_parameters.begin(), _parameters.end(), TEXT("AUTOPLAY")) != _parameters.end();\r
- GetChannel()->producer().load(GetLayerIndex(), pFP2, autoPlay); // TODO: LOOP\r
+ GetChannel()->producer()->load(GetLayerIndex(), pFP2, autoPlay); // TODO: LOOP\r
\r
CASPAR_LOG(info) << "Loaded " << _parameters[0] << TEXT(" successfully to background");\r
SetReplyString(TEXT("202 LOADBG OK\r\n"));\r
{\r
try\r
{\r
- GetChannel()->producer().pause(GetLayerIndex());\r
+ GetChannel()->producer()->pause(GetLayerIndex());\r
SetReplyString(TEXT("202 PAUSE OK\r\n"));\r
return true;\r
}\r
{\r
try\r
{\r
- GetChannel()->producer().play(GetLayerIndex());\r
+ GetChannel()->producer()->play(GetLayerIndex());\r
SetReplyString(TEXT("202 PLAY OK\r\n"));\r
return true;\r
}\r
{\r
try\r
{\r
- GetChannel()->producer().stop(GetLayerIndex());\r
+ GetChannel()->producer()->stop(GetLayerIndex());\r
SetReplyString(TEXT("202 STOP OK\r\n"));\r
return true;\r
}\r
{\r
int index = GetLayerIndex(std::numeric_limits<int>::min());\r
if(index != std::numeric_limits<int>::min())\r
- GetChannel()->producer().clear(index);\r
+ GetChannel()->producer()->clear(index);\r
else\r
- GetChannel()->producer().clear();\r
+ GetChannel()->producer()->clear();\r
\r
SetReplyString(TEXT("202 CLEAR OK\r\n"));\r
\r
\r
bool CGCommand::DoExecuteClear() \r
{\r
- get_default_cg_producer(safe_ptr<core::channel>(GetChannel()), GetLayerIndex(cg_producer::DEFAULT_LAYER))->clear();\r
+ GetChannel()->producer()->clear(GetLayerIndex(cg_producer::DEFAULT_LAYER));\r
SetReplyString(TEXT("202 CG OK\r\n"));\r
return true;\r
}\r
else if(state_ == 1)\r
get_default_cg_producer(pCIIStrategy_->GetChannel())->stop(layer_, 0);\r
else if(state_ == 2)\r
- get_default_cg_producer(pCIIStrategy_->GetChannel())->clear();\r
+ pCIIStrategy_->GetChannel()->producer()->clear(cg_producer::DEFAULT_LAYER);\r
else if(state_ == 3)\r
get_default_cg_producer(pCIIStrategy_->GetChannel())->play(layer_);\r
}\r
return;\r
}\r
\r
- auto producer = create_flash_producer(boost::assign::list_of(env::template_folder()+TEXT("CG.fth")));\r
+ auto producer = create_flash_producer(this->GetChannel()->mixer(), boost::assign::list_of(env::template_folder()+TEXT("CG.fth")));\r
\r
std::wstringstream flashParam;\r
flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>1</number><string>") << currentProfile_ << '/' << templateName << TEXT("</string><number>0</number><true/><string> </string><string><![CDATA[ ") << xmlData << TEXT(" ]]></string></arguments></invoke>");\r
{\r
try\r
{\r
- pChannel_->producer().load(0, GetPreparedTemplate(titleName));\r
- pChannel_->producer().play(0);\r
+ pChannel_->producer()->load(0, GetPreparedTemplate(titleName));\r
+ pChannel_->producer()->play(0);\r
\r
CASPAR_LOG(info) << L"Displayed title " << titleName ;\r
}\r
transition.type = transition::mix;\r
transition.duration = 12;\r
\r
- auto pFP = create_producer(boost::assign::list_of(filename));\r
- auto pTransition = make_safe<core::transition_producer>(pFP, transition);\r
+ auto pFP = create_producer(GetChannel()->mixer(), boost::assign::list_of(filename));\r
+ auto pTransition = create_transition_producer(GetChannel()->get_video_format_desc(), pFP, transition);\r
\r
try\r
{\r
- pChannel_->producer().load(0, pTransition);\r
+ pChannel_->producer()->load(0, pTransition);\r
}\r
catch(...)\r
{\r
return;\r
}\r
\r
- pChannel_->producer().play(0);\r
+ pChannel_->producer()->play(0);\r
\r
CASPAR_LOG(info) << L"Displayed " << filename;\r
}\r
\r
if(currentCommand_.command_ == CLKCommand::CLKReset) \r
{\r
- get_default_cg_producer(pChannel_)->clear();\r
+ pChannel_->producer()->clear(cg_producer::DEFAULT_LAYER);\r
bClockLoaded_ = false;\r
\r
CASPAR_LOG(info) << L"CLK: Recieved and executed reset-command";\r
stretch = stretch::uniform_to_fill;\r
\r
bool windowed = xml_consumer.second.get("windowed", false);\r
- channels_.back()->consumer().add(index++, ogl_consumer(device, stretch, windowed));\r
+ channels_.back()->consumer()->add(index++, ogl_consumer(device, stretch, windowed));\r
}\r
else if(name == "bluefish") \r
- channels_.back()->consumer().add(index++, bluefish_consumer(xml_consumer.second.get("device", 0), \r
+ channels_.back()->consumer()->add(index++, bluefish_consumer(xml_consumer.second.get("device", 0), \r
xml_consumer.second.get("embedded-audio", true))); \r
else if(name == "decklink")\r
- channels_.back()->consumer().add(index++, decklink_consumer(xml_consumer.second.get("device", 0), \r
+ channels_.back()->consumer()->add(index++, decklink_consumer(xml_consumer.second.get("device", 0), \r
xml_consumer.second.get("embedded-audio", true), \r
xml_consumer.second.get("internal-key", false)));\r
else if(name == "audio")\r
- channels_.back()->consumer().add(index++, oal_consumer()); \r
+ channels_.back()->consumer()->add(index++, oal_consumer()); \r
}\r
catch(...)\r
{\r
</diagnostics>\r
<channels>\r
<channel>\r
- <videomode>PAL</videomode>\r
+ <videomode>1080i5000</videomode>\r
<consumers>\r
- <!--<decklink>\r
+ <!--decklink>\r
<device>1</device>\r
<embedded-audio>true</embedded-audio>\r
<internal-key>false</internal-key>\r
- </decklink>-->\r
+ </decklink-->\r
<ogl>\r
<device>1</device>\r
<stretch>uniform</stretch>\r