]> git.sesse.net Git - casparcg/blobdiff - protocol/amcp/AMCPCommandsImpl.cpp
* Fixed bug where deferred transforms did not compose correctly when committed.
[casparcg] / protocol / amcp / AMCPCommandsImpl.cpp
index ec2151f1ea289584a6232a592b7cbfcb74ba4f6a..ef042f78834ea8026dab2c39814d90bc1a14ffc3 100644 (file)
@@ -980,6 +980,16 @@ std::wstring cg_play_command(command_context& ctx)
        return L"202 CG OK\r\n";
 }
 
+spl::shared_ptr<core::cg_proxy> get_expected_cg_proxy(command_context& ctx)
+{
+       auto proxy = ctx.cg_registry->get_proxy(spl::make_shared_ptr(ctx.channel.channel), ctx.layer_index(core::cg_proxy::DEFAULT_LAYER));
+
+       if (proxy == cg_proxy::empty())
+               CASPAR_THROW_EXCEPTION(file_not_found() << msg_info(L"No CG proxy running on layer"));
+
+       return proxy;
+}
+
 void cg_stop_describer(core::help_sink& sink, const core::help_repository& repo)
 {
        sink.short_description(L"Stop and remove a template.");
@@ -994,7 +1004,7 @@ void cg_stop_describer(core::help_sink& sink, const core::help_repository& repo)
 std::wstring cg_stop_command(command_context& ctx)
 {
        int layer = get_and_validate_layer(ctx.parameters.at(0));
-       ctx.cg_registry->get_proxy(spl::make_shared_ptr(ctx.channel.channel), ctx.layer_index(core::cg_proxy::DEFAULT_LAYER))->stop(layer, 0);
+       get_expected_cg_proxy(ctx)->stop(layer, 0);
 
        return L"202 CG OK\r\n";
 }
@@ -1013,7 +1023,7 @@ void cg_next_describer(core::help_sink& sink, const core::help_repository& repo)
 std::wstring cg_next_command(command_context& ctx)
 {
        int layer = get_and_validate_layer(ctx.parameters.at(0));
-       ctx.cg_registry->get_proxy(spl::make_shared_ptr(ctx.channel.channel), ctx.layer_index(core::cg_proxy::DEFAULT_LAYER))->next(layer);
+       get_expected_cg_proxy(ctx)->next(layer);
 
        return L"202 CG OK\r\n";
 }
@@ -1030,7 +1040,7 @@ void cg_remove_describer(core::help_sink& sink, const core::help_repository& rep
 std::wstring cg_remove_command(command_context& ctx)
 {
        int layer = get_and_validate_layer(ctx.parameters.at(0));
-       ctx.cg_registry->get_proxy(spl::make_shared_ptr(ctx.channel.channel), ctx.layer_index(core::cg_proxy::DEFAULT_LAYER))->remove(layer);
+       get_expected_cg_proxy(ctx)->remove(layer);
 
        return L"202 CG OK\r\n";
 }
@@ -1073,10 +1083,7 @@ std::wstring cg_update_command(command_context& ctx)
                dataString = read_file(boost::filesystem::path(filename));
        }
 
-       ctx.cg_registry->get_proxy(
-               spl::make_shared_ptr(ctx.channel.channel),
-               ctx.layer_index(core::cg_proxy::DEFAULT_LAYER))
-               ->update(layer, dataString);
+       get_expected_cg_proxy(ctx)->update(layer, dataString);
 
        return L"202 CG OK\r\n";
 }
@@ -1094,10 +1101,7 @@ std::wstring cg_invoke_command(command_context& ctx)
        std::wstringstream replyString;
        replyString << L"201 CG OK\r\n";
        int layer = get_and_validate_layer(ctx.parameters.at(0));
-       auto result = ctx.cg_registry->get_proxy(
-               spl::make_shared_ptr(ctx.channel.channel),
-               ctx.layer_index(core::cg_proxy::DEFAULT_LAYER))
-               ->invoke(layer, ctx.parameters.at(1));
+       auto result = get_expected_cg_proxy(ctx)->invoke(layer, ctx.parameters.at(1));
        replyString << result << L"\r\n";
 
        return replyString.str();
