]> git.sesse.net Git - casparcg/commitdiff
2.1.0: Integrating monitoring.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 10 Feb 2012 22:22:20 +0000 (22:22 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 10 Feb 2012 22:22:20 +0000 (22:22 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.1.0@2343 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

19 files changed:
common/reactive.h
core/producer/color/color_producer.cpp
core/producer/frame_producer.cpp
core/producer/frame_producer.h
core/producer/layer.cpp
core/producer/separated/separated_producer.cpp
core/producer/stage.cpp
core/producer/transition/transition_producer.cpp
core/producer/transition/transition_producer.h
core/video_channel.cpp
modules/decklink/producer/decklink_producer.cpp
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/flash/producer/flash_producer.cpp
modules/image/producer/image_producer.cpp
modules/image/producer/image_scroll_producer.cpp
modules/reroute/producer/reroute_producer.cpp
shell/main.cpp
shell/server.cpp
shell/server.h

index 8e526ff6d8d860337ceda6e7886ccc2df86cae46..88133c085a05023c2f2ac409833048d8c6e8a2f9 100644 (file)
@@ -306,7 +306,7 @@ template<typename F>
 spl::shared_ptr<observer_function<typename std::decay<typename detail::function_traits<F>::arg1_type>::type, F>> \r
 make_observer(F func)\r
 {\r
-       return std::make_shared<observer_function<std::decay<typename detail::function_traits<F>::arg1_type>::type, F>>(std::move(func));\r
+       return spl::make_shared<observer_function<std::decay<typename detail::function_traits<F>::arg1_type>::type, F>>(std::move(func));\r
 }\r
 \r
 template<typename T>\r
index f414d971f01e5bfc365e04e6c73783a28202aafc..142f140cc43eaf5f4dc76a7b7ffaf33f288752a3 100644 (file)
@@ -65,6 +65,11 @@ public:
                return L"color[" + color_str_ + L"]";\r
        }\r
 \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"color";\r
+       }\r
+\r
        boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
index 928ec5957ee3d4e63e25b0f337f3220c72a62e01..82ec06fe9f1f16435d825ad4ecdab90f26187b75 100644 (file)
@@ -56,6 +56,9 @@ struct empty_frame_producer : public frame_producer
        virtual void set_frame_factory(const spl::shared_ptr<frame_factory>&){}\r
        virtual uint32_t nb_frames() const {return 0;}\r
        virtual std::wstring print() const { return L"empty";}\r
+       virtual void subscribe(const monitor::observable::observer_ptr& o){}\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o){}  \r
+       virtual std::wstring name() const {return L"empty";}\r
        \r
        virtual boost::property_tree::wptree info() const override\r
        {\r
@@ -84,19 +87,25 @@ public:
        virtual spl::shared_ptr<draw_frame>                                                     receive(int hints) override                                                                                                             {return producer_->receive(hints);}\r
        virtual spl::shared_ptr<draw_frame>                                                     last_frame() const override                                                                                                             {return producer_->last_frame();}\r
        virtual std::wstring                                                                            print() const override                                                                                                                  {return producer_->print();}\r
+       virtual std::wstring                                                                            name() const override                                                                                                                   {return producer_->name();}\r
        virtual boost::property_tree::wptree                                            info() const override                                                                                                                   {return producer_->info();}\r
        virtual boost::unique_future<std::wstring>                                      call(const std::wstring& str) override                                                                                  {return producer_->call(str);}\r
        virtual spl::shared_ptr<frame_producer>                                         get_following_producer() const override                                                                                 {return producer_->get_following_producer();}\r
        virtual void                                                                                            set_leading_producer(const spl::shared_ptr<frame_producer>& producer) override  {return producer_->set_leading_producer(producer);}\r
        virtual uint32_t                                                                                        nb_frames() const override                                                                                                              {return producer_->nb_frames();}\r
+       virtual void subscribe(const monitor::observable::observer_ptr& o)                                                                                                                                                      {return producer_->subscribe(o);}\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o)                                                                                                                                            {return producer_->unsubscribe(o);}\r
 };\r
 \r
 class follow_producer_proxy : public producer_proxy_base\r
 {      \r
+       spl::shared_ptr<monitor::subject> event_subject_;\r
 public:\r
        follow_producer_proxy(spl::shared_ptr<frame_producer>&& producer) \r
                : producer_proxy_base(std::move(producer))\r
+               , event_subject_(new monitor::subject("asd"))\r
        {\r
+               producer->subscribe(event_subject_);\r
        }\r
 \r
        virtual spl::shared_ptr<draw_frame>     receive(int hints) override                                                                                                             \r
@@ -109,7 +118,10 @@ public:
                        if(following != frame_producer::empty())\r
                        {\r
                                following->set_leading_producer(spl::make_shared_ptr(producer_));\r
+\r
+                               producer_->unsubscribe(event_subject_);\r
                                producer_ = std::move(following);\r
+                               event_subject_->subscribe(event_subject_);\r
                        }\r
 \r
                        return receive(hints);\r
@@ -121,6 +133,16 @@ public:
        {\r
                return draw_frame::mute(producer_->last_frame());\r
        }\r
+\r
+       virtual void subscribe(const monitor::observable::observer_ptr& o) override                                                                                                                     \r
+       {\r
+               return event_subject_->subscribe(o);\r
+       }\r
+\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o) override           \r
+       {\r
+               return event_subject_->unsubscribe(o);\r
+       }\r
 };\r
 \r
 class destroy_producer_proxy : public producer_proxy_base\r
