]> git.sesse.net Git - casparcg/commitdiff
Draft of interaction with producers and scene_producer
authorHelge Norberg <helge.norberg@svt.se>
Thu, 4 Jul 2013 09:11:00 +0000 (11:11 +0200)
committerHelge Norberg <helge.norberg@svt.se>
Thu, 4 Jul 2013 09:11:00 +0000 (11:11 +0200)
common/memory.h
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
modules/screen/consumer/screen_consumer.cpp
modules/screen/consumer/screen_consumer.h
shell/server.cpp

index 8bf205e16dcebb76b1bec80a14e2d545e0701adb..2927970c92730b07e147101342e37623912e1f47 100644 (file)
@@ -269,7 +269,7 @@ unique_ptr<T> const_pointer_cast(const unique_ptr<T2>& p)
 template <class T, class T2>
 unique_ptr<T> dynamic_pointer_cast(const unique_ptr<T2>& p)
 {
-    aT2to temp = std::dynamic_pointer_cast<T>(std::unique_ptr<T2>(p));
+    auto temp = std::dynamic_pointer_cast<T>(std::unique_ptr<T2>(p));
     if(!temp)
         throw std::bad_cast();
     return unique_ptr<T>(std::move(temp));
@@ -599,7 +599,7 @@ shared_ptr<T> const_pointer_cast(const shared_ptr<T2>& p)
 template <class T, class T2>
 shared_ptr<T> dynamic_pointer_cast(const shared_ptr<T2>& p)
 {
-    aT2to temp = std::dynamic_pointer_cast<T>(std::shared_ptr<T2>(p));
+    auto temp = std::dynamic_pointer_cast<T>(std::shared_ptr<T2>(p));
     if(!temp)
         throw std::bad_cast();
     return shared_ptr<T>(std::move(temp));
index 61a4f2abc58c8252fe0315373b892d40f5f27dc6..1a9eac90c64928e5e7cfe8c3feb073448452609c 100644 (file)
@@ -100,6 +100,7 @@ class decklink_producer : boost::noncopyable, public IDeckLinkInputCallback
        spl::shared_ptr<core::frame_factory>                    frame_factory_;
        core::video_format_desc                                                 in_format_desc_;
        core::video_format_desc                                                 out_format_desc_;
+       core::constraints                                                               constraints_;
 
        tbb::concurrent_bounded_queue<core::draw_frame> frame_buffer_;
 
@@ -119,6 +120,7 @@ public:
                , filter_(filter)
                , in_format_desc_(in_format_desc)
                , out_format_desc_(out_format_desc)
+               , constraints_(in_format_desc.width, in_format_desc.height)
                , muxer_(in_format_desc.fps, frame_factory, out_format_desc, filter)
                , audio_cadence_(out_format_desc.audio_cadence)
                , sync_buffer_(out_format_desc.audio_cadence.size())
@@ -169,6 +171,11 @@ public:
                }
        }
 
+       core::constraints& pixel_constraints()
+       {
+               return constraints_;
+       }
+
        virtual HRESULT STDMETHODCALLTYPE       QueryInterface (REFIID, LPVOID*)        {return E_NOINTERFACE;}
        virtual ULONG STDMETHODCALLTYPE         AddRef ()                                                       {return 1;}
        virtual ULONG STDMETHODCALLTYPE         Release ()                                                      {return 1;}
@@ -354,6 +361,11 @@ public:
        {               
                return producer_->get_frame();
        }
+
+       core::constraints& pixel_constraints() override
+       {
+               return producer_->pixel_constraints();
+       }
                        
        uint32_t nb_frames() const override
        {
index 3a378a2bb73e3b730062909832b6dd4e80dca5d6..725c3f01a7a90bf15eeadea75bea5c5d4d9b434a 100644 (file)
@@ -82,6 +82,7 @@ struct ffmpeg_producer : public core::frame_producer_base
        std::unique_ptr<video_decoder>                                  video_decoder_;
        std::unique_ptr<audio_decoder>                                  audio_decoder_; 
        frame_muxer                                                                             muxer_;
+       core::constraints                                                               constraints_;
        
        core::draw_frame                                                                last_frame_;
 
@@ -113,6 +114,8 @@ public:
                {
                        video_decoder_.reset(new video_decoder(input_));
                        video_decoder_->subscribe(event_subject_);
+                       constraints_.width.set(video_decoder_->width());
+                       constraints_.height.set(video_decoder_->height());
                        
                        CASPAR_LOG(info) << print() << L" " << video_decoder_->print();
                }
@@ -187,7 +190,12 @@ public:
                end_seek();
                return core::draw_frame::still(last_frame_);
        }
