]> git.sesse.net Git - casparcg/blobdiff - modules/ffmpeg/producer/filter/parallel_yadif.cpp
2.0. parallel_yadif: Disable for % 64 != 0.
[casparcg] / modules / ffmpeg / producer / filter / parallel_yadif.cpp
index 4b2483ba95bd06bd5a70c3d3281c8dea9c568cc9..919528ca0448907bba4c76f9d74bab43cbba64e9 100644 (file)
@@ -2,10 +2,22 @@
 \r
 #include "parallel_yadif.h"\r
 \r
+#include <common/log/log.h>\r
+\r
+#if defined(_MSC_VER)\r
+#pragma warning (push)\r
+#pragma warning (disable : 4244)\r
+#endif\r
 extern "C" \r
 {\r
        #include <libavfilter/avfilter.h>\r
 }\r
+#if defined(_MSC_VER)\r
+#pragma warning (pop)\r
+#endif\r
+\r
+#include <tbb/parallel_for.h>\r
+#include <tbb/concurrent_queue.h>\r
 \r
 #include <boost/thread/once.hpp>\r
 \r
@@ -75,42 +87,42 @@ void RENAME(x)(uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w,
 ff(0); ff(1); ff(2); ff(3); ff(4); ff(5); ff(6); ff(7); ff(8); ff(9); ff(10); ff(11); ff(12); ff(13); ff(14); ff(15); ff(16); ff(17);\r
 \r
 void (*fs[])(uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int prefs, int mrefs, int parity, int mode) = \r
-\r
 {f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17};\r
 \r
 namespace caspar {\r
        \r
-tbb::concurrent_bounded_queue<int> tags;\r
+tbb::concurrent_bounded_queue<decltype(org_yadif_filter_line)> parallel_line_func_pool;\r
 \r
 void init_pool()\r
 {\r
-       for(int n = 0; n < 18; ++n)\r
-               tags.push(n);\r
+       for(int n = 0; n < sizeof(fs)/sizeof(fs[0]); ++n)\r
+               parallel_line_func_pool.push(fs[n]);\r
+}\r
+\r
+void return_parallel_yadif(void* func)\r
+{\r
+       if(func != nullptr)\r
+               parallel_line_func_pool.push(reinterpret_cast<decltype(fs[0])>(func));\r
 }\r
 \r
-int init(AVFilterContext* ctx)\r
+std::shared_ptr<void> make_parallel_yadif(AVFilterContext* ctx, size_t height)\r
 {\r
+       if(height % 64 != 0)\r
+               return std::shared_ptr<void>(nullptr, return_parallel_yadif);\r
+\r
        static boost::once_flag flag = BOOST_ONCE_INIT;\r
        boost::call_once(&init_pool, flag);\r
 \r
        YADIFContext* yadif = (YADIFContext*)ctx->priv;\r
        org_yadif_filter_line = yadif->filter_line; // Data race is not a problem.\r
-\r
-       int tag;\r
-       if(!tags.try_pop(tag))\r
-       {\r
-               CASPAR_LOG(warning) << "Not enough scalable-yadif instances. Running non-scalable";\r
-               return -1;\r
-       }\r
-\r
-       yadif->filter_line = fs[tag];\r
-       return tag;\r
-}\r
-\r
-void uninit(int tag)\r
-{\r
-       if(tag != -1)\r
-               tags.push(tag);\r
+       \r
+       decltype(org_yadif_filter_line) func = nullptr;\r
+       if(!parallel_line_func_pool.try_pop(func))      \r
+               CASPAR_LOG(warning) << "Not enough scalable-yadif context instances. Running non-scalable";\r
+       else\r
+               yadif->filter_line = func;\r
+       \r
+       return std::shared_ptr<void>(func, return_parallel_yadif);\r
 }\r
 \r
 }
\ No newline at end of file