]> 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>
Fri, 8 Apr 2011 22:07:08 +0000 (22:07 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 8 Apr 2011 22:07:08 +0000 (22:07 +0000)
30 files changed:
core/channel.cpp
core/channel.h
core/producer/color/color_producer.cpp
core/producer/color/color_producer.h
core/producer/frame_producer.cpp
core/producer/frame_producer.h
core/producer/frame_producer_device.cpp
core/producer/frame_producer_device.h
core/producer/layer.cpp
core/producer/transition/transition_producer.cpp
core/producer/transition/transition_producer.h
modules/decklink/producer/decklink_producer.cpp
modules/decklink/producer/decklink_producer.h
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/ffmpeg_producer.h
modules/flash/flash.cpp
modules/flash/producer/cg_producer.cpp
modules/flash/producer/cg_producer.h
modules/flash/producer/flash_producer.cpp
modules/flash/producer/flash_producer.h
modules/image/producer/image_producer.cpp
modules/image/producer/image_producer.h
modules/silverlight/producer/silverlight_producer.cpp
modules/silverlight/producer/silverlight_producer.h
protocol/amcp/AMCPCommandsImpl.cpp
protocol/cii/CIICommandsImpl.cpp
protocol/cii/CIIProtocolStrategy.cpp
protocol/clk/CLKProtocolStrategy.cpp
shell/boostrapper.cpp
shell/caspar.config

index 289f06a64b850fce73a1ff3b63a1d6e8db6f1f97..be14867128706355bc6c347a42f9f7d1ed6e68a6 100644 (file)
@@ -26,9 +26,9 @@ struct channel::implementation : boost::noncopyable
        const int index_;\r
        video_format_desc format_desc_;\r
        \r
-       std::shared_ptr<frame_mixer_device>      mixer_;\r
-       std::shared_ptr<frame_consumer_device> consumer_;\r
-       std::shared_ptr<frame_producer_device> producer_;\r
+       safe_ptr<frame_mixer_device>     mixer_;\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
@@ -39,7 +39,7 @@ public:
                , format_desc_(format_desc)\r
                , consumer_(new frame_consumer_device(format_desc))\r
                , mixer_(new frame_mixer_device(format_desc))\r
-               , producer_(new frame_producer_device(safe_ptr<frame_factory>(mixer_))) \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::vector<safe_ptr<basic_frame>>& frames){mixer_->send(frames);}))\r
        {}\r
@@ -56,8 +56,8 @@ public:
                mixer_connection_.disconnect();\r
 \r
                consumer_->set_video_format_desc(format_desc_);\r
-               mixer_.reset(new frame_mixer_device(format_desc_));\r
-               producer_.reset(new frame_producer_device(safe_ptr<frame_factory>(mixer_)));\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::vector<safe_ptr<basic_frame>>& frames){mixer_->send(frames);});\r
@@ -66,9 +66,9 @@ public:
 \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
-frame_producer_device& channel::producer() { return *impl_->producer_;} \r
-frame_mixer_device& channel::mixer() { return *impl_->mixer_;} \r
-frame_consumer_device& channel::consumer() { return *impl_->consumer_;} \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
 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 b416a6cb2aab8ea52caa194832ab7b647b069c95..fcf97105186f20f5a687e43346c2ec854f2d796e 100644 (file)
@@ -27,9 +27,9 @@ public:
        explicit channel(int index, const video_format_desc& format_desc);\r
        channel(channel&& other);\r
 \r
-       frame_producer_device& producer();\r
-       frame_mixer_device& mixer();\r
-       frame_consumer_device& consumer();\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
 \r
        const video_format_desc& get_video_format_desc() const;\r
        void set_video_format_desc(const video_format_desc& format_desc);\r
index 01afdc44637de653cd4129291b774c34b72f9851..ff527d489ee10b1283ccf43f22ece272142a2226 100644 (file)
@@ -34,33 +34,30 @@ class color_producer : public frame_producer
        std::wstring color_str_;\r
 \r
 public:\r
-       explicit color_producer(const std::wstring& color) \r
+       explicit color_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& color) \r
                : color_str_(color)\r
                , frame_(basic_frame::empty())\r
        {\r
                if(color.length() != 9 || color[0] != '#')\r
                        BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("color") << arg_value_info(narrow(color)) << msg_info("Invalid color code"));\r
-       }\r
 \r
-       virtual void set_frame_factory(const safe_ptr<frame_factory>& frame_factory)\r
-       {\r
                auto frame = frame_factory->create_frame(1, 1, pixel_format::bgra);\r
                auto& value = *reinterpret_cast<unsigned long*>(frame->image_data().begin());\r
                std::wstringstream str(color_str_.substr(1));\r
                str >> std::hex >> value;       \r
                frame_ = std::move(frame);\r
        }\r
-               \r
+                       \r
        virtual safe_ptr<basic_frame> receive() { return frame_; }\r
        \r
        virtual std::wstring print() const { return L"color[" + color_str_ + L"]"; }\r
 };\r
 \r
-safe_ptr<frame_producer> create_color_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<frame_producer> create_color_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
 {\r
        if(params.empty() || params[0].at(0) != '#')\r
                return frame_producer::empty();\r
-       return make_safe<color_producer>(params[0]);\r
+       return make_safe<color_producer>(frame_factory, params[0]);\r
 }\r
 \r
 }}
\ No newline at end of file
index 228124cf2d03ab3a63d4e68ecbf9f923e73309be..f4eff6a848f48016ab1169e22660e08f87d1fd4c 100644 (file)
@@ -26,6 +26,6 @@
 \r
 namespace caspar { namespace core {\r
        \r
-safe_ptr<frame_producer> create_color_producer(const std::vector<std::wstring>& params);\r
+       safe_ptr<frame_producer> create_color_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 \r
 }}\r