index 48f7bc72fe588c139e4fb35107ff28368f3a4dd1..abbc3784715834fb89198042696410bcb6dc7f50 100644 (file)
@@ -21,6 +21,8 @@
 \r
 #pragma once\r
 \r
+#include "../monitor/monitor.h"\r
+\r
 #include <common/forward.h>\r
 #include <common/spl/memory.h>\r
 #include <common/enum_class.h>\r
@@ -40,7 +42,8 @@ FORWARD1(boost, template<typename T> class unique_future);
 \r
 namespace caspar { namespace core {\r
        \r
-struct frame_producer : boost::noncopyable\r
+struct frame_producer : public monitor::observable\r
+                                         , boost::noncopyable\r
 {\r
        struct flags_def\r
        {\r
@@ -56,6 +59,7 @@ struct frame_producer : boost::noncopyable
        virtual ~frame_producer(){}     \r
 \r
        virtual std::wstring print() const = 0; // nothrow\r
+       virtual std::wstring name() const = 0;\r
        virtual boost::property_tree::wptree info() const = 0;\r
 \r
        virtual boost::unique_future<std::wstring> call(const std::wstring&);\r
@@ -68,7 +72,13 @@ struct frame_producer : boost::noncopyable
        virtual spl::shared_ptr<class draw_frame> receive(int flags) = 0;\r
        virtual spl::shared_ptr<class draw_frame> last_frame() const = 0;\r
 \r
+\r
        static const spl::shared_ptr<frame_producer>& empty(); // nothrow\r
+\r
+       // monitor::observable\r
+\r
+       virtual void subscribe(const monitor::observable::observer_ptr& o) {}\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o) {}\r
 };\r
 \r
 typedef std::function<spl::shared_ptr<core::frame_producer>(const spl::shared_ptr<struct frame_factory>&, const std::vector<std::wstring>&)> producer_factory_t;\r
index 1e85f467e5856bf2b81167bec90fc43682f1149a..d90f6d4739be3109ddeab8d5ff4eea2c73ec9030 100644 (file)
@@ -36,23 +36,29 @@ namespace caspar { namespace core {
 \r
 struct layer::impl\r
 {                              \r
-       monitor::subject                                event_subject_;\r
-       spl::shared_ptr<frame_producer> foreground_;\r
-       spl::shared_ptr<frame_producer> background_;\r
-       int64_t                                                 frame_number_;\r
-       boost::optional<int32_t>                auto_play_delta_;\r
-       bool                                                    is_paused_;\r
+       spl::shared_ptr<monitor::subject>       event_subject_;\r
+       spl::shared_ptr<monitor::subject>       foreground_event_subject_;\r
+       spl::shared_ptr<monitor::subject>       background_event_subject_;\r
+       spl::shared_ptr<frame_producer>         foreground_;\r
+       spl::shared_ptr<frame_producer>         background_;\r
+       int64_t                                                         frame_number_;\r
+       boost::optional<int32_t>                        auto_play_delta_;\r
+       bool                                                            is_paused_;\r
 \r
 public:\r
        impl(int index) \r
-               : event_subject_(monitor::path("layer") % index)\r
+               : event_subject_(new monitor::subject(monitor::path("layer") % index))\r
+               , foreground_event_subject_(new monitor::subject("foreground"))\r
+               , background_event_subject_(new monitor::subject("background"))\r
                , foreground_(frame_producer::empty())\r
                , background_(frame_producer::empty())\r
                , frame_number_(0)\r
                , is_paused_(false)\r
        {\r
+               foreground_event_subject_->subscribe(event_subject_);\r
+               background_event_subject_->subscribe(event_subject_);\r
        }\r
-       \r
+\r
        void pause()\r
        {\r
                is_paused_ = true;\r
@@ -65,7 +71,10 @@ public:
 \r
        void load(spl::shared_ptr<frame_producer> producer, const boost::optional<int32_t>& auto_play_delta)\r
        {               \r
-               background_              = std::move(producer);\r
+               background_->unsubscribe(background_event_subject_);\r
+               background_ = std::move(producer);\r
+               background_->subscribe(background_event_subject_);\r
+\r
                auto_play_delta_ = auto_play_delta;\r
 \r
                if(auto_play_delta_ && foreground_ == frame_producer::empty())\r
@@ -77,8 +86,15 @@ public:
                if(background_ != frame_producer::empty())\r
                {\r
                        background_->set_leading_producer(foreground_);\r
-                       foreground_             = background_;\r
-                       background_             = frame_producer::empty();\r
+\r
+                       background_->unsubscribe(background_event_subject_);\r
+                       foreground_->unsubscribe(foreground_event_subject_);\r
+\r
+                       foreground_ = std::move(background_);\r
+                       background_ = std::move(frame_producer::empty());\r
+                       \r
+                       foreground_->subscribe(foreground_event_subject_);\r
+\r
                        frame_number_   = 0;\r
                        auto_play_delta_.reset();\r
                }\r
@@ -88,7 +104,10 @@ public:
        \r
        void stop()\r
        {\r
-               foreground_             = frame_producer::empty();\r
+               foreground_->unsubscribe(foreground_event_subject_);\r
+\r
+               foreground_ = std::move(frame_producer::empty());\r
+\r
                frame_number_   = 0;\r
                auto_play_delta_.reset();\r
 \r
@@ -118,11 +137,14 @@ public:
                                }\r
                        }\r
 \r
-                       event_subject_  << monitor::event("state")      % u8(is_paused_ ? L"paused" : (foreground_ == frame_producer::empty() ? L"stopped" : L"playing"))                                                       \r
+                       *event_subject_ << monitor::event("state")      % u8(is_paused_ ? L"paused" : (foreground_ == frame_producer::empty() ? L"stopped" : L"playing"))                                                       \r
                                                        << monitor::event("time")       % monitor::duration(frame_number_/format_desc.fps)\r
                                                                                                                % monitor::duration(static_cast<int64_t>(foreground_->nb_frames()) - static_cast<int64_t>(auto_play_delta_ ? *auto_play_delta_ : 0)/format_desc.fps)\r
                                                        << monitor::event("frame")      % static_cast<int64_t>(frame_number_)\r
                                                                                                                % static_cast<int64_t>((static_cast<int64_t>(foreground_->nb_frames()) - static_cast<int64_t>(auto_play_delta_ ? *auto_play_delta_ : 0)));\r
+\r
+                       *foreground_event_subject_ << monitor::event("type") % u8(foreground_->name());\r
+                       *background_event_subject_ << monitor::event("type") % u8(foreground_->name());\r
                                \r
                        return frame;\r
                }\r
@@ -170,6 +192,6 @@ spl::shared_ptr<draw_frame> layer::receive(frame_producer::flags flags, const vi
 spl::shared_ptr<frame_producer> layer::foreground() const { return impl_->foreground_;}\r
 spl::shared_ptr<frame_producer> layer::background() const { return impl_->background_;}\r
 boost::property_tree::wptree layer::info() const{return impl_->info();}\r
-void layer::subscribe(const monitor::observable::observer_ptr& o) {impl_->event_subject_.subscribe(o);}\r
-void layer::unsubscribe(const monitor::observable::observer_ptr& o) {impl_->event_subject_.unsubscribe(o);}\r
+void layer::subscribe(const monitor::observable::observer_ptr& o) {impl_->event_subject_->subscribe(o);}\r
+void layer::unsubscribe(const monitor::observable::observer_ptr& o) {impl_->event_subject_->unsubscribe(o);}\r
 }}
\ No newline at end of file
index 0f39b0800ea95cbba3159a9e5d33d9812d7f7368..65ccb3134cafaa609a89cda8607460ee69edbd9f 100644 (file)
@@ -92,6 +92,11 @@ struct separated_producer : public frame_producer
                return L"separated[fill:" + fill_producer_->print() + L"|key[" + key_producer_->print() + L"]]";\r
        }       \r
 \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"separated";\r
+       }\r
+\r
        boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
@@ -100,6 +105,16 @@ struct separated_producer : public frame_producer
                info.add_child(L"key.producer", key_producer_->info());\r
                return info;\r
        }\r
+\r
+       virtual void subscribe(const monitor::observable::observer_ptr& o) override                                                                                                                     \r
+       {\r
+               return fill_producer_->subscribe(o);\r
+       }\r
+\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o) override           \r
+       {\r
+               return fill_producer_->unsubscribe(o);\r
+       }\r
 };\r
 \r
 spl::shared_ptr<frame_producer> create_separated_producer(const spl::shared_ptr<frame_producer>& fill, const spl::shared_ptr<frame_producer>& key)\r
