5 #include "consumer/oal/oal_frame_consumer.h"
\r
6 #ifndef DISABLE_BLUEFISH
\r
7 #include "consumer/bluefish/BlueFishVideoConsumer.h"
\r
9 #include "consumer/decklink/DecklinkVideoConsumer.h"
\r
10 #include "consumer/ogl/ogl_frame_consumer.h"
\r
12 #include <FreeImage.h>
\r
14 #include "protocol/amcp/AMCPProtocolStrategy.h"
\r
15 #include "protocol/cii/CIIProtocolStrategy.h"
\r
16 #include "protocol/CLK/CLKProtocolStrategy.h"
\r
17 #include "producer/flash/FlashAxContainer.h"
\r
19 #include "../common/io/AsyncEventServer.h"
\r
20 #include "../common/io/SerialPort.h"
\r
21 #include "../common/utility/string_convert.h"
\r
23 #include <boost/algorithm/string.hpp>
\r
24 #include <boost/lexical_cast.hpp>
\r
25 #include <boost/filesystem.hpp>
\r
26 #include <boost/foreach.hpp>
\r
27 #include <boost/property_tree/ptree.hpp>
\r
28 #include <boost/property_tree/xml_parser.hpp>
\r
32 struct server::implementation : boost::noncopyable
\r
36 FreeImage_Initialise(true);
\r
38 boost::property_tree::ptree pt;
\r
39 boost::property_tree::read_xml(boost::filesystem::initial_path().file_string() + "\\caspar.config", pt);
\r
43 setup_controllers(pt);
\r
45 if(!flash::FlashAxContainer::CheckForFlashSupport())
\r
46 CASPAR_LOG(error) << "No flashplayer activex-control installed. Flash support will be disabled";
\r
51 FreeImage_DeInitialise();
\r
52 serial_ports_.clear();
\r
53 async_servers_.clear();
\r
57 static void setup_paths()
\r
59 if(!media_folder_.empty())
\r
62 std::string initialPath = boost::filesystem::initial_path().file_string();
\r
63 boost::property_tree::ptree pt;
\r
64 boost::property_tree::read_xml(initialPath + "\\caspar.config", pt);
\r
66 auto paths = pt.get_child("configuration.paths");
\r
67 media_folder_ = common::widen(paths.get("media-path", initialPath + "\\media\\"));
\r
68 log_folder_ = common::widen(paths.get("log-path", initialPath + "\\log\\"));
\r
69 template_folder_ = common::widen(paths.get("template-path", initialPath + "\\template\\"));
\r
70 data_folder_ = common::widen(paths.get("data-path", initialPath + "\\data\\"));
\r
73 void setup_channels(boost::property_tree::ptree& pt)
\r
75 using boost::property_tree::ptree;
\r
76 BOOST_FOREACH(auto& xml_channel, pt.get_child("configuration.channels"))
\r
78 auto format_desc = get_video_format_desc(common::widen(xml_channel.second.get("videomode", "PAL")));
\r
79 std::vector<frame_consumer_ptr> consumers;
\r
81 BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers"))
\r
85 frame_consumer_ptr pConsumer;
\r
86 std::string name = xml_consumer.first;
\r
89 int device = xml_consumer.second.get("device", 0);
\r
91 ogl::stretch stretch = ogl::stretch::fill;
\r
92 std::string stretchStr = xml_consumer.second.get("stretch", "");
\r
93 if(stretchStr == "none")
\r
94 stretch = ogl::stretch::none;
\r
95 else if(stretchStr == "uniform")
\r
96 stretch = ogl::stretch::uniform;
\r
97 else if(stretchStr == "uniformtofill")
\r
98 stretch = ogl::stretch::uniform_to_fill;
\r
100 bool windowed = xml_consumer.second.get("windowed", false);
\r
101 pConsumer = std::make_shared<ogl::ogl_frame_consumer>(format_desc, device, stretch, windowed);
\r
103 #ifndef DISABLE_BLUEFISH
\r
104 else if(name == "bluefish")
\r
105 pConsumer = caspar::bluefish::BlueFishVideoConsumer::Create(format_desc, xml_consumer.second.get("device", 0));
\r
107 else if(name == "decklink")
\r
108 pConsumer = std::make_shared<decklink::DecklinkVideoConsumer>(format_desc, xml_consumer.second.get("internalkey", false));
\r
109 else if(name == "audio")
\r
110 pConsumer = std::make_shared<audio::oal_frame_consumer>(format_desc);
\r
113 consumers.push_back(pConsumer);
\r
117 CASPAR_LOG_CURRENT_EXCEPTION();
\r
121 channels_.push_back(std::make_shared<renderer::render_device>(format_desc, channels_.size() + 1, consumers));
\r
125 void setup_controllers(boost::property_tree::ptree& pt)
\r
127 using boost::property_tree::ptree;
\r
128 BOOST_FOREACH(auto& xml_controller, pt.get_child("configuration.controllers"))
\r
132 std::string name = xml_controller.first;
\r
133 std::string protocol = xml_controller.second.get<std::string>("protocol");
\r
135 if(name == "tcpcontroller")
\r
137 unsigned int port = xml_controller.second.get<unsigned int>("port");
\r
138 port = port != 0 ? port : 5250;
\r
139 auto asyncserver = std::make_shared<caspar::IO::AsyncEventServer>(create_protocol(protocol), port);
\r
140 asyncserver->Start();
\r
141 async_servers_.push_back(asyncserver);
\r
143 else if(name == "serialcontroller")
\r
145 std::wstring portName = common::widen(xml_controller.second.get<std::string>("port-name"));
\r
146 unsigned int baudRate = xml_controller.second.get<unsigned int>("baud-rate");
\r
147 unsigned int dataBits = xml_controller.second.get<unsigned int>("data-bits");
\r
148 unsigned int parity = xml_controller.second.get<unsigned int>("parity");
\r
149 unsigned int stopBits = xml_controller.second.get<unsigned int>("stop-bits");
\r
151 baudRate = baudRate != 0 ? baudRate : 19200;
\r
152 dataBits = dataBits != 0 ? dataBits : 8;
\r
153 parity = parity != 0 ? parity : NOPARITY;
\r
154 stopBits = stopBits != 0 ? stopBits : ONESTOPBIT;
\r
156 auto serialPort = std::make_shared<IO::SerialPort>(create_protocol(protocol), baudRate, parity, dataBits, stopBits, portName, xml_controller.second.get("spy", false));
\r
157 serialPort->Start();
\r
158 serial_ports_.push_back(serialPort);
\r
161 BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info(name) << msg_info("Invalid controller"));
\r
165 CASPAR_LOG_CURRENT_EXCEPTION();
\r
171 IO::ProtocolStrategyPtr create_protocol(const std::string& name) const
\r
174 return std::make_shared<amcp::AMCPProtocolStrategy>(channels_);
\r
175 else if(name == "CII")
\r
176 return std::make_shared<cii::CIIProtocolStrategy>(channels_);
\r
177 else if(name == "CLOCK")
\r
178 return std::make_shared<CLK::CLKProtocolStrategy>(channels_);
\r
180 BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info("name") << arg_value_info(name) << msg_info("Invalid protocol"));
\r
183 std::vector<IO::SerialPortPtr> serial_ports_;
\r
184 std::vector<IO::AsyncEventServerPtr> async_servers_;
\r
186 std::vector<renderer::render_device_ptr> channels_;
\r
190 static std::wstring media_folder_;
\r
191 static std::wstring log_folder_;
\r
192 static std::wstring template_folder_;
\r
193 static std::wstring data_folder_;
\r
196 std::wstring server::implementation::media_folder_ = L"";
\r
197 std::wstring server::implementation::log_folder_ = L"";
\r
198 std::wstring server::implementation::template_folder_ = L"";
\r
199 std::wstring server::implementation::data_folder_ = L"";
\r
201 server::server() : impl_(new implementation()){}
\r
203 const std::wstring& server::media_folder()
\r
205 server::implementation::setup_paths();
\r
206 return server::implementation::media_folder_;
\r
209 const std::wstring& server::log_folder()
\r
211 server::implementation::setup_paths();
\r
212 return server::implementation::log_folder_;
\r
215 const std::wstring& server::template_folder()
\r
217 server::implementation::setup_paths();
\r
218 return server::implementation::template_folder_;
\r
221 const std::wstring& server::data_folder()
\r
223 server::implementation::setup_paths();
\r
224 return server::implementation::data_folder_;
\r
227 const std::vector<renderer::render_device_ptr>& server::get_channels() const{ return impl_->channels_; }
\r