]> git.sesse.net Git - casparcg/commitdiff
2.1.0: Refactored "last_frame".
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 12 Feb 2012 21:07:22 +0000 (21:07 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 12 Feb 2012 21:07:22 +0000 (21:07 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.1.0@2376 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

18 files changed:
accelerator/cpu/image/image_mixer.cpp
accelerator/cpu/image/image_mixer.h
accelerator/cpu/util/write_frame.cpp
accelerator/cpu/util/write_frame.h
accelerator/ogl/image/image_mixer.cpp
accelerator/ogl/image/image_mixer.h
accelerator/ogl/util/write_frame.cpp
accelerator/ogl/util/write_frame.h
core/frame/draw_frame.cpp
core/frame/draw_frame.h
core/frame/frame_transform.cpp
core/frame/frame_transform.h
core/frame/frame_visitor.h
core/mixer/audio/audio_mixer.cpp
core/mixer/audio/audio_mixer.h
core/mixer/image/image_mixer.h
core/producer/frame_producer.cpp
core/producer/frame_producer.h

index eb08afc728df941e93b163a12866225964948456..a4080ffd358607e0e08972047ad16bc315d1a127 100644 (file)
@@ -187,8 +187,18 @@ private:
        {               \r
                BOOST_FOREACH(auto& item, items)\r
                        item.transform.field_mode &= field_mode;\r
-\r
-               boost::remove_erase_if(items, [](item& item){return item.transform.field_mode == core::field_mode::empty;});\r
+               \r
+               // Remove empty items.\r
+               boost::range::remove_erase_if(items, [&](const item& item)\r
+               {\r
+                       return item.transform.field_mode == core::field_mode::empty;\r
+               });\r
+               \r
+               // Remove first field stills.\r
+               boost::range::remove_erase_if(items, [&](const item& item)\r
+               {\r
+                       return item.transform.is_still && item.transform.field_mode == field_mode; // only us last field for stills.\r
+               });\r
 \r
                if(items.empty())\r
                        return;\r
@@ -297,14 +307,14 @@ public:
        {\r
        }\r
                \r
-       void push(core::frame_transform& transform)\r
+       void push(const core::frame_transform& transform)\r
        {\r
                transform_stack_.push_back(transform_stack_.back()*transform);\r
        }\r
                \r
-       void visit(core::data_frame& frame2)\r
+       void visit(const core::data_frame& frame2)\r
        {                       \r
-               write_frame* frame = dynamic_cast<write_frame*>(&frame2);\r
+               auto frame = dynamic_cast<const write_frame*>(&frame2);\r
                if(frame == nullptr)\r
                        return;\r
 \r
@@ -347,8 +357,8 @@ public:
 };\r
 \r
 image_mixer::image_mixer() : impl_(new impl()){}\r
-void image_mixer::push(core::frame_transform& transform){impl_->push(transform);}\r
-void image_mixer::visit(core::data_frame& frame){impl_->visit(frame);}\r
+void image_mixer::push(const core::frame_transform& transform){impl_->push(transform);}\r
+void image_mixer::visit(const core::data_frame& frame){impl_->visit(frame);}\r
 void image_mixer::pop(){impl_->pop();}\r
 boost::shared_future<boost::iterator_range<const uint8_t*>> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
 void image_mixer::begin_layer(core::blend_mode blend_mode){impl_->begin_layer(blend_mode);}\r
index d7706638ae89901583a7d3cb433ead196d46dd1c..55aa539199a38de3a25659dd171903443342235d 100644 (file)
@@ -23,8 +23,8 @@ class image_mixer sealed : public core::image_mixer
 public:\r
        image_mixer();\r
        \r
-       virtual void push(core::frame_transform& frame);\r
-       virtual void visit(core::data_frame& frame);\r
+       virtual void push(const core::frame_transform& frame);\r
+       virtual void visit(const core::data_frame& frame);\r
        virtual void pop();\r
 \r
        void begin_layer(core::blend_mode blend_mode);\r
index 1d3e83f4ad7224bb38399f3a0e3ea2252fb89d5e..39456f26d57a673b7405436c9ac978eb9f1c6599 100644 (file)
@@ -54,7 +54,7 @@ struct write_frame::impl : boost::noncopyable
                });\r
        }\r
                        \r
-       void accept(write_frame& self, core::frame_visitor& visitor)\r
+       void accept(const write_frame& self, core::frame_visitor& visitor) const\r
        {\r
                visitor.push(self.get_frame_transform());\r
                visitor.visit(self);\r
@@ -80,7 +80,7 @@ write_frame& write_frame::operator=(write_frame&& other)
        return *this;\r
 }\r
 void write_frame::swap(write_frame& other){impl_.swap(other.impl_);}\r