index 14a284141cb73b7ca7e7ff485a79cea98c279ea8..be554480f1f296564f93c630369cd4fe8611e4c5 100644 (file)
@@ -90,6 +90,7 @@ public:
                        }       \r
                        \r
                        graph_->set_value("produce-time", frame_timer.elapsed()*format_desc.fps*0.5);\r
+                       //*event_subject_ << monitor::event("profiler/time") % frame_timer.elapsed() % (1.0/format_desc.fps);\r
 \r
                        return frames;\r
                });\r
index c6332e6f874ade318f316331aee3e5a1819883dd..7e0b9d4a1d09858d722e49e3d4b34ea1965adf79 100644 (file)
@@ -26,6 +26,7 @@
 #include "../frame_producer.h"\r
 #include "../../frame/draw_frame.h"\r
 #include "../../frame/frame_transform.h"\r
+#include "../../monitor/monitor.h"\r
 \r
 #include <tbb/parallel_invoke.h>\r
 \r
@@ -33,15 +34,16 @@ namespace caspar { namespace core {
 \r
 struct transition_producer : public frame_producer\r
 {      \r
-       const field_mode                mode_;\r
-       unsigned int                            current_frame_;\r
+       spl::shared_ptr<monitor::subject>       event_subject_;\r
+       const field_mode                                        mode_;\r
+       int                                                                     current_frame_;\r
        \r
-       const transition_info           info_;\r
+       const transition_info                           info_;\r
        \r
-       spl::shared_ptr<frame_producer> dest_producer_;\r
-       spl::shared_ptr<frame_producer> source_producer_;\r
+       spl::shared_ptr<frame_producer>         dest_producer_;\r
+       spl::shared_ptr<frame_producer>         source_producer_;\r
 \r
-       spl::shared_ptr<draw_frame>             last_frame_;\r
+       spl::shared_ptr<draw_frame>                     last_frame_;\r
                \r
        explicit transition_producer(const field_mode& mode, const spl::shared_ptr<frame_producer>& dest, const transition_info& info) \r
                : mode_(mode)\r
@@ -49,7 +51,10 @@ struct transition_producer : public frame_producer
                , info_(info)\r
                , dest_producer_(dest)\r
                , source_producer_(frame_producer::empty())\r
-               , last_frame_(draw_frame::empty()){}\r
+               , last_frame_(draw_frame::empty())\r
+       {\r
+               dest->subscribe(event_subject_);\r
+       }\r
        \r
        // frame_producer\r
 \r
@@ -68,6 +73,20 @@ struct transition_producer : public frame_producer
                if(++current_frame_ >= info_.duration)\r
                        return draw_frame::eof();\r
                \r
+               *event_subject_ << monitor::event("transition/frame") % current_frame_ % info_.duration\r
+                                               << monitor::event("transition/type") % [&]() -> std::string\r
+                                                                                                                               {\r
+                                                                                                                                       switch(info_.type.value())\r
+                                                                                                                                       {\r
+                                                                                                                                       case transition_type::mix:              return "mix";\r
+                                                                                                                                       case transition_type::wipe:             return "wipe";\r
+                                                                                                                                       case transition_type::slide:    return "slide";\r
+                                                                                                                                       case transition_type::push:             return "push";\r
+                                                                                                                                       case transition_type::cut:              return "cut";\r
+                                                                                                                                       default:                                                return "n/a";\r
+                                                                                                                                       }\r
+                                                                                                                               }();\r
+\r
                auto dest = draw_frame::empty();\r
                auto source = draw_frame::empty();\r
 \r
@@ -83,7 +102,7 @@ struct transition_producer : public frame_producer
                        source = source_producer_->receive(flags);\r
                        if(source == core::draw_frame::late())\r
                                source = source_producer_->last_frame();\r
-               });\r
+               });             \r
 \r
                return compose(dest, source);\r
        }\r
