]> 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>
Mon, 13 Dec 2010 00:51:43 +0000 (00:51 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 13 Dec 2010 00:51:43 +0000 (00:51 +0000)
16 files changed:
common/common.vcxproj
common/common.vcxproj.filters
common/utility/singleton_pool.h [new file with mode: 0644]
core/core.vcxproj
core/core.vcxproj.filters
core/format/pixel_format.cpp [deleted file]
core/format/pixel_format.h
core/processor/composite_frame.cpp
core/processor/draw_frame.h
core/processor/frame_processor_device.cpp
core/processor/frame_renderer.cpp
core/processor/read_frame.cpp
core/processor/transform_frame.cpp
core/processor/transform_frame.h
core/processor/write_frame.cpp
core/producer/ffmpeg/video/video_transformer.cpp

index 061afd3eadb8c8d1a1e9dae70f49669c3dd5267b..3e2469f85255f0b57dac3f68593552ebd1ed58d1 100644 (file)
     <ClInclude Include="log\log.h" />\r
     <ClInclude Include="stdafx.h" />\r
     <ClInclude Include="utility\scope_exit.h" />\r
+    <ClInclude Include="utility\singleton_pool.h" />\r
     <ClInclude Include="utility\string_convert.h" />\r
   </ItemGroup>\r
   <ItemGroup>\r
index ed7ee1db9e55afed553a359edc560f407bc5e627..1bdedcdb9825ce252ff3a12a043a6e84ef5773b6 100644 (file)
     <ClInclude Include="gl\shader_program.h">\r
       <Filter>Source\gl</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="utility\singleton_pool.h">\r
+      <Filter>Source\utility</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
diff --git a/common/utility/singleton_pool.h b/common/utility/singleton_pool.h
new file mode 100644 (file)
index 0000000..b99eea9
--- /dev/null
@@ -0,0 +1,81 @@
+#pragma once\r
+          \r
+#include <tbb/concurrent_queue.h>\r
+#include <tbb/scalable_allocator.h>\r
+\r
+namespace caspar { namespace common {\r
+\r
+template <typename T>\r
+class singleton_pool\r
+{\r
+public:\r
+       \r
+       static T* allocate()\r
+       {\r
+               T* ptr;\r
+               if(!get_pool().try_pop(ptr))\r
+                       ptr = static_cast<T*>(scalable_malloc(sizeof(T)));\r
+               return ptr;\r
+       }\r
+       \r
+       static void deallocate(T* ptr)\r
+       {\r
+               if(!get_pool().try_push(ptr))\r
+                       scalable_free(ptr);\r
+       }\r
+\r
+       static void destroy(T* ptr)\r
+       {\r
+               ptr->~T();\r
+               deallocate(ptr);\r
+       }\r
+\r
+       static std::shared_ptr<T> make_shared()\r
+       {\r
+               return std::shared_ptr<T>(new(allocate()) T(), destroy);\r
+       }\r
+       \r
+       template<typename P0>\r
+       static std::shared_ptr<T> make_shared(P0 p0)\r
+       {\r
+               return std::shared_ptr<T>(new(allocate()) T(std::forward<P0>(p0)), destroy);\r
+       }\r
+       \r
+       template<typename P0, typename P1>\r
+       static std::shared_ptr<T> make_shared(P0 p0, P1 p1)\r
+       {\r
+               return std::shared_ptr<T>(new(allocate()) T(std::forward<P0>(p0), std::forward<P1>(p1)), destroy);\r
+       }\r
+       \r
+       template<typename P0, typename P1, typename P2>\r
+       static std::shared_ptr<T> make_shared(P0 p0, P1 p1, P2 p2)\r
+       {\r
+               return std::shared_ptr<T>(new(allocate()) T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)), destroy);\r
+       }\r
+       \r
+       template<typename P0, typename P1, typename P2, typename P3>\r
+       static std::shared_ptr<T> make_shared(P0 p0, P1 p1, P2 p2, P3 p3)\r
+       {\r
+               return std::shared_ptr<T>(new(allocate()) T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3)), destroy);\r
+       }\r
+\r
+private:\r
+       struct pool\r
+       {\r
+               ~pool()\r
+               {\r
+                       T* ptr;\r
+                       while(value.try_pop(ptr))\r
+                               scalable_free(ptr);\r
+               }\r
+               tbb::concurrent_bounded_queue<T*> value;\r
+       };\r
+\r
+       static tbb::concurrent_bounded_queue<T*>& get_pool()\r
+       {\r
+               static pool global_pool;\r
+               return global_pool.value;\r
+       }\r
+};\r
+\r
+}}
\ No newline at end of file
index 0d3268d6aeccc09d178a37780b32d714001bb1a4..f2041712bf5b8306a802bcaa02c4241fe6314472 100644 (file)
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
-    <ClCompile Include="format\pixel_format.cpp">\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
-    </ClCompile>\r
     <ClCompile Include="format\video_format.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
