X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=shell%2Fserver.cpp;h=9fbf722ea4778fba975f2a79894ec5cf87804dac;hb=93b9e5dca7229dca21bf6fa21d75380bc417d0ad;hp=5d9bf906f80ffbf8e496804fa7c1b7a1b1030ff7;hpb=ac7b3acb915f90de6b224e54a2240023fc221e5a;p=casparcg diff --git a/shell/server.cpp b/shell/server.cpp index 5d9bf906f..9fbf722ea 100644 --- a/shell/server.cpp +++ b/shell/server.cpp @@ -1,31 +1,35 @@ /* -* copyright (c) 2010 Sveriges Television AB +* Copyright (c) 2011 Sveriges Television AB * -* This file is part of CasparCG. +* This file is part of CasparCG (www.casparcg.com). * -* CasparCG is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. * -* CasparCG is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with CasparCG. If not, see . +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . * +* Author: Robert Nagy, ronag89@gmail.com */ +#include "stdafx.h" #include "server.h" +#include + #include -#include -#include +#include +#include -#include #include +#include #include #include @@ -34,14 +38,13 @@ #include #include #include -#include -#include +#include #include #include #include #include -#include +#include #include #include @@ -60,92 +63,119 @@ namespace caspar { using namespace core; using namespace protocol; -struct server::implementation : boost::noncopyable +struct server::impl : boost::noncopyable { - std::vector> async_servers_; - std::vector> channels_; - ogl_device ogl_; + monitor::basic_subject event_subject_; + accelerator::accelerator accelerator_; + std::vector> async_servers_; + std::vector> channels_; + + impl() + : accelerator_(env::properties().get(L"configuration.accelerator", L"auto")) + { - implementation() - { ffmpeg::init(); - bluefish::init(); - decklink::init(); - flash::init(); - oal::init(); - ogl::init(); - //init_silverlight(); - image::init(); + CASPAR_LOG(info) << L"Initialized ffmpeg module."; + + bluefish::init(); + CASPAR_LOG(info) << L"Initialized bluefish module."; + + decklink::init(); + CASPAR_LOG(info) << L"Initialized decklink module."; + + oal::init(); + CASPAR_LOG(info) << L"Initialized oal module."; + + screen::init(); + CASPAR_LOG(info) << L"Initialized ogl module."; + + image::init(); + CASPAR_LOG(info) << L"Initialized image module."; + + flash::init(); + CASPAR_LOG(info) << L"Initialized flash module."; setup_channels(env::properties()); + CASPAR_LOG(info) << L"Initialized channels."; + setup_controllers(env::properties()); + CASPAR_LOG(info) << L"Initialized controllers."; } - ~implementation() + ~impl() { - ffmpeg::uninit(); - async_servers_.clear(); channels_.clear(); + + Sleep(500); // HACK: Wait for asynchronous destruction of producers and consumers. + + image::uninit(); + ffmpeg::uninit(); } - void setup_channels(const boost::property_tree::ptree& pt) + void setup_channels(const boost::property_tree::wptree& pt) { - using boost::property_tree::ptree; - BOOST_FOREACH(auto& xml_channel, pt.get_child("configuration.channels")) + using boost::property_tree::wptree; + BOOST_FOREACH(auto& xml_channel, pt.get_child(L"configuration.channels")) { - auto format_desc = video_format_desc::get(widen(xml_channel.second.get("video-mode", "PAL"))); + auto format_desc = video_format_desc(xml_channel.second.get(L"video-mode", L"PAL")); if(format_desc.format == video_format::invalid) BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Invalid video-mode.")); - channels_.push_back(video_channel(channels_.size(), format_desc, ogl_)); + auto channel = spl::make_shared(static_cast(channels_.size()+1), format_desc, accelerator_.create_image_mixer()); - int index = 0; - BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers")) + BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child(L"consumers")) { try { - const std::string name = xml_consumer.first; - if(name == "screen") - channels_.back()->output()->add(index++, ogl::create_consumer(xml_consumer.second)); - else if(name == "bluefish") - channels_.back()->output()->add(index++, bluefish::create_consumer(xml_consumer.second)); - else if(name == "decklink") - channels_.back()->output()->add(index++, decklink::create_consumer(xml_consumer.second)); - //else if(name == "file") - // channels_.back()->output()->add(index++, create_ffmpeg_consumer(xml_consumer.second)); - else if(name == "audio") - channels_.back()->output()->add(index++, oal::create_consumer()); - else if(name != "") - CASPAR_LOG(warning) << "Invalid consumer: " << widen(name); + auto name = xml_consumer.first; + if(name == L"screen") + channel->output().add(caspar::screen::create_consumer(xml_consumer.second)); + else if(name == L"bluefish") + channel->output().add(bluefish::create_consumer(xml_consumer.second)); + else if(name == L"decklink") + channel->output().add(decklink::create_consumer(xml_consumer.second)); + else if(name == L"file") + channel->output().add(ffmpeg::create_consumer(xml_consumer.second)); + else if(name == L"system-audio") + channel->output().add(oal::create_consumer()); + else if(name != L"") + CASPAR_LOG(warning) << "Invalid consumer: " << name; } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); } - } + } + + channel->subscribe(monitor::observable::observer_ptr(event_subject_)); + channels_.push_back(channel); } + + // Dummy diagnostics channel + if(env::properties().get(L"configuration.channel-grid", false)) + channels_.push_back(spl::make_shared(static_cast(channels_.size()+1), core::video_format_desc(core::video_format::x576p2500), accelerator_.create_image_mixer())); } - void setup_controllers(const boost::property_tree::ptree& pt) + void setup_controllers(const boost::property_tree::wptree& pt) { - using boost::property_tree::ptree; - BOOST_FOREACH(auto& xml_controller, pt.get_child("configuration.controllers")) + using boost::property_tree::wptree; + BOOST_FOREACH(auto& xml_controller, pt.get_child(L"configuration.controllers")) { try { - std::string name = xml_controller.first; - std::string protocol = xml_controller.second.get("protocol"); + auto name = xml_controller.first; + auto protocol = xml_controller.second.get(L"protocol"); - if(name == "tcp") + if(name == L"tcp") { - unsigned int port = xml_controller.second.get("port", 5250); - auto asyncbootstrapper = make_safe(create_protocol(protocol), port); + unsigned int port = xml_controller.second.get(L"port", 5250); + auto asyncbootstrapper = spl::make_shared(create_protocol(protocol), port); asyncbootstrapper->Start(); async_servers_.push_back(asyncbootstrapper); } else - CASPAR_LOG(warning) << "Invalid controller: " << widen(name); + CASPAR_LOG(warning) << "Invalid controller: " << name; } catch(...) { @@ -154,24 +184,26 @@ struct server::implementation : boost::noncopyable } } - safe_ptr create_protocol(const std::string& name) const + spl::shared_ptr create_protocol(const std::wstring& name) const { - if(name == "AMCP") - return make_safe(channels_); - else if(name == "CII") - return make_safe(channels_); - else if(name == "CLOCK") - return make_safe(channels_); + if(boost::iequals(name, L"AMCP")) + return spl::make_shared(channels_); + else if(boost::iequals(name, L"CII")) + return spl::make_shared(channels_); + else if(boost::iequals(name, L"CLOCK")) + return spl::make_shared(channels_); - BOOST_THROW_EXCEPTION(caspar_exception() << arg_name_info("name") << arg_value_info(name) << msg_info("Invalid protocol")); + BOOST_THROW_EXCEPTION(caspar_exception() << arg_name_info(L"name") << arg_value_info(name) << msg_info(L"Invalid protocol")); } }; -server::server() : impl_(new implementation()){} +server::server() : impl_(new impl()){} -const std::vector> server::get_channels() const +const std::vector> server::channels() const { return impl_->channels_; } +void server::subscribe(const monitor::observable::observer_ptr& o){impl_->event_subject_.subscribe(o);} +void server::unsubscribe(const monitor::observable::observer_ptr& o){impl_->event_subject_.unsubscribe(o);} } \ No newline at end of file