@@ -102,6 +121,11 @@ struct transition_producer : public frame_producer
        {\r
                return L"transition[" + source_producer_->print() + L"=>" + dest_producer_->print() + L"]";\r
        }\r
+\r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"transition";\r
+       }\r
        \r
        boost::property_tree::wptree info() const override\r
        {\r
@@ -172,6 +196,16 @@ struct transition_producer : public frame_producer
 \r
                return draw_frame::over(s_frame, d_frame);\r
        }\r
+\r
+       virtual void subscribe(const monitor::observable::observer_ptr& o) override                                                                                                                     \r
+       {\r
+               return event_subject_->subscribe(o);\r
+       }\r
+\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o) override           \r
+       {\r
+               return event_subject_->unsubscribe(o);\r
+       }\r
 };\r
 \r
 spl::shared_ptr<frame_producer> create_transition_producer(const field_mode& mode, const spl::shared_ptr<frame_producer>& destination, const transition_info& info)\r
index c5fa5b0a22af8533b4f37fe4bcda9ff1a40f3402..30d5deadf2205bf94c78ae8db970eef7addde2e4 100644 (file)
@@ -64,7 +64,7 @@ struct transition_info
                , direction(transition_direction::from_left)\r
                , tweener(L"linear"){}\r
                \r
-       size_t                                  duration;\r
+       int                                             duration;\r
        transition_direction    direction;\r
        transition_type                 type;\r
        tweener                                 tweener;\r
