]> 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>
Sat, 3 Mar 2012 11:12:36 +0000 (11:12 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 3 Mar 2012 11:12:36 +0000 (11:12 +0000)
accelerator/accelerator.vcxproj
accelerator/accelerator.vcxproj.filters
accelerator/cpu/image/deinterlacer.cpp [new file with mode: 0644]
accelerator/cpu/image/deinterlacer.h [new file with mode: 0644]
accelerator/ogl/image/image_mixer.cpp
core/frame/frame.cpp
core/frame/frame.h
core/mixer/audio/audio_mixer.cpp
modules/ffmpeg/producer/muxer/frame_muxer.cpp
modules/ffmpeg/producer/util/util.cpp
modules/ffmpeg/producer/util/util.h

index 190972e6b0bc3af72cee34ef370d1f23c9b8c980..461c648cab807540e32db5771be26738632cca9d 100644 (file)
     </Lib>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
+    <ClInclude Include="cpu\image\deinterlacer.h" />\r
     <ClInclude Include="cpu\image\image_mixer.h" />\r
     <ClInclude Include="cpu\util\xmm.h" />\r
     <ClInclude Include="accelerator.h" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="accelerator.cpp" />\r
+    <ClCompile Include="cpu\image\deinterlacer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
     <ClCompile Include="cpu\image\image_mixer.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
index c5dd0891769e47e8a120fc6998c6535283285c68..6f9a035dca729b2269f38d5ee8c545beea43cef7 100644 (file)
@@ -58,6 +58,9 @@
     <ClInclude Include="ogl\util\buffer.h">\r
       <Filter>source\ogl\util</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="cpu\image\deinterlacer.h">\r
+      <Filter>source\cpu\image</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="StdAfx.cpp" />\r
@@ -88,5 +91,8 @@
     <ClCompile Include="ogl\util\buffer.cpp">\r
       <Filter>source\ogl\util</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="cpu\image\deinterlacer.cpp">\r
+      <Filter>source\cpu\image</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
diff --git a/accelerator/cpu/image/deinterlacer.cpp b/accelerator/cpu/image/deinterlacer.cpp
new file mode 100644 (file)
index 0000000..97d3298
--- /dev/null
@@ -0,0 +1,73 @@
+#include "../../StdAfx.h"\r
+\r
+#include "deinterlacer.h"\r
+/*\r
+#include <core/frame/frame_factory.h>\r
+\r
+#include <modules/ffmpeg/producer/filter/filter.h>\r
+#include <modules/ffmpeg/producer/util/util.h>\r
+\r
+#include <tbb/concurrent_hash_map.h>\r
+\r
+#include <tuple>\r
+\r
+namespace caspar { namespace accelerator { namespace cpu {\r
+\r
+struct deinterlacer::impl : public std::enable_shared_from_this<impl> \r
+{\r
+       ffmpeg::filter filter_;\r
+\r
+       typedef tbb::concurrent_hash_map<const void*, std::tuple<boost::signals2::scoped_connection, std::vector<core::const_frame>>> cache_t; \r
+\r
+       cache_t frame_cache_;\r
+\r
+public:\r
+\r
+       impl() \r
+               : filter_(L"YADIF=1:-1")\r
+       {\r
+       }\r
+\r
+       std::vector<core::const_frame> operator()(const core::const_frame& frame, core::frame_factory& frame_factory)\r
+       {\r
+               auto tag = frame.data_tag();\r
+\r
+               cache_t::const_accessor a;\r
+               \r
+               if(frame_cache_.find(a, tag))\r
+                       return std::get<1>(a->second);\r
+               \r
+               std::array<uint8_t*, 4> data = {};\r
+               for(int n = 0; n < frame.pixel_format_desc().planes.size(); ++n)\r
+                       data[n] = const_cast<uint8_t*>(frame.image_data(n).begin());\r
+\r
+               auto av_frame = ffmpeg::make_av_frame(data, frame.pixel_format_desc());\r
+\r
+               filter_.push(av_frame);\r
+\r
+               auto av_frames = filter_.poll_all();\r
+\r
+               std::vector<core::const_frame> frames;\r
+\r
+               BOOST_FOREACH(auto av_frame, av_frames)\r
+                       frames.push_back(ffmpeg::make_frame(tag, av_frame, frame.frame_rate(), frame_factory, 0));\r
+\r
+               std::weak_ptr<impl> self = shared_from_this();\r
+               auto connection = frame.on_released.connect(std::function<void()>([self, tag]() mutable\r
+               {\r
+                       auto self2 = self.lock();\r
+                       if(self2)\r
+                               self2->frame_cache_.erase(tag);\r
+               }));\r
+\r
+               frame_cache_.insert(std::make_pair(&frame, std::make_tuple(connection, frames)));\r
+\r
+               return frames;\r
+       }               \r
+};\r
+\r
+deinterlacer::deinterlacer() : impl_(new impl()){}\r
+deinterlacer::~deinterlacer(){}\r
+std::vector<core::const_frame> deinterlacer::operator()(const core::const_frame& frame, core::frame_factory& frame_factory){return (*impl_)(frame, frame_factory);}\r
+\r
+}}}*/
\ No newline at end of file
diff --git a/accelerator/cpu/image/deinterlacer.h b/accelerator/cpu/image/deinterlacer.h
new file mode 100644 (file)
index 0000000..14b8beb
--- /dev/null
@@ -0,0 +1,33 @@
+#pragma once\r
+/*\r
+#include <common/forward.h>\r
+\r
+#include <core/frame/frame.h>\r
+\r
+FORWARD2(caspar, core, class frame_factory);\r
+\r
+namespace caspar { namespace accelerator { namespace cpu {\r
+       \r
+class deinterlacer sealed \r
+{\r
+public:\r
+\r
+       // Static Members\r
+\r
+       // Constructors\r
+\r
+       deinterlacer();\r
+       ~deinterlacer();\r
+\r
+       // Methods      \r
+                       \r
+       std::vector<core::const_frame> operator()(const core::const_frame& frame, core::frame_factory& frame_factory);\r
+               \r
+       // Properties\r
+\r
+private:\r
+       struct impl;\r
+       spl::unique_ptr<impl> impl_;\r
+};\r
+\r
+}}}*/
\ No newline at end of file
index f7f69b02cd55bca41e4ea3f7b8a2728fb33bede6..2a6de6d05475652952bdd58b22aa16609a24000d 100644 (file)
@@ -266,7 +266,7 @@ private:
        }\r
 };\r
                \r