index 541f11bfd1f77837fc9422cbec67afbce0ab0738..8b5073e955a71782ccd23e63cdf5c1f36aee05e0 100644 (file)
@@ -12,13 +12,57 @@ namespace caspar { namespace core {
 std::vector<const producer_factory_t> p_factories;\r
 tbb::spin_rw_mutex p_factories_mutex;\r
 \r
+safe_ptr<basic_frame> receive(safe_ptr<frame_producer>& producer)\r
+{\r
+       auto frame = basic_frame::eof();\r
+       try\r
+       {\r
+               frame = producer->receive();\r
+       }\r
+       catch(...)\r
+       {\r
+               try\r
+               {\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       CASPAR_LOG(warning) << producer->print() << " Failed to receive frame. Removing producer.";\r
+               }\r
+               catch(...){}\r
+       }\r
+\r
+       if(frame == basic_frame::eof())\r
+       {\r
+               auto following = producer->get_following_producer();\r
+               if(following == frame_producer::empty())\r
+                       producer = frame_producer::eof();\r
+               else\r
+               {\r
+                       following->set_leading_producer(producer);\r
+                       producer = std::move(following);\r
+                       return receive(producer);\r
+               }\r
+       }\r
+       return frame;\r
+}\r
+\r
+std::wostream& operator<<(std::wostream& out, const frame_producer& producer)\r
+{\r
+       out << producer.print().c_str();\r
+       return out;\r
+}\r
+\r
+std::wostream& operator<<(std::wostream& out, const safe_ptr<const frame_producer>& producer)\r
+{\r
+       out << producer->print().c_str();\r
+       return out;\r
+}\r
+\r
 void register_producer_factory(const producer_factory_t& factory)\r
 {\r
        tbb::spin_rw_mutex::scoped_lock(p_factories_mutex, true);\r
        p_factories.push_back(factory);\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& params)\r
 {\r
        if(params.empty())\r
                BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("params") << arg_value_info(""));\r
@@ -29,7 +73,7 @@ safe_ptr<core::frame_producer> create_producer(const std::vector<std::wstring>&
                {\r
                        try\r
                        {\r
-                               producer = factory(params);\r
+                               producer = factory(my_frame_factory, params);\r
                        }\r
                        catch(...)\r
                        {\r
@@ -39,7 +83,7 @@ safe_ptr<core::frame_producer> create_producer(const std::vector<std::wstring>&
                });\r
 \r
        if(producer == frame_producer::empty())\r
-               producer = create_color_producer(params);\r
+               producer = create_color_producer(my_frame_factory, params);\r
 \r
        if(producer == frame_producer::empty())\r
                BOOST_THROW_EXCEPTION(file_not_found() << msg_info("No match found for supplied commands. Check syntax."));\r
index e6f22f58f2af200ff9931591fe8657392320c370..4cc401ec08ccbbffe9053552f95a1faa2520c007 100644 (file)
@@ -37,44 +37,9 @@ class frame_producer : boost::noncopyable
 public:\r
        virtual ~frame_producer(){}     \r
 \r
-       ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       /// \fn virtual basic_frame :::receive() = 0;\r
-       ///\r
-       /// \brief      Renders a frame.\r
-       ///             \r
-       /// \note       This function is run in through the tbb task_schedular and shall be *non blocking*.\r
-       ///\r
-       /// \return     The frame. \r
-       ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        virtual safe_ptr<basic_frame> receive() = 0;\r
-\r
-       ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       /// \fn virtual std::shared_ptr<frame_producer> :::get_following_producer() const\r
-       ///\r
-       /// \brief      Gets the producer which will replace the current producer on EOF. \r
-       ///\r
-       /// \return     The following producer, or nullptr if there is no following producer. \r
-       ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        virtual safe_ptr<frame_producer> get_following_producer() const {return frame_producer::empty();}  // nothrow\r
-       \r
-       ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       /// \fn virtual void :::set_leading_producer(const std::shared_ptr<frame_producer>& producer)\r
-       ///\r
-       /// \brief      Sets the producer which was run before the current producer. \r
-       ///\r
-       /// \param      producer        The leading producer.\r
-       ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        virtual void set_leading_producer(const safe_ptr<frame_producer>& /*producer*/) {}  // nothrow\r
-       \r
-       ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       /// \fn virtual void :::set_frame_factory(const safe_ptr<frame_factory>& frame_factory) = 0;\r
-       ///\r
-       /// \brief      Sets the frame frame_factory used to create frames. \r
-       ///\r
-       /// \param      frame_factory   The frame frame_factory. \r
-       ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       virtual void set_frame_factory(const safe_ptr<frame_factory>& frame_factory) = 0;\r
-\r
        virtual void param(const std::wstring&){}\r
 \r
        virtual std::wstring print() const = 0;\r
@@ -89,25 +54,30 @@ public:
                };\r
                static safe_ptr<frame_producer> producer = make_safe<empty_frame_producer>();\r
                return producer;\r
+       }       \r
+\r
+       static const safe_ptr<frame_producer>& eof()  // nothrow\r
+       {\r
+               struct eof_frame_producer : public frame_producer\r
+               {\r
+                       virtual safe_ptr<basic_frame> receive(){return basic_frame::eof();}\r
+                       virtual void set_frame_factory(const safe_ptr<frame_factory>&){}\r
+                       virtual std::wstring print() const { return L"eof";}\r
+               };\r
+               static safe_ptr<frame_producer> producer = make_safe<eof_frame_producer>();\r
+               return producer;\r
        }\r
 };\r
 \r
-inline std::wostream& operator<<(std::wostream& out, const frame_producer& producer)\r
-{\r
-       out << producer.print().c_str();\r
-       return out;\r
-}\r
+safe_ptr<basic_frame> receive(safe_ptr<frame_producer>& producer);\r
 \r
-inline std::wostream& operator<<(std::wostream& out, const safe_ptr<const frame_producer>& producer)\r
-{\r
-       out << producer->print().c_str();\r
-       return out;\r
-}\r
+std::wostream& operator<<(std::wostream& out, const frame_producer& producer);\r
+std::wostream& operator<<(std::wostream& out, const safe_ptr<const frame_producer>& producer);\r
 \r
-typedef std::function<safe_ptr<core::frame_producer>(const std::vector<std::wstring>&)> producer_factory_t;\r
+typedef std::function<safe_ptr<core::frame_producer>(const safe_ptr<frame_factory>&, const std::vector<std::wstring>&)> producer_factory_t;\r
 \r
 void register_producer_factory(const producer_factory_t& factory);\r
-safe_ptr<core::frame_producer> create_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>&, const std::vector<std::wstring>& params);\r
 \r
 \r
 }}\r
index 2c9c1c966caaf44a3983d10d9fba26373cb8451a..37b6e609702c136ebeac80cae4734cad70414ab2 100644 (file)
@@ -25,14 +25,14 @@ struct frame_producer_device::implementation : boost::noncopyable
 {              \r
        std::map<int, layer> layers_;           \r
        \r
-       const safe_ptr<frame_factory> factory_;\r
+       const video_format_desc format_desc_;\r
 \r
        output_t output_;\r
        \r
        mutable executor executor_;\r
 public:\r
-       implementation(const safe_ptr<frame_factory>& factory)  \r
-               : factory_(factory)\r
+       implementation(const video_format_desc& format_desc)  \r
+               : format_desc_(format_desc)\r
                , executor_(L"frame_producer_device")\r
        {\r
                executor_.start();\r
@@ -84,12 +84,12 @@ public:
                        }\r
                });             \r
                boost::range::remove_erase(frames, basic_frame::empty());\r
+               boost::range::remove_erase(frames, basic_frame::eof());\r
                return frames;\r
        }\r
 \r
        void load(int index, const safe_ptr<frame_producer>& producer, bool play_on_load, bool preview)\r
        {\r
-               producer->set_frame_factory(factory_);\r
                executor_.invoke([&]{get_layer(index).load(producer, play_on_load, preview);});\r
        }\r
 \r
@@ -132,7 +132,7 @@ public:
                        swap_layer(index, other_index);\r
                else\r
                {\r
-                       if(factory_->get_video_format_desc() != other.impl_->factory_->get_video_format_desc())\r
+                       if(format_desc_ != other.impl_->format_desc_)\r
                                BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Cannot swap between channels with different formats."));\r
 \r
                        auto func = [&]\r
@@ -151,7 +151,7 @@ public:
                if(other.impl_.get() == this)\r
                        return;\r
 \r
-               if(factory_->get_video_format_desc() != other.impl_->factory_->get_video_format_desc())\r
+               if(format_desc_ != other.impl_->format_desc_)\r
                        BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Cannot swap between channels with different formats."));\r
 \r
                auto func = [&]\r
@@ -191,7 +191,7 @@ public:
        }\r
 };\r
 \r
-frame_producer_device::frame_producer_device(const safe_ptr<frame_factory>& factory) : impl_(new implementation(factory)){}\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(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
index 74c3cef0b07f7a1d50d5b81cc3c577da194ed52c..8f5972b5227daa7972478bf1c54357cf028da19b 100644 (file)
@@ -31,7 +31,7 @@ public:
         \r
        boost::signals2::connection connect(const output_t::slot_type& subscriber);\r
 \r
-       explicit frame_producer_device(const safe_ptr<frame_factory>& factory);\r
+       explicit frame_producer_device(const video_format_desc& format_desc);\r
        frame_producer_device(frame_producer_device&& other);\r
        void swap(frame_producer_device& other);\r
                \r
index d11fc716466acb715f5b0a127fed7bcd9fc52196..150651713af79061b585290971793602713677fa 100644 (file)
@@ -108,28 +108,11 @@ public:
                        return last_frame_;\r
                }\r
 \r