-void write_frame::accept(core::frame_visitor& visitor){impl_->accept(*this, visitor);}\r
+void write_frame::accept(core::frame_visitor& visitor) const {impl_->accept(*this, visitor);}\r
 const core::pixel_format_desc& write_frame::get_pixel_format_desc() const{return impl_->desc_;}\r
 const boost::iterator_range<const uint8_t*> write_frame::image_data(int index) const{return impl_->image_data(index);}\r
 const core::audio_buffer& write_frame::audio_data() const{return impl_->audio_data_;}\r
@@ -90,6 +90,6 @@ double write_frame::get_frame_rate() const{return 0.0;} // TODO: what's this?
 int write_frame::width() const{return impl_->desc_.planes.at(0).width;}\r
 int write_frame::height() const{return impl_->desc_.planes.at(0).height;}                                              \r
 const void* write_frame::tag() const{return impl_->tag_;}      \r
-std::vector<spl::shared_ptr<host_buffer>> write_frame::get_buffers(){return impl_->buffers_;}\r
+std::vector<spl::shared_ptr<host_buffer>> write_frame::get_buffers() const{return impl_->buffers_;}\r
 \r
 }}}
\ No newline at end of file
index 7abe766583d78a10efbb782dc5b170fa943f5d9d..a36ca0677bf9a7ca3d806a3ca2756cbc3071896f 100644 (file)
@@ -55,7 +55,7 @@ public:
                        \r
        // draw_frame\r
 \r
-       virtual void accept(core::frame_visitor& visitor) override;\r
+       virtual void accept(core::frame_visitor& visitor) const override;\r
 \r
        // data_frame\r
                \r
@@ -76,7 +76,7 @@ public:
 \r
        // write_frames\r
 \r
-       std::vector<spl::shared_ptr<host_buffer>> get_buffers();                \r
+       std::vector<spl::shared_ptr<host_buffer>> get_buffers() const;          \r
 private:\r
        struct impl;\r
        spl::shared_ptr<impl> impl_;\r
index 198006d68ccef56d21ab8d93a507620d549c5029..32dc99bfde1529d57f38ef42cc32a88710d1ebca 100644 (file)
@@ -253,10 +253,16 @@ private:
                                        const core::video_format_desc&          format_desc)\r
        {               \r
                // Remove empty items.\r
-               boost::range::remove_erase_if(layer.items, [](const item& item)\r
+               boost::range::remove_erase_if(layer.items, [&](const item& item)\r
                {\r
                        return item.transform.field_mode == core::field_mode::empty;\r
                });\r
+               \r
+               // Remove first field stills.\r
+               boost::range::remove_erase_if(layer.items, [&](const item& item)\r
+               {\r
+                       return item.transform.is_still && item.transform.field_mode == format_desc.field_mode; // only us last field for stills.\r
+               });\r
 \r
                if(layer.items.empty())\r
                        return;\r
@@ -378,14 +384,14 @@ public:
                layers_.push_back(layer(std::vector<item>(), blend_mode));\r
        }\r
                \r
-       void push(core::frame_transform& transform)\r
+       void push(const core::frame_transform& transform)\r
        {\r
                transform_stack_.push_back(transform_stack_.back()*transform);\r
        }\r
                \r
-       void visit(core::data_frame& frame2)\r
+       void visit(const core::data_frame& frame2)\r
        {                       \r
-               write_frame* frame = dynamic_cast<write_frame*>(&frame2);\r
+               auto frame = dynamic_cast<const write_frame*>(&frame2);\r
                if(frame == nullptr)\r
                        return;\r
 \r
@@ -434,8 +440,8 @@ public:
 };\r
 \r
 image_mixer::image_mixer(const spl::shared_ptr<context>& ogl) : impl_(new impl(ogl)){}\r
-void image_mixer::push(core::frame_transform& transform){impl_->push(transform);}\r
-void image_mixer::visit(core::data_frame& frame){impl_->visit(frame);}\r
+void image_mixer::push(const core::frame_transform& transform){impl_->push(transform);}\r
+void image_mixer::visit(const core::data_frame& frame){impl_->visit(frame);}\r
 void image_mixer::pop(){impl_->pop();}\r
 boost::shared_future<boost::iterator_range<const uint8_t*>> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
 void image_mixer::begin_layer(core::blend_mode blend_mode){impl_->begin_layer(blend_mode);}\r
index 112710053285f88db9ebc341b555eb5eb14f83c4..2e88864ce65fdc65e093d0610e829aaa31b81120 100644 (file)
@@ -43,8 +43,8 @@ class image_mixer sealed : public core::image_mixer
 public:\r
        image_mixer(const spl::shared_ptr<class context>& ogl);\r
        \r
-       virtual void push(core::frame_transform& frame);\r
-       virtual void visit(core::data_frame& frame);\r
+       virtual void push(const core::frame_transform& frame);\r
+       virtual void visit(const core::data_frame& frame);\r
        virtual void pop();\r
 \r
        void begin_layer(core::blend_mode blend_mode);\r
index b42512ba3b32e4dda7f5ebedc3c3449727af2b51..a4ba0263ed65e0c3da5b9422f5a39c55641e0445 100644 (file)
@@ -60,7 +60,7 @@ struct write_frame::impl : boost::noncopyable
                });\r
        }\r
                        \r
