]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2:
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 11 Dec 2010 17:18:02 +0000 (17:18 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 11 Dec 2010 17:18:02 +0000 (17:18 +0000)
 - Frame use non-null framework to avoid potential null-reference bugs.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@281 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

28 files changed:
common/concurrency/executor.h
core/core.vcxproj
core/core.vcxproj.filters
core/processor/composite_frame.cpp
core/processor/composite_frame.h
core/processor/consumer_frame.h
core/processor/drawable_frame.h [new file with mode: 0644]
core/processor/frame_processor_device.cpp
core/processor/frame_processor_device.h
core/processor/frame_renderer.cpp
core/processor/fwd.h
core/processor/producer_frame.h
core/processor/read_frame.cpp
core/processor/read_frame.h
core/processor/transform_frame.cpp
core/processor/transform_frame.h
core/processor/write_frame.cpp
core/processor/write_frame.h
core/producer/color/color_producer.cpp
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/video/video_transformer.cpp
core/producer/ffmpeg/video/video_transformer.h
core/producer/flash/flash_producer.cpp
core/producer/frame_producer_device.cpp
core/producer/image/image_producer.cpp
core/producer/image/image_scroll_producer.cpp
core/producer/layer.cpp
core/producer/transition/transition_producer.cpp

index 23f8dafba090424149f0dd82b16c53c1340ba0b6..66255da87e81643656915a54069416eb143a85e8 100644 (file)
@@ -80,7 +80,7 @@ public:
        {       \r
                typedef decltype(func()) result_type; \r
                                \r
-               auto task = std::make_shared<boost::packaged_task<result_type>>(std::forward<Func>(func));      \r
+               auto task = std::make_shared<boost::packaged_task<result_type>>(std::forward<Func>(func)); // boost::packaged_task cannot be moved, need to used shared_ptr.\r
                auto future = task->get_future();\r
                \r
                task->set_wait_callback(std::function<void(decltype(*task)& task)>([=](decltype(*task)& task) // The std::function wrapper is required in order to add ::result_type to functor class.\r
@@ -112,12 +112,7 @@ public:
                \r
                return begin_invoke(std::forward<Func>(func)).get();\r
        }\r
-\r
-       void set_capacity(size_t capacity)\r
-       {\r
-               execution_queue_.set_capacity(capacity);\r
-       }\r
-       \r
+               \r
 private:\r
 \r
        virtual void run()\r
index 958089ec9a5f8230b6df1810c89e147a52927823..9ad0b4aec310501bda03c8b3295b51de7638a8a2 100644 (file)
     <ClInclude Include="format\video_format.h" />\r
     <ClInclude Include="processor\composite_frame.h" />\r
     <ClInclude Include="processor\consumer_frame.h" />\r
+    <ClInclude Include="processor\drawable_frame.h" />\r
     <ClInclude Include="processor\frame_processor_device.h" />\r
     <ClInclude Include="processor\frame_renderer.h" />\r
     <ClInclude Include="processor\frame_shader.h" />\r
index f6db5d36737124aeac2e544ff92509192a05cdc5..3d2e484e220841c23044451f4207d193c13badc9 100644 (file)
     <ClInclude Include="processor\consumer_frame.h">\r
       <Filter>Source\channel\processor</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="processor\drawable_frame.h">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="StdAfx.cpp">\r
index 08da985cda7b62432618c20be150bd3963fb8b83..31218e8c25dbec986ff47420f7b21334f791200c 100644 (file)
@@ -21,17 +21,20 @@ struct composite_frame::implementation : boost::noncopyable
        \r
        void begin_write()\r
        {\r
-               boost::range::for_each(frames_, std::mem_fn(&producer_frame::begin_write));             \r
+               for(size_t n = 0; n < frames_.size(); ++n)\r
+                       frames_[n].begin_write();\r
        }\r
 \r
        void end_write()\r
        {\r
-               boost::range::for_each(frames_, std::mem_fn(&producer_frame::end_write));                               \r
+               for(size_t n = 0; n < frames_.size(); ++n)\r
+                       frames_[n].end_write(); \r
        }\r
        \r
        void draw(frame_shader& shader)\r
        {\r
-               boost::range::for_each(frames_, std::bind(&producer_frame::draw, std::placeholders::_1, std::ref(shader)));     \r
+               for(size_t n = 0; n < frames_.size(); ++n)\r
+                       frames_[n].draw(shader);\r
        }\r
                        \r
        std::vector<short>& audio_data()\r
@@ -67,6 +70,13 @@ struct composite_frame::implementation : boost::noncopyable
 #endif\r
 \r
 composite_frame::composite_frame(const std::vector<producer_frame>& frames) : impl_(new implementation(frames)){}\r
+composite_frame::composite_frame(composite_frame&& other) : impl_(std::move(other.impl_)){}\r
+composite_frame& composite_frame::operator=(composite_frame&& other)\r
+{\r
+       impl_ = std::move(other.impl_);\r
+       return *this;\r
+}\r
+\r
 composite_frame::composite_frame(const producer_frame& frame1, const producer_frame& frame2)\r
 {\r
        std::vector<producer_frame> frames;\r
@@ -81,21 +91,25 @@ void composite_frame::draw(frame_shader& shader){impl_->draw(shader);}
 std::vector<short>& composite_frame::audio_data(){return impl_->audio_data();}\r
 const std::vector<short>& composite_frame::audio_data() const{return impl_->audio_data();}\r
 \r
-composite_frame_ptr composite_frame::interlace(const producer_frame& frame1, const producer_frame& frame2, video_mode::type mode)\r
+composite_frame composite_frame::interlace(producer_frame&& frame1, producer_frame&& frame2, video_mode::type mode)\r
 {                      \r
-       auto my_frame1 = std::make_shared<transform_frame>(frame1);\r
-       auto my_frame2 = std::make_shared<transform_frame>(frame2);\r
+       transform_frame my_frame1 = std::move(frame1);\r
+       transform_frame my_frame2 = std::move(frame2);\r
        if(mode == video_mode::upper)\r
        {\r
-               my_frame1->video_mode(video_mode::upper);\r
-               my_frame2->video_mode(video_mode::lower);\r
+               my_frame1.video_mode(video_mode::upper);\r
+               my_frame2.video_mode(video_mode::lower);\r
        }\r
        else\r
        {\r
-               my_frame1->video_mode(video_mode::lower);\r
-               my_frame2->video_mode(video_mode::upper);\r
+               my_frame1.video_mode(video_mode::lower);\r
+               my_frame2.video_mode(video_mode::upper);\r
        }\r
-       return std::make_shared<composite_frame>(my_frame1, my_frame2);\r
+\r
+       std::vector<producer_frame> frames;\r
+       frames.push_back(std::move(my_frame1));\r
+       frames.push_back(std::move(my_frame2));\r
+       return composite_frame(frames);\r
 }\r
 \r
 }}
\ No newline at end of file
index 5c2bead1b66d26c9823a95bdf24c644e7c20f552..ce1d9b6d43c81b006d2df9b26cce960055170245 100644 (file)
@@ -2,6 +2,8 @@
 \r
 #include "fwd.h"\r
 \r
+#include "drawable_frame.h"\r
+\r
 #include "../format/video_format.h"\r
 \r
 #include <memory>\r
 \r
 namespace caspar { namespace core {\r
        \r
-class composite_frame\r
+class composite_frame : public drawable_frame\r
 {\r
 public:\r
        composite_frame(const std::vector<producer_frame>& frames);\r
        composite_frame(const producer_frame& frame1, const producer_frame& frame2);\r
+       composite_frame(composite_frame&& other);\r
+       composite_frame& operator=(composite_frame&& other);\r
 \r
-       static std::shared_ptr<composite_frame> interlace(const producer_frame& frame1, const producer_frame& frame2, video_mode::type mode);\r
+       static composite_frame interlace(producer_frame&& frame1, producer_frame&& frame2, video_mode::type mode);\r
        \r
-       const std::vector<short>& audio_data() const;\r
-       std::vector<short>& audio_data();\r
+       virtual const std::vector<short>& audio_data() const;\r
+       virtual std::vector<short>& audio_data();\r
        \r
-       void begin_write();\r
-       void end_write();\r
-       void draw(frame_shader& shader);\r
+       virtual void begin_write();\r
+       virtual void end_write();\r
+       virtual void draw(frame_shader& shader);\r
 \r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<composite_frame> composite_frame_ptr;\r
        \r
 }}
\ No newline at end of file
index f23de1e64bf290d27b0766d76fb08af0ffcc72e1..d413211ab2f9c7e81d0cb3042c02c5e8f4749c4f 100644 (file)
@@ -13,12 +13,12 @@ namespace caspar { namespace core {
 class consumer_frame\r
 {\r
 public:        \r
-       consumer_frame(const read_frame_ptr& frame) : frame_(frame){}\r
-       const boost::iterator_range<const unsigned char*> pixel_data() const {return frame_->pixel_data();}\r
-       const std::vector<short>& audio_data() const {return frame_->audio_data();}\r
+       consumer_frame(read_frame&& frame) : frame_(std::move(frame)){}\r
+       const boost::iterator_range<const unsigned char*> pixel_data() const {return frame_.pixel_data();}\r
+       const std::vector<short>& audio_data() const {return frame_.audio_data();}\r
        \r
 private:\r
-       read_frame_ptr frame_;\r
+       read_frame frame_;\r
 };\r
 typedef std::shared_ptr<consumer_frame> consumer_frame_ptr;\r
 typedef std::unique_ptr<consumer_frame> consumer_frame_uptr;\r
diff --git a/core/processor/drawable_frame.h b/core/processor/drawable_frame.h
new file mode 100644 (file)
index 0000000..78ba332
--- /dev/null
@@ -0,0 +1,22 @@
+#pragma once\r
+\r
+#include <boost/noncopyable.hpp>\r
+\r
+#include <memory>\r
+#include <array>\r
+#include <vector>\r
+\r
+namespace caspar { namespace core {\r
+               \r
+struct drawable_frame : boost::noncopyable\r
+{      \r
+       virtual const std::vector<short>& audio_data() const = 0;\r
+       virtual std::vector<short>& audio_data() = 0;\r
+                       \r
+       virtual void begin_write() = 0;\r
+       virtual void end_write() = 0;\r
+       virtual void draw(frame_shader& shader) = 0;\r
+};\r
+\r
+\r
+}}
\ No newline at end of file
index cd14efcb780809c61558a63ec6e07f67fd006a2a..27f6a976414aac5ab7d328fa93af404bc7f04e95 100644 (file)
@@ -43,26 +43,26 @@ struct frame_processor_device::implementation : boost::noncopyable
                });\r
        }\r
                \r
-       write_frame_ptr create_frame(const pixel_format_desc& desc)\r
+       write_frame create_frame(const pixel_format_desc& desc)\r
        {\r
                auto pool = &frame_pools_[desc];\r
                \r
-               write_frame_ptr my_frame;\r
+               write_frame_impl_ptr my_frame;\r
                if(!pool->try_pop(my_frame))            \r
-                       my_frame = executor_.invoke([&]{return std::shared_ptr<write_frame>(new write_frame(desc));});          \r
+                       my_frame = executor_.invoke([&]{return std::shared_ptr<write_frame_impl>(new write_frame_impl(desc));});                \r
                \r
-               return write_frame_ptr(my_frame.get(), [=](write_frame*)\r
+               return write_frame(write_frame_impl_ptr(my_frame.get(), [=](write_frame_impl*)\r
                {\r
                        executor_.begin_invoke([=]\r
                        {\r
                                my_frame->reset();\r
                                pool->push(my_frame);\r
                        });\r
-               });\r
+               }));\r
        }\r
                \r
        void send(const producer_frame& frame)\r
-       {                                                       \r
+       {                       \r
                auto future = executor_.begin_invoke([=]{return renderer_->render(frame);});    \r
                output_.push(std::move(future)); // Blocks\r
        }\r
@@ -93,19 +93,19 @@ struct frame_processor_device::implementation : boost::noncopyable
        std::unique_ptr<frame_renderer> renderer_;      \r
                                \r
        tbb::concurrent_bounded_queue<boost::shared_future<consumer_frame>> output_;    \r
-       tbb::concurrent_unordered_map<pixel_format_desc, tbb::concurrent_bounded_queue<write_frame_ptr>, std::hash<pixel_format_desc>> frame_pools_;\r
+       tbb::concurrent_unordered_map<pixel_format_desc, tbb::concurrent_bounded_queue<write_frame_impl_ptr>, std::hash<pixel_format_desc>> frame_pools_;\r
        \r
        const video_format_desc fmt_;\r
        long underrun_count_;\r
 };\r
        \r
 frame_processor_device::frame_processor_device(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-void frame_processor_device::send(const producer_frame& frame){impl_->send(frame);}\r
+void frame_processor_device::send(const producer_frame& frame){impl_->send(std::move(frame));}\r
 consumer_frame frame_processor_device::receive(){return impl_->receive();}\r
 const video_format_desc& frame_processor_device::get_video_format_desc() const { return impl_->fmt_; }\r
 \r
-write_frame_ptr frame_processor_device::create_frame(const pixel_format_desc& desc){ return impl_->create_frame(desc); }               \r
-write_frame_ptr frame_processor_device::create_frame(size_t width, size_t height)\r
+write_frame frame_processor_device::create_frame(const pixel_format_desc& desc){ return impl_->create_frame(desc); }           \r
+write_frame frame_processor_device::create_frame(size_t width, size_t height)\r
 {\r
        // Create bgra frame\r
        pixel_format_desc desc;\r
@@ -114,7 +114,7 @@ write_frame_ptr frame_processor_device::create_frame(size_t width, size_t height
        return create_frame(desc);\r
 }\r
                        \r
-write_frame_ptr frame_processor_device::create_frame()\r
+write_frame frame_processor_device::create_frame()\r
 {\r
        // Create bgra frame with output resolution\r
        pixel_format_desc desc;\r
index 8f96ed615392d33878317eceecd9a35d334cab62..a69b8c0d350408b987e02dbdc3ac2b2fb08803cc 100644 (file)
@@ -37,9 +37,9 @@ public:
        void send(const producer_frame& frame);\r
        consumer_frame receive();\r
        \r
-       write_frame_ptr create_frame(const pixel_format_desc& desc);            \r
-       write_frame_ptr create_frame(size_t width, size_t height);                      \r
-       write_frame_ptr create_frame();\r
+       write_frame create_frame(const pixel_format_desc& desc);                \r
+       write_frame create_frame(size_t width, size_t height);                  \r
+       write_frame create_frame();\r
        \r
        const video_format_desc& get_video_format_desc() const;\r
 private:\r
index d8185d19d99f24f64e02dcdf5440e7e38dc43f07..8ac55b6b5221f7634adb10587288db13b6699424 100644 (file)
@@ -28,7 +28,7 @@ namespace caspar { namespace core {
 struct frame_renderer::implementation : boost::noncopyable\r
 {      \r
        implementation(const video_format_desc& format_desc) : shader_(format_desc), format_desc_(format_desc),\r
-               reading_(new read_frame(0, 0)), writing_(producer_frame::empty()), drawing_(producer_frame::empty()), fbo_(format_desc.width, format_desc.height)\r
+               reading_(new read_frame_impl(0, 0)), fbo_(format_desc.width, format_desc.height)\r
        {       \r
                GL(glEnable(GL_POLYGON_STIPPLE));\r
                GL(glEnable(GL_TEXTURE_2D));\r
@@ -40,7 +40,7 @@ struct frame_renderer::implementation : boost::noncopyable
                                \r
        consumer_frame render(const producer_frame& frame)\r
        {\r
-               read_frame_ptr result;\r
+               read_frame_impl_ptr result;\r
                try\r
                {\r
                        drawing_ = writing_;\r
@@ -67,24 +67,24 @@ struct frame_renderer::implementation : boost::noncopyable
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                }\r
 \r
-               return result;\r
+               return read_frame(result);\r
        }\r
 \r
-       read_frame_ptr create_output_frame()\r
+       read_frame_impl_ptr create_output_frame()\r
        {\r
-               read_frame_ptr frame;\r
+               read_frame_impl_ptr frame;\r
                if(!frame_pool_.try_pop(frame))         \r
-                       frame.reset(new read_frame(format_desc_.width, format_desc_.height));           \r
-               return read_frame_ptr(frame.get(), [=](read_frame*){frame_pool_.push(frame);});\r
+                       frame = std::make_shared<read_frame_impl>(format_desc_.width, format_desc_.height);             \r
+               return read_frame_impl_ptr(frame.get(), [=](read_frame_impl*){frame_pool_.push(frame);});\r
        }\r
 \r
-       tbb::concurrent_bounded_queue<read_frame_ptr> frame_pool_;\r
+       tbb::concurrent_bounded_queue<read_frame_impl_ptr> frame_pool_;\r
 \r
        common::gl::frame_buffer_object fbo_;\r
 \r
-       read_frame_ptr  reading_;       \r
-       producer_frame  writing_;\r
-       producer_frame  drawing_;\r
+       read_frame_impl_ptr     reading_;       \r
+       producer_frame          writing_;\r
+       producer_frame          drawing_;\r
        \r
        frame_shader shader_;\r
 \r
@@ -92,8 +92,5 @@ struct frame_renderer::implementation : boost::noncopyable
 };\r
        \r
 frame_renderer::frame_renderer(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-consumer_frame frame_renderer::render(const producer_frame& frame)\r
-{\r
-       return impl_->render(frame);\r
-}\r
+consumer_frame frame_renderer::render(const producer_frame& frame){return impl_->render(std::move(frame));}\r
 }}
\ No newline at end of file
index 65392fbf2eb9d8d9de18e62ca84c00445911dfbc..f2e0084ce4c5eeb0bcfa8ca49ec625d8d946dc2e 100644 (file)
@@ -3,10 +3,13 @@
 #include <memory>\r
 \r
 namespace caspar { namespace core {\r
-               \r
+       \r
 class read_frame;\r
 typedef std::shared_ptr<read_frame> read_frame_ptr;\r
 \r
+struct drawable_frame;\r
+typedef std::shared_ptr<drawable_frame> drawable_frame_ptr;\r
+\r
 class write_frame;\r
 typedef std::shared_ptr<write_frame> write_frame_ptr;\r
 \r
index 07d54101391ddaa1b4de1afcbaf1bdcffc387636..4b704cb41ce0145ae8662948475b0a2055080a57 100644 (file)
 #include <boost/noncopyable.hpp>\r
 #include <boost/range/iterator_range.hpp>\r
 #include <boost/variant.hpp>\r
+#include <boost/utility/enable_if.hpp>\r
 \r
 #include <memory>\r
 #include <vector>\r
+#include <type_traits>\r
 \r
 namespace caspar { namespace core {\r
+               \r
+struct eof_frame{};\r
+struct empty_frame{};\r
 \r
 class producer_frame\r
 {\r
-public:        \r
-       typedef boost::iterator_range<const unsigned char*> pixel_data_type;\r
-       typedef std::vector<short> audio_data_type;\r
+       enum frame_type\r
+       {\r
+               normal_type,\r
+               eof_type,\r
+               empty_type\r
+       };\r
+public:\r
+       producer_frame() : type_(empty_type){}\r
+       producer_frame(const producer_frame& other) : frame_(other.frame_), type_(other.type_){}\r
+       producer_frame(producer_frame&& other) : frame_(std::move(other.frame_)), type_(other.type_){}\r
        \r
-       producer_frame() : frame_(empty_frame()){}\r
-       producer_frame(const write_frame_ptr& frame) : frame_(frame){if(!frame) frame_ = eof_frame();}\r
-       producer_frame(const composite_frame_ptr& frame) : frame_(frame){if(!frame) frame_ = eof_frame();}\r
-       producer_frame(const transform_frame_ptr& frame) : frame_(frame){if(!frame) frame_ = eof_frame();}\r
+       producer_frame(drawable_frame_ptr&& frame) : frame_(std::move(frame)), type_(normal_type){}\r
+       producer_frame(write_frame&& frame) : frame_(std::make_shared<write_frame>(std::move(frame))), type_(normal_type){}\r
+       producer_frame(composite_frame&& frame) : frame_(std::make_shared<composite_frame>(std::move(frame))), type_(normal_type){}\r
+       producer_frame(transform_frame&& frame) : frame_(std::make_shared<transform_frame>(std::move(frame))), type_(normal_type){}\r
 \r
-       producer_frame(const producer_frame& other) : frame_(other.frame_){}\r
-       producer_frame(producer_frame&& other) : frame_(std::move(other.frame_)){}\r
-\r
-       producer_frame& operator=(const producer_frame& other)\r
+       producer_frame(eof_frame&&) : type_(eof_type){}\r
+       producer_frame(empty_frame&&) : type_(empty_type){}\r
+       \r
+       const std::vector<short>& audio_data() const \r
        {\r
-               producer_frame temp(other);\r
-               frame_.swap(temp.frame_);\r
-               return *this;\r
-       }\r
+               static std::vector<short> no_audio;\r
+               return frame_ ? frame_->audio_data() : no_audio;\r
+       }       \r
 \r
-       producer_frame& operator=(producer_frame&& other)\r
+       void begin_write()\r
        {\r
-               frame_ = std::move(other.frame_);\r
-               return *this;\r
+               if(frame_)\r
+                       frame_->begin_write();\r
        }\r
-               \r
-       const audio_data_type& audio_data() const {return boost::apply_visitor(audio_data_visitor(), frame_);}\r
 \r
-       void begin_write() {boost::apply_visitor(begin_write_visitor(), frame_);}       \r
-       void draw(frame_shader& shader) {boost::apply_visitor(draw_visitor(shader), frame_);    }\r
-       void end_write() {boost::apply_visitor(end_write_visitor(), frame_);}\r
-       \r
-       static const producer_frame& eof()\r
+       void end_write()\r
        {\r
-               static producer_frame eof(eof_frame());\r
-               return eof;\r
+               if(frame_)\r
+                       frame_->end_write();\r
        }\r
 \r
-       static const producer_frame& empty()\r
+       void draw(frame_shader& shader)\r
        {\r
-               static producer_frame empty(empty_frame());\r
-               return empty;\r
+               if(frame_)\r
+                       frame_->draw(shader);\r
        }\r
 \r
-       bool operator==(const producer_frame& other)\r
+       void swap(producer_frame& other)\r
        {\r
-               return frame_ == other.frame_;\r
+               frame_.swap(other.frame_);\r
+               std::swap(type_, other.type_);\r
        }\r
 \r
-       bool operator!=(const producer_frame& other)\r
-       {\r
-               return !(*this == other);\r
-       }\r
+       static eof_frame eof(){return eof_frame();}\r
+       static empty_frame empty(){return empty_frame();}\r
+       \r
+       bool operator==(const eof_frame&){return type_ == eof_type;}\r
+       bool operator!=(const eof_frame&){return type_ != eof_type;}\r
 \r
-private:\r
+       bool operator==(const empty_frame&){return type_ == empty_type;}\r
+       bool operator!=(const empty_frame&){return type_ != empty_type;}\r
 \r
-       friend class frame_processor_device;\r
-       friend class frame_renderer;\r
+       bool operator==(const producer_frame& other){return frame_ == other.frame_ && type_ == other.type_;}\r
+       bool operator!=(const producer_frame& other){return !(*this == other);}\r
        \r
-       struct null_frame\r
-       {\r
-               void begin_write(){}\r
-               void draw(frame_shader& shader){}\r
-               void end_write(){}\r
-               audio_data_type& audio_data() { static audio_data_type audio_data; return audio_data;} \r
-       };\r
-       typedef std::shared_ptr<null_frame> null_frame_ptr;\r
-\r
-       producer_frame(const null_frame_ptr& frame) : frame_(frame){}\r
-               \r
-       static const null_frame_ptr& eof_frame()\r
+       producer_frame& operator=(const producer_frame& other)\r
        {\r
-               static null_frame_ptr eof(new null_frame());\r
-               return eof;\r
+               producer_frame temp(other);\r
+               temp.swap(*this);\r
+               return *this;\r
        }\r
-\r
-       static const null_frame_ptr& empty_frame()\r
+       producer_frame& operator=(producer_frame&& other)\r
        {\r
-               static null_frame_ptr empty(new null_frame());\r
-               return empty;\r
+               frame_ = std::move(other.frame_);\r
+               std::swap(type_, other.type_);\r
+               return *this;\r
        }\r
-\r
-       struct audio_data_visitor : public boost::static_visitor<audio_data_type&>\r
-       {\r
-               template<typename P> audio_data_type& operator()(P& frame) const{return frame->audio_data();}\r
-       };\r
-\r
-       struct begin_write_visitor : public boost::static_visitor<void>\r
-       {\r
-               template<typename P> void operator()(P& frame) const{frame->begin_write();}\r
-       };\r
-       \r
-       struct draw_visitor : public boost::static_visitor<void>\r
+       producer_frame& operator=(eof_frame&& frame)\r
        {\r
-               draw_visitor(frame_shader& shader) : shader_(shader){}\r
-               template<typename P> void operator()(P& frame) const{frame->draw(shader_);}\r
-               frame_shader& shader_;\r
-       };\r
-\r
-       struct end_write_visitor : public boost::static_visitor<void>\r
+               frame_ = nullptr;\r
+               type_ = eof_type;\r
+               return *this;\r
+       }       \r
+       producer_frame& operator=(empty_frame&& frame)\r
        {\r
-               template<typename P> void operator()(P& frame) const{frame->end_write();}\r
-       };\r
+               frame_ = nullptr;\r
+               type_ = empty_type;\r
+               return *this;\r
+       }       \r
 \r
-       boost::variant<write_frame_ptr, composite_frame_ptr, transform_frame_ptr, null_frame_ptr> frame_;\r
+private:               \r
+       drawable_frame_ptr frame_;\r
+       frame_type type_;\r
 };\r
 \r
 }}
\ No newline at end of file
index 689d3248d9c52c8d16847cccfb38d63fdcf178cb..b54f42f6f09a8df6c9a7b90b8ac0b53e731800ae 100644 (file)
@@ -9,7 +9,7 @@
 \r
 namespace caspar { namespace core {\r
                                                                                                                                                                                                                                                                                                                        \r
-struct read_frame::implementation : boost::noncopyable\r
+struct read_frame_impl::implementation : boost::noncopyable\r
 {\r
        implementation(size_t width, size_t height) : pixel_data_(nullptr)\r
        {\r
@@ -37,14 +37,14 @@ struct read_frame::implementation : boost::noncopyable
        std::vector<short> audio_data_;\r
 };\r
        \r
-read_frame::read_frame(size_t width, size_t height) : impl_(new implementation(width, height)){}\r
-void read_frame::begin_read(){impl_->begin_read();}\r
-void read_frame::end_read(){impl_->end_read();}\r
-const boost::iterator_range<const unsigned char*> read_frame::pixel_data() const\r
+read_frame_impl::read_frame_impl(size_t width, size_t height) : impl_(new implementation(width, height)){}\r
+void read_frame_impl::begin_read(){impl_->begin_read();}\r
+void read_frame_impl::end_read(){impl_->end_read();}\r
+const boost::iterator_range<const unsigned char*> read_frame_impl::pixel_data() const\r
 {\r
        auto ptr = static_cast<const unsigned char*>(impl_->pixel_data_);\r
        return boost::iterator_range<const unsigned char*>(ptr, ptr+impl_->pbo_->size());\r
 }\r
-const std::vector<short>& read_frame::audio_data() const { return impl_->audio_data_; }\r
-std::vector<short>& read_frame::audio_data() { return impl_->audio_data_; }\r
+const std::vector<short>& read_frame_impl::audio_data() const { return impl_->audio_data_; }\r
+std::vector<short>& read_frame_impl::audio_data() { return impl_->audio_data_; }\r
 }}
\ No newline at end of file
index 3180edfd2d0ff3a11fa825fa862be8fb40925f14..e2853f33ef5245ceaba92140e89f74e01e6a130e 100644 (file)
 \r
 namespace caspar { namespace core {\r
 \r
-class read_frame : boost::noncopyable\r
+class read_frame_impl : boost::noncopyable\r
 {\r
 public:        \r
-       explicit read_frame(size_t width, size_t height);\r
+       read_frame_impl(size_t width, size_t height);\r
 \r
        const boost::iterator_range<const unsigned char*> pixel_data() const;\r
        const std::vector<short>& audio_data() const;\r
@@ -27,5 +27,28 @@ private:
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<read_frame> read_frame_ptr;\r
+typedef std::shared_ptr<read_frame_impl> read_frame_impl_ptr;\r
+\r
+class read_frame\r
+{\r
+public:\r
+       explicit read_frame(const read_frame_impl_ptr& frame) : frame_(frame){}\r
+       read_frame(read_frame&& other) : frame_(std::move(other.frame_)){}\r
+       read_frame& operator=(read_frame&& other)\r
+       {\r
+               frame_ = std::move(other.frame_);\r
+               return *this;\r
+       }\r
+       \r
+       const boost::iterator_range<const unsigned char*> pixel_data() const { return frame_->pixel_data();}\r
+       const std::vector<short>& audio_data() const { return frame_->audio_data();}\r
+       std::vector<short>& audio_data() { return frame_->audio_data();};\r
+       \r
+       void begin_read(){ frame_->begin_read();}\r
+       void end_read(){ frame_->end_read();}\r
+\r
+private:\r
+       read_frame_impl_ptr frame_;\r
+};\r
+\r
 }}
\ No newline at end of file
index f0ef051fff678c01a4d00738c3fea8823fddf601..03b873c0fa33c34576bea16d7edb10821ca42685 100644 (file)
@@ -61,7 +61,13 @@ struct transform_frame::implementation : boost::noncopyable
        producer_frame frame_;\r
 };\r
        \r
-transform_frame::transform_frame(const producer_frame& frame) : impl_(new implementation(frame)){}\r
+transform_frame::transform_frame(const producer_frame& frame) : impl_(new implementation(std::move(frame))){}\r
+transform_frame::transform_frame(transform_frame&& other) : impl_(std::move(other.impl_)){}\r
+transform_frame& transform_frame::operator=(transform_frame&& other)\r
+{\r
+       impl_ = std::move(other.impl_);\r
+       return *this;\r
+}\r
 void transform_frame::begin_write(){impl_->begin_write();}\r
 void transform_frame::end_write(){impl_->end_write();} \r
 void transform_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
index 7397c5d20beb2562e1b7b40805bc817ab7edc37e..720a60df3dca748296c4ad070286770939cde882 100644 (file)
@@ -2,6 +2,8 @@
 \r
 #include "fwd.h"\r
 \r
+#include "drawable_frame.h"\r
+\r
 #include "../format/video_format.h"\r
 #include "../format/pixel_format.h"\r
 \r
 \r
 namespace caspar { namespace core {\r
                \r
-class transform_frame\r
+class transform_frame : public drawable_frame\r
 {\r
 public:\r
-       explicit transform_frame(const producer_frame& frame);\r
+       transform_frame(const producer_frame& frame);\r
+       transform_frame(transform_frame&& other);\r
+       transform_frame& operator=(transform_frame&& other);\r
        \r
-       std::vector<short>& audio_data();\r
-       const std::vector<short>& audio_data() const;\r
+       virtual std::vector<short>& audio_data();\r
+       virtual const std::vector<short>& audio_data() const;\r
 \r
        void audio_volume(unsigned char volume);\r
        void translate(double x, double y);\r
@@ -28,14 +32,13 @@ public:
        void video_mode(video_mode::type mode);\r
        void alpha(double value);\r
 \r
-       void begin_write();\r
-       void end_write();\r
-       void draw(frame_shader& shader);\r
+       virtual void begin_write();\r
+       virtual void end_write();\r
+       virtual void draw(frame_shader& shader);\r
 \r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<transform_frame> transform_frame_ptr;\r
 \r
 }}
\ No newline at end of file
index fe3d773d355098331fe307ed4401506fcc0218dc..de0e34f582a6b31d1caeb4ca68d46d6dc742b0d2 100644 (file)
@@ -13,7 +13,7 @@
 \r
 namespace caspar { namespace core {\r
                                                                                                                                                                                                                                                                                                                        \r
-struct write_frame::implementation : boost::noncopyable\r
+struct write_frame_impl::implementation : boost::noncopyable\r
 {\r
        implementation(const pixel_format_desc& desc) : desc_(desc)\r
        {                       \r
@@ -85,22 +85,22 @@ struct write_frame::implementation : boost::noncopyable
        const pixel_format_desc desc_;\r
 };\r
        \r
-write_frame::write_frame(const pixel_format_desc& desc) : impl_(new implementation(desc)){}\r
-void write_frame::begin_write(){impl_->begin_write();}\r
-void write_frame::end_write(){impl_->end_write();}     \r
-void write_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
-boost::iterator_range<unsigned char*> write_frame::pixel_data(size_t index)\r
+write_frame_impl::write_frame_impl(const pixel_format_desc& desc) : impl_(new implementation(desc)){}\r
+void write_frame_impl::begin_write(){impl_->begin_write();}\r
+void write_frame_impl::end_write(){impl_->end_write();}        \r
+void write_frame_impl::draw(frame_shader& shader){impl_->draw(shader);}\r
+boost::iterator_range<unsigned char*> write_frame_impl::pixel_data(size_t index)\r
 {\r
        auto ptr = static_cast<unsigned char*>(impl_->pixel_data_[index]);\r
        return boost::iterator_range<unsigned char*>(ptr, ptr+impl_->desc_.planes[index].size);\r
 }\r
-const boost::iterator_range<const unsigned char*> write_frame::pixel_data(size_t index) const\r
+const boost::iterator_range<const unsigned char*> write_frame_impl::pixel_data(size_t index) const\r
 {\r
        auto ptr = static_cast<const unsigned char*>(impl_->pixel_data_[index]);\r
        return boost::iterator_range<const unsigned char*>(ptr, ptr+impl_->desc_.planes[index].size);\r
 }\r
 \r
-std::vector<short>& write_frame::audio_data() { return impl_->audio_data_; }\r
-const std::vector<short>& write_frame::audio_data() const { return impl_->audio_data_; }\r
-void write_frame::reset(){impl_->reset();}\r
+std::vector<short>& write_frame_impl::audio_data() { return impl_->audio_data_; }\r
+const std::vector<short>& write_frame_impl::audio_data() const { return impl_->audio_data_; }\r
+void write_frame_impl::reset(){impl_->reset();}\r
 }}
\ No newline at end of file
index eb2b3fdfb2aeb52e6874210ba63743d244a6ed97..c67480aa3ad458725095c9255fc2b9516eb1c91d 100644 (file)
@@ -2,6 +2,8 @@
 \r
 #include "fwd.h"\r
 \r
+#include "drawable_frame.h"\r
+\r
 #include "../format/video_format.h"\r
 #include "../format/pixel_format.h"\r
 \r
 \r
 namespace caspar { namespace core {\r
                \r
-class write_frame\r
+class write_frame_impl\r
 {\r
 public:        \r
-       explicit write_frame(const pixel_format_desc& desc);\r
+       explicit write_frame_impl(const pixel_format_desc& desc);\r
 \r
        boost::iterator_range<unsigned char*> pixel_data(size_t index = 0);\r
        const boost::iterator_range<const unsigned char*> pixel_data(size_t index = 0) const;\r
+       \r
+       void reset();\r
 \r
        std::vector<short>& audio_data();\r
        const std::vector<short>& audio_data() const;\r
        \r
-       void reset();\r
-               \r
        void begin_write();\r
        void end_write();\r
        void draw(frame_shader& shader);\r
@@ -36,7 +38,33 @@ private:
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<write_frame> write_frame_ptr;\r
+typedef std::shared_ptr<write_frame_impl> write_frame_impl_ptr;\r
+\r
+class write_frame : public drawable_frame\r
+{\r
+public:\r
+       explicit write_frame(const write_frame_impl_ptr& frame) : frame_(frame){}\r
+       write_frame(write_frame&& other) : frame_(std::move(other.frame_)){}\r
+       write_frame& operator=(write_frame&& other)\r
+       {\r
+               frame_ = std::move(other.frame_);\r
+               return *this;\r
+       }\r
+\r
+       boost::iterator_range<unsigned char*> pixel_data(size_t index = 0) {return frame_->pixel_data(index);}\r
+       const boost::iterator_range<const unsigned char*> pixel_data(size_t index = 0) const {return frame_->pixel_data(index);}\r
+       \r
+       void reset() {return frame_->reset();}\r
+\r
+       virtual std::vector<short>& audio_data() {return frame_->audio_data();}\r
+       virtual const std::vector<short>& audio_data() const {return frame_->audio_data();}\r
+                       \r
+       virtual void begin_write() {return frame_->begin_write();}\r
+       virtual void end_write() {return frame_->end_write();}\r
+       virtual void draw(frame_shader& shader) {return frame_->draw(shader);}\r
+private:\r
+       write_frame_impl_ptr frame_;\r
+};\r
 \r
 \r
 }}
\ No newline at end of file
index 45314db3cce9b67216fbad041574f7c80a13f1ed..6b26b728de8f883f154b5d48b191893941599a86 100644 (file)
@@ -66,7 +66,7 @@ unsigned int get_pixel_color_value(const std::wstring& parameter)
 class color_producer : public frame_producer\r
 {\r
 public:\r
-       explicit color_producer(const std::wstring& color) : color_str_(color), color_value_(get_pixel_color_value(color)), frame_(producer_frame::empty()){}\r
+       explicit color_producer(const std::wstring& color) : color_str_(color), color_value_(get_pixel_color_value(color)){}\r
        \r
        producer_frame receive()\r
        { \r
@@ -75,9 +75,9 @@ public:
 \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
-               auto frame = frame_processor->create_frame();\r
-               __stosd(reinterpret_cast<unsigned long*>(frame->pixel_data().begin()), color_value_, frame->pixel_data().size() / sizeof(unsigned long));\r
-               frame_ = frame;\r
+               write_frame frame = std::move(frame_processor->create_frame());\r
+               __stosd(reinterpret_cast<unsigned long*>(frame.pixel_data().begin()), color_value_, frame.pixel_data().size() / sizeof(unsigned long));\r
+               frame_ = std::move(frame);\r
        }\r
        \r
        std::wstring print() const\r
index a6db77baf4172fd7024399425cfc3ce69a4d8beb..cbf938923124e97e990fde5ae5f84a5d11e6fbdd 100644 (file)
@@ -93,7 +93,7 @@ public:
                                {\r
                                        auto decoded_frame = video_decoder_->execute(video_packet);\r
                                        auto transformed_frame = video_transformer_->execute(decoded_frame);\r
-                                       video_frame_channel_.push_back(transformed_frame);      \r
+                                       video_frame_channel_.push_back(std::move(transformed_frame));   \r
                                }\r
                        }, \r
                        [&] \r
@@ -122,13 +122,13 @@ public:
 \r
                        while(!video_frame_channel_.empty() && (!audio_chunk_channel_.empty() || !has_audio_))\r
                        {\r
-                               if(has_audio_ && video_frame_channel_.front()\r
+                               if(has_audio_) \r
                                {\r
-                                       video_frame_channel_.front()->audio_data() = std::move(audio_chunk_channel_.front());\r
+                                       video_frame_channel_.front().audio_data() = std::move(audio_chunk_channel_.front());\r
                                        audio_chunk_channel_.pop_front();\r
                                }\r
                                \r
-                               auto frame = video_frame_channel_.front();\r
+                               auto frame = std::move(video_frame_channel_.front());\r
                                video_frame_channel_.pop_front();\r
                                ouput_channel_.push(std::move(frame));\r
                        }                               \r
@@ -136,7 +136,7 @@ public:
 \r
                if(!ouput_channel_.empty())\r
                {\r
-                       last_frame_ = ouput_channel_.front();\r
+                       last_frame_ = std::move(ouput_channel_.front());\r
                        ouput_channel_.pop();\r
                }\r
                else if(input_->is_eof())\r
@@ -156,12 +156,12 @@ public:
 \r
        video_decoder_uptr                                      video_decoder_;\r
        video_transformer_uptr                          video_transformer_;\r
-       std::deque<transform_frame_ptr>         video_frame_channel_;\r
+       std::deque<transform_frame>                     video_frame_channel_;\r
        \r
        audio_decoder_ptr                                       audio_decoder_;\r
        std::deque<std::vector<short>>          audio_chunk_channel_;\r
 \r
-       std::queue<transform_frame_ptr>         ouput_channel_;\r
+       std::queue<transform_frame>                     ouput_channel_;\r
        \r
        std::wstring                                            filename_;\r
 \r
index fb435ca85cc7d318134406b8d248f1fc24f41375..4558f43187d272465eaaa0e830068a1882e159fc 100644 (file)
@@ -3,7 +3,7 @@
 #include "video_transformer.h"\r
 \r
 #include "../../../format/video_format.h"\r
-#include "../../../processor/write_frame.h"\r
+#include "../../../processor/transform_frame.h"\r
 #include "../../../processor/transform_frame.h"\r
 #include "../../../processor/producer_frame.h"\r
 #include "../../../processor/frame_processor_device.h"\r
@@ -105,20 +105,20 @@ struct video_transformer::implementation : boost::noncopyable
                }\r
        }\r
        \r
-       transform_frame_ptr execute(const std::shared_ptr<AVFrame>& decoded_frame)\r
+       transform_frame execute(const std::shared_ptr<AVFrame>& decoded_frame)\r
        {                               \r
                if(decoded_frame == nullptr)\r
-                       return nullptr;\r
+                       return transform_frame(producer_frame::eof()); // TODO\r
                                \r
-               write_frame_ptr result_frame;\r
+               transform_frame transform = producer_frame::eof();\r
                if(sws_context_ == nullptr)\r
                {\r
-                       result_frame = frame_processor_->create_frame(desc_);\r
+                       auto write = frame_processor_->create_frame(desc_);\r
 \r
                        tbb::parallel_for(0, static_cast<int>(desc_.planes.size()), 1, [&](int n)\r
                        {\r
                                auto plane            = desc_.planes[n];\r
-                               auto result           = result_frame->pixel_data(n).begin();\r
+                               auto result           = write.pixel_data(n).begin();\r
                                auto decoded          = decoded_frame->data[n];\r
                                auto decoded_linesize = decoded_frame->linesize[n];\r
                                \r
@@ -127,25 +127,29 @@ struct video_transformer::implementation : boost::noncopyable
                                        std::copy_n(decoded + y*decoded_linesize, plane.linesize, result + y*plane.linesize);\r
                                });\r
                        });\r
+\r
+                       transform = producer_frame(std::move(write));\r
                }\r
                else\r
                {\r
-                       result_frame = frame_processor_->create_frame(width_, height_);\r
+                       auto write = frame_processor_->create_frame(width_, height_);\r
 \r
                        AVFrame av_frame;       \r
                        avcodec_get_frame_defaults(&av_frame);\r
-                       avpicture_fill(reinterpret_cast<AVPicture*>(&av_frame), result_frame->pixel_data().begin(), PIX_FMT_BGRA, width_, height_);\r
+                       avpicture_fill(reinterpret_cast<AVPicture*>(&av_frame), write.pixel_data().begin(), PIX_FMT_BGRA, width_, height_);\r
                 \r
-                       sws_scale(sws_context_.get(), decoded_frame->data, decoded_frame->linesize, 0, height_, av_frame.data, av_frame.linesize);              \r
+                       sws_scale(sws_context_.get(), decoded_frame->data, decoded_frame->linesize, 0, height_, av_frame.data, av_frame.linesize);      \r
+                       \r
+                       transform = producer_frame(std::move(write));\r
                }\r
                \r
-               auto transform = std::make_shared<transform_frame>(result_frame);\r
                // TODO: Make generic for all formats and modes.\r
                if(codec_context_->codec_id == CODEC_ID_DVVIDEO) // Move up one field           \r
-                       transform->translate(0.0f, 1.0/static_cast<double>(frame_processor_->get_video_format_desc().height));          \r
+                       transform.translate(0.0f, 1.0/static_cast<double>(frame_processor_->get_video_format_desc().height));           \r
                \r
                return transform;\r
        }\r
+\r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
                frame_processor_ = frame_processor;\r
@@ -163,6 +167,6 @@ struct video_transformer::implementation : boost::noncopyable
 };\r
 \r
 video_transformer::video_transformer(AVCodecContext* codec_context) : impl_(new implementation(codec_context)){}\r
-transform_frame_ptr video_transformer::execute(const std::shared_ptr<AVFrame>& decoded_frame){return impl_->execute(decoded_frame);}\r
+transform_frame video_transformer::execute(const std::shared_ptr<AVFrame>& decoded_frame){return impl_->execute(decoded_frame);}\r
 void video_transformer::initialize(const frame_processor_device_ptr& frame_processor){impl_->initialize(frame_processor); }\r
 }}}
\ No newline at end of file
index c27ecf6f5698914388ae894be2762d7a61dd05d0..566eb3471ccb5f07a8e735bb9c102b36b9439bab 100644 (file)
@@ -13,7 +13,7 @@ class video_transformer : boost::noncopyable
 {\r
 public:\r
        video_transformer(AVCodecContext* codec_context);\r
-       transform_frame_ptr execute(const std::shared_ptr<AVFrame>& video_packet);      \r
+       transform_frame execute(const std::shared_ptr<AVFrame>& video_packet);  \r
        void initialize(const frame_processor_device_ptr& frame_processor);\r
 private:\r
        struct implementation;\r
index 5845e64cb10a4854d7bfc1e0a64d86774d3a285d..b1d90b7237d9dfb81aea5456eeb08700af31818c 100644 (file)
@@ -230,12 +230,8 @@ struct flash_producer::implementation
                        if(is_progressive)                                                      \r
                                result = do_receive();          \r
                        else\r
-                       {\r
-                               producer_frame frame1 = do_receive();\r
-                               producer_frame frame2 = do_receive();\r
-                               result = composite_frame::interlace(frame1, frame2, format_desc.mode);\r
-                       }\r
-\r
+                               result = composite_frame::interlace(do_receive(), do_receive(), format_desc.mode);\r
+                       \r
                        frame_buffer_.push(result);\r
                        is_empty_ = flashax_container_->IsEmpty();\r
                }\r
@@ -255,8 +251,8 @@ struct flash_producer::implementation
                }       \r
 \r
                auto frame = frame_processor_->create_frame(format_desc.width, format_desc.height);\r
-               std::copy(current_frame_->data(), current_frame_->data() + current_frame_->size(), frame->pixel_data().begin());\r
-               return frame;\r
+               std::copy(current_frame_->data(), current_frame_->data() + current_frame_->size(), frame.pixel_data().begin());\r
+               return producer_frame(std::make_shared<write_frame>(std::move(frame)));\r
        }\r
                \r
        producer_frame receive()\r
