return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4), std::forward<P5>(p5), std::forward<P6>(p6), std::forward<P7>(p7)));
}
+template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
+shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6, P7&& p7, P8&& p8)
+{
+ return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4), std::forward<P5>(p5), std::forward<P6>(p6), std::forward<P7>(p7), std::forward<P8>(p8)));
+}
+
template<typename T>
shared_ptr<T>::shared_ptr()
: p_(make_shared<T>())
#include <map>
namespace caspar { namespace core {
-
-std::vector<consumer_factory_t> g_consumer_factories;
-std::map<std::wstring, preconfigured_consumer_factory_t> g_preconfigured_consumer_factories;
-void register_consumer_factory(const consumer_factory_t& factory)
+struct frame_consumer_registry::impl
+{
+ std::vector<consumer_factory_t> consumer_factories;
+ std::map<std::wstring, preconfigured_consumer_factory_t> preconfigured_consumer_factories;
+};
+
+frame_consumer_registry::frame_consumer_registry()
+ : impl_(new impl)
+{
+}
+
+void frame_consumer_registry::register_consumer_factory(const consumer_factory_t& factory)
{
- g_consumer_factories.push_back(factory);
+ impl_->consumer_factories.push_back(factory);
}
-void register_preconfigured_consumer_factory(
+void frame_consumer_registry::register_preconfigured_consumer_factory(
const std::wstring& element_name,
const preconfigured_consumer_factory_t& factory)
{
- g_preconfigured_consumer_factories.insert(std::make_pair(element_name, factory));
+ impl_->preconfigured_consumer_factories.insert(std::make_pair(element_name, factory));
}
class destroy_consumer_proxy : public frame_consumer
monitor::subject& monitor_output() override {return consumer_->monitor_output();}
};
-spl::shared_ptr<core::frame_consumer> create_consumer(
- const std::vector<std::wstring>& params, interaction_sink* sink)
+spl::shared_ptr<core::frame_consumer> frame_consumer_registry::create_consumer(
+ const std::vector<std::wstring>& params, interaction_sink* sink) const
{
if(params.empty())
CASPAR_THROW_EXCEPTION(invalid_argument() << arg_name_info("params") << arg_value_info(""));
auto consumer = frame_consumer::empty();
- std::any_of(g_consumer_factories.begin(), g_consumer_factories.end(), [&](const consumer_factory_t& factory) -> bool
+ auto& consumer_factories = impl_->consumer_factories;
+ std::any_of(consumer_factories.begin(), consumer_factories.end(), [&](const consumer_factory_t& factory) -> bool
{
try
{
std::move(consumer)))));
}
-spl::shared_ptr<frame_consumer> create_consumer(
+spl::shared_ptr<frame_consumer> frame_consumer_registry::create_consumer(
const std::wstring& element_name,
const boost::property_tree::wptree& element,
- interaction_sink* sink)
+ interaction_sink* sink) const
{
- auto found = g_preconfigured_consumer_factories.find(element_name);
+ auto& preconfigured_consumer_factories = impl_->preconfigured_consumer_factories;
+ auto found = preconfigured_consumer_factories.find(element_name);
- if (found == g_preconfigured_consumer_factories.end())
+ if (found == preconfigured_consumer_factories.end())
CASPAR_THROW_EXCEPTION(file_not_found()
<< msg_info(L"No consumer factory registered for element name " + element_name));
const boost::property_tree::wptree& element,
interaction_sink* sink)> preconfigured_consumer_factory_t;
-void register_consumer_factory(const consumer_factory_t& factory);
-void register_preconfigured_consumer_factory(
- const std::wstring& element_name,
- const preconfigured_consumer_factory_t& factory);
-spl::shared_ptr<frame_consumer> create_consumer(
- const std::vector<std::wstring>& params,
- interaction_sink* sink);
-spl::shared_ptr<frame_consumer> create_consumer(
- const std::wstring& element_name,
- const boost::property_tree::wptree& element,
- interaction_sink* sink);
+class frame_consumer_registry : boost::noncopyable
+{
+public:
+ frame_consumer_registry();
+ void register_consumer_factory(const consumer_factory_t& factory);
+ void register_preconfigured_consumer_factory(
+ const std::wstring& element_name,
+ const preconfigured_consumer_factory_t& factory);
+ spl::shared_ptr<frame_consumer> create_consumer(
+ const std::vector<std::wstring>& params,
+ interaction_sink* sink) const;
+ spl::shared_ptr<frame_consumer> create_consumer(
+ const std::wstring& element_name,
+ const boost::property_tree::wptree& element,
+ interaction_sink* sink) const;
+private:
+ struct impl;
+ spl::shared_ptr<impl> impl_;
+};
}}
#include "producer/cg_proxy.h"
#include "producer/media_info/media_info_repository.h"
#include "producer/frame_producer.h"
+#include "consumer/frame_consumer.h"
namespace caspar { namespace core {
const spl::shared_ptr<cg_producer_registry> cg_registry;
const spl::shared_ptr<media_info_repository> media_info_repo;
const spl::shared_ptr<frame_producer_registry> producer_registry;
+ const spl::shared_ptr<frame_consumer_registry> consumer_registry;
module_dependencies(
spl::shared_ptr<system_info_provider_repository> system_info_provider_repo,
spl::shared_ptr<cg_producer_registry> cg_registry,
spl::shared_ptr<media_info_repository> media_info_repo,
- spl::shared_ptr<frame_producer_registry> producer_registry)
+ spl::shared_ptr<frame_producer_registry> producer_registry,
+ spl::shared_ptr<frame_consumer_registry> consumer_registry)
: system_info_provider_repo(std::move(system_info_provider_repo))
, cg_registry(std::move(cg_registry))
, media_info_repo(std::move(media_info_repo))
, producer_registry(std::move(producer_registry))
+ , consumer_registry(std::move(consumer_registry))
{
}
};
}
catch(...){}
- core::register_consumer_factory(create_consumer);
- core::register_preconfigured_consumer_factory(L"bluefish", create_preconfigured_consumer);
+ dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_preconfigured_consumer_factory(L"bluefish", create_preconfigured_consumer);
dependencies.system_info_provider_repo->register_system_info_provider([](boost::property_tree::wptree& info)
{
info.add(L"system.bluefish.version", version());
void init(core::module_dependencies dependencies)
{
- core::register_consumer_factory(create_consumer);
- core::register_preconfigured_consumer_factory(L"decklink", create_preconfigured_consumer);
+ dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_preconfigured_consumer_factory(L"decklink", create_preconfigured_consumer);
dependencies.producer_registry->register_producer_factory(create_producer);
dependencies.system_info_provider_repo->register_system_info_provider([](boost::property_tree::wptree& info)
{
avformat_network_init();
avcodec_register_all();
- core::register_consumer_factory(create_consumer);
- core::register_consumer_factory(create_streaming_consumer);
- core::register_preconfigured_consumer_factory(L"file", create_preconfigured_consumer);
- core::register_preconfigured_consumer_factory(L"stream", create_preconfigured_streaming_consumer);
+ dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_consumer_factory(create_streaming_consumer);
+ dependencies.consumer_registry->register_preconfigured_consumer_factory(L"file", create_preconfigured_consumer);
+ dependencies.consumer_registry->register_preconfigured_consumer_factory(L"stream", create_preconfigured_streaming_consumer);
dependencies.producer_registry->register_producer_factory(create_producer);
dependencies.media_info_repo->register_extractor(
dependencies.producer_registry->register_producer_factory(create_scroll_producer);
dependencies.producer_registry->register_producer_factory(create_producer);
dependencies.producer_registry->register_thumbnail_producer_factory(create_thumbnail_producer);
- core::register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_consumer_factory(create_consumer);
dependencies.media_info_repo->register_extractor([](const std::wstring& file, const std::wstring& extension, core::media_info& info)
{
if (extension == L".TGA"
try
{
if (airsend::is_available())
- core::register_consumer_factory(create_ivga_consumer);
+ dependencies.consumer_registry->register_consumer_factory(create_ivga_consumer);
dependencies.system_info_provider_repo->register_system_info_provider([](boost::property_tree::wptree& info)
{
info.add(L"system.newtek-ivga.version", airsend::is_available()
? L"available"
: L"unavailable (" + airsend::dll_name() + L")");
});
- core::register_preconfigured_consumer_factory(L"newtek-ivga", create_preconfigured_ivga_consumer);
+ dependencies.consumer_registry->register_preconfigured_consumer_factory(L"newtek-ivga", create_preconfigured_ivga_consumer);
}
catch(...){}
}
void init(core::module_dependencies dependencies)
{
- core::register_consumer_factory(create_consumer);
- core::register_preconfigured_consumer_factory(L"system-audio", create_preconfigured_consumer);
+ dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_preconfigured_consumer_factory(L"system-audio", create_preconfigured_consumer);
}
}}
void init(core::module_dependencies dependencies)
{
- core::register_consumer_factory(create_consumer);
- core::register_preconfigured_consumer_factory(L"screen", create_preconfigured_consumer);
+ dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_preconfigured_consumer_factory(L"screen", create_preconfigured_consumer);
}
}}
spl::shared_ptr<core::system_info_provider_repository> system_info_repo;
std::shared_ptr<core::thumbnail_generator> thumb_gen;
spl::shared_ptr<const core::frame_producer_registry> producer_registry;
+ spl::shared_ptr<const core::frame_consumer_registry> consumer_registry;
std::promise<bool>& shutdown_server_now;
std::vector<std::wstring> parameters;
spl::shared_ptr<core::system_info_provider_repository> system_info_repo,
std::shared_ptr<core::thumbnail_generator> thumb_gen,
spl::shared_ptr<const core::frame_producer_registry> producer_registry,
+ spl::shared_ptr<const core::frame_consumer_registry> consumer_registry,
std::promise<bool>& shutdown_server_now)
: client(std::move(client))
, channel(channel)
, system_info_repo(std::move(system_info_repo))
, thumb_gen(std::move(thumb_gen))
, producer_registry(std::move(producer_registry))
+ , consumer_registry(std::move(consumer_registry))
, shutdown_server_now(shutdown_server_now)
{
}
core::diagnostics::scoped_call_context save;
core::diagnostics::call_context::for_thread().video_channel = ctx.channel_index + 1;
- auto consumer = create_consumer(ctx.parameters, &ctx.channel.channel->stage());
+ auto consumer = ctx.consumer_registry->create_consumer(ctx.parameters, &ctx.channel.channel->stage());
ctx.channel.channel->output().add(ctx.layer_index(consumer->index()), consumer);
return L"202 ADD OK\r\n";
ctx.client->address(),
ctx.parameters);
- index = create_consumer(ctx.parameters, &ctx.channel.channel->stage())->index();
+ index = ctx.consumer_registry->create_consumer(ctx.parameters, &ctx.channel.channel->stage())->index();
}
ctx.channel.channel->output().remove(index);
std::wstring print_command(command_context& ctx)
{
- ctx.channel.channel->output().add(create_consumer({ L"IMAGE" }, &ctx.channel.channel->stage()));
+ ctx.channel.channel->output().add(ctx.consumer_registry->create_consumer({ L"IMAGE" }, &ctx.channel.channel->stage()));
return L"202 PRINT OK\r\n";
}
params.push_back(L"0");
params.push_back(L"NAME");
params.push_back(L"Channel Grid Window");
- auto screen = create_consumer(params, &self.channel->stage());
+ auto screen = ctx.consumer_registry->create_consumer(params, &self.channel->stage());
self.channel->output().add(screen);
spl::shared_ptr<core::cg_producer_registry> cg_registry;
spl::shared_ptr<core::help_repository> help_repo;
spl::shared_ptr<const core::frame_producer_registry> producer_registry;
+ spl::shared_ptr<const core::frame_consumer_registry> consumer_registry;
std::promise<bool>& shutdown_server_now;
std::map<std::wstring, std::pair<amcp_command_func, int>> commands;
const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
const spl::shared_ptr<core::help_repository>& help_repo,
const spl::shared_ptr<const core::frame_producer_registry>& producer_registry,
+ const spl::shared_ptr<const core::frame_consumer_registry>& consumer_registry,
std::promise<bool>& shutdown_server_now)
: thumb_gen(thumb_gen)
, media_info_repo(media_info_repo)
, cg_registry(cg_registry)
, help_repo(help_repo)
, producer_registry(producer_registry)
+ , consumer_registry(consumer_registry)
, shutdown_server_now(shutdown_server_now)
{
int index = 0;
const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
const spl::shared_ptr<core::help_repository>& help_repo,
const spl::shared_ptr<const core::frame_producer_registry>& producer_registry,
+ const spl::shared_ptr<const core::frame_consumer_registry>& consumer_registry,
std::promise<bool>& shutdown_server_now)
- : impl_(new impl(channels, thumb_gen, media_info_repo, system_info_provider_repo, cg_registry, help_repo, producer_registry, shutdown_server_now))
+ : impl_(new impl(
+ channels,
+ thumb_gen,
+ media_info_repo,
+ system_info_provider_repo,
+ cg_registry,
+ help_repo,
+ producer_registry,
+ consumer_registry,
+ shutdown_server_now))
{
}
self.system_info_provider_repo,
self.thumb_gen,
self.producer_registry,
+ self.consumer_registry,
self.shutdown_server_now);
auto command = find_command(self.commands, s, ctx, tokens);
self.system_info_provider_repo,
self.thumb_gen,
self.producer_registry,
+ self.consumer_registry,
self.shutdown_server_now);
auto command = find_command(self.channel_commands, s, ctx, tokens);
const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
const spl::shared_ptr<core::help_repository>& help_repo,
const spl::shared_ptr<const core::frame_producer_registry>& producer_registry,
+ const spl::shared_ptr<const core::frame_consumer_registry>& consumer_registry,
std::promise<bool>& shutdown_server_now);
AMCPCommand::ptr_type create_command(const std::wstring& s, IO::ClientInfoPtr client, std::list<std::wstring>& tokens) const;
auto media_info_repo = core::create_in_memory_media_info_repository();
spl::shared_ptr<core::help_repository> help_repo;
spl::shared_ptr<core::frame_producer_registry> producer_registry;
+ spl::shared_ptr<core::frame_consumer_registry> consumer_registry;
std::promise<bool> shutdown_server_now;
protocol::amcp::amcp_command_repository repo(
{ },
cg_registry,
help_repo,
producer_registry,
+ consumer_registry,
shutdown_server_now);
protocol::amcp::register_commands(repo);
- core::module_dependencies dependencies(system_info_provider_repo, cg_registry, media_info_repo, producer_registry);
+ core::module_dependencies dependencies(system_info_provider_repo, cg_registry, media_info_repo, producer_registry, consumer_registry);
initialize_modules(dependencies);
generate_amcp_commands_help(*help_repo);
spl::shared_ptr<system_info_provider_repository> system_info_provider_repo_;
spl::shared_ptr<core::cg_producer_registry> cg_registry_;
spl::shared_ptr<core::frame_producer_registry> producer_registry_;
+ spl::shared_ptr<core::frame_consumer_registry> consumer_registry_;
tbb::atomic<bool> running_;
std::shared_ptr<thumbnail_generator> thumbnail_generator_;
std::promise<bool>& shutdown_server_now_;
system_info_provider_repo_,
cg_registry_,
media_info_repo_,
- producer_registry_);
+ producer_registry_,
+ consumer_registry_);
initialize_modules(dependencies);
core::text::init(dependencies);
auto name = xml_consumer.first;
if (name != L"<xmlcomment>")
- channel->output().add(create_consumer(name, xml_consumer.second, &channel->stage()));
+ channel->output().add(consumer_registry_->create_consumer(name, xml_consumer.second, &channel->stage()));
}
catch(...)
{
cg_registry_,
help_repo_,
producer_registry_,
+ consumer_registry_,
shutdown_server_now_);
amcp::register_commands(*amcp_command_repo_);