index 60fafcd8d9f362c6d06866b353abf06519c9108d..eb584b0940c5a65e6afeb770fbc5169f5eec06be 100644 (file)
     <ClCompile Include="channel.cpp">\r
       <Filter>Source\channel</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="format\pixel_format.cpp">\r
-      <Filter>Source\channel\format</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="consumer\decklink\decklink_consumer.cpp">\r
       <Filter>Source\channel\consumer\decklink</Filter>\r
     </ClCompile>\r
diff --git a/core/format/pixel_format.cpp b/core/format/pixel_format.cpp
deleted file mode 100644 (file)
index 10d802f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "..\StdAfx.h"\r
-\r
-#include "pixel_format.h"\r
-\r
-namespace caspar { namespace core {\r
-       \r
-size_t hash(const pixel_format_desc& desc)\r
-{\r
-       size_t hash = 0;\r
-       switch(desc.pix_fmt)\r
-       {\r
-       case pixel_format::ycbcr:\r
-       case pixel_format::ycbcra:\r
-               //  0-10 (11) width\r
-               // 11-21 (11) height\r
-               // 22-24 (3)  x-ratio\r
-               // 25-27 (3)  y-ratio\r
-               // 28-29 (2)  unused\r
-               // 30    (1)  alpha\r
-               // 31    (1)  yuv = true => 1\r
-               hash |= ( desc.planes[0].width                                                  & 0x7FF ) << 0;\r
-               hash |= ( desc.planes[0].height                                                 & 0x7FF ) << 11;\r
-               hash |= ((desc.planes[0].height/desc.planes[1].height)  & 0x7   ) << 22;\r
-               hash |= ((desc.planes[0].width/desc.planes[1].width)    & 0x7   ) << 25;\r
-               hash |= desc.pix_fmt == pixel_format::ycbcra ? (1 << 30) : 0;\r
-               hash |= 1 << 31;\r
-               return hash;\r
-       case pixel_format::bgra:\r
-       case pixel_format::rgba:\r
-       case pixel_format::argb:\r
-       case pixel_format::abgr:\r
-               \r
-               //0-10  (11) height\r
-               //11-21 (11) width\r
-               //22-29 (8)  unused\r
-               //30    (1)  alpha\r
-               //31    (1)  yuv = false => 0\r
-               hash |= (desc.planes[0].height & 0xFFFF) << 0;\r
-               hash |= (desc.planes[0].width  & 0xFFFF) << 15;\r
-               hash |= 1 << 30;\r
-               return hash;\r
-\r
-       default:\r
-               return hash;\r
-       };\r
-}\r
-       \r
-}}\r
index a6037b56ed4d5985d184148cf32374cd3b5e315e..41a3129c6b8556645b040d7fff222cccd5f03714 100644 (file)
@@ -40,26 +40,5 @@ struct pixel_format_desc
        pixel_format::type pix_fmt;\r
        std::vector<plane> planes;\r
 };\r
-\r
-size_t hash(const pixel_format_desc& desc);\r
-       \r
-inline bool operator==(const pixel_format_desc& lhs, const pixel_format_desc& rhs)\r
-{\r
-       return hash(lhs) == hash(rhs);\r
-}\r
-\r
-inline bool operator!=(const pixel_format_desc& lhs, const pixel_format_desc& rhs)\r
-{\r
-       return !(lhs == rhs);\r
-}\r
        \r