-               try\r
-               {\r
-                       last_frame_ = foreground_->receive(); \r
-                       if(last_frame_ == basic_frame::eof())\r
-                       {\r
-                               CASPAR_VERIFY(foreground_ != frame_producer::empty());\r
-\r
-                               auto following = foreground_->get_following_producer();\r
-                               following->set_leading_producer(foreground_);\r
-                               g_remover.remove(std::move(foreground_));\r
-                               foreground_ = following;\r
-                               CASPAR_LOG(info) << foreground_->print() << L" Added.";\r
-\r
-                               last_frame_ = receive();\r
-                       }\r
-               }\r
-               catch(...)\r
-               {\r
-                       CASPAR_LOG(error) << print() << L" Unhandled Exception: ";\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-                       stop();\r
-               }\r
+               auto keep_alive = foreground_;\r
+               last_frame_ = core::receive(foreground_);\r
+\r
+               if(keep_alive != foreground_)\r
+                       g_remover.remove(std::move(keep_alive));\r
 \r
                return last_frame_;\r
        }\r
index 1d94bb2a283d2b0028e6f3b51b915b42c66dc2ea..f472e16758dae9e70df62b31bb232b86ce2529e9 100644 (file)
 \r
 namespace caspar { namespace core {    \r
 \r
-struct transition_producer::implementation : boost::noncopyable\r
+struct transition_producer : public frame_producer\r
 {      \r
-       const transition_producer* self_;\r
+       const video_format_desc         format_desc_;\r
        unsigned short                          current_frame_;\r
        \r
        const transition_info           info_;\r
        \r
        safe_ptr<frame_producer>        dest_producer_;\r
        safe_ptr<frame_producer>        source_producer_;\r
-\r
-       std::shared_ptr<frame_factory>  frame_factory_;\r
-\r
+       \r
        std::vector<safe_ptr<basic_frame>> frame_buffer_;\r
        \r
-       implementation(const transition_producer* self, const safe_ptr<frame_producer>& dest, const transition_info& info) \r
-               : self_(self)\r
+       transition_producer(const video_format_desc& format_desc, const safe_ptr<frame_producer>& dest, const transition_info& info) \r
+               : format_desc_(format_desc)\r
                , current_frame_(0)\r
                , info_(info)\r
                , dest_producer_(dest)\r
@@ -52,13 +50,7 @@ struct transition_producer::implementation : boost::noncopyable
        {\r
                frame_buffer_.push_back(basic_frame::empty());\r
        }\r
-                               \r
-       void set_frame_factory(const safe_ptr<frame_factory>& frame_factory)\r
-       {\r
-               dest_producer_->set_frame_factory(frame_factory);\r
-               frame_factory_ = frame_factory;\r
-       }\r
-       \r
+                                       \r
        safe_ptr<frame_producer> get_following_producer() const\r
        {\r
                return dest_producer_;\r
@@ -79,51 +71,13 @@ struct transition_producer::implementation : boost::noncopyable
 \r
                tbb::parallel_invoke\r
                (\r
-                       [&]{dest   = render_sub_frame(dest_producer_);},\r
-                       [&]{source = render_sub_frame(source_producer_);}\r
+                       [&]{dest   = core::receive(dest_producer_);},\r
+                       [&]{source = core::receive(source_producer_);}\r
                );\r
 \r
                return compose(dest, source);\r
        }\r
-       \r
-       safe_ptr<basic_frame> render_sub_frame(safe_ptr<frame_producer>& producer)\r
-       {\r
-               if(producer == frame_producer::empty())\r
-                       return basic_frame::eof();\r
-\r
-               auto frame = basic_frame::eof();\r
-               try\r
-               {\r
-                       frame = producer->receive();\r
-               }\r
-               catch(...)\r
-               {\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-                       producer = frame_producer::empty();\r
-                       CASPAR_LOG(warning) << self_->print() << " Failed to receive frame. Removed producer from transition.";\r
-               }\r
-\r
-               if(frame == basic_frame::eof())\r
-               {\r
-                       try\r
-                       {\r
-                               auto following = producer->get_following_producer();\r
-                               following->set_frame_factory(safe_ptr<frame_factory>(frame_factory_));\r
-                               following->set_leading_producer(producer);\r
-                               producer = std::move(following);\r
-                       }\r
-                       catch(...)\r
-                       {\r
-                               CASPAR_LOG_CURRENT_EXCEPTION();\r
-                               producer = frame_producer::empty();\r
-                               CASPAR_LOG(warning) << self_->print() << " Failed to initialize following producer.";\r
-                       }\r
-\r
-                       return render_sub_frame(producer);\r
-               }\r
-               return frame;\r
-       }\r
-                                       \r
+                                               \r
        safe_ptr<basic_frame> compose(const safe_ptr<basic_frame>& dest_frame, const safe_ptr<basic_frame>& src_frame) \r
        {       \r
                if(dest_frame == basic_frame::eof() && src_frame == basic_frame::eof())\r
@@ -175,29 +129,25 @@ struct transition_producer::implementation : boost::noncopyable
                        d_frame2->get_image_transform().set_key_scale(delta2, 1.0);                     \r
                }\r
                \r
-               auto mode = frame_factory_->get_video_format_desc().mode;\r
-               auto s_frame = s_frame1->get_image_transform() == s_frame2->get_image_transform() ? s_frame2 : basic_frame::interlace(s_frame1, s_frame2, mode);\r
-               auto d_frame = basic_frame::interlace(d_frame1, d_frame2, mode);\r
+               auto s_frame = s_frame1->get_image_transform() == s_frame2->get_image_transform() ? s_frame2 : basic_frame::interlace(s_frame1, s_frame2, format_desc_.mode);\r
+               auto d_frame = basic_frame::interlace(d_frame1, d_frame2, format_desc_.mode);\r
 \r
                return basic_frame(s_frame, d_frame);\r
        }\r
 \r
        std::wstring print() const\r
        {\r
-               return L"transition[" + info_.name() + L":" + boost::lexical_cast<std::wstring>(info_.duration) + L"]";\r
+               return L"transition[" + transition::print(info_.type) + L":" + boost::lexical_cast<std::wstring>(info_.duration) + L"]";\r
        }\r
 \r
        std::wstring source_print() const { return print() + L"/source";}\r
        std::wstring dest_print() const { return print() + L"/dest";}\r
 };\r
 \r
-transition_producer::transition_producer(const safe_ptr<frame_producer>& dest, const transition_info& info) : impl_(new implementation(this, dest, info)){}\r
-transition_producer::transition_producer(transition_producer&& other) : impl_(std::move(other.impl_)){}\r
-safe_ptr<basic_frame> transition_producer::receive(){return impl_->receive();}\r
-safe_ptr<frame_producer> transition_producer::get_following_producer() const{return impl_->get_following_producer();}\r
-void transition_producer::set_leading_producer(const safe_ptr<frame_producer>& producer) { impl_->set_leading_producer(producer); }\r
-void transition_producer::set_frame_factory(const safe_ptr<frame_factory>& frame_factory) { impl_->set_frame_factory(frame_factory);}\r
-std::wstring transition_producer::print() const { return impl_->print();}\r
+safe_ptr<frame_producer> create_transition_producer(const video_format_desc& format_desc, const safe_ptr<frame_producer>& destination, const transition_info& info)\r
+{\r
+       return make_safe<transition_producer>(format_desc, destination, info);\r
+}\r
 \r
 }}\r
 \r
index 84266a13984d2937735504666fa4cccbea23d8bf..7351aaf7b9ffbbccd4ec8269eb8a98849bd65607 100644 (file)
@@ -39,6 +39,19 @@ struct transition
                slide,\r
                wipe\r
        };\r
+\r
+       static std::wstring print(type t)\r
+       {\r
+               switch(t)\r
+               {\r
+               case transition::cut:   return L"cut";\r
+               case transition::mix:   return L"mix";\r
+               case transition::push:  return L"push";\r
+               case transition::slide: return L"slide";\r
+               case transition::wipe:  return L"wipe";\r
+               default:                                return L"";\r
+               }\r
+       }\r
 };\r
 \r
 struct transition_direction\r
@@ -57,41 +70,13 @@ struct transition_info
                , duration(0)\r
                , direction(transition_direction::from_left)\r
                , tweener(get_tweener(L"linear")){}\r