index 661bb969bea6c440cad529e5dd7ec9d3a0d20ca4..af03254b1fa4ee0fc26310f6d81616a941341e56 100644 (file)
@@ -123,8 +123,8 @@ public:
                \r
                        graph_->set_value("tick-time", frame_timer.elapsed()*format_desc.fps*0.5);\r
 \r
-                       *event_subject_ << monitor::event("debug/time")  % frame_timer.elapsed();\r
-                       *event_subject_ << monitor::event("format")             % u8(format_desc.name);\r
+                       //*event_subject_ << monitor::event("debug/profiler")  % frame_timer.elapsed() % (1.0/format_desc_.fps);\r
+                       //*event_subject_ << monitor::event("format")           % u8(format_desc.name);\r
                }\r
                catch(...)\r
                {\r
index fa578c6f4f54254efc8ce7f3f76e9b9b09c2b204..a67c66ac517540a903502d5766f614b1928e5f2d 100644 (file)
@@ -315,10 +315,15 @@ public:
                return length_;\r
        }\r
        \r
-       std::wstring print() const override\r
+       virtual std::wstring print() const override\r
        {\r
                return producer_->print();\r
        }\r
+       \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"decklinke";\r
+       }\r
 \r
        virtual boost::property_tree::wptree info() const override\r
        {\r
index 7cfec870b5906ee9dd3711be72da5886df4cc9db..da285c30917e60769f7ee37a1258fad46fd5d1b3 100644 (file)
@@ -41,6 +41,7 @@
 #include <core/frame/frame_factory.h>\r
 #include <core/frame/draw_frame.h>\r
 #include <core/frame/frame_transform.h>\r
+#include <core/monitor/monitor.h>\r
 \r
 #include <boost/algorithm/string.hpp>\r
 #include <common/assert.h>\r
@@ -64,10 +65,10 @@ namespace caspar { namespace ffmpeg {
                                \r
 struct ffmpeg_producer : public core::frame_producer\r
 {\r
+       spl::shared_ptr<monitor::subject>                                                       event_subject_;\r
        const std::wstring                                                                                      filename_;\r
        \r
        const spl::shared_ptr<diagnostics::graph>                                       graph_;\r
-       boost::timer                                                                                            frame_timer_;\r
                                        \r
        const spl::shared_ptr<core::frame_factory>                                      frame_factory_;\r
        const core::video_format_desc                                                           format_desc_;\r
@@ -141,16 +142,31 @@ public:
        \r
        virtual spl::shared_ptr<core::draw_frame> receive(int flags) override\r
        {               \r
-               frame_timer_.restart();\r
+               boost::timer frame_timer;\r
                                \r
                std::shared_ptr<core::draw_frame> frame = try_decode_frame(flags);\r
                                                        \r
-               graph_->set_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
+               graph_->set_value("frame-time", frame_timer.elapsed()*format_desc_.fps*0.5);\r
+               \r
+               *event_subject_ << monitor::event("profiler/time")              % frame_timer.elapsed() % (1.0/format_desc_.fps)                                        \r
+                                               << monitor::event("file/time")                  % monitor::duration(file_frame_number()/fps_) \r
+                                                                                                                               % monitor::duration(file_nb_frames()/fps_)\r
+                                               << monitor::event("file/frame")                 % static_cast<int64_t>(file_frame_number())\r
+                                                                                                                               % static_cast<int64_t>(file_nb_frames())\r
+                                               << monitor::event("file/fps")                   % fps_\r
+                                               << monitor::event("file/video/mode")    % u8(print_mode())\r
+                                               << monitor::event("file/video/codec")   % (video_decoder_ ? u8(video_decoder_->print()) : "n/a")\r
+                                               << monitor::event("file/audio/codec")   % (audio_decoder_ ? u8(audio_decoder_->print()) : "n/a")\r
+                                               << monitor::event("filename")                   % u8(filename_)\r
+                                               << monitor::event("loop")                               % input_.loop();\r
                                \r
                if(!frame)\r
                {\r
-                       if(!input_.eof())                               \r
+                       if(!input_.eof())               \r
+                       {\r
                                graph_->set_tag("underflow");   \r
+                               *event_subject_ << monitor::event("underflow") % true;\r
+                       }\r
                        return last_frame();\r
                }\r
                                \r
@@ -206,6 +222,11 @@ public:
                                                  + boost::lexical_cast<std::wstring>(file_frame_number()) + L"/" + boost::lexical_cast<std::wstring>(file_nb_frames()) + L"]";\r
        }\r
 \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"ffmpeg";\r
+       }\r
+\r
        boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
@@ -223,12 +244,22 @@ public:
                info.add(L"file-nb-frames",             file_nb_frames());\r
                return info;\r
        }\r
+       \r
+       virtual void subscribe(const monitor::observable::observer_ptr& o) override\r
+       {\r
+               event_subject_->subscribe(o);\r
+       }\r
+\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o) override\r
+       {\r
+               event_subject_->unsubscribe(o);\r
+       }\r
 \r
        // ffmpeg_producer\r
 \r
        std::wstring print_mode() const\r
        {\r
-               return video_decoder_ ? ffmpeg::print_mode(video_decoder_->width(), video_decoder_->height(), fps_, !video_decoder_->is_progressive()) : L"";\r
+               return video_decoder_ ? ffmpeg::print_mode(video_decoder_->width(), video_decoder_->height(), fps_, !video_decoder_->is_progressive()) : L"n/a";\r
        }\r
                                        \r
        std::wstring do_call(const std::wstring& param)\r
index ba30dfc9f042e50b48afb3fd54b9445381c48880..d22b8912c3dfe58b611b9db2525767b126fc135c 100644 (file)
@@ -422,6 +422,11 @@ public:
                return L"flash[" + boost::filesystem::path(filename_).wstring() + L"|" + boost::lexical_cast<std::wstring>(fps_) + L"]";                \r
        }       \r
 \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"flash";\r