-}}\r
-\r
-namespace std {\r
-\r
-template<> struct hash<caspar::core::pixel_format_desc>\r
-{\r
-       size_t operator()(const caspar::core::pixel_format_desc& desc) const { return caspar::core::hash(desc);}\r
-};\r
-\r
-}
\ No newline at end of file
+}}
\ No newline at end of file
index 60918a4a40fa67266b50f78340ca3b6b9ebe4a5c..3f0f46ef85289200452966797208cf0f0768b556 100644 (file)
@@ -3,13 +3,10 @@
 #include "draw_frame.h"\r
 #include "composite_frame.h"\r
 #include "transform_frame.h"\r
-#include "../../common/gl/utility.h"\r
+#include "frame_shader.h"\r
+#include "../../common/utility/singleton_pool.h"\r
 \r
 #include <boost/range/algorithm.hpp>\r
-#include <boost/range/algorithm_ext/erase.hpp>\r
-\r
-#include <algorithm>\r
-#include <numeric>\r
 \r
 #include <tbb/parallel_for.h>\r
 \r
@@ -17,19 +14,24 @@ namespace caspar { namespace core {
        \r
 struct composite_frame::implementation\r
 {      \r
-       implementation(std::vector<draw_frame>&& frames) : frames_(std::move(frames)), audio_data_(1920*2, 0)\r
+       implementation(std::vector<draw_frame>&& frames) : frames_(std::move(frames))\r
        {               \r
                boost::range::for_each(frames_, [&](const draw_frame& frame)\r
                {\r
-                       tbb::parallel_for\r
-                       (\r
-                               tbb::blocked_range<size_t>(0, frame.audio_data().size()),\r
-                               [&](const tbb::blocked_range<size_t>& r)\r
-                               {\r
-                                       for(size_t n = r.begin(); n < r.end(); ++n)                                     \r
-                                               audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n]) + static_cast<int>(frame.audio_data()[n])) & 0xFFFF);                                             \r
-                               }\r
-                       );\r
+                       if(audio_data_.empty())\r
+                               audio_data_ = frame.audio_data();\r
+                       else\r
+                       {\r
+                               tbb::parallel_for\r
+                               (\r
+                                       tbb::blocked_range<size_t>(0, frame.audio_data().size()),\r
+                                       [&](const tbb::blocked_range<size_t>& r)\r
+                                       {\r
+                                               for(size_t n = r.begin(); n < r.end(); ++n)                                     \r
+                                                       audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n]) + static_cast<int>(frame.audio_data()[n])) & 0xFFFF);                                             \r
+                                       }\r
+                               );\r
+                       }\r
                });\r
        }\r
        \r
@@ -48,13 +50,13 @@ struct composite_frame::implementation
                boost::range::for_each(frames_, std::bind(&detail::draw_frame_access::draw, std::placeholders::_1, std::ref(shader)));\r
        }\r
                                \r
-       std::vector<draw_frame> frames_;\r
        std::vector<short> audio_data_;\r
+       std::vector<draw_frame> frames_;\r
 };\r
 \r
-composite_frame::composite_frame(std::vector<draw_frame>&& frames) : impl_(new implementation(std::move(frames))){}\r
+composite_frame::composite_frame(std::vector<draw_frame>&& frames) : impl_(common::singleton_pool<implementation>::make_shared(std::move(frames))){}\r
 composite_frame::composite_frame(composite_frame&& other) : impl_(std::move(other.impl_)){}\r
-composite_frame::composite_frame(const composite_frame& other) : impl_(new implementation(*other.impl_)){}\r
+composite_frame::composite_frame(const composite_frame& other) : impl_(common::singleton_pool<implementation>::make_shared(*other.impl_)){}\r
 composite_frame& composite_frame::operator=(const composite_frame& other)\r
 {\r
        composite_frame temp(other);\r
index 9881bbbf6a7410e9a4f79d8d59e58f8d6ec9c88d..65b0c73adf37d22851c89c47b4c805ccaba3c5ed 100644 (file)
@@ -51,7 +51,7 @@ public:
 \r
        template<typename T>\r
        draw_frame(T&& impl, typename std::enable_if<std::is_base_of<detail::draw_frame_impl, typename std::remove_reference<T>::type>::value, void>::type* dummy = nullptr)\r
-               : impl_(std::make_shared<T>(std::forward<T>(impl))), tag_(normal_tag){}\r
+               : impl_(std::make_shared<T>(std::forward<T>(impl))), tag_(normal_tag){dummy;}\r
 \r
        draw_frame(eof_frame&&) : tag_(eof_tag){}\r
        draw_frame(empty_frame&&) : tag_(empty_tag){}\r
index 90dd5d9d97a78d1c7f5d74fd5142901db16e52b0..6d9c50c2e3699daf472414fb8f32847c4fc9bbb1 100644 (file)
@@ -109,7 +109,14 @@ struct frame_processor_device::implementation : boost::noncopyable
                static GLenum mapping[] = {GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA};\r
                auto pooled_pbo = std::make_shared<pbo>(plane.width, plane.height, mapping[plane.channels-1]);\r
                pooled_pbo->end_write();\r
-               return pbo_ptr(pooled_pbo.get(), [=](pbo*){pool->push(pooled_pbo);});\r
+               return pbo_ptr(pooled_pbo.get(), [=](pbo*)\r
+               {\r
+                       executor_.begin_invoke([=]\r
+                       {\r
+                               pooled_pbo->end_write();\r
+                               pool->push(pooled_pbo);\r
+                       });\r
+               });\r
        }\r
                                \r
        common::executor executor_;     \r
