* Added HELP CONSUMER command to list available consumers and get help for them.
* Updated generate_docs.cpp to also include a wiki page for the consumers.
struct frame_consumer_registry::impl
{
- std::vector<consumer_factory_t> consumer_factories;
- std::map<std::wstring, preconfigured_consumer_factory_t> preconfigured_consumer_factories;
+ std::vector<consumer_factory_t> consumer_factories;
+ std::map<std::wstring, preconfigured_consumer_factory_t> preconfigured_consumer_factories;
+ spl::shared_ptr<help_repository> help_repo;
+
+ impl(spl::shared_ptr<help_repository> help_repo)
+ : help_repo(std::move(help_repo))
+ {
+ }
};
-frame_consumer_registry::frame_consumer_registry()
- : impl_(new impl)
+frame_consumer_registry::frame_consumer_registry(spl::shared_ptr<help_repository> help_repo)
+ : impl_(new impl(std::move(help_repo)))
{
}
-void frame_consumer_registry::register_consumer_factory(const consumer_factory_t& factory)
+void frame_consumer_registry::register_consumer_factory(const std::wstring& name, const consumer_factory_t& factory, const help_item_describer& describer)
{
impl_->consumer_factories.push_back(factory);
+ impl_->help_repo->register_item({ L"consumer" }, std::move(name), describer);
}
void frame_consumer_registry::register_preconfigured_consumer_factory(
#include "../monitor/monitor.h"
#include "../fwd.h"
+#include "../help/help_repository.h"
#include <common/memory.h>
#include <common/future_fwd.h>
class frame_consumer_registry : boost::noncopyable
{
public:
- frame_consumer_registry();
- void register_consumer_factory(const consumer_factory_t& factory);
+ frame_consumer_registry(spl::shared_ptr<help_repository> help_repo);
+ void register_consumer_factory(const std::wstring& name, const consumer_factory_t& factory, const help_item_describer& describer);
void register_preconfigured_consumer_factory(
const std::wstring& element_name,
const preconfigured_consumer_factory_t& factory);
}
catch(...){}
- dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_consumer_factory(L"Bluefish Consumer", create_consumer, describe_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)
{
#include <core/video_format.h>
#include <core/frame/frame.h>
+#include <core/help/help_repository.h>
+#include <core/help/help_sink.h>
#include <common/executor.h>
#include <common/diagnostics/graph.h>
}
};
+
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo)
+{
+ sink.short_description(L"Sends video on an SDI output using Bluefish video cards.");
+ sink.syntax(L"BLUEFISH {[device_index:int]|1} {[embedded_audio:EMBEDDED_AUDIO]} {[key_only:KEY_ONLY]}");
+ sink.para()
+ ->text(L"Sends video on an SDI output using Bluefish video cards. Multiple video cards can be ")
+ ->text(L"installed in the same machine and used at the same time, they will be addressed via ")
+ ->text(L"different ")->code(L"device_index")->text(L" parameters.");
+ sink.para()->text(L"Specify ")->code(L"embedded_audio")->text(L" to embed audio into the SDI signal.");
+ sink.para()
+ ->text(L"Specifying ")->code(L"key_only")->text(L" will extract only the alpha channel from the ")
+ ->text(L"channel. This is useful when you have two SDI video cards, and neither has native support ")
+ ->text(L"for separate fill/key output");
+ sink.para()->text(L"Examples:");
+ sink.example(L">> ADD 1 BLUEFISH", L"uses the default device_index of 1.");
+ sink.example(L">> ADD 1 BLUEFISH 2", L"for device_index 2.");
+ sink.example(
+ L">> ADD 1 BLUEFISH 1 EMBEDDED_AUDIO\n"
+ L">> ADD 1 BLUEFISH 2 KEY_ONLY", L"uses device with index 1 as fill output with audio and device with index 2 as key output.");
+}
+
spl::shared_ptr<core::frame_consumer> create_consumer(
const std::vector<std::wstring>& params, core::interaction_sink*)
{
namespace caspar { namespace bluefish {
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo);
spl::shared_ptr<core::frame_consumer> create_consumer(
const std::vector<std::wstring>& params, core::interaction_sink*);
spl::shared_ptr<core::frame_consumer> create_preconfigured_consumer(
#include <core/frame/frame.h>
#include <core/mixer/audio/audio_mixer.h>
+#include <core/consumer/frame_consumer.h>
+#include <core/diagnostics/call_context.h>
+#include <core/help/help_sink.h>
+#include <core/help/help_repository.h>
#include <common/executor.h>
#include <common/lock.h>
#include <common/timer.h>
#include <common/param.h>
-#include <core/consumer/frame_consumer.h>
-#include <core/diagnostics/call_context.h>
-
#include <tbb/concurrent_queue.h>
#include <common/assert.h>
}
};
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo)
+{
+ sink.short_description(L"Sends video on an SDI output using Blackmagic Decklink video cards.");
+ sink.syntax(L"DECKLINK "
+ L"{[device_index:int]|1} "
+ L"{[keyer:INTERNAL_KEY,EXTERNAL_KEY]} "
+ L"{[low_latency:LOW_LATENCY]} "
+ L"{[embedded_audio:EMBEDDED_AUDIO]} "
+ L"{[key_only:KEY_ONLY]}");
+ sink.para()->text(L"Sends video on an SDI output using Blackmagic Decklink video cards.");
+ sink.definitions()
+ ->item(L"device_index", L"The Blackmagic video card to use (See Blackmagic control panel for card order). Default is 1.")
+ ->item(L"keyer", L"If given tries to enable either internal or external keying. Not all Blackmagic cards supports this.")
+ ->item(L"low_latency", L"Tries to enable low latency if given.")
+ ->item(L"embedded_audio", L"Embeds the audio into the SDI signal if given.")
+ ->item(L"key_only",
+ L" will extract only the alpha channel from the "
+ L"channel. This is useful when you have two SDI video cards, and neither has native support "
+ L"for separate fill/key output");
+ sink.para()->text(L"Examples:");
+ sink.example(L">> ADD 1 DECKLINK", L"for using the default device_index of 1.");
+ sink.example(L">> ADD 1 DECKLINK 2", L"uses device_index 2.");
+ sink.example(L">> ADD 1 DECKLINK 1 EXTERNAL_KEY EMBEDDED_AUDIO");
+ sink.example(
+ L">> ADD 1 DECKLINK 1 EMBEDDED_AUDIO\n"
+ L">> ADD 1 DECKLINK 2 KEY_ONLY", L"uses device with index 1 as fill output with audio and device with index 2 as key output.");
+}
+
spl::shared_ptr<core::frame_consumer> create_consumer(
const std::vector<std::wstring>& params, core::interaction_sink*)
{
namespace caspar { namespace decklink {
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo);
spl::shared_ptr<core::frame_consumer> create_consumer(
const std::vector<std::wstring>& params, core::interaction_sink*);
spl::shared_ptr<core::frame_consumer> create_preconfigured_consumer(
void init(core::module_dependencies dependencies)
{
- dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_consumer_factory(L"Decklink Consumer", create_consumer, describe_consumer);
dependencies.consumer_registry->register_preconfigured_consumer_factory(L"decklink", create_preconfigured_consumer);
dependencies.producer_registry->register_producer_factory(L"Decklink Producer", create_producer, describe_producer);
dependencies.system_info_provider_repo->register_system_info_provider([](boost::property_tree::wptree& info)
#include <core/mixer/audio/audio_util.h>
#include <core/consumer/frame_consumer.h>
#include <core/video_format.h>
+#include <core/help/help_repository.h>
+#include <core/help/help_sink.h>
#include <common/array.h>
#include <common/env.h>
{
return consumer_->monitor_output();
}
-};
+};
+
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo)
+{
+ sink.short_description(L"Can record a channel to a file supported by FFMpeg.");
+ sink.syntax(L"FILE [filename:string] {-[ffmpeg_param1:string] [value1:string] {-[ffmpeg_param2:string] [value2:string] {...}}} {[separate_key:SEPARATE_KEY]}");
+ sink.para()->text(L"Can record a channel to a file supported by FFMpeg.");
+ sink.definitions()
+ ->item(L"filename", L"The filename under the media folder including the extension (decides which kind of container format that will be used).")
+ ->item(L"ffmpeg_paramX", L"A parameter supported by FFMpeg. For example vcodec or acodec etc.")
+ ->item(L"separate_key", L"If defined will create two files simultaneously -- One for fill and one for key (_A will be appended).")
+ ;
+ sink.para()->text(L"Examples:");
+ sink.example(L">> ADD 1 FILE output.mov -vcodec dnxhd");
+ sink.example(L">> ADD 1 FILE output.mov -vcodec prores");
+ sink.example(L">> ADD 1 FILE output.mov -vcodec dvvideo");
+ sink.example(L">> ADD 1 FILE output.mov - vcodec libx264 -preset ultrafast -tune fastdecode -crf 25");
+ sink.example(L">> ADD 1 FILE output.mov -vcodec dnxhd SEPARATE_KEY", L"for creating output.mov with fill and output_A.mov with key/alpha");
+}
+
spl::shared_ptr<core::frame_consumer> create_consumer(
const std::vector<std::wstring>& params, core::interaction_sink*)
{
namespace caspar { namespace ffmpeg {
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo);
spl::shared_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>& params, core::interaction_sink*);
spl::shared_ptr<core::frame_consumer> create_preconfigured_consumer(const boost::property_tree::wptree& ptree, core::interaction_sink*);
#include <core/frame/frame.h>
#include <core/video_format.h>
#include <core/monitor/monitor.h>
+#include <core/help/help_repository.h>
+#include <core/help/help_sink.h>
#include <boost/noncopyable.hpp>
#include <boost/rational.hpp>
return result;
}
};
-
+
+void describe_streaming_consumer(core::help_sink& sink, const core::help_repository& repo)
+{
+ sink.short_description(L"For streaming the contents of a channel using FFMpeg.");
+ sink.syntax(L"STREAM [url:string] {-[ffmpeg_param1:string] [value1:string] {-[ffmpeg_param2:string] [value2:string] {...}}}");
+ sink.para()->text(L"For streaming the contents of a channel using FFMpeg");
+ sink.definitions()
+ ->item(L"url", L"The stream URL to create/stream to.")
+ ->item(L"ffmpeg_paramX", L"A parameter supported by FFMpeg. For example vcodec or acodec etc.");
+ sink.para()->text(L"Examples:");
+ sink.example(L">> ADD 1 STREAM udp://<client_ip_address>:9250 -format mpegts -vcodec libx264 -crf 25 -tune zerolatency -preset ultrafast");
+}
+
spl::shared_ptr<core::frame_consumer> create_streaming_consumer(
const std::vector<std::wstring>& params, core::interaction_sink*)
{
#include <vector>
namespace caspar { namespace ffmpeg {
-
+
+void describe_streaming_consumer(core::help_sink& sink, const core::help_repository& repo);
spl::shared_ptr<core::frame_consumer> create_streaming_consumer(
const std::vector<std::wstring>& params, core::interaction_sink*);
spl::shared_ptr<core::frame_consumer> create_preconfigured_streaming_consumer(
avformat_network_init();
avcodec_register_all();
- dependencies.consumer_registry->register_consumer_factory(create_consumer);
- dependencies.consumer_registry->register_consumer_factory(create_streaming_consumer);
+ dependencies.consumer_registry->register_consumer_factory(L"FFMpeg Consumer", create_consumer, describe_consumer);
+ dependencies.consumer_registry->register_consumer_factory(L"Streaming Consumer", create_streaming_consumer, describe_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(L"FFmpeg Producer", create_producer, describe_producer);
#include <core/consumer/frame_consumer.h>
#include <core/video_format.h>
#include <core/frame/frame.h>
+#include <core/help/help_sink.h>
+#include <core/help/help_repository.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread.hpp>
namespace caspar { namespace image {
- void write_cropped_png(
+void write_cropped_png(
const core::const_frame& frame,
const core::video_format_desc& format_desc,
const boost::filesystem::path& output_file,
int width,
int height)
- {
- auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_Allocate(width, height, 32), FreeImage_Unload);
- image_view<bgra_pixel> destination_view(FreeImage_GetBits(bitmap.get()), width, height);
- image_view<bgra_pixel> complete_frame(const_cast<uint8_t*>(frame.image_data().begin()), format_desc.width, format_desc.height);
- auto thumbnail_view = complete_frame.subview(0, 0, width, height);
-
- std::copy(thumbnail_view.begin(), thumbnail_view.end(), destination_view.begin());
- FreeImage_FlipVertical(bitmap.get());
- FreeImage_SaveU(FIF_PNG, bitmap.get(), output_file.wstring().c_str(), 0);
- }
+{
+ auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_Allocate(width, height, 32), FreeImage_Unload);
+ image_view<bgra_pixel> destination_view(FreeImage_GetBits(bitmap.get()), width, height);
+ image_view<bgra_pixel> complete_frame(const_cast<uint8_t*>(frame.image_data().begin()), format_desc.width, format_desc.height);
+ auto thumbnail_view = complete_frame.subview(0, 0, width, height);
+
+ std::copy(thumbnail_view.begin(), thumbnail_view.end(), destination_view.begin());
+ FreeImage_FlipVertical(bitmap.get());
+ FreeImage_SaveU(FIF_PNG, bitmap.get(), output_file.wstring().c_str(), 0);
+}
struct image_consumer : public core::frame_consumer
{
}
};
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo)
+{
+ sink.short_description(L"Writes a single PNG snapshot of a video channel.");
+ sink.syntax(L"IMAGE {[filename:string]|yyyyMMddTHHmmss}");
+ sink.para()
+ ->text(L"Writes a single PNG snapshot of a video channel. ")->code(L".png")->text(L" will be appended to ")
+ ->code(L"filename")->text(L". The PNG image will be stored under the ")->code(L"media")->text(L" folder.");
+ sink.para()->text(L"Examples:");
+ sink.example(L">> ADD 1 IMAGE screenshot", L"creating media/screenshot.png");
+ sink.example(L">> ADD 1 IMAGE", L"creating media/20130228T210946.png if the current time is 2013-02-28 21:09:46.");
+}
+
spl::shared_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>& params, core::interaction_sink*)
{
if (params.size() < 1 || !boost::iequals(params.at(0), L"IMAGE"))
int width,
int height);
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo);
spl::shared_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>& params, struct core::interaction_sink*);
}}
dependencies.producer_registry->register_producer_factory(L"Image Scroll Producer", create_scroll_producer, describe_scroll_producer);
dependencies.producer_registry->register_producer_factory(L"Image Producer", create_producer, describe_producer);
dependencies.producer_registry->register_thumbnail_producer_factory(create_thumbnail_producer);
- dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_consumer_factory(L"Image Consumer", create_consumer, describe_consumer);
dependencies.media_info_repo->register_extractor([](const std::wstring& file, const std::wstring& extension, core::media_info& info)
{
if (extension == L".TGA"
#include <core/frame/frame.h>
#include <core/mixer/audio/audio_util.h>
#include <core/monitor/monitor.h>
+#include <core/help/help_sink.h>
+#include <core/help/help_repository.h>
#include <common/assert.h>
#include <common/executor.h>
}
};
+void describe_ivga_consumer(core::help_sink& sink, const core::help_repository& repo)
+{
+ sink.short_description(L"A consumer for streaming a channel to a NewTek TriCaster via iVGA/AirSend protocol.");
+ sink.syntax(L"NEWTEK_IVGA {[dont_provide_sync:DONT_PROVIDE_SYNC]}");
+ sink.para()->text(L"A consumer for streaming a channel to a NewTek TriCaster via iVGA/AirSend protocol.");
+ sink.para()->text(L"If ")->code(L"dont_provide_sync")->text(L" is specified, the consumer will not genlock the channel.");
+ sink.para()->text(L"Examples:");
+ sink.example(L">> ADD 1 NEWTEK_IVGA");
+ sink.example(L">> ADD 1 NEWTEK_IVGA DONT_PROVIDE_SYNC");
+}
+
spl::shared_ptr<core::frame_consumer> create_ivga_consumer(const std::vector<std::wstring>& params, core::interaction_sink*)
{
if (params.size() < 1 || !boost::iequals(params.at(0), L"NEWTEK_IVGA"))
namespace caspar { namespace newtek {
+void describe_ivga_consumer(core::help_sink& sink, const core::help_repository& repo);
spl::shared_ptr<core::frame_consumer> create_ivga_consumer(const std::vector<std::wstring>& params, core::interaction_sink*);
spl::shared_ptr<core::frame_consumer> create_preconfigured_ivga_consumer(const boost::property_tree::wptree& ptree, core::interaction_sink*);
{
try
{
- if (airsend::is_available())
- dependencies.consumer_registry->register_consumer_factory(create_ivga_consumer);
+ dependencies.consumer_registry->register_consumer_factory(L"iVGA Consumer", create_ivga_consumer, describe_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()
#include <core/mixer/audio/audio_util.h>
#include <core/mixer/audio/audio_mixer.h>
#include <core/video_format.h>
+#include <core/help/help_sink.h>
+#include <core/help/help_repository.h>
#include <boost/circular_buffer.hpp>
#include <boost/lexical_cast.hpp>
}
};
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo)
+{
+ sink.short_description(L"A system audio consumer.");
+ sink.syntax(L"AUDIO");
+ sink.para()->text(L"Uses the system's default audio playback device.");
+ sink.para()->text(L"Examples:");
+ sink.example(L">> ADD 1 AUDIO");
+}
+
spl::shared_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>& params, core::interaction_sink*)
{
if(params.size() < 1 || !boost::iequals(params.at(0), L"AUDIO"))
namespace caspar { namespace oal {
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo);
spl::shared_ptr<core::frame_consumer> create_consumer(
const std::vector<std::wstring>& params, core::interaction_sink*);
spl::shared_ptr<core::frame_consumer> create_preconfigured_consumer(
void init(core::module_dependencies dependencies)
{
- dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_consumer_factory(L"System Audio Consumer", create_consumer, describe_consumer);
dependencies.consumer_registry->register_preconfigured_consumer_factory(L"system-audio", create_preconfigured_consumer);
}
#include <core/frame/frame.h>
#include <core/consumer/frame_consumer.h>
#include <core/interaction/interaction_sink.h>
+#include <core/help/help_sink.h>
+#include <core/help/help_repository.h>
#include <boost/circular_buffer.hpp>
#include <boost/lexical_cast.hpp>
}
};
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo)
+{
+ sink.short_description(L"Displays the contents of a channel on screen using OpenGL.");
+ sink.syntax(
+ L"SCREEN "
+ L"{[screen_index:int]|1} "
+ L"{[fullscreen:FULLSCREEN]} "
+ L"{[key_only:KEY_ONLY]} "
+ L"{[non_interactive:NON_INTERACTIVE]} "
+ L"{[no_auto_deinterlace:NO_AUTO_DEINTERLACE]} "
+ L"{NAME [name:string]}");
+ sink.para()->text(L"Displays the contents of a channel on screen using OpenGL.");
+ sink.definitions()
+ ->item(L"screen_index", L"Determines which screen the channel should be displayed on. Defaults to 1.")
+ ->item(L"fullscreen", L"If specified opens the window in fullscreen.")
+ ->item(L"key_only", L"Only displays the alpha channel of the video channel if specified.")
+ ->item(L"non_interactive", L"If specified does not send mouse input to producers on the video channel.")
+ ->item(L"no_auto_deinterlace", L"If the video mode of the channel is an interlaced mode, specifying this will turn of deinterlacing.")
+ ->item(L"name", L"Optionally specifies a name of the window to show.");
+ sink.para()->text(L"Examples:");
+ sink.example(L">> ADD 1 SCREEN", L"opens a screen consumer on the default screen.");
+ sink.example(L">> ADD 1 SCREEN 2", L"opens a screen consumer on the screen 2.");
+ sink.example(L">> ADD 1 SCREEN 1 FULLSCREEN", L"opens a screen consumer in fullscreen on screen 1.");
+}
+
spl::shared_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>& params, core::interaction_sink* sink)
{
if (params.size() < 1 || !boost::iequals(params.at(0), L"SCREEN"))
namespace caspar { namespace screen {
+void describe_consumer(core::help_sink& sink, const core::help_repository& repo);
spl::shared_ptr<core::frame_consumer> create_consumer(
const std::vector<std::wstring>& params,
core::interaction_sink* sink);
void init(core::module_dependencies dependencies)
{
- dependencies.consumer_registry->register_consumer_factory(create_consumer);
+ dependencies.consumer_registry->register_consumer_factory(L"Screen Consumer", create_consumer, describe_consumer);
dependencies.consumer_registry->register_preconfigured_consumer_factory(L"screen", create_preconfigured_consumer);
}
void mixer_commit_describer(core::help_sink& sink, const core::help_repository& repo)
{
sink.short_description(L"Commit all deferred mixer transforms.");
- sink.syntax(L"MIXER [video_channel:int]{-[layer:int]|-0} COMMIT");
+ sink.syntax(L"MIXER [video_channel:int] COMMIT");
sink.para()->text(L"Commits all deferred mixer transforms on the specified channel. This ensures that all animations start at the same exact frame.");
sink.para()->text(L"Examples:");
sink.example(
return create_help_details(L"HELP PRODUCER", ctx, { L"producer" });
}
+void help_consumer_describer(core::help_sink& sink, const core::help_repository& repository)
+{
+ sink.short_description(L"Show online help for consumers.");
+ sink.syntax(LR"(HELP CONSUMER {[consumer:string]})");
+ sink.para()->text(LR"(Shows online help for a specific consumer or a list of all consumers.)");
+ sink.example(L">> HELP CONSUMER", L"Shows a list of consumers.");
+ sink.example(L">> HELP CONSUMER Decklink Consumer", L"Shows a detailed description of the Decklink Consumer.");
+}
+
+std::wstring help_consumer_command(command_context& ctx)
+{
+ if (ctx.parameters.size() == 0)
+ return create_help_list(L"HELP CONSUMER", ctx, { L"consumer" });
+ else
+ return create_help_details(L"HELP CONSUMER", ctx, { L"consumer" });
+}
+
void bye_describer(core::help_sink& sink, const core::help_repository& repo)
{
sink.short_description(L"Disconnect the session.");
repo.register_command( L"Query Commands", L"RESTART", restart_describer, restart_command, 0);
repo.register_command( L"Query Commands", L"HELP", help_describer, help_command, 0);
repo.register_command( L"Query Commands", L"HELP PRODUCER", help_producer_describer, help_producer_command, 0);
+ repo.register_command( L"Query Commands", L"HELP CONSUMER", help_consumer_describer, help_consumer_command, 0);
}
} //namespace amcp
file.flush();
}
+void generate_consumers_help(const core::help_repository& help_repo)
+{
+ boost::filesystem::wofstream file(L"consumers_help.wiki");
+ mediawiki_help_sink sink(file);
+
+ sink.start_section(L"Consumers (Output Modules)");
+ help_repo.help({ L"consumer" }, sink);
+
+ file.flush();
+}
+
int main(int argc, char** argv)
{
env::configure(L"casparcg.config");
auto media_info_repo = core::create_in_memory_media_info_repository();
spl::shared_ptr<core::help_repository> help_repo;
auto producer_registry = spl::make_shared<core::frame_producer_registry>(help_repo);
- spl::shared_ptr<core::frame_consumer_registry> consumer_registry;
+ auto consumer_registry = spl::make_shared<core::frame_consumer_registry>(help_repo);
std::promise<bool> shutdown_server_now;
protocol::amcp::amcp_command_repository repo(
{ },
generate_amcp_commands_help(*help_repo);
generate_producers_help(*help_repo);
+ generate_consumers_help(*help_repo);
uninitialize_modules();
, osc_client_(io_service_manager_.service())
, media_info_repo_(create_in_memory_media_info_repository())
, producer_registry_(spl::make_shared<core::frame_producer_registry>(help_repo_))
+ , consumer_registry_(spl::make_shared<core::frame_consumer_registry>(help_repo_))
, shutdown_server_now_(shutdown_server_now)
{
running_ = false;