]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Wed, 27 Jul 2011 18:38:28 +0000 (18:38 +0000)
committerRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Wed, 27 Jul 2011 18:38:28 +0000 (18:38 +0000)
core/mixer/image/image_mixer.cpp
core/mixer/write_frame.cpp
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/filter/filter.cpp
modules/ffmpeg/producer/filter/filter.h
modules/ffmpeg/producer/video/video_decoder.cpp

index e0067896f8fa6f2d4b3c9b238b40a817f1f39e37..f5b2f6304e43ddef2a64f02333921cbd859789ea 100644 (file)
@@ -106,6 +106,9 @@ public:
                \r
        void visit(core::write_frame& frame)\r
        {                       \r
+               if(frame.get_textures().empty())\r
+                       return;\r
+\r
                render_item item = {frame.get_pixel_format_desc(), frame.get_textures(), transform_stack_.top()*frame.get_image_transform(), frame.tag()};      \r
 \r
                auto& layer = render_queue_.back();\r
index ac57f244f24329bd796a4573bb9a2910d781bb8d..8f10bba5b6cb06fa5241e8718e4c0c91299b4d42 100644 (file)
@@ -32,13 +32,13 @@ namespace caspar { namespace core {
                                                                                                                                                                                                                                                                                                                        \r
 struct write_frame::implementation\r
 {                              \r
-       ogl_device*                                                                             ogl_;\r
-       std::vector<std::shared_ptr<host_buffer>>               buffers_;\r
-       std::array<std::shared_ptr<device_buffer>, 4>   textures_;\r
-       std::vector<int16_t>                                                    audio_data_;\r
-       const core::pixel_format_desc                                   desc_;\r
-       int                                                                                             tag_;\r
-       core::video_mode::type                                                  mode_;\r
+       ogl_device*                                                                     ogl_;\r
+       std::vector<std::shared_ptr<host_buffer>>       buffers_;\r
+       std::vector<safe_ptr<device_buffer>>            textures_;\r
+       std::vector<int16_t>                                            audio_data_;\r
+       const core::pixel_format_desc                           desc_;\r
+       int                                                                                     tag_;\r
+       core::video_mode::type                                          mode_;\r
 \r
        implementation()\r
        {\r
@@ -66,8 +66,7 @@ struct write_frame::implementation
        void accept(write_frame& self, core::frame_visitor& visitor)\r
        {\r
                visitor.begin(self);\r
-               if(!desc_.planes().empty())\r
-                       visitor.visit(self);\r
+               visitor.visit(self);\r
                visitor.end();\r
        }\r
 \r
@@ -103,13 +102,11 @@ struct write_frame::implementation
                if(!buffer)\r
                        return;\r
 \r
-               auto texture\r
+               auto texture = textures_.at(plane_index);\r
                \r
                ogl_->begin_invoke([=]\r
-               {\r
-                       auto plane = desc_.planes[plane_index];\r
-                       textures_[plane_index] = ogl_->create_device_buffer(plane.width, plane.height, plane.channels);                 \r
-                       textures_[plane_index]->read(*buffer);\r
+               {                       \r
+                       texture->read(*buffer);\r
                }, high_priority);\r
        }\r
 };\r
@@ -132,17 +129,7 @@ const boost::iterator_range<const int16_t*> write_frame::audio_data() const
 }\r
 int write_frame::tag() const {return impl_->tag_;}\r
 const core::pixel_format_desc& write_frame::get_pixel_format_desc() const{return impl_->desc_;}\r
-const std::vector<safe_ptr<device_buffer>> write_frame::get_textures() const\r
-{\r
-       std::vector<safe_ptr<device_buffer>> textures;\r
-       BOOST_FOREACH(auto texture, impl_->textures_)\r
-       {\r
-               if(texture)\r
-                       textures.push_back(make_safe(texture));\r
-       }\r
-\r
-       return textures;\r
-}\r
+const std::vector<safe_ptr<device_buffer>>& write_frame::get_textures() const{return impl_->textures_;}\r
 void write_frame::commit(size_t plane_index){impl_->commit(plane_index);}\r
 void write_frame::commit(){impl_->commit();}\r
 void write_frame::set_type(const video_mode::type& mode){impl_->mode_ = mode;}\r
index 5c0e44f7dcabce80caca15d58db93b71b034fda2..7ff31a7363f617afd474bc548964ac0f4f499a40 100644 (file)
@@ -197,7 +197,15 @@ safe_ptr<core::frame_producer> create_ffmpeg_producer(const safe_ptr<core::frame
                        start = boost::lexical_cast<int>(*seek_it);\r
        }\r
 \r
-       return make_safe<ffmpeg_producer>(frame_factory, path, L"", loop, start, length);\r
+       std::wstring filter = L"";\r
+       auto filter_it = std::find(params.begin(), params.end(), L"FILTER");\r
+       if(filter_it != params.end())\r
+       {\r
+               if(++filter_it != params.end())\r
+                       filter = *filter_it;\r
+       }\r
+\r
+       return make_safe<ffmpeg_producer>(frame_factory, path, filter, loop, start, length);\r
 }\r
 \r
 }
\ No newline at end of file
index 9a5d26688c49fa825c40cb21ccc70a532d61270e..831425c7742ccaa0e1a68cf348572c52ea4ad6ac 100644 (file)
@@ -42,7 +42,7 @@ struct filter::implementation
                std::transform(filters_.begin(), filters_.end(), filters_.begin(), ::tolower);\r
        }\r
 \r
