]> git.sesse.net Git - casparcg/blob - shell/boostrapper.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / shell / boostrapper.cpp
1 #include "bootstrapper.h"\r
2 \r
3 #include <core/channel.h>\r
4 \r
5 #include <core/consumer/oal/oal_consumer.h>\r
6 #include <core/consumer/bluefish/bluefish_consumer.h>\r
7 #include <core/consumer/decklink/decklink_consumer.h>\r
8 #include <core/consumer/ogl/ogl_consumer.h>\r
9 #include <core/consumer/ffmpeg/ffmpeg_consumer.h>\r
10 \r
11 #include <core/producer/flash/FlashAxContainer.h>\r
12 \r
13 #include <protocol/amcp/AMCPProtocolStrategy.h>\r
14 #include <protocol/cii/CIIProtocolStrategy.h>\r
15 #include <protocol/CLK/CLKProtocolStrategy.h>\r
16 #include <protocol/util/AsyncEventServer.h>\r
17 \r
18 #include <common/env.h>\r
19 #include <common/exception/exceptions.h>\r
20 #include <common/utility/string_convert.h>\r
21 \r
22 #include <boost/algorithm/string.hpp>\r
23 #include <boost/lexical_cast.hpp>\r
24 #include <boost/filesystem.hpp>\r
25 #include <boost/foreach.hpp>\r
26 #include <boost/property_tree/ptree.hpp>\r
27 #include <boost/property_tree/xml_parser.hpp>\r
28 \r
29 namespace caspar {\r
30 \r
31 using namespace core;\r
32 using namespace protocol;\r
33 \r
34 struct bootstrapper::implementation : boost::noncopyable\r
35 {\r
36         std::vector<safe_ptr<IO::AsyncEventServer>> async_servers_;     \r
37         std::vector<safe_ptr<channel>> channels_;\r
38 \r
39         implementation()                                                                                                \r
40         {                       \r
41                 setup_channels(env::properties());\r
42                 setup_controllers(env::properties());\r
43         \r
44                 if(!flash::FlashAxContainer::CheckForFlashSupport())\r
45                         CASPAR_LOG(error) << "No flashplayer activex-control installed. Flash support will be disabled";\r
46         }\r
47 \r
48         ~implementation()\r
49         {                               \r
50                 async_servers_.clear();\r
51                 channels_.clear();\r
52         }\r
53                                 \r
54         void setup_channels(const boost::property_tree::ptree& pt)\r
55         {   \r
56                 using boost::property_tree::ptree;\r
57                 BOOST_FOREACH(auto& xml_channel, pt.get_child("configuration.channels"))\r
58                 {               \r
59                         auto format_desc = video_format_desc::get(widen(xml_channel.second.get("videomode", "PAL")));           \r
60                         if(format_desc.format == video_format::invalid)\r
61                                 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Invalid videomode."));\r
62                         std::vector<safe_ptr<frame_consumer>> consumers;\r
63 \r
64                         BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers"))\r
65                         {\r
66                                 try\r
67                                 {\r
68                                         std::string name = xml_consumer.first;\r
69                                         if(name == "ogl")\r
70                                         {                       \r
71                                                 int device = xml_consumer.second.get("device", 0);\r
72                         \r
73                                                 ogl::stretch stretch = ogl::stretch::fill;\r
74                                                 std::string stretchStr = xml_consumer.second.get("stretch", "");\r
75                                                 if(stretchStr == "none")\r
76                                                         stretch = ogl::stretch::none;\r
77                                                 else if(stretchStr == "uniform")\r
78                                                         stretch = ogl::stretch::uniform;\r
79                                                 else if(stretchStr == "uniformtofill")\r
80                                                         stretch = ogl::stretch::uniform_to_fill;\r
81 \r
82                                                 bool windowed = xml_consumer.second.get("windowed", false);\r
83                                                 consumers.push_back(ogl::consumer(format_desc, device, stretch, windowed));\r
84                                         }\r
85                                         else if(name == "bluefish")                                     \r
86                                                 consumers.push_back(bluefish::consumer(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("embedded-audio", false)));                                   \r
87                                         else if(name == "decklink")\r
88                                                 consumers.push_back(make_safe<decklink::decklink_consumer>(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("internalkey", false)));\r
89                                         else if(name == "audio")\r
90                                                 consumers.push_back(oal::consumer(format_desc));                        \r
91                                 }\r
92                                 catch(...)\r
93                                 {\r
94                                         CASPAR_LOG_CURRENT_EXCEPTION();\r
95                                 }\r
96                         }\r
97 \r
98                         try\r
99                         {\r
100                                 consumers.push_back(ffmpeg::consumer(format_desc, env::media_folder() + L"test.mpeg")); \r
101                         }\r
102                         catch(...)\r
103                         {\r
104                                 CASPAR_LOG_CURRENT_EXCEPTION();\r
105                         }\r
106                                                         \r
107                         channels_.push_back(channel(format_desc, consumers));\r
108                 }\r
109         }\r
110                 \r
111         void setup_controllers(const boost::property_tree::ptree& pt)\r
112         {               \r
113                 using boost::property_tree::ptree;\r
114                 BOOST_FOREACH(auto& xml_controller, pt.get_child("configuration.controllers"))\r
115                 {\r
116                         try\r
117                         {\r
118                                 std::string name = xml_controller.first;\r
119                                 std::string protocol = xml_controller.second.get<std::string>("protocol");      \r
120 \r
121                                 if(name == "tcpcontroller")\r
122                                 {                                       \r
123                                         unsigned int port = xml_controller.second.get<unsigned int>("port");\r
124                                         port = port != 0 ? port : 5250;\r
125                                         auto asyncbootstrapper = make_safe<IO::AsyncEventServer>(create_protocol(protocol), port);\r
126                                         asyncbootstrapper->Start();\r
127                                         async_servers_.push_back(asyncbootstrapper);\r
128                                 }\r
129                                 else\r
130                                         BOOST_THROW_EXCEPTION(invalid_bootstrapper() << arg_name_info(name) << msg_info("Invalid controller"));\r
131                         }\r
132                         catch(...)\r
133                         {\r
134                                 CASPAR_LOG_CURRENT_EXCEPTION();\r
135                         }\r
136                 }\r
137         }\r
138 \r
139         safe_ptr<IO::IProtocolStrategy> create_protocol(const std::string& name) const\r
140         {\r
141                 if(name == "AMCP")\r
142                         return make_safe<amcp::AMCPProtocolStrategy>(channels_);\r
143                 else if(name == "CII")\r
144                         return make_safe<cii::CIIProtocolStrategy>(channels_);\r
145                 else if(name == "CLOCK")\r
146                         return make_safe<CLK::CLKProtocolStrategy>(channels_);\r
147                 \r
148                 BOOST_THROW_EXCEPTION(invalid_bootstrapper() << arg_name_info("name") << arg_value_info(name) << msg_info("Invalid protocol"));\r
149         }\r
150 };\r
151 \r
152 bootstrapper::bootstrapper() : impl_(new implementation()){}\r
153 \r
154 const std::vector<safe_ptr<channel>> bootstrapper::get_channels() const\r
155 {\r
156         return impl_->channels_;\r
157 }\r
158 \r
159 }