index 4d84852a23b03cf84c8af7213c2a7f6ded89d31a..e06cd84e08f1002f275630198e5431b0f866ab27 100644 (file)
@@ -48,7 +48,6 @@ struct frame_renderer::implementation : boost::noncopyable
                reading_frame result;\r
                try\r
                {\r
-                       detail::draw_frame_access::end_write(drawing_); // Map data pointer before returning to pool.\r
                        drawing_ = writing_;\r
                        writing_ = frame;\r
                                                \r
@@ -61,7 +60,7 @@ struct frame_renderer::implementation : boost::noncopyable
                                                \r
                        detail::draw_frame_access::draw(drawing_, shader_);\r
                                \r
-                       reading_ = create_reading(drawing_.audio_data());                       \r
+                       reading_ = create_reading(std::vector<short>(drawing_.audio_data().begin(), drawing_.audio_data().end()));                      \r
                        reading_.first->begin_read();\r
                                                \r
                        drawing_ = draw_frame::empty();\r
index 05f19d60c653bc3eb0584739c0969bc7b78eb878..6da482def2632003ac8099bbe0709db635daa664 100644 (file)
@@ -4,6 +4,7 @@
 #include "../format/pixel_format.h"\r
 #include "../../common/gl/utility.h"\r
 #include "../../common/gl/pixel_buffer_object.h"\r
+#include "../../common/utility/singleton_pool.h"\r
 \r
 #include <boost/range/algorithm.hpp>\r
 \r
@@ -16,7 +17,7 @@ struct read_frame::implementation : boost::noncopyable
        std::vector<short> audio_data_;\r
 };\r
        \r
