#include "channel.h"\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 "mixer/frame/draw_frame.h"\r
#include "mixer/frame_mixer_device.h"\r
\r
struct channel::implementation : boost::noncopyable\r
{ \r
- const safe_ptr<frame_mixer_device> processor_device_;\r
- frame_consumer_device consumer_device_;\r
- \r
- std::map<int, layer> layers_; \r
+ std::shared_ptr<frame_consumer_device> consumer_;\r
+ std::shared_ptr<frame_mixer_device> mixer_;\r
+ std::shared_ptr<frame_producer_device> producer_;\r
\r
const video_format_desc format_desc_;\r
\r
- mutable executor executor_;\r
-\r
public:\r
implementation(const video_format_desc& format_desc) \r
: format_desc_(format_desc)\r
- , processor_device_(frame_mixer_device(format_desc))\r
- , consumer_device_(format_desc)\r
- {\r
- executor_.start();\r
- executor_.begin_invoke([=]{tick();});\r
- }\r
- \r
- void tick()\r
- { \r
- auto drawed_frame = draw();\r
- auto processed_frame = processor_device_->process(std::move(drawed_frame));\r
- consumer_device_.consume(std::move(processed_frame));\r
-\r
- executor_.begin_invoke([=]{tick();});\r
- }\r
- \r
- safe_ptr<draw_frame> draw()\r
- { \r
- std::vector<safe_ptr<draw_frame>> frames(layers_.size(), draw_frame::empty());\r
- tbb::parallel_for(tbb::blocked_range<size_t>(0, frames.size()), \r
- [&](const tbb::blocked_range<size_t>& r)\r
- {\r
- auto it = layers_.begin();\r
- std::advance(it, r.begin());\r
- for(size_t i = r.begin(); i != r.end(); ++i, ++it)\r
- frames[i] = it->second.receive();\r
- }); \r
- boost::range::remove_erase(frames, draw_frame::eof());\r
- boost::range::remove_erase(frames, draw_frame::empty());\r
- return draw_frame(frames);\r
- }\r
-\r
- // Consumers\r
- void add(int index, const safe_ptr<frame_consumer>& consumer)\r
- {\r
- consumer_device_.add(index, consumer);\r
- }\r
- \r
- void remove(int index)\r
- {\r
- consumer_device_.remove(index);\r
- }\r
-\r
- // Layers and Producers\r
- void set_video_gain(int index, double value)\r
- {\r
- begin_invoke_layer(index, std::bind(&layer::set_video_gain, std::placeholders::_1, value));\r
- }\r
-\r
- void set_video_opacity(int index, double value)\r
- {\r
- begin_invoke_layer(index, std::bind(&layer::set_video_opacity, std::placeholders::_1, value));\r
- }\r
-\r
- void set_audio_gain(int index, double value)\r
- {\r
- begin_invoke_layer(index, std::bind(&layer::set_audio_gain, std::placeholders::_1, value));\r
- }\r
+ , consumer_(new frame_consumer_device(format_desc))\r
+ , mixer_(new frame_mixer_device(format_desc, std::bind(&frame_consumer_device::send, consumer_.get(), std::placeholders::_1)))\r
+ , producer_(new frame_producer_device(format_desc, safe_ptr<frame_factory>(mixer_), std::bind(&frame_mixer_device::send, mixer_.get(), std::placeholders::_1))) {}\r
\r
- void load(int index, const safe_ptr<frame_producer>& producer, bool play_on_load)\r
+ ~implementation()\r
{\r
- producer->initialize(processor_device_);\r
- executor_.begin_invoke([=]\r
- {\r
- auto it = layers_.insert(std::make_pair(index, layer(index))).first;\r
- it->second.load(producer, play_on_load);\r
- });\r
+ CASPAR_LOG(info) << "Shutting down channel.";\r
+ producer_.reset();\r
+ CASPAR_LOG(info) << "Successfully shut down producer-device.";\r
+ consumer_.reset();\r
+ CASPAR_LOG(info) << "Successfully shut down consumer-device.";\r
+ mixer_.reset();\r
+ CASPAR_LOG(info) << "Successfully shut down mixer-device.";\r
}\r
- \r
- void preview(int index, const safe_ptr<frame_producer>& producer)\r
- {\r
- producer->initialize(processor_device_);\r
- executor_.begin_invoke([=]\r
- {\r
- auto it = layers_.insert(std::make_pair(index, layer(index))).first;\r
- it->second.preview(producer);\r
- });\r
- }\r
-\r
- void pause(int index)\r
- { \r
- begin_invoke_layer(index, std::mem_fn(&layer::pause));\r
- }\r
-\r
- void play(int index)\r
- { \r
- begin_invoke_layer(index, std::mem_fn(&layer::play));\r
- }\r
-\r
- void stop(int index)\r
- { \r
- begin_invoke_layer(index, std::mem_fn(&layer::stop));\r
- }\r
-\r
- void clear(int index)\r
- {\r
- executor_.begin_invoke([=]\r
- { \r
- auto it = layers_.find(index);\r
- if(it != layers_.end())\r
- {\r
- it->second.clear(); \r
- layers_.erase(it);\r
- }\r
- });\r
- }\r
- \r
- void clear()\r
- {\r
- executor_.begin_invoke([=]\r
- { \r
- layers_.clear();\r
- });\r
- } \r
-\r
- template<typename F>\r
- void begin_invoke_layer(int index, F&& func)\r
- {\r
- executor_.begin_invoke([=]\r
- {\r
- auto it = layers_.find(index);\r
- if(it != layers_.end())\r
- func(it->second); \r
- });\r
- }\r
-\r
- boost::unique_future<safe_ptr<frame_producer>> foreground(int index) const\r
- {\r
- return executor_.begin_invoke([=]() -> safe_ptr<frame_producer>\r
- { \r
- auto it = layers_.find(index);\r
- return it != layers_.end() ? it->second.foreground() : frame_producer::empty();\r
- });\r
- }\r
- \r
- boost::unique_future<safe_ptr<frame_producer>> background(int index) const\r
- {\r
- return executor_.begin_invoke([=]() -> safe_ptr<frame_producer>\r
- {\r
- auto it = layers_.find(index);\r
- return it != layers_.end() ? it->second.background() : frame_producer::empty();\r
- });\r
- };\r
};\r
\r
channel::channel(channel&& other) : impl_(std::move(other.impl_)){}\r
channel::channel(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-\r
-void channel::add(int index, const safe_ptr<frame_consumer>& consumer){impl_->add(index, consumer);}\r
-void channel::remove(int index){impl_->remove(index);}\r
-\r
-void channel::set_video_gain(int index, double value){impl_->set_video_gain(index, value);}\r
-void channel::set_video_opacity(int index, double value){impl_->set_video_opacity(index, value);}\r
-void channel::set_audio_gain(int index, double value){impl_->set_audio_gain(index, value);}\r
-void channel::load(int index, const safe_ptr<frame_producer>& producer, bool play_on_load){impl_->load(index, producer, play_on_load);}\r
-void channel::preview(int index, const safe_ptr<frame_producer>& producer){impl_->preview(index, producer);}\r
-void channel::pause(int index){impl_->pause(index);}\r
-void channel::play(int index){impl_->play(index);}\r
-void channel::stop(int index){impl_->stop(index);}\r
-void channel::clear(int index){impl_->clear(index);}\r
-void channel::clear(){impl_->clear();}\r
-boost::unique_future<safe_ptr<frame_producer>> channel::foreground(int index) const{ return impl_->foreground(index);}\r
-boost::unique_future<safe_ptr<frame_producer>> channel::background(int index) const{return impl_->background(index);}\r
-const video_format_desc& channel::get_video_format_desc() const{ return impl_->format_desc_;}\r
+frame_producer_device& channel::producer() { return *impl_->producer_;} \r
+frame_consumer_device& channel::consumer() { return *impl_->consumer_;} \r
+const video_format_desc& channel::get_video_format_desc() const{return impl_->format_desc_;}\r
\r
}}
\ No newline at end of file
#pragma once\r
\r
-#include "consumer/frame_consumer.h"\r
-#include "producer/frame_producer.h"\r
+#include "consumer/frame_consumer_device.h"\r
+#include "producer/frame_producer_device.h"\r
\r
#include <common/memory/safe_ptr.h>\r
\r
explicit channel(const video_format_desc& format_desc);\r
channel(channel&& other);\r
\r
- // Consumers\r
- void add(int index, const safe_ptr<frame_consumer>& consumer);\r
- void remove(int index);\r
- \r
- // Layers and Producers\r
- void set_video_gain(int index, double value);\r
- void set_video_opacity(int index, double value);\r
-\r
- void set_audio_gain(int index, double value);\r
-\r
- void load(int index, const safe_ptr<frame_producer>& producer, bool play_on_load = false);\r
- void preview(int index, const safe_ptr<frame_producer>& producer);\r
- void pause(int index);\r
- void play(int index);\r
- void stop(int index);\r
- void clear(int index);\r
- void clear(); \r
- boost::unique_future<safe_ptr<frame_producer>> foreground(int index) const;\r
- boost::unique_future<safe_ptr<frame_producer>> background(int index) const;\r
+ frame_producer_device& producer();\r
+ frame_consumer_device& consumer();\r
+\r
const video_format_desc& get_video_format_desc() const;\r
\r
private:\r
struct frame_consumer_device::implementation\r
{\r
static int const MAX_DEPTH = 3;\r
-\r
+ \r
timer clock_;\r
- executor executor_; \r
\r
boost::circular_buffer<safe_ptr<const read_frame>> buffer_;\r
\r
std::map<int, std::shared_ptr<frame_consumer>> consumers_; // Valid iterators after erase\r
\r
const video_format_desc fmt_;\r
-\r
+ \r
+ executor executor_; \r
public:\r
implementation(const video_format_desc& format_desc) : fmt_(format_desc)\r
{ \r
- executor_.set_capacity(3);\r
+ executor_.set_capacity(2);\r
executor_.start();\r
}\r
\r
+ ~implementation()\r
+ {\r
+ executor_.clear();\r
+ CASPAR_LOG(info) << "Shutting down consumer-device.";\r
+ }\r
+\r
void add(int index, const safe_ptr<frame_consumer>& consumer)\r
{ \r
executor_.invoke([&]\r
});\r
}\r
\r
- void consume(safe_ptr<const read_frame>&& frame)\r
+ void send(const safe_ptr<const read_frame>& frame)\r
{ \r
executor_.begin_invoke([=]\r
{ \r
frame_consumer_device::frame_consumer_device(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
void frame_consumer_device::add(int index, const safe_ptr<frame_consumer>& consumer){impl_->add(index, consumer);}\r
void frame_consumer_device::remove(int index){impl_->remove(index);}\r
-void frame_consumer_device::consume(safe_ptr<const read_frame>&& future_frame) { impl_->consume(std::move(future_frame)); }\r
+void frame_consumer_device::send(const safe_ptr<const read_frame>& future_frame) { impl_->send(future_frame); }\r
}}
\ No newline at end of file
\r
void add(int index, const safe_ptr<frame_consumer>& consumer);\r
void remove(int index);\r
- void consume(safe_ptr<const read_frame>&& future_frame); // nothrow\r
+ void send(const safe_ptr<const read_frame>& future_frame); // nothrow\r
private:\r
struct implementation;\r
safe_ptr<implementation> impl_;\r
<ClInclude Include="mixer\frame\pixel_format.h" />\r
<ClInclude Include="mixer\frame\read_frame.h" />\r
<ClInclude Include="mixer\frame\write_frame.h" />\r
+ <ClInclude Include="mixer\frame_factory.h" />\r
<ClInclude Include="mixer\frame_mixer_device.h" />\r
<ClInclude Include="mixer\fwd.h" />\r
<ClInclude Include="mixer\gpu\device_buffer.h" />\r
<ClInclude Include="producer\flash\flash_producer.h" />\r
<ClInclude Include="producer\flash\TimerHelper.h" />\r
<ClInclude Include="producer\frame_producer.h" />\r
+ <ClInclude Include="producer\frame_producer_device.h" />\r
<ClInclude Include="producer\image\image_loader.h" />\r
<ClInclude Include="producer\image\image_producer.h" />\r
<ClInclude Include="producer\image\image_scroll_producer.h" />\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|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
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+ </ClCompile>\r
<ClCompile Include="producer\image\image_loader.cpp">\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
<ClInclude Include="video_format.h">\r
<Filter>Source</Filter>\r
</ClInclude>\r
- <ClInclude Include="producer\layer.h">\r
- <Filter>Source</Filter>\r
- </ClInclude>\r
<ClInclude Include="channel.h">\r
<Filter>Source</Filter>\r
</ClInclude>\r
<ClInclude Include="mixer\frame\write_frame.h">\r
<Filter>Source\mixer\frame</Filter>\r
</ClInclude>\r
+ <ClInclude Include="producer\frame_producer_device.h">\r
+ <Filter>Source\producer</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="producer\layer.h">\r
+ <Filter>Source\producer</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="mixer\frame_factory.h">\r
+ <Filter>Source\mixer</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ClCompile Include="consumer\decklink\DeckLinkAPI_i.c">\r
<ClCompile Include="channel.cpp">\r
<Filter>Source</Filter>\r
</ClCompile>\r
- <ClCompile Include="producer\layer.cpp">\r
- <Filter>Source</Filter>\r
- </ClCompile>\r
<ClCompile Include="producer\decklink\decklink_producer.cpp">\r
<Filter>Source\producer\decklink</Filter>\r
</ClCompile>\r
<ClCompile Include="mixer\frame\write_frame.cpp">\r
<Filter>Source\mixer\frame</Filter>\r
</ClCompile>\r
+ <ClCompile Include="producer\frame_producer_device.cpp">\r
+ <Filter>Source\producer</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="producer\layer.cpp">\r
+ <Filter>Source\producer</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<Midl Include="producer\flash\Flash9e.IDL">\r
\r
virtual safe_ptr<draw_frame> receive() { return frame_; }\r
\r
- virtual void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
- auto frame = frame_mixer->create_frame(1, 1, pixel_format::bgra);\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
CComPtr<IDeckLink> decklink_;\r
CComQIPtr<IDeckLinkInput> input_;\r
\r
- std::shared_ptr<frame_mixer_device> frame_mixer_;\r
+ std::shared_ptr<frame_factory> frame_factory_;\r
\r
tbb::concurrent_bounded_queue<safe_ptr<draw_frame>> frame_buffer_;\r
safe_ptr<draw_frame> head_;\r
\r
public:\r
\r
- decklink_input(size_t device_index, const video_format_desc& format_desc, const std::shared_ptr<frame_mixer_device>& frame_mixer)\r
+ decklink_input(size_t device_index, const video_format_desc& format_desc, const std::shared_ptr<frame_factory>& frame_factory)\r
: device_index_(device_index)\r
, format_desc_(format_desc)\r
- , frame_mixer_(frame_mixer)\r
+ , frame_factory_(frame_factory)\r
, head_(draw_frame::empty())\r
, tail_(draw_frame::empty())\r
{\r
desc.planes.push_back(pixel_format_desc::plane(format_desc_.width, format_desc_.height, 1));\r
desc.planes.push_back(pixel_format_desc::plane(format_desc_.width/2, format_desc_.height, 1));\r
desc.planes.push_back(pixel_format_desc::plane(format_desc_.width/2, format_desc_.height, 1)); \r
- auto frame = frame_mixer_->create_frame(desc);\r
+ auto frame = frame_factory_->create_frame(desc);\r
\r
unsigned char* data = reinterpret_cast<unsigned char*>(bytes);\r
int frame_size = (format_desc_.width * 16 / 8) * format_desc_.height;\r
return input_->get_frame();\r
}\r
\r
- virtual void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
executor_.start();\r
executor_.invoke([=]\r
{\r
- input_.reset(new decklink_input(device_index_, format_desc_, frame_mixer));\r
+ input_.reset(new decklink_input(device_index_, format_desc_, frame_factory));\r
});\r
}\r
\r
, video_decoder_(input_.get_video_codec_context().get()) \r
, audio_decoder_(input_.get_audio_codec_context().get() ? new audio_decoder(input_.get_audio_codec_context().get(), input_.fps()) : nullptr){}\r
\r
- virtual void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
- format_desc_ = frame_mixer->get_video_format_desc();\r
- video_decoder_.initialize(frame_mixer);\r
+ format_desc_ = frame_factory->get_video_format_desc();\r
+ video_decoder_.initialize(frame_factory);\r
}\r
\r
virtual safe_ptr<draw_frame> receive()\r
\r
struct video_decoder::implementation : boost::noncopyable\r
{ \r
- std::shared_ptr<frame_mixer_device> frame_mixer_;\r
+ std::shared_ptr<frame_factory> frame_factory_;\r
std::shared_ptr<SwsContext> sws_context_;\r
\r
AVCodecContext* codec_context_;\r
\r
if(sws_context_ == nullptr)\r
{\r
- auto write = frame_mixer_->create_frame(desc_);\r
+ auto write = frame_factory_->create_frame(desc_);\r
\r
tbb::parallel_for(0, static_cast<int>(desc_.planes.size()), 1, [&](int n)\r
{\r
});\r
});\r
\r
- if(codec_context_->codec_id == CODEC_ID_DVVIDEO) // Move up one field frame_mixer_->get_video_format_desc().mode == video_mode::upper && \r
+ if(codec_context_->codec_id == CODEC_ID_DVVIDEO) // Move up one field frame_factory_->get_video_format_desc().mode == video_mode::upper && \r
write->get_image_transform().pos = boost::make_tuple(0.0f, 1.0/static_cast<double>(height_));\r
\r
return write;\r
}\r
else\r
{\r
- auto write = frame_mixer_->create_frame(width_, height_);\r
+ auto write = frame_factory_->create_frame(width_, height_);\r
\r
AVFrame av_frame; \r
avcodec_get_frame_defaults(&av_frame);\r
} \r
}\r
\r
- void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+ void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
- frame_mixer_ = frame_mixer; \r
+ frame_factory_ = frame_factory; \r
double frame_rate = static_cast<double>(codec_context_->time_base.den) / static_cast<double>(codec_context_->time_base.num);\r
- if(abs(frame_rate - frame_mixer->get_video_format_desc().fps) > std::numeric_limits<double>::min())\r
+ if(abs(frame_rate - frame_factory->get_video_format_desc().fps) > std::numeric_limits<double>::min())\r
BOOST_THROW_EXCEPTION(file_read_error() << msg_info("Invalid video framerate."));\r
}\r
};\r
\r
video_decoder::video_decoder(AVCodecContext* codec_context) : impl_(new implementation(codec_context)){}\r
safe_ptr<write_frame> video_decoder::execute(const aligned_buffer& video_packet){return impl_->execute(video_packet);}\r
-void video_decoder::initialize(const safe_ptr<frame_mixer_device>& frame_mixer){impl_->initialize(frame_mixer); }\r
+void video_decoder::initialize(const safe_ptr<frame_factory>& frame_factory){impl_->initialize(frame_factory); }\r
}}}
\ No newline at end of file
public:\r
explicit video_decoder(AVCodecContext* codec_context);\r
safe_ptr<write_frame> execute(const aligned_buffer& video_packet); \r
- void initialize(const safe_ptr<frame_mixer_device>& frame_mixer);\r
+ void initialize(const safe_ptr<frame_factory>& frame_factory);\r
private:\r
struct implementation;\r
std::shared_ptr<implementation> impl_;\r
return flash_producer_->receive();\r
}\r
\r
- void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+ void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
- frame_mixer_ = frame_mixer;\r
- flash_producer_->initialize(frame_mixer);\r
+ frame_factory_ = frame_factory;\r
+ flash_producer_->initialize(frame_factory);\r
}\r
\r
std::wstring print() const\r
}\r
\r
safe_ptr<flash_producer> flash_producer_;\r
- std::shared_ptr<frame_mixer_device> frame_mixer_;\r
+ std::shared_ptr<frame_factory> frame_factory_;\r
};\r
\r
safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<channel>& channel, int render_layer)\r
{ \r
try\r
{\r
- return dynamic_pointer_cast<cg_producer>(channel->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->load(render_layer, producer, true); \r
+ channel->producer().load(render_layer, producer, true); \r
return producer;\r
}\r
}\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::initialize(const safe_ptr<frame_mixer_device>& frame_mixer){impl_->initialize(frame_mixer);}\r
+void cg_producer::initialize(const safe_ptr<frame_factory>& frame_factory){impl_->initialize(frame_factory);}\r
std::wstring cg_producer::print() const{return impl_->print();}\r
}}}
\ No newline at end of file
cg_producer(cg_producer&& other);\r
\r
virtual safe_ptr<draw_frame> receive();\r
- virtual void initialize(const safe_ptr<frame_mixer_device>& frame_mixer);\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory);\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
const std::wstring filename_;\r
const video_format_desc format_desc_;\r
\r
- std::shared_ptr<frame_mixer_device> frame_mixer_;\r
+ std::shared_ptr<frame_factory> frame_factory_;\r
\r
BYTE* bmp_data_; \r
std::shared_ptr<void> hdc_;\r
safe_ptr<draw_frame> head_;\r
\r
public:\r
- flash_renderer(const std::shared_ptr<frame_mixer_device>& frame_mixer, const std::wstring& filename) \r
+ flash_renderer(const std::shared_ptr<frame_factory>& frame_factory, const std::wstring& filename) \r
: filename_(filename)\r
- , format_desc_(frame_mixer->get_video_format_desc())\r
- , frame_mixer_(frame_mixer)\r
+ , format_desc_(frame_factory->get_video_format_desc())\r
+ , frame_factory_(frame_factory)\r
, bmp_data_(nullptr)\r
, hdc_(CreateCompatibleDC(0), DeleteDC)\r
, ax_(nullptr)\r
std::fill_n(bmp_data_, format_desc_.size, 0);\r
ax_->DrawControl(static_cast<HDC>(hdc_.get()));\r
\r
- auto frame = frame_mixer_->create_frame();\r
+ auto frame = frame_factory_->create_frame();\r
std::copy_n(bmp_data_, format_desc_.size, frame->image_data().begin());\r
head_ = frame;\r
} \r
executor executor_;\r
\r
std::shared_ptr<flash_renderer> renderer_;\r
- std::shared_ptr<frame_mixer_device> frame_mixer_;\r
+ std::shared_ptr<frame_factory> frame_factory_;\r
\r
std::wstring print() const{ return L"flash[" + boost::filesystem::wpath(filename_).filename() + L"]"; } \r
std::wstring filename_;\r
return tail_;\r
}\r
\r
- virtual void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
- frame_mixer_ = frame_mixer;\r
- frame_buffer_.set_capacity(static_cast<size_t>(frame_mixer->get_video_format_desc().fps/2.0));\r
+ frame_factory_ = frame_factory;\r
+ frame_buffer_.set_capacity(static_cast<size_t>(frame_factory->get_video_format_desc().fps/2.0));\r
while(frame_buffer_.try_push(draw_frame::empty())){}\r
executor_.start();\r
}\r
executor_.begin_invoke([=]\r
{\r
if(!renderer_)\r
- renderer_.reset(new flash_renderer(frame_mixer_, filename_));\r
+ renderer_.reset(new flash_renderer(frame_factory_, filename_));\r
\r
try\r
{\r
flash_producer::flash_producer(const std::wstring& filename) : impl_(new implementation(filename)){}\r
safe_ptr<draw_frame> flash_producer::receive(){return impl_->receive();}\r
void flash_producer::param(const std::wstring& param){impl_->param(param);}\r
-void flash_producer::initialize(const safe_ptr<frame_mixer_device>& frame_mixer) { impl_->initialize(frame_mixer);}\r
+void flash_producer::initialize(const safe_ptr<frame_factory>& frame_factory) { impl_->initialize(frame_factory);}\r
std::wstring flash_producer::print() const {return impl_->print();}\r
\r
std::wstring flash_producer::find_template(const std::wstring& template_name)\r
flash_producer(flash_producer&& other);\r
\r
virtual safe_ptr<draw_frame> receive();\r
- virtual void initialize(const safe_ptr<frame_mixer_device>& frame_mixer);\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory);\r
virtual std::wstring print() const;\r
\r
void param(const std::wstring& param);\r
#pragma once\r
\r
#include "../mixer/frame/draw_frame.h"\r
-#include "../mixer/frame_mixer_device.h"\r
+#include "../mixer/frame_factory.h"\r
\r
#include <common/memory/safe_ptr.h>\r
\r
virtual void set_leading_producer(const safe_ptr<frame_producer>& /*producer*/) {} // nothrow\r
\r
////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual void :::initialize(const safe_ptr<frame_mixer_device>& frame_mixer) = 0;\r
+ /// \fn virtual void :::initialize(const safe_ptr<frame_factory>& frame_factory) = 0;\r
///\r
- /// \brief Provides the frame frame_mixer used to create frames and initializes the producer. \r
+ /// \brief Provides the frame frame_factory used to create frames and initializes the producer. \r
///\r
- /// \param frame_mixer The frame frame_mixer. \r
+ /// \param frame_factory The frame frame_factory. \r
////////////////////////////////////////////////////////////////////////////////////////////////////\r
- virtual void initialize(const safe_ptr<frame_mixer_device>& frame_mixer) = 0;\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory) = 0;\r
\r
static safe_ptr<frame_producer> empty() // nothrow\r
{\r
struct empty_frame_producer : public frame_producer\r
{\r
virtual safe_ptr<draw_frame> receive(){return draw_frame::empty();}\r
- virtual void initialize(const safe_ptr<frame_mixer_device>&){}\r
+ virtual void initialize(const safe_ptr<frame_factory>&){}\r
virtual std::wstring print() const { return L"empty";}\r
};\r
static safe_ptr<frame_producer> producer = make_safe<empty_frame_producer>();\r
\r
struct image_producer : public frame_producer\r
{ \r
- std::shared_ptr<frame_mixer_device> frame_mixer_;\r
+ std::shared_ptr<frame_factory> frame_factory_;\r
std::wstring filename_;\r
safe_ptr<draw_frame> frame_;\r
\r
image_producer(image_producer&& other) \r
- : frame_mixer_(std::move(other.frame_mixer_))\r
+ : frame_factory_(std::move(other.frame_factory_))\r
, filename_(std::move(other.filename_))\r
, frame_(draw_frame::empty()){}\r
\r
\r
virtual safe_ptr<draw_frame> receive(){return frame_;}\r
\r
- virtual void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
- frame_mixer_ = frame_mixer;\r
+ frame_factory_ = frame_factory;\r
auto bitmap = load_image(filename_);\r
FreeImage_FlipVertical(bitmap.get());\r
- auto frame = frame_mixer->create_frame(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(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
// draw_frame do_receive()\r
// {\r
-// auto frame = frame_mixer_->create_frame(format_desc_.width, format_desc_.height);\r
+// auto frame = frame_factory_->create_frame(format_desc_.width, format_desc_.height);\r
// std::fill(frame.image_data().begin(), frame.image_data().end(), 0);\r
//\r
// const int delta_x = direction_ == direction::Left ? speed_ : -speed_;\r
// return receive(); \r
// }\r
// \r
-// void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+// void initialize(const safe_ptr<frame_factory>& frame_factory)\r
// {\r
-// frame_mixer_ = frame_mixer;\r
-// format_desc_ = frame_mixer_->get_video_format_desc();\r
+// frame_factory_ = frame_factory;\r
+// format_desc_ = frame_factory_->get_video_format_desc();\r
// \r
// if(image_width_ - format_desc_.width > image_height_ - format_desc_.height)\r
// direction_ = speed_ < 0 ? direction::Right : direction::Left;\r
//\r
// std::wstring filename_;\r
//\r
-// safe_ptr<frame_mixer_device> frame_mixer_;\r
+// safe_ptr<frame_mixer_device> frame_factory_;\r
//};\r
//\r
//safe_ptr<frame_producer> create_image_scroll_producer(const std::vector<std::wstring>& params)\r
safe_ptr<frame_producer> dest_producer_;\r
safe_ptr<frame_producer> source_producer_;\r
\r
- std::shared_ptr<frame_mixer_device> frame_mixer_;\r
+ std::shared_ptr<frame_factory> frame_factory_;\r
\r
implementation(const safe_ptr<frame_producer>& dest, const transition_info& info) \r
: current_frame_(0)\r
try\r
{\r
auto following = producer->get_following_producer();\r
- following->initialize(safe_ptr<frame_mixer_device>(frame_mixer_));\r
+ following->initialize(safe_ptr<frame_factory>(frame_factory_));\r
following->set_leading_producer(producer);\r
producer = std::move(following);\r
}\r
return draw_frame(std::move(my_src_frame), std::move(my_dest_frame));\r
}\r
\r
- void initialize(const safe_ptr<frame_mixer_device>& frame_mixer)\r
+ void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
- dest_producer_->initialize(frame_mixer);\r
- frame_mixer_ = frame_mixer;\r
+ dest_producer_->initialize(frame_factory);\r
+ frame_factory_ = frame_factory;\r
}\r
\r
std::wstring print() const\r
safe_ptr<draw_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::initialize(const safe_ptr<frame_mixer_device>& frame_mixer) { impl_->initialize(frame_mixer);}\r
+void transition_producer::initialize(const safe_ptr<frame_factory>& frame_factory) { impl_->initialize(frame_factory);}\r
std::wstring transition_producer::print() const { return impl_->print();}\r
\r
}}\r
\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 initialize(const safe_ptr<frame_mixer_device>& frame_mixer);\r
+ virtual void initialize(const safe_ptr<frame_factory>& frame_factory);\r
virtual std::wstring print() const;\r
private:\r
struct implementation;\r
\r
void AMCPCommand::Clear() \r
{\r
- pChannel_->clear();\r
+ pChannel_->producer().clear();\r
pClientInfo_.reset();\r
channelIndex_ = 0;\r
_parameters.clear();\r
if(_parameters[1] == L"OPACITY")\r
{\r
double value = boost::lexical_cast<double>(_parameters[2]);\r
- GetChannel()->set_video_opacity(GetLayerIndex(), value);\r
+ GetChannel()->producer().set_video_opacity(GetLayerIndex(), value);\r
}\r
else if(_parameters[1] == L"GAIN")\r
{\r
double value = boost::lexical_cast<double>(_parameters[2]);\r
- GetChannel()->set_video_gain(GetLayerIndex(), value);\r
+ GetChannel()->producer().set_video_gain(GetLayerIndex(), value);\r
}\r
else if(_parameters[1] == L"RESET")\r
{\r
- GetChannel()->set_video_opacity(GetLayerIndex(), 1.0);\r
- GetChannel()->set_video_gain(GetLayerIndex(), 1.0);\r
+ GetChannel()->producer().set_video_opacity(GetLayerIndex(), 1.0);\r
+ GetChannel()->producer().set_video_gain(GetLayerIndex(), 1.0);\r
}\r
}\r
else if(_parameters[0] == L"AUDIO")\r
if(_parameters[1] == L"GAIN")\r
{\r
double value = boost::lexical_cast<double>(_parameters[2]);\r
- GetChannel()->set_audio_gain(GetLayerIndex(), value);\r
+ GetChannel()->producer().set_audio_gain(GetLayerIndex(), value);\r
}\r
else if(_parameters[1] == L"RESET")\r
{\r
- GetChannel()->set_audio_gain(GetLayerIndex(), 1.0);\r
+ GetChannel()->producer().set_audio_gain(GetLayerIndex(), 1.0);\r
}\r
}\r
else if(_parameters[0] == L"RESET")\r
{\r
- GetChannel()->set_video_opacity(GetLayerIndex(), 1.0);\r
- GetChannel()->set_video_gain(GetLayerIndex(), 1.0);\r
- GetChannel()->set_audio_gain(GetLayerIndex(), 1.0);\r
+ GetChannel()->producer().set_video_opacity(GetLayerIndex(), 1.0);\r
+ GetChannel()->producer().set_video_gain(GetLayerIndex(), 1.0);\r
+ GetChannel()->producer().set_audio_gain(GetLayerIndex(), 1.0);\r
}\r
\r
SetReplyString(TEXT("202 MIXER OK\r\n"));\r
try\r
{\r
auto consumer = create_consumer(_parameters); \r
- GetChannel()->add(GetLayerIndex(), consumer);\r
+ GetChannel()->consumer().add(GetLayerIndex(), consumer);\r
\r
CASPAR_LOG(info) << "Added " << _parameters[0] << TEXT(" successfully");\r
\r
//Perform loading of the clip\r
try\r
{\r
- GetChannel()->remove(GetLayerIndex());\r
+ GetChannel()->consumer().remove(GetLayerIndex());\r
\r
CASPAR_LOG(info) << "Removed " << TEXT(" successfully");\r
\r
{\r
_parameters[0] = _parameters[0];\r
auto pFP = create_producer(_parameters); \r
- GetChannel()->preview(GetLayerIndex(), pFP);\r
+ GetChannel()->producer().preview(GetLayerIndex(), pFP);\r
\r
CASPAR_LOG(info) << "Loaded " << _parameters[0] << TEXT(" successfully");\r
\r
\r
pFP = safe_ptr<core::frame_producer>(transition_producer(pFP, transitionInfo));\r
bool autoPlay = std::find(_parameters.begin(), _parameters.end(), TEXT("AUTOPLAY")) != _parameters.end();\r
- GetChannel()->load(GetLayerIndex(), pFP, autoPlay); // TODO: LOOP\r
+ GetChannel()->producer().load(GetLayerIndex(), pFP, 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()->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()->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()->stop(GetLayerIndex());\r
+ GetChannel()->producer().stop(GetLayerIndex());\r
SetReplyString(TEXT("202 STOP OK\r\n"));\r
return true;\r
}\r
\r
bool ClearCommand::DoExecute()\r
{\r
- GetChannel()->clear(GetLayerIndex());\r
+ GetChannel()->producer().clear(GetLayerIndex());\r
\r
SetReplyString(TEXT("202 CLEAR OK\r\n"));\r
\r
\r
void GenerateChannelInfo(int index, const safe_ptr<core::channel>& pChannel, std::wstringstream& replyString)\r
{\r
- replyString << index << TEXT(" ") << pChannel->get_video_format_desc().name << TEXT("\r\n") << (pChannel->foreground(0).get()->print());\r
+ replyString << index << TEXT(" ") << pChannel->get_video_format_desc().name << TEXT("\r\n") << (pChannel->producer().foreground(0).get()->print());\r
}\r
\r
bool InfoCommand::DoExecute()\r
\r
if(name == TEXT("MODE"))\r
{\r
- //if(this->GetChannel()->SetVideoFormat(value)) TODO\r
+ //if(this->GetChannel()->producer().SetVideoFormat(value)) TODO\r
// this->SetReplyString(TEXT("202 SET MODE OK\r\n"));\r
//else\r
this->SetReplyString(TEXT("501 SET MODE FAILED\r\n"));\r
{\r
try\r
{\r
- pChannel_->load(0, GetPreparedTemplate(titleName));\r
- pChannel_->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
\r
try\r
{\r
- pChannel_->load(0, pTransition);\r
+ pChannel_->producer().load(0, pTransition);\r
}\r
catch(...)\r
{\r
return;\r
}\r
\r
- pChannel_->play(0);\r
+ pChannel_->producer().play(0);\r
\r
CASPAR_LOG(info) << L"Displayed " << filename;\r
}\r
stretch = stretch::uniform_to_fill;\r
\r
bool windowed = xml_consumer.second.get("windowed", false);\r
- channels_.back()->add(index++, ogl_consumer(format_desc, device, stretch, windowed));\r
+ channels_.back()->consumer().add(index++, ogl_consumer(format_desc, device, stretch, windowed));\r
}\r
else if(name == "bluefish") \r
- channels_.back()->add(index++, bluefish_consumer(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("embedded-audio", false))); \r
+ channels_.back()->consumer().add(index++, bluefish_consumer(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("embedded-audio", false))); \r
else if(name == "decklink")\r
- channels_.back()->add(index++, decklink_consumer(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("internalkey", false)));\r
+ channels_.back()->consumer().add(index++, decklink_consumer(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("internalkey", false)));\r
else if(name == "audio")\r
- channels_.back()->add(index++, oal_consumer(format_desc)); \r
+ channels_.back()->consumer().add(index++, oal_consumer(format_desc)); \r
}\r
catch(...)\r
{\r