]> git.sesse.net Git - casparcg/commitdiff
2.0. - core/ffmpeg: Fixed async producer processing.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 8 Aug 2011 10:20:05 +0000 (10:20 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 8 Aug 2011 10:20:05 +0000 (10:20 +0000)
     - image_mixer: Fixed scissors bug.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1088 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

common/gl/gl_check.h
core/mixer/image/image_kernel.cpp
core/mixer/mixer.cpp
core/producer/layer.cpp
core/producer/layer.h
core/producer/separated/separated_producer.cpp
core/producer/stage.cpp
core/producer/transition/transition_producer.cpp

index fe573e42f0772cd412c46bfc763286d2736a5cc5..4750309b76343cbb15e263bb1b29032785dc66b9 100644 (file)
@@ -44,11 +44,11 @@ void SMFL_GLCheckError(const std::string& expr, const std::string& File, unsigne
 #define CASPAR_GL_EXPR_STR(expr) #expr\r
 \r
 #define GL(expr) \\r
-       do \\r
+       [&] \\r
        { \\r
                (expr);  \\r
                caspar::gl::SMFL_GLCheckError(CASPAR_GL_EXPR_STR(expr), __FILE__, __LINE__);\\r
-       }while(0);\r
+       }()\r
 \r
 #define GL2(expr) \\r
        [&]() -> decltype(expr)\\r
index e3017120d5c5c950a645faba4c965a87966efd1c..2dc7c01f51f72f76707d92b540c75c9798ce8147 100644 (file)
@@ -55,8 +55,15 @@ struct image_kernel::implementation : boost::noncopyable
 \r
        std::string vertex_;\r
        std::string fragment_;\r
+\r
+       core::video_mode::type  last_mode_;\r
+       size_t                                  last_width_;\r
+       size_t                                  last_height_;\r
        \r
-       implementation()\r
+       implementation() \r
+               : last_mode_(core::video_mode::progressive)\r
+               , last_width_(0)\r
+               , last_height_(0)\r
        {\r
                vertex_ = \r
                        "void main()                                                                                                                                            \n"\r
@@ -254,21 +261,31 @@ struct image_kernel::implementation : boost::noncopyable
                {\r
                        shader_.reset(new shader(vertex_, fragment_));\r
                        GL(glEnable(GL_TEXTURE_2D));\r
-                       GL(glEnable(GL_SCISSOR_TEST));\r
                }\r
-                                       \r
-               if(item.mode == core::video_mode::upper)\r
+\r
+               if(last_mode_ != item.mode)\r
                {\r
-                       GL(glEnable(GL_POLYGON_STIPPLE));\r
-                       glPolygonStipple(upper_pattern);\r
+                       last_mode_ = item.mode;\r
+                       \r
+                       if(item.mode == core::video_mode::progressive)                  \r
+                               GL(glDisable(GL_POLYGON_STIPPLE));                      \r
+                       else                    \r
+                       {\r
+                               GL(glEnable(GL_POLYGON_STIPPLE));                       \r
+\r
+                               if(item.mode == core::video_mode::upper)\r
+                                       glPolygonStipple(upper_pattern);\r
+                               else if(item.mode == core::video_mode::lower)\r
+                                       glPolygonStipple(lower_pattern);\r
+                       }\r
                }\r
-               else if(item.mode == core::video_mode::lower)\r
+\r
+               if(last_width_ != background->width() || last_height_ != background->height())\r
                {\r
-                       GL(glEnable(GL_POLYGON_STIPPLE));\r
-                       glPolygonStipple(lower_pattern);\r
+                       last_width_ = background->width();\r
+                       last_height_ = background->height();\r
+                       GL(glViewport(0, 0, background->width(), background->height()));\r
                }\r
-               else\r
-                       GL(glDisable(GL_POLYGON_STIPPLE));\r
 \r
                // Bind textures\r
 \r
@@ -335,13 +352,13 @@ struct image_kernel::implementation : boost::noncopyable
                // Setup drawing area\r
 \r
                GL(glColor4d(item.transform.get_gain(), item.transform.get_gain(), item.transform.get_gain(), item.transform.get_opacity()));\r
-               GL(glViewport(0, 0, background->width(), background->height()));\r
                                                \r
                auto m_p = item.transform.get_clip_translation();\r
                auto m_s = item.transform.get_clip_scale();\r
                double w = static_cast<double>(background->width());\r
                double h = static_cast<double>(background->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 = item.transform.get_fill_translation();\r
@@ -355,6 +372,8 @@ struct image_kernel::implementation : boost::noncopyable
                        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
+\r
+               GL(glDisable(GL_SCISSOR_TEST)); \r
        }\r
 };\r
 \r
index c43f415caa02e31ec28f8f1e44e84c2b250d1657..3445a5b798eab56d60854747ddda9fe76f7d8ddc 100644 (file)
@@ -193,7 +193,8 @@ private:
                        {\r
                                auto frame2 = make_safe<core::basic_frame>(frame.second);\r
                                frame2->get_image_transform() = image_transforms[frame.first].fetch_and_tick(1);\r
-                               frame1 = core::basic_frame::interlace(frame1, frame2, channel_.get_format_desc().mode); // image_mixer optimizes away unecessary interlacing. No need to worry about it here.\r
+                               if(frame1->get_image_transform() != frame2->get_image_transform())\r
+                                       frame1 = core::basic_frame::interlace(frame1, frame2, channel_.get_format_desc().mode);\r
                        }\r
 \r
                        frame1->accept(image_mixer_);\r
index f4499d6d96059de8ae24d40a61b1494a2da6cf59..e9c531f9aed680aade98cefc73809aae6fea6fbc 100644 (file)
@@ -125,6 +125,11 @@ public:
                                \r
                return frame;\r
        }\r
