]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Increased mixer pipeline depth to take into consideration host to device...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 17 May 2011 09:18:31 +0000 (09:18 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 17 May 2011 09:18:31 +0000 (09:18 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@763 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/mixer/audio/audio_mixer.cpp
core/mixer/image/image_mixer.cpp
modules/flash/producer/flash_producer.cpp
shell/caspar.config

index 7ab35d11003e995c5ced02a0dcfc38fa62b214db..d7a9a22b44c7f37a771488977ecf954dc1436d22 100644 (file)
@@ -29,7 +29,7 @@ namespace caspar { namespace mixer {
        \r
 struct audio_mixer::implementation\r
 {\r
-       std::vector<short> audio_data_;\r
+       std::deque<std::vector<short>> audio_data_;\r
        std::stack<core::audio_transform> transform_stack_;\r
 \r
        std::map<int, core::audio_transform> prev_audio_transforms_;\r
@@ -39,6 +39,10 @@ public:
        implementation()\r
        {\r
                transform_stack_.push(core::audio_transform());\r
+\r
+               // 2 frames delay\r
+               audio_data_.push_back(std::vector<short>());\r
+               audio_data_.push_back(std::vector<short>());\r
        }\r
        \r
        void begin(const core::basic_frame& frame)\r
@@ -54,8 +58,8 @@ public:
                auto& audio_data = frame.audio_data();\r
                auto tag = frame.tag(); // Get the identifier for the audio-stream.\r
 \r
-               if(audio_data_.empty())\r
-                       audio_data_.resize(audio_data.size(), 0);\r
+               if(audio_data_.back().empty())\r
+                       audio_data_.back().resize(audio_data.size(), 0);\r
                \r
                auto next = transform_stack_.top();\r
                auto prev = next;\r
@@ -79,11 +83,11 @@ public:
                        {\r
                                for(size_t n = r.begin(); n < r.end(); ++n)\r
                                {\r
-                                       double alpha = static_cast<double>(n)/static_cast<double>(audio_data_.size());\r
+                                       double alpha = static_cast<double>(n)/static_cast<double>(audio_data_.back().size());\r
                                        double sample_gain = prev_gain * (1.0 - alpha) + next_gain * alpha;\r
                                        int sample = static_cast<int>(audio_data[n]);\r
                                        sample = (static_cast<int>(sample_gain*static_cast<double>(1<<15))*sample)>>15;\r
-                                       audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n]) + sample) & 0xFFFF);\r
+                                       audio_data_.back()[n] = static_cast<short>((static_cast<int>(audio_data_.back()[n]) + sample) & 0xFFFF);\r
                                }\r
                        }\r
                );\r
@@ -102,7 +106,12 @@ public:
 \r
        std::vector<short> begin_pass()\r
        {\r
-               return std::move(audio_data_);\r
+               auto result = std::move(audio_data_.front());\r
+               audio_data_.pop_front();\r
+               \r
+               audio_data_.push_back(std::vector<short>());\r
+\r
+               return result;\r
        }\r
 \r
        void end_pass()\r
index 2fd86da696ae4d1b1fe17ef081edaa17dcdf0d50..4b531ecf1e39242cb784be6c0b4b67c34a3583ce 100644 (file)
@@ -63,10 +63,11 @@ struct image_mixer::implementation : boost::noncopyable
        struct render_item\r
        {\r
                core::pixel_format_desc desc;\r
-               std::vector<safe_ptr<host_buffer>> buffers;\r
+               std::vector<safe_ptr<device_buffer>> textures;\r
                core::image_transform transform;\r
        };\r
-\r
+       \r
+       std::vector<render_item> waiting_queue_;\r
        std::vector<render_item> render_queue_;\r
 \r
 public:\r
@@ -115,14 +116,28 @@ public:
                auto gpu_frame = dynamic_cast<gpu_write_frame*>(&frame);\r
                if(!gpu_frame)\r
                        return;\r
+               \r
+               auto desc = gpu_frame->get_pixel_format_desc();\r
+               auto buffers = gpu_frame->get_plane_buffers();\r
+               auto transform = transform_stack_.top();\r
 \r