-               
+
+       core::constraints& pixel_constraints() override
+       {
+               return constraints_;
+       }
+
        uint32_t nb_frames() const override
        {
                if(input_.loop())
index 2ccfcdd00e483ab635482663ca8f227e0e1187a5..8b734933f8650039f2673f6ecb68a69e5f5b8c61 100644 (file)
@@ -330,6 +330,7 @@ struct flash_producer : public core::frame_producer_base
        const core::video_format_desc                                   format_desc_;
        const int                                                                               width_;
        const int                                                                               height_;
+       core::constraints                                                               constraints_;
        const int                                                                               buffer_size_;
 
        tbb::atomic<int>                                                                fps_;
@@ -352,6 +353,7 @@ public:
                , format_desc_(format_desc)
                , width_(width > 0 ? width : format_desc.width)
                , height_(height > 0 ? height : format_desc.height)
+               , constraints_(width_, height_)
                , buffer_size_(env::properties().get(L"configuration.flash.buffer-depth", format_desc.fps > 30.0 ? 4 : 2))
                , executor_(L"flash_producer")
        {       
@@ -393,6 +395,11 @@ public:
 
                return last_frame_ = frame;
        }
+
+       core::constraints& pixel_constraints() override
+       {
+               return constraints_;
+       }
                
        boost::unique_future<std::wstring> call(const std::wstring& param) override
        {       
index 059decfa8b96f9425172f8dd8c3ec3299d68d666..6b8ea158f8b4773d26f3ed8e859f31923151c662 100644 (file)
@@ -51,6 +51,7 @@ struct image_producer : public core::frame_producer_base
        monitor::basic_subject  event_subject_;
        const std::wstring              filename_;
        core::draw_frame                frame_;
+       core::constraints               constraints_;
        
        explicit image_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) 
                : filename_(filename)
@@ -60,11 +61,15 @@ struct image_producer : public core::frame_producer_base
                FreeImage_FlipVertical(bitmap.get());
                
                core::pixel_format_desc desc = core::pixel_format::bgra;
-               desc.planes.push_back(core::pixel_format_desc::plane(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), 4));
+               auto width = FreeImage_GetWidth(bitmap.get());
+               auto height = FreeImage_GetHeight(bitmap.get());
+               desc.planes.push_back(core::pixel_format_desc::plane(width, height, 4));
                auto frame = frame_factory->create_frame(this, desc);
 
                std::copy_n(FreeImage_GetBits(bitmap.get()), frame.image_data(0).size(), frame.image_data(0).begin());
                frame_ = core::draw_frame(std::move(frame));
+               constraints_.width.set(width);
+               constraints_.height.set(height);
 
                CASPAR_LOG(info) << print() << L" Initialized";
        }
@@ -77,6 +82,11 @@ struct image_producer : public core::frame_producer_base
 
                return frame_;
        }
+
+       core::constraints& pixel_constraints() override
+       {
+               return constraints_;
+       }
                        
        std::wstring print() const override
        {
index 097451d30165a89233f00f249b1b5350bf2116ab..5d10afc5aa0fd64dad54b63bace5a5aad8893d07 100644 (file)
@@ -64,6 +64,7 @@ struct image_scroll_producer : public core::frame_producer_base
        core::video_format_desc                 format_desc_;
        int                                                             width_;
        int                                                             height_;
+       core::constraints                               constraints_;
 
        double                                                  delta_;
        double                                                  speed_;
@@ -94,6 +95,8 @@ struct image_scroll_producer : public core::frame_producer_base
 
                width_  = FreeImage_GetWidth(bitmap.get());
                height_ = FreeImage_GetHeight(bitmap.get());
+               constraints_.width.set(width_);
+               constraints_.height.set(height_);
 
                bool vertical = width_ == format_desc_.width;
                bool horizontal = height_ == format_desc_.height;
@@ -352,6 +355,11 @@ struct image_scroll_producer : public core::frame_producer_base
 
                return result;
        }
