]> git.sesse.net Git - casparcg/commitdiff
* Merged straight alpha support to 2.1.0
authorHelge Norberg <helge.norberg@svt.se>
Tue, 22 Sep 2015 17:56:34 +0000 (19:56 +0200)
committerHelge Norberg <helge.norberg@svt.se>
Tue, 22 Sep 2015 17:56:34 +0000 (19:56 +0200)
15 files changed:
accelerator/accelerator.cpp
accelerator/cpu/image/image_mixer.cpp
accelerator/cpu/image/image_mixer.h
accelerator/ogl/image/image_kernel.cpp
accelerator/ogl/image/image_kernel.h
accelerator/ogl/image/image_mixer.cpp
accelerator/ogl/image/image_mixer.h
accelerator/ogl/image/image_shader.cpp
accelerator/ogl/image/image_shader.h
core/mixer/image/image_mixer.h
core/mixer/mixer.cpp
core/mixer/mixer.h
protocol/amcp/AMCPCommandsImpl.cpp
shell/casparcg.config
shell/server.cpp

index 4fbd90073cd28713177255b38a6c0971008097f7..a632315d41493048cbf20ad4093f3ffed20af0f2 100644 (file)
@@ -37,7 +37,10 @@ struct accelerator::impl
                                if(!ogl_device_)
                                        ogl_device_.reset(new ogl::device());
 
-                               return std::unique_ptr<core::image_mixer>(new ogl::image_mixer(spl::make_shared_ptr(ogl_device_), env::properties().get(L"configuration.mixer.blend-modes", false)));
+                               return std::unique_ptr<core::image_mixer>(new ogl::image_mixer(
+                                               spl::make_shared_ptr(ogl_device_),
+                                               env::properties().get(L"configuration.mixer.blend-modes", false),
+                                               env::properties().get(L"configuration.mixer.straight-alpha", false)));
                        }
                }
                catch(...)
index 3b0c2e4a80a28d2b63a9489294e4a5bcab4594e8..8313a9f8c9bf7ad852d317bcf0172342dd31d4de 100644 (file)
@@ -365,7 +365,7 @@ image_mixer::~image_mixer(){}
 void image_mixer::push(const core::frame_transform& transform){impl_->push(transform);}
 void image_mixer::visit(const core::const_frame& frame){impl_->visit(frame);}
 void image_mixer::pop(){impl_->pop();}
-std::future<array<const std::uint8_t>> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}
+std::future<array<const std::uint8_t>> image_mixer::operator()(const core::video_format_desc& format_desc, bool /* straighten_alpha */){return impl_->render(format_desc);}
 core::mutable_frame image_mixer::create_frame(const void* tag, const core::pixel_format_desc& desc) {return impl_->create_frame(tag, desc);}
 
 }}}
index f1c202ef2abe7e8d7c49c35ea7c91362fe6a59c7..37a89420457f1d64d868561dedc01060ae230855 100644 (file)
@@ -32,7 +32,7 @@ public:
        virtual void visit(const core::const_frame& frame);
        virtual void pop();
                
-       std::future<array<const std::uint8_t>> operator()(const core::video_format_desc& format_desc) override;
+       std::future<array<const std::uint8_t>> operator()(const core::video_format_desc& format_desc, bool straighten_alpha) override;
                
        core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc) override;
 
index 4c7b6a9ec565f8b8b99d818aa4584a3771ce6838..b10accd133e0ecfe1778e6cce55bfcbd77567528 100644 (file)
@@ -135,11 +135,15 @@ struct image_kernel::impl
        spl::shared_ptr<device> ogl_;
        spl::shared_ptr<shader> shader_;
        bool                                    blend_modes_;
-                                                       
-       impl(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted)
+       bool                                    post_processing_;
+       bool                                    supports_texture_barrier_       = glTextureBarrierNV != 0;
+
+       impl(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted, bool straight_alpha_wanted)
                : ogl_(ogl)
-               , shader_(ogl_->invoke([&]{return get_image_shader(ogl, blend_modes_, blend_modes_wanted); }))
+               , shader_(ogl_->invoke([&]{return get_image_shader(ogl, blend_modes_, blend_modes_wanted, post_processing_, straight_alpha_wanted); }))
        {
+               if (!supports_texture_barrier_)
+                       CASPAR_LOG(warning) << L"[image_mixer] TextureBarrierNV not supported. Post processing will not be available";
        }
 
        void draw(draw_params params)
@@ -244,6 +248,7 @@ struct image_kernel::impl
                                                                
                shader_->use();
 
+               shader_->set("post_processing", false);
                shader_->set("plane[0]",                texture_id::plane0);
                shader_->set("plane[1]",                texture_id::plane1);
                shader_->set("plane[2]",                texture_id::plane2);
@@ -452,11 +457,43 @@ struct image_kernel::impl
                GL(glDisable(GL_POLYGON_STIPPLE));
                GL(glDisable(GL_BLEND));
        }
