#pragma warning (disable : 4244)\r
#endif\r
\r
-#include "frame_consumer_device.h"\r
+#include "output.h"\r
\r
#include "../video_channel_context.h"\r
\r
\r
namespace caspar { namespace core {\r
\r
-struct frame_consumer_device::implementation\r
+struct output::implementation\r
{ \r
typedef std::pair<safe_ptr<const read_frame>, safe_ptr<const read_frame>> fill_and_key;\r
\r
\r
void execute(const safe_ptr<read_frame>& frame)\r
{ \r
- if(!has_synchronization_clock())\r
- timer_.tick(1.0/channel_.get_format_desc().fps);\r
+ try\r
+ { \r
+ if(!has_synchronization_clock())\r
+ timer_.tick(1.0/channel_.get_format_desc().fps);\r
\r
- auto fill = frame;\r
- auto key = get_key_frame(frame);\r
+ auto fill = frame;\r
+ auto key = get_key_frame(frame);\r
\r
- for_each_consumer([&](safe_ptr<frame_consumer>& consumer)\r
+ auto it = consumers_.begin();\r
+ while(it != consumers_.end())\r
+ {\r
+ try\r
+ {\r
+ auto consumer = it->second;\r
+\r
+ if(consumer->get_video_format_desc() != channel_.get_format_desc())\r
+ consumer->initialize(channel_.get_format_desc());\r
+\r
+ auto frame = consumer->key_only() ? key : fill;\r
+\r
+ if(static_cast<size_t>(frame->image_data().size()) == consumer->get_video_format_desc().size)\r
+ consumer->send(frame);\r
+\r
+ ++it;\r
+ }\r
+ catch(...)\r
+ {\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ consumers_.erase(it++);\r
+ CASPAR_LOG(error) << print() << L" " << it->second->print() << L" Removed.";\r
+ }\r
+ }\r
+ }\r
+ catch(...)\r
{\r
- if(consumer->get_video_format_desc() != channel_.get_format_desc())\r
- consumer->initialize(channel_.get_format_desc());\r
-\r
- auto frame = consumer->key_only() ? key : fill;\r
-\r
- if(static_cast<size_t>(frame->image_data().size()) == consumer->get_video_format_desc().size)\r
- consumer->send(frame);\r
- });\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ }\r
}\r
\r
private:\r
-\r
+ \r
bool has_synchronization_clock()\r
{\r
return std::any_of(consumers_.begin(), consumers_.end(), [](const decltype(*consumers_.begin())& p)\r
\r
return make_safe<read_frame>();\r
}\r
- \r
- void for_each_consumer(const std::function<void(safe_ptr<frame_consumer>& consumer)>& func)\r
- {\r
- auto it = consumers_.begin();\r
- while(it != consumers_.end())\r
- {\r
- try\r
- {\r
- func(it->second);\r
- ++it;\r
- }\r
- catch(...)\r
- {\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- consumers_.erase(it++);\r
- CASPAR_LOG(error) << print() << L" " << it->second->print() << L" Removed.";\r
- }\r
- }\r
- }\r
+ \r
\r
std::wstring print() const\r
{\r
- return L"frame_consumer_device";\r
+ return L"output";\r
}\r
};\r
\r
-frame_consumer_device::frame_consumer_device(video_channel_context& video_channel) \r
+output::output(video_channel_context& video_channel) \r
: impl_(new implementation(video_channel)){}\r
-void frame_consumer_device::add(int index, safe_ptr<frame_consumer>&& consumer){impl_->add(index, std::move(consumer));}\r
-void frame_consumer_device::remove(int index){impl_->remove(index);}\r
-void frame_consumer_device::execute(const safe_ptr<read_frame>& frame) {impl_->execute(frame); }\r
+void output::add(int index, safe_ptr<frame_consumer>&& consumer){impl_->add(index, std::move(consumer));}\r
+void output::remove(int index){impl_->remove(index);}\r
+void output::execute(const safe_ptr<read_frame>& frame) {impl_->execute(frame); }\r
}}
\ No newline at end of file
\r
class video_channel_context;;\r
\r
-class frame_consumer_device : boost::noncopyable\r
+class output : boost::noncopyable\r
{\r
public:\r
- explicit frame_consumer_device(video_channel_context& video_channel);\r
+ explicit output(video_channel_context& video_channel);\r
\r
void add(int index, safe_ptr<frame_consumer>&& consumer);\r
void remove(int index);\r
<ItemGroup>\r
<ClInclude Include="video_channel.h" />\r
<ClInclude Include="video_channel_context.h" />\r
- <ClInclude Include="consumer\frame_consumer_device.h" />\r
+ <ClInclude Include="consumer\output.h" />\r
<ClInclude Include="consumer\frame_consumer.h" />\r
<ClInclude Include="mixer\audio\audio_mixer.h" />\r
- <ClInclude Include="mixer\frame_mixer_device.h" />\r
+ <ClInclude Include="mixer\mixer.h" />\r
<ClInclude Include="mixer\gpu\device_buffer.h" />\r
<ClInclude Include="mixer\gpu\host_buffer.h" />\r
<ClInclude Include="mixer\gpu\ogl_device.h" />\r
<ClInclude Include="producer\frame\image_transform.h" />\r
<ClInclude Include="producer\frame\pixel_format.h" />\r
<ClInclude Include="producer\frame_producer.h" />\r
- <ClInclude Include="producer\frame_producer_device.h" />\r
+ <ClInclude Include="producer\stage.h" />\r
<ClInclude Include="producer\layer.h" />\r
<ClInclude Include="producer\separated\separated_producer.h" />\r
<ClInclude Include="producer\transition\transition_producer.h" />\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
</ClCompile>\r
- <ClCompile Include="consumer\frame_consumer_device.cpp">\r
+ <ClCompile Include="consumer\output.cpp">\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
</ClCompile>\r
- <ClCompile Include="mixer\frame_mixer_device.cpp">\r
+ <ClCompile Include="mixer\mixer.cpp">\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
</ClCompile>\r
- <ClCompile Include="producer\frame_producer_device.cpp">\r
+ <ClCompile Include="producer\stage.cpp">\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
<ClInclude Include="producer\transition\transition_producer.h">\r
<Filter>producer\transition</Filter>\r
</ClInclude>\r
- <ClInclude Include="consumer\frame_consumer_device.h">\r
- <Filter>consumer</Filter>\r
- </ClInclude>\r
<ClInclude Include="consumer\frame_consumer.h">\r
<Filter>consumer</Filter>\r
</ClInclude>\r
- <ClInclude Include="producer\frame_producer_device.h">\r
- <Filter>producer</Filter>\r
- </ClInclude>\r
<ClInclude Include="producer\frame_producer.h">\r
<Filter>producer</Filter>\r
</ClInclude>\r
<ClInclude Include="mixer\write_frame.h">\r
<Filter>mixer</Filter>\r
</ClInclude>\r
- <ClInclude Include="mixer\frame_mixer_device.h">\r
- <Filter>mixer</Filter>\r
- </ClInclude>\r
<ClInclude Include="video_channel.h" />\r
<ClInclude Include="video_channel_context.h" />\r
<ClInclude Include="StdAfx.h" />\r
+ <ClInclude Include="mixer\mixer.h">\r
+ <Filter>mixer</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="producer\stage.h">\r
+ <Filter>producer</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="consumer\output.h">\r
+ <Filter>consumer</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ClCompile Include="producer\transition\transition_producer.cpp">\r
<ClCompile Include="consumer\frame_consumer.cpp">\r
<Filter>consumer</Filter>\r
</ClCompile>\r
- <ClCompile Include="consumer\frame_consumer_device.cpp">\r
- <Filter>consumer</Filter>\r
- </ClCompile>\r
<ClCompile Include="producer\frame_producer.cpp">\r
<Filter>producer</Filter>\r
</ClCompile>\r
- <ClCompile Include="producer\frame_producer_device.cpp">\r
- <Filter>producer</Filter>\r
- </ClCompile>\r
<ClCompile Include="producer\color\color_producer.cpp">\r
<Filter>producer\color</Filter>\r
</ClCompile>\r
<Filter>producer\frame</Filter>\r
</ClCompile>\r
<ClCompile Include="video_format.cpp" />\r
- <ClCompile Include="mixer\frame_mixer_device.cpp">\r
- <Filter>mixer</Filter>\r
- </ClCompile>\r
<ClCompile Include="mixer\image\image_mixer.cpp">\r
<Filter>mixer\image</Filter>\r
</ClCompile>\r
<ClCompile Include="video_channel.cpp" />\r
<ClCompile Include="StdAfx.cpp" />\r
<ClCompile Include="video_channel_context.cpp" />\r
+ <ClCompile Include="mixer\mixer.cpp">\r
+ <Filter>mixer</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="producer\stage.cpp">\r
+ <Filter>producer</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="consumer\output.cpp">\r
+ <Filter>consumer</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
void audio_mixer::visit(core::write_frame& frame){impl_->visit(frame);}\r
void audio_mixer::end(){impl_->end();}\r
std::vector<int16_t> audio_mixer::mix(){return impl_->mix();}\r
+audio_mixer& audio_mixer::operator=(audio_mixer&& other)\r
+{\r
+ impl_ = std::move(other.impl_);\r
+ return *this;\r
+}\r
\r
}}
\ No newline at end of file
virtual void end();\r
\r
std::vector<int16_t> mix();\r
-\r
+ \r
+ audio_mixer& operator=(audio_mixer&& other);\r
private:\r
struct implementation;\r
std::shared_ptr<implementation> impl_;\r
safe_ptr<write_frame> image_mixer::create_frame(void* tag, const core::pixel_format_desc& desc){return impl_->create_frame(tag, desc);}\r
void image_mixer::begin_layer(){impl_->begin_layer();}\r
void image_mixer::end_layer(){impl_->end_layer();}\r
+image_mixer& image_mixer::operator=(image_mixer&& other)\r
+{\r
+ impl_ = std::move(other.impl_);\r
+ return *this;\r
+}\r
\r
}}
\ No newline at end of file
\r
void begin_layer();\r
void end_layer();\r
+\r
+ image_mixer& operator=(image_mixer&& other);\r
\r
safe_ptr<host_buffer> render();\r
\r
*/\r
#include "../StdAfx.h"\r
\r
-#include "frame_mixer_device.h"\r
+#include "mixer.h"\r
\r
#include "read_frame.h"\r
#include "write_frame.h"\r
}\r
};\r
\r
-struct frame_mixer_device::implementation : boost::noncopyable\r
+struct mixer::implementation : boost::noncopyable\r
{ \r
video_channel_context& channel_;\r
\r
}\r
\r
safe_ptr<read_frame> execute(const std::map<int, safe_ptr<core::basic_frame>>& frames)\r
- { \r
- auto image = mix_image(frames);\r
- auto audio = mix_audio(frames);\r
+ { \r
+ try\r
+ {\r
+ auto image = mix_image(frames);\r
+ auto audio = mix_audio(frames);\r
\r
- return make_safe<read_frame>(std::move(image), std::move(audio));\r
+ return make_safe<read_frame>(std::move(image), std::move(audio));\r
+ }\r
+ catch(...)\r
+ {\r
+ channel_.ogl().gc();\r
+ image_mixer_ = image_mixer(channel_);\r
+ audio_mixer_ = audio_mixer();\r
+ channel_.ogl().gc();\r
+\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ return make_safe<read_frame>();\r
+ }\r
}\r
\r
safe_ptr<core::write_frame> create_frame(void* tag, const core::pixel_format_desc& desc)\r
\r
std::wstring print() const\r
{\r
- return L"frame_mixer_device";\r
+ return L"mixer";\r
}\r
\r
private:\r
}\r
};\r
\r
-frame_mixer_device::frame_mixer_device(video_channel_context& video_channel) : impl_(new implementation(video_channel)){}\r
-safe_ptr<core::read_frame> frame_mixer_device::execute(const std::map<int, safe_ptr<core::basic_frame>>& frames){ return impl_->execute(frames);}\r
-core::video_format_desc frame_mixer_device::get_video_format_desc() const { return impl_->channel_.get_format_desc(); }\r
-safe_ptr<core::write_frame> frame_mixer_device::create_frame(void* tag, const core::pixel_format_desc& desc){ return impl_->create_frame(tag, desc); } \r
-safe_ptr<core::write_frame> frame_mixer_device::create_frame(void* tag, size_t width, size_t height, core::pixel_format::type pix_fmt)\r
+mixer::mixer(video_channel_context& video_channel) : impl_(new implementation(video_channel)){}\r
+safe_ptr<core::read_frame> mixer::execute(const std::map<int, safe_ptr<core::basic_frame>>& frames){ return impl_->execute(frames);}\r
+core::video_format_desc mixer::get_video_format_desc() const { return impl_->channel_.get_format_desc(); }\r
+safe_ptr<core::write_frame> mixer::create_frame(void* tag, const core::pixel_format_desc& desc){ return impl_->create_frame(tag, desc); } \r
+safe_ptr<core::write_frame> mixer::create_frame(void* tag, size_t width, size_t height, core::pixel_format::type pix_fmt)\r
{\r
// Create bgra frame\r
core::pixel_format_desc desc;\r
desc.planes.push_back( core::pixel_format_desc::plane(width, height, 4));\r
return create_frame(tag, desc);\r
}\r
-void frame_mixer_device::set_image_transform(const core::image_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform<core::image_transform>(transform, mix_duration, tween);}\r
-void frame_mixer_device::set_image_transform(int index, const core::image_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform<core::image_transform>(index, transform, mix_duration, tween);}\r
-void frame_mixer_device::set_audio_transform(const core::audio_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform<core::audio_transform>(transform, mix_duration, tween);}\r
-void frame_mixer_device::set_audio_transform(int index, const core::audio_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform<core::audio_transform>(index, transform, mix_duration, tween);}\r
-void frame_mixer_device::apply_image_transform(const std::function<core::image_transform(core::image_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform<core::image_transform>(transform, mix_duration, tween);}\r
-void frame_mixer_device::apply_image_transform(int index, const std::function<core::image_transform(core::image_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform<core::image_transform>(index, transform, mix_duration, tween);}\r
-void frame_mixer_device::apply_audio_transform(const std::function<core::audio_transform(core::audio_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform<core::audio_transform>(transform, mix_duration, tween);}\r
-void frame_mixer_device::apply_audio_transform(int index, const std::function<core::audio_transform(core::audio_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform<core::audio_transform>(index, transform, mix_duration, tween);}\r
-void frame_mixer_device::reset_image_transform(unsigned int mix_duration, const std::wstring& tween){impl_->reset_transform<core::image_transform>(mix_duration, tween);}\r
-void frame_mixer_device::reset_image_transform(int index, unsigned int mix_duration, const std::wstring& tween){impl_->reset_transform<core::image_transform>(index, mix_duration, tween);}\r
-void frame_mixer_device::reset_audio_transform(unsigned int mix_duration, const std::wstring& tween){impl_->reset_transform<core::audio_transform>(mix_duration, tween);}\r
-void frame_mixer_device::reset_audio_transform(int index, unsigned int mix_duration, const std::wstring& tween){impl_->reset_transform<core::audio_transform>(index, mix_duration, tween);}\r
+void mixer::set_image_transform(const core::image_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform<core::image_transform>(transform, mix_duration, tween);}\r
+void mixer::set_image_transform(int index, const core::image_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform<core::image_transform>(index, transform, mix_duration, tween);}\r
+void mixer::set_audio_transform(const core::audio_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform<core::audio_transform>(transform, mix_duration, tween);}\r
+void mixer::set_audio_transform(int index, const core::audio_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform<core::audio_transform>(index, transform, mix_duration, tween);}\r
+void mixer::apply_image_transform(const std::function<core::image_transform(core::image_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform<core::image_transform>(transform, mix_duration, tween);}\r
+void mixer::apply_image_transform(int index, const std::function<core::image_transform(core::image_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform<core::image_transform>(index, transform, mix_duration, tween);}\r
+void mixer::apply_audio_transform(const std::function<core::audio_transform(core::audio_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform<core::audio_transform>(transform, mix_duration, tween);}\r
+void mixer::apply_audio_transform(int index, const std::function<core::audio_transform(core::audio_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform<core::audio_transform>(index, transform, mix_duration, tween);}\r
+void mixer::reset_image_transform(unsigned int mix_duration, const std::wstring& tween){impl_->reset_transform<core::image_transform>(mix_duration, tween);}\r
+void mixer::reset_image_transform(int index, unsigned int mix_duration, const std::wstring& tween){impl_->reset_transform<core::image_transform>(index, mix_duration, tween);}\r
+void mixer::reset_audio_transform(unsigned int mix_duration, const std::wstring& tween){impl_->reset_transform<core::audio_transform>(mix_duration, tween);}\r
+void mixer::reset_audio_transform(int index, unsigned int mix_duration, const std::wstring& tween){impl_->reset_transform<core::audio_transform>(index, mix_duration, tween);}\r
}}
\ No newline at end of file
class image_transform;\r
class video_channel_context;;\r
\r
-class frame_mixer_device : public core::frame_factory\r
+class mixer : public core::frame_factory\r
{\r
public: \r
- explicit frame_mixer_device(video_channel_context& video_channel);\r
+ explicit mixer(video_channel_context& video_channel);\r
\r
safe_ptr<core::read_frame> execute(const std::map<int, safe_ptr<core::basic_frame>>& frames); // nothrow\r
\r
\r
#include "../StdAfx.h"\r
\r
-#include "frame_producer_device.h"\r
+#include "stage.h"\r
\r
#include "../video_channel_context.h"\r
\r
virtual void set_leading_producer(const safe_ptr<frame_producer>& producer) {producer_->set_leading_producer(producer);}\r
};\r
\r
-struct frame_producer_device::implementation : boost::noncopyable\r
+struct stage::implementation : boost::noncopyable\r
{ \r
std::map<int, layer> layers_; \r
typedef std::map<int, layer>::value_type layer_t;\r
{ \r
std::map<int, safe_ptr<basic_frame>> frames;\r
\r
- // Allocate placeholders.\r
- BOOST_FOREACH(auto layer, layers_)\r
- frames[layer.first] = basic_frame::empty();\r
-\r
- // Render layers\r
- tbb::parallel_for_each(layers_.begin(), layers_.end(), [&](layer_t& layer)\r
+ try\r
+ {\r
+ // Allocate placeholders.\r
+ BOOST_FOREACH(auto layer, layers_)\r
+ frames[layer.first] = basic_frame::empty();\r
+\r
+ // Render layers\r
+ tbb::parallel_for_each(layers_.begin(), layers_.end(), [&](layer_t& layer)\r
+ {\r
+ frames[layer.first] = layer.second.receive();\r
+ });\r
+ }\r
+ catch(...)\r
{\r
- frames[layer.first] = layer.second.receive();\r
- });\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ }\r
\r
return frames;\r
}\r
channel_.execution().invoke([&]{layers_[index].swap(layers_[other_index]);});\r
}\r
\r
- void swap_layer(int index, size_t other_index, frame_producer_device& other)\r
+ void swap_layer(int index, size_t other_index, stage& other)\r
{\r
if(other.impl_.get() == this)\r
swap_layer(index, other_index);\r
}\r
}\r
\r
- void swap(frame_producer_device& other)\r
+ void swap(stage& other)\r
{\r
if(other.impl_.get() == this)\r
return;\r
}\r
};\r
\r
-frame_producer_device::frame_producer_device(video_channel_context& video_channel) : impl_(new implementation(video_channel)){}\r
-void frame_producer_device::swap(frame_producer_device& other){impl_->swap(other);}\r
-void frame_producer_device::load(int index, const safe_ptr<frame_producer>& producer, bool preview){impl_->load(index, producer, preview);}\r
-void frame_producer_device::pause(int index){impl_->pause(index);}\r
-void frame_producer_device::play(int index){impl_->play(index);}\r
-void frame_producer_device::stop(int index){impl_->stop(index);}\r
-void frame_producer_device::clear(int index){impl_->clear(index);}\r
-void frame_producer_device::clear(){impl_->clear();}\r
-void frame_producer_device::swap_layer(int index, size_t other_index){impl_->swap_layer(index, other_index);}\r
-void frame_producer_device::swap_layer(int index, size_t other_index, frame_producer_device& other){impl_->swap_layer(index, other_index, other);}\r
-boost::unique_future<safe_ptr<frame_producer>> frame_producer_device::foreground(size_t index) {return impl_->foreground(index);}\r
-boost::unique_future<safe_ptr<frame_producer>> frame_producer_device::background(size_t index) {return impl_->background(index);}\r
-std::map<int, safe_ptr<basic_frame>> frame_producer_device::execute(){return impl_->execute();}\r
+stage::stage(video_channel_context& video_channel) : impl_(new implementation(video_channel)){}\r
+void stage::swap(stage& other){impl_->swap(other);}\r
+void stage::load(int index, const safe_ptr<frame_producer>& producer, bool preview){impl_->load(index, producer, preview);}\r
+void stage::pause(int index){impl_->pause(index);}\r
+void stage::play(int index){impl_->play(index);}\r
+void stage::stop(int index){impl_->stop(index);}\r
+void stage::clear(int index){impl_->clear(index);}\r
+void stage::clear(){impl_->clear();}\r
+void stage::swap_layer(int index, size_t other_index){impl_->swap_layer(index, other_index);}\r
+void stage::swap_layer(int index, size_t other_index, stage& other){impl_->swap_layer(index, other_index, other);}\r
+boost::unique_future<safe_ptr<frame_producer>> stage::foreground(size_t index) {return impl_->foreground(index);}\r
+boost::unique_future<safe_ptr<frame_producer>> stage::background(size_t index) {return impl_->background(index);}\r
+std::map<int, safe_ptr<basic_frame>> stage::execute(){return impl_->execute();}\r
}}
\ No newline at end of file
struct video_format_desc;\r
class video_channel_context;;\r
\r
-class frame_producer_device : boost::noncopyable\r
+class stage : boost::noncopyable\r
{\r
public:\r
- explicit frame_producer_device(video_channel_context& video_channel);\r
+ explicit stage(video_channel_context& video_channel);\r
\r
- void swap(frame_producer_device& other);\r
+ void swap(stage& other);\r
\r
std::map<int, safe_ptr<basic_frame>> execute();\r
\r
void clear(int index);\r
void clear(); \r
void swap_layer(int index, size_t other_index);\r
- void swap_layer(int index, size_t other_index, frame_producer_device& other);\r
+ void swap_layer(int index, size_t other_index, stage& other);\r
boost::unique_future<safe_ptr<frame_producer>> foreground(size_t index);\r
boost::unique_future<safe_ptr<frame_producer>> background(size_t index);\r
\r
#include "StdAfx.h"\r
\r
#include "video_channel.h"\r
-\r
#include "video_channel_context.h"\r
-\r
#include "video_format.h"\r
+\r
+#include "consumer/output.h"\r
+#include "mixer/mixer.h"\r
+#include "producer/stage.h"\r
#include "producer/layer.h"\r
\r
#include <common/concurrency/executor.h>\r
{\r
video_channel_context context_;\r
\r
- safe_ptr<frame_consumer_device> consumer_;\r
- safe_ptr<frame_mixer_device> mixer_;\r
- safe_ptr<frame_producer_device> producer_;\r
+ safe_ptr<caspar::core::output> output_;\r
+ safe_ptr<caspar::core::mixer> mixer_;\r
+ safe_ptr<caspar::core::stage> stage_;\r
\r
safe_ptr<diagnostics::graph> diag_;\r
boost::timer frame_timer_;\r
implementation(int index, const video_format_desc& format_desc, ogl_device& ogl) \r
: context_(index, ogl, format_desc)\r
, diag_(diagnostics::create_graph(narrow(print())))\r
- , consumer_(new frame_consumer_device(context_))\r
- , mixer_(new frame_mixer_device(context_))\r
- , producer_(new frame_producer_device(context_)) \r
+ , output_(new caspar::core::output(context_))\r
+ , mixer_(new caspar::core::mixer(context_))\r
+ , stage_(new caspar::core::stage(context_)) \r
{\r
diag_->add_guide("produce-time", 0.5f); \r
diag_->set_color("produce-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
\r
frame_timer_.restart();\r
\r
- auto simple_frames = producer_->execute();\r
+ auto simple_frames = stage_->execute();\r
\r
diag_->update_value("produce-time", frame_timer_.elapsed()*context_.get_format_desc().fps*0.5);\r
\r
\r
// Consume\r
\r
- consumer_->execute(finished_frame);\r
+ output_->execute(finished_frame);\r
\r
diag_->update_value("tick-time", tick_timer_.elapsed()*context_.get_format_desc().fps*0.5);\r
tick_timer_.restart();\r
\r
video_channel::video_channel(int index, const video_format_desc& format_desc, ogl_device& ogl) : impl_(new implementation(index, format_desc, ogl)){}\r
video_channel::video_channel(video_channel&& other) : impl_(std::move(other.impl_)){}\r
-safe_ptr<frame_producer_device> video_channel::producer() { return impl_->producer_;} \r
-safe_ptr<frame_mixer_device> video_channel::mixer() { return impl_->mixer_;} \r
-safe_ptr<frame_consumer_device> video_channel::consumer() { return impl_->consumer_;} \r
+safe_ptr<stage> video_channel::stage() { return impl_->stage_;} \r
+safe_ptr<mixer> video_channel::mixer() { return impl_->mixer_;} \r
+safe_ptr<output> video_channel::output() { return impl_->output_;} \r
video_format_desc video_channel::get_video_format_desc() const{return impl_->context_.get_format_desc();}\r
void video_channel::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);}\r
std::wstring video_channel::print() const { return impl_->print();}\r
\r
#pragma once\r
\r
-#include "consumer/frame_consumer_device.h"\r
-#include "mixer/frame_mixer_device.h"\r
-#include "producer/frame_producer_device.h"\r
-\r
#include <common/memory/safe_ptr.h>\r
\r
#include <boost/noncopyable.hpp>\r
\r
namespace caspar { namespace core {\r
\r
+class stage;\r
+class mixer;\r
+class output;\r
class ogl_device;\r
+struct video_format_desc;\r
\r
class video_channel : boost::noncopyable\r
{\r
explicit video_channel(int index, const video_format_desc& format_desc, ogl_device& ogl);\r
video_channel(video_channel&& other);\r
\r
- safe_ptr<frame_producer_device> producer();\r
- safe_ptr<frame_mixer_device> mixer();\r
- safe_ptr<frame_consumer_device> consumer();\r
+ safe_ptr<stage> stage();\r
+ safe_ptr<mixer> mixer();\r
+ safe_ptr<output> output();\r
\r
video_format_desc get_video_format_desc() const;\r
void set_video_format_desc(const video_format_desc& format_desc);\r
\r
#include <common/env.h>\r
\r
+#include <core/mixer/mixer.h>\r
+\r
#include <boost/filesystem.hpp>\r
#include <boost/format.hpp>\r
\r
\r
safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::video_channel>& video_channel, int render_layer)\r
{ \r
- auto flash_producer = video_channel->producer()->foreground(render_layer).get();\r
+ auto flash_producer = video_channel->stage()->foreground(render_layer).get();\r
\r
if(flash_producer->print().find(L"flash") == std::string::npos)\r
{\r
flash_producer = create_flash_producer(video_channel->mixer(), boost::assign::list_of(env::template_host())); \r
- video_channel->producer()->load(render_layer, flash_producer, true); \r
- video_channel->producer()->play(render_layer);\r
+ video_channel->stage()->load(render_layer, flash_producer, true); \r
+ video_channel->stage()->play(render_layer);\r
}\r
\r
return make_safe<cg_producer>(flash_producer);\r
#pragma once\r
\r
#include <core/producer/frame_producer.h>\r
-#include <core/producer/frame_producer_device.h>\r
+#include <core/producer/stage.h>\r
#include <core/video_format.h>\r
#include <core/video_channel.h>\r
\r
\r
#include <core/producer/frame/image_transform.h>\r
#include <core/producer/frame/audio_transform.h>\r
+#include <core/mixer/mixer.h>\r
+#include <core/consumer/output.h>\r
\r
#include <algorithm>\r
#include <locale>\r
\r
void AMCPCommand::Clear() \r
{\r
- pChannel_->producer()->clear();\r
+ pChannel_->stage()->clear();\r
pClientInfo_.reset();\r
channelIndex_ = 0;\r
_parameters.clear();\r
{\r
auto what = _parameters.at(2);\r
if(what == L"B")\r
- GetChannel()->producer()->background(GetLayerIndex()).get()->param(_parameters.at(3));\r
+ GetChannel()->stage()->background(GetLayerIndex()).get()->param(_parameters.at(3));\r
else if(what == L"F")\r
- GetChannel()->producer()->foreground(GetLayerIndex()).get()->param(_parameters.at(3));\r
+ GetChannel()->stage()->foreground(GetLayerIndex()).get()->param(_parameters.at(3));\r
\r
CASPAR_LOG(info) << "Executed param: " << _parameters[0] << TEXT(" successfully");\r
\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->stage()->swap_layer(l1, l2, *ch2->stage());\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->stage()->swap(*ch2->stage());\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()->output()->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()->output()->remove(GetLayerIndex());\r
\r
SetReplyString(TEXT("202 REMOVE OK\r\n"));\r
\r
{\r
_parameters[0] = _parameters[0];\r
auto pFP = create_producer(GetChannel()->mixer(), _parameters); \r
- GetChannel()->producer()->load(GetLayerIndex(), pFP, true);\r
+ GetChannel()->stage()->load(GetLayerIndex(), pFP, true);\r
\r
CASPAR_LOG(info) << "Loaded " << _parameters[0] << TEXT(" successfully");\r
\r
BOOST_THROW_EXCEPTION(file_not_found() << msg_info(_parameters.size() > 0 ? narrow(_parameters[0]) : ""));\r
\r
auto pFP2 = create_transition_producer(GetChannel()->get_video_format_desc().mode, pFP, transitionInfo);\r
- GetChannel()->producer()->load(GetLayerIndex(), pFP2); // TODO: LOOP\r
+ GetChannel()->stage()->load(GetLayerIndex(), pFP2); // 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()->stage()->pause(GetLayerIndex());\r
SetReplyString(TEXT("202 PAUSE OK\r\n"));\r
return true;\r
}\r
CASPAR_LOG(info) << "Playing " << _parameters[0];\r
}\r
\r
- GetChannel()->producer()->play(GetLayerIndex());\r
+ GetChannel()->stage()->play(GetLayerIndex());\r
\r
SetReplyString(TEXT("202 PLAY OK\r\n"));\r
return true;\r
{\r
try\r
{\r
- GetChannel()->producer()->stop(GetLayerIndex());\r
+ GetChannel()->stage()->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()->stage()->clear(index);\r
else\r
- GetChannel()->producer()->clear();\r
+ GetChannel()->stage()->clear();\r
\r
SetReplyString(TEXT("202 CLEAR OK\r\n"));\r
\r
\r
bool CGCommand::DoExecuteClear() \r
{\r
- GetChannel()->producer()->clear(GetLayerIndex(cg_producer::DEFAULT_LAYER));\r
+ GetChannel()->stage()->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
- pCIIStrategy_->GetChannel()->producer()->clear(cg_producer::DEFAULT_LAYER);\r
+ pCIIStrategy_->GetChannel()->stage()->clear(cg_producer::DEFAULT_LAYER);\r
else if(state_ == 3)\r
get_default_cg_producer(pCIIStrategy_->GetChannel())->play(layer_);\r
}\r
#include "CIICommandsimpl.h"\r
#include <modules/flash/producer/flash_producer.h>\r
#include <core/producer/transition/transition_producer.h>\r
-#include <core/producer/frame_producer.h>\r
+#include <core/mixer/mixer.h>\r
#include <common/env.h>\r
\r
#if defined(_MSC_VER)\r
{\r
try\r
{\r
- pChannel_->producer()->load(0, GetPreparedTemplate(titleName));\r
- pChannel_->producer()->play(0);\r
+ pChannel_->stage()->load(0, GetPreparedTemplate(titleName));\r
+ pChannel_->stage()->play(0);\r
\r
CASPAR_LOG(info) << L"Displayed title " << titleName ;\r
}\r
\r
try\r
{\r
- pChannel_->producer()->load(0, pTransition);\r
+ pChannel_->stage()->load(0, pTransition);\r
}\r
catch(...)\r
{\r
return;\r
}\r
\r
- pChannel_->producer()->play(0);\r
+ pChannel_->stage()->play(0);\r
\r
CASPAR_LOG(info) << L"Displayed " << filename;\r
}\r
#include "../util/ProtocolStrategy.h"\r
#include "CIICommand.h"\r
\r
-#include <core/consumer/frame_consumer.h>\r
+#include <core/producer/stage.h>\r
\r
#include <common/concurrency/executor.h>\r
\r
\r
if(currentCommand_.command_ == CLKCommand::CLKReset) \r
{\r
- pChannel_->producer()->clear(cg_producer::DEFAULT_LAYER);\r
+ pChannel_->stage()->clear(cg_producer::DEFAULT_LAYER);\r
bClockLoaded_ = false;\r
\r
CASPAR_LOG(info) << L"CLK: Recieved and executed reset-command";\r
\r
#include <core/mixer/gpu/ogl_device.h>\r
#include <core/video_channel.h>\r
+#include <core/producer/stage.h>\r
+#include <core/consumer/output.h>\r
\r
#include <modules/bluefish/bluefish.h>\r
#include <modules/decklink/decklink.h>\r
{\r
const std::string name = xml_consumer.first;\r
if(name == "screen")\r
- channels_.back()->consumer()->add(index++, create_ogl_consumer(xml_consumer.second)); \r
+ channels_.back()->output()->add(index++, create_ogl_consumer(xml_consumer.second)); \r
else if(name == "bluefish") \r
- channels_.back()->consumer()->add(index++, create_bluefish_consumer(xml_consumer.second)); \r
+ channels_.back()->output()->add(index++, create_bluefish_consumer(xml_consumer.second)); \r
else if(name == "decklink") \r
- channels_.back()->consumer()->add(index++, create_decklink_consumer(xml_consumer.second)); \r
+ channels_.back()->output()->add(index++, create_decklink_consumer(xml_consumer.second)); \r
//else if(name == "file") \r
- // channels_.back()->consumer()->add(index++, create_ffmpeg_consumer(xml_consumer.second)); \r
+ // channels_.back()->output()->add(index++, create_ffmpeg_consumer(xml_consumer.second)); \r
else if(name == "audio")\r
- channels_.back()->consumer()->add(index++, make_safe<oal_consumer>()); \r
+ channels_.back()->output()->add(index++, make_safe<oal_consumer>()); \r
else if(name != "<xmlcomment>")\r
CASPAR_LOG(warning) << "Invalid consumer: " << widen(name); \r
}\r