]> git.sesse.net Git - casparcg/blob - core/producer/flash/cg_producer.cpp
2.0.0.2:
[casparcg] / core / producer / flash / cg_producer.cpp
1 #include "../../StdAfx.h"\r
2 \r
3 #if defined(_MSC_VER)\r
4 #pragma warning (disable : 4714) // marked as __forceinline not inlined\r
5 #endif\r
6 \r
7 #include "cg_producer.h"\r
8 #include "flash_producer.h"\r
9 \r
10 #include "../../renderer/render_device.h"\r
11 #include "../../frame/frame_format.h"\r
12 #include "../../frame/gpu_frame.h"\r
13 #include "../../Server.h"\r
14 \r
15 #include <boost/filesystem.hpp>\r
16 #include <boost/assign.hpp>\r
17 #include <tbb/concurrent_unordered_map.h>\r
18                 \r
19 namespace caspar { namespace core { namespace flash{\r
20 \r
21 struct flash_cg_proxy\r
22 {\r
23         virtual std::wstring add(int layer, const std::wstring& templateName,  bool playOnLoad, const std::wstring& startFromLabel = TEXT(""), const std::wstring& data = TEXT("")) = 0;\r
24         virtual std::wstring remove(int layer) = 0;\r
25         virtual std::wstring play(int layer)  = 0;\r
26         virtual std::wstring stop(int layer, unsigned int mixOutDuration) = 0;\r
27         virtual std::wstring next(int layer) = 0;\r
28         virtual std::wstring update(int layer, const std::wstring& data) = 0;\r
29         virtual std::wstring invoke(int layer, const std::wstring& label) = 0;\r
30 };\r
31 \r
32 struct flash_cg_proxy16 : public flash_cg_proxy\r
33 {               \r
34         virtual std::wstring add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& label, const std::wstring& data) \r
35         {\r
36                 std::wstringstream flashParam;\r
37                 std::wstring::size_type pos = templateName.find('.');\r
38                 std::wstring filename = (pos != std::wstring::npos) ? templateName.substr(0, pos) : templateName;               \r
39                 flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << filename << TEXT("</string><number>0</number>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << label << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
40                 return flashParam.str();\r
41         }\r
42 \r
43         virtual std::wstring remove(int layer) \r
44         {\r
45                 std::wstringstream flashParam;\r
46                 flashParam << TEXT("<invoke name=\"Delete\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
47                 return flashParam.str();\r
48         }\r
49 \r
50         virtual std::wstring play(int layer) \r
51         {\r
52                 std::wstringstream flashParam;\r
53                 flashParam << TEXT("<invoke name=\"Play\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
54                 return flashParam.str();\r
55         }\r
56 \r
57         virtual std::wstring stop(int layer, unsigned int mixOutDuration) \r
58         {\r
59                 std::wstringstream flashParam;\r
60                 flashParam << TEXT("<invoke name=\"Stop\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><number>") << mixOutDuration << TEXT("</number></arguments></invoke>");\r
61                 return flashParam.str();\r
62         }\r
63 \r
64         virtual std::wstring next(int layer) \r
65         {\r
66                 std::wstringstream flashParam;\r
67                 flashParam << TEXT("<invoke name=\"Next\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
68                 return flashParam.str();\r
69         }\r
70 \r
71         virtual std::wstring update(int layer, const std::wstring& data) \r
72         {\r
73                 std::wstringstream flashParam;\r
74                 flashParam << TEXT("<invoke name=\"SetData\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
75                 return flashParam.str();\r
76         }\r
77 \r
78         virtual std::wstring invoke(int layer, const std::wstring& label) \r
79         {\r
80                 std::wstringstream flashParam;\r
81                 flashParam << TEXT("<invoke name=\"ExecuteMethod\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << label << TEXT("</string></arguments></invoke>");\r
82                 return flashParam.str();\r
83         }\r
84 };\r
85 \r
86 struct flash_cg_proxy17 : public flash_cg_proxy\r
87 {\r
88         virtual std::wstring add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& label, const std::wstring& data) \r
89         {\r
90                 std::wstringstream flashParam;\r
91 \r
92                 std::wstring::size_type pos = templateName.find('.');\r
93                 std::wstring filename = (pos != std::wstring::npos) ? templateName.substr(0, pos) : templateName;\r
94                 \r
95                 flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << filename << TEXT("</string>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << label << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
96                 return flashParam.str();\r
97         }\r
98 \r
99         virtual std::wstring remove(int layer) \r
100         {\r
101                 std::wstringstream flashParam;\r
102                 flashParam << TEXT("<invoke name=\"Delete\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
103                 return flashParam.str();\r
104         }\r
105 \r
106         virtual std::wstring play(int layer) \r
107         {\r
108                 std::wstringstream flashParam;\r
109                 flashParam << TEXT("<invoke name=\"Play\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
110                 return flashParam.str();\r
111         }\r
112 \r
113         virtual std::wstring stop(int layer, unsigned int mixOutDuration)\r
114         {\r
115                 std::wstringstream flashParam;\r
116                 flashParam << TEXT("<invoke name=\"Stop\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><number>") << mixOutDuration << TEXT("</number></arguments></invoke>");\r
117                 return flashParam.str();\r
118         }\r
119 \r
120         virtual std::wstring next(int layer)\r
121         {\r
122                 std::wstringstream flashParam;\r
123                 flashParam << TEXT("<invoke name=\"Next\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
124                 return flashParam.str();\r
125         }\r
126 \r
127         virtual std::wstring update(int layer, const std::wstring& data) \r
128         {\r
129                 std::wstringstream flashParam;\r
130                 flashParam << TEXT("<invoke name=\"SetData\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
131                 return flashParam.str();\r
132         }\r
133 \r
134         virtual std::wstring invoke(int layer, const std::wstring& label)\r
135         {\r
136                 std::wstringstream flashParam;\r
137                 flashParam << TEXT("<invoke name=\"Invoke\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string>") << label << TEXT("</string></arguments></invoke>");\r
138                 return flashParam.str();\r
139         }\r
140 };\r
141 \r
142 struct flash_cg_proxy18 : public flash_cg_proxy17\r
143 {\r
144         virtual std::wstring add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& label, const std::wstring& data)\r
145         {\r
146                 std::wstringstream flashParam;\r
147                 flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << templateName << TEXT("</string>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << label << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
148                 return flashParam.str();\r
149         }\r
150 };\r
151 \r
152 struct cg_producer::implementation : boost::noncopyable\r
153 {\r
154 public:\r
155 \r
156         implementation(const frame_format_desc& fmtDesc) : format_desc_(fmtDesc)\r
157         {\r
158                 if(boost::filesystem::exists(server::template_folder()+TEXT("cg.fth.18")))\r
159                 {\r
160                         flash_producer_ = std::make_shared<flash_producer>(server::template_folder()+TEXT("cg.fth.18"), fmtDesc);\r
161                         proxy_.reset(new flash_cg_proxy18());\r
162                         CASPAR_LOG(info) << L"Running version 1.8 template graphics.";\r
163                 }\r
164                 else if(boost::filesystem::exists(server::template_folder()+TEXT("cg.fth.17")))\r
165                 {\r
166                         flash_producer_ = std::make_shared<flash_producer>(server::template_folder()+TEXT("cg.fth.17"), fmtDesc);\r
167                         proxy_.reset(new flash_cg_proxy17());\r
168                         CASPAR_LOG(info) << L"Running version 1.7 template graphics.";\r
169                 }\r
170                 else if(boost::filesystem::exists(server::template_folder()+TEXT("cg.fth"))) \r
171                 {\r
172                         flash_producer_ = std::make_shared<flash_producer>(server::template_folder()+TEXT("cg.fth"), fmtDesc);\r
173                         proxy_.reset(new flash_cg_proxy16());\r
174                         CASPAR_LOG(info) << L"Running version 1.6 template graphics.";\r
175                 }\r
176                 else \r
177                         CASPAR_LOG(info) << L"No templatehost found. Template graphics will be disabled";\r
178                 \r
179         }\r
180 \r
181         void clear()\r
182         {\r
183                 flash_producer_.reset();\r
184         }\r
185 \r
186         void add(int layer, const std::wstring& templateName,  bool playOnLoad, const std::wstring& startFromLabel, const std::wstring& data)\r
187         {\r
188                 if(flash_producer_ == nullptr)\r
189                         return;\r
190                 CASPAR_LOG(info) << "Invoking add-command";\r
191                 flash_producer_->param(proxy_->add(layer, templateName, playOnLoad, startFromLabel, data));\r
192         }\r
193 \r
194         void remove(int layer)\r
195         {\r
196                 if(flash_producer_ == nullptr)\r
197                         return;\r
198                 CASPAR_LOG(info) << "Invoking remove-command";\r
199                 flash_producer_->param(proxy_->remove(layer));\r
200         }\r
201 \r
202         void play(int layer)\r
203         {\r
204                 if(flash_producer_ == nullptr)\r
205                         return;\r
206                 CASPAR_LOG(info) << "Invoking play-command";\r
207                 flash_producer_->param(proxy_->play(layer));\r
208         }\r
209 \r
210         void stop(int layer, unsigned int mixOutDuration)\r
211         {\r
212                 if(flash_producer_ == nullptr)\r
213                         return;\r
214                 CASPAR_LOG(info) << "Invoking stop-command";\r
215                 flash_producer_->param(proxy_->stop(layer, mixOutDuration));\r
216         }\r
217 \r
218         void next(int layer)\r
219         {\r
220                 if(flash_producer_ == nullptr)\r
221                         return;\r
222                 CASPAR_LOG(info) << "Invoking next-command";\r
223                 flash_producer_->param(proxy_->next(layer));\r
224         }\r
225 \r
226         void update(int layer, const std::wstring& data)\r
227         {\r
228                 if(flash_producer_ == nullptr)\r
229                         return;\r
230                 CASPAR_LOG(info) << "Invoking update-command";\r
231                 flash_producer_->param(proxy_->update(layer, data));\r
232         }\r
233 \r
234         void invoke(int layer, const std::wstring& label)\r
235         {\r
236                 if(flash_producer_ == nullptr)\r
237                         return;\r
238                 CASPAR_LOG(info) << "Invoking invoke-command";\r
239                 flash_producer_->param(proxy_->invoke(layer, label));\r
240         }\r
241 \r
242         gpu_frame_ptr get_frame()\r
243         {\r
244                 return flash_producer_ ? flash_producer_->get_frame() : nullptr;\r
245         }\r
246                 \r
247         void initialize(const frame_factory_ptr& factory)\r
248         {\r
249                 factory_ = factory;\r
250                 if(flash_producer_)\r
251                         flash_producer_->initialize(factory_);\r
252         }\r
253 \r
254         frame_format_desc format_desc_;\r
255         flash_producer_ptr flash_producer_;\r
256         std::unique_ptr<flash_cg_proxy> proxy_;\r
257         frame_factory_ptr factory_;\r
258 };\r
259         \r
260 // This is somewhat a hack... needs redesign\r
261 cg_producer_ptr get_default_cg_producer(const renderer::render_device_ptr& render_device, unsigned int exLayer)\r
262 {\r
263         if(!render_device)\r
264                 BOOST_THROW_EXCEPTION(null_argument() << msg_info("render_device"));\r
265         \r
266         auto producer = std::dynamic_pointer_cast<cg_producer>(render_device->active(exLayer));\r
267         if(!producer)\r
268         {\r
269                 producer = std::make_shared<cg_producer>(render_device->get_frame_format_desc());               \r
270                 render_device->load(exLayer, producer, renderer::load_option::auto_play); \r
271         }\r
272         \r
273         return producer;\r
274 }\r
275 \r
276 cg_producer::cg_producer(const frame_format_desc& fmtDesc) : impl_(new implementation(fmtDesc)){}\r
277 gpu_frame_ptr cg_producer::get_frame(){return impl_->get_frame();}\r
278 void cg_producer::clear(){impl_->clear();}\r
279 void cg_producer::add(int layer, const std::wstring& templateName,  bool playOnLoad, const std::wstring& startFromLabel, const std::wstring& data){impl_->add(layer, templateName, playOnLoad, startFromLabel, data);}\r
280 void cg_producer::remove(int layer){impl_->remove(layer);}\r
281 void cg_producer::play(int layer){impl_->play(layer);}\r
282 void cg_producer::stop(int layer, unsigned int mixOutDuration){impl_->stop(layer, mixOutDuration);}\r
283 void cg_producer::next(int layer){impl_->next(layer);}\r
284 void cg_producer::update(int layer, const std::wstring& data){impl_->update(layer, data);}\r
285 void cg_producer::invoke(int layer, const std::wstring& label){impl_->invoke(layer, label);}\r
286 const frame_format_desc& cg_producer::get_frame_format_desc() const { return impl_->format_desc_; }\r
287 void cg_producer::initialize(const frame_factory_ptr& factory){impl_->initialize(factory);}\r
288 }}}