-struct image_mixer::impl : boost::noncopyable\r
+struct image_mixer::impl : public core::frame_factory\r
 {      \r
        spl::shared_ptr<device>                         ogl_;\r
        image_renderer                                          renderer_;\r
@@ -306,7 +306,7 @@ public:
                item.pix_desc   = frame.pixel_format_desc();\r
                item.field_mode = frame.field_mode();\r
                item.transform  = transform_stack_.back();\r
-\r
+               \r
                // NOTE: Once we have copied the arrays they are no longer valid for reading!!! Check for alternative solution e.g. transfer with AMD_pinned_memory.\r
                for(int n = 0; n < static_cast<int>(item.pix_desc.planes.size()); ++n)\r
                        item.textures.push_back(ogl_->copy_async(frame.image_data(n), item.pix_desc.planes[n].width, item.pix_desc.planes[n].height, item.pix_desc.planes[n].stride));\r
@@ -328,7 +328,7 @@ public:
                return renderer_(std::move(layers_), format_desc);\r
        }\r
        \r
-       virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode)\r
+       virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) override\r
        {\r
                std::vector<array<std::uint8_t>> buffers;\r
                BOOST_FOREACH(auto& plane, desc.planes)         \r
index 497fc1e137a2ae452677cd32f0f7b12242201887..b775c4f45aa1be57fdac673cefaa7207a8690ef1 100644 (file)
@@ -76,8 +76,8 @@ double mutable_frame::frame_rate() const{return impl_->frame_rate_;}
 core::field_mode mutable_frame::field_mode() const{return impl_->field_mode_;}\r
 std::size_t mutable_frame::width() const{return impl_->desc_.planes.at(0).width;}\r
 std::size_t mutable_frame::height() const{return impl_->desc_.planes.at(0).height;}                                            \r
-const void* mutable_frame::tag() const{return impl_->tag_;}    \r
-\r
+const void* mutable_frame::stream_tag()const{return impl_->tag_;}                              \r
+const void* mutable_frame::data_tag()const{return impl_.get();}        \r
 \r
 const const_frame& const_frame::empty()\r
 {\r
@@ -121,7 +121,7 @@ struct const_frame::impl : boost::noncopyable
        impl(mutable_frame&& other)\r
                : audio_data_(other.audio_data())\r
                , desc_(other.pixel_format_desc())\r
-               , tag_(other.tag())\r
+               , tag_(other.stream_tag())\r
                , id_(reinterpret_cast<int>(this))\r
                , frame_rate_(other.frame_rate())\r
                , field_mode_(other.field_mode())\r
@@ -136,27 +136,22 @@ struct const_frame::impl : boost::noncopyable
 \r
        array<const std::uint8_t> image_data(int index) const\r
        {\r
-               return tag_ != empty().tag() ? future_buffers_.at(index).get() : array<const std::uint8_t>(nullptr, 0, true, 0);\r
+               return tag_ != empty().stream_tag() ? future_buffers_.at(index).get() : array<const std::uint8_t>(nullptr, 0, true, 0);\r
        }\r
 \r
        std::size_t width() const\r
        {\r
-               return tag_ != empty().tag() ? desc_.planes.at(0).width : 0;\r
+               return tag_ != empty().stream_tag() ? desc_.planes.at(0).width : 0;\r
        }\r
 \r
        std::size_t height() const\r
        {\r
-               return tag_ != empty().tag() ? desc_.planes.at(0).height : 0;\r
+               return tag_ != empty().stream_tag() ? desc_.planes.at(0).height : 0;\r
        }\r
 \r
        std::size_t size() const\r
        {\r
-               return tag_ != empty().tag() ? desc_.planes.at(0).size : 0;\r
-       }\r
-\r
-       bool operator==(const impl& other)\r
-       {\r
-               return tag_ == other.tag_ && id_ == other.id_;\r
+               return tag_ != empty().stream_tag() ? desc_.planes.at(0).size : 0;\r
        }\r
 };\r
        \r
@@ -164,7 +159,10 @@ const_frame::const_frame(const void* tag) : impl_(new impl(tag)){}
 const_frame::const_frame(boost::shared_future<array<const std::uint8_t>> image, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
        : impl_(new impl(std::move(image), std::move(audio_buffer), tag, desc, frame_rate, field_mode)){}\r
 const_frame::const_frame(mutable_frame&& other) : impl_(new impl(std::move(other))){}\r
-const_frame::~const_frame(){}\r
+const_frame::~const_frame()\r
+{\r
+       on_released();\r
+}\r
 const_frame::const_frame(const_frame&& other) : impl_(std::move(other.impl_)){}\r
 const_frame& const_frame::operator=(const_frame&& other)\r
 {\r
@@ -177,8 +175,10 @@ const_frame& const_frame::operator=(const const_frame& other)
        impl_ = other.impl_;\r
        return *this;\r
 }\r
-bool const_frame::operator==(const const_frame& other){return *impl_ == *other.impl_;}\r
+bool const_frame::operator==(const const_frame& other){return impl_ == other.impl_;}\r
 bool const_frame::operator!=(const const_frame& other){return !(*this == other);}\r
+bool const_frame::operator<(const const_frame& other){return impl_< other.impl_;}\r
+bool const_frame::operator>(const const_frame& other){return impl_> other.impl_;}\r
 const core::pixel_format_desc& const_frame::pixel_format_desc()const{return impl_->desc_;}\r
 array<const std::uint8_t> const_frame::image_data(int index)const{return impl_->image_data(index);}\r
 const core::audio_buffer& const_frame::audio_data()const{return impl_->audio_data_;}\r
@@ -187,6 +187,7 @@ core::field_mode const_frame::field_mode()const{return impl_->field_mode_;}
 std::size_t const_frame::width()const{return impl_->width();}\r
 std::size_t const_frame::height()const{return impl_->height();}        \r
 std::size_t const_frame::size()const{return impl_->size();}                                            \r
-const void* const_frame::tag()const{return impl_->tag_;}       \r
+const void* const_frame::stream_tag()const{return impl_->tag_;}                                \r
+const void* const_frame::data_tag()const{return impl_.get();}  \r
 \r
 }}
