3 #include <common/env.h>
\r
4 #include <common/exception/exceptions.h>
\r
5 #include <common/utility/string.h>
\r
7 #include <core/channel.h>
\r
9 #include <modules/bluefish/bluefish.h>
\r
10 #include <modules/decklink/decklink.h>
\r
11 #include <modules/ffmpeg/ffmpeg.h>
\r
12 #include <modules/flash/flash.h>
\r
13 #include <modules/oal/oal.h>
\r
14 #include <modules/ogl/ogl.h>
\r
15 #include <modules/silverlight/silverlight.h>
\r
16 #include <modules/image/image.h>
\r
18 #include <modules/oal/consumer/oal_consumer.h>
\r
19 #include <modules/bluefish/consumer/bluefish_consumer.h>
\r
20 #include <modules/decklink/consumer/decklink_consumer.h>
\r
21 #include <modules/ogl/consumer/ogl_consumer.h>
\r
22 #include <modules/ffmpeg/consumer/ffmpeg_consumer.h>
\r
24 #include <protocol/amcp/AMCPProtocolStrategy.h>
\r
25 #include <protocol/cii/CIIProtocolStrategy.h>
\r
26 #include <protocol/CLK/CLKProtocolStrategy.h>
\r
27 #include <protocol/util/AsyncEventServer.h>
\r
29 #include <boost/algorithm/string.hpp>
\r
30 #include <boost/lexical_cast.hpp>
\r
31 #include <boost/filesystem.hpp>
\r
32 #include <boost/foreach.hpp>
\r
33 #include <boost/property_tree/ptree.hpp>
\r
34 #include <boost/property_tree/xml_parser.hpp>
\r
38 using namespace core;
\r
39 using namespace protocol;
\r
41 struct server::implementation : boost::noncopyable
\r
43 std::vector<safe_ptr<IO::AsyncEventServer>> async_servers_;
\r
44 std::vector<safe_ptr<channel>> channels_;
\r
57 setup_channels(env::properties());
\r
58 setup_controllers(env::properties());
\r
63 async_servers_.clear();
\r
67 void setup_channels(const boost::property_tree::ptree& pt)
\r
69 using boost::property_tree::ptree;
\r
70 BOOST_FOREACH(auto& xml_channel, pt.get_child("configuration.channels"))
\r
72 auto format_desc = video_format_desc::get(widen(xml_channel.second.get("videomode", "PAL")));
\r
73 if(format_desc.format == video_format::invalid)
\r
74 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Invalid videomode."));
\r
76 channels_.push_back(channel(channels_.size(), format_desc));
\r
79 BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers"))
\r
83 std::string name = xml_consumer.first;
\r
86 int device = xml_consumer.second.get("device", 0);
\r
88 stretch stretch = stretch::fill;
\r
89 std::string stretchStr = xml_consumer.second.get("stretch", "");
\r
90 if(stretchStr == "none")
\r
91 stretch = stretch::none;
\r
92 else if(stretchStr == "uniform")
\r
93 stretch = stretch::uniform;
\r
94 else if(stretchStr == "uniformtofill")
\r
95 stretch = stretch::uniform_to_fill;
\r
97 bool windowed = xml_consumer.second.get("windowed", false);
\r
98 channels_.back()->consumer()->add(index++, ogl_consumer(device, stretch, windowed));
\r
100 else if(name == "bluefish")
\r
101 channels_.back()->consumer()->add(index++, bluefish_consumer(xml_consumer.second.get("device", 0),
\r
102 xml_consumer.second.get("embedded-audio", true)));
\r
103 else if(name == "decklink")
\r
104 channels_.back()->consumer()->add(index++, decklink_consumer(xml_consumer.second.get("device", 0),
\r
105 xml_consumer.second.get("embedded-audio", true),
\r
106 xml_consumer.second.get("internal-key", false)));
\r
107 else if(name == "audio")
\r
108 channels_.back()->consumer()->add(index++, oal_consumer());
\r
112 CASPAR_LOG_CURRENT_EXCEPTION();
\r
118 void setup_controllers(const boost::property_tree::ptree& pt)
\r
120 using boost::property_tree::ptree;
\r
121 BOOST_FOREACH(auto& xml_controller, pt.get_child("configuration.controllers"))
\r
125 std::string name = xml_controller.first;
\r
126 std::string protocol = xml_controller.second.get<std::string>("protocol");
\r
130 unsigned int port = xml_controller.second.get("port", 5250);
\r
131 auto asyncbootstrapper = make_safe<IO::AsyncEventServer>(create_protocol(protocol), port);
\r
132 asyncbootstrapper->Start();
\r
133 async_servers_.push_back(asyncbootstrapper);
\r
136 BOOST_THROW_EXCEPTION(invalid_bootstrapper() << arg_name_info(name) << msg_info("Invalid controller."));
\r
140 CASPAR_LOG_CURRENT_EXCEPTION();
\r
145 safe_ptr<IO::IProtocolStrategy> create_protocol(const std::string& name) const
\r
148 return make_safe<amcp::AMCPProtocolStrategy>(channels_);
\r
149 else if(name == "CII")
\r
150 return make_safe<cii::CIIProtocolStrategy>(channels_);
\r
151 else if(name == "CLOCK")
\r
152 return make_safe<CLK::CLKProtocolStrategy>(channels_);
\r
154 BOOST_THROW_EXCEPTION(invalid_bootstrapper() << arg_name_info("name") << arg_value_info(name) << msg_info("Invalid protocol"));
\r
158 server::server() : impl_(new implementation()){}
\r
160 const std::vector<safe_ptr<channel>> server::get_channels() const
\r
162 return impl_->channels_;
\r