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
18 #include "protocol/monitor/Monitor.h"
\r
20 #include "../common/io/AsyncEventServer.h"
\r
21 #include "../common/io/SerialPort.h"
\r
22 #include "../common/utility/string_convert.h"
\r
24 #include <boost/algorithm/string.hpp>
\r
25 #include <boost/lexical_cast.hpp>
\r
26 #include <boost/filesystem.hpp>
\r
27 #include <boost/foreach.hpp>
\r
28 #include <boost/property_tree/ptree.hpp>
\r
29 #include <boost/property_tree/xml_parser.hpp>
\r
33 struct server::implementation : boost::noncopyable
\r
37 FreeImage_Initialise(true);
\r
39 boost::property_tree::ptree pt;
\r
40 boost::property_tree::read_xml(boost::filesystem::initial_path().file_string() + "\\caspar.config", pt);
\r
44 setup_controllers(pt);
\r
46 if(!flash::FlashAxContainer::CheckForFlashSupport())
\r
47 CASPAR_LOG(error) << "No flashplayer activex-control installed. Flash support will be disabled";
\r
52 FreeImage_DeInitialise();
\r
53 serial_ports_.clear();
\r
54 async_servers_.clear();
\r
58 static void setup_paths()
\r
60 if(!media_folder_.empty())
\r
63 std::string initialPath = boost::filesystem::initial_path().file_string();
\r
64 boost::property_tree::ptree pt;
\r
65 boost::property_tree::read_xml(initialPath + "\\caspar.config", pt);
\r
67 auto paths = pt.get_child("configuration.paths");
\r
68 media_folder_ = common::widen(paths.get("media-path", initialPath + "\\media\\"));
\r
69 log_folder_ = common::widen(paths.get("log-path", initialPath + "\\log\\"));
\r
70 template_folder_ = common::widen(paths.get("template-path", initialPath + "\\template\\"));
\r
71 data_folder_ = common::widen(paths.get("data-path", initialPath + "\\data\\"));
\r
74 void setup_channels(boost::property_tree::ptree& pt)
\r
76 using boost::property_tree::ptree;
\r
77 BOOST_FOREACH(auto& xml_channel, pt.get_child("configuration.channels"))
\r
79 auto format_desc = get_video_format_desc(common::widen(xml_channel.second.get("videomode", "PAL")));
\r
80 std::vector<frame_consumer_ptr> consumers;
\r
82 BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers"))
\r
86 frame_consumer_ptr pConsumer;
\r
87 std::string name = xml_consumer.first;
\r
90 int device = xml_consumer.second.get("device", 0);
\r
92 ogl::stretch stretch = ogl::stretch::fill;
\r
93 std::string stretchStr = xml_consumer.second.get("stretch", "");
\r
94 if(stretchStr == "none")
\r
95 stretch = ogl::stretch::none;
\r
96 else if(stretchStr == "uniform")
\r
97 stretch = ogl::stretch::uniform;
\r
98 else if(stretchStr == "uniformtofill")
\r
99 stretch = ogl::stretch::uniform_to_fill;
\r
101 bool windowed = xml_consumer.second.get("windowed", false);
\r
102 pConsumer = std::make_shared<ogl::ogl_frame_consumer>(format_desc, device, stretch, windowed);
\r
104 #ifndef DISABLE_BLUEFISH
\r
105 else if(name == "bluefish")
\r
106 pConsumer = caspar::bluefish::BlueFishVideoConsumer::Create(format_desc, xml_consumer.second.get("device", 0));
\r
108 else if(name == "decklink")
\r
109 pConsumer = std::make_shared<decklink::DecklinkVideoConsumer>(format_desc, xml_consumer.second.get("internalkey", false));
\r
110 else if(name == "audio")
\r
111 pConsumer = std::make_shared<audio::oal_frame_consumer>(format_desc);
\r
114 consumers.push_back(pConsumer);
\r
118 CASPAR_LOG_CURRENT_EXCEPTION();
\r
122 channels_.push_back(std::make_shared<renderer::render_device>(format_desc, channels_.size() + 1, consumers));
\r
126 void setup_controllers(boost::property_tree::ptree& pt)
\r
128 using boost::property_tree::ptree;
\r
129 BOOST_FOREACH(auto& xml_controller, pt.get_child("configuration.controllers"))
\r
133 std::string name = xml_controller.first;
\r
134 std::string protocol = xml_controller.second.get<std::string>("protocol");
\r
136 if(name == "tcpcontroller")
\r
138 unsigned int port = xml_controller.second.get<unsigned int>("port");
\r
139 port = port != 0 ? port : 5250;
\r
140 auto asyncserver = std::make_shared<caspar::IO::AsyncEventServer>(create_protocol(protocol), port);
\r
141 asyncserver->SetClientDisconnectHandler(std::tr1::bind(&Monitor::ClearListener, std::tr1::placeholders::_1));
\r
142 asyncserver->Start();
\r
143 async_servers_.push_back(asyncserver);
\r
145 else if(name == "serialcontroller")
\r
147 std::wstring portName = common::widen(xml_controller.second.get<std::string>("port-name"));
\r
148 unsigned int baudRate = xml_controller.second.get<unsigned int>("baud-rate");
\r
149 unsigned int dataBits = xml_controller.second.get<unsigned int>("data-bits");
\r
150 unsigned int parity = xml_controller.second.get<unsigned int>("parity");
\r
151 unsigned int stopBits = xml_controller.second.get<unsigned int>("stop-bits");
\r
153 baudRate = baudRate != 0 ? baudRate : 19200;
\r
154 dataBits = dataBits != 0 ? dataBits : 8;
\r
155 parity = parity != 0 ? parity : NOPARITY;
\r
156 stopBits = stopBits != 0 ? stopBits : ONESTOPBIT;
\r
158 auto serialPort = std::make_shared<IO::SerialPort>(create_protocol(protocol), baudRate, parity, dataBits, stopBits, portName, xml_controller.second.get("spy", false));
\r
159 serialPort->Start();
\r
160 serial_ports_.push_back(serialPort);
\r
163 BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info(name) << msg_info("Invalid controller"));
\r
167 CASPAR_LOG_CURRENT_EXCEPTION();
\r
173 IO::ProtocolStrategyPtr create_protocol(const std::string& name) const
\r
176 return std::make_shared<amcp::AMCPProtocolStrategy>(channels_);
\r
177 else if(name == "CII")
\r
178 return std::make_shared<cii::CIIProtocolStrategy>(channels_);
\r
179 else if(name == "CLOCK")
\r
180 return std::make_shared<CLK::CLKProtocolStrategy>(channels_);
\r
182 BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info("name") << arg_value_info(name) << msg_info("Invalid protocol"));
\r
185 std::vector<IO::SerialPortPtr> serial_ports_;
\r
186 std::vector<IO::AsyncEventServerPtr> async_servers_;
\r
188 std::vector<renderer::render_device_ptr> channels_;
\r
192 static std::wstring media_folder_;
\r
193 static std::wstring log_folder_;
\r
194 static std::wstring template_folder_;
\r
195 static std::wstring data_folder_;
\r
198 std::wstring server::implementation::media_folder_ = L"";
\r
199 std::wstring server::implementation::log_folder_ = L"";
\r
200 std::wstring server::implementation::template_folder_ = L"";
\r
201 std::wstring server::implementation::data_folder_ = L"";
\r
203 server::server() : impl_(new implementation()){}
\r
205 const std::wstring& server::media_folder()
\r
207 server::implementation::setup_paths();
\r
208 return server::implementation::media_folder_;
\r
211 const std::wstring& server::log_folder()
\r
213 server::implementation::setup_paths();
\r
214 return server::implementation::log_folder_;
\r
217 const std::wstring& server::template_folder()
\r
219 server::implementation::setup_paths();
\r
220 return server::implementation::template_folder_;
\r
223 const std::wstring& server::data_folder()
\r
225 server::implementation::setup_paths();
\r
226 return server::implementation::data_folder_;
\r
229 const std::vector<renderer::render_device_ptr>& server::get_channels() const{ return impl_->channels_; }
\r