-\r
-       std::wstring name() const\r
-       {\r
-               switch(type)\r
-               {\r
-               case transition::cut: return L"cut";\r
-               case transition::mix: return L"mix";\r
-               case transition::push: return L"push";\r
-               case transition::slide: return L"slide";\r
-               case transition::wipe: return L"wipe";\r
-               default: return L"";\r
-               }\r
-       }\r
-       \r
+               \r
        size_t                                          duration;\r
        transition_direction::type      direction;\r
        transition::type                        type;\r
        tweener_t                                       tweener;\r
 };\r
 \r
-class transition_producer : public frame_producer\r
-{\r
-public:\r
-       explicit transition_producer(const safe_ptr<frame_producer>& destination, const transition_info& info);\r
-       transition_producer(transition_producer&& other);\r
-\r
-       // frame_producer\r
-       virtual safe_ptr<basic_frame> receive();\r
-       virtual safe_ptr<frame_producer> get_following_producer() const;\r
-       virtual void set_leading_producer(const safe_ptr<frame_producer>& producer);\r
-       virtual void set_frame_factory(const safe_ptr<frame_factory>& frame_factory);\r
-       virtual std::wstring print() const;\r
-private:\r
-       struct implementation;\r
-       std::shared_ptr<implementation> impl_;\r
-};\r
+safe_ptr<frame_producer> create_transition_producer(const video_format_desc& format_desc, const safe_ptr<frame_producer>& destination, const transition_info& info);\r
 \r
 }}
\ No newline at end of file
index a3f3fee0025358a54c6ad851e0b53448e6333b1b..78049ce3602187cb836272a6707876bfe86a424d 100644 (file)
@@ -252,10 +252,17 @@ class decklink_producer : public core::frame_producer
        executor executor_;\r
 public:\r
 \r
-       explicit decklink_producer(const core::video_format_desc& format_desc, size_t device_index)\r
+       explicit decklink_producer(const safe_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index)\r
                : format_desc_(format_desc) \r
                , device_index_(device_index)\r
-               , executor_(L"decklink_producer"){}\r
+               , executor_(L"decklink_producer")\r
+       {\r
+               executor_.start();\r
+               executor_.invoke([=]\r
+               {\r
+                       input_.reset(new decklink_input(format_desc_, device_index_, frame_factory));\r
+               });\r
+       }\r
 \r
        ~decklink_producer()\r
        {       \r
@@ -264,16 +271,7 @@ public:
                        input_ = nullptr;\r
                });\r
        }\r
-\r
-       virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
-       {\r
-               executor_.start();\r
-               executor_.invoke([=]\r
-               {\r
-                       input_.reset(new decklink_input(format_desc_, device_index_, frame_factory));\r
-               });\r
-       }\r
-               \r
+                       \r
        virtual safe_ptr<core::basic_frame> receive()\r
        {\r
                return input_->get_frame();\r
@@ -285,7 +283,7 @@ public:
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_decklink_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_decklink_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
 {\r
        if(params.empty() || !boost::iequals(params[0], "decklink"))\r
                return core::frame_producer::empty();\r
@@ -304,7 +302,7 @@ safe_ptr<core::frame_producer> create_decklink_producer(const std::vector<std::w
                format_desc = format_desc.format != core::video_format::invalid ? format_desc : core::video_format_desc::get(L"PAL");\r
        }\r
 \r
-       return make_safe<decklink_producer>(format_desc, device_index);\r
+       return make_safe<decklink_producer>(frame_factory, format_desc, device_index);\r
 }\r
 \r
 }
\ No newline at end of file
index 6aeaa975f7d57bb79b13a395320d67e759768b07..09b9c99d2918c03ebd9b4e29a2b7fbc347b6fb2f 100644 (file)
@@ -26,6 +26,6 @@
 \r
 namespace caspar { \r
        \r
-safe_ptr<core::frame_producer> create_decklink_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_decklink_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 \r
 }\r
index 7c7882491628258d4b2dab0ee7b4b4e2e82c9521..415acb0e0f1b538546626f8d8395ad547a465e90 100644 (file)
@@ -46,20 +46,16 @@ struct ffmpeg_producer : public core::frame_producer
 \r
        std::unique_ptr<input>                          input_; \r
 public:\r
-       explicit ffmpeg_producer(const std::wstring& filename, bool loop) \r
+       explicit ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, bool loop) \r
                : filename_(filename)\r
                , loop_(loop) \r
                , last_frame_(core::basic_frame(core::basic_frame::empty()))\r
-               \r
+               , frame_factory_(frame_factory)         \r
        {\r
                graph_ = diagnostics::create_graph(boost::bind(&ffmpeg_producer::print, this)); \r
                graph_->add_guide("frame-time", 0.5);\r
                graph_->set_color("frame-time",  diagnostics::color(1.0f, 0.0f, 0.0f));\r
-       }\r
-       \r
-       virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
-       {\r
-               frame_factory_ = frame_factory;\r
+\r
                input_.reset(new input(safe_ptr<diagnostics::graph>(graph_), filename_, loop_));\r
                video_decoder_.reset(input_->get_video_codec_context().get() ? new video_decoder(input_->get_video_codec_context().get(), frame_factory) : nullptr);\r
                audio_decoder_.reset(input_->get_audio_codec_context().get() ? new audio_decoder(input_->get_audio_codec_context().get(), frame_factory->get_video_format_desc().fps) : nullptr);\r
@@ -68,9 +64,8 @@ public:
                double format_frame_time = 1.0/frame_factory->get_video_format_desc().fps;\r
                if(abs(frame_time - format_frame_time) > 0.0001)\r
                        CASPAR_LOG(warning) << print() << L" Invalid framerate detected. This may cause distorted audio during playback. frame-time: " << frame_time;\r
-\r
        }\r