+
+       void post_process(const std::shared_ptr<texture>& background, bool straighten_alpha)
+       {
+               bool should_post_process =
+                               supports_texture_barrier_
+                               && straighten_alpha
+                               && post_processing_;
+
+               if (!should_post_process)
+                       return;
+
+               background->attach();
+
+               background->bind(static_cast<int>(texture_id::background));
+
+               shader_->use();
+               shader_->set("background", texture_id::background);
+               shader_->set("post_processing", true);
+               shader_->set("straighten_alpha", straighten_alpha);
+
+               GL(glViewport(0, 0, background->width(), background->height()));
+
+               glBegin(GL_QUADS);
+                       glMultiTexCoord2d(GL_TEXTURE0, 0.0, 0.0); glVertex2d(0.0, 0.0);
+                       glMultiTexCoord2d(GL_TEXTURE0, 1.0, 0.0); glVertex2d(1.0, 0.0);
+                       glMultiTexCoord2d(GL_TEXTURE0, 1.0, 1.0); glVertex2d(1.0, 1.0);
+                       glMultiTexCoord2d(GL_TEXTURE0, 0.0, 1.0); glVertex2d(0.0, 1.0);
+               glEnd();
+
+               glTextureBarrierNV();
+       }
 };
 
-image_kernel::image_kernel(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted) : impl_(new impl(ogl, blend_modes_wanted)){}
+image_kernel::image_kernel(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted, bool straight_alpha_wanted) : impl_(new impl(ogl, blend_modes_wanted, straight_alpha_wanted)){}
 image_kernel::~image_kernel(){}
 void image_kernel::draw(const draw_params& params){impl_->draw(params);}
+void image_kernel::post_process(const std::shared_ptr<texture>& background, bool straighten_alpha) { impl_->post_process(background, straighten_alpha);}
 bool image_kernel::has_blend_modes() const{return impl_->blend_modes_;}
 
 }}}
index fd747f0b9fbdc3783a72da33fcc4988559bc4a8e..19fa810f4772c65509797ce49e6efa15c61a4550 100644 (file)
@@ -61,13 +61,15 @@ public:
 
        // Constructors
 
-       image_kernel(const spl::shared_ptr<class device>& ogl, bool blend_modes_wanted);
+       image_kernel(const spl::shared_ptr<class device>& ogl, bool blend_modes_wanted, bool straight_alpha_wanted);
        ~image_kernel();
 
        // Methods
 
        void draw(const draw_params& params);
-       
+       void post_process(
+                       const std::shared_ptr<class texture>& background, bool straighten_alpha);
+
        // Properties
 
        bool has_blend_modes() const;
index bea3bbe6b059fbd2c86863a3d85430c937290459..1ee5e3fb0ee8977fd1ad48fad6bcac4d6646417e 100644 (file)
@@ -86,13 +86,13 @@ class image_renderer
        spl::shared_ptr<device> ogl_;
        image_kernel                    kernel_;
 public:
-       image_renderer(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted)
+       image_renderer(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted, bool straight_alpha_wanted)
                : ogl_(ogl)
-               , kernel_(ogl_, blend_modes_wanted)
+               , kernel_(ogl_, blend_modes_wanted, straight_alpha_wanted)
        {
        }
        
-       std::future<array<const std::uint8_t>> operator()(std::vector<layer> layers, const core::video_format_desc& format_desc)
+       std::future<array<const std::uint8_t>> operator()(std::vector<layer> layers, const core::video_format_desc& format_desc, bool straighten_alpha)
        {       
                if(layers.empty())
                { // Bypass GPU with empty frame.
@@ -131,6 +131,8 @@ public:
                        else
                                draw(target_texture, std::move(layers), format_desc, core::field_mode::progressive);
 
+                       kernel_.post_process(target_texture, straighten_alpha);
+
                        return ogl_->copy_async(target_texture);
                }));
        }
@@ -293,9 +295,9 @@ struct image_mixer::impl : public core::frame_factory
        std::vector<layer>                                      layers_; // layer/stream/items
        std::vector<layer*>                                     layer_stack_;
 public:
-       impl(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted
+       impl(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted, bool straight_alpha_wanted)
                : ogl_(ogl)
-               , renderer_(ogl, blend_modes_wanted)
+               , renderer_(ogl, blend_modes_wanted, straight_alpha_wanted)
                , transform_stack_(1)   
        {
                CASPAR_LOG(info) << L"Initialized OpenGL Accelerated GPU Image Mixer";
@@ -354,9 +356,9 @@ public:
                layer_stack_.resize(transform_stack_.back().layer_depth);
        }
        
-       std::future<array<const std::uint8_t>> render(const core::video_format_desc& format_desc)
+       std::future<array<const std::uint8_t>> render(const core::video_format_desc& format_desc, bool straighten_alpha)
        {
-               return renderer_(std::move(layers_), format_desc);
+               return renderer_(std::move(layers_), format_desc, straighten_alpha);
        }
        
        core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc) override
@@ -369,12 +371,12 @@ public:
        }
 };
 
-image_mixer::image_mixer(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted) : impl_(new impl(ogl, blend_modes_wanted)){}
+image_mixer::image_mixer(const spl::shared_ptr<device>& ogl, bool blend_modes_wanted, bool straight_alpha_wanted) : impl_(new impl(ogl, blend_modes_wanted, straight_alpha_wanted)){}
 image_mixer::~image_mixer(){}
 void image_mixer::push(const core::frame_transform& transform){impl_->push(transform);}
 void image_mixer::visit(const core::const_frame& frame){impl_->visit(frame);}
 void image_mixer::pop(){impl_->pop();}