+       }\r
+\r
        virtual boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
index 69b2c783a505c6c5a5daf2a6d2667a5df13a29e9..0b77bb8dbf5a6fb081adc123ca50b302a7f4b887 100644 (file)
@@ -80,6 +80,11 @@ struct image_producer : public core::frame_producer
                return L"image_producer[" + filename_ + L"]";\r
        }\r
 \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"image";\r
+       }\r
+\r
        virtual boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
index 3dbaafe5677ba73735f8d5e68b806117df68e877..67071b15fe257bb2b8463e78ef815415fe2a3849 100644 (file)
@@ -201,6 +201,11 @@ struct image_scroll_producer : public core::frame_producer
                return L"image_scroll_producer[" + filename_ + L"]";\r
        }\r
 \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"image-scroll";\r
+       }\r
+\r
        virtual boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
index 479bc0af50d1f62bcbdf7040c1c2ec278ff5233c..643836878ed63a6e4a517e884a3cd6cf20e80ee6 100644 (file)
@@ -128,6 +128,11 @@ public:
                return L"reroute[]";\r
        }\r
 \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"reroute";\r
+       }\r
+\r
        virtual boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
index 642e4cb1b4a438c86d4afbfa387b571893de8034..394751cb5bd6c6c801592cb0caa44d3427918937 100644 (file)
@@ -226,7 +226,7 @@ int main(int argc, wchar_t* argv[])
 \r
                // Print environment information.\r
                print_info();\r