-       void accept(write_frame& self, core::frame_visitor& visitor)\r
+       void accept(const write_frame& self, core::frame_visitor& visitor) const\r
        {\r
                visitor.push(self.get_frame_transform());\r
                visitor.visit(self);\r
@@ -86,7 +86,7 @@ write_frame& write_frame::operator=(write_frame&& other)
        return *this;\r
 }\r
 void write_frame::swap(write_frame& other){impl_.swap(other.impl_);}\r
-void write_frame::accept(core::frame_visitor& visitor){impl_->accept(*this, visitor);}\r
+void write_frame::accept(core::frame_visitor& visitor) const {impl_->accept(*this, visitor);}\r
 const core::pixel_format_desc& write_frame::get_pixel_format_desc() const{return impl_->desc_;}\r
 const boost::iterator_range<const uint8_t*> write_frame::image_data(int index) const{return impl_->image_data(index);}\r
 const core::audio_buffer& write_frame::audio_data() const{return impl_->audio_data_;}\r
@@ -96,6 +96,6 @@ double write_frame::get_frame_rate() const{return 0.0;} // TODO: what's this?
 int write_frame::width() const{return impl_->desc_.planes.at(0).width;}\r
 int write_frame::height() const{return impl_->desc_.planes.at(0).height;}                                              \r
 const void* write_frame::tag() const{return impl_->tag_;}      \r
-std::vector<spl::shared_ptr<ogl::host_buffer>> write_frame::get_buffers(){return impl_->buffers_;}\r
+std::vector<spl::shared_ptr<ogl::host_buffer>> write_frame::get_buffers() const{return impl_->buffers_;}\r
 \r
 }}}
\ No newline at end of file
index b79bf7f5bdf2ae507df72e1d6ed970d19dd844e3..df9093d882150b12e0e1129bf992c54de39eac1a 100644 (file)
@@ -52,7 +52,7 @@ public:
                        \r
        // draw_frame\r
 \r
-       virtual void accept(core::frame_visitor& visitor) override;\r
+       virtual void accept(core::frame_visitor& visitor) const override;\r
 \r
        // data_frame\r
                \r
@@ -73,7 +73,7 @@ public:
                        \r
        // write_frames\r
 \r
-       std::vector<spl::shared_ptr<class host_buffer>> get_buffers();\r
+       std::vector<spl::shared_ptr<class host_buffer>> get_buffers() const;\r
 private:\r
        struct impl;\r
        spl::shared_ptr<impl> impl_;\r