-       void push(const safe_ptr<AVFrame>& frame)\r
+       void push(const std::shared_ptr<AVFrame>& frame)\r
        {               \r
                int errn = 0;   \r
 \r
@@ -149,6 +149,6 @@ struct filter::implementation
 };\r
 \r
 filter::filter(const std::wstring& filters) : impl_(new implementation(filters)){}\r
-void filter::push(const safe_ptr<AVFrame>& frame) {impl_->push(frame);}\r
+void filter::push(const std::shared_ptr<AVFrame>& frame) {impl_->push(frame);}\r
 std::vector<safe_ptr<AVFrame>> filter::poll() {return impl_->poll();}\r
 }
\ No newline at end of file
index 6c7b87119721030e491a1959b58907958abe997d..959ec25b9334668e34ccac07f3aa0423872c32d2 100644 (file)
@@ -25,7 +25,7 @@ class filter
 public:\r
        filter(const std::wstring& filters);\r
 \r
-       void push(const safe_ptr<AVFrame>& frame);\r
+       void push(const std::shared_ptr<AVFrame>& frame);\r
        std::vector<safe_ptr<AVFrame>> poll();\r
 \r
 private:\r
index 86642d7f555d7288c4426df1e12dd64392d5303c..45959e0f35b07ac5eb56ca12db8f3e021c2d9902 100644 (file)
@@ -66,6 +66,7 @@ struct video_decoder::implementation : boost::noncopyable
        std::queue<std::shared_ptr<AVPacket>>   packet_buffer_;\r
 \r
        std::unique_ptr<filter>                                 filter_;\r
+       tbb::task_group                                                 filter_tasks_;\r
 \r
        double                                                                  fps_;\r
 public:\r
@@ -91,8 +92,8 @@ public:
                        codec_context_->time_base.num = static_cast<int>(std::pow(10.0, static_cast<int>(std::log10(static_cast<float>(codec_context_->time_base.den)))-1));    \r
 \r
                fps_ = static_cast<double>(codec_context_->time_base.den) / static_cast<double>(codec_context_->time_base.num);\r
-               //if(double_rate(filter))\r
-               //      fps_ *= 2;\r
+               if(double_rate(filter))\r
+                       fps_ *= 2;\r
        }\r
                \r
        void push(const std::shared_ptr<AVPacket>& packet)\r
@@ -114,6 +115,8 @@ public:
                        result.push_back(make_safe<core::write_frame>());\r
                else if(!packet_buffer_.empty())\r
                {\r
+                       std::vector<std::shared_ptr<AVFrame>> av_frames;\r
+\r
                        auto packet = std::move(packet_buffer_.front());\r
                        packet_buffer_.pop();\r
                \r
@@ -123,23 +126,32 @@ public:
                                {\r
                                        // FIXME: This might cause bad performance.\r
                                        AVPacket pkt = {0};\r
-                                       auto frame = decode_frame(pkt);\r
-                                       if(frame)\r
-                                               result.push_back(make_write_frame(this, make_safe(frame), frame_factory_));\r
+                                       av_frames.push_back(decode_frame(pkt));\r
                                }\r
 \r
                                avcodec_flush_buffers(codec_context_.get());\r
                        }\r
                        else\r
                        {\r
-                               auto frame = decode_frame(*packet);\r
-                               if(frame)\r
+                               av_frames.push_back(decode_frame(*packet));                             \r
+                       }\r
+\r
+                       if(filter_)\r
+                       {\r
+                               filter_tasks_.wait();\r
+                               \r
+                               av_frames.clear();\r
+                               boost::range::push_back(av_frames, filter_->poll());\r
+\r
+                               filter_tasks_.run([=]\r
                                {\r
-                                       auto frame2 = make_write_frame(this, make_safe(frame), frame_factory_); \r
-                                       mode_ = frame2->get_type();\r
-                                       result.push_back(std::move(frame2));\r
-                               }\r
+                                       BOOST_FOREACH(auto& frame, av_frames)                           \r
+                                               filter_->push(frame);\r
+                               });\r
                        }\r
+                                               \r
+                       BOOST_FOREACH(auto& frame, av_frames)\r
+                               result.push_back(make_write_frame(this, make_safe(frame), frame_factory_));\r
                }\r
                \r
                return result;\r