+
+       core::constraints& pixel_constraints() override
+       {
+               return constraints_;
+       }
                                
        std::wstring print() const override
        {
index 11313a1077dbc48b26c3329eafc940d76e00544f..40daf74ff6982749b34f3e14ca4ae64ddaac7b45 100644 (file)
@@ -54,6 +54,7 @@ namespace caspar { namespace reroute {
 class reroute_producer : public reactive::observer<std::map<int, core::draw_frame>>
                                           , public core::frame_producer_base
 {
+       core::constraints                                                                                               constraints_;
        const spl::shared_ptr<diagnostics::graph>                                               graph_;
        
        tbb::concurrent_bounded_queue<std::map<int, core::draw_frame>>  input_buffer_;
@@ -88,7 +89,12 @@ public:
                }
 
                return boost::accumulate(frames | boost::adaptors::map_values, core::draw_frame::empty(), core::draw_frame::over);
-       }       
+       }
+
+       core::constraints& pixel_constraints() override
+       {
+               return constraints_;
+       }
                
        std::wstring print() const override
        {
index 4042b04f2aa9de7a86710ddb7c21f461583b6323..5a829cd6b74dbcd321a02a4cc25d5ff388b881f2 100644 (file)
@@ -39,6 +39,7 @@
 #include <core/video_format.h>
 #include <core/frame/frame.h>
 #include <core/consumer/frame_consumer.h>
+#include <core/consumer/frame_consumer.h>
 
 #include <boost/timer.hpp>
 #include <boost/circular_buffer.hpp>
@@ -100,6 +101,7 @@ struct configuration
        bool                    key_only;
        aspect_ratio    aspect; 
        bool                    vsync;
+       bool                    interactive;
 
        configuration()
                : name(L"ogl")
@@ -110,6 +112,7 @@ struct configuration
                , key_only(false)
                , aspect(aspect_invalid)
                , vsync(true)
+               , interactive(true)
        {
        }
 };
@@ -141,13 +144,14 @@ struct screen_consumer : boost::noncopyable
        caspar::prec_timer                                      wait_timer_;
 
        tbb::concurrent_bounded_queue<core::const_frame>        frame_buffer_;
+       core::interaction_sink*                                                         sink_;
 
        boost::thread                                           thread_;
        tbb::atomic<bool>                                       is_running_;
        
        ffmpeg::filter                                          filter_;
 public:
-       screen_consumer(const configuration& config, const core::video_format_desc& format_desc, int channel_index) 
+       screen_consumer(const configuration& config, const core::video_format_desc& format_desc, int channel_index, core::interaction_sink* sink
                : config_(config)
                , format_desc_(format_desc)
                , channel_index_(channel_index)
@@ -157,6 +161,7 @@ public:
                , screen_height_(format_desc.height)
                , square_width_(format_desc.square_width)
                , square_height_(format_desc.square_height)
+               , sink_(sink)
                , filter_(format_desc.field_mode == core::field_mode::progressive || !config.auto_deinterlace ? L"" : L"YADIF=1:-1", boost::assign::list_of(PIX_FMT_BGRA))
        {               
                if(format_desc_.format == core::video_format::ntsc && config_.aspect == configuration::aspect_4_3)
@@ -171,7 +176,7 @@ public:
                                square_width_ = (format_desc.height*4)/3;
                }
 
-               frame_buffer_.set_capacity(2);
+               frame_buffer_.set_capacity(1);
                
                graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f));   
                graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));