index 842770aed4e9525087cceea05d2ee66318438cd0..53a744a97ef81ddff6e957c489178e2db8e18ed8 100644 (file)
@@ -31,7 +31,7 @@ namespace caspar { namespace core {
                                                                                                                                                                                                                                                                                                                \r
 struct draw_frame::impl\r
 {              \r
-       std::vector<spl::shared_ptr<draw_frame>> frames_;\r
+       std::vector<spl::shared_ptr<const draw_frame>> frames_;\r
 \r
        frame_transform frame_transform_;               \r
 public:\r
@@ -39,34 +39,53 @@ public:
        {\r
        }\r
 \r
-       impl(std::vector<spl::shared_ptr<draw_frame>> frames) : frames_(std::move(frames))\r
+       impl(std::vector<spl::shared_ptr<draw_frame>> frames)\r
        {\r
+               frames_.insert(frames_.end(), frames.begin(), frames.end());\r
        }\r
 \r
-       impl(spl::shared_ptr<draw_frame>&& frame) \r
+       impl(std::vector<spl::shared_ptr<const draw_frame>> frames) : frames_(std::move(frames))\r
        {\r
-               frames_.push_back(std::move(frame));\r
        }\r
 \r
-       impl(const spl::shared_ptr<draw_frame>& frame)          \r
-       { \r
-               frames_.push_back(frame);\r
+       impl(spl::shared_ptr<const draw_frame> frame) \r
+       {\r
+               frames_.push_back(std::move(frame));\r
        }\r
-       \r
-       void accept(frame_visitor& visitor)\r
+               \r
+       void accept(frame_visitor& visitor) const\r
        {\r
                visitor.push(frame_transform_);\r
                BOOST_FOREACH(auto frame, frames_)\r
                        frame->accept(visitor);\r
                visitor.pop();\r
        }       \r
+               \r
+       core::field_mode field_mode() const\r
+       {\r
+               if(frame_transform_.field_mode == field_mode::upper || frame_transform_.field_mode == field_mode::lower)\r
+                       return frame_transform_.field_mode;\r
+\r
+               if(frames_.empty())\r
+                       return field_mode::progressive;\r
+               \r
+               BOOST_FOREACH(auto frame, frames_)\r
+               {\r
+                       auto mode = frame->field_mode();\r
+                       if(frame_transform_.field_mode == field_mode::upper || frame_transform_.field_mode == field_mode::lower)\r
+                               return mode;\r
+               }\r
+\r
+               return field_mode::progressive;\r
+       }\r
 };\r
        \r
 draw_frame::draw_frame() : impl_(new impl()){}\r
 draw_frame::draw_frame(const draw_frame& other) : impl_(new impl(*other.impl_)){}\r
 draw_frame::draw_frame(draw_frame&& other) : impl_(std::move(other.impl_)){}\r
 draw_frame::draw_frame(std::vector<spl::shared_ptr<draw_frame>> frames) : impl_(new impl(frames)){}\r
-draw_frame::draw_frame(spl::shared_ptr<draw_frame> frame)  : impl_(new impl(std::move(frame))){}\r
+draw_frame::draw_frame(std::vector<spl::shared_ptr<const draw_frame>> frames) : impl_(new impl(frames)){}\r
+draw_frame::draw_frame(spl::shared_ptr<const draw_frame> frame)  : impl_(new impl(std::move(frame))){}\r
 draw_frame& draw_frame::operator=(draw_frame other)\r
 {\r
        other.swap(*this);\r
@@ -76,9 +95,10 @@ void draw_frame::swap(draw_frame& other){impl_.swap(other.impl_);}
 \r
 const frame_transform& draw_frame::get_frame_transform() const { return impl_->frame_transform_;}\r
 frame_transform& draw_frame::get_frame_transform() { return impl_->frame_transform_;}\r
-void draw_frame::accept(frame_visitor& visitor){impl_->accept(visitor);}\r
+void draw_frame::accept(frame_visitor& visitor) const{impl_->accept(visitor);}\r
+field_mode draw_frame::field_mode() const{return impl_->field_mode();}\r
 \r
-spl::shared_ptr<draw_frame> draw_frame::interlace(const spl::shared_ptr<draw_frame>& frame1, const spl::shared_ptr<draw_frame>& frame2, field_mode mode)\r
+spl::shared_ptr<draw_frame> draw_frame::interlace(const spl::shared_ptr<const draw_frame>& frame1, const spl::shared_ptr<const draw_frame>& frame2, core::field_mode mode)\r
 {                              \r
        if(frame1 == draw_frame::eof() || frame2 == draw_frame::eof())\r
                return draw_frame::eof();\r
@@ -86,11 +106,12 @@ spl::shared_ptr<draw_frame> draw_frame::interlace(const spl::shared_ptr<draw_fra
        if(frame1 == draw_frame::empty() && frame2 == draw_frame::empty())\r
                return draw_frame::empty();\r
        \r
-       if(frame1 == frame2 || mode == field_mode::progressive)\r
-               return frame2;\r
-\r
        auto my_frame1 = spl::make_shared<draw_frame>(frame1);\r
        auto my_frame2 = spl::make_shared<draw_frame>(frame2);\r
+\r
+       if(frame1 == frame2 || mode == field_mode::progressive)\r
+               return my_frame2;\r
+\r
        if(mode == field_mode::upper)\r
        {\r
                my_frame1->get_frame_transform().field_mode = field_mode::upper;        \r
@@ -102,13 +123,13 @@ spl::shared_ptr<draw_frame> draw_frame::interlace(const spl::shared_ptr<draw_fra
                my_frame2->get_frame_transform().field_mode = field_mode::upper;        \r
        }\r
 \r
-       std::vector<spl::shared_ptr<draw_frame>> frames;\r
+       std::vector<spl::shared_ptr<const draw_frame>> frames;\r
        frames.push_back(my_frame1);\r
        frames.push_back(my_frame2);\r
        return spl::make_shared<draw_frame>(std::move(frames));\r
 }\r
 \r
-spl::shared_ptr<draw_frame> draw_frame::over(const spl::shared_ptr<draw_frame>& frame1, const spl::shared_ptr<draw_frame>& frame2)\r
+spl::shared_ptr<draw_frame> draw_frame::over(const spl::shared_ptr<const draw_frame>& frame1, const spl::shared_ptr<const draw_frame>& frame2)\r
 {      \r
        if(frame1 == draw_frame::eof() || frame2 == draw_frame::eof())\r
                return draw_frame::eof();\r
@@ -116,13 +137,13 @@ spl::shared_ptr<draw_frame> draw_frame::over(const spl::shared_ptr<draw_frame>&
        if(frame1 == draw_frame::empty() && frame2 == draw_frame::empty())\r
                return draw_frame::empty();\r
 \r
-       std::vector<spl::shared_ptr<draw_frame>> frames;\r
+       std::vector<spl::shared_ptr<const draw_frame>> frames;\r
        frames.push_back(frame1);\r
        frames.push_back(frame2);\r
        return spl::make_shared<draw_frame>(std::move(frames));\r
 }\r
 \r
-spl::shared_ptr<draw_frame> draw_frame::mask(const spl::shared_ptr<draw_frame>& fill, const spl::shared_ptr<draw_frame>& key)\r
+spl::shared_ptr<draw_frame> draw_frame::mask(const spl::shared_ptr<const draw_frame>& fill, const spl::shared_ptr<const draw_frame>& key)\r
 {      \r
        if(fill == draw_frame::eof() || key == draw_frame::eof())\r
                return draw_frame::eof();\r
@@ -130,17 +151,18 @@ spl::shared_ptr<draw_frame> draw_frame::mask(const spl::shared_ptr<draw_frame>&
        if(fill == draw_frame::empty() || key == draw_frame::empty())\r
                return draw_frame::empty();\r
 \r
-       std::vector<spl::shared_ptr<draw_frame>> frames;\r
-       key->get_frame_transform().is_key = true;\r
-       frames.push_back(key);\r
+       std::vector<spl::shared_ptr<const draw_frame>> frames;\r
+       auto key2 = spl::make_shared<draw_frame>(key);\r
+       key2->get_frame_transform().is_key = true;\r
+       frames.push_back(key2);\r
        frames.push_back(fill);\r
        return spl::make_shared<draw_frame>(std::move(frames));\r
 }\r
-       \r
-spl::shared_ptr<draw_frame> draw_frame::mute(const spl::shared_ptr<draw_frame>& frame)\r
+\r
+spl::shared_ptr<draw_frame> draw_frame::still(const spl::shared_ptr<const draw_frame>& frame)\r
 {\r
        auto frame2 = spl::make_shared<draw_frame>(frame);\r
-       frame2->get_frame_transform().volume = 0.0;\r
+       frame2->get_frame_transform().is_still = true;          \r
        return frame2;\r
 }\r
 \r
index f8d0f97a27309b87c4e509c52630f2e9f2ee1d82..046861024e68e3478cc64b86aa1900492b121f7b 100644 (file)
@@ -40,24 +40,27 @@ public:
        draw_frame& operator=(draw_frame other);\r
        virtual ~draw_frame(){}\r
 \r
-       draw_frame(spl::shared_ptr<draw_frame> frame);\r
+       draw_frame(spl::shared_ptr<const draw_frame> frame);\r
        draw_frame(std::vector<spl::shared_ptr<draw_frame>> frames);\r
+       draw_frame(std::vector<spl::shared_ptr<const draw_frame>> frames);\r
                \r
        void swap(draw_frame& other);\r
 \r
+       field_mode field_mode() const;\r
+\r
        const struct frame_transform& get_frame_transform() const;\r
        struct frame_transform& get_frame_transform();\r
                                \r
-       static spl::shared_ptr<draw_frame> interlace(const spl::shared_ptr<draw_frame>& frame1, const spl::shared_ptr<draw_frame>& frame2, field_mode mode);\r
-       static spl::shared_ptr<draw_frame> over(const spl::shared_ptr<draw_frame>& frame1, const spl::shared_ptr<draw_frame>& frame2);\r
-       static spl::shared_ptr<draw_frame> mask(const spl::shared_ptr<draw_frame>& fill, const spl::shared_ptr<draw_frame>& key);\r
-       static spl::shared_ptr<draw_frame> mute(const spl::shared_ptr<draw_frame>& frame);\r
+       static spl::shared_ptr<draw_frame> interlace(const spl::shared_ptr<const draw_frame>& frame1, const spl::shared_ptr<const draw_frame>& frame2, core::field_mode mode);\r
+       static spl::shared_ptr<draw_frame> over(const spl::shared_ptr<const draw_frame>& frame1, const spl::shared_ptr<const draw_frame>& frame2);\r
+       static spl::shared_ptr<draw_frame> mask(const spl::shared_ptr<const draw_frame>& fill, const spl::shared_ptr<const draw_frame>& key);\r
+       static spl::shared_ptr<draw_frame> still(const spl::shared_ptr<const draw_frame>& frame);\r
                \r
        static const spl::shared_ptr<draw_frame>& eof();\r
        static const spl::shared_ptr<draw_frame>& empty();\r
        static const spl::shared_ptr<draw_frame>& late();\r
        \r
-       virtual void accept(frame_visitor& visitor);\r
+       virtual void accept(frame_visitor& visitor) const;\r
 private:\r
        struct impl;\r
        spl::shared_ptr<impl> impl_;\r
index 19aa2f03620b224a2acc619b3a00c90c51f9eed6..37ce3891868614273a89bcfb11a01bf072df2514 100644 (file)
@@ -37,6 +37,7 @@ frame_transform::frame_transform()
        , field_mode(field_mode::progressive)\r
        , is_key(false)\r
        , is_mix(false)\r
+       , is_still(false)\r
 {\r
        boost::range::fill(fill_translation, 0.0);\r
        boost::range::fill(fill_scale, 1.0);\r
@@ -67,6 +68,7 @@ frame_transform& frame_transform::operator*=(const frame_transform &other)
        field_mode                               = static_cast<core::field_mode>(field_mode & other.field_mode);\r
        is_key                                  |= other.is_key;\r
        is_mix                                  |= other.is_mix;\r
+       is_still                                |= other.is_still;\r
        return *this;\r
 }\r
 \r
@@ -104,6 +106,7 @@ frame_transform frame_transform::tween(double time, const frame_transform& sourc
        result.field_mode                       = source.field_mode & dest.field_mode;\r
        result.is_key                           = source.is_key | dest.is_key;\r
        result.is_mix                           = source.is_mix | dest.is_mix;\r
+       result.is_still                         = source.is_still | dest.is_still;\r
        \r
        return result;\r
 }\r
index 70666474fe824dad284b3c294bc6a4cd0bca448a..488c9bf696eb9646e1971316fb7ea83b4970969f 100644 (file)
@@ -65,6 +65,7 @@ public:
        field_mode                              field_mode;\r
        bool                                    is_key;\r
        bool                                    is_mix;\r
+       bool                                    is_still;\r
        \r
        frame_transform& frame_transform::operator*=(const frame_transform &other);\r
        frame_transform frame_transform::operator*(const frame_transform &other) const;\r
index 6ef2061f40486a0a4120a633aa3a0e458e96888e..511848de0aafd64dfefadc8ea73ca883dce928f1 100644 (file)
@@ -28,8 +28,8 @@ namespace caspar { namespace core {
 struct frame_visitor : boost::noncopyable\r
 {\r
        virtual ~frame_visitor(){}\r
-       virtual void push(struct frame_transform& transform) = 0;\r
-       virtual void visit(struct data_frame& frame) = 0;\r
+       virtual void push(const struct frame_transform& transform) = 0;\r
+       virtual void visit(const struct data_frame& frame) = 0;\r
        virtual void pop() = 0;\r
 };\r
 \r
index 30fa6b58cfa040f4ad9f100dba24d9652160607a..ee888676080497dfa5f222b8d9025ba41074f0ac 100644 (file)
@@ -76,17 +76,20 @@ public:
                transform_stack_.push(core::frame_transform());\r
        }\r
        \r
-       void push(frame_transform& transform)\r
+       void push(const frame_transform& transform)\r
        {\r
                transform_stack_.push(transform_stack_.top()*transform);\r
        }\r
 \r
-       void visit(data_frame& frame)\r
+       void visit(const data_frame& frame)\r
        {\r
                audio_item item;\r
                item.tag                = frame.tag();\r
                item.transform  = transform_stack_.top();\r
                item.audio_data = frame.audio_data();\r
+\r
+               if(item.transform.is_still)\r
+                       item.transform.volume = 0.0;\r
                \r
                items_.push_back(std::move(item));              \r
        }\r
@@ -192,8 +195,8 @@ public:
 };\r
 \r
 audio_mixer::audio_mixer() : impl_(new impl()){}\r
-void audio_mixer::push(frame_transform& transform){impl_->push(transform);}\r
-void audio_mixer::visit(data_frame& frame){impl_->visit(frame);}\r
+void audio_mixer::push(const frame_transform& transform){impl_->push(transform);}\r
+void audio_mixer::visit(const data_frame& frame){impl_->visit(frame);}\r
 void audio_mixer::pop(){impl_->pop();}\r
 audio_buffer audio_mixer::operator()(const video_format_desc& format_desc){return impl_->mix(format_desc);}\r
 \r
index 5de0565c401fbfc807233c927a15ff6a59a3198c..bf71a1dbb67f660d85c036c919cf3deb40b1dd5e 100644 (file)
@@ -41,8 +41,8 @@ class audio_mixer sealed : public frame_visitor
 public:\r
        audio_mixer();\r
 \r
-       virtual void push(struct frame_transform& transform);\r
-       virtual void visit(struct data_frame& frame);\r
+       virtual void push(const struct frame_transform& transform);\r
+       virtual void visit(const struct data_frame& frame);\r
        virtual void pop();\r
 \r
        audio_buffer operator()(const struct video_format_desc& format_desc);\r
index 75fe3f4fcf632561b77244025aab1c066ed8345a..3fc060db5bb81aab421865f1caaeff2c4cb47e7b 100644 (file)
@@ -42,8 +42,8 @@ struct image_mixer : public frame_visitor
 {\r
        virtual ~image_mixer(){}\r
        \r
-       virtual void push(struct frame_transform& frame) = 0;\r
-       virtual void visit(struct data_frame& frame) = 0;\r
+       virtual void push(const struct frame_transform& frame) = 0;\r
+       virtual void visit(const struct data_frame& frame) = 0;\r
        virtual void pop() = 0;\r
 \r
        virtual void begin_layer(blend_mode blend_mode) = 0;\r
index 783d4a2a9ae8cd22de5eafa0a9d5f468dd46d065..2dd249e5c37c4441114d71becddbb7dcc04c0fd7 100644 (file)
@@ -54,6 +54,9 @@ boost::unique_future<std::wstring> frame_producer::call(const std::wstring&)
        BOOST_THROW_EXCEPTION(not_supported());\r
 }\r
 \r
+const spl::shared_ptr<frame_producer>& frame_producer::empty() // nothrow\r
+{\r
+\r
 struct empty_frame_producer : public frame_producer\r
 {\r
        virtual spl::shared_ptr<draw_frame> receive(int){return draw_frame::empty();}\r
@@ -73,43 +76,22 @@ struct empty_frame_producer : public frame_producer
        }\r
 };\r
 \r
-const spl::shared_ptr<frame_producer>& frame_producer::empty() // nothrow\r
-{\r
        static spl::shared_ptr<frame_producer> producer = spl::make_shared<empty_frame_producer>();\r
        return producer;\r
 }      \r
 \r
-class producer_proxy_base : public frame_producer\r
+class producer_proxy : public frame_producer\r
 {      \r
-protected:\r
        std::shared_ptr<frame_producer> producer_;\r
+       spl::shared_ptr<draw_frame>             last_frame_;\r
 public:\r
-       producer_proxy_base(spl::shared_ptr<frame_producer>&& producer) \r
+       producer_proxy(spl::shared_ptr<frame_producer>&& producer) \r
                : producer_(std::move(producer))\r
        {\r
-       }\r
-       \r
-       virtual spl::shared_ptr<draw_frame>                                                     receive(int hints) override                                                                                                             {return producer_->receive(hints);}\r
-       virtual spl::shared_ptr<draw_frame>                                                     last_frame() const override                                                                                                             {return producer_->last_frame();}\r
-       virtual std::wstring                                                                            print() const override                                                                                                                  {return producer_->print();}\r
-       virtual std::wstring                                                                            name() const override                                                                                                                   {return producer_->name();}\r
-       virtual boost::property_tree::wptree                                            info() const override                                                                                                                   {return producer_->info();}\r
-       virtual boost::unique_future<std::wstring>                                      call(const std::wstring& str) override                                                                                  {return producer_->call(str);}\r
-       virtual void                                                                                            leading_producer(const spl::shared_ptr<frame_producer>& producer) override              {return producer_->leading_producer(producer);}\r
-       virtual uint32_t                                                                                        nb_frames() const override                                                                                                              {return producer_->nb_frames();}\r
-       virtual void subscribe(const monitor::observable::observer_ptr& o)                                                                                                                                                      {return producer_->subscribe(o);}\r
-       virtual void unsubscribe(const monitor::observable::observer_ptr& o)                                                                                                                                            {return producer_->unsubscribe(o);}\r
-};\r
-\r
-class destroy_producer_proxy : public producer_proxy_base\r
-{      \r
-public:\r
-       destroy_producer_proxy(spl::shared_ptr<frame_producer>&& producer) \r
-               : producer_proxy_base(std::move(producer))\r
-       {\r
+               CASPAR_LOG(info) << producer_->print() << L" Initialized.";\r
        }\r
 \r
-       ~destroy_producer_proxy()\r
+       virtual ~producer_proxy()\r
        {               \r
                static tbb::atomic<int> counter = tbb::atomic<int>();\r
                \r
@@ -129,60 +111,42 @@ public:
                                        CASPAR_LOG(trace) << str << L" Destroying on asynchronous destruction thread.";\r
                        }\r
                        catch(...){}\r
-\r
+                       \r
+                       CASPAR_LOG(trace) << str << L" Uninitializing.";\r
                        pointer_guard.reset();\r
+                       CASPAR_LOG(info) << str << L" Uninitialized.";\r
 \r
                        --counter;\r
                }); \r
        }\r
-};\r
-\r
-class print_producer_proxy : public producer_proxy_base\r
-{      \r
-public:\r
-       print_producer_proxy(spl::shared_ptr<frame_producer>&& producer) \r
-               : producer_proxy_base(std::move(producer))\r
+       \r
+       virtual spl::shared_ptr<draw_frame>     receive(int hints) override                                                                                                             \r
        {\r
-               CASPAR_LOG(info) << producer_->print() << L" Initialized.";\r
-       }\r
-\r
-       ~print_producer_proxy()\r
-       {               \r
-               auto str = producer_->print();\r
-               CASPAR_LOG(trace) << str << L" Uninitializing.";\r
-               producer_.reset();\r
-               CASPAR_LOG(info) << str << L" Uninitialized.";\r
-       }\r
-};\r
+               auto frame = producer_->receive(hints);\r
+               \r
+               if(frame != draw_frame::late())\r
+                       last_frame_ = frame;\r
 \r
-class last_frame_producer_proxy : public producer_proxy_base\r
-{      \r
-       spl::shared_ptr<draw_frame> last_frame_;\r
-public:\r
-       last_frame_producer_proxy(spl::shared_ptr<frame_producer>&& producer) \r
-               : producer_proxy_base(std::move(producer))\r
-               , last_frame_(draw_frame::empty())\r
-       {\r
-               CASPAR_LOG(info) << producer_->print() << L" Initialized.";\r
+               return std::move(frame);\r
        }\r
-       \r
-       virtual spl::shared_ptr<draw_frame>     receive(int hints) override                                     \r
+       virtual spl::shared_ptr<draw_frame>     last_frame() const override                                                                                                             \r
        {\r
-               return last_frame_ = producer_->receive(hints);\r
+               return draw_frame::still(last_frame_);\r
        }\r
 \r
-       virtual spl::shared_ptr<draw_frame>     last_frame() const override                                                                                                             \r
-       {\r
-               return last_frame_;\r
-       }\r
+       virtual std::wstring                                                                            print() const override                                                                                                                  {return producer_->print();}\r
+       virtual std::wstring                                                                            name() const override                                                                                                                   {return producer_->name();}\r
+       virtual boost::property_tree::wptree                                            info() const override                                                                                                                   {return producer_->info();}\r
+       virtual boost::unique_future<std::wstring>                                      call(const std::wstring& str) override                                                                                  {return producer_->call(str);}\r
+       virtual void                                                                                            leading_producer(const spl::shared_ptr<frame_producer>& producer) override              {return producer_->leading_producer(producer);}\r
+       virtual uint32_t                                                                                        nb_frames() const override                                                                                                              {return producer_->nb_frames();}\r
+       virtual void subscribe(const monitor::observable::observer_ptr& o)                                                                                                                                                      {return producer_->subscribe(o);}\r
+       virtual void unsubscribe(const monitor::observable::observer_ptr& o)                                                                                                                                            {return producer_->unsubscribe(o);}\r
 };\r
 \r
 spl::shared_ptr<core::frame_producer> wrap_producer(spl::shared_ptr<core::frame_producer> producer)\r
 {\r
-       return spl::make_shared<destroy_producer_proxy>(\r
-                        spl::make_shared<print_producer_proxy>(\r
-                         spl::make_shared<last_frame_producer_proxy>(\r
-                          std::move(producer))));\r
+       return spl::make_shared<producer_proxy>(std::move(producer));\r
 }\r
 \r
 spl::shared_ptr<core::frame_producer> do_create_producer(const spl::shared_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& params)\r
index a89bbd3013152e40b148265426761b7ccaac3c59..eacb2058d04ab288d2b0eefc9c612cd536f02e0d 100644 (file)
@@ -68,7 +68,7 @@ struct frame_producer : public monitor::observable
                \r
        virtual uint32_t nb_frames() const {return std::numeric_limits<uint32_t>::max();}\r
        \r
-       virtual spl::shared_ptr<class draw_frame> receive(int fBlags) = 0;\r
+       virtual spl::shared_ptr<class draw_frame> receive(int flags) = 0;\r
        virtual spl::shared_ptr<class draw_frame> last_frame() const;\r
        \r
        static const spl::shared_ptr<frame_producer>& empty(); // nothrow\r