-read_frame::read_frame(common::gl::pbo_ptr&& pbo, std::vector<short>&& audio_data) : impl_(new implementation(std::move(pbo), std::move(audio_data))){}\r
+read_frame::read_frame(common::gl::pbo_ptr&& pbo, std::vector<short>&& audio_data) : impl_(common::singleton_pool<implementation>::make_shared(std::move(pbo), std::move(audio_data))){}\r
 const boost::iterator_range<const unsigned char*> read_frame::pixel_data() const\r
 {\r
        if(!impl_->pbo_ || !impl_->pbo_->data())\r
index 86fa08405569d762679cab1b970042a696630aa8..78ab4460ad7994ebaa893225edff737b1354e99e 100644 (file)
@@ -8,6 +8,7 @@
 #include "../format/pixel_format.h"\r
 #include "../../common/gl/utility.h"\r
 #include "../../common/gl/pixel_buffer_object.h"\r
+#include "../../common/utility/singleton_pool.h"\r
 \r
 #include <boost/range/algorithm.hpp>\r
 \r
@@ -18,7 +19,7 @@ namespace caspar { namespace core {
 struct transform_frame::implementation\r
 {\r
        implementation(const draw_frame& frame) : frame_(frame), audio_volume_(255), override_audio_(false){}\r
-       implementation(const draw_frame& frame, const std::vector<short>& audio_data) : frame_(frame), audio_volume_(255), audio_data_(audio_data), override_audio_(true){}\r
+       implementation(const draw_frame& frame, std::vector<short>&& audio_data) : frame_(frame), audio_volume_(255), audio_data_(std::move(audio_data)), override_audio_(true){}\r
        implementation(draw_frame&& frame) : frame_(std::move(frame)), audio_volume_(255), override_audio_(false){}\r
        \r
        void begin_write(){detail::draw_frame_access::begin_write(frame_);}\r
@@ -51,16 +52,16 @@ struct transform_frame::implementation
        }\r
                \r
        bool override_audio_;\r
-       std::vector<short> audio_data_;\r
-       shader_transform transform_;    \r
        unsigned char audio_volume_;\r
        draw_frame frame_;\r
+       std::vector<short> audio_data_;\r
+       shader_transform transform_;    \r
 };\r
        \r
-transform_frame::transform_frame(const draw_frame& frame) : impl_(new implementation(frame)){}\r
-transform_frame::transform_frame(const draw_frame& frame, const std::vector<short>& audio_data) : impl_(new implementation(frame, audio_data)){}\r
-transform_frame::transform_frame(draw_frame&& frame) : impl_(new implementation(std::move(frame))){}\r
-transform_frame::transform_frame(const transform_frame& other) : impl_(new implementation(*other.impl_)){}\r
+transform_frame::transform_frame(const draw_frame& frame) : impl_(common::singleton_pool<implementation>::make_shared(frame)){}\r
+transform_frame::transform_frame(const draw_frame& frame, std::vector<short>&& audio_data) : impl_(common::singleton_pool<implementation>::make_shared(frame, std::move(audio_data))){}\r
+transform_frame::transform_frame(draw_frame&& frame) : impl_(common::singleton_pool<implementation>::make_shared(std::move(frame))){}\r
+transform_frame::transform_frame(const transform_frame& other) : impl_(common::singleton_pool<implementation>::make_shared(*other.impl_)){}\r
 transform_frame& transform_frame::operator=(const transform_frame& other)\r
 {\r
        transform_frame temp(other);\r
index 464bfd408ffa060439733b3d8d0942fa71dd23b6..b74786426b4f3dcea15b1dc2653e6768c524b3d0 100644 (file)
@@ -20,7 +20,7 @@ class transform_frame : public detail::draw_frame_impl
 {\r
 public:\r
        transform_frame(const draw_frame& frame);\r
-       transform_frame(const draw_frame& frame, const std::vector<short>& audio_data);\r
+       transform_frame(const draw_frame& frame, std::vector<short>&& audio_data);\r
        transform_frame(draw_frame&& frame);\r
        \r
        transform_frame(const transform_frame& other);\r
index 3dfcfe532165ba9b883eecd6df4382e57ebed0b3..37db29a42baba452df48f43d7ed9e9e2675269db 100644 (file)
@@ -8,6 +8,7 @@
 #include "../format/pixel_format.h"\r
 #include "../../common/gl/utility.h"\r
 #include "../../common/gl/pixel_buffer_object.h"\r
+#include "../../common/utility/singleton_pool.h"\r
 \r
 #include <boost/range/algorithm.hpp>\r
 \r
@@ -53,7 +54,7 @@ struct write_frame::implementation : boost::noncopyable
        const pixel_format_desc desc_;\r
 };\r
        \r
-write_frame::write_frame(std::vector<common::gl::pbo_ptr>&& pbos, const pixel_format_desc& desc) : impl_(new implementation(std::move(pbos), desc)){}\r
+write_frame::write_frame(std::vector<common::gl::pbo_ptr>&& pbos, const pixel_format_desc& desc) : impl_(common::singleton_pool<implementation>::make_shared(std::move(pbos), desc)){}\r
 write_frame::write_frame(write_frame&& other) : impl_(std::move(other.impl_)){}\r
 write_frame& write_frame::operator=(write_frame&& other)\r
 {\r
index 9e198ed513537d925dacafe1e35096ce0c11544f..1b080f653e02485bbc69e8262ca1cb451c6d68bd 100644 (file)
@@ -108,7 +108,7 @@ struct video_transformer::implementation : boost::noncopyable
        draw_frame execute(const std::shared_ptr<AVFrame>& decoded_frame)\r
        {                               \r
                if(decoded_frame == nullptr)\r
-                       return draw_frame::eof(); // TODO\r
+                       return draw_frame::eof();\r
                                \r
                if(sws_context_ == nullptr)\r
                {\r