#include <common/exception/exceptions.h>\r
#include <common/concurrency/executor.h>\r
#include <common/diagnostics/graph.h>\r
+#include <common/utility/assert.h>\r
#include <common/utility/timer.h>\r
#include <common/gl/gl_check.h>\r
\r
\r
struct frame_mixer_device::implementation : boost::noncopyable\r
{ \r
+ const printer parent_printer_;\r
+ const video_format_desc format_desc_;\r
+\r
safe_ptr<diagnostics::graph> graph_;\r
timer perf_timer_;\r
-\r
- const video_format_desc format_desc_;\r
+ timer wait_perf_timer_;\r
\r
audio_mixer audio_mixer_;\r
image_mixer image_mixer_;\r
\r
executor executor_;\r
public:\r
- implementation(const video_format_desc& format_desc, const output_func& output) \r
- : graph_(diagnostics::create_graph("mixer"))\r
+ implementation(const printer& parent_printer, const video_format_desc& format_desc, const output_func& output) \r
+ : parent_printer_(parent_printer)\r
, format_desc_(format_desc)\r
+ , graph_(diagnostics::create_graph(narrow(print())))\r
, image_mixer_(format_desc)\r
, output_(output)\r
+ , executor_(print())\r
{\r
- graph_->add_guide("frame_time_target", 0.5f, diagnostics::color(1.0f, 0.0f, 0.0f)); \r
- graph_->set_color("frame_time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
- graph_->set_color("buffer_size", diagnostics::color( 0.0f, 1.0f, 0.0f)); \r
+ graph_->guide("frame-time", 0.5f); \r
+ graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
+ graph_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f));\r
+ graph_->set_color("input-buffer", diagnostics::color(1.0f, 1.0f, 0.0f)); \r
executor_.start();\r
executor_.set_capacity(2);\r
+ CASPAR_LOG(info) << print() << L" Successfully initialized."; \r
}\r
\r
- ~implementation()\r
- {\r
- CASPAR_LOG(info) << "Shutting down mixer-device.";\r
- }\r
-\r
void send(const std::vector<safe_ptr<draw_frame>>& frames)\r
{ \r
executor_.begin_invoke([=]\r
audio_mixer_.end();\r
}\r
audio_mixer_.end_pass();\r
- graph_->update("frame_time", static_cast<float>(perf_timer_.elapsed()/format_desc_.interval*0.5));\r
+\r
+ graph_->update("frame-time", static_cast<float>(perf_timer_.elapsed()/format_desc_.interval*0.5));\r
\r
output_(make_safe<const read_frame>(std::move(image.get()), std::move(audio)));\r
+ graph_->update("tick-time", static_cast<float>(wait_perf_timer_.elapsed()/format_desc_.interval*0.5));\r
+ wait_perf_timer_.reset();\r
+\r
+ graph_->set("input-buffer", static_cast<float>(executor_.size())/static_cast<float>(executor_.capacity()));\r
});\r
- graph_->update("buffer_size", static_cast<float>(executor_.size())/static_cast<float>(executor_.capacity()));\r
+ graph_->set("input-buffer", static_cast<float>(executor_.size())/static_cast<float>(executor_.capacity()));\r
}\r
\r
safe_ptr<write_frame> create_frame(const pixel_format_desc& desc)\r
return executor_.invoke([&]{return audio_transforms_[index];});\r
}\r
\r
- void set_image_transform(int index, image_transform&& transform)\r
+ void set_image_transform(int index, image_transform&& transform, int mix_duration)\r
+ {\r
+ return executor_.invoke([&]\r
+ {\r
+ image_transforms_[index] = std::move(transform);\r
+ });\r
+ }\r
+\r
+ void set_audio_transform(int index, audio_transform&& transform, int mix_duration)\r
{\r
- return executor_.invoke([&]{image_transforms_[index] = std::move(transform);});\r
+ return executor_.invoke([&]\r
+ {\r
+ audio_transforms_[index] = std::move(transform);\r
+ });\r
}\r
\r
- void set_audio_transform(int index, audio_transform&& transform)\r
+ std::wstring print() const\r
{\r
- return executor_.invoke([&]{audio_transforms_[index] = std::move(transform);});\r
+ return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"mixer";\r
}\r
};\r
\r
-frame_mixer_device::frame_mixer_device(const video_format_desc& format_desc, const output_func& output) : impl_(new implementation(format_desc, output)){}\r
+frame_mixer_device::frame_mixer_device(const printer& parent_printer, const video_format_desc& format_desc, const output_func& output) : impl_(new implementation(parent_printer, format_desc, output)){}\r
frame_mixer_device::frame_mixer_device(frame_mixer_device&& other) : impl_(std::move(other.impl_)){}\r
void frame_mixer_device::send(const std::vector<safe_ptr<draw_frame>>& frames){impl_->send(frames);}\r
const video_format_desc& frame_mixer_device::get_video_format_desc() const { return impl_->format_desc_; }\r
}\r
image_transform frame_mixer_device::get_image_transform(int index){return impl_->get_image_transform(index);}\r
audio_transform frame_mixer_device::get_audio_transform(int index){return impl_->get_audio_transform(index);}\r
-void frame_mixer_device::set_image_transform(int index, image_transform&& transform){impl_->set_image_transform(index, std::move(transform));}\r
-void frame_mixer_device::set_audio_transform(int index, audio_transform&& transform){impl_->set_audio_transform(index, std::move(transform));}\r
+void frame_mixer_device::set_image_transform(int index, image_transform&& transform, int mix_duration){impl_->set_image_transform(index, std::move(transform), mix_duration);}\r
+void frame_mixer_device::set_audio_transform(int index, audio_transform&& transform, int mix_duration){impl_->set_audio_transform(index, std::move(transform), mix_duration);}\r
\r
}}
\ No newline at end of file