]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Fixed IS_KEY support. KEY_DEPTH will have to wait.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 16 May 2011 23:57:32 +0000 (23:57 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 16 May 2011 23:57:32 +0000 (23:57 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@762 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/mixer/frame_mixer_device.cpp
core/mixer/image/image_kernel.cpp
core/mixer/image/image_mixer.cpp
core/mixer/image/image_mixer.h
protocol/amcp/AMCPCommandsImpl.cpp
shell/caspar.config

index 9c7dca934db27f511984b0970cddb2431fb57c88..150c0a9a17c73c6a2ecb6a05f4976037c46d16ef 100644 (file)
@@ -134,7 +134,6 @@ public:
                auto& root_image_transform = boost::fusion::at_key<core::image_transform>(root_transforms_);\r
                auto& image_transforms = boost::fusion::at_key<core::image_transform>(transforms_);\r
 \r
-               auto image = image_mixer_.begin_pass();\r
                BOOST_FOREACH(auto& frame, frames)\r
                {\r
                        if(format_desc_.mode != core::video_mode::progressive)\r
@@ -157,8 +156,8 @@ public:
                                frame1->accept(image_mixer_);\r
                        }\r
                }\r
-               image_mixer_.end_pass();\r
-               return std::move(image);\r
+\r
+               return image_mixer_.render();\r
        }\r
 \r
        std::vector<short> mix_audio(const std::map<int, safe_ptr<core::basic_frame>>& frames)\r
index b207d28797c258a25299527065687f8eff53210f..c3d3e709553fb5bc164d1442959b2b1e4db853a3 100644 (file)
@@ -169,6 +169,7 @@ public:
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
                        "       gl_TexCoord[0] = gl_MultiTexCoord0;                                                                     "\r
+                       "       gl_TexCoord[1] = gl_MultiTexCoord1;                                                                     "\r
                        "       gl_FrontColor = gl_Color;                                                                                       "\r
                        "       gl_Position = ftransform();                                                                                     "\r
                        "}                                                                                                                                              ";\r
@@ -219,7 +220,7 @@ public:
                        "{                                                                                                                                              "\r
                        "       vec4 rgba = vec4(texture2D(plane[0], gl_TexCoord[0].st).rrr, 1.0);      "\r
                        "       if(has_separate_key)                                                                                            "\r
-                       "               rgba.a = texture2D(plane[3], gl_TexCoord[0].st).r;                              "\r
+                       "               rgba.a = texture2D(plane[3], gl_TexCoord[1].st).r;                              "\r
                        "       gl_FragColor = rgba * gain;                                                                                     "\r
                        "}                                                                                                                                              ");\r
 \r
@@ -229,7 +230,7 @@ public:
                        "{                                                                                                                                              "\r
                        "       vec4 abgr = texture2D(plane[0], gl_TexCoord[0].st);                                     "\r
                        "       if(has_separate_key)                                                                                            "\r
-                       "               abgr.b = texture2D(plane[3], gl_TexCoord[0].st).r;                              "\r
+                       "               abgr.b = texture2D(plane[3], gl_TexCoord[1].st).r;                              "\r
                        "       gl_FragColor = abgr.argb * gain;                                                                        "\r
                        "}                                                                                                                                              ");\r
                \r
@@ -239,7 +240,7 @@ public:
                        "{                                                                                                                                              "\r
                        "       vec4 argb = texture2D(plane[0], gl_TexCoord[0].st);                                     "\r
                        "       if(has_separate_key)                                                                                            "\r
-                       "               argb.b = texture2D(plane[3], gl_TexCoord[0].st).r;                              "\r
+                       "               argb.b = texture2D(plane[3], gl_TexCoord[1].st).r;                              "\r
                        "       gl_FragColor = argb.grab * gl_Color * gain;                                                     "\r
                        "}                                                                                                                                              ");\r
                \r
@@ -249,7 +250,7 @@ public:
                        "{                                                                                                                                              "\r
                        "       vec4 bgra = texture2D(plane[0], gl_TexCoord[0].st);                                     "\r
                        "       if(has_separate_key)                                                                                            "\r