-               \r
+                       \r
        virtual safe_ptr<core::basic_frame> receive()\r
        {\r
                perf_timer_.reset();\r
@@ -134,7 +129,7 @@ public:
 \r
                                if(audio_decoder_) \r
                                {\r
-                                       if(!frame)\r
+                                       if(!frame) // If there is no video create a dummy frame.\r
                                        {\r
                                                frame = frame_factory_->create_frame(1, 1);\r
                                                std::fill(frame->image_data().begin(), frame->image_data().end(), 0);\r
@@ -154,14 +149,8 @@ public:
                graph_->update_value("frame-time", static_cast<float>(perf_timer_.elapsed()/frame_factory_->get_video_format_desc().interval*0.5));\r
 \r
                auto result = last_frame_;\r
-               if(!ouput_channel_.empty())\r
-               {\r
-                       result = get_frame();\r
-\r
-                       bool interlace = abs(input_->fps()/2.0 - frame_factory_->get_video_format_desc().fps) < 0.001;\r
-                       if(interlace && !ouput_channel_.empty())\r
-                               result = core::basic_frame::interlace(result, get_frame(), frame_factory_->get_video_format_desc().mode);\r
-               }\r
+               if(!ouput_channel_.empty())             \r
+                       result = get_frame(); // TODO: Support 50p              \r
                else if(input_->is_eof())\r
                        result = core::basic_frame::eof();\r
                \r
@@ -184,7 +173,7 @@ public:
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_ffmpeg_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
 {                      \r
        static const std::vector<std::wstring> extensions = boost::assign::list_of\r
                (L"mpg")(L"mpeg")(L"avi")(L"mov")(L"qt")(L"webm")(L"dv")(L"mp4")(L"f4v")(L"flv")(L"mkv")(L"mka")(L"wmw")(L"wma")(L"ogg")(L"divx")(L"wav")(L"mp3");\r
@@ -201,7 +190,7 @@ safe_ptr<core::frame_producer> create_ffmpeg_producer(const std::vector<std::wst
        std::wstring path = filename + L"." + *ext;\r
        bool loop = std::find(params.begin(), params.end(), L"LOOP") != params.end();\r
        \r
-       return make_safe<ffmpeg_producer>(path, loop);\r
+       return make_safe<ffmpeg_producer>(frame_factory, path, loop);\r
 }\r
 \r
 }
\ No newline at end of file
index 9ac70f1dbb00125d39c13f78a9e47ed8751fdee4..9490f6524410fff0a526d2733529a4fb3638a61a 100644 (file)
@@ -9,6 +9,6 @@
 \r
 namespace caspar {\r
        \r
-safe_ptr<core::frame_producer> create_ffmpeg_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 \r
 }
\ No newline at end of file
index 84de48f5145bcb73cec6500e9a0392f63e0aff86..3ef4943b6bdbde3f57a11fcc0c32953c223c4909 100644 (file)
@@ -13,12 +13,6 @@ namespace caspar{
 void init_flash()\r
 {\r
        core::register_producer_factory(create_ct_producer);\r
-\r
-       try\r
-       {\r
-               create_flash_producer(boost::assign::list_of(env::template_host()));\r
-       }\r
-       catch(...){}\r
 }\r
 \r
 std::wstring get_cg_version()\r
index a1b3a187d878b2f3bbc1868806db664c1c61c81c..31afdf136f3fa61b5ec74a5f3aab1a18a502dcb6 100644 (file)
@@ -18,21 +18,14 @@ namespace caspar {
        \r
 struct cg_producer::implementation : boost::noncopyable\r
 {\r
-       const cg_producer* self_;\r
+       safe_ptr<core::frame_factory> frame_factory_;\r
        safe_ptr<core::frame_producer> flash_producer_;\r
-       std::shared_ptr<core::frame_factory> frame_factory_;\r
 public:\r
-       implementation(const cg_producer* self\r
-               : self_(self)\r
-               , flash_producer_(create_flash_producer(boost::assign::list_of(env::template_host())))\r
+       implementation(const safe_ptr<core::frame_factory>& frame_factory\r
+               : frame_factory_(frame_factory)\r
+               , flash_producer_(create_flash_producer(frame_factory_, boost::assign::list_of(env::template_host())))\r
        {}\r
-\r
-       void clear()\r
-       {\r
-               flash_producer_ = create_flash_producer(boost::assign::list_of(env::template_host()));\r
-               flash_producer_->set_frame_factory(safe_ptr<core::frame_factory>(frame_factory_));\r
-       }\r
-\r
+       \r
        void add(int layer, const std::wstring& filename,  bool play_on_load, const std::wstring& label, const std::wstring& data)\r
        {\r
                CASPAR_LOG(info) << flash_producer_->print() << " Invoking add-command";\r
@@ -79,13 +72,7 @@ public:
        {\r
                return flash_producer_->receive();\r
        }\r
-               \r
-       void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
-       {\r
-               frame_factory_ = frame_factory;\r
-               flash_producer_->set_frame_factory(frame_factory);\r
-       }\r
-       \r
+                       \r
        std::wstring print() const\r
        {\r
                return flash_producer_->print();\r
@@ -96,32 +83,32 @@ safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::channel>& cha
 {      \r
        try\r
        {\r
-               return dynamic_pointer_cast<cg_producer>(channel->producer().foreground(render_layer).get());\r
+               return dynamic_pointer_cast<cg_producer>(channel->producer()->foreground(render_layer).get());\r
        }\r
        catch(std::bad_cast&)\r
        {\r
-               auto producer = make_safe<cg_producer>();               \r
-               channel->producer().load(render_layer, producer, true); \r
+               safe_ptr<core::frame_factory> factory = channel->mixer();\r
+               auto producer = make_safe<cg_producer>(factory);                \r
+               channel->producer()->load(render_layer, producer, true); \r
                return producer;\r
        }\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_ct_producer(const std::vector<std::wstring>& params) \r
+safe_ptr<core::frame_producer> create_ct_producer(const safe_ptr<core::frame_factory> frame_factory, const std::vector<std::wstring>& params) \r
 {\r
        std::wstring filename = env::media_folder() + L"\\" + params[0] + L".ct";\r
        if(!boost::filesystem::exists(filename))\r
                return core::frame_producer::empty();\r
 \r
-       auto producer = make_safe<cg_producer>();\r
+       auto producer = make_safe<cg_producer>(frame_factory);\r
        producer->add(0, filename, 1);\r
 \r
        return producer;\r
 }\r
 \r
-cg_producer::cg_producer() : impl_(new implementation(this)){}\r
+cg_producer::cg_producer(const safe_ptr<core::frame_factory>& frame_factory) : impl_(new implementation(frame_factory)){}\r
 cg_producer::cg_producer(cg_producer&& other) : impl_(std::move(other.impl_)){}\r
 safe_ptr<core::basic_frame> cg_producer::receive(){return impl_->receive();}\r
-void cg_producer::clear(){impl_->clear();}\r
 void cg_producer::add(int layer, const std::wstring& template_name,  bool play_on_load, const std::wstring& startFromLabel, const std::wstring& data){impl_->add(layer, template_name, play_on_load, startFromLabel, data);}\r
 void cg_producer::remove(int layer){impl_->remove(layer);}\r
 void cg_producer::play(int layer){impl_->play(layer);}\r
@@ -129,7 +116,6 @@ void cg_producer::stop(int layer, unsigned int mix_out_duration){impl_->stop(lay
 void cg_producer::next(int layer){impl_->next(layer);}\r
 void cg_producer::update(int layer, const std::wstring& data){impl_->update(layer, data);}\r
 void cg_producer::invoke(int layer, const std::wstring& label){impl_->invoke(layer, label);}\r
-void cg_producer::set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory){impl_->set_frame_factory(frame_factory);}\r
 std::wstring cg_producer::print() const{return impl_->print();}\r
 \r
 }
\ No newline at end of file
index 2fb67db134aefa651157e07c64c77e2af838cfdd..bbd7a3c2a8d03da5f0167d2d359ecbcd9dea4eaf 100644 (file)
@@ -14,10 +14,9 @@ class cg_producer : public core::frame_producer
 public:\r
        static const unsigned int DEFAULT_LAYER = 9999;\r
 \r
-       explicit cg_producer();\r
+       explicit cg_producer(const safe_ptr<core::frame_factory>& frame_factory);\r
        cg_producer(cg_producer&& other);\r
        \r
-       void clear();\r
        void add(int layer, const std::wstring& template_name,  bool play_on_load, const std::wstring& start_from_label = TEXT(""), const std::wstring& data = TEXT(""));\r
        void remove(int layer);\r
        void play(int layer);\r
@@ -28,7 +27,6 @@ public:
        \r
        // frame_producer\r
        virtual safe_ptr<core::basic_frame> receive();\r
-       virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory);\r
        virtual std::wstring print() const;\r
 \r
 private:\r
@@ -37,6 +35,6 @@ private:
 };\r
 safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::channel>& channel, int layer_index = cg_producer::DEFAULT_LAYER);\r
 \r
-safe_ptr<core::frame_producer> create_ct_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_ct_producer(const safe_ptr<core::frame_factory> frame_factory, const std::vector<std::wstring>& params);\r
 \r
 }
\ No newline at end of file
index 0a78c79f58c669104dd319065aac65a94e388210..d2e8f963e0ece731d9d35ca88db34a0cdccf969f 100644 (file)
@@ -205,20 +205,31 @@ struct flash_producer : public core::frame_producer
        tbb::concurrent_bounded_queue<safe_ptr<core::basic_frame>> frame_buffer_;\r
 \r
        std::shared_ptr<flash_renderer> renderer_;\r
-       std::shared_ptr<core::frame_factory> frame_factory_;\r
-       core::video_format_desc format_desc_;\r
+       safe_ptr<core::frame_factory> frame_factory_;\r
+       const core::video_format_desc format_desc_;\r
                        \r
        executor executor_;\r
                \r
 public:\r
-       flash_producer(const std::wstring& filename) \r
+       flash_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) \r
                : filename_(filename)           \r
                , tail_(core::basic_frame::empty())             \r
+               , frame_factory_(frame_factory)\r
+               , format_desc_(frame_factory->get_video_format_desc())\r
                , executor_(L"flash_producer")\r
        {       \r
                if(!boost::filesystem::exists(filename))\r
                        BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename)));  \r
                 \r
+               frame_buffer_.set_capacity(4);\r
+               graph_ = diagnostics::create_graph([this]{return print();});\r
+               graph_->set_color("output-buffer", diagnostics::color(0.0f, 1.0f, 0.0f));\r
+               \r
+               executor_.begin_invoke([=]\r
+               {\r
+                       init_renderer();\r
+               });\r
+\r
                fps_ = 0;\r
                executor_.start();\r
        }\r
@@ -232,21 +243,7 @@ public:
                        renderer_ = nullptr;\r
                });             \r
        }\r
