]> git.sesse.net Git - casparcg/blob - core/server.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / core / server.cpp
1 #include "StdAfx.h"\r
2 \r
3 #include "server.h"\r
4 \r
5 #include "consumer/oal/oal_consumer.h"\r
6 #ifndef DISABLE_BLUEFISH\r
7 #include "consumer/bluefish/bluefish_consumer.h"\r
8 #endif\r
9 #include "consumer/decklink/DecklinkVideoConsumer.h"\r
10 #include "consumer/ogl/ogl_consumer.h"\r
11 \r
12 #include "protocol/amcp/AMCPProtocolStrategy.h"\r
13 #include "protocol/cii/CIIProtocolStrategy.h"\r
14 #include "protocol/CLK/CLKProtocolStrategy.h"\r
15 #include "producer/flash/FlashAxContainer.h"\r
16 \r
17 #include "../common/io/AsyncEventServer.h"\r
18 #include "../common/utility/string_convert.h"\r
19 \r
20 #include <boost/algorithm/string.hpp>\r
21 #include <boost/lexical_cast.hpp>\r
22 #include <boost/filesystem.hpp>\r
23 #include <boost/foreach.hpp>\r
24 #include <boost/property_tree/ptree.hpp>\r
25 #include <boost/property_tree/xml_parser.hpp>\r
26 \r
27 namespace caspar { namespace core {\r
28 \r
29 struct server::implementation : boost::noncopyable\r
30 {\r
31         implementation()                                                                                                \r
32         {                       \r
33                 boost::property_tree::ptree pt;\r
34                 boost::property_tree::read_xml(boost::filesystem::initial_path().file_string() + "\\caspar.config", pt);\r
35 \r
36                 setup_paths();\r
37                 setup_channels(pt);\r
38                 setup_controllers(pt);\r
39         \r
40                 if(!flash::FlashAxContainer::CheckForFlashSupport())\r
41                         CASPAR_LOG(error) << "No flashplayer activex-control installed. Flash support will be disabled";\r
42         }\r
43 \r
44         ~implementation()\r
45         {                               \r
46                 async_servers_.clear();\r
47                 channels_.clear();\r
48         }\r
49 \r
50         static void setup_paths()\r
51         {\r
52                 if(!media_folder_.empty())\r
53                         return;\r
54 \r
55                 std::string initialPath = boost::filesystem::initial_path().file_string();\r
56                 boost::property_tree::ptree pt;\r
57                 boost::property_tree::read_xml(initialPath + "\\caspar.config", pt);\r
58 \r
59                 auto paths = pt.get_child("configuration.paths");\r
60                 media_folder_ = common::widen(paths.get("media-path", initialPath + "\\media\\"));\r
61                 log_folder_ = common::widen(paths.get("log-path", initialPath + "\\log\\"));\r
62                 template_folder_ = common::widen(paths.get("template-path", initialPath + "\\template\\"));\r
63                 data_folder_ = common::widen(paths.get("data-path", initialPath + "\\data\\"));\r
64         }\r
65                         \r
66         void setup_channels(boost::property_tree::ptree& pt)\r
67         {   \r
68                 using boost::property_tree::ptree;\r
69                 BOOST_FOREACH(auto& xml_channel, pt.get_child("configuration.channels"))\r
70                 {               \r
71                         auto format_desc = get_video_format_desc(common::widen(xml_channel.second.get("videomode", "PAL")));                    \r
72                         std::vector<frame_consumer_ptr> consumers;\r
73 \r
74                         BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers"))\r
75                         {\r
76                                 try\r
77                                 {\r
78                                         frame_consumer_ptr pConsumer;\r
79                                         std::string name = xml_consumer.first;\r
80                                         if(name == "ogl")\r
81                                         {                       \r
82                                                 int device = xml_consumer.second.get("device", 0);\r
83                         \r
84                                                 ogl::stretch stretch = ogl::stretch::fill;\r
85                                                 std::string stretchStr = xml_consumer.second.get("stretch", "");\r
86                                                 if(stretchStr == "none")\r
87                                                         stretch = ogl::stretch::none;\r
88                                                 else if(stretchStr == "uniform")\r
89                                                         stretch = ogl::stretch::uniform;\r
90                                                 else if(stretchStr == "uniformtofill")\r
91                                                         stretch = ogl::stretch::uniform_to_fill;\r
92 \r
93                                                 bool windowed = xml_consumer.second.get("windowed", false);\r
94                                                 pConsumer = std::make_shared<ogl::consumer>(format_desc, device, stretch, windowed);\r
95                                         }\r
96                                 #ifndef DISABLE_BLUEFISH\r
97                                         else if(name == "bluefish")                                     \r
98                                                 pConsumer = std::make_shared<bluefish::consumer>(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("embedded-audio", false));                                  \r
99                                 #endif\r
100                                         else if(name == "decklink")\r
101                                                 pConsumer = std::make_shared<decklink::DecklinkVideoConsumer>(format_desc, xml_consumer.second.get("internalkey", false));\r
102                                         else if(name == "audio")\r
103                                                 pConsumer = std::make_shared<oal::consumer>(format_desc);\r
104 \r
105                                         if(pConsumer)                                   \r
106                                                 consumers.push_back(pConsumer);                                 \r
107                                 }\r
108                                 catch(...)\r
109                                 {\r
110                                         CASPAR_LOG_CURRENT_EXCEPTION();\r
111                                 }\r
112                         }\r
113                         \r
114                         channels_.push_back(std::make_shared<renderer::render_device>(format_desc, channels_.size() + 1, consumers));\r
115                 }\r
116         }\r
117                 \r
118         void setup_controllers(boost::property_tree::ptree& pt)\r
119         {               \r
120                 using boost::property_tree::ptree;\r
121                 BOOST_FOREACH(auto& xml_controller, pt.get_child("configuration.controllers"))\r
122                 {\r
123                         try\r
124                         {\r
125                                 std::string name = xml_controller.first;\r
126                                 std::string protocol = xml_controller.second.get<std::string>("protocol");      \r
127 \r
128                                 if(name == "tcpcontroller")\r
129                                 {                                       \r
130                                         unsigned int port = xml_controller.second.get<unsigned int>("port");\r
131                                         port = port != 0 ? port : 5250;\r
132                                         auto asyncserver = std::make_shared<IO::AsyncEventServer>(create_protocol(protocol), port);\r
133                                         asyncserver->Start();\r
134                                         async_servers_.push_back(asyncserver);\r
135                                 }\r
136                                 else\r
137                                         BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info(name) << msg_info("Invalid controller"));\r
138                         }\r
139                         catch(...)\r
140                         {\r
141                                 CASPAR_LOG_CURRENT_EXCEPTION();\r
142                                 throw;\r
143                         }\r
144                 }\r
145         }\r
146 \r
147         IO::ProtocolStrategyPtr create_protocol(const std::string& name) const\r
148         {\r
149                 if(name == "AMCP")\r
150                         return std::make_shared<amcp::AMCPProtocolStrategy>(channels_);\r
151                 else if(name == "CII")\r
152                         return std::make_shared<cii::CIIProtocolStrategy>(channels_);\r
153                 else if(name == "CLOCK")\r
154                         return std::make_shared<CLK::CLKProtocolStrategy>(channels_);\r
155                 \r
156                 BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info("name") << arg_value_info(name) << msg_info("Invalid protocol"));\r
157         }\r
158 \r
159         std::vector<IO::AsyncEventServerPtr> async_servers_;\r
160 \r
161         std::vector<renderer::render_device_ptr> channels_;\r
162 \r
163         int logLevel_;\r
164 \r
165         static std::wstring media_folder_;\r
166         static std::wstring log_folder_;\r
167         static std::wstring template_folder_;\r
168         static std::wstring data_folder_;\r
169 };\r
170 \r
171 std::wstring server::implementation::media_folder_ = L"";\r
172 std::wstring server::implementation::log_folder_ = L"";\r
173 std::wstring server::implementation::template_folder_ = L"";\r
174 std::wstring server::implementation::data_folder_ = L"";\r
175 \r
176 server::server() : impl_(new implementation()){}\r
177 \r
178 const std::wstring& server::media_folder()\r
179 {\r
180         server::implementation::setup_paths();\r
181         return server::implementation::media_folder_;\r
182 }\r
183 \r
184 const std::wstring& server::log_folder()\r
185 {\r
186         server::implementation::setup_paths();\r
187         return server::implementation::log_folder_;\r
188 }\r
189 \r
190 const std::wstring& server::template_folder()\r
191 {\r
192         server::implementation::setup_paths();\r
193         return server::implementation::template_folder_;\r
194 }\r
195 \r
196 const std::wstring& server::data_folder()\r
197 {\r
198         server::implementation::setup_paths();\r
199         return server::implementation::data_folder_;\r
200 }\r
201 \r
202 const std::vector<renderer::render_device_ptr>& server::get_channels() const{ return impl_->channels_; }\r
203 \r
204 }}