-                       "               bgra.a = texture2D(plane[3], gl_TexCoord[0].st).r;                              "\r
+                       "               bgra.a = texture2D(plane[3], gl_TexCoord[1].st).r;                              "\r
                        "       gl_FragColor = bgra.rgba * gl_Color * gain;                                                     "\r
                        "}                                                                                                                                              ");\r
                \r
@@ -259,7 +260,7 @@ public:
                        "{                                                                                                                                              "\r
                        "       vec4 rgba = texture2D(plane[0], gl_TexCoord[0].st);                                     "\r
                        "       if(has_separate_key)                                                                                            "\r
-                       "               rgba.a = texture2D(plane[3], gl_TexCoord[0].st).r;                              "\r
+                       "               rgba.a = texture2D(plane[3], gl_TexCoord[1].st).r;                              "\r
                        "       gl_FragColor = rgba.bgra * gl_Color * gain;                                                     "\r
                        "}                                                                                                                                              ");\r
                \r
@@ -272,7 +273,7 @@ public:
                        "       float cr = texture2D(plane[2], gl_TexCoord[0].st).r;                            "\r
                        "       float a = 1.0;                                                                                                          "       \r
                        "       if(has_separate_key)                                                                                            "\r
-                       "               a = texture2D(plane[3], gl_TexCoord[0].st).r;                                   "\r
+                       "               a = texture2D(plane[3], gl_TexCoord[1].st).r;                                   "\r
                        "       if(HD)                                                                                                                          "\r
                        "               gl_FragColor = ycbcra_to_bgra_hd(y, cb, cr, a) * gl_Color * gain;"\r
                        "       else                                                                                                                            "\r
index 660903063d923d5bded5ecfb060efcbd9c6223bd..2fd86da696ae4d1b1fe17ef081edaa17dcdf0d50 100644 (file)
@@ -35,7 +35,7 @@
 #include <core/producer/frame/pixel_format.h>\r
 #include <core/video_format.h>\r
 \r
-#include <boost/cast.hpp>\r
+#include <boost/foreach.hpp>\r
 \r
 #include <Glee.h>\r
 #include <SFML/Window/Context.hpp>\r
@@ -53,15 +53,26 @@ struct image_mixer::implementation : boost::noncopyable
 \r
        GLuint fbo_;\r
        std::array<std::shared_ptr<device_buffer>, 2> render_targets_;\r
+       std::shared_ptr<device_buffer> key_target_;\r
+       bool is_key_;\r
 \r
        std::shared_ptr<host_buffer> reading_;\r
 \r
        image_kernel kernel_;\r
 \r
-       std::shared_ptr<device_buffer> key_;\r
+       struct render_item\r
+       {\r
+               core::pixel_format_desc desc;\r
+               std::vector<safe_ptr<host_buffer>> buffers;\r
+               core::image_transform transform;\r
+       };\r
+\r
+       std::vector<render_item> render_queue_;\r
+\r
 public:\r
        implementation(const core::video_format_desc& format_desc) \r
                : format_desc_(format_desc)\r
+               , is_key_(false)\r
        {\r
                ogl_device::invoke([]\r
                {\r
@@ -76,7 +87,8 @@ public:
 \r
                        GL(glEnable(GL_TEXTURE_2D));\r
                        GL(glDisable(GL_DEPTH_TEST));           \r
-\r
+                       \r
+                       key_target_ = ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4);\r
                        render_targets_[0] = ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4);\r
                        render_targets_[1] = ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4);\r
                        \r
@@ -99,67 +111,18 @@ public:
        }\r
                \r
        void visit(core::write_frame& frame)\r