@@ -210,7 +215,7 @@ public:
        void init()
        {
                window_.Create(sf::VideoMode(screen_width_, screen_height_, 32), u8(L"Screen consumer " + channel_and_format()), config_.windowed ? sf::Style::Resize | sf::Style::Close : sf::Style::Fullscreen);
-               window_.ShowMouseCursor(false);
+               window_.ShowMouseCursor(config_.interactive);
                window_.SetPosition(screen_x_, screen_y_);
                window_.SetSize(screen_width_, screen_height_);
                window_.SetActive();
@@ -286,10 +291,37 @@ public:
                                        sf::Event e;            
                                        while(window_.GetEvent(e))
                                        {
-                                               if(e.Type == sf::Event::Resized)
+                                               if (e.Type == sf::Event::Resized)
                                                        calculate_aspect();
-                                               else if(e.Type == sf::Event::Closed)
+                                               else if (e.Type == sf::Event::Closed)
                                                        is_running_ = false;
+                                               else if (config_.interactive && sink_)
+                                               {
+                                                       switch (e.Type)
+                                                       {
+                                                       case sf::Event::MouseMoved:
+                                                               {
+                                                                       auto& mouse_move = e.MouseMove;
+                                                                       sink_->on_interaction(spl::make_shared<core::mouse_move_event>(
+                                                                                       1,
+                                                                                       static_cast<double>(mouse_move.X) / screen_width_,
+                                                                                       static_cast<double>(mouse_move.Y) / screen_height_));
+                                                               }
+                                                               break;
+                                                       case sf::Event::MouseButtonPressed:
+                                                       case sf::Event::MouseButtonReleased:
+                                                               {
+                                                                       auto& mouse_button = e.MouseButton;
+                                                                       sink_->on_interaction(spl::make_shared<core::mouse_button_event>(
+                                                                                       1,
+                                                                                       static_cast<double>(mouse_button.X) / screen_width_,
+                                                                                       static_cast<double>(mouse_button.Y) / screen_height_,
+                                                                                       static_cast<int>(mouse_button.Button),
+                                                                                       e.Type == sf::Event::MouseButtonPressed));
+                                                               }
+                                                               break;
+                                                       }
+                                               }
                                        }
                        
                                        auto frame = core::const_frame::empty();
@@ -524,18 +556,22 @@ struct screen_consumer_proxy : public core::frame_consumer
 {
        const configuration config_;
        std::unique_ptr<screen_consumer> consumer_;
+       core::interaction_sink* sink_;
 
 public:
 
-       screen_consumer_proxy(const configuration& config)
-               : config_(config){}
+       screen_consumer_proxy(const configuration& config, core::interaction_sink* sink)
+               : config_(config)
+               , sink_(sink)
+       {
+       }
        
        // frame_consumer
 
        void initialize(const core::video_format_desc& format_desc, int channel_index) override
        {
                consumer_.reset();
-               consumer_.reset(new screen_consumer(config_, format_desc, channel_index));
+               consumer_.reset(new screen_consumer(config_, format_desc, channel_index, sink_));
        }
        
        boost::unique_future<bool> send(core::const_frame frame) override
@@ -570,7 +606,7 @@ public:
        
        int buffer_depth() const override
        {
-               return 2;
+               return 1;
        }
 
        int index() const override
@@ -604,10 +640,10 @@ spl::shared_ptr<core::frame_consumer> create_consumer(const std::vector<std::wst
        if(name_it != params.end() && ++name_it != params.end())
                config.name = *name_it;
 
-       return spl::make_shared<screen_consumer_proxy>(config);
+       return spl::make_shared<screen_consumer_proxy>(config, nullptr);
 }
 
-spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptree& ptree) 
+spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptree& ptree, core::interaction_sink* sink
 {
        configuration config;
        config.name                             = ptree.get(L"name",     config.name);
@@ -629,7 +665,7 @@ spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree
        else if(aspect_str == L"4:3")
                config.aspect = configuration::aspect_4_3;
        
-       return spl::make_shared<screen_consumer_proxy>(config);
+       return spl::make_shared<screen_consumer_proxy>(config, sink);
 }
 
 }}
\ No newline at end of file
index 666e28f2eb089bad17461b6ed0b41b097d63b074..5c076999d492f6347374ba807589c1f19069071e 100644 (file)
@@ -22,6 +22,7 @@
 #pragma once
 
 #include <common/memory.h>
+#include <core/interaction/interaction_sink.h>
 
 #include <vector>
 #include <boost/property_tree/ptree.hpp>
@@ -36,6 +37,6 @@ namespace screen {
 
 
 spl::shared_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>& params);
-spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptree& ptree);
+spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptree& ptree, core::interaction_sink* sink);
 
 }}
\ No newline at end of file
index 29b5e6d98de624ab46967c20b42b1ba6a83e9993..7b5e65393fcdfc478074b7645627f5d448660945 100644 (file)
@@ -33,6 +33,7 @@
 #include <core/video_format.h>
 #include <core/producer/stage.h>
 #include <core/producer/frame_producer.h>
+#include <core/producer/scene/scene_producer.h>
 #include <core/consumer/output.h>
 
 #include <modules/bluefish/bluefish.h>
@@ -98,6 +99,8 @@ struct server::impl : boost::noncopyable
                flash::init();            
                CASPAR_LOG(info) << L"Initialized flash module.";
 
+               register_producer_factory(&core::scene::create_dummy_scene_producer);
+
                setup_channels(env::properties());
                CASPAR_LOG(info) << L"Initialized channels.";
 
@@ -133,7 +136,7 @@ struct server::impl : boost::noncopyable
                                {
                                        auto name = xml_consumer.first;
                                        if(name == L"screen")
-                                               channel->output().add(caspar::screen::create_consumer(xml_consumer.second));                                    
+                                               channel->output().add(caspar::screen::create_consumer(xml_consumer.second, &channel->stage()));                                 
                                        else if(name == L"bluefish")                                    
                                                channel->output().add(bluefish::create_consumer(xml_consumer.second));                                  
                                        else if(name == L"decklink")