+\r
+       bool empty() const\r
+       {\r
+               return background_ == core::frame_producer::empty() && foreground_ == core::frame_producer::empty();\r
+       }\r
 };\r
 \r
 layer::layer() : impl_(new implementation()){}\r
@@ -152,4 +157,5 @@ void layer::stop(){impl_->stop();}
 safe_ptr<basic_frame> layer::receive() {return impl_->receive();}\r
 safe_ptr<frame_producer> layer::foreground() const { return impl_->foreground_;}\r
 safe_ptr<frame_producer> layer::background() const { return impl_->background_;}\r
+bool layer::empty() const {return impl_->empty();}\r
 }}
\ No newline at end of file
index 86c741ded4868d35f98f6806a35b9e129ad66d2f..eb976d5d7293a7ce5f4fcf00eb0381fd56efd678 100644 (file)
@@ -46,6 +46,8 @@ public:
        void stop(); // nothrow\r
        void param(const std::wstring& param);\r
 \r
+       bool empty() const;\r
+\r
        safe_ptr<frame_producer> foreground() const; // nothrow\r
        safe_ptr<frame_producer> background() const; // nothrow\r
 \r
index 95bf3840666183911a8fe1aa5200c57752e1db59..42b465d7057c00eace94ccf99a21fcc5b37c0cff 100644 (file)
@@ -23,8 +23,6 @@
 \r
 #include <core/producer/frame/basic_frame.h>\r
 \r
