]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 12 Jan 2012 17:03:14 +0000 (17:03 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 12 Jan 2012 17:03:14 +0000 (17:03 +0000)
core/producer/stage.cpp
core/producer/stage.h
protocol/amcp/AMCPCommandsImpl.cpp

index 475e2bdc38045e50f7b7e01171bfe6b4489e7622..24c9df5650c4e0a4401bf75f1a6681e9cbbf597f 100644 (file)
@@ -170,8 +170,21 @@ public:
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                }               \r
        }\r
+               \r
+       void apply_transforms(const std::vector<std::tuple<int, stage::transform_func_t, unsigned int, std::wstring>>& transforms)\r
+       {\r
+               executor_.begin_invoke([=]\r
+               {\r
+                       BOOST_FOREACH(auto& transform, transforms)\r
+                       {\r
+                               auto src = transforms_[std::get<0>(transform)].fetch();\r
+                               auto dst = std::get<1>(transform)(src);\r
+                               transforms_[std::get<0>(transform)] = tweened_transform<frame_transform>(src, dst, std::get<2>(transform), std::get<3>(transform));\r
+                       }\r
+               }, high_priority);\r
+       }\r
                                                \r
-       void apply_transform(int index, const std::function<frame_transform(frame_transform)>& transform, unsigned int mix_duration, const std::wstring& tween)\r
+       void apply_transform(int index, const stage::transform_func_t& transform, unsigned int mix_duration, const std::wstring& tween)\r
        {\r
                executor_.begin_invoke([=]\r
                {\r
@@ -339,6 +352,7 @@ public:
 };\r
 \r
 stage::stage(const safe_ptr<stage::target_t>& target, const safe_ptr<diagnostics::graph>& graph, const struct video_format_desc& format_desc) : impl_(new impl(target, graph, format_desc)){}\r
+void stage::apply_transforms(const std::vector<stage::transform_tuple_t>& transforms){impl_->apply_transforms(transforms);}\r
 void stage::apply_transform(int index, const std::function<core::frame_transform(core::frame_transform)>& transform, unsigned int mix_duration, const std::wstring& tween){impl_->apply_transform(index, transform, mix_duration, tween);}\r
 void stage::clear_transforms(int index){impl_->clear_transforms(index);}\r
 void stage::clear_transforms(){impl_->clear_transforms();}\r
index f5ddc1101532a0318c559ceae835c28914f74815..a435279f05229b64788a516ec9acc145cceaeb60 100644 (file)
@@ -31,6 +31,8 @@
 #include <boost/property_tree/ptree_fwd.hpp>\r
 \r
 #include <functional>\r
+#include <tuple>\r
+#include <vector>\r
 \r
 FORWARD2(caspar, diagnostics, class graph);\r
 FORWARD1(boost, template<typename> class unique_future);\r
@@ -41,13 +43,16 @@ class stage sealed
 {\r
        CASPAR_NO_COPY(stage);\r
 public:        \r
-       typedef target<std::pair<std::map<int, safe_ptr<class basic_frame>>, std::shared_ptr<void>>> target_t;\r
+       typedef std::function<struct frame_transform(struct frame_transform)>                                                   transform_func_t;\r
+       typedef std::tuple<int, transform_func_t, unsigned int, std::wstring>                                                   transform_tuple_t;\r
+       typedef target<std::pair<std::map<int, safe_ptr<class basic_frame>>, std::shared_ptr<void>>>    target_t;\r
 \r
        stage(const safe_ptr<target_t>& target, const safe_ptr<diagnostics::graph>& graph, const struct video_format_desc& format_desc);\r
        \r
        // stage\r
        \r
-       void apply_transform(int index, const std::function<struct frame_transform(struct frame_transform)>& transform, unsigned int mix_duration = 0, const std::wstring& tween = L"linear");\r
+       void apply_transforms(const std::vector<transform_tuple_t>& transforms);\r
+       void apply_transform(int index, const transform_func_t& transform, unsigned int mix_duration = 0, const std::wstring& tween = L"linear");\r
        void clear_transforms(int index);\r
        void clear_transforms();\r
 \r
index 62404dfc2298bc3c487ff6e62e6759b1bbae1f5e..e7ca0db94970534630f017e04464b7c4b2d7f4a6 100644 (file)
@@ -69,6 +69,8 @@
 #include <boost/regex.hpp>\r
 #include <boost/property_tree/xml_parser.hpp>\r
 \r
+#include <tbb/concurrent_unordered_map.h>\r
+\r
 /* Return codes\r
 \r
 100 [action]                   Information om att något har hänt  \r
@@ -317,22 +319,27 @@ bool CallCommand::DoExecute()
        }\r
 }\r
 \r
+tbb::concurrent_unordered_map<int, std::vector<stage::transform_tuple_t>> deferred_transforms;\r
+\r
 bool MixerCommand::DoExecute()\r
 {      \r
        //Perform loading of the clip\r
        try\r
        {       \r
+               bool defer = _parameters.back() == L"DEFER";\r
+               if(defer)\r
+                       _parameters.pop_back();\r
+\r
+               std::vector<stage::transform_tuple_t> transforms;\r
+\r
                if(_parameters[0] == L"KEYER" || _parameters[0] == L"IS_KEY")\r
                {\r
                        bool value = boost::lexical_cast<int>(_parameters.at(1));\r
-                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                       transforms.push_back(stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) -> frame_transform\r
                        {\r
                                transform.is_key = value;\r
                                return transform;                                       \r
-                       };\r
-\r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform);\r
+                       }, 0, L"linear"));\r
                }\r
                else if(_parameters[0] == L"OPACITY")\r
                {\r
@@ -341,14 +348,11 @@ bool MixerCommand::DoExecute()
 \r
                        double value = boost::lexical_cast<double>(_parameters.at(1));\r
                        \r
-                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                       transforms.push_back(stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) -> frame_transform\r
                        {\r
                                transform.opacity = value;\r
                                return transform;                                       \r
-                       };\r
-\r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform, duration, tween);\r
+                       }, duration, tween));\r
                }\r
                else if(_parameters[0] == L"FILL" || _parameters[0] == L"FILL_RECT")\r
                {\r
@@ -359,7 +363,7 @@ bool MixerCommand::DoExecute()
                        double x_s      = boost::lexical_cast<double>(_parameters.at(3));\r
                        double y_s      = boost::lexical_cast<double>(_parameters.at(4));\r
 \r
-                       auto transform = [=](frame_transform transform) mutable -> frame_transform\r
+                       transforms.push_back(stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) mutable -> frame_transform\r
                        {\r
                                transform.fill_translation[0]   = x;\r
                                transform.fill_translation[1]   = y;\r
@@ -370,10 +374,7 @@ bool MixerCommand::DoExecute()
                                transform.clip_scale[0]                 = x_s;\r
                                transform.clip_scale[1]                 = y_s;\r
                                return transform;\r
-                       };\r
-                               \r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform, duration, tween);\r
+                       }, duration, tween));\r
                }\r
                else if(_parameters[0] == L"CLIP" || _parameters[0] == L"CLIP_RECT")\r
                {\r
@@ -384,17 +385,14 @@ bool MixerCommand::DoExecute()
                        double x_s      = boost::lexical_cast<double>(_parameters.at(3));\r
                        double y_s      = boost::lexical_cast<double>(_parameters.at(4));\r
 \r
-                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                       transforms.push_back(stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) -> frame_transform\r
                        {\r
                                transform.clip_translation[0]   = x;\r
                                transform.clip_translation[1]   = y;\r
                                transform.clip_scale[0]                 = x_s;\r
                                transform.clip_scale[1]                 = y_s;\r
                                return transform;\r
-                       };\r
-                               \r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform, duration, tween);\r
+                       }, duration, tween));\r
                }\r
                else if(_parameters[0] == L"GRID")\r
                {\r
@@ -407,7 +405,7 @@ bool MixerCommand::DoExecute()
                                for(int y = 0; y < n; ++y)\r
                                {\r
                                        int index = x+y*n+1;\r
-                                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                                       transforms.push_back(stage::transform_tuple_t(index, [=](frame_transform transform) -> frame_transform\r
                                        {               \r
                                                transform.fill_translation[0]   = x*delta;\r
                                                transform.fill_translation[1]   = y*delta;\r
@@ -418,8 +416,7 @@ bool MixerCommand::DoExecute()
                                                transform.clip_scale[0]                 = delta;\r
                                                transform.clip_scale[1]                 = delta;                        \r
                                                return transform;\r
-                                       };\r
-                                       GetChannel()->stage()->apply_transform(index, transform, duration, tween);\r
+                                       }, duration, tween));\r
                                }\r
                        }\r
                }\r
@@ -434,42 +431,33 @@ bool MixerCommand::DoExecute()
                        auto value = boost::lexical_cast<double>(_parameters.at(1));\r
                        int duration = _parameters.size() > 2 ? boost::lexical_cast<int>(_parameters[2]) : 0;\r
                        std::wstring tween = _parameters.size() > 3 ? _parameters[3] : L"linear";\r
-                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                       auto transform = stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) -> frame_transform\r
                        {\r
                                transform.brightness = value;\r
                                return transform;\r
-                       };\r
-                               \r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform, duration, tween);    \r
+                       }, duration, tween);\r
                }\r
                else if(_parameters[0] == L"SATURATION")\r
                {\r
                        auto value = boost::lexical_cast<double>(_parameters.at(1));\r
                        int duration = _parameters.size() > 2 ? boost::lexical_cast<int>(_parameters[2]) : 0;\r
                        std::wstring tween = _parameters.size() > 3 ? _parameters[3] : L"linear";\r
-                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                       auto transform = stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) -> frame_transform\r
                        {\r
                                transform.saturation = value;\r
                                return transform;\r
-                       };\r
-                               \r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform, duration, tween);    \r
+                       }, duration, tween);    \r
                }\r
                else if(_parameters[0] == L"CONTRAST")\r
                {\r
                        auto value = boost::lexical_cast<double>(_parameters.at(1));\r
                        int duration = _parameters.size() > 2 ? boost::lexical_cast<int>(_parameters[2]) : 0;\r
                        std::wstring tween = _parameters.size() > 3 ? _parameters[3] : L"linear";\r
-                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                       auto transform = stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) -> frame_transform\r
                        {\r
                                transform.contrast = value;\r
                                return transform;\r
-                       };\r
-                               \r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform, duration, tween);    \r
+                       }, duration, tween);    \r
                }\r
                else if(_parameters[0] == L"LEVELS")\r
                {\r
@@ -482,14 +470,11 @@ bool MixerCommand::DoExecute()
                        int duration = _parameters.size() > 6 ? boost::lexical_cast<int>(_parameters[6]) : 0;\r
                        std::wstring tween = _parameters.size() > 7 ? _parameters[7] : L"linear";\r
 \r
-                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                       auto transform = stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) -> frame_transform\r
                        {\r
                                transform.levels = value;\r
                                return transform;\r
-                       };\r
-                               \r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform, duration, tween);    \r
+                       }, duration, tween);\r
                }\r
                else if(_parameters[0] == L"VOLUME")\r
                {\r
@@ -497,14 +482,11 @@ bool MixerCommand::DoExecute()
                        std::wstring tween = _parameters.size() > 3 ? _parameters[3] : L"linear";\r
                        double value = boost::lexical_cast<double>(_parameters[1]);\r
 \r
-                       auto transform = [=](frame_transform transform) -> frame_transform\r
+                       auto transform = stage::transform_tuple_t(GetLayerIndex(), [=](frame_transform transform) -> frame_transform\r
                        {\r
                                transform.volume = value;\r
                                return transform;\r
-                       };\r
-                               \r
-                       int layer = GetLayerIndex();\r
-                       GetChannel()->stage()->apply_transform(GetLayerIndex(), transform, duration, tween);\r
+                       }, duration, tween);\r
                }\r
                else if(_parameters[0] == L"CLEAR")\r
                {\r
@@ -514,11 +496,23 @@ bool MixerCommand::DoExecute()
                        else\r
                                GetChannel()->stage()->clear_transforms(layer);\r
                }\r
+               else if(_parameters[0] == L"COMMIT")\r
+               {\r
+                       transforms = std::move(deferred_transforms[GetChannelIndex()]);\r
+               }\r
                else\r
                {\r
                        SetReplyString(TEXT("404 MIXER ERROR\r\n"));\r
                        return false;\r
                }\r
+\r
+               if(defer)\r
+               {\r
+                       auto& defer_tranforms = deferred_transforms[GetChannelIndex()];\r
+                       defer_tranforms.insert(defer_tranforms.end(), transforms.begin(), transforms.end());\r
+               }\r
+               else\r
+                       GetChannel()->stage()->apply_transforms(transforms);\r
        \r
                SetReplyString(TEXT("202 MIXER OK\r\n"));\r
 \r