\ No newline at end of file
index 0e09bb89ff07950033da204dcfbf945d955f592b..84607da9f11fca9704670b77fa3103b37b9faa50 100644 (file)
@@ -1,5 +1,8 @@
 #pragma once\r
 \r
+#undef BOOST_PARAMETER_MAX_ARITY\r
+#define BOOST_PARAMETER_MAX_ARITY 7\r
+\r
 #include "../video_format.h"\r
 \r
 #include <common/memory.h>\r
@@ -8,6 +11,7 @@
 \r
 #include <boost/range.hpp>\r
 #include <boost/any.hpp>\r
+#include <boost/signals2.hpp>\r
 \r
 #include <tbb/cache_aligned_allocator.h>\r
 \r
@@ -61,7 +65,8 @@ public:
        std::size_t width() const;\r
        std::size_t height() const;\r
                                                                \r
-       const void* tag() const;\r
+       const void* stream_tag() const;\r
+       const void* data_tag() const;\r
                        \r
 private:\r
        struct impl;\r
@@ -96,6 +101,8 @@ public:
        const_frame& operator=(const const_frame& other);\r
                                \r
        // Properties\r
+\r
+       boost::signals2::signal<void()> on_released;\r
                        \r
        const struct pixel_format_desc& pixel_format_desc() const;\r
 \r
