struct channel::implementation : boost::noncopyable\r
{ \r
const int index_;\r
- const video_format_desc format_desc_;\r
+ video_format_desc format_desc_;\r
\r
- const std::shared_ptr<frame_mixer_device> mixer_;\r
- const std::shared_ptr<frame_consumer_device> consumer_;\r
- const std::shared_ptr<frame_producer_device> producer_;\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
\r
boost::signals2::scoped_connection mixer_connection_;\r
boost::signals2::scoped_connection producer_connection_;\r
{\r
return L"channel[" + boost::lexical_cast<std::wstring>(index_+1) + L"-" + format_desc_.name + L"]";\r
}\r
+\r
+ void set_video_format_desc(const video_format_desc& format_desc)\r
+ {\r
+ format_desc_ = format_desc;\r
+ producer_connection_.disconnect();\r
+ mixer_connection_.disconnect();\r
+\r
+ consumer_->set_video_format_desc(format_desc_);\r
+ mixer_.reset(new frame_mixer_device([=]{return print();}, format_desc_));\r
+ producer_.reset(new frame_producer_device([=]{return print();}, safe_ptr<frame_factory>(mixer_)));\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
};\r
\r
channel::channel(int index, const video_format_desc& format_desc) : impl_(new implementation(index, format_desc)){}\r
frame_mixer_device& channel::mixer() { return *impl_->mixer_;} \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
-void channel::set_video_format_desc(const video_format_desc& format_desc){impl_ = make_safe<implementation>(impl_->index_, 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
\r
}}
\ No newline at end of file
\r
std::map<int, std::shared_ptr<frame_consumer>> consumers_; // Valid iterators after erase\r
\r
- const video_format_desc format_desc_;\r
+ video_format_desc format_desc_;\r
\r
executor executor_; \r
public:\r
\r
void add(int index, safe_ptr<frame_consumer>&& consumer)\r
{ \r
- consumer->initialize(format_desc_, std::bind(&implementation::print, this));\r
+ consumer->initialize(format_desc_, [this]{return print();});\r
executor_.invoke([&]\r
{\r
if(buffer_.capacity() < consumer->buffer_depth())\r
{\r
return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"consumer";\r
}\r
+ \r
+ void set_video_format_desc(const video_format_desc& format_desc)\r
+ {\r
+ auto p = [this]{return print();};\r
+ executor_.invoke([&]\r
+ {\r
+ format_desc_ = format_desc;\r
+ buffer_.clear();\r
+ BOOST_FOREACH(auto& consumer, consumers_)\r
+ consumer.second->initialize(format_desc_, p);\r
+ });\r
+ }\r
};\r
\r
frame_consumer_device::frame_consumer_device(const printer& parent_printer, const video_format_desc& format_desc) : impl_(new implementation(parent_printer, format_desc)){}\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::send(const safe_ptr<const read_frame>& future_frame) { impl_->send(future_frame); }\r
+void frame_consumer_device::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);}\r
}}
\ No newline at end of file
void remove(int index);\r
\r
void send(const safe_ptr<const read_frame>& future_frame); // nothrow\r
+ \r
+ void set_video_format_desc(const video_format_desc& format_desc);\r
private:\r
struct implementation;\r
safe_ptr<implementation> impl_;\r
}\r
};\r
\r
-bluefish_consumer::bluefish_consumer(bluefish_consumer&& other) : impl_(std::move(other.impl_)){}\r
bluefish_consumer::bluefish_consumer(unsigned int device_index, bool embed_audio) : impl_(new implementation(device_index, embed_audio)){} \r
-void bluefish_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer){impl_->initialize(format_desc, parent_printer);}\r
+bluefish_consumer::bluefish_consumer(bluefish_consumer&& other) : impl_(std::move(other.impl_)){}\r
+void bluefish_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer)\r
+{\r
+ impl_.reset(new implementation(impl_->device_index_, impl_->embed_audio_));\r
+ impl_->initialize(format_desc, parent_printer);\r
+}\r
void bluefish_consumer::send(const safe_ptr<const core::read_frame>& frame){impl_->send(frame);}\r
size_t bluefish_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
std::wstring bluefish_consumer::print() const {return impl_->print();} \r
ffmpeg_consumer::ffmpeg_consumer(ffmpeg_consumer&& other) : impl_(std::move(other.impl_)){}\r
void ffmpeg_consumer::send(const safe_ptr<const core::read_frame>& frame){impl_->send(frame);}\r
size_t ffmpeg_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
-void ffmpeg_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer) {impl_->initialize(format_desc, parent_printer);}\r
+void ffmpeg_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer)\r
+{\r
+ impl_.reset(new implementation(impl_->filename_));\r
+ impl_->initialize(format_desc, parent_printer);\r
+}\r
std::wstring ffmpeg_consumer::print() const {return impl_->print();}\r
\r
safe_ptr<core::frame_consumer> create_ffmpeg_consumer(const std::vector<std::wstring>& params)\r
\r
core::video_format_desc format_desc_;\r
public:\r
- implementation() \r
- : graph_(diagnostics::create_graph(narrow(print())))\r
+ implementation(const core::video_format_desc& format_desc, const printer& parent_printer) \r
+ : parent_printer_(parent_printer)\r
+ , graph_(diagnostics::create_graph(narrow(print())))\r
, container_(5)\r
+ , format_desc_(format_desc)\r
{\r
graph_->add_guide("tick-time", 0.5);\r
graph_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f));\r
is_running_ = true;\r
input_.set_capacity(4);\r
+ for(size_t n = 0; n < buffer_depth(); ++n)\r
+ input_.push(std::vector<short>(static_cast<size_t>(48000.0f/format_desc_.fps)*2, 0)); \r
+\r
+ sf::SoundStream::Initialize(2, 48000);\r
+ Play(); \r
+ CASPAR_LOG(info) << print() << " Sucessfully initialized.";\r
}\r
\r
~implementation()\r
Stop();\r
CASPAR_LOG(info) << print() << L" Shutting down."; \r
}\r
-\r
- void initialize(const core::video_format_desc& format_desc, const printer& parent_printer)\r
- {\r
- format_desc_ = format_desc;\r
- parent_printer_ = parent_printer;\r
- for(size_t n = 0; n < buffer_depth(); ++n)\r
- input_.push(std::vector<short>(static_cast<size_t>(48000.0f/format_desc_.fps)*2, 0)); \r
- sf::SoundStream::Initialize(2, 48000);\r
- Play(); \r
- CASPAR_LOG(info) << print() << " Sucessfully initialized.";\r
- }\r
-\r
+ \r
void send(const safe_ptr<const core::read_frame>& frame)\r
{ \r
if(!frame->audio_data().empty())\r
}\r
};\r
\r
+oal_consumer::oal_consumer(){}\r
oal_consumer::oal_consumer(oal_consumer&& other) : impl_(std::move(other.impl_)){}\r
-oal_consumer::oal_consumer() : impl_(new implementation()){}\r
void oal_consumer::send(const safe_ptr<const core::read_frame>& frame){impl_->send(frame);}\r
size_t oal_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
-void oal_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer){impl_->initialize(format_desc, parent_printer);}\r
+void oal_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer){impl_.reset(new implementation(format_desc, parent_printer));}\r
std::wstring oal_consumer::print() const { return impl_->print(); }\r
\r
safe_ptr<core::frame_consumer> create_oal_consumer(const std::vector<std::wstring>& params)\r
ogl_consumer::ogl_consumer(unsigned int screen_index, stretch stretch, bool windowed) : impl_(new implementation(screen_index, stretch, windowed)){}\r
void ogl_consumer::send(const safe_ptr<const core::read_frame>& frame){impl_->send(frame);}\r
size_t ogl_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
-void ogl_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer){impl_->initialize(format_desc, parent_printer);}\r
+void ogl_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer)\r
+{\r
+ impl_.reset(new implementation(impl_->screen_index_, impl_->stretch_, impl_->windowed_));\r
+ impl_->initialize(format_desc, parent_printer);\r
+}\r
std::wstring ogl_consumer::print() const {return impl_->print();}\r
\r
safe_ptr<core::frame_consumer> create_ogl_consumer(const std::vector<std::wstring>& params)\r
<channel>\r
<videomode>PAL</videomode>\r
<consumers>\r
- <!--<ogl>\r
- <device>0</device>\r
- <stretch>uniform</stretch>\r
- <windowed>true</windowed>\r
- </ogl>\r
- <audio/>\r
- <decklink>\r
+ <!--<decklink>\r
<device>1</device>\r
<embedded-audio>true</embedded-audio>\r
<internal-key>false</internal-key>\r
<stretch>uniform</stretch>\r
<windowed>true</windowed>\r
</ogl>\r
- <bluefish>\r
+ <audio/>\r
+ <!--<bluefish>\r
<device>1</device>\r
<embedded-audio>false</embedded-audio>\r
- </bluefish>\r
- </consumers>\r
- </channel>\r
- <channel>\r
- <videomode>PAL</videomode>\r
- <consumers>\r
- <ogl>\r
- <device>0</device>\r
- <stretch>uniform</stretch>\r
- <windowed>true</windowed>\r
- </ogl>\r
- <audio/>\r
+ </bluefish>-->\r
</consumers>\r
</channel>\r
</channels>\r