-                       \r
+               \r
                std::wstringstream str;\r
                boost::property_tree::xml_writer_settings<wchar_t> w(' ', 3);\r
                boost::property_tree::write_xml(str, caspar::env::properties(), w);\r
@@ -241,6 +241,13 @@ int main(int argc, wchar_t* argv[])
 \r
                        // Create a dummy client which prints amcp responses to console.\r
                        auto console_client = std::make_shared<caspar::IO::ConsoleClientInfo>();\r
+                       \r
+                       //auto console_obs = caspar::reactive::make_observer([](const caspar::monitor::event& e)\r
+                       //{\r
+                       //      std::cout << e.path().str() << std::endl;\r
+                       //});\r
+                       //\r
+                       //caspar_server.subscribe(console_obs);\r
 \r
                        std::wstring wcmd;\r
                        while(true)\r
index e05fea63ff8d9ef49cc88398fc3ace5cb5eb9683..b66295dd287a88a7a81f6da0e31a93c8969d00c7 100644 (file)
@@ -67,6 +67,7 @@ using namespace protocol;
 \r
 struct server::impl : boost::noncopyable\r
 {\r
+       spl::shared_ptr<monitor::subject>                                       event_subject_;\r
        std::unique_ptr<accelerator::factory>                           accel_factory_;\r
        std::vector<spl::shared_ptr<IO::AsyncEventServer>>      async_servers_; \r
        std::vector<spl::shared_ptr<video_channel>>                     channels_;\r
@@ -137,7 +138,7 @@ struct server::impl : boost::noncopyable
                        if(format_desc.format == video_format::invalid)\r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Invalid video-mode."));\r
                        \r
-                       channels_.push_back(spl::make_shared<video_channel>(static_cast<int>(channels_.size()+1), format_desc, accel_factory_->create_image_mixer()));\r
+                       auto channel = spl::make_shared<video_channel>(static_cast<int>(channels_.size()+1), format_desc, accel_factory_->create_image_mixer());\r
                        \r
                        BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child(L"consumers"))\r
                        {\r
@@ -145,15 +146,15 @@ struct server::impl : boost::noncopyable
                                {\r
                                        auto name = xml_consumer.first;\r
                                        if(name == L"screen")\r
-                                               channels_.back()->output()->add(caspar::screen::create_consumer(xml_consumer.second));                                  \r
+                                               channel->output()->add(caspar::screen::create_consumer(xml_consumer.second));                                   \r
                                        else if(name == L"bluefish")                                    \r
-                                               channels_.back()->output()->add(bluefish::create_consumer(xml_consumer.second));                                        \r
+                                               channel->output()->add(bluefish::create_consumer(xml_consumer.second));                                 \r
                                        else if(name == L"decklink")                                    \r
-                                               channels_.back()->output()->add(decklink::create_consumer(xml_consumer.second));                                \r
+                                               channel->output()->add(decklink::create_consumer(xml_consumer.second));                         \r
                                        else if(name == L"file")                                        \r
-                                               channels_.back()->output()->add(ffmpeg::create_consumer(xml_consumer.second));                                          \r
+                                               channel->output()->add(ffmpeg::create_consumer(xml_consumer.second));                                           \r
                                        else if(name == L"system-audio")\r
-                                               channels_.back()->output()->add(oal::create_consumer());                \r
+                                               channel->output()->add(oal::create_consumer());         \r
                                        else if(name != L"<xmlcomment>")\r
                                                CASPAR_LOG(warning) << "Invalid consumer: " << name;    \r
                                }\r
@@ -161,7 +162,10 @@ struct server::impl : boost::noncopyable
                                {\r
                                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                                }\r
-                       }                                                       \r
+                       }               \r
+\r
+                   channel->subscribe(monitor::observable::observer_ptr(event_subject_));\r
+                       channels_.push_back(channel);\r
                }\r
 \r
                // Dummy diagnostics channel\r