@@ -1118,19 +1122,13 @@ std::wstring cg_info_command(command_context& ctx)
 
        if (ctx.parameters.empty())
        {
-               auto info = ctx.cg_registry->get_proxy(
-                       spl::make_shared_ptr(ctx.channel.channel),
-                       ctx.layer_index(core::cg_proxy::DEFAULT_LAYER))
-                       ->template_host_info();
+               auto info = get_expected_cg_proxy(ctx)->template_host_info();
                replyString << info << L"\r\n";
        }
        else
        {
                int layer = get_and_validate_layer(ctx.parameters.at(0));
-               auto desc = ctx.cg_registry->get_proxy(
-                       spl::make_shared_ptr(ctx.channel.channel),
-                       ctx.layer_index(core::cg_proxy::DEFAULT_LAYER))
-                       ->description(layer);
+               auto desc = get_expected_cg_proxy(ctx)->description(layer);
 
                replyString << desc << L"\r\n";
        }
@@ -1177,8 +1175,9 @@ public:
 
        void commit_deferred()
        {
-               ctx_.channel.channel->stage().apply_transforms(
-                               std::move(deferred_transforms_[ctx_.channel_index]));
+               auto& transforms = deferred_transforms_[ctx_.channel_index];
+               ctx_.channel.channel->stage().apply_transforms(transforms).get();
+               transforms.clear();
        }
 
        void apply()
@@ -2147,7 +2146,7 @@ std::wstring cinf_command(command_context& ctx)
                auto path = itr->path();
                auto file = path.replace_extension(L"").filename().wstring();
                if (boost::iequals(file, ctx.parameters.at(0)))
-                       info += MediaInfo(itr->path(), ctx.media_info_repo) + L"\r\n";
+                       info += MediaInfo(itr->path(), ctx.media_info_repo);
        }
 
        if (info.empty())
@@ -2416,13 +2415,34 @@ std::wstring info_threads_command(command_context& ctx)
 
        for (auto& thread : get_thread_infos())
        {
-               replyString << thread->native_id << L"\t" << u16(thread->name) << L"\r\n";
+               replyString << thread->native_id << L" " << u16(thread->name) << L"\r\n";
        }
 
        replyString << L"\r\n";
        return replyString.str();
 }
 
+void info_delay_describer(core::help_sink& sink, const core::help_repository& repo)
+{
+       sink.short_description(L"Get the current delay on a channel or a layer.");
+       sink.syntax(L"INFO [video_channel:int]{-[layer:int]} DELAY");
+       sink.para()->text(L"Get the current delay on the specified channel or layer.");
+}
+
+std::wstring info_delay_command(command_context& ctx)
+{
+       boost::property_tree::wptree info;
+       auto layer = ctx.layer_index(std::numeric_limits<int>::min());
+
+       if (layer == std::numeric_limits<int>::min())
+               info.add_child(L"channel-delay", ctx.channel.channel->delay_info());
+       else
+               info.add_child(L"layer-delay", ctx.channel.channel->stage().delay_info(layer).get())
+                       .add(L"index", layer);
+
+       return create_info_xml_reply(info, L"DELAY");
+}
+
 void diag_describer(core::help_sink& sink, const core::help_repository& repo)
 {
        sink.short_description(L"Open the diagnostics window.");
@@ -2788,6 +2808,7 @@ void register_commands(amcp_command_repository& repo)
        repo.register_command(                  L"Query Commands",              L"INFO SERVER",                         info_server_describer,                          info_server_command,                    0);
        repo.register_command(                  L"Query Commands",              L"INFO QUEUES",                         info_queues_describer,                          info_queues_command,                    0);
        repo.register_command(                  L"Query Commands",              L"INFO THREADS",                        info_threads_describer,                         info_threads_command,                   0);
+       repo.register_channel_command(  L"Query Commands",              L"INFO DELAY",                          info_delay_describer,                           info_delay_command,                             0);
        repo.register_command(                  L"Query Commands",              L"DIAG",                                        diag_describer,                                         diag_command,                                   0);
        repo.register_command(                  L"Query Commands",              L"BYE",                                         bye_describer,                                          bye_command,                                    0);
        repo.register_command(                  L"Query Commands",              L"KILL",                                        kill_describer,                                         kill_command,                                   0);