From c6451f26fb01554e326549cb26ec529ccf13fe5c Mon Sep 17 00:00:00 2001 From: ronag Date: Fri, 2 Dec 2011 14:27:03 +0000 Subject: [PATCH] 2.0.2: Improved INFO. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.2@1757 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- casparcg.sln | 20 ++++++------ core/consumer/frame_consumer.cpp | 6 ++-- core/consumer/frame_consumer.h | 2 +- core/consumer/output.cpp | 39 +++++++++++++++++++++--- core/consumer/output.h | 14 ++++++--- core/mixer/mixer.cpp | 9 ++++++ core/mixer/mixer.h | 8 ++++- core/producer/frame_producer.h | 8 +++++ core/producer/layer.cpp | 13 ++++++++ core/producer/layer.h | 3 ++ core/producer/stage.cpp | 22 ++++++++++++- core/producer/stage.h | 4 +++ core/video_channel.cpp | 23 ++++++++++++++ core/video_channel.h | 4 +++ modules/decklink/interop/DeckLinkAPI_h.h | 2 +- modules/decklink/interop/DeckLinkAPI_i.c | 2 +- modules/flash/util/swf.cpp | 14 ++++++--- modules/flash/util/swf.h | 4 ++- protocol/amcp/AMCPCommandsImpl.cpp | 35 +++++++++++++++------ shell/casparcg.config | 8 +++++ 20 files changed, 197 insertions(+), 43 deletions(-) diff --git a/casparcg.sln b/casparcg.sln index bd760c768..ef1bcec92 100644 --- a/casparcg.sln +++ b/casparcg.sln @@ -1,8 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common\common.vcxproj", "{02308602-7FE0-4253-B96E-22134919F56A}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "core\core.vcxproj", "{79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shell", "shell\shell.vcxproj", "{8C26C94F-8092-4769-8D84-DEA479721C5B}" @@ -31,6 +29,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ogl", "modules\ogl\ogl.vcxp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image", "modules\image\image.vcxproj", "{3E11FF65-A9DA-4F80-87F2-A7C6379ED5E2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common\common.vcxproj", "{02308602-7FE0-4253-B96E-22134919F56A}" +EndProject Global GlobalSection(SubversionScc) = preSolution Svn-Managed = True @@ -43,14 +43,6 @@ Global Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {02308602-7FE0-4253-B96E-22134919F56A}.Debug|Win32.ActiveCfg = Debug|Win32 - {02308602-7FE0-4253-B96E-22134919F56A}.Debug|Win32.Build.0 = Debug|Win32 - {02308602-7FE0-4253-B96E-22134919F56A}.Develop|Win32.ActiveCfg = Develop|Win32 - {02308602-7FE0-4253-B96E-22134919F56A}.Develop|Win32.Build.0 = Develop|Win32 - {02308602-7FE0-4253-B96E-22134919F56A}.Profile|Win32.ActiveCfg = Profile|Win32 - {02308602-7FE0-4253-B96E-22134919F56A}.Profile|Win32.Build.0 = Profile|Win32 - {02308602-7FE0-4253-B96E-22134919F56A}.Release|Win32.ActiveCfg = Release|Win32 - {02308602-7FE0-4253-B96E-22134919F56A}.Release|Win32.Build.0 = Release|Win32 {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Debug|Win32.ActiveCfg = Debug|Win32 {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Debug|Win32.Build.0 = Debug|Win32 {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Develop|Win32.ActiveCfg = Develop|Win32 @@ -131,6 +123,14 @@ Global {3E11FF65-A9DA-4F80-87F2-A7C6379ED5E2}.Profile|Win32.Build.0 = Profile|Win32 {3E11FF65-A9DA-4F80-87F2-A7C6379ED5E2}.Release|Win32.ActiveCfg = Release|Win32 {3E11FF65-A9DA-4F80-87F2-A7C6379ED5E2}.Release|Win32.Build.0 = Release|Win32 + {02308602-7FE0-4253-B96E-22134919F56A}.Debug|Win32.ActiveCfg = Debug|Win32 + {02308602-7FE0-4253-B96E-22134919F56A}.Debug|Win32.Build.0 = Debug|Win32 + {02308602-7FE0-4253-B96E-22134919F56A}.Develop|Win32.ActiveCfg = Develop|Win32 + {02308602-7FE0-4253-B96E-22134919F56A}.Develop|Win32.Build.0 = Develop|Win32 + {02308602-7FE0-4253-B96E-22134919F56A}.Profile|Win32.ActiveCfg = Profile|Win32 + {02308602-7FE0-4253-B96E-22134919F56A}.Profile|Win32.Build.0 = Profile|Win32 + {02308602-7FE0-4253-B96E-22134919F56A}.Release|Win32.ActiveCfg = Release|Win32 + {02308602-7FE0-4253-B96E-22134919F56A}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/core/consumer/frame_consumer.cpp b/core/consumer/frame_consumer.cpp index 11eb115ee..45974d014 100644 --- a/core/consumer/frame_consumer.cpp +++ b/core/consumer/frame_consumer.cpp @@ -71,8 +71,8 @@ class cadence_guard : public frame_consumer boost::circular_buffer sync_buffer_; bool synced_; public: - cadence_guard(safe_ptr&& consumer) - : consumer_(std::move(consumer)) + cadence_guard(const safe_ptr& consumer) + : consumer_(consumer) { } @@ -126,7 +126,7 @@ public: } }; -safe_ptr create_consumer_cadence_guard(safe_ptr&& consumer) +safe_ptr create_consumer_cadence_guard(const safe_ptr& consumer) { return make_safe(std::move(consumer)); } diff --git a/core/consumer/frame_consumer.h b/core/consumer/frame_consumer.h index 3d8fb1f93..a75882a5a 100644 --- a/core/consumer/frame_consumer.h +++ b/core/consumer/frame_consumer.h @@ -59,7 +59,7 @@ struct frame_consumer : boost::noncopyable } }; -safe_ptr create_consumer_cadence_guard(safe_ptr&& consumer); +safe_ptr create_consumer_cadence_guard(const safe_ptr& consumer); typedef std::function(const std::vector&)> consumer_factory_t; diff --git a/core/consumer/output.cpp b/core/consumer/output.cpp index 4a7f810b3..b2258e912 100644 --- a/core/consumer/output.cpp +++ b/core/consumer/output.cpp @@ -40,6 +40,7 @@ #include #include #include +#include namespace caspar { namespace core { @@ -69,20 +70,25 @@ public: graph_->set_color("consume-time", diagnostics::color(1.0f, 0.4f, 0.0f)); } - void add(safe_ptr&& consumer) + void add(int index, safe_ptr consumer) { - remove(consumer->index()); + remove(index); - consumer = create_consumer_cadence_guard(std::move(consumer)); + consumer = create_consumer_cadence_guard(consumer); consumer->initialize(format_desc_, channel_index_); executor_.invoke([&] { - consumers_.insert(std::make_pair(consumer->index(), consumer)); + consumers_.insert(std::make_pair(index, consumer)); CASPAR_LOG(info) << print() << L" " << consumer->print() << L" Added."; }, high_priority); } + void add(const safe_ptr& consumer) + { + add(consumer->index(), consumer); + } + void remove(int index) { // Destroy consumer on calling thread: @@ -105,6 +111,11 @@ public: CASPAR_LOG(info) << print() << L" " << str << L" Removed."; } } + + void remove(const safe_ptr& consumer) + { + remove(consumer->index()); + } void set_video_format_desc(const video_format_desc& format_desc) { @@ -225,11 +236,29 @@ public: { return L"output[" + boost::lexical_cast(channel_index_) + L"]"; } + + boost::unique_future info() + { + return std::move(executor_.begin_invoke([&]() -> boost::property_tree::wptree + { + boost::property_tree::wptree info; + BOOST_FOREACH(auto& consumer, consumers_) + { + auto& node = info.add(L"output.devices.device", L""); + node.add(L"index", consumer.first); + node.add(L"consumer", consumer.second->print()); + } + return info; + }, high_priority)); + } }; output::output(const safe_ptr& graph, const video_format_desc& format_desc, int channel_index) : impl_(new implementation(graph, format_desc, channel_index)){} -void output::add(safe_ptr&& consumer){impl_->add(std::move(consumer));} +void output::add(int index, const safe_ptr& consumer){impl_->add(index, consumer);} +void output::add(const safe_ptr& consumer){impl_->add(consumer);} void output::remove(int index){impl_->remove(index);} +void output::remove(const safe_ptr& consumer){impl_->remove(consumer);} void output::send(const std::pair, std::shared_ptr>& frame) {impl_->send(frame); } void output::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);} +boost::unique_future output::info() const{return impl_->info();} }} \ No newline at end of file diff --git a/core/consumer/output.h b/core/consumer/output.h index 3f9f638b0..656e8e2a8 100644 --- a/core/consumer/output.h +++ b/core/consumer/output.h @@ -26,25 +26,31 @@ #include #include +#include +#include namespace caspar { namespace core { -class output : public target, std::shared_ptr>>, boost::noncopyable +class output : public target, std::shared_ptr>> + , boost::noncopyable { public: explicit output(const safe_ptr& graph, const video_format_desc& format_desc, int channel_index); // target - virtual void send(const std::pair, std::shared_ptr>& frame) override; + virtual void send( const std::pair, std::shared_ptr>& frame) override; // output - - void add(safe_ptr&& consumer); + + void add(const safe_ptr& consumer); + void add(int index, const safe_ptr& consumer); + void remove(const safe_ptr& consumer); void remove(int index); void set_video_format_desc(const video_format_desc& format_desc); + boost::unique_future info() const; private: struct implementation; safe_ptr impl_; diff --git a/core/mixer/mixer.cpp b/core/mixer/mixer.cpp index 045dbe36b..793bf395e 100644 --- a/core/mixer/mixer.cpp +++ b/core/mixer/mixer.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -225,6 +226,13 @@ public: tbb::spin_mutex::scoped_lock lock(format_desc_mutex_); return format_desc_; } + + boost::unique_future info() const + { + boost::promise info; + info.set_value(boost::property_tree::wptree()); + return info.get_future(); + } }; mixer::mixer(const safe_ptr& graph, const safe_ptr& target, const video_format_desc& format_desc, const safe_ptr& ogl) @@ -239,4 +247,5 @@ void mixer::clear_transforms(int index){impl_->clear_transforms(index);} void mixer::clear_transforms(){impl_->clear_transforms();} void mixer::set_blend_mode(int index, blend_mode::type value){impl_->set_blend_mode(index, value);} void mixer::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);} +boost::unique_future mixer::info() const{return impl_->info();} }} \ No newline at end of file diff --git a/core/mixer/mixer.h b/core/mixer/mixer.h index d1c841d3e..d17207772 100644 --- a/core/mixer/mixer.h +++ b/core/mixer/mixer.h @@ -27,6 +27,9 @@ #include #include +#include +#include + #include namespace caspar { @@ -42,7 +45,8 @@ class ogl_device; struct frame_transform; struct pixel_format; -class mixer : public target>, std::shared_ptr>>, public core::frame_factory +class mixer : public target>, std::shared_ptr>> + , public core::frame_factory { public: typedef target, std::shared_ptr>> target_t; @@ -66,6 +70,8 @@ public: void clear_transforms(); void set_blend_mode(int index, blend_mode::type value); + + boost::unique_future info() const; private: struct implementation; diff --git a/core/producer/frame_producer.h b/core/producer/frame_producer.h index ac7ba1ea6..93c45ddfe 100644 --- a/core/producer/frame_producer.h +++ b/core/producer/frame_producer.h @@ -31,6 +31,7 @@ #include #include +#include namespace caspar { @@ -61,6 +62,13 @@ public: return promise.get_future(); } + virtual boost::property_tree::wptree info() const + { + boost::property_tree::wptree info; + info.push_front(std::make_pair(L"producer", print())); + return info; + } + virtual safe_ptr get_following_producer() const {return frame_producer::empty();} // nothrow virtual void set_leading_producer(const safe_ptr&) {} // nothrow diff --git a/core/producer/layer.cpp b/core/producer/layer.cpp index 14ee70457..7548ab990 100644 --- a/core/producer/layer.cpp +++ b/core/producer/layer.cpp @@ -25,6 +25,8 @@ #include "frame_producer.h" #include "frame/basic_frame.h" +#include + namespace caspar { namespace core { struct layer::implementation @@ -144,6 +146,16 @@ public: { return background_ == core::frame_producer::empty() && foreground_ == core::frame_producer::empty(); } + + boost::property_tree::wptree info() const + { + boost::property_tree::wptree info; + info.add_child(L"layer.foreground", foreground_->info()); + info.add_child(L"layer.background", foreground_->info()); + info.add(L"layer.status", is_paused_ ? L"paused" : (foreground_ == frame_producer::empty() ? L"stopped" : L"playing")); + info.add(L"layer.auto_delta", auto_play_delta_); + return info; + } }; layer::layer() : impl_(new implementation()){} @@ -176,4 +188,5 @@ safe_ptr layer::foreground() const { return impl_->foreground_;} safe_ptr layer::background() const { return impl_->background_;} bool layer::empty() const {return impl_->empty();} boost::unique_future layer::call(bool foreground, const std::wstring& param){return impl_->call(foreground, param);} +boost::property_tree::wptree layer::info() const{return impl_->info();} }} \ No newline at end of file diff --git a/core/producer/layer.h b/core/producer/layer.h index 45eda8dad..cd8e57e6c 100644 --- a/core/producer/layer.h +++ b/core/producer/layer.h @@ -24,6 +24,7 @@ #include #include +#include #include @@ -71,6 +72,8 @@ public: safe_ptr background() const; // nothrow safe_ptr receive(); // nothrow + + boost::property_tree::wptree info() const; private: struct implementation; safe_ptr impl_; diff --git a/core/producer/stage.cpp b/core/producer/stage.cpp index 3799b87a1..f2f38dd76 100644 --- a/core/producer/stage.cpp +++ b/core/producer/stage.cpp @@ -34,6 +34,8 @@ #include +#include + #include namespace caspar { namespace core { @@ -231,7 +233,24 @@ public: executor_.begin_invoke([=] { format_desc_ = format_desc; - }, high_priority ); + }, high_priority); + } + + boost::unique_future info() + { + return std::move(executor_.begin_invoke([&]() -> boost::property_tree::wptree + { + boost::property_tree::wptree info; + auto& layers_node = info.add(L"layers", L""); + BOOST_FOREACH(auto& layer, layers_) + { + auto layer_info = layer.second.info(); + layer_info.add(L"layer.index", layer.first); + BOOST_FOREACH(auto& update, layer_info) + layers_node.add_child(update.first, update.second); + } + return info; + }, high_priority)); } }; @@ -251,4 +270,5 @@ boost::unique_future> stage::foreground(size_t 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);} +boost::unique_future stage::info() const{return impl_->info();} }} \ No newline at end of file diff --git a/core/producer/stage.h b/core/producer/stage.h index 9e393f46e..eff2545b7 100644 --- a/core/producer/stage.h +++ b/core/producer/stage.h @@ -27,6 +27,8 @@ #include #include +#include +#include namespace caspar { namespace core { @@ -62,6 +64,8 @@ public: void set_video_format_desc(const video_format_desc& format_desc); + boost::unique_future info() const; + private: struct implementation; safe_ptr impl_; diff --git a/core/video_channel.cpp b/core/video_channel.cpp index 67eebfde8..5cca96834 100644 --- a/core/video_channel.cpp +++ b/core/video_channel.cpp @@ -32,6 +32,8 @@ #include #include +#include + #include namespace caspar { namespace core { @@ -86,6 +88,26 @@ public: { return L"video_channel[" + boost::lexical_cast(index_) + L"|" + format_desc_.name + L"]"; } + + boost::property_tree::wptree info() const + { + boost::property_tree::wptree info; + info.put(L"channel.video-mode", format_desc_.name); + + auto& channel_node = info.get_child(L"channel"); + auto stage_info = stage_->info(); + auto mixer_info = mixer_->info(); + auto output_info = output_->info(); + + BOOST_FOREACH(auto& update, stage_info.get()) + channel_node.put_child(update.first, update.second); + BOOST_FOREACH(auto& update, mixer_info.get()) + channel_node.put_child(update.first, update.second); + BOOST_FOREACH(auto& update, output_info.get()) + channel_node.put_child(update.first, update.second); + + return info; + } }; video_channel::video_channel(int index, const video_format_desc& format_desc, const safe_ptr& ogl) : impl_(new implementation(index, format_desc, ogl)){} @@ -94,5 +116,6 @@ 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_->format_desc_;} void video_channel::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);} +boost::property_tree::wptree video_channel::info() const{return impl_->info();} }} \ No newline at end of file diff --git a/core/video_channel.h b/core/video_channel.h index 450354861..66d884847 100644 --- a/core/video_channel.h +++ b/core/video_channel.h @@ -24,6 +24,8 @@ #include +#include + namespace caspar { namespace core { class stage; @@ -43,6 +45,8 @@ public: video_format_desc get_video_format_desc() const; void set_video_format_desc(const video_format_desc& format_desc); + + boost::property_tree::wptree info() const; private: struct implementation; diff --git a/modules/decklink/interop/DeckLinkAPI_h.h b/modules/decklink/interop/DeckLinkAPI_h.h index 67c772703..c9abad893 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 Thu Dec 01 20:20:22 2011 +/* at Fri Dec 02 15:12:59 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 1e212c150..b150561c0 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 Thu Dec 01 20:20:22 2011 +/* at Fri Dec 02 15:12:59 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/util/swf.cpp b/modules/flash/util/swf.cpp index b8cf015f6..b12becf53 100644 --- a/modules/flash/util/swf.cpp +++ b/modules/flash/util/swf.cpp @@ -2,11 +2,15 @@ #include -#include -#include +#include +#include +#include #include +#include +#include + namespace caspar { namespace flash { std::vector decompress_one_file(const std::vector& in_data, uLong buf_size = 5000000) @@ -29,7 +33,7 @@ std::vector decompress_one_file(const std::vector& in_data, uLong bu return out_data; } -std::wstring read_template_meta_info(const std::wstring& filename) +std::string read_template_meta_info(const std::wstring& filename) { auto file = std::fstream(filename, std::ios::in | std::ios::binary); @@ -67,8 +71,8 @@ std::wstring read_template_meta_info(const std::wstring& filename) if(beg_it == data.end() || end_it == data.end()) BOOST_THROW_EXCEPTION(file_read_error()); - - return widen(std::string(beg_it, end_it+end_str.size())); + + return std::string(beg_it, end_it+end_str.size()); } }} \ No newline at end of file diff --git a/modules/flash/util/swf.h b/modules/flash/util/swf.h index 9cbfb3996..46675b5c2 100644 --- a/modules/flash/util/swf.h +++ b/modules/flash/util/swf.h @@ -2,8 +2,10 @@ #include +#include + namespace caspar { namespace flash { -std::wstring read_template_meta_info(const std::wstring& filename); +std::string read_template_meta_info(const std::wstring& filename); }} \ No newline at end of file diff --git a/protocol/amcp/AMCPCommandsImpl.cpp b/protocol/amcp/AMCPCommandsImpl.cpp index 339415d7b..d0d4090d2 100644 --- a/protocol/amcp/AMCPCommandsImpl.cpp +++ b/protocol/amcp/AMCPCommandsImpl.cpp @@ -57,6 +57,7 @@ #include #include #include +#include /* Return codes @@ -525,7 +526,8 @@ bool AddCommand::DoExecute() //Perform loading of the clip try { - GetChannel()->output()->add(create_consumer(_parameters)); + auto consumer = create_consumer(_parameters); + GetChannel()->output()->add(GetLayerIndex(consumer->index()), consumer); CASPAR_LOG(info) << "Added " << _parameters[0] << TEXT(" successfully"); @@ -1301,7 +1303,7 @@ bool CinfCommand::DoExecute() SetReplyString(TEXT("404 CINF ERROR\r\n")); return false; } - replyString << TEXT("200 INFO OK\r\n"); + replyString << TEXT("200 CINF OK\r\n"); replyString << info << "\r\n"; } catch(...) @@ -1331,7 +1333,10 @@ bool InfoCommand::DoExecute() std::wstringstream ss; ss << L"201 INFO OK\r\n"; - ss << flash::read_template_meta_info(filename) << L"\r\n"; + + auto xml = flash::read_template_meta_info(filename); + ss << widen(xml); + ss << L"\r\n"; SetReplyString(ss.str()); return true; @@ -1347,19 +1352,29 @@ bool InfoCommand::DoExecute() try { std::wstringstream replyString; + replyString << TEXT("201 INFO OK\r\n"); + if(_parameters.size() >= 1) { - int channelIndex = boost::lexical_cast(_parameters.at(0).c_str())-1; - replyString << TEXT("201 INFO OK\r\n"); - GenerateChannelInfo(channelIndex, channels_.at(channelIndex), replyString); + int channelIndex = boost::lexical_cast(_parameters.at(0).c_str())-1; + boost::property_tree::xml_parser::write_xml(replyString, channels_.at(channelIndex)->info(), boost::property_tree::xml_writer_settings(' ', 3)); } else { - replyString << TEXT("200 INFO OK\r\n"); - for(size_t n = 0; n < channels_.size(); ++n) - GenerateChannelInfo(n, channels_[n], replyString); - replyString << TEXT("\r\n"); + boost::property_tree::wptree info; + auto& node = info.add(L"channels", L""); + int index = 0; + BOOST_FOREACH(auto channel, channels_) + { + BOOST_FOREACH(auto update, channel->info()) + { + auto& channel = node.add_child(update.first, update.second); + channel.push_front(std::make_pair(L"index", boost::lexical_cast(++index))); + } + } + boost::property_tree::xml_parser::write_xml(replyString, info, boost::property_tree::xml_writer_settings(' ', 3)); } + replyString << TEXT("\r\n"); SetReplyString(replyString.str()); return true; } diff --git a/shell/casparcg.config b/shell/casparcg.config index 092fa0334..56068843d 100644 --- a/shell/casparcg.config +++ b/shell/casparcg.config @@ -7,6 +7,14 @@ D:\casparcg\_templates\ + + 720p5000 + + + 1 + + + 720p5000 -- 2.39.2