X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=core%2Fvideo_channel.cpp;h=45d3b9158ac364ccea7ce41f347fdac65d73545c;hb=e96e4f77fbc3b59fa21c5ecfe827be8f8a589ef1;hp=d3e43ab224c351571b57b895af10935b75d0bfdb;hpb=92196ec300b217123cfd48955578a6e02d2c6767;p=casparcg diff --git a/core/video_channel.cpp b/core/video_channel.cpp index d3e43ab22..45d3b9158 100644 --- a/core/video_channel.cpp +++ b/core/video_channel.cpp @@ -23,13 +23,16 @@ #include "video_channel.h" #include "video_channel_context.h" - #include "video_format.h" -#include "producer/layer.h" + +#include "consumer/output.h" +#include "mixer/mixer.h" +#include "producer/stage.h" #include +#include -#include +#include #ifdef _MSC_VER #pragma warning(disable : 4355) @@ -39,39 +42,85 @@ namespace caspar { namespace core { struct video_channel::implementation : boost::noncopyable { - video_channel_context context_; + video_channel_context context_; + + safe_ptr output_; + safe_ptr mixer_; + safe_ptr stage_; - safe_ptr consumer_; - safe_ptr mixer_; - safe_ptr producer_; + safe_ptr diag_; + boost::timer frame_timer_; + boost::timer tick_timer_; + boost::timer output_timer_; public: implementation(int index, const video_format_desc& format_desc, ogl_device& ogl) : context_(index, ogl, format_desc) - , consumer_(new frame_consumer_device(context_)) - , mixer_(new frame_mixer_device(context_)) - , producer_(new frame_producer_device(context_)) + , diag_(diagnostics::create_graph(narrow(print()))) + , output_(new caspar::core::output(context_)) + , mixer_(new caspar::core::mixer(context_)) + , stage_(new caspar::core::stage(context_)) { + diag_->add_guide("produce-time", 0.5f); + diag_->set_color("produce-time", diagnostics::color(1.0f, 0.0f, 0.0f)); + diag_->set_color("mix-time", diagnostics::color(1.0f, 0.0f, 1.0f)); + diag_->set_color("output-time", diagnostics::color(1.0f, 1.0f, 0.0f)); + diag_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f)); + CASPAR_LOG(info) << print() << " Successfully Initialized."; - context_.execution.begin_invoke([this]{tick();}); + context_.execution().begin_invoke([this]{tick();}); } ~implementation() { // Stop context before destroying devices. - context_.execution.stop(); - context_.execution.join(); - context_.destruction.stop(); - context_.destruction.join(); + context_.execution().stop(); + context_.execution().join(); + context_.destruction().stop(); + context_.destruction().join(); } void tick() { - auto simple_frames = (*producer_)(); - auto finished_frame = (*mixer_)(simple_frames); - (*consumer_)(finished_frame); + try + { + // Produce + + frame_timer_.restart(); + + auto simple_frames = stage_->execute(); + + diag_->update_value("produce-time", frame_timer_.elapsed()*context_.get_format_desc().fps*0.5); + + // Mix + + frame_timer_.restart(); + + auto finished_frame = mixer_->execute(simple_frames); + + diag_->update_value("mix-time", frame_timer_.elapsed()*context_.get_format_desc().fps*0.5); + + // Consume + + output_timer_.restart(); + + output_->execute(finished_frame); + + diag_->update_value("output-time", frame_timer_.elapsed()*context_.get_format_desc().fps*0.5); + + + diag_->update_value("tick-time", tick_timer_.elapsed()*context_.get_format_desc().fps*0.5); + tick_timer_.restart(); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + CASPAR_LOG(error) << context_.print() << L" Unexpected exception. Clearing stage and freeing memory"; + stage_->clear(); + context_.ogl().gc().wait(); + } - context_.execution.begin_invoke([this]{tick();}); + context_.execution().begin_invoke([this]{tick();}); } std::wstring print() const @@ -81,19 +130,20 @@ public: void set_video_format_desc(const video_format_desc& format_desc) { - context_.execution.begin_invoke([=] + context_.execution().begin_invoke([=] { - context_.format_desc = format_desc; + stage_->clear(); + context_.set_format_desc(format_desc); }); } }; video_channel::video_channel(int index, const video_format_desc& format_desc, ogl_device& ogl) : impl_(new implementation(index, format_desc, ogl)){} video_channel::video_channel(video_channel&& other) : impl_(std::move(other.impl_)){} -safe_ptr video_channel::producer() { return impl_->producer_;} -safe_ptr video_channel::mixer() { return impl_->mixer_;} -safe_ptr video_channel::consumer() { return impl_->consumer_;} -const video_format_desc& video_channel::get_video_format_desc() const{return impl_->context_.format_desc;} +safe_ptr video_channel::stage() { return impl_->stage_;} +safe_ptr video_channel::mixer() { return impl_->mixer_;} +safe_ptr video_channel::output() { return impl_->output_;} +video_format_desc video_channel::get_video_format_desc() const{return impl_->context_.get_format_desc();} void video_channel::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);} std::wstring video_channel::print() const { return impl_->print();}