-       \r
-       virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
-       {       \r
-               frame_factory_ = frame_factory;\r
-               format_desc_ = frame_factory->get_video_format_desc();\r
-               frame_buffer_.set_capacity(4);\r
-               graph_ = diagnostics::create_graph([this]{return print();});\r
-               graph_->set_color("output-buffer", diagnostics::color(0.0f, 1.0f, 0.0f));\r
                \r
-               executor_.begin_invoke([=]\r
-               {\r
-                       init_renderer();\r
-               });\r
-       }\r
-       \r
        virtual safe_ptr<core::basic_frame> receive()\r
        {               \r
                if(!renderer_)\r
@@ -312,11 +309,11 @@ public:
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_flash_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_flash_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
 {\r
        std::wstring filename = env::template_folder() + L"\\" + params[0];\r
        \r
-       return make_safe<flash_producer>(filename);\r
+       return make_safe<flash_producer>(frame_factory, filename);\r
 }\r
 \r
 std::wstring find_flash_template(const std::wstring& template_name)\r
index 652fa56c9387f2aa489136ba9e5450f57a9e0760..dd47d9b9d89583d21358bd9bff8768067f49228b 100644 (file)
@@ -25,7 +25,7 @@
 \r
 namespace caspar {\r
 \r
-safe_ptr<core::frame_producer> create_flash_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_flash_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 \r
 std::wstring find_flash_template(const std::wstring& templateName);\r
 \r
index daec6cc9e884748a9e7046148828b2323259ae06..98e6233aa3e20b1139254e4ec7c78e8918b5ccd0 100644 (file)
@@ -20,29 +20,22 @@ namespace caspar {
 \r
 struct image_producer : public core::frame_producer\r
 {      \r
-       std::shared_ptr<core::frame_factory> frame_factory_;\r
        std::wstring filename_;\r
        safe_ptr<core::basic_frame> frame_;\r
-       decltype(load_image(L"")) bitmap_;\r
        \r
-       explicit image_producer(const std::wstring& filename) \r
+       explicit image_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) \r
                : filename_(filename)\r
                , frame_(core::basic_frame::empty())    \r
-               , bitmap_(load_image(filename_))\r
        {\r
-               FreeImage_FlipVertical(bitmap_.get());\r
+               auto bitmap = load_image(filename_);\r
+               FreeImage_FlipVertical(bitmap.get());\r
+               auto frame = frame_factory->create_frame(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()));\r
+               std::copy_n(FreeImage_GetBits(bitmap.get()), frame->image_data().size(), frame->image_data().begin());\r
+               frame_ = std::move(frame);\r
        }\r
        \r
        virtual safe_ptr<core::basic_frame> receive(){return frame_;}\r
 \r
-       virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
-       {\r
-               frame_factory_ = frame_factory;\r
-               auto frame = frame_factory->create_frame(FreeImage_GetWidth(bitmap_.get()), FreeImage_GetHeight(bitmap_.get()));\r
-               std::copy_n(FreeImage_GetBits(bitmap_.get()), frame->image_data().size(), frame->image_data().begin());\r
-               bitmap_.reset();\r
-               frame_ = std::move(frame);\r
-       }\r
        \r
        virtual std::wstring print() const\r
        {\r
@@ -50,7 +43,7 @@ struct image_producer : public core::frame_producer
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_image_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_image_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
 {\r
        static const std::vector<std::wstring> extensions = list_of(L"png")(L"tga")(L"bmp")(L"jpg")(L"jpeg");\r
        std::wstring filename = env::media_folder() + L"\\" + params[0];\r
@@ -63,7 +56,7 @@ safe_ptr<core::frame_producer> create_image_producer(const std::vector<std::wstr
        if(ext == extensions.end())\r
                return core::frame_producer::empty();\r
 \r
-       return make_safe<image_producer>(filename + L"." + *ext);\r
+       return make_safe<image_producer>(frame_factory, filename + L"." + *ext);\r
 }\r
 \r
 \r
index 9ea4a968ae12abddb2005bca8d356bdf5aec6ee5..e6ade86daf0b75c0ed930bd463e83069fb17b97c 100644 (file)
@@ -7,6 +7,6 @@
 \r
 namespace caspar { \r
 \r
-safe_ptr<core::frame_producer> create_image_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_image_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 \r
 }
\ No newline at end of file
index 83a2085435fe5b7d71ef5b1af85e5c731c1a90bb..e558fc67b1543668cc9320f2d256a30270a26c68 100644 (file)
@@ -140,9 +140,7 @@ struct silverlight_producer : public core::frame_producer
        executor executor_;\r
 public:\r
 \r
-       silverlight_producer() : executor_(L"silverlight"){}\r
-       \r
-       virtual void set_frame_factory(const safe_ptr<core::frame_factory>& frame_factory)\r
+       silverlight_producer(const safe_ptr<core::frame_factory>& frame_factory) : executor_(L"silverlight")\r
        {\r
                executor_.start();\r
                executor_.invoke([=]\r
@@ -150,7 +148,7 @@ public:
                        renderer_.reset(new silverlight_renderer(frame_factory));\r
                });\r
        }\r
-       \r
+               \r
        virtual safe_ptr<core::basic_frame> receive()\r
        {\r
                executor_.begin_invoke([=]\r
@@ -164,7 +162,7 @@ public:
        std::wstring print() const{ return L"silverlight"; }    \r
 };\r
 \r
-safe_ptr<core::frame_producer> create_silverlight_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_silverlight_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
 {\r
        //std::wstring filename = env::template_folder() + L"\\" + params[0] + L".xap";\r
        //if(!boost::filesystem::exists(filename))\r
@@ -172,7 +170,7 @@ safe_ptr<core::frame_producer> create_silverlight_producer(const std::vector<std
        if(params[0] != L"SILVER")\r
                return core::frame_producer::empty();\r
 \r
-       return make_safe<silverlight_producer>();\r
+       return make_safe<silverlight_producer>(frame_factory);\r
 }\r
 \r
 }
\ No newline at end of file
index 8273a24fce5697fef9eb54128ea6483d8a676f78..7f29d57fb6625e09acc10b00957af176d5a7fc0d 100644 (file)
@@ -26,6 +26,6 @@
 \r
 namespace caspar {\r
        \r
-safe_ptr<core::frame_producer> create_silverlight_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_silverlight_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 \r
 }\r
index ebbe5b152450e126cde442e7662c7cec7a0bc679..498ce907e989e728efe785e01dc33fe670be3fd6 100644 (file)
@@ -164,7 +164,7 @@ void AMCPCommand::SendReply()
 \r
 void AMCPCommand::Clear() \r
 {\r
-       pChannel_->producer().clear();\r
+       pChannel_->producer()->clear();\r
        pClientInfo_.reset();\r
        channelIndex_ = 0;\r
        _parameters.clear();\r
@@ -192,9 +192,9 @@ bool MixerCommand::DoExecute()
 \r
                                int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
                                if(layer != std::numeric_limits<int>::min())                                    \r
-                                       GetChannel()->mixer().apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
+                                       GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
                                else\r
-                                       GetChannel()->mixer().apply_image_transform(transform, duration, tween);\r
+                                       GetChannel()->mixer()->apply_image_transform(transform, duration, tween);\r
                        }\r
                        else if(_parameters[1] == L"GAIN")\r
                        {\r
@@ -210,9 +210,9 @@ bool MixerCommand::DoExecute()
 \r
                                int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
                                if(layer != std::numeric_limits<int>::min())\r
-                                       GetChannel()->mixer().apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
+                                       GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
                                else\r
-                                       GetChannel()->mixer().apply_image_transform(transform, duration, tween);\r
+                                       GetChannel()->mixer()->apply_image_transform(transform, duration, tween);\r
                        }\r
                        else if(_parameters[1] == L"FILL_RECT")\r
                        {\r
@@ -234,9 +234,9 @@ bool MixerCommand::DoExecute()
 \r
                                int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
                                if(layer != std::numeric_limits<int>::min())\r
-                                       GetChannel()->mixer().apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
+                                       GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
                                else\r
-                                       GetChannel()->mixer().apply_image_transform(transform, duration, tween);\r
+                                       GetChannel()->mixer()->apply_image_transform(transform, duration, tween);\r
                        }\r
                        else if(_parameters[1] == L"KEY_RECT")\r
                        {\r
@@ -256,9 +256,9 @@ bool MixerCommand::DoExecute()
 \r
                                int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
                                if(layer != std::numeric_limits<int>::min())\r
-                                       GetChannel()->mixer().apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
+                                       GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, duration, tween);\r
                                else\r
-                                       GetChannel()->mixer().apply_image_transform(transform, duration, tween);\r
+                                       GetChannel()->mixer()->apply_image_transform(transform, duration, tween);\r
                        }\r
                        else if(_parameters[1] == L"GRID")\r
                        {\r
@@ -279,14 +279,14 @@ bool MixerCommand::DoExecute()
                                                        transform.set_key_scale(delta, delta);\r
                                                        return transform;\r
                                                };\r
-                                               GetChannel()->mixer().apply_image_transform(index, transform, duration, tween);\r
+                                               GetChannel()->mixer()->apply_image_transform(index, transform, duration, tween);\r
                                        }\r
                                }\r
                        }\r
                        else if(_parameters[1] == L"RESET")\r
                        {\r
                                int duration = _parameters.size() > 1 ? lexical_cast_or_default(_parameters[2], 0) : 0;\r
-                               GetChannel()->mixer().reset_image_transform(duration);\r
+                               GetChannel()->mixer()->reset_image_transform(duration);\r
                        }\r
                }\r
                else if(_parameters[0] == L"AUDIO")\r
