]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Fixed a bug in com_context where the old context was destroyed after the...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 26 May 2011 18:08:34 +0000 (18:08 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 26 May 2011 18:08:34 +0000 (18:08 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@814 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

common/concurrency/com_context.h
core/StdAfx.h
core/channel.cpp
core/channel.h
core/mixer/frame_mixer_device.cpp
core/mixer/frame_mixer_device.h
core/producer/frame_producer_device.cpp
core/producer/frame_producer_device.h
shell/caspar.config

index dfd66ddc8a29593ed9d83240c5edfd8c060fcf5d..242f165791ec4fd2cc5920416afba74b5dea8976 100644 (file)
@@ -32,14 +32,13 @@ public:
                });\r
        }\r
        \r
-       void reset(const std::function<T*()>& factory)\r
+       void reset(const std::function<T*()>& factory = nullptr)\r
        {\r
                executor::invoke([&]\r
                {\r
+                       instance_.reset();\r
                        if(factory)\r
                                instance_.reset(factory());\r
-                       else\r
-                               instance_.reset(nullptr);\r
                });\r
        }\r
 \r
index 67d7fc72f5b677f28c2483a0ae7d0ecac231e25c..bb3903489e655896cbc9a04d6544b6e7ebab571d 100644 (file)
 #include <GLee.h>\r
 #include <SFML/Window.hpp>\r
 \r
-#include <tchar.h>\r
-#include <sstream>\r
-#include <memory>\r
+#include <algorithm>\r
 #include <array>\r
 #include <functional>\r
-#include <algorithm>\r
-#include <vector>\r
 #include <deque>\r
+#include <map>\r
+#include <memory>\r
 #include <queue>\r
 #include <string>\r
-#include <math.h>\r
+#include <vector>\r
 \r
 #include <tbb/atomic.h>\r
 #include <tbb/concurrent_queue.h>\r
@@ -74,7 +72,6 @@
 #include <boost/filesystem.hpp>\r
 #include <boost/foreach.hpp>\r
 #include <boost/range/algorithm.hpp>\r
-#include <boost/signals2.hpp>\r
 \r
 #include <common/utility/string.h>\r
 #include <common/memory/safe_ptr.h>\r
index 7866099bd306d84d6ab761fbafd5554f287e7581..b95f65407dcfdd207ced847d25c9c55b12e11629 100644 (file)
 #include "channel.h"\r
 \r
 #include "video_format.h"\r
-#include "consumer/frame_consumer_device.h"\r
-#include "mixer/frame_mixer_device.h"\r
-#include "producer/frame_producer_device.h"\r
 #include "producer/layer.h"\r
 \r
 #include <common/concurrency/executor.h>\r
 \r
 #include <boost/range/algorithm_ext/erase.hpp>\r
 \r
-#include <tbb/parallel_for.h>\r
-\r
-#include <memory>\r
-\r
 #ifdef _MSC_VER\r
 #pragma warning(disable : 4355)\r
 #endif\r
@@ -47,22 +40,17 @@ struct channel::implementation : boost::noncopyable
        const int index_;\r
        video_format_desc format_desc_;\r
        \r
-       safe_ptr<frame_mixer_device> mixer_; // Mixer must be destroyed last in order to make sure that all frames have been returned to the pool.\r
-       safe_ptr<frame_consumer_device> consumer_;\r
-       safe_ptr<frame_producer_device> producer_;\r
-\r
-       boost::signals2::scoped_connection mixer_connection_;\r
-       boost::signals2::scoped_connection producer_connection_;\r
-\r
+       std::shared_ptr<frame_consumer_device>  consumer_;\r
+       std::shared_ptr<frame_mixer_device>             mixer_;\r
+       std::shared_ptr<frame_producer_device>  producer_;\r
+       \r
 public:\r
        implementation(int index, const video_format_desc& format_desc)  \r
                : index_(index)\r
                , format_desc_(format_desc)\r
+               , mixer_(new frame_mixer_device(format_desc, [=](const safe_ptr<const read_frame>& frame){consumer_->send(frame);}))\r
                , consumer_(new frame_consumer_device(format_desc))\r
-               , mixer_(new frame_mixer_device(format_desc))\r
-               , producer_(new frame_producer_device(format_desc_))    \r
-               , mixer_connection_(mixer_->connect([=](const safe_ptr<const read_frame>& frame){consumer_->send(frame);}))\r
-               , producer_connection_(producer_->connect([=](const std::map<int, safe_ptr<basic_frame>>& frames){mixer_->send(frames);}))\r
+               , producer_(new frame_producer_device(format_desc_, [=](const std::map<int, safe_ptr<basic_frame>>& frames){mixer_->send(frames);}))    \r
        {\r
                CASPAR_LOG(info) << print() << " Successfully Initialized.";\r
        }\r