index 3f6319d6610b0a839335f92357f128dcb40945d2..60571295155ccad9ad99a6be205ffc25dbbd38eb 100644 (file)
@@ -22,7 +22,7 @@
        \r
 namespace caspar { namespace core {\r
        \r
-std::vector<producer_frame> receives(std::map<int, layer>& layers)\r
+std::vector<producer_frame> receive(std::map<int, layer>& layers)\r
 {      \r
        std::vector<producer_frame> frames(layers.size(), producer_frame::empty());\r
        tbb::parallel_for(tbb::blocked_range<size_t>(0, frames.size()), \r
@@ -48,7 +48,7 @@ struct frame_producer_device::implementation : boost::noncopyable
        {               \r
                try\r
                {       \r
-                       frame_processor_->send(std::make_shared<composite_frame>(receives(layers_)));\r
+                       frame_processor_->send(composite_frame(receive(layers_)));\r
                }\r
                catch(...)\r
                {\r
@@ -147,8 +147,7 @@ struct frame_producer_device::implementation : boost::noncopyable
        std::map<int, layer> layers_;           \r
 };\r
 \r
-frame_producer_device::frame_producer_device(const frame_processor_device_ptr& frame_processor) \r
-       : impl_(new implementation(frame_processor)){}\r
+frame_producer_device::frame_producer_device(const frame_processor_device_ptr& frame_processor) : impl_(new implementation(frame_processor)){}\r
 void frame_producer_device::load(int render_layer, const frame_producer_ptr& producer, load_option::type option){impl_->load(render_layer, producer, option);}\r
 void frame_producer_device::pause(int render_layer){impl_->pause(render_layer);}\r
 void frame_producer_device::play(int render_layer){impl_->play(render_layer);}\r
index b4303f875a00eebd339ba5708255e06a26f4fd6f..87eb6d6c138b653c28582e8d17d8a4e40a33f6ec 100644 (file)
@@ -28,8 +28,8 @@ struct image_producer : public frame_producer
                auto bitmap = load_image(filename_);\r
                FreeImage_FlipVertical(bitmap.get());\r
                auto frame = frame_processor->create_frame(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()));\r
-               std::copy_n(FreeImage_GetBits(bitmap.get()), frame->pixel_data().size(), frame->pixel_data().begin());\r
-               frame_ = frame;\r
+               std::copy_n(FreeImage_GetBits(bitmap.get()), frame.pixel_data().size(), frame.pixel_data().begin());\r
+               frame_ = std::move(frame);\r
        }\r
 \r
        std::wstring print() const\r
index b899c0bb6b3a71eb464707bfb112460c0a0f7bcc..9afa81f06f4d3ee38fc1d3ab26c6235f517d1c39 100644 (file)
@@ -70,12 +70,12 @@ struct image_scroll_producer : public frame_producer
        producer_frame do_receive()\r
        {\r
                auto frame = frame_processor_->create_frame(format_desc_.width, format_desc_.height);\r
-               std::fill(frame->pixel_data().begin(), frame->pixel_data().end(), 0);\r
+               std::fill(frame.pixel_data().begin(), frame.pixel_data().end(), 0);\r
 \r
                const int delta_x = direction_ == direction::Left ? speed_ : -speed_;\r
                const int delta_y = direction_ == direction::Up ? speed_ : -speed_;\r
 \r
-               unsigned char* frame_data = frame->pixel_data().begin();\r
+               unsigned char* frame_data = frame.pixel_data().begin();\r
                unsigned char* image_data = image_.get();\r
        \r
                if (direction_ == direction::Up || direction_ == direction::Down)\r
@@ -109,7 +109,7 @@ struct image_scroll_producer : public frame_producer
                        offset_ += delta_x;\r
                }\r
 \r
-               return frame;\r
+               return std::move(frame);\r
        }\r
                \r
        producer_frame receive()\r
@@ -118,8 +118,8 @@ struct image_scroll_producer : public frame_producer
                {\r
                        producer_frame frame1;\r
                        producer_frame frame2;\r
-                       tbb::parallel_invoke([&]{ frame1 = do_receive(); }, [&]{ frame2 = do_receive(); });\r
-                       return composite_frame::interlace(frame1, frame2, format_desc_.mode);\r
+                       tbb::parallel_invoke([&]{ frame1 = std::move(do_receive()); }, [&]{ frame2 = std::move(do_receive()); });\r
+                       return composite_frame::interlace(std::move(frame1), std::move(frame2), format_desc_.mode);\r
                }                       \r
 \r
                return receive();       \r
index fe9d688adece23d1cdb0be51bc09689b0fd08e3a..379fc3904edf8b7650412cd7f5f681c2bba5b325 100644 (file)
@@ -63,7 +63,7 @@ struct layer::implementation
                {\r
                        last_frame_ = foreground_->receive();\r
 \r
-                       if(last_frame_ == producer_frame::eof())\r
+                       if(last_frame_ == producer_frame::eof() && foreground_->get_following_producer())\r
                        {\r
                                CASPAR_LOG(info) << L"EOF: " << foreground_->print();\r
                                auto following = foreground_->get_following_producer();\r
index 1fa5e71b2f9cd4a28eeab07d53660ba070608baa..2cd71861371f542b0621d17851599f1204d21da4 100644 (file)
@@ -131,30 +131,30 @@ struct transition_producer::implementation : boost::noncopyable
                double alpha = static_cast<double>(current_frame_)/static_cast<double>(info_.duration);\r
                unsigned char volume = static_cast<unsigned char>(alpha*256.0);\r
 \r
-               auto my_src_frame = std::make_shared<transform_frame>(src_frame);\r
-               auto my_dest_frame = std::make_shared<transform_frame>(dest_frame);\r
+               transform_frame my_src_frame = std::move(src_frame);\r
+               transform_frame my_dest_frame = std::move(dest_frame);\r
 \r
-               my_src_frame->audio_volume(255-volume);\r
-               my_dest_frame->audio_volume(volume);\r
+               my_src_frame.audio_volume(255-volume);\r
+               my_dest_frame.audio_volume(volume);\r
 \r
                double dir = info_.direction == transition_direction::from_left ? 1.0 : -1.0;           \r
                \r
                if(info_.type == transition::mix)\r
-                       my_dest_frame->alpha(alpha);            \r
+                       my_dest_frame.alpha(alpha);             \r
                else if(info_.type == transition::slide)                        \r
-                       my_dest_frame->translate((-1.0+alpha)*dir, 0.0);                        \r
+                       my_dest_frame.translate((-1.0+alpha)*dir, 0.0);                 \r
                else if(info_.type == transition::push)\r
                {\r
-                       my_dest_frame->translate((-1.0+alpha)*dir, 0.0);\r
-                       my_src_frame->translate((0.0+alpha)*dir, 0.0);\r
+                       my_dest_frame.translate((-1.0+alpha)*dir, 0.0);\r
+                       my_src_frame.translate((0.0+alpha)*dir, 0.0);\r
                }\r
                else if(info_.type == transition::wipe)\r
                {\r
-                       my_dest_frame->translate((-1.0+alpha)*dir, 0.0);                        \r
-                       my_dest_frame->texcoord((-1.0+alpha)*dir, 1.0, 1.0-(1.0-alpha)*dir, 0.0);                               \r
+                       my_dest_frame.translate((-1.0+alpha)*dir, 0.0);                 \r
+                       my_dest_frame.texcoord((-1.0+alpha)*dir, 1.0, 1.0-(1.0-alpha)*dir, 0.0);                                \r
                }\r
-                                               \r
-               return std::make_shared<composite_frame>(my_src_frame, my_dest_frame);\r
+\r
+               return std::make_shared<composite_frame>(std::move(my_src_frame), std::move(my_dest_frame));\r
        }\r
                \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r