@@ -109,10 +116,13 @@ public:
        std::size_t height() const;\r
        std::size_t size() const;\r
                                                                \r
-       const void* tag() const;\r
+       const void* stream_tag() const;\r
+       const void* data_tag() const;\r
 \r
        bool operator==(const const_frame& other);\r
        bool operator!=(const const_frame& other);\r
+       bool operator<(const const_frame& other);\r
+       bool operator>(const const_frame& other);\r
                        \r
 private:\r
        struct impl;\r
index 95c979fa8e9ae7c98f6f939c7bc9907436430487..b07a7fad27b93af4ff0a8f00d463102ef9f861d3 100644 (file)
@@ -84,7 +84,7 @@ public:
        void visit(const const_frame& frame)\r
        {\r
                audio_item item;\r
-               item.tag                = frame.tag();\r
+               item.tag                = frame.stream_tag();\r
                item.transform  = transform_stack_.top();\r
                item.audio_data = frame.audio_data();\r
                \r
index 4cf4e62ade9f5493ee9827dd6bc50db065174576..2f13400349c9c42b21a6c4c242ac18fd0605c1d0 100644 (file)
@@ -144,7 +144,7 @@ struct frame_muxer::impl : boost::noncopyable
                                if(video_frame->format == PIX_FMT_GRAY8 && format == CASPAR_PIX_FMT_LUMA)\r
                                        av_frame->format = format;\r
 \r
-                               video_streams_.back().push(make_frame(this, av_frame, format_desc_.fps, frame_factory_, flags));\r
+                               video_streams_.back().push(make_frame(this, av_frame, format_desc_.fps, *frame_factory_, flags));\r
                        }\r
                }\r
 \r
