\r
boost::unique_future<std::wstring> call(const std::wstring& str)\r
{ \r
- static const boost::wregex add_exp (L"ADD (?<LAYER>\\d+) (?<FILENAME>[^\\s]+) (?<PLAY_ON_LOAD>\\d)( (?<DATA>.*))?");\r
- static const boost::wregex remove_exp (L"REMOVE (?<LAYER>\\d+)");\r
- static const boost::wregex play_exp (L"PLAY (?<LAYER>\\d+)");\r
- static const boost::wregex stop_exp (L"STOP (?<LAYER>\\d+)");\r
- static const boost::wregex next_exp (L"NEXT (?<LAYER>\\d+)");\r
- static const boost::wregex update_exp (L"UPDATE (?<LAYER>\\d+) (?<DATA>.+)");\r
- static const boost::wregex invoke_exp (L"INVOKE (?<LAYER>\\d+) (?<LABEL>.+)");\r
- static const boost::wregex description_exp (L"INFO (?<LAYER>\\d+)");\r
- static const boost::wregex info_exp (L"INFO");\r
+ static const boost::wregex add_exp (L"ADD (?<LAYER>\\d+) (?<FILENAME>[^\\s]+) (?<PLAY_ON_LOAD>\\d)( (?<DATA>.*))?", boost::regex::perl|boost::regex::icase);\r
+ static const boost::wregex remove_exp (L"REMOVE (?<LAYER>\\d+)", boost::regex::perl|boost::regex::icase);\r
+ static const boost::wregex play_exp (L"PLAY (?<LAYER>\\d+)", boost::regex::perl|boost::regex::icase);\r
+ static const boost::wregex stop_exp (L"STOP (?<LAYER>\\d+)", boost::regex::perl|boost::regex::icase);\r
+ static const boost::wregex next_exp (L"NEXT (?<LAYER>\\d+)", boost::regex::perl|boost::regex::icase);\r
+ static const boost::wregex update_exp (L"UPDATE (?<LAYER>\\d+) (?<DATA>.+)", boost::regex::perl|boost::regex::icase);\r
+ static const boost::wregex invoke_exp (L"INVOKE (?<LAYER>\\d+) (?<LABEL>.+)", boost::regex::perl|boost::regex::icase);\r
+ static const boost::wregex description_exp (L"INFO (?<LAYER>\\d+)", boost::regex::perl|boost::regex::icase);\r
+ static const boost::wregex info_exp (L"INFO", boost::regex::perl|boost::regex::icase);\r
\r
boost::wsmatch what;\r
if(boost::regex_match(str, what, add_exp))\r
}\r
};\r
\r
-safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::video_channel>& video_channel, int render_layer)\r
+safe_ptr<cg_producer> get_default_cg_producer(\r
+ const safe_ptr<core::video_channel>& video_channel,\r
+ bool expect_existing,\r
+ int render_layer)\r
{ \r
auto flash_producer = video_channel->stage()->foreground(render_layer).get();\r
\r
{\r
if(flash_producer->print().find(L"flash[") == std::string::npos) // UGLY hack\r
{\r
+ if (expect_existing)\r
+ BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(\r
+ "No flash producer on layer "\r
+ + boost::lexical_cast<std::string>(render_layer)));\r
+\r
flash_producer = flash::create_producer(video_channel->mixer(), boost::assign::list_of<std::wstring>()); \r
video_channel->stage()->load(render_layer, flash_producer); \r
video_channel->stage()->play(render_layer);\r
}\r
+\r
+ if (expect_existing && flash_producer->call(L"?").get() == L"0")\r
+ BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(\r
+ "No flash player on layer "\r
+ + boost::lexical_cast<std::string>(render_layer)));\r
}\r
catch(...)\r
{\r
struct implementation;\r
std::shared_ptr<implementation> impl_;\r
};\r
-safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::video_channel>& video_channel, int layer_index = cg_producer::DEFAULT_LAYER);\r
+safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::video_channel>& video_channel, bool expect_existing, int layer_index = cg_producer::DEFAULT_LAYER);\r
\r
safe_ptr<core::frame_producer> create_ct_producer(\r
const safe_ptr<core::frame_factory>& frame_factory,\r
#include <common/env.h>\r
#include <common/concurrency/executor.h>\r
#include <common/concurrency/lock.h>\r
+#include <common/concurrency/future_util.h>\r
#include <common/diagnostics/graph.h>\r
#include <common/memory/memcpy.h>\r
#include <common/memory/memclr.h>\r
safe_ptr<core::basic_frame> last_frame_;\r
\r
std::unique_ptr<flash_renderer> renderer_;\r
+ tbb::atomic<bool> has_renderer_;\r
\r
executor executor_; \r
public:\r
diagnostics::register_graph(graph_);\r
\r
renderer_.reset(new flash_renderer(graph_, frame_factory_, filename_, width_, height_));\r
+ has_renderer_ = true;\r
\r
while(output_buffer_.size() < buffer_size_)\r
output_buffer_.push(core::basic_frame::empty());\r
\r
virtual boost::unique_future<std::wstring> call(const std::wstring& param) override\r
{ \r
+ if (param == L"?")\r
+ return wrap_as_future(std::wstring(has_renderer_ ? L"1" : L"0"));\r
+\r
return executor_.begin_invoke([this, param]() -> std::wstring\r
- { \r
+ {\r
try\r
{\r
if(!renderer_)\r
\r
while(output_buffer_.size() < buffer_size_)\r
output_buffer_.push(core::basic_frame::empty());\r
+\r
+ has_renderer_ = true;\r
}\r
\r
return renderer_->call(param); \r
{\r
CASPAR_LOG_CURRENT_EXCEPTION();\r
renderer_.reset(nullptr);\r
+ has_renderer_ = false;\r
}\r
\r
return L"";\r
fps_.fetch_and_store(static_cast<int>(renderer_->fps()*100.0)); \r
graph_->set_text(print());\r
\r
- if(renderer_->is_empty()) \r
+ if(renderer_->is_empty())\r
+ {\r
renderer_.reset();\r
+ has_renderer_ = false;\r
+ }\r
}\r
\r
output_buffer_.push(std::move(frame_buffer_.front()));\r
std::wstring filename = _parameters[2];\r
filename.append(extension);\r
\r
- flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->add(layer, filename, bDoStart, label, (pDataString!=0) ? pDataString : TEXT(""));\r
+ flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), false, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->add(layer, filename, bDoStart, label, (pDataString!=0) ? pDataString : TEXT(""));\r
SetReplyString(TEXT("202 CG OK\r\n"));\r
}\r
else\r
return false;\r
}\r
int layer = _ttoi(_parameters[1].c_str());\r
- flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->play(layer);\r
+ flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), true, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->play(layer);\r
}\r
else\r
{\r
return false;\r
}\r
int layer = _ttoi(_parameters[1].c_str());\r
- flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->stop(layer, 0);\r
+ flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), true, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->stop(layer, 0);\r
}\r
else \r
{\r
}\r
\r
int layer = _ttoi(_parameters[1].c_str());\r
- flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->next(layer);\r
+ flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), true, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->next(layer);\r
}\r
else \r
{\r
}\r
\r
int layer = _ttoi(_parameters[1].c_str());\r
- flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->remove(layer);\r
+ flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), true, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->remove(layer);\r
}\r
else \r
{\r
} \r
\r
int layer = _ttoi(_parameters.at(1).c_str());\r
- flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->update(layer, dataString);\r
+ flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), true, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->update(layer, dataString);\r
}\r
catch(...)\r
{\r
return false;\r
}\r
int layer = _ttoi(_parameters[1].c_str());\r
- auto result = flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->invoke(layer, _parameters.at_original(2));\r
+ auto result = flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), true, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->invoke(layer, _parameters.at_original(2));\r
replyString << result << TEXT("\r\n"); \r
}\r
else \r
}\r
\r
int layer = _ttoi(_parameters[1].c_str());\r
- auto desc = flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->description(layer);\r
+ auto desc = flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), false, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->description(layer);\r
\r
replyString << desc << TEXT("\r\n"); \r
}\r
else \r
{\r
- auto info = flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->template_host_info();\r
+ auto info = flash::get_default_cg_producer(safe_ptr<core::video_channel>(GetChannel()), false, GetLayerIndex(flash::cg_producer::DEFAULT_LAYER))->template_host_info();\r
replyString << info << TEXT("\r\n"); \r
} \r
\r
{\r
// HACK fix. The data sent is UTF8, however the protocol is implemented for ISO-8859-1. Instead of doing risky changes we simply convert into proper encoding when leaving protocol code.\r
auto xmlData2 = boost::locale::conv::utf_to_utf<wchar_t, char>(std::string(xmlData_.begin(), xmlData_.end()));\r
- flash::get_default_cg_producer(pCIIStrategy_->GetChannel())->add(layer_, filename_, false, TEXT(""), xmlData2);\r
+ flash::get_default_cg_producer(pCIIStrategy_->GetChannel(), false)->add(layer_, filename_, false, TEXT(""), xmlData2);\r
}\r
}\r
\r
\r
//TODO: Need to be checked for validity\r
else if(state_ == 1)\r
- flash::get_default_cg_producer(pCIIStrategy_->GetChannel())->stop(layer_, 0);\r
+ flash::get_default_cg_producer(pCIIStrategy_->GetChannel(), false)->stop(layer_, 0);\r
else if(state_ == 2)\r
pCIIStrategy_->GetChannel()->stage()->clear(flash::cg_producer::DEFAULT_LAYER);\r
else if(state_ == 3)\r
- flash::get_default_cg_producer(pCIIStrategy_->GetChannel())->play(layer_);\r
+ flash::get_default_cg_producer(pCIIStrategy_->GetChannel(), false)->play(layer_);\r
}\r
\r
void KeydataCommand::Setup(const std::vector<std::wstring>& parameters) {\r
{\r
if (!clock_loaded_) \r
{\r
- flash::get_default_cg_producer(channel_)->add(\r
+ flash::get_default_cg_producer(channel_, false)->add(\r
0, L"hawrysklocka/clock.ft", true, L"", data);\r
clock_loaded_ = true;\r
}\r
else\r
{\r
- flash::get_default_cg_producer(channel_)->update(0, data);\r
+ flash::get_default_cg_producer(channel_, false)->update(0, data);\r
}\r
\r
CASPAR_LOG(debug) << L"CLK: Clockdata sent: " << data;\r