-std::future<array<const std::uint8_t>> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}
+std::future<array<const std::uint8_t>> image_mixer::operator()(const core::video_format_desc& format_desc, bool straighten_alpha){return impl_->render(format_desc, straighten_alpha);}
 core::mutable_frame image_mixer::create_frame(const void* tag, const core::pixel_format_desc& desc) {return impl_->create_frame(tag, desc);}
 
 }}}
index 5f7e8c845074c05ffdca8338a299b1c6f3955511..372ce3aec80fe1bf6ffb84a933cd1e4f76f31dba 100644 (file)
@@ -44,12 +44,12 @@ public:
        
        // Constructors
 
-       image_mixer(const spl::shared_ptr<class device>& ogl, bool blend_modes_wanted);
+       image_mixer(const spl::shared_ptr<class device>& ogl, bool blend_modes_wanted, bool straight_alpha_wanted);
        ~image_mixer();
 
        // Methods
                        
-       std::future<array<const std::uint8_t>> operator()(const core::video_format_desc& format_desc) override;         
+       std::future<array<const std::uint8_t>> operator()(const core::video_format_desc& format_desc, bool straighten_alpha) override;
        core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc) override;
 
        // core::image_mixer
index 070e2ed3f2c02140ad316738cae177d387649e93..dfc47a0b2ef6675e79eb1e68129210ebc5032c9c 100644 (file)
@@ -37,7 +37,8 @@ namespace caspar { namespace accelerator { namespace ogl {
 
 std::weak_ptr<shader>  g_shader;
 tbb::mutex                             g_shader_mutex;
-bool                                   g_blend_modes = false;
+bool                                   g_blend_modes           = false;
+bool                                   g_post_processing       = false;
 
 std::string get_blend_color_func()
 {
@@ -142,6 +143,22 @@ std::string get_chroma_func()
                )shader";
 }
 
+std::string get_post_process()
+{
+       return R"shader(
+               if (post_processing)
+               {
+                       gl_FragColor = post_process().bgra;
+               }
+               else
+       )shader";
+}
+
+std::string get_no_post_process()
+{
+       return "";
+}
+
 std::string get_vertex()
 {
        return R"shader(
@@ -158,7 +175,7 @@ std::string get_vertex()
        )shader";
 }
 
-std::string get_fragment(bool blend_modes)
+std::string get_fragment(bool blend_modes, bool post_processing)
 {
        return R"shader(
 
@@ -190,6 +207,9 @@ std::string get_fragment(bool blend_modes)
                        uniform float           sat;
                        uniform float           con;
 
+                       uniform bool            post_processing;
+                       uniform bool            straighten_alpha;
+
                        uniform bool            chroma;
                        uniform int                     chroma_mode;
                        uniform vec2            chroma_blend;
@@ -291,28 +311,53 @@ std::string get_fragment(bool blend_modes)
                                return vec4(0.0, 0.0, 0.0, 0.0);
                        }
 
+                       vec4 post_process()
+                       {
+                               vec4 color = texture2D(background, gl_TexCoord[0].st).bgra;
+
+                               if (straighten_alpha)
+                                       color.rgb /= color.a + 0.0000001;
+
+                               return color;
+                       }       
+
                        void main()
                        {
-                               vec4 color = get_rgba_color();
-                               if (chroma)
-                                       color = chroma_key(color);
-                               if(levels)
-                                       color.rgb = LevelsControl(color.rgb, min_input, gamma, max_input, min_output, max_output);
-                               if(csb)
-                                       color.rgb = ContrastSaturationBrightness(color.rgb, brt, sat, con);
-                               if(has_local_key)
-                                       color *= texture2D(local_key, gl_TexCoord[1].st).r;
-                               if(has_layer_key)
-                                       color *= texture2D(layer_key, gl_TexCoord[1].st).r;
-                               color *= opacity;
-                               color = blend(color);
-                               gl_FragColor = color.bgra;
+       )shader"
+
+       +
+
+       (post_processing ? get_post_process() : get_no_post_process())
+
+       +
+
+       R"shader(
+                               {
+                                       vec4 color = get_rgba_color();
+                                       if (chroma)
+                                               color = chroma_key(color);
+                                       if(levels)
+                                               color.rgb = LevelsControl(color.rgb, min_input, gamma, max_input, min_output, max_output);
+                                       if(csb)
+                                               color.rgb = ContrastSaturationBrightness(color.rgb, brt, sat, con);
+                                       if(has_local_key)
+                                               color *= texture2D(local_key, gl_TexCoord[1].st).r;
+                                       if(has_layer_key)
+                                               color *= texture2D(layer_key, gl_TexCoord[1].st).r;
+                                       color *= opacity;
+                                       color = blend(color);
+                                       gl_FragColor = color.bgra;
+                               }
                        }
        )shader";
 }
 
 std::shared_ptr<shader> get_image_shader(
-               const spl::shared_ptr<device>& ogl, bool& blend_modes, bool blend_modes_wanted)
+               const spl::shared_ptr<device>& ogl,
+               bool& blend_modes,
+               bool blend_modes_wanted,
+               bool& post_processing,
+               bool straight_alpha_wanted)
 {
        tbb::mutex::scoped_lock lock(g_shader_mutex);
        auto existing_shader = g_shader.lock();
@@ -320,6 +365,7 @@ std::shared_ptr<shader> get_image_shader(
        if(existing_shader)
        {
                blend_modes = g_blend_modes;
+               post_processing = g_post_processing;
                return existing_shader;
        }
 
@@ -341,7 +387,8 @@ std::shared_ptr<shader> get_image_shader(
        try
        {                               
                g_blend_modes  = glTextureBarrierNV ? blend_modes_wanted : false;
-               existing_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes)), deleter);
+               g_post_processing = straight_alpha_wanted;
+               existing_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes, g_post_processing)), deleter);
        }
        catch(...)
        {
@@ -349,9 +396,9 @@ std::shared_ptr<shader> get_image_shader(
                CASPAR_LOG(warning) << "Failed to compile shader. Trying to compile without blend-modes.";
                                
                g_blend_modes = false;
-               existing_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes)), deleter);
+               existing_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes, g_post_processing)), deleter);
        }