@@ -350,7 +350,7 @@ struct frame_muxer::impl : boost::noncopyable
                                filter_.push(frame);\r
                                auto av_frame = filter_.poll();\r
                                if(av_frame)                                                    \r
-                                       video_streams_.back().push(make_frame(this, spl::make_shared_ptr(av_frame), format_desc_.fps, frame_factory_, 0));\r
+                                       video_streams_.back().push(make_frame(this, spl::make_shared_ptr(av_frame), format_desc_.fps, *frame_factory_, 0));\r
                        }\r
                        filter_ = filter(filter_str);\r
                        CASPAR_LOG(info) << L"[frame_muxer] " << display_mode_ << L" " << print_mode(frame->width, frame->height, in_fps_, frame->interlaced_frame > 0);\r
index ae03350ec9ed01b4f97d78f37cc7531b8ee52312..f443da00e12466f0f339cae419d55865035ef881 100644 (file)
@@ -172,12 +172,12 @@ int make_alpha_format(int format)
        }\r
 }\r
 \r
-core::mutable_frame make_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags)\r
+core::mutable_frame make_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, core::frame_factory& frame_factory, int flags)\r
 {                      \r
        static tbb::concurrent_unordered_map<int, tbb::concurrent_queue<std::shared_ptr<SwsContext>>> sws_contexts_;\r
        \r
        if(decoded_frame->width < 1 || decoded_frame->height < 1)\r
-               return frame_factory->create_frame(tag, core::pixel_format_desc(core::pixel_format::invalid));\r
+               return frame_factory.create_frame(tag, core::pixel_format_desc(core::pixel_format::invalid));\r
 \r
        const auto width  = decoded_frame->width;\r
        const auto height = decoded_frame->height;\r
@@ -206,7 +206,7 @@ core::mutable_frame make_frame(const void* tag, const spl::shared_ptr<AVFrame>&
                \r
                auto target_desc = pixel_format_desc(target_pix_fmt, width, height);\r
 \r
-               auto write = frame_factory->create_frame(tag, target_desc, fps, get_mode(*decoded_frame));\r
+               auto write = frame_factory.create_frame(tag, target_desc, fps, get_mode(*decoded_frame));\r
 \r
                std::shared_ptr<SwsContext> sws_context;\r
 \r
@@ -253,7 +253,7 @@ core::mutable_frame make_frame(const void* tag, const spl::shared_ptr<AVFrame>&
        }\r
        else\r
        {\r
-               auto write = frame_factory->create_frame(tag, desc, fps, get_mode(*decoded_frame));\r
+               auto write = frame_factory.create_frame(tag, desc, fps, get_mode(*decoded_frame));\r
                \r
                for(int n = 0; n < static_cast<int>(desc.planes.size()); ++n)\r
                {\r
index b46b2610adeea42fc326cc67391dc31c22a3424b..6a338b4fd1f682f3ff1bee731cc02087c7cae54a 100644 (file)
@@ -54,8 +54,9 @@ static const int CASPAR_PIX_FMT_LUMA = 10; // Just hijack some unual pixel forma
 \r
 core::field_mode                                       get_mode(const AVFrame& frame);\r
 int                                                                    make_alpha_format(int format); // NOTE: Be careful about CASPAR_PIX_FMT_LUMA, change it to PIX_FMT_GRAY8 if you want to use the frame inside some ffmpeg function.\r
-core::mutable_frame                    make_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags);\r
+core::mutable_frame                    make_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, core::frame_factory& frame_factory, int flags);\r
 spl::shared_ptr<AVFrame>                       make_av_frame(core::mutable_frame& frame);\r
+spl::shared_ptr<AVFrame>                       make_av_frame(core::const_frame& frame);\r
 spl::shared_ptr<AVFrame>                       make_av_frame(std::array<uint8_t*, 4> data, const core::pixel_format_desc& pix_desc);\r
 \r
 core::pixel_format_desc                                pixel_format_desc(PixelFormat pix_fmt, int width, int height);\r