-#include <tbb/parallel_invoke.h>\r
-\r
 namespace caspar { namespace core {    \r
 \r
 struct separated_producer : public frame_producer\r
@@ -46,19 +44,11 @@ struct separated_producer : public frame_producer
        \r
        virtual safe_ptr<basic_frame> receive(int hints)\r
        {\r
-               tbb::parallel_invoke\r
-               (\r
-                       [&]\r
-                       {\r
-                               if(fill_ == core::basic_frame::late())\r
-                                       fill_ = receive_and_follow(fill_producer_, hints);\r
-                       },\r
-                       [&]\r
-                       {\r
-                               if(key_ == core::basic_frame::late())\r
-                                       key_ = receive_and_follow(key_producer_, hints | ALPHA_HINT);\r
-                       }\r
-               );\r
+               if(fill_ == core::basic_frame::late())\r
+                       fill_ = receive_and_follow(fill_producer_, hints);\r
+       \r
+               if(key_ == core::basic_frame::late())\r
+                       key_ = receive_and_follow(key_producer_, hints | ALPHA_HINT);\r
 \r
                if(fill_ == basic_frame::eof())\r
                        return basic_frame::eof();\r
index 6d2fbd987a615d625c365265e82e6fb0be47a2cc..1ef79f3d33d872e2ee217a92f3b6dc3f85280c3c 100644 (file)
 \r
 #include <boost/range/algorithm.hpp>\r
 \r
-#include <tbb/parallel_for.h>\r
-\r
 #include <map>\r
 \r
 namespace caspar { namespace core {\r
                \r
 void destroy_producer(safe_ptr<frame_producer>& producer)\r
 {\r
-       if(!producer.unique())\r
+       bool unique = producer.unique();\r
+\r
+       if(!unique)\r
                CASPAR_LOG(warning) << producer->print() << L" Not destroyed on safe asynchronous destruction thread.";\r
-               \r
+       \r
        producer = frame_producer::empty();\r
+               \r
+       if(unique)\r
+               CASPAR_LOG(debug) << producer->print() << L" Destroyed.";\r
 }\r
 \r
 class destroy_producer_proxy : public frame_producer\r
@@ -91,15 +94,11 @@ public:
 \r
                try\r
                {\r
-                       // Allocate placeholders.\r
-                       BOOST_FOREACH(auto layer, layers_)\r
-                               frames[layer.first] = basic_frame::empty();\r
+                       auto layers2 = std::move(layers_);\r
+                       std::remove_copy_if(layers2.begin(), layers2.end(), std::inserter(layers_, layers_.begin()), [](layer_t& layer){return layer.second.empty();});\r
 \r
-                       // Render layers\r
-                       tbb::parallel_for_each(layers_.begin(), layers_.end(), [&](layer_t& layer)\r
-                       {\r
+                       BOOST_FOREACH(auto& layer, layers_)\r
                                frames[layer.first] = layer.second.receive();\r
-                       });\r
                }\r
                catch(...)\r
                {\r
index af8fe101bde7ea64df4820a244865d9994c5b515..e25bb0c95de5cb81a96568611344ef7d2263c608 100644 (file)
@@ -66,24 +66,13 @@ struct transition_producer : public frame_producer
                if(current_frame_++ >= info_.duration)\r
                        return basic_frame::eof();\r
                \r
-               auto dest       = core::basic_frame::empty();\r
-               auto source     = core::basic_frame::empty();\r
-\r
-               tbb::parallel_invoke\r
-               (\r
-                       [&]\r
-                       {\r
-                               dest = receive_and_follow(dest_producer_, hints);\r
-                               if(dest == core::basic_frame::late())\r
-                                       dest = dest_producer_->last_frame();\r
-                       },\r
-                       [&]\r
-                       {\r
-                               source = receive_and_follow(source_producer_, hints);\r
-                               if(source == core::basic_frame::late())\r
-                                       source = source_producer_->last_frame();\r
-                       }\r
-               );\r
+               auto dest = receive_and_follow(dest_producer_, hints);\r
+               if(dest == core::basic_frame::late())\r
+                       dest = dest_producer_->last_frame();\r
+               \r
+               auto source = receive_and_follow(source_producer_, hints);\r
+               if(source == core::basic_frame::late())\r
+                       source = source_producer_->last_frame();\r
 \r
                return last_frame_ = compose(dest, source);\r
        }\r