-       {\r
-               auto gpu_frame = boost::polymorphic_downcast<gpu_write_frame*>(&frame);\r
-               auto desc = gpu_frame->get_pixel_format_desc();\r
-               auto buffers = gpu_frame->get_plane_buffers();\r
+       {               \r
+               auto gpu_frame = dynamic_cast<gpu_write_frame*>(&frame);\r
+               if(!gpu_frame)\r
+                       return;\r
 \r
-               auto transform = transform_stack_.top();\r
-               ogl_device::begin_invoke([=]\r
-               {\r
-                       std::vector<safe_ptr<device_buffer>> device_buffers;\r
-                       for(size_t n = 0; n < buffers.size(); ++n)\r
-                       {\r
-                               auto texture = ogl_device::create_device_buffer(desc.planes[n].width, desc.planes[n].height, desc.planes[n].channels);\r
-                               texture->read(*buffers[n]);\r
-                               device_buffers.push_back(texture);\r
-                       }\r
-                                               \r
-                       if(transform.get_is_key()) // Its a key_frame just save buffer for next frame.\r
-                       {\r
-                               if(!device_buffers.empty())                             \r
-                                       key_ = device_buffers[0];                               \r
-                       }\r
-                       else\r
-                       {\r
-                               for(size_t n = 0; n < buffers.size(); ++n)\r
-                               {\r
-                                       GL(glActiveTexture(GL_TEXTURE0+n));\r
-                                       device_buffers[n]->bind();\r
-                               }\r
-                                               \r
-                               if(key_)\r
-                               {\r
-                                       GL(glActiveTexture(GL_TEXTURE0+3));\r
-                                       key_->bind();\r
-                               }\r
-\r
-                               GL(glColor4d(1.0, 1.0, 1.0, transform.get_opacity()));\r
-                               GL(glViewport(0, 0, format_desc_.width, format_desc_.height));\r
-                               kernel_.apply(desc, transform, key_ != nullptr);\r
-                                               \r
-                               auto m_p = transform.get_key_translation();\r
-                               auto m_s = transform.get_key_scale();\r
-                               double w = static_cast<double>(format_desc_.width);\r
-                               double h = static_cast<double>(format_desc_.height);\r
-                       \r
-                               GL(glEnable(GL_SCISSOR_TEST));\r
-                               GL(glScissor(static_cast<size_t>(m_p[0]*w), static_cast<size_t>(m_p[1]*h), static_cast<size_t>(m_s[0]*w), static_cast<size_t>(m_s[1]*h)));\r
-                       \r
-                               auto f_p = transform.get_fill_translation();\r
-                               auto f_s = transform.get_fill_scale();\r
-                       \r
-                               glBegin(GL_QUADS);\r
-                                       glTexCoord2d(0.0, 0.0); glVertex2d( f_p[0]        *2.0-1.0,      f_p[1]        *2.0-1.0);\r
-                                       glTexCoord2d(1.0, 0.0); glVertex2d((f_p[0]+f_s[0])*2.0-1.0,  f_p[1]        *2.0-1.0);\r
-                                       glTexCoord2d(1.0, 1.0); glVertex2d((f_p[0]+f_s[0])*2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
-                                       glTexCoord2d(0.0, 1.0); glVertex2d( f_p[0]        *2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
-                               glEnd();\r
-                               GL(glDisable(GL_SCISSOR_TEST));         \r
-\r
-                               key_ = nullptr;         \r
-                       }\r
-               });\r
+               render_item item;\r
+\r
+               item.desc = gpu_frame->get_pixel_format_desc();\r
+               item.buffers = gpu_frame->get_plane_buffers();\r
+               item.transform = transform_stack_.top();\r
+\r
+               render_queue_.push_back(item);\r
        }\r
 \r
        void end()\r
@@ -167,27 +130,103 @@ public:
                transform_stack_.pop();\r
        }\r
 \r
-       boost::unique_future<safe_ptr<const host_buffer>> begin_pass()\r
+       boost::unique_future<safe_ptr<const host_buffer>> render()\r
        {\r
+               auto queue = render_queue_;\r
+               render_queue_.clear();\r
                return ogl_device::begin_invoke([=]() -> safe_ptr<const host_buffer>\r
                {\r
-                       reading_->map();\r
-                       render_targets_[0]->attach(0);\r
+                       is_key_ = false;\r
+                       key_target_->attach();\r
+                       GL(glClear(GL_COLOR_BUFFER_BIT));       \r
+\r
+                       // START_PASS\r
+                       auto result = reading_;\r
+                       result->map();\r
+                       render_targets_[0]->attach();\r
                        GL(glClear(GL_COLOR_BUFFER_BIT));\r
-                       return safe_ptr<const host_buffer>(reading_);\r
-               });\r
-       }\r
 \r
-       void end_pass()\r
-       {\r
-               ogl_device::begin_invoke([=]\r
-               {\r
+                       BOOST_FOREACH(auto item, queue)\r
+                               render(item);                   \r
+\r
+                       // END PASS\r
                        reading_ = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only);\r
+                       render_targets_[0]->attach();\r
                        render_targets_[0]->write(*reading_);\r
                        std::rotate(render_targets_.begin(), render_targets_.begin() + 1, render_targets_.end());\r
+\r
+                       return make_safe(result);\r
                });\r
        }\r
-               \r
+\r
+       void render(const render_item& item)\r
+       {               \r
+               const auto desc          = item.desc;\r
+               auto       buffers       = item.buffers;\r
+               const auto transform = item.transform;\r
+                               \r
+               // Setup key and kernel\r
+\r
+               if(transform.get_is_key())\r
+               {\r
+                       kernel_.apply(desc, transform, false);\r
+                       if(!is_key_)\r
+                       {\r
+                               key_target_->attach();\r
+                               is_key_ = true;\r
+                               GL(glClear(GL_COLOR_BUFFER_BIT));               \r
+                       }\r
+               }               \r
+               else\r
+               {                                               \r
+                       kernel_.apply(desc, transform, is_key_);        \r
+                       if(is_key_)\r
+                       {\r
+                               if(buffers.size() == 4)\r
+                                       buffers.pop_back();\r
+                               is_key_ = false;\r
+\r
+                               render_targets_[0]->attach();                   \r
+                               GL(glActiveTexture(GL_TEXTURE0+3));\r
+                               key_target_->bind();\r
+                       }       \r
+               }       \r
+\r
+               // Bind textures\r
+\r
+               std::vector<safe_ptr<device_buffer>> textures;\r
+               for(size_t n = 0; n < buffers.size(); ++n)\r
+               {\r
+                       GL(glActiveTexture(GL_TEXTURE0+n));\r
+                       auto texture = ogl_device::create_device_buffer(desc.planes[n].width, desc.planes[n].height, desc.planes[n].channels);\r
+                       texture->read(*buffers[n]);\r
+                       texture->bind();\r
+                       textures.push_back(texture);\r
+               }                       \r
+\r
+               GL(glColor4d(1.0, 1.0, 1.0, transform.get_opacity()));\r
+               GL(glViewport(0, 0, format_desc_.width, format_desc_.height));\r
+                                               \r
+               auto m_p = transform.get_key_translation();\r
+               auto m_s = transform.get_key_scale();\r
+               double w = static_cast<double>(format_desc_.width);\r
+               double h = static_cast<double>(format_desc_.height);\r
+\r
+               GL(glEnable(GL_SCISSOR_TEST));\r
+               GL(glScissor(static_cast<size_t>(m_p[0]*w), static_cast<size_t>(m_p[1]*h), static_cast<size_t>(m_s[0]*w), static_cast<size_t>(m_s[1]*h)));\r
+                       \r
+               auto f_p = transform.get_fill_translation();\r
+               auto f_s = transform.get_fill_scale();\r
+                       \r
+               glBegin(GL_QUADS);\r
+                       glMultiTexCoord2d(GL_TEXTURE0, 0.0, 0.0); glMultiTexCoord2d(GL_TEXTURE1,  f_p[0]        ,  f_p[1]        );             glVertex2d( f_p[0]        *2.0-1.0,  f_p[1]        *2.0-1.0);\r
+                       glMultiTexCoord2d(GL_TEXTURE0, 1.0, 0.0); glMultiTexCoord2d(GL_TEXTURE1, (f_p[0]+f_s[0]),  f_p[1]        );             glVertex2d((f_p[0]+f_s[0])*2.0-1.0,  f_p[1]        *2.0-1.0);\r
+                       glMultiTexCoord2d(GL_TEXTURE0, 1.0, 1.0); glMultiTexCoord2d(GL_TEXTURE1, (f_p[0]+f_s[0]), (f_p[1]+f_s[1]));             glVertex2d((f_p[0]+f_s[0])*2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
+                       glMultiTexCoord2d(GL_TEXTURE0, 0.0, 1.0); glMultiTexCoord2d(GL_TEXTURE1,  f_p[0]        , (f_p[1]+f_s[1]));             glVertex2d( f_p[0]        *2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
+               glEnd();\r
+               GL(glDisable(GL_SCISSOR_TEST));         \r
+       }\r
+                       \r
        std::vector<safe_ptr<host_buffer>> create_buffers(const core::pixel_format_desc& format)\r
        {\r
                std::vector<safe_ptr<host_buffer>> buffers;\r
@@ -203,8 +242,7 @@ image_mixer::image_mixer(const core::video_format_desc& format_desc) : impl_(new
 void image_mixer::begin(const core::basic_frame& frame){impl_->begin(frame);}\r
 void image_mixer::visit(core::write_frame& frame){impl_->visit(frame);}\r
 void image_mixer::end(){impl_->end();}\r
-boost::unique_future<safe_ptr<const host_buffer>> image_mixer::begin_pass(){   return impl_->begin_pass();}\r
-void image_mixer::end_pass(){impl_->end_pass();}\r
+boost::unique_future<safe_ptr<const host_buffer>> image_mixer::render(){return impl_->render();}\r
 std::vector<safe_ptr<host_buffer>> image_mixer::create_buffers(const core::pixel_format_desc& format){return impl_->create_buffers(format);}\r
 \r
 }}
\ No newline at end of file
index c0350fb62bd24201d2eac20df05ca41db2f62b61..263963bb086faaf26f3bc0eced4d903542330b22 100644 (file)
@@ -41,9 +41,8 @@ public:
        virtual void begin(const core::basic_frame& frame);\r
        virtual void visit(core::write_frame& frame);\r
        virtual void end();\r
-\r
-       boost::unique_future<safe_ptr<const host_buffer>> begin_pass();\r
-       void end_pass();\r
+       \r
+       boost::unique_future<safe_ptr<const host_buffer>> render();\r
 \r
        std::vector<safe_ptr<host_buffer>> create_buffers(const core::pixel_format_desc& format);\r
 \r
index 2c5c402915149481ac2758004f5e03980441411a..d6620ffb015837fba398de7a070cd33b79e51d50 100644 (file)
@@ -204,18 +204,18 @@ bool MixerCommand::DoExecute()
                {\r
                        if(_parameters[1] == L"IS_KEY")\r
                        {\r
-                               //bool value = lexical_cast_or_default(_parameters.at(2), false);\r
-                               //auto transform = [=](image_transform transform) -> image_transform\r
-                               //{\r
-                               //      transform.set_is_key(value);\r
-                               //      return transform;                                       \r
-                               //};\r
-\r
-                               //int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
-                               //if(layer != std::numeric_limits<int>::min())                                  \r
-                               //      GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, 0);\r
-                               //else\r
-                               //      GetChannel()->mixer()->apply_image_transform(transform, 0);\r
+                               bool value = lexical_cast_or_default(_parameters.at(2), false);\r
+                               auto transform = [=](image_transform transform) -> image_transform\r
+                               {\r
+                                       transform.set_is_key(value);\r
+                                       return transform;                                       \r
+                               };\r
+\r
+                               int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
+                               if(layer != std::numeric_limits<int>::min())                                    \r
+                                       GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, 0);\r
+                               else\r
+                                       GetChannel()->mixer()->apply_image_transform(transform, 0);\r
                        }\r
                        else if(_parameters[1] == L"OPACITY")\r
                        {\r
index d17c7a3d526f87c02cdb312a6bbb62f2d253d355..f4ddba67237697837d4437e51c9fac7b2d13cddb 100644 (file)
@@ -19,7 +19,7 @@
           <embedded-audio>true</embedded-audio>\r
           <latency>low</latency>\r
           <key>external</key>\r
-          <output>key_only</output>\r
+          <output>key_and_fill</output>\r
         </decklink>\r
         <ogl>\r
           <device>1</device>\r