]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Updated layers swap logic.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 27 Feb 2011 02:12:26 +0000 (02:12 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 27 Feb 2011 02:12:26 +0000 (02:12 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@487 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/producer/frame_producer_device.cpp
core/producer/layer.cpp
core/producer/layer.h

index e8f534c0b3ec56e3f7a8413f3b5f394455b9288d..a43fc8f89520a8cd2fb619884a87b75cfcd8c4aa 100644 (file)
@@ -83,76 +83,52 @@ public:
        {\r
                producer->set_parent_printer(std::bind(&layer::print, &layers_.at(index)));\r
                producer->initialize(factory_);\r
-               executor_.invoke([&]\r
-               {\r
-                       layers_.at(index).load(producer, play_on_load);\r
-               });\r
+               executor_.invoke([&]{layers_.at(index).load(producer, play_on_load);});\r
        }\r
                        \r
        void preview(size_t index, const safe_ptr<frame_producer>& producer)\r
        {\r
                producer->initialize(factory_);\r
-               executor_.invoke([&]\r
-               {                       \r
-                       layers_.at(index).preview(producer);\r
-               });\r
+               executor_.invoke([&]{layers_.at(index).preview(producer);});\r
        }\r
 \r
        void pause(size_t index)\r
        {               \r
-               executor_.invoke([&]\r
-               {\r
-                       layers_.at(index).pause();\r
-               });\r
+               executor_.invoke([&]{layers_.at(index).pause();});\r
        }\r
 \r
        void play(size_t index)\r
        {               \r
-               executor_.invoke([&]\r
-               {\r
-                       layers_.at(index).play();\r
-               });\r
+               executor_.invoke([&]{layers_.at(index).play();});\r
        }\r
 \r
        void stop(size_t index)\r
        {               \r
-               executor_.invoke([&]\r
-               {\r
-                       layers_.at(index).stop();\r
-               });\r
+               executor_.invoke([&]{layers_.at(index).stop();});\r
        }\r
 \r
        void clear(size_t index)\r
        {\r
-               executor_.invoke([&]\r
-               {\r
-                       layers_.at(index) = std::move(layer(index, parent_printer_));\r
-               });\r
+               executor_.invoke([&]{layers_.at(index).clear();});\r
        }\r
                \r
        void clear()\r
        {\r
                executor_.invoke([&]\r
                {\r
-                       for(size_t n = 0; n < layers_.size(); ++n)\r
-                               layers_[n] = layer(n, parent_printer_);\r
+                       BOOST_FOREACH(auto& layer, layers_)\r
+                               layer.clear();\r
                });\r
        }       \r
        \r
        void swap_layer(size_t index, size_t other_index)\r
        {\r
-               executor_.invoke([&]\r
-               {\r
-                       layers_.at(index).swap(layers_[other_index]);\r
-               });\r
+               layers_.at(index).swap(layers_[other_index]);\r
        }\r
 \r
        void swap_layer(size_t index, size_t other_index, frame_producer_device& other)\r
        {\r
-               executor_.invoke([&]\r
-               {\r
-                       layers_.at(index).swap(other.impl_->layers_.at(other_index));\r
-               });\r
+               layers_.at(index).swap(other.impl_->layers_.at(other_index));\r
        }\r
 \r
        void swap_output(frame_producer_device& other)\r
index 149bddae840cf8819c53acf53dc620740f30de3c..14ba9f3a9caa40879ef0cbb6cf07c6335607a701 100644 (file)
@@ -14,6 +14,8 @@
 #include <mixer/audio/audio_mixer.h>\r
 #include <mixer/audio/audio_transform.h>\r
 \r
+#include <tbb/recursive_mutex.h>\r
+\r
 namespace caspar { namespace core {\r
 \r
 class frame_producer_remover\r
@@ -47,12 +49,14 @@ frame_producer_remover g_remover;
 \r
 struct layer::implementation : boost::noncopyable\r
 {                              \r
+       tbb::recursive_mutex            mutex_;\r
        printer                                         parent_printer_;\r
+       tbb::atomic<int>                        index_;\r
+\r
        safe_ptr<frame_producer>        foreground_;\r
        safe_ptr<frame_producer>        background_;\r
        safe_ptr<draw_frame>            last_frame_;\r
        bool                                            is_paused_;\r
-       tbb::atomic<int>                        index_;\r
 public:\r
        implementation(int index, const printer& parent_printer) \r
                : parent_printer_(parent_printer)\r
@@ -65,7 +69,9 @@ public:
        }\r
        \r
        void load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load)\r
-       {                       \r
+       {               \r
+               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
+\r
                background_ = frame_producer;\r
                is_paused_ = false;\r
                if(play_on_load)\r
@@ -74,13 +80,17 @@ public:
 \r
        void preview(const safe_ptr<frame_producer>& frame_producer)\r
        {\r
+               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
+\r
                load(frame_producer, true);\r
                receive();\r
                pause();\r
        }\r
        \r
        void play()\r
-       {                       \r
+       {               \r
+               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
+       \r
                if(!is_paused_)                 \r
                {\r
                        background_->set_leading_producer(foreground_);\r
@@ -93,11 +103,15 @@ public:
 \r
        void pause()\r
        {\r
+               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
+\r
                is_paused_ = true;\r
        }\r
 \r
        void stop()\r
        {\r
+               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
+\r
                pause();\r
                last_frame_ = draw_frame::empty();\r
                foreground_ = frame_producer::empty();\r
@@ -105,12 +119,18 @@ public:
 \r
        void clear()\r
        {\r
-               stop();\r
+               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
+               \r
+               foreground_ = frame_producer::empty();\r
                background_ = frame_producer::empty();\r
+               last_frame_ = draw_frame::empty();\r
+               is_paused_ = false;\r
        }\r
        \r
        safe_ptr<draw_frame> receive()\r
        {               \r
+               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
+\r
                if(is_paused_)\r
                {\r
                        last_frame_->get_audio_transform().set_gain(0.0);\r
@@ -143,33 +163,31 @@ public:
                return last_frame_;\r
        }\r
        \r
+       void swap(implementation& other)\r
+       {\r
+               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
+               std::swap(foreground_, other.foreground_);\r
+               std::swap(background_, other.background_);\r
+               std::swap(last_frame_, other.last_frame_);\r
+               std::swap(is_paused_, other.is_paused_);\r
+       }\r
+       \r
        std::wstring print() const\r
        {\r
                return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"layer[" + boost::lexical_cast<std::wstring>(index_) + L"]";\r
        }\r
 };\r
 \r
-layer::layer(int index, const printer& parent_printer) \r
-{\r
-       impl_ = new implementation(index, parent_printer);\r
-}\r
-layer::layer(layer&& other) \r
-{\r
-       impl_ = other.impl_.compare_and_swap(nullptr, other.impl_);\r
-}\r
-layer::~layer()\r
-{\r
-       delete impl_.fetch_and_store(nullptr);\r
-}\r
+layer::layer(int index, const printer& parent_printer) : impl_(new implementation(index, parent_printer)){}\r
+layer::layer(layer&& other) : impl_(std::move(other.impl_)){}\r
 layer& layer::operator=(layer&& other)\r
 {\r
-       impl_ = other.impl_.compare_and_swap(nullptr, other.impl_);\r
+       impl_ = std::move(other.impl_);\r
        return *this;\r
 }\r
 void layer::swap(layer& other)\r
 {\r
-       impl_ = other.impl_.compare_and_swap(impl_, other.impl_);\r
-       impl_->index_ = other.impl_->index_.compare_and_swap(impl_->index_, other.impl_->index_);\r
+       impl_->swap(*other.impl_);\r
 }\r
 void layer::load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load){return impl_->load(frame_producer, play_on_load);} \r
 void layer::preview(const safe_ptr<frame_producer>& frame_producer){return impl_->preview(frame_producer);}    \r
index 101943ecb91b02cc1d53910d4bd7be08cb993302..556183f7e6e2f940ef5bd22d7f163ac4d65a60cd 100644 (file)
@@ -7,6 +7,8 @@
 \r
 #include <tbb/atomic.h>\r
 \r
+#include <memory>\r
+\r
 namespace caspar { namespace core {\r
 \r
 class frame_producer;\r
@@ -17,10 +19,8 @@ class layer : boost::noncopyable
 public:\r
        layer(int index, const printer& parent_printer = nullptr); // nothrow\r
        layer(layer&& other); // nothrow\r
-       ~layer(); // nothrow\r
        layer& operator=(layer&& other); // nothrow\r
 \r
-       //NOTE: swap is thread-safe on "other", NOT on "this".\r
        void swap(layer& other); // nothrow \r
                \r
        void load(const safe_ptr<frame_producer>& producer, bool play_on_load = false); // nothrow\r
@@ -38,7 +38,7 @@ public:
        std::wstring print() const;\r
 private:\r
        struct implementation;\r
-       tbb::atomic<implementation*> impl_;\r
+       std::shared_ptr<implementation> impl_;\r
 };\r
 \r
 }}
\ No newline at end of file