@@ -304,21 +304,21 @@ bool MixerCommand::DoExecute()
                                \r
                                int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
                                if(layer != std::numeric_limits<int>::min())\r
-                                       GetChannel()->mixer().apply_audio_transform(GetLayerIndex(), transform, duration);\r
+                                       GetChannel()->mixer()->apply_audio_transform(GetLayerIndex(), transform, duration);\r
                                else\r
-                                       GetChannel()->mixer().apply_audio_transform(transform, duration);\r
+                                       GetChannel()->mixer()->apply_audio_transform(transform, duration);\r
                        }\r
                        else if(_parameters[1] == L"RESET")\r
                        {\r
                                int duration = _parameters.size() > 1 ? lexical_cast_or_default(_parameters[2], 0) : 0;\r
-                               GetChannel()->mixer().reset_audio_transform(duration);\r
+                               GetChannel()->mixer()->reset_audio_transform(duration);\r
                        }\r
                }\r
                else if(_parameters[0] == L"RESET")\r
                {\r
                        int duration = _parameters.size() > 1 ? lexical_cast_or_default(_parameters[2], 0) : 0;\r
-                       GetChannel()->mixer().reset_image_transform(duration);\r
-                       GetChannel()->mixer().reset_audio_transform(duration);\r
+                       GetChannel()->mixer()->reset_image_transform(duration);\r
+                       GetChannel()->mixer()->reset_audio_transform(duration);\r
                }\r
        \r
                SetReplyString(TEXT("202 MIXER OK\r\n"));\r
@@ -355,13 +355,13 @@ bool SwapCommand::DoExecute()
                        int l1 = GetLayerIndex();\r
                        int l2 = boost::lexical_cast<int>(strs.at(1));\r
 \r
-                       ch1->producer().swap_layer(l1, l2, ch2->producer());\r
+                       ch1->producer()->swap_layer(l1, l2, *ch2->producer());\r
                }\r
                else\r
                {\r
                        auto ch1 = GetChannel();\r
                        auto ch2 = GetChannels().at(boost::lexical_cast<int>(_parameters[0])-1);\r
-                       ch1->producer().swap(ch2->producer());\r
+                       ch1->producer()->swap(*ch2->producer());\r
                }\r
 \r
                CASPAR_LOG(info) << "Swapped successfully";\r