@@ -75,23 +63,20 @@ public:
        void set_video_format_desc(const video_format_desc& format_desc)\r
        {\r
                format_desc_ = format_desc;\r
-               producer_connection_.disconnect();\r
-               mixer_connection_.disconnect();\r
+               producer_.reset();\r
+               mixer_.reset();\r
 \r
                consumer_->set_video_format_desc(format_desc_);\r
-               mixer_ = make_safe<frame_mixer_device>(format_desc_);\r
-               producer_ = make_safe<frame_producer_device>(format_desc_);\r
-\r
-               mixer_connection_ = mixer_->connect([=](const safe_ptr<const read_frame>& frame){consumer_->send(frame);});\r
-               producer_connection_ = producer_->connect([=](const std::map<int, safe_ptr<basic_frame>>& frames){mixer_->send(frames);});\r
+               mixer_ = make_safe<frame_mixer_device>(format_desc_, [=](const safe_ptr<const read_frame>& frame){consumer_->send(frame);});\r
+               producer_ = make_safe<frame_producer_device>(format_desc_, [=](const std::map<int, safe_ptr<basic_frame>>& frames){mixer_->send(frames);});\r
        }\r
 };\r
 \r
 channel::channel(int index, const video_format_desc& format_desc) : impl_(new implementation(index, format_desc)){}\r
 channel::channel(channel&& other) : impl_(std::move(other.impl_)){}\r
-const safe_ptr<frame_producer_device>& channel::producer() { return impl_->producer_;} \r
-const safe_ptr<frame_mixer_device>& channel::mixer() { return impl_->mixer_;} \r
-const safe_ptr<frame_consumer_device>& channel::consumer() { return impl_->consumer_;} \r
+safe_ptr<frame_producer_device> channel::producer() { return make_safe(impl_->producer_);} \r
+safe_ptr<frame_mixer_device> channel::mixer() { return make_safe(impl_->mixer_);} \r
+safe_ptr<frame_consumer_device> channel::consumer() { return make_safe(impl_->consumer_);} \r
 const video_format_desc& channel::get_video_format_desc() const{return impl_->format_desc_;}\r
 void channel::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);}\r
 std::wstring channel::print() const { return impl_->print();}\r
index 98a9fee64ecefd29cf48747551edf17748770d52..05ef7eb8fdcfcea1ece52fd8bee61e036db784e4 100644 (file)
 #include <common/memory/safe_ptr.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