-                                               
+
        //if(!g_blend_modes)
        //{
        //      ogl.blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
@@ -360,6 +407,7 @@ std::shared_ptr<shader> get_image_shader(
 
 
        blend_modes = g_blend_modes;
+       post_processing = g_post_processing;
        g_shader = existing_shader;
        return existing_shader;
 }
index 87b9db2b16d2040308de8258eec182f1b02585bc..6782b00915276b536388a5733d8538c714c29eb5 100644 (file)
@@ -40,7 +40,10 @@ enum class texture_id
 };
 
 std::shared_ptr<shader> get_image_shader(
-               const spl::shared_ptr<device>& ogl, bool& blend_modes, bool blend_modes_wanted);
+               const spl::shared_ptr<device>& ogl,
+               bool& blend_modes,
+               bool blend_modes_wanted,
+               bool& post_processing,
+               bool straight_alpha_wanted);
 
-
-}}}
\ No newline at end of file
+}}}
index bd019d9721c941d794acbf79a8684add445acd06..316677bc55d6a04e5f1174cce4f5a4c88a2edd83 100644 (file)
@@ -59,7 +59,7 @@ public:
        virtual void visit(const class const_frame& frame) = 0;
        virtual void pop() = 0;
                
-       virtual std::future<array<const std::uint8_t>> operator()(const struct video_format_desc& format_desc) = 0;
+       virtual std::future<array<const std::uint8_t>> operator()(const struct video_format_desc& format_desc, bool straighten_alpha) = 0;
 
        virtual class mutable_frame create_frame(const void* tag, const struct pixel_format_desc& desc) = 0;
 
index 021d2c5ab76d238655a3d86aab116ac3bbe173dc..30061d5229a56240a7919c6368424577ee6f4a9d 100644 (file)
@@ -61,6 +61,8 @@ struct mixer::impl : boost::noncopyable
        spl::shared_ptr<monitor::subject>       monitor_subject_        = spl::make_shared<monitor::subject>("/mixer");
        audio_mixer                                                     audio_mixer_            { graph_ };
        spl::shared_ptr<image_mixer>            image_mixer_;
+
+       bool                                                            straighten_alpha_       = false;
                        
        executor                                                        executor_                       { L"mixer " + boost::lexical_cast<std::wstring>(channel_index_) };
 
@@ -94,7 +96,7 @@ public:
                                        frame.second.accept(*image_mixer_);
                                }
                                
-                               auto image = (*image_mixer_)(format_desc);
+                               auto image = (*image_mixer_)(format_desc, straighten_alpha_);
                                auto audio = audio_mixer_(format_desc);
 
                                auto desc = core::pixel_format_desc(core::pixel_format::bgra);
@@ -131,6 +133,22 @@ public:
                }, task_priority::high_priority);
        }
 