@@ -389,7 +389,7 @@ bool AddCommand::DoExecute()
        //Perform loading of the clip\r
        try\r
        {\r
-               GetChannel()->consumer().add(GetLayerIndex(), create_consumer(_parameters));\r
+               GetChannel()->consumer()->add(GetLayerIndex(), create_consumer(_parameters));\r
        \r
                CASPAR_LOG(info) << "Added " <<  _parameters[0] << TEXT(" successfully");\r
 \r
@@ -416,7 +416,7 @@ bool RemoveCommand::DoExecute()
        //Perform loading of the clip\r
        try\r
        {\r
-               GetChannel()->consumer().remove(GetLayerIndex());\r
+               GetChannel()->consumer()->remove(GetLayerIndex());\r
 \r
                SetReplyString(TEXT("202 REMOVE OK\r\n"));\r
 \r
@@ -442,8 +442,8 @@ bool LoadCommand::DoExecute()
        try\r
        {\r
                _parameters[0] = _parameters[0];\r
-               auto pFP = create_producer(_parameters);                \r
-               GetChannel()->producer().load(GetLayerIndex(), pFP, false, true);\r
+               auto pFP = create_producer(GetChannel()->mixer(), _parameters);         \r
+               GetChannel()->producer()->load(GetLayerIndex(), pFP, false, true);\r
        \r
                CASPAR_LOG(info) << "Loaded " <<  _parameters[0] << TEXT(" successfully");\r
 \r
@@ -550,13 +550,13 @@ bool LoadbgCommand::DoExecute()
        try\r
        {\r
                _parameters[0] = _parameters[0];\r
-               auto pFP = create_producer(_parameters);\r
+               auto pFP = create_producer(GetChannel()->mixer(), _parameters);\r
                if(pFP == frame_producer::empty())\r
                        BOOST_THROW_EXCEPTION(file_not_found() << msg_info(_parameters.size() > 0 ? narrow(_parameters[0]) : ""));\r
 \r
-               auto pFP2 = make_safe<core::transition_producer>(pFP, transitionInfo);\r
+               auto pFP2 = create_transition_producer(GetChannel()->get_video_format_desc(), pFP, transitionInfo);\r
                bool autoPlay = std::find(_parameters.begin(), _parameters.end(), TEXT("AUTOPLAY")) != _parameters.end();\r
-               GetChannel()->producer().load(GetLayerIndex(), pFP2, autoPlay); // TODO: LOOP\r
+               GetChannel()->producer()->load(GetLayerIndex(), pFP2, autoPlay); // TODO: LOOP\r
        \r
                CASPAR_LOG(info) << "Loaded " << _parameters[0] << TEXT(" successfully to background");\r
                SetReplyString(TEXT("202 LOADBG OK\r\n"));\r
@@ -581,7 +581,7 @@ bool PauseCommand::DoExecute()
 {\r
        try\r
        {\r
-               GetChannel()->producer().pause(GetLayerIndex());\r
+               GetChannel()->producer()->pause(GetLayerIndex());\r
                SetReplyString(TEXT("202 PAUSE OK\r\n"));\r
                return true;\r
        }\r
@@ -597,7 +597,7 @@ bool PlayCommand::DoExecute()
 {\r
        try\r
        {\r
-               GetChannel()->producer().play(GetLayerIndex());\r
+               GetChannel()->producer()->play(GetLayerIndex());\r
                SetReplyString(TEXT("202 PLAY OK\r\n"));\r
                return true;\r
        }\r
@@ -613,7 +613,7 @@ bool StopCommand::DoExecute()
 {\r
        try\r
        {\r
-               GetChannel()->producer().stop(GetLayerIndex());\r
+               GetChannel()->producer()->stop(GetLayerIndex());\r
                SetReplyString(TEXT("202 STOP OK\r\n"));\r
                return true;\r
        }\r
@@ -629,9 +629,9 @@ bool ClearCommand::DoExecute()
 {\r
        int index = GetLayerIndex(std::numeric_limits<int>::min());\r
        if(index != std::numeric_limits<int>::min())\r
-               GetChannel()->producer().clear(index);\r
+               GetChannel()->producer()->clear(index);\r
        else\r
-               GetChannel()->producer().clear();\r
+               GetChannel()->producer()->clear();\r
                \r
        SetReplyString(TEXT("202 CLEAR OK\r\n"));\r
 \r
@@ -860,7 +860,7 @@ bool CGCommand::DoExecuteRemove()
 \r
 bool CGCommand::DoExecuteClear() \r
 {\r
-       get_default_cg_producer(safe_ptr<core::channel>(GetChannel()), GetLayerIndex(cg_producer::DEFAULT_LAYER))->clear();\r
+       GetChannel()->producer()->clear(GetLayerIndex(cg_producer::DEFAULT_LAYER));\r
        SetReplyString(TEXT("202 CG OK\r\n"));\r
        return true;\r
 }\r
index e70d66116a595c2ccfbd30d4f3728a42d3ad5fef..67ec6e973937b243615b396dd0dcbc994180eae4 100644 (file)
@@ -156,7 +156,7 @@ void KeydataCommand::Execute()
        else if(state_ == 1)\r
                get_default_cg_producer(pCIIStrategy_->GetChannel())->stop(layer_, 0);\r
        else if(state_ == 2)\r
-               get_default_cg_producer(pCIIStrategy_->GetChannel())->clear();\r
+               pCIIStrategy_->GetChannel()->producer()->clear(cg_producer::DEFAULT_LAYER);\r
        else if(state_ == 3)\r
                get_default_cg_producer(pCIIStrategy_->GetChannel())->play(layer_);\r
 }\r
index b9dfc21345a8f061c60db62e7fc74289bcfc8816..8cc57d6d6a9a3b0fb72e4d64b9ab5213d693c53c 100644 (file)
@@ -181,7 +181,7 @@ void CIIProtocolStrategy::WriteTemplateData(const std::wstring& templateName, co
                return;\r
        }\r
        \r
-       auto producer = create_flash_producer(boost::assign::list_of(env::template_folder()+TEXT("CG.fth")));\r
+       auto producer = create_flash_producer(this->GetChannel()->mixer(), boost::assign::list_of(env::template_folder()+TEXT("CG.fth")));\r
 \r
        std::wstringstream flashParam;\r
        flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>1</number><string>") << currentProfile_ << '/' <<  templateName << TEXT("</string><number>0</number><true/><string> </string><string><![CDATA[ ") << xmlData << TEXT(" ]]></string></arguments></invoke>");\r
@@ -197,8 +197,8 @@ void CIIProtocolStrategy::DisplayTemplate(const std::wstring& titleName)
 {\r
        try\r
        {\r
-               pChannel_->producer().load(0, GetPreparedTemplate(titleName));\r
-               pChannel_->producer().play(0);\r
+               pChannel_->producer()->load(0, GetPreparedTemplate(titleName));\r
+               pChannel_->producer()->play(0);\r
 \r
                CASPAR_LOG(info) << L"Displayed title " << titleName ;\r
        }\r
@@ -214,12 +214,12 @@ void CIIProtocolStrategy::DisplayMediaFile(const std::wstring& filename)
        transition.type = transition::mix;\r
        transition.duration = 12;\r
 \r
-       auto pFP = create_producer(boost::assign::list_of(filename));\r
-       auto pTransition = make_safe<core::transition_producer>(pFP, transition);\r
+       auto pFP = create_producer(GetChannel()->mixer(), boost::assign::list_of(filename));\r
+       auto pTransition = create_transition_producer(GetChannel()->get_video_format_desc(), pFP, transition);\r
 \r
        try\r
        {\r
-               pChannel_->producer().load(0, pTransition);\r
+               pChannel_->producer()->load(0, pTransition);\r
        }\r
        catch(...)\r
        {\r
@@ -228,7 +228,7 @@ void CIIProtocolStrategy::DisplayMediaFile(const std::wstring& filename)
                return;\r
        }\r
 \r
-       pChannel_->producer().play(0);\r
+       pChannel_->producer()->play(0);\r
 \r
        CASPAR_LOG(info) << L"Displayed " << filename;\r
 }\r
index 2ddd55c18a3b73b9ce8b87d3a33d4f7f9edcc5ee..1c9ad903b3519010c8201ecd47469a8c9c779fd0 100644 (file)
@@ -115,7 +115,7 @@ void CLKProtocolStrategy::Parse(const TCHAR* pData, int charCount, IO::ClientInf
 \r
                        if(currentCommand_.command_ == CLKCommand::CLKReset) \r
                        {\r
-                               get_default_cg_producer(pChannel_)->clear();\r
+                               pChannel_->producer()->clear(cg_producer::DEFAULT_LAYER);\r
                                bClockLoaded_ = false;\r
                                \r
                                CASPAR_LOG(info) << L"CLK: Recieved and executed reset-command";\r
index dee5f5884a2a373167b35dfba501227e52cc12fa..fc28f14630580fe2751b9edaeaf5a8a0dfd42bbf 100644 (file)
@@ -95,17 +95,17 @@ struct bootstrapper::implementation : boost::noncopyable
                                                        stretch = stretch::uniform_to_fill;\r
 \r
                                                bool windowed = xml_consumer.second.get("windowed", false);\r
-                                               channels_.back()->consumer().add(index++, ogl_consumer(device, stretch, windowed));\r
+                                               channels_.back()->consumer()->add(index++, ogl_consumer(device, stretch, windowed));\r
                                        }\r
                                        else if(name == "bluefish")                                     \r
-                                               channels_.back()->consumer().add(index++, bluefish_consumer(xml_consumer.second.get("device", 0), \r
+                                               channels_.back()->consumer()->add(index++, bluefish_consumer(xml_consumer.second.get("device", 0), \r
                                                                                                                                                                        xml_consumer.second.get("embedded-audio", true)));                                      \r
                                        else if(name == "decklink")\r
-                                               channels_.back()->consumer().add(index++, decklink_consumer(xml_consumer.second.get("device", 0), \r
+                                               channels_.back()->consumer()->add(index++, decklink_consumer(xml_consumer.second.get("device", 0), \r
                                                                                                                                                                        xml_consumer.second.get("embedded-audio", true), \r
                                                                                                                                                                        xml_consumer.second.get("internal-key", false)));\r
                                        else if(name == "audio")\r
-                                               channels_.back()->consumer().add(index++, oal_consumer());                      \r
+                                               channels_.back()->consumer()->add(index++, oal_consumer());                     \r
                                }\r
                                catch(...)\r
                                {\r
index 7d2103d9c7f9f2090fce3446a0eee426bb1b351e..b818721c3e22e76007386a6895fabc5d11548256 100644 (file)
   </diagnostics>\r
   <channels>\r
     <channel>\r
-      <videomode>PAL</videomode>\r
+      <videomode>1080i5000</videomode>\r
       <consumers>\r
-        <!--<decklink>\r
+        <!--decklink>\r
           <device>1</device>\r
           <embedded-audio>true</embedded-audio>\r
           <internal-key>false</internal-key>\r
-        </decklink>-->\r
+        </decklink-->\r
         <ogl>\r
           <device>1</device>\r
           <stretch>uniform</stretch>\r