@@ -215,5 +219,7 @@ const std::vector<spl::shared_ptr<video_channel>> server::get_channels() const
 {\r
        return impl_->channels_;\r
 }\r
+void server::subscribe(const monitor::observable::observer_ptr& o){impl_->event_subject_->subscribe(o);}\r
+void server::unsubscribe(const monitor::observable::observer_ptr& o){impl_->event_subject_->unsubscribe(o);}\r
 \r
 }
\ No newline at end of file
index 74a6fda4feb3822edea4acd5212794e37166d67b..bc92d0babe33333d43cbecc20a174e31ea9de920 100644 (file)
@@ -23,6 +23,8 @@
 \r
 #include <common/spl/memory.h>\r
 \r
+#include <core/monitor/monitor.h>\r
+\r
 #include <boost/noncopyable.hpp>\r
 \r
 #include <vector>\r
@@ -33,11 +35,17 @@ namespace core {
        class video_channel;\r
 }\r
 \r
-class server sealed : boost::noncopyable\r
+class server sealed : public monitor::subject\r
+                                       , boost::noncopyable\r
 {\r
 public:\r
        server();\r
        const std::vector<spl::shared_ptr<core::video_channel>> get_channels() const;\r
+\r
+       // monitor::observable\r
+\r
+       virtual void subscribe(const monitor::observable::observer_ptr& o) override;\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o) override;\r
 private:\r
        struct impl;\r
        spl::shared_ptr<impl> impl_;\r