From 12a238be4c234c190883942eddd5e5bd69c88253 Mon Sep 17 00:00:00 2001 From: ronag Date: Wed, 30 Nov 2011 18:35:30 +0000 Subject: [PATCH] 2.0.2: Refactoring. AMCP commands now executed asynchronously when possible, which reduces command execution latency as it is less likely to be interleaved by a rendering tick. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.2@1732 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- core/mixer/mixer.cpp | 29 ++----- core/mixer/mixer.h | 1 - core/producer/color/color_producer.cpp | 7 +- core/producer/frame/frame_factory.h | 3 +- core/producer/stage.cpp | 86 +++++++++++-------- core/producer/stage.h | 14 +-- modules/decklink/interop/DeckLinkAPI_h.h | 2 +- modules/decklink/interop/DeckLinkAPI_i.c | 2 +- modules/flash/producer/cg_producer.cpp | 2 +- modules/flash/producer/flash_producer.cpp | 6 +- modules/image/producer/image_producer.cpp | 7 +- .../image/producer/image_scroll_producer.cpp | 11 ++- protocol/amcp/AMCPCommandsImpl.cpp | 6 +- shell/casparcg.config | 12 +-- 14 files changed, 100 insertions(+), 88 deletions(-) diff --git a/core/mixer/mixer.cpp b/core/mixer/mixer.cpp index beb1665b6..045dbe36b 100644 --- a/core/mixer/mixer.cpp +++ b/core/mixer/mixer.cpp @@ -164,19 +164,10 @@ public: { return image_mixer_.create_frame(tag, desc); } - - safe_ptr create_frame(const void* tag, size_t width, size_t height, core::pixel_format::type pix_fmt) - { - // Create bgra frame - core::pixel_format_desc desc; - desc.pix_fmt = pix_fmt; - desc.planes.push_back(core::pixel_format_desc::plane(width, height, 4)); - return create_frame(tag, desc); - } - + void set_transform(int index, const frame_transform& transform, unsigned int mix_duration, const std::wstring& tween) { - executor_.invoke([&] + executor_.begin_invoke([=] { auto src = transforms_[index].fetch(); auto dst = transform; @@ -186,7 +177,7 @@ public: void apply_transform(int index, const std::function& transform, unsigned int mix_duration, const std::wstring& tween) { - executor_.invoke([&] + executor_.begin_invoke([=] { auto src = transforms_[index].fetch(); auto dst = transform(src); @@ -196,7 +187,7 @@ public: void clear_transforms(int index) { - executor_.invoke([&] + executor_.begin_invoke([=] { transforms_.erase(index); blend_modes_.erase(index); @@ -205,7 +196,7 @@ public: void clear_transforms() { - executor_.invoke([&] + executor_.begin_invoke([=] { transforms_.clear(); blend_modes_.clear(); @@ -214,7 +205,7 @@ public: void set_blend_mode(int index, blend_mode::type value) { - executor_.invoke([&] + executor_.begin_invoke([=] { blend_modes_[index] = value; }, high_priority); @@ -241,14 +232,6 @@ mixer::mixer(const safe_ptr& graph, const safe_ptr void mixer::send(const std::pair>, std::shared_ptr>& frames){ impl_->send(frames);} core::video_format_desc mixer::get_video_format_desc() const { return impl_->get_video_format_desc(); } safe_ptr mixer::create_frame(const void* tag, const core::pixel_format_desc& desc){ return impl_->create_frame(tag, desc); } -safe_ptr mixer::create_frame(const void* tag, size_t width, size_t height, core::pixel_format::type pix_fmt) -{ - // Create bgra frame - core::pixel_format_desc desc; - desc.pix_fmt = pix_fmt; - desc.planes.push_back(core::pixel_format_desc::plane(width, height, 4)); - return create_frame(tag, desc); -} void mixer::set_frame_transform(int index, const core::frame_transform& transform, unsigned int mix_duration, const std::wstring& tween){impl_->set_transform(index, transform, mix_duration, tween);} void mixer::apply_frame_transform(int index, const std::function& transform, unsigned int mix_duration, const std::wstring& tween) {impl_->apply_transform(index, transform, mix_duration, tween);} diff --git a/core/mixer/mixer.h b/core/mixer/mixer.h index 4b52ac819..d1c841d3e 100644 --- a/core/mixer/mixer.h +++ b/core/mixer/mixer.h @@ -56,7 +56,6 @@ public: // mixer safe_ptr create_frame(const void* tag, const core::pixel_format_desc& desc); - safe_ptr create_frame(const void* tag, size_t width, size_t height, pixel_format::type pix_fmt = pixel_format::bgra); core::video_format_desc get_video_format_desc() const; // nothrow void set_video_format_desc(const video_format_desc& format_desc); diff --git a/core/producer/color/color_producer.cpp b/core/producer/color/color_producer.cpp index b6b738c8d..b7d4ab7e2 100644 --- a/core/producer/color/color_producer.cpp +++ b/core/producer/color/color_producer.cpp @@ -119,8 +119,11 @@ safe_ptr create_color_frame(void* tag, const safe_ptrcreate_frame(tag, 1, 1, pixel_format::bgra); + + core::pixel_format_desc desc; + desc.pix_fmt = pixel_format::bgra; + desc.planes.push_back(core::pixel_format_desc::plane(1, 1, 4)); + auto frame = frame_factory->create_frame(tag, desc); // Read color from hex-string and write to frame pixel. diff --git a/core/producer/frame/frame_factory.h b/core/producer/frame/frame_factory.h index c8880155b..fa5deffff 100644 --- a/core/producer/frame/frame_factory.h +++ b/core/producer/frame/frame_factory.h @@ -33,8 +33,7 @@ struct video_format_desc; struct frame_factory : boost::noncopyable { - virtual safe_ptr create_frame(const void* video_stream_tag, const pixel_format_desc& desc) = 0; - virtual safe_ptr create_frame(const void* video_stream_tag, size_t width, size_t height, pixel_format::type pix_fmt = pixel_format::bgra) = 0; + virtual safe_ptr create_frame(const void* video_stream_tag, const pixel_format_desc& desc) = 0; virtual video_format_desc get_video_format_desc() const = 0; // nothrow }; diff --git a/core/producer/stage.cpp b/core/producer/stage.cpp index 9f5bc86a6..3799b87a1 100644 --- a/core/producer/stage.cpp +++ b/core/producer/stage.cpp @@ -108,7 +108,7 @@ public: void load(int index, const safe_ptr& producer, bool preview, int auto_play_delta) { - executor_.invoke([&] + executor_.begin_invoke([=] { layers_[index].load(producer, preview, auto_play_delta); }, high_priority); @@ -116,7 +116,7 @@ public: void pause(int index) { - executor_.invoke([&] + executor_.begin_invoke([=] { layers_[index].pause(); }, high_priority); @@ -124,7 +124,7 @@ public: void play(int index) { - executor_.invoke([&] + executor_.begin_invoke([=] { layers_[index].play(); }, high_priority); @@ -132,7 +132,7 @@ public: void stop(int index) { - executor_.invoke([&] + executor_.begin_invoke([=] { layers_[index].stop(); }, high_priority); @@ -140,7 +140,7 @@ public: void clear(int index) { - executor_.invoke([&] + executor_.begin_invoke([=] { layers_.erase(index); }, high_priority); @@ -148,7 +148,7 @@ public: void clear() { - executor_.invoke([&] + executor_.begin_invoke([=] { layers_.clear(); }, high_priority); @@ -156,62 +156,74 @@ public: boost::unique_future call(int index, bool foreground, const std::wstring& param) { - return std::move(*executor_.invoke([&] + return std::move(*executor_.invoke([=] { return std::make_shared>(std::move(layers_[index].call(foreground, param))); }, high_priority)); } + + void swap_layers(const safe_ptr& other) + { + if(other->impl_.get() == this) + return; + + auto func = [=] + { + std::swap(layers_, other->impl_->layers_); + }; + executor_.begin_invoke([=] + { + other->impl_->executor_.invoke(func, high_priority); + }, high_priority); + } void swap_layer(int index, size_t other_index) { - executor_.invoke([&] + executor_.begin_invoke([=] { std::swap(layers_[index], layers_[other_index]); }, high_priority); } - void swap_layer(int index, size_t other_index, stage& other) + void swap_layer(int index, size_t other_index, const safe_ptr& other) { - if(other.impl_.get() == this) + if(other->impl_.get() == this) swap_layer(index, other_index); else { - auto func = [&] + auto func = [=] { - std::swap(layers_[index], other.impl_->layers_[other_index]); + std::swap(layers_[index], other->impl_->layers_[other_index]); }; - executor_.invoke([&]{other.impl_->executor_.invoke(func, high_priority);}, high_priority); + executor_.begin_invoke([=] + { + other->impl_->executor_.invoke(func, high_priority); + }, high_priority); } } - void swap(stage& other) - { - if(other.impl_.get() == this) - return; - - auto func = [&] - { - std::swap(layers_, other.impl_->layers_); - }; - executor_.invoke([&]{other.impl_->executor_.invoke(func, high_priority);}, high_priority); - } - - layer_status get_status(int index) + boost::unique_future get_status(int index) { - return executor_.invoke([&] + return executor_.begin_invoke([=] { return layers_[index].status(); }, high_priority ); } - safe_ptr foreground(int index) + boost::unique_future> foreground(int index) { - return executor_.invoke([=]{return layers_[index].foreground();}, high_priority); + return executor_.begin_invoke([=] + { + return layers_[index].foreground(); + }, high_priority); } - safe_ptr background(int index) + boost::unique_future> background(int index) { - return executor_.invoke([=]{return layers_[index].background();}, high_priority); + return executor_.begin_invoke([=] + { + return layers_[index].background(); + }, high_priority); } void set_video_format_desc(const video_format_desc& format_desc) @@ -225,18 +237,18 @@ public: stage::stage(const safe_ptr& graph, const safe_ptr& target, const video_format_desc& format_desc) : impl_(new implementation(graph, target, format_desc)){} void stage::spawn_token(){impl_->spawn_token();} -void stage::swap(stage& other){impl_->swap(other);} void stage::load(int index, const safe_ptr& producer, bool preview, int auto_play_delta){impl_->load(index, producer, preview, auto_play_delta);} void stage::pause(int index){impl_->pause(index);} void stage::play(int index){impl_->play(index);} void stage::stop(int index){impl_->stop(index);} void stage::clear(int index){impl_->clear(index);} void stage::clear(){impl_->clear();} +void stage::swap_layers(const safe_ptr& other){impl_->swap_layers(other);} void stage::swap_layer(int index, size_t other_index){impl_->swap_layer(index, other_index);} -void stage::swap_layer(int index, size_t other_index, stage& other){impl_->swap_layer(index, other_index, other);} -layer_status stage::get_status(int index){return impl_->get_status(index);} -safe_ptr stage::foreground(size_t index) {return impl_->foreground(index);} -safe_ptr stage::background(size_t index) {return impl_->background(index);} -void stage::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);} +void stage::swap_layer(int index, size_t other_index, const safe_ptr& other){impl_->swap_layer(index, other_index, other);} +boost::unique_future stage::get_status(int index){return impl_->get_status(index);} +boost::unique_future> stage::foreground(size_t index) {return impl_->foreground(index);} +boost::unique_future> stage::background(size_t index) {return impl_->background(index);} boost::unique_future stage::call(int index, bool foreground, const std::wstring& param){return impl_->call(index, foreground, param);} +void stage::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);} }} \ No newline at end of file diff --git a/core/producer/stage.h b/core/producer/stage.h index 13e9d046f..9e393f46e 100644 --- a/core/producer/stage.h +++ b/core/producer/stage.h @@ -44,7 +44,6 @@ public: void spawn_token(); - void swap(stage& other); void load(int index, const safe_ptr& producer, bool preview = false, int auto_play_delta = -1); void pause(int index); @@ -52,13 +51,14 @@ public: void stop(int index); void clear(int index); void clear(); - boost::unique_future call(int index, bool foreground, const std::wstring& param); + void swap_layers(const safe_ptr& other); void swap_layer(int index, size_t other_index); - void swap_layer(int index, size_t other_index, stage& other); - - layer_status get_status(int index); - safe_ptr foreground(size_t index); - safe_ptr background(size_t index); + void swap_layer(int index, size_t other_index, const safe_ptr& other); + + boost::unique_future call(int index, bool foreground, const std::wstring& param); + boost::unique_future get_status(int index); + boost::unique_future> foreground(size_t index); + boost::unique_future> background(size_t index); void set_video_format_desc(const video_format_desc& format_desc); diff --git a/modules/decklink/interop/DeckLinkAPI_h.h b/modules/decklink/interop/DeckLinkAPI_h.h index 0a81f2a58..1ea2456c4 100644 --- a/modules/decklink/interop/DeckLinkAPI_h.h +++ b/modules/decklink/interop/DeckLinkAPI_h.h @@ -4,7 +4,7 @@ /* File created by MIDL compiler version 7.00.0555 */ -/* at Mon Nov 28 22:42:59 2011 +/* at Wed Nov 30 19:17:46 2011 */ /* Compiler settings for interop\DeckLinkAPI.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 diff --git a/modules/decklink/interop/DeckLinkAPI_i.c b/modules/decklink/interop/DeckLinkAPI_i.c index db8e310e3..45cfc1576 100644 --- a/modules/decklink/interop/DeckLinkAPI_i.c +++ b/modules/decklink/interop/DeckLinkAPI_i.c @@ -6,7 +6,7 @@ /* File created by MIDL compiler version 7.00.0555 */ -/* at Mon Nov 28 22:42:59 2011 +/* at Wed Nov 30 19:17:46 2011 */ /* Compiler settings for interop\DeckLinkAPI.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 diff --git a/modules/flash/producer/cg_producer.cpp b/modules/flash/producer/cg_producer.cpp index a7d2f9387..26f04d4a5 100644 --- a/modules/flash/producer/cg_producer.cpp +++ b/modules/flash/producer/cg_producer.cpp @@ -182,7 +182,7 @@ public: safe_ptr get_default_cg_producer(const safe_ptr& video_channel, int render_layer) { - auto flash_producer = video_channel->stage()->foreground(render_layer); + auto flash_producer = video_channel->stage()->foreground(render_layer).get(); if(flash_producer->print().find(L"flash[") == std::string::npos) // UGLY hack { diff --git a/modules/flash/producer/flash_producer.cpp b/modules/flash/producer/flash_producer.cpp index da8a34d26..b3e0072ed 100644 --- a/modules/flash/producer/flash_producer.cpp +++ b/modules/flash/producer/flash_producer.cpp @@ -248,7 +248,11 @@ public: fast_memclr(bmp_.data(), width_*height_*4); ax_->DrawControl(bmp_); - auto frame = frame_factory_->create_frame(this, width_, height_); + core::pixel_format_desc desc; + desc.pix_fmt = core::pixel_format::bgra; + desc.planes.push_back(core::pixel_format_desc::plane(width_, height_, 4)); + auto frame = frame_factory_->create_frame(this, desc); + fast_memcpy(frame->image_data().begin(), bmp_.data(), width_*height_*4); frame->commit(); head_ = frame; diff --git a/modules/image/producer/image_producer.cpp b/modules/image/producer/image_producer.cpp index fcadb7aab..532fd9d21 100644 --- a/modules/image/producer/image_producer.cpp +++ b/modules/image/producer/image_producer.cpp @@ -49,7 +49,12 @@ struct image_producer : public core::frame_producer { auto bitmap = load_image(filename_); FreeImage_FlipVertical(bitmap.get()); - auto frame = frame_factory->create_frame(this, FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), core::pixel_format::bgra); + + core::pixel_format_desc desc; + desc.pix_fmt = core::pixel_format::bgra; + desc.planes.push_back(core::pixel_format_desc::plane(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), 4)); + auto frame = frame_factory->create_frame(this, desc); + std::copy_n(FreeImage_GetBits(bitmap.get()), frame->image_data().size(), frame->image_data().begin()); frame->commit(); frame_ = std::move(frame); diff --git a/modules/image/producer/image_scroll_producer.cpp b/modules/image/producer/image_scroll_producer.cpp index 93a07c65c..860a0391e 100644 --- a/modules/image/producer/image_scroll_producer.cpp +++ b/modules/image/producer/image_scroll_producer.cpp @@ -84,7 +84,11 @@ struct image_scroll_producer : public core::frame_producer { while(count > 0) { - auto frame = frame_factory->create_frame(reinterpret_cast(rand()), width_, format_desc_.height); + core::pixel_format_desc desc; + desc.pix_fmt = core::pixel_format::bgra; + desc.planes.push_back(core::pixel_format_desc::plane(width_, format_desc_.height, 4)); + auto frame = frame_factory->create_frame(reinterpret_cast(rand()), desc); + if(count >= frame->image_data().size()) { std::copy_n(bytes + count - frame->image_data().size(), frame->image_data().size(), frame->image_data().begin()); @@ -113,7 +117,10 @@ struct image_scroll_producer : public core::frame_producer int i = 0; while(count > 0) { - auto frame = frame_factory->create_frame(reinterpret_cast(rand()), format_desc_.width, height_); + core::pixel_format_desc desc; + desc.pix_fmt = core::pixel_format::bgra; + desc.planes.push_back(core::pixel_format_desc::plane(format_desc_.width, height_, 4)); + auto frame = frame_factory->create_frame(reinterpret_cast(rand()), desc); if(count >= frame->image_data().size()) { for(size_t y = 0; y < height_; ++y) diff --git a/protocol/amcp/AMCPCommandsImpl.cpp b/protocol/amcp/AMCPCommandsImpl.cpp index 444bbf1cf..62ffd1b23 100644 --- a/protocol/amcp/AMCPCommandsImpl.cpp +++ b/protocol/amcp/AMCPCommandsImpl.cpp @@ -491,13 +491,13 @@ bool SwapCommand::DoExecute() int l1 = GetLayerIndex(); int l2 = boost::lexical_cast(strs.at(1)); - ch1->stage()->swap_layer(l1, l2, *ch2->stage()); + ch1->stage()->swap_layer(l1, l2, ch2->stage()); } else { auto ch1 = GetChannel(); auto ch2 = GetChannels().at(boost::lexical_cast(_parameters[0])-1); - ch1->stage()->swap(*ch2->stage()); + ch1->stage()->swap_layers(ch2->stage()); } CASPAR_LOG(info) << "Swapped successfully"; @@ -804,7 +804,7 @@ bool StatusCommand::DoExecute() { if (GetLayerIndex() > -1) { - auto status = GetChannel()->stage()->get_status(GetLayerIndex()); + auto status = GetChannel()->stage()->get_status(GetLayerIndex()).get(); std::wstringstream status_text; status_text << L"201 STATUS OK\r\n" diff --git a/shell/casparcg.config b/shell/casparcg.config index 7303afce0..4d3d10108 100644 --- a/shell/casparcg.config +++ b/shell/casparcg.config @@ -1,18 +1,18 @@ - F:\casparcg\_media\ - F:\casparcg\_log\ - F:\casparcg\_data\ - F:\casparcg\_templates\ + D:\casparcg\_media\ + D:\casparcg\_log\ + D:\casparcg\_data\ + D:\casparcg\_templates\ PAL - + true - + -- 2.39.2