-               render_item item;\r
+               ogl_device::begin_invoke([=]\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
+                       item.desc = desc;\r
+                       item.transform = transform;\r
+                       \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
+                               item.textures.push_back(texture);\r
+                       }       \r
 \r
-               render_queue_.push_back(item);\r
+                       waiting_queue_.push_back(item);\r
+               });\r
        }\r
 \r
        void end()\r
@@ -132,39 +147,58 @@ public:
 \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
+               auto result = ogl_device::begin_invoke([=]() -> safe_ptr<const host_buffer>\r
+               {\r
+                       reading_->map(); // Might block.\r
+                       return make_safe(reading_);\r
+               });\r
+                       \r
+               ogl_device::begin_invoke([=]\r
                {\r
                        is_key_ = false;\r
+\r
+                       // Clear and bind frame-buffers.\r
+\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
 \r
-                       BOOST_FOREACH(auto item, queue)\r
+                       // Render items.\r
+\r
+                       BOOST_FOREACH(auto item, render_queue_)\r
                                render(item);                   \r
 \r
-                       // END PASS\r
+                       // Move waiting items to queue.\r
+\r
+                       render_queue_ = std::move(waiting_queue_);\r
+\r
+                       // Start read-back.\r
+\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
+                       std::swap(render_targets_[0], render_targets_[1]);\r
                });\r
+\r
+               return std::move(result);\r
        }\r
 \r
        void render(const render_item& item)\r
        {               \r
                const auto desc          = item.desc;\r
-               auto       buffers       = item.buffers;\r
+               auto       textures      = item.textures;\r
                const auto transform = item.transform;\r
                                \r
+               // Bind textures\r
+\r
+               for(size_t n = 0; n < textures.size(); ++n)\r
+               {\r
+                       GL(glActiveTexture(GL_TEXTURE0+n));\r
+                       textures[n]->bind();\r
+               }               \r
+\r
                // Setup key and kernel\r
 \r
                if(transform.get_is_key())\r
@@ -182,27 +216,13 @@ public:
                        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
 \r
                GL(glColor4d(1.0, 1.0, 1.0, transform.get_opacity()));\r
                GL(glViewport(0, 0, format_desc_.width, format_desc_.height));\r
index 625f062a9450d689fd34f325aaee51e1645b3fea..5880daac13516380211e30000338a9d9269d6d07 100644 (file)
@@ -297,14 +297,14 @@ public:
                                const auto& format_desc = frame_factory_->get_video_format_desc();\r
                                auto frame = core::basic_frame::empty();\r
 \r
-                               if(abs(context_->fps()/2.0 - format_desc.fps) < 0.1) // flash == 2 * format -> interlace\r
+                               if(abs(context_->fps()/2.0 - format_desc.fps) < 0.01) // flash == 2 * format -> interlace\r
                                {\r
                                        auto frame1 = context_->render_frame(frame_buffer_.size() < frame_buffer_.capacity());\r
                                        auto frame2 = context_->render_frame(frame_buffer_.size() < frame_buffer_.capacity());\r
                                        frame_buffer_.push(core::basic_frame::interlace(frame1, frame2, format_desc.mode));\r
                                        frame = frame2;\r
                                }\r
-                               else if(abs(context_->fps()- format_desc.fps/2.0 ) < 0.1) // format == 2 * flash -> duplicate\r
+                               else if(abs(context_->fps()- format_desc.fps/2.0) < 0.01) // format == 2 * flash -> duplicate\r
                                {\r
                                        frame = context_->render_frame(frame_buffer_.size() < frame_buffer_.capacity());\r
                                        frame_buffer_.push(frame);\r
index f4ddba67237697837d4437e51c9fac7b2d13cddb..523a89ee4826556b214c929e3557ddc0c2652624 100644 (file)
@@ -5,7 +5,7 @@
     <log-path>L:\\Casparcg\\_log\\</log-path>\r
     <data-path>L:\\Casparcg\\_data\\</data-path>\r
     <template-path>L:\\Casparcg\\_templates\\</template-path>\r
-    <template-host>cg.fth.18</template-host>\r
+    <template-host>cg.fth.1920x1080p29.97</template-host>\r
   </paths>\r
   <diagnostics>\r
     <graphs>true</graphs>\r