+       void set_straight_alpha_output(bool value)
+       {
+               executor_.begin_invoke([=]
+               {
+                       straighten_alpha_ = value;
+               }, task_priority::high_priority);
+       }
+
+       bool get_straight_alpha_output()
+       {
+               return executor_.invoke([=]
+               {
+                       return straighten_alpha_;
+               }, task_priority::high_priority);
+       }
+
        std::future<boost::property_tree::wptree> info() const
        {
                boost::property_tree::wptree info;
@@ -152,6 +170,8 @@ mixer::mixer(int channel_index, spl::shared_ptr<diagnostics::graph> graph, spl::
        : impl_(new impl(channel_index, std::move(graph), std::move(image_mixer))){}
 void mixer::set_master_volume(float volume) { impl_->set_master_volume(volume); }
 float mixer::get_master_volume() { return impl_->get_master_volume(); }
+void mixer::set_straight_alpha_output(bool value) { impl_->set_straight_alpha_output(value); }
+bool mixer::get_straight_alpha_output() { return impl_->get_straight_alpha_output(); }
 std::future<boost::property_tree::wptree> mixer::info() const{return impl_->info();}
 std::future<boost::property_tree::wptree> mixer::delay_info() const{ return impl_->delay_info(); }
 const_frame mixer::operator()(std::map<int, draw_frame> frames, const video_format_desc& format_desc){ return (*impl_)(std::move(frames), format_desc); }
index dbd23309239754f51393e6d086edabd8c88cb402..9b4b61283de18b645936d4d27560b7cd2ea45ad8 100644 (file)
@@ -57,6 +57,8 @@ public:
 
        void set_master_volume(float volume);
        float get_master_volume();
+       void set_straight_alpha_output(bool value);
+       bool get_straight_alpha_output();
 
        mutable_frame create_frame(const void* tag, const pixel_format_desc& desc);
 
index ef042f78834ea8026dab2c39814d90bc1a14ffc3..cabbf5c50d403ef9e47b0574a53cbf9bf1d67fe3 100644 (file)
@@ -1876,6 +1876,35 @@ std::wstring mixer_mastervolume_command(command_context& ctx)
        return L"202 MIXER OK\r\n";
 }
 
+void mixer_straight_alpha_describer(core::help_sink& sink, const core::help_repository& repo)
+{
+       sink.short_description(L"Turn straight alpha output on or off for a channel.");
+       sink.syntax(L"MIXER [video_channel:int] STRAIGHT_ALPHA_OUTPUT {[straight_alpha:0,1|0]}");
+       sink.para()->text(L"Turn straight alpha output on or off for the specified channel.");
+       sink.para()->code(L"casparcg.config")->text(L" needs to be configured to enable the feature.");
+       sink.para()->text(L"Examples:");
+       sink.example(L">> MIXER 1 STRAIGHT_ALPHA_OUTPUT 0");
+       sink.example(L">> MIXER 1 STRAIGHT_ALPHA_OUTPUT 1");
+       sink.example(
+                       L">> MIXER 1 STRAIGHT_ALPHA_OUTPUT\n"
+                       L"<< 201 MIXER OK\n"
+                       L"<< 1");
+}
+
+std::wstring mixer_straight_alpha_command(command_context& ctx)
+{
+       if (ctx.parameters.empty())
+       {
+               bool state = ctx.channel.channel->mixer().get_straight_alpha_output();
+               return L"201 MIXER OK\r\n" + boost::lexical_cast<std::wstring>(state) + L"\r\n";
+       }
+
+       bool state = boost::lexical_cast<bool>(ctx.parameters.at(0));
+       ctx.channel.channel->mixer().set_straight_alpha_output(state);
+
+       return L"202 MIXER OK\r\n";
+}
+
 void mixer_grid_describer(core::help_sink& sink, const core::help_repository& repo)
 {
        sink.short_description(L"Create a grid of video layers.");
@@ -2737,85 +2766,86 @@ std::wstring lock_command(command_context& ctx)
 
 void register_commands(amcp_command_repository& repo)
 {
-       repo.register_channel_command(  L"Basic Commands",              L"LOADBG",                                      loadbg_describer,                                       loadbg_command,                                 1);
-       repo.register_channel_command(  L"Basic Commands",              L"LOAD",                                        load_describer,                                         load_command,                                   1);
-       repo.register_channel_command(  L"Basic Commands",              L"PLAY",                                        play_describer,                                         play_command,                                   0);
-       repo.register_channel_command(  L"Basic Commands",              L"PAUSE",                                       pause_describer,                                        pause_command,                                  0);
-       repo.register_channel_command(  L"Basic Commands",              L"RESUME",                                      resume_describer,                                       resume_command,                                 0);
-       repo.register_channel_command(  L"Basic Commands",              L"STOP",                                        stop_describer,                                         stop_command,                                   0);
-       repo.register_channel_command(  L"Basic Commands",              L"CLEAR",                                       clear_describer,                                        clear_command,                                  0);
-       repo.register_channel_command(  L"Basic Commands",              L"CALL",                                        call_describer,                                         call_command,                                   1);
-       repo.register_channel_command(  L"Basic Commands",              L"SWAP",                                        swap_describer,                                         swap_command,                                   1);
-       repo.register_channel_command(  L"Basic Commands",              L"ADD",                                         add_describer,                                          add_command,                                    1);
-       repo.register_channel_command(  L"Basic Commands",              L"REMOVE",                                      remove_describer,                                       remove_command,                                 0);
-       repo.register_channel_command(  L"Basic Commands",              L"PRINT",                                       print_describer,                                        print_command,                                  0);
-       repo.register_command(                  L"Basic Commands",              L"LOG LEVEL",                           log_level_describer,                            log_level_command,                              1);
-       repo.register_channel_command(  L"Basic Commands",              L"SET",                                         set_describer,                                          set_command,                                    2);
-       repo.register_command(                  L"Basic Commands",              L"LOCK",                                        lock_describer,                                         lock_command,                                   2);
-
-       repo.register_command(                  L"Data Commands",               L"DATA STORE",                          data_store_describer,                           data_store_command,                             2);
-       repo.register_command(                  L"Data Commands",               L"DATA RETRIEVE",                       data_retrieve_describer,                        data_retrieve_command,                  1);
-       repo.register_command(                  L"Data Commands",               L"DATA LIST",                           data_list_describer,                            data_list_command,                              0);
-       repo.register_command(                  L"Data Commands",               L"DATA REMOVE",                         data_remove_describer,                          data_remove_command,                    1);
-
-       repo.register_channel_command(  L"Template Commands",   L"CG ADD",                                      cg_add_describer,                                       cg_add_command,                                 3);
-       repo.register_channel_command(  L"Template Commands",   L"CG PLAY",                                     cg_play_describer,                                      cg_play_command,                                1);
-       repo.register_channel_command(  L"Template Commands",   L"CG STOP",                                     cg_stop_describer,                                      cg_stop_command,                                1);
-       repo.register_channel_command(  L"Template Commands",   L"CG NEXT",                                     cg_next_describer,                                      cg_next_command,                                1);
-       repo.register_channel_command(  L"Template Commands",   L"CG REMOVE",                           cg_remove_describer,                            cg_remove_command,                              1);
-       repo.register_channel_command(  L"Template Commands",   L"CG CLEAR",                            cg_clear_describer,                                     cg_clear_command,                               0);
-       repo.register_channel_command(  L"Template Commands",   L"CG UPDATE",                           cg_update_describer,                            cg_update_command,                              2);
-       repo.register_channel_command(  L"Template Commands",   L"CG INVOKE",                           cg_invoke_describer,                            cg_invoke_command,                              2);
-       repo.register_channel_command(  L"Template Commands",   L"CG INFO",                                     cg_info_describer,                                      cg_info_command,                                0);
-
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER KEYER",                         mixer_keyer_describer,                          mixer_keyer_command,                    0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CHROMA",                        mixer_chroma_describer,                         mixer_chroma_command,                   0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER BLEND",                         mixer_blend_describer,                          mixer_blend_command,                    0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER OPACITY",                       mixer_opacity_describer,                        mixer_opacity_command,                  0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER BRIGHTNESS",            mixer_brightness_describer,                     mixer_brightness_command,               0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER SATURATION",            mixer_saturation_describer,                     mixer_saturation_command,               0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CONTRAST",                      mixer_contrast_describer,                       mixer_contrast_command,                 0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER LEVELS",                        mixer_levels_describer,                         mixer_levels_command,                   0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER FILL",                          mixer_fill_describer,                           mixer_fill_command,                             0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CLIP",                          mixer_clip_describer,                           mixer_clip_command,                             0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER ANCHOR",                        mixer_anchor_describer,                         mixer_anchor_command,                   0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CROP",                          mixer_crop_describer,                           mixer_crop_command,                             0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER ROTATION",                      mixer_rotation_describer,                       mixer_rotation_command,                 0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER PERSPECTIVE",           mixer_perspective_describer,            mixer_perspective_command,              0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER MIPMAP",                        mixer_mipmap_describer,                         mixer_mipmap_command,                   0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER VOLUME",                        mixer_volume_describer,                         mixer_volume_command,                   0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER MASTERVOLUME",          mixer_mastervolume_describer,           mixer_mastervolume_command,             0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER GRID",                          mixer_grid_describer,                           mixer_grid_command,                             1);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER COMMIT",                        mixer_commit_describer,                         mixer_commit_command,                   0);
-       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CLEAR",                         mixer_clear_describer,                          mixer_clear_command,                    0);
-       repo.register_command(                  L"Mixer Commands",              L"CHANNEL_GRID",                        channel_grid_describer,                         channel_grid_command,                   0);
-
-       repo.register_command(                  L"Thumbnail Commands",  L"THUMBNAIL LIST",                      thumbnail_list_describer,                       thumbnail_list_command,                 0);
-       repo.register_command(                  L"Thumbnail Commands",  L"THUMBNAIL RETRIEVE",          thumbnail_retrieve_describer,           thumbnail_retrieve_command,             1);
-       repo.register_command(                  L"Thumbnail Commands",  L"THUMBNAIL GENERATE",          thumbnail_generate_describer,           thumbnail_generate_command,             1);
-       repo.register_command(                  L"Thumbnail Commands",  L"THUMBNAIL GENERATE_ALL",      thumbnail_generateall_describer,        thumbnail_generateall_command,  0);
-
-       repo.register_command(                  L"Query Commands",              L"CINF",                                        cinf_describer,                                         cinf_command,                                   1);
-       repo.register_command(                  L"Query Commands",              L"CLS",                                         cls_describer,                                          cls_command,                                    0);
-       repo.register_command(                  L"Query Commands",              L"TLS",                                         tls_describer,                                          tls_command,                                    0);
-       repo.register_command(                  L"Query Commands",              L"VERSION",                                     version_describer,                                      version_command,                                0);
-       repo.register_command(                  L"Query Commands",              L"INFO",                                        info_describer,                                         info_command,                                   0);
-       repo.register_channel_command(  L"Query Commands",              L"INFO",                                        info_channel_describer,                         info_channel_command,                   0);
-       repo.register_command(                  L"Query Commands",              L"INFO TEMPLATE",                       info_template_describer,                        info_template_command,                  1);
-       repo.register_command(                  L"Query Commands",              L"INFO CONFIG",                         info_config_describer,                          info_config_command,                    0);
-       repo.register_command(                  L"Query Commands",              L"INFO PATHS",                          info_paths_describer,                           info_paths_command,                             0);
-       repo.register_command(                  L"Query Commands",              L"INFO SYSTEM",                         info_system_describer,                          info_system_command,                    0);
-       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);
-       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);
+       repo.register_channel_command(  L"Basic Commands",              L"LOADBG",                                              loadbg_describer,                                       loadbg_command,                                 1);
+       repo.register_channel_command(  L"Basic Commands",              L"LOAD",                                                load_describer,                                         load_command,                                   1);
+       repo.register_channel_command(  L"Basic Commands",              L"PLAY",                                                play_describer,                                         play_command,                                   0);
+       repo.register_channel_command(  L"Basic Commands",              L"PAUSE",                                               pause_describer,                                        pause_command,                                  0);
+       repo.register_channel_command(  L"Basic Commands",              L"RESUME",                                              resume_describer,                                       resume_command,                                 0);
+       repo.register_channel_command(  L"Basic Commands",              L"STOP",                                                stop_describer,                                         stop_command,                                   0);
+       repo.register_channel_command(  L"Basic Commands",              L"CLEAR",                                               clear_describer,                                        clear_command,                                  0);
+       repo.register_channel_command(  L"Basic Commands",              L"CALL",                                                call_describer,                                         call_command,                                   1);
+       repo.register_channel_command(  L"Basic Commands",              L"SWAP",                                                swap_describer,                                         swap_command,                                   1);
+       repo.register_channel_command(  L"Basic Commands",              L"ADD",                                                 add_describer,                                          add_command,                                    1);
+       repo.register_channel_command(  L"Basic Commands",              L"REMOVE",                                              remove_describer,                                       remove_command,                                 0);
+       repo.register_channel_command(  L"Basic Commands",              L"PRINT",                                               print_describer,                                        print_command,                                  0);
+       repo.register_command(                  L"Basic Commands",              L"LOG LEVEL",                                   log_level_describer,                            log_level_command,                              1);
+       repo.register_channel_command(  L"Basic Commands",              L"SET",                                                 set_describer,                                          set_command,                                    2);
+       repo.register_command(                  L"Basic Commands",              L"LOCK",                                                lock_describer,                                         lock_command,                                   2);
+
+       repo.register_command(                  L"Data Commands",               L"DATA STORE",                                  data_store_describer,                           data_store_command,                             2);
+       repo.register_command(                  L"Data Commands",               L"DATA RETRIEVE",                               data_retrieve_describer,                        data_retrieve_command,                  1);
+       repo.register_command(                  L"Data Commands",               L"DATA LIST",                                   data_list_describer,                            data_list_command,                              0);
+       repo.register_command(                  L"Data Commands",               L"DATA REMOVE",                                 data_remove_describer,                          data_remove_command,                    1);
+
+       repo.register_channel_command(  L"Template Commands",   L"CG ADD",                                              cg_add_describer,                                       cg_add_command,                                 3);
+       repo.register_channel_command(  L"Template Commands",   L"CG PLAY",                                             cg_play_describer,                                      cg_play_command,                                1);
+       repo.register_channel_command(  L"Template Commands",   L"CG STOP",                                             cg_stop_describer,                                      cg_stop_command,                                1);
+       repo.register_channel_command(  L"Template Commands",   L"CG NEXT",                                             cg_next_describer,                                      cg_next_command,                                1);
+       repo.register_channel_command(  L"Template Commands",   L"CG REMOVE",                                   cg_remove_describer,                            cg_remove_command,                              1);
+       repo.register_channel_command(  L"Template Commands",   L"CG CLEAR",                                    cg_clear_describer,                                     cg_clear_command,                               0);
+       repo.register_channel_command(  L"Template Commands",   L"CG UPDATE",                                   cg_update_describer,                            cg_update_command,                              2);
+       repo.register_channel_command(  L"Template Commands",   L"CG INVOKE",                                   cg_invoke_describer,                            cg_invoke_command,                              2);
+       repo.register_channel_command(  L"Template Commands",   L"CG INFO",                                             cg_info_describer,                                      cg_info_command,                                0);
+
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER KEYER",                                 mixer_keyer_describer,                          mixer_keyer_command,                    0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CHROMA",                                mixer_chroma_describer,                         mixer_chroma_command,                   0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER BLEND",                                 mixer_blend_describer,                          mixer_blend_command,                    0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER OPACITY",                               mixer_opacity_describer,                        mixer_opacity_command,                  0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER BRIGHTNESS",                    mixer_brightness_describer,                     mixer_brightness_command,               0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER SATURATION",                    mixer_saturation_describer,                     mixer_saturation_command,               0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CONTRAST",                              mixer_contrast_describer,                       mixer_contrast_command,                 0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER LEVELS",                                mixer_levels_describer,                         mixer_levels_command,                   0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER FILL",                                  mixer_fill_describer,                           mixer_fill_command,                             0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CLIP",                                  mixer_clip_describer,                           mixer_clip_command,                             0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER ANCHOR",                                mixer_anchor_describer,                         mixer_anchor_command,                   0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CROP",                                  mixer_crop_describer,                           mixer_crop_command,                             0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER ROTATION",                              mixer_rotation_describer,                       mixer_rotation_command,                 0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER PERSPECTIVE",                   mixer_perspective_describer,            mixer_perspective_command,              0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER MIPMAP",                                mixer_mipmap_describer,                         mixer_mipmap_command,                   0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER VOLUME",                                mixer_volume_describer,                         mixer_volume_command,                   0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER MASTERVOLUME",                  mixer_mastervolume_describer,           mixer_mastervolume_command,             0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER STRAIGHT_ALPHA_OUTPUT", mixer_straight_alpha_describer,         mixer_straight_alpha_command,   0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER GRID",                                  mixer_grid_describer,                           mixer_grid_command,                             1);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER COMMIT",                                mixer_commit_describer,                         mixer_commit_command,                   0);
+       repo.register_channel_command(  L"Mixer Commands",              L"MIXER CLEAR",                                 mixer_clear_describer,                          mixer_clear_command,                    0);
+       repo.register_command(                  L"Mixer Commands",              L"CHANNEL_GRID",                                channel_grid_describer,                         channel_grid_command,                   0);
+
+       repo.register_command(                  L"Thumbnail Commands",  L"THUMBNAIL LIST",                              thumbnail_list_describer,                       thumbnail_list_command,                 0);
+       repo.register_command(                  L"Thumbnail Commands",  L"THUMBNAIL RETRIEVE",                  thumbnail_retrieve_describer,           thumbnail_retrieve_command,             1);
+       repo.register_command(                  L"Thumbnail Commands",  L"THUMBNAIL GENERATE",                  thumbnail_generate_describer,           thumbnail_generate_command,             1);
+       repo.register_command(                  L"Thumbnail Commands",  L"THUMBNAIL GENERATE_ALL",              thumbnail_generateall_describer,        thumbnail_generateall_command,  0);
+
+       repo.register_command(                  L"Query Commands",              L"CINF",                                                cinf_describer,                                         cinf_command,                                   1);
+       repo.register_command(                  L"Query Commands",              L"CLS",                                                 cls_describer,                                          cls_command,                                    0);
+       repo.register_command(                  L"Query Commands",              L"TLS",                                                 tls_describer,                                          tls_command,                                    0);
+       repo.register_command(                  L"Query Commands",              L"VERSION",                                             version_describer,                                      version_command,                                0);
+       repo.register_command(                  L"Query Commands",              L"INFO",                                                info_describer,                                         info_command,                                   0);
+       repo.register_channel_command(  L"Query Commands",              L"INFO",                                                info_channel_describer,                         info_channel_command,                   0);
+       repo.register_command(                  L"Query Commands",              L"INFO TEMPLATE",                               info_template_describer,                        info_template_command,                  1);
+       repo.register_command(                  L"Query Commands",              L"INFO CONFIG",                                 info_config_describer,                          info_config_command,                    0);
+       repo.register_command(                  L"Query Commands",              L"INFO PATHS",                                  info_paths_describer,                           info_paths_command,                             0);
+       repo.register_command(                  L"Query Commands",              L"INFO SYSTEM",                                 info_system_describer,                          info_system_command,                    0);
+       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);
+       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
index ffceab1df2b0687ba083057a8ec0b97c083bde6d..f03f0b761c50273d8091c15bfaec23a77b6cc94f 100644 (file)
@@ -39,6 +39,7 @@
 <mixer>\r
     <blend-modes>          false [true|false]</blend-modes>\r
     <mipmapping_default_on>false [true|false]</mipmapping_default_on>\r
