From a9baf9ba1e7e4b94b5e08385328441de6607ad23 Mon Sep 17 00:00:00 2001 From: Helge Norberg Date: Fri, 7 Apr 2017 16:45:30 +0200 Subject: [PATCH] [channel_producer] #590 Added NO_AUTO_DEINTERLACE parameter to channel route AMCP syntax to avoid deinterlacing when performance is more important than quality. Also used by channel_grid for that reason. --- modules/reroute/producer/channel_producer.cpp | 15 ++++++++++----- modules/reroute/producer/channel_producer.h | 3 ++- modules/reroute/producer/reroute_producer.cpp | 11 ++++++++--- protocol/amcp/AMCPCommandsImpl.cpp | 2 +- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/modules/reroute/producer/channel_producer.cpp b/modules/reroute/producer/channel_producer.cpp index 2d02397e7..fd86d12bb 100644 --- a/modules/reroute/producer/channel_producer.cpp +++ b/modules/reroute/producer/channel_producer.cpp @@ -244,7 +244,11 @@ class channel_producer : public core::frame_producer_base std::queue frame_buffer_; public: - explicit channel_producer(const core::frame_producer_dependencies& dependecies, const spl::shared_ptr& channel, int frames_delay) + explicit channel_producer( + const core::frame_producer_dependencies& dependecies, + const spl::shared_ptr& channel, + int frames_delay, + bool no_auto_deinterlace) : frame_factory_(dependecies.frame_factory) , output_format_desc_(dependecies.format_desc) , consumer_(spl::make_shared(frames_delay)) @@ -252,11 +256,11 @@ public: channel->video_format_desc().framerate, { ffmpeg::create_input_pad(channel->video_format_desc(), channel->audio_channel_layout().num_channels) }, dependecies.frame_factory, - get_progressive_format(channel->video_format_desc()), + no_auto_deinterlace ? channel->video_format_desc() : get_progressive_format(channel->video_format_desc()), channel->audio_channel_layout(), L"", false, - true) + !no_auto_deinterlace) { pixel_constraints_.width.set(output_format_desc_.width); pixel_constraints_.height.set(output_format_desc_.height); @@ -346,9 +350,10 @@ public: spl::shared_ptr create_channel_producer( const core::frame_producer_dependencies& dependencies, const spl::shared_ptr& channel, - int frames_delay) + int frames_delay, + bool no_auto_deinterlace) { - auto producer = spl::make_shared(dependencies, channel, frames_delay); + auto producer = spl::make_shared(dependencies, channel, frames_delay, no_auto_deinterlace); return core::create_framerate_producer( producer, diff --git a/modules/reroute/producer/channel_producer.h b/modules/reroute/producer/channel_producer.h index c4ddfc4d0..d43250fb9 100644 --- a/modules/reroute/producer/channel_producer.h +++ b/modules/reroute/producer/channel_producer.h @@ -30,6 +30,7 @@ namespace caspar { namespace reroute { spl::shared_ptr create_channel_producer( const core::frame_producer_dependencies& dependencies, const spl::shared_ptr& channel, - int frames_delay); + int frames_delay, + bool no_auto_deinterlace); }} diff --git a/modules/reroute/producer/reroute_producer.cpp b/modules/reroute/producer/reroute_producer.cpp index cd281afe3..d334a4365 100644 --- a/modules/reroute/producer/reroute_producer.cpp +++ b/modules/reroute/producer/reroute_producer.cpp @@ -40,7 +40,7 @@ namespace caspar { namespace reroute { void describe_producer(core::help_sink& sink, const core::help_repository& repository) { sink.short_description(L"Reroutes a complete channel or a layer to another layer."); - sink.syntax(L"route://[source_channel:int]{-[source_layer:int]} {FRAMES_DELAY [frames_delay:int]}"); + sink.syntax(L"route://[source_channel:int]{-[source_layer:int]} {FRAMES_DELAY [frames_delay:int]} {[no_auto_deinterlace:NO_AUTO_DEINTERLACE]}"); sink.para()->text(L"Reroutes the composited video of a channel or the untransformed video of a layer."); sink.para() ->text(L"If ")->code(L"source_layer")->text(L" is specified, only the video of the source layer is rerouted. ") @@ -48,9 +48,13 @@ void describe_producer(core::help_sink& sink, const core::help_repository& repos sink.para() ->text(L"An optional additional delay can be specified with the ")->code(L"frames_delay") ->text(L" parameter."); + sink.para() + ->text(L"For channel routing an optional ")->code(L"no_auto_deinterlace") + ->text(L" parameter can be specified, when performance is more important than good quality output."); sink.para()->text(L"Examples:"); sink.example(L">> PLAY 1-10 route://1-11", L"Play the contents of layer 1-11 on layer 1-10 as well."); sink.example(L">> PLAY 1-10 route://2", L"Play the composited contents of channel 2 on layer 1-10 as well."); + sink.example(L">> PLAY 1-10 route://2 NO_AUTO_DEINTERLACE"); sink.example( L">> MIXER 1-10 FILL 0.02 0.01 0.9 0.9\n" L">> PLAY 1-10 route://1\n" @@ -94,7 +98,8 @@ spl::shared_ptr create_producer( auto params2 = params; params2.erase(params2.begin()); - auto frames_delay = get_param(L"FRAMES_DELAY", params2, 0); + auto frames_delay = get_param(L"FRAMES_DELAY", params2, 0); + bool no_auto_deinterlace = contains_param(L"NO_AUTO_DEINTERLACE", params2); if (has_layer_spec) { @@ -104,7 +109,7 @@ spl::shared_ptr create_producer( } else { - return create_channel_producer(dependencies, *found_channel, frames_delay); + return create_channel_producer(dependencies, *found_channel, frames_delay, no_auto_deinterlace); } } diff --git a/protocol/amcp/AMCPCommandsImpl.cpp b/protocol/amcp/AMCPCommandsImpl.cpp index 6b7a80abb..69826476d 100644 --- a/protocol/amcp/AMCPCommandsImpl.cpp +++ b/protocol/amcp/AMCPCommandsImpl.cpp @@ -2145,7 +2145,7 @@ std::wstring channel_grid_command(command_context& ctx) if (channel.channel != self.channel) { core::diagnostics::call_context::for_thread().layer = index; - auto producer = ctx.producer_registry->create_producer(get_producer_dependencies(self.channel, ctx), L"route://" + boost::lexical_cast(channel.channel->index())); + auto producer = ctx.producer_registry->create_producer(get_producer_dependencies(self.channel, ctx), L"route://" + boost::lexical_cast(channel.channel->index()) + L" NO_AUTO_DEINTERLACE"); self.channel->stage().load(index, producer, false); self.channel->stage().play(index); index++; -- 2.39.2