-#include <boost/thread/future.hpp>\r
 \r
 namespace caspar { namespace core {\r
-\r
+       \r
 class channel : boost::noncopyable\r
 {\r
 public:\r
        explicit channel(int index, const video_format_desc& format_desc);\r
        channel(channel&& other);\r
 \r
-       const safe_ptr<frame_producer_device>& producer();\r
-       const safe_ptr<frame_mixer_device>& mixer();\r
-       const safe_ptr<frame_consumer_device>& consumer();\r
+       safe_ptr<frame_producer_device> producer();\r
+       safe_ptr<frame_mixer_device>    mixer();\r
+       safe_ptr<frame_consumer_device> consumer();\r
 \r
        const video_format_desc& get_video_format_desc() const;\r
        void set_video_format_desc(const video_format_desc& format_desc);\r
index ea8154afb724153472556e67e7321eeecbc24edc..ac36055dbceb7560c3da56a98d99bef1f360def4 100644 (file)
@@ -94,7 +94,7 @@ struct frame_mixer_device::implementation : boost::noncopyable
        audio_mixer     audio_mixer_;\r
        image_mixer image_mixer_;\r
 \r
-       output_t output_;\r
+       std::function<void(const safe_ptr<const core::read_frame>&)> output_;\r
        \r
        typedef std::unordered_map<int, tweened_transform<core::image_transform>> image_transforms;\r
        typedef std::unordered_map<int, tweened_transform<core::audio_transform>> audio_transforms;\r
@@ -107,10 +107,11 @@ struct frame_mixer_device::implementation : boost::noncopyable
 \r
        executor executor_;\r
 public:\r
-       implementation(const core::video_format_desc& format_desc) \r
+       implementation(const core::video_format_desc& format_desc, const std::function<void(const safe_ptr<const core::read_frame>&)>& output\r
                : format_desc_(format_desc)\r
                , diag_(diagnostics::create_graph(narrow(print())))\r
                , image_mixer_(format_desc)\r
+               , output_(output)\r
                , executor_(L"frame_mixer_device")\r
        {\r
                diag_->add_guide("frame-time", 0.5f);   \r
@@ -125,12 +126,7 @@ public:
 \r
                CASPAR_LOG(info) << print() << L" Successfully initialized.";   \r
        }\r
-\r
-       boost::signals2::connection connect(const output_t::slot_type& subscriber)\r
-       {\r
-               return output_.connect(subscriber);\r
-       }\r
-\r
+       \r
        boost::unique_future<safe_ptr<const host_buffer>> mix_image(std::map<int, safe_ptr<core::basic_frame>> frames)\r
        {               \r
                auto& root_image_transform = boost::fusion::at_key<core::image_transform>(root_transforms_);\r
@@ -288,9 +284,8 @@ public:
        }\r
 };\r
        \r
-frame_mixer_device::frame_mixer_device(const core::video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
+frame_mixer_device::frame_mixer_device(const core::video_format_desc& format_desc, const std::function<void(const safe_ptr<const core::read_frame>&)>& output) : impl_(new implementation(format_desc, output)){}\r
 frame_mixer_device::frame_mixer_device(frame_mixer_device&& other) : impl_(std::move(other.impl_)){}\r
-boost::signals2::connection frame_mixer_device::connect(const output_t::slot_type& subscriber){return impl_->connect(subscriber);}\r
 void frame_mixer_device::send(const std::map<int, safe_ptr<core::basic_frame>>& frames){impl_->send(frames);}\r
 const core::video_format_desc& frame_mixer_device::get_video_format_desc() const { return impl_->format_desc_; }\r
 safe_ptr<core::write_frame> frame_mixer_device::create_frame(void* tag, const core::pixel_format_desc& desc){ return impl_->create_frame(tag, desc); }         \r
index a7c7bc66fa642851add86825b667b59192367fdb..f3835663cc7d6e947a3252624c0c8fa9d6e5ed53 100644 (file)
@@ -24,9 +24,8 @@
 \r
 #include <common/memory/safe_ptr.h>\r
 \r
-#include <boost/signals2.hpp>\r
-\r
 #include <functional>\r
+#include <map>\r
 \r
 namespace caspar { \r
 \r
@@ -44,12 +43,8 @@ namespace core {
        \r
 class frame_mixer_device : public core::frame_factory\r
 {\r
-public:\r
-       typedef boost::signals2::signal<void(const safe_ptr<const core::read_frame>&)> output_t;\r
-        \r
-       boost::signals2::connection connect(const output_t::slot_type& subscriber);\r
-       \r
-       frame_mixer_device(const core::video_format_desc& format_desc);\r
+public:        \r
+       frame_mixer_device(const core::video_format_desc& format_desc, const std::function<void(const safe_ptr<const core::read_frame>&)>& output);\r
        frame_mixer_device(frame_mixer_device&& other); // nothrow\r
                \r
        void send(const std::map<int, safe_ptr<core::basic_frame>>& frames); // nothrow\r
index 9fae118f282e8e23a6b39a8d8aa5ec6db35eb62c..2498370da820eeb3a74768278c317e80067896cf 100644 (file)
@@ -38,7 +38,6 @@
 \r
 #include <tbb/parallel_for.h>\r
 #include <tbb/mutex.h>\r
-#include <tbb/combinable.h>\r
 \r
 #include <array>\r
 #include <memory>\r
@@ -54,7 +53,7 @@ struct frame_producer_device::implementation : boost::noncopyable
        \r
        safe_ptr<diagnostics::graph> diag_;\r
 \r
-       output_t output_;\r
+       const std::function<void(const std::map<int, safe_ptr<basic_frame>>&)> output_;\r
 \r
        boost::timer frame_timer_;\r
        boost::timer tick_timer_;\r
@@ -62,10 +61,11 @@ struct frame_producer_device::implementation : boost::noncopyable
        \r
        mutable executor executor_;\r
 public:\r
-       implementation(const video_format_desc& format_desc)  \r
+       implementation(const video_format_desc& format_desc, const std::function<void(const std::map<int, safe_ptr<basic_frame>>&)>& output)  \r
                : format_desc_(format_desc)\r
                , diag_(diagnostics::create_graph(std::string("frame_producer_device")))\r
                , executor_(L"frame_producer_device")\r
+               , output_(output)\r
        {\r
                diag_->add_guide("frame-time", 0.5f);   \r
                diag_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
@@ -75,23 +75,11 @@ public:
                {\r
                        SetThreadPriority(GetCurrentThread(), ABOVE_NORMAL_PRIORITY_CLASS);\r
                });\r
+               executor_.begin_invoke([=]{tick();});           \r
        }\r
-\r
-       boost::signals2::connection connect(const output_t::slot_type& subscriber)\r
-       {\r
-               return executor_.invoke([&]() -> boost::signals2::connection\r
-               {\r
-                       if(output_.empty())\r
-                               executor_.begin_invoke([=]{tick();});           \r
-                       return output_.connect(subscriber);\r
-               });\r
-       }\r
-                                       \r
+                       \r
        void tick()\r
        {                               \r
-               if(output_.empty())\r
-                       return;                         \r
-               \r
                auto frame = draw();\r
                output_timer_.restart();\r
                output_(frame);\r
@@ -104,27 +92,23 @@ public:
        {       \r
                frame_timer_.restart();\r
 \r
-               tbb::combinable<std::map<int, safe_ptr<basic_frame>>> frames;\r
+               std::map<int, safe_ptr<basic_frame>> frames;\r
+               for(auto it = layers_.begin(); it != layers_.end(); ++it)\r
+                       frames[it->first] = basic_frame::empty();\r
 \r
                tbb::parallel_for_each(layers_.begin(), layers_.end(), [&](decltype(*layers_.begin())& pair)\r
                {\r
                        auto frame = pair.second.receive();\r
                        if(is_concrete_frame(frame))\r
-                               frames.local()[pair.first] = frame;             \r
+                               frames[pair.first] = frame;             \r
                });\r
-\r
-               std::map<int, safe_ptr<basic_frame>> result;\r
-               frames.combine_each([&](const std::map<int, safe_ptr<basic_frame>>& map)\r
-               {\r
-                       result.insert(map.begin(), map.end());\r
-               });\r
-\r
+               \r
                diag_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()*format_desc_.fps*0.5));\r
-                               \r
+\r
                diag_->update_value("tick-time", static_cast<float>(tick_timer_.elapsed()*format_desc_.fps*0.5));\r
                tick_timer_.restart();\r
 \r
-               return result;\r
+               return frames;\r
        }\r
 \r
        void load(int index, const safe_ptr<frame_producer>& producer, bool preview)\r
@@ -214,9 +198,8 @@ public:
        }\r
 };\r
 \r
-frame_producer_device::frame_producer_device(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
+frame_producer_device::frame_producer_device(const video_format_desc& format_desc, const std::function<void(const std::map<int, safe_ptr<basic_frame>>&)>& output) : impl_(new implementation(format_desc, output)){}\r
 frame_producer_device::frame_producer_device(frame_producer_device&& other) : impl_(std::move(other.impl_)){}\r
-boost::signals2::connection frame_producer_device::connect(const output_t::slot_type& subscriber){return impl_->connect(subscriber);}\r
 void frame_producer_device::swap(frame_producer_device& other){impl_->swap(other);}\r
 void frame_producer_device::load(int index, const safe_ptr<frame_producer>& producer, bool preview){impl_->load(index, producer, preview);}\r
 void frame_producer_device::pause(int index){impl_->pause(index);}\r
index 79b5d64b51c8706e7b8b83d3a0988f1a42a3d035..ced321e310c5c178acdcedea37341394ce4c421d 100644 (file)
@@ -25,7 +25,6 @@
 #include <common/memory/safe_ptr.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
-#include <boost/signals2.hpp>\r
 #include <boost/thread/future.hpp>\r
 \r
 namespace caspar { namespace core {\r
@@ -46,12 +45,8 @@ struct video_format_desc;
 class frame_producer_device : boost::noncopyable\r
 {\r
 public:\r
-       typedef boost::signals2::signal<void(const std::map<int, safe_ptr<basic_frame>>&)> output_t;\r
-        \r
-       explicit frame_producer_device(const video_format_desc& format_desc);\r
+       explicit frame_producer_device(const video_format_desc& format_desc, const std::function<void(const std::map<int, safe_ptr<basic_frame>>&)>& output);\r
        frame_producer_device(frame_producer_device&& other);\r
-       \r
-       boost::signals2::connection connect(const output_t::slot_type& subscriber);\r
 \r
        void swap(frame_producer_device& other);\r
                \r
index 586eee9e395ad86221358ebc996eaa78aba9bd8a..baeaef99e1e9fee6cca6b83a8d10b4d662f3cc76 100644 (file)
       <videomode>1080i5000</videomode>\r
       <consumers>\r
         <decklink>\r
-          <device>1</device>                    <!-- [1..] Specifies which device to use. -->\r
-          <embedded-audio>true</embedded-audio> <!-- [true/false] -->\r
-          <low-latency>false</low-latency>      <!-- [true/false] - Experimental feature that reduces frame delay by 3 frames or less. -->\r
-          <external-key>true</external-key>     <!-- [true/false]-->\r
-          <key-only>false</key-only>            <!-- [true/false] - Copies key into fill channels. -->\r
+          <device>1</device>                    \r
+          <embedded-audio>true</embedded-audio> \r
+          <low-latency>true</low-latency>      \r
+          <external-key>true</external-key>     \r
+          <key-only>false</key-only>            \r
         </decklink>\r
         <!--<audio>\r
         </audio>-->\r