+    <straight-alpha>       false [true|false]</straight-alpha>\r
 </mixer>\r
 <auto-transcode>      true  [true|false]</auto-transcode>\r
 <accelerator>auto [cpu|gpu|auto]</accelerator>\r
@@ -65,7 +66,8 @@
 </thumbnails>\r
 <channels>\r
     <channel>\r
-        <video-mode> PAL [PAL|NTSC|576p2500|720p2398|720p2400|720p2500|720p5000|720p2997|720p5994|720p3000|720p6000|1080p2398|1080p2400|1080i5000|1080i5994|1080i6000|1080p2500|1080p2997|1080p3000|1080p5000|1080p5994|1080p6000|1556p2398|1556p2400|1556p2500|dci1080p2398|dci1080p2400|dci1080p2500|2160p2398|2160p2400|2160p2500|2160p2997|2160p3000|dci2160p2398|dci2160p2400|dci2160p2500] </video-mode>\r
+        <video-mode>PAL [PAL|NTSC|576p2500|720p2398|720p2400|720p2500|720p5000|720p2997|720p5994|720p3000|720p6000|1080p2398|1080p2400|1080i5000|1080i5994|1080i6000|1080p2500|1080p2997|1080p3000|1080p5000|1080p5994|1080p6000|1556p2398|1556p2400|1556p2500|dci1080p2398|dci1080p2400|dci1080p2500|2160p2398|2160p2400|2160p2500|2160p2997|2160p3000|dci2160p2398|dci2160p2400|dci2160p2500] </video-mode>\r
+        <straight-alpha-output>false [true|false]</straight-alpha-output>\r
         <consumers>\r
             <decklink>\r
                 <device>[1..]</device>\r
index ecc3add8547f757d2c5ac57516c5a13635fc1c30..2620f534aad086ba816a8028fb47ab02dcc4826b 100644 (file)
@@ -40,6 +40,7 @@
 #include <core/producer/scene/xml_scene_producer.h>
 #include <core/producer/text/text_producer.h>
 #include <core/consumer/output.h>
+#include <core/mixer/mixer.h>
 #include <core/thumbnail_generator.h>
 #include <core/producer/media_info/media_info.h>
 #include <core/producer/media_info/media_info_repository.h>
@@ -237,6 +238,7 @@ struct server::impl : boost::noncopyable
                        }               
 
                    channel->monitor_output().attach_parent(monitor_subject_);
+                       channel->mixer().set_straight_alpha_output(xml_channel.second.get(L"straight-alpha-output", false));
                        channels_.push_back(channel);
                }