]> git.sesse.net Git - casparcg/blobdiff - modules/ffmpeg/producer/filter/parallel_yadif.cpp
2.0. parallel_yadif: Reduced overhead.
[casparcg] / modules / ffmpeg / producer / filter / parallel_yadif.cpp
index 919528ca0448907bba4c76f9d74bab43cbba64e9..237cf0f515589cff39daa731f50cc00779d45b4a 100644 (file)
@@ -51,8 +51,9 @@ struct parallel_yadif_context
                int mode;\r
        };\r
 \r
-       arg     args[64];\r
+       arg     args[1080];\r
        int     index;\r
+       int last_index;\r
 \r
        parallel_yadif_context() : index(0){}\r
 };\r
@@ -64,7 +65,7 @@ void parallel_yadif_filter_line(parallel_yadif_context& ctx, uint8_t *dst, uint8
        parallel_yadif_context::arg arg = {dst, prev, cur, next, w, prefs, mrefs, parity, mode};\r
        ctx.args[ctx.index++] = arg;\r
        \r
-       if(ctx.index == 64)\r
+       if(ctx.index == ctx.last_index)\r
        {               \r
                tbb::parallel_for(tbb::blocked_range<size_t>(0, ctx.index), [=](const tbb::blocked_range<size_t>& r)\r
                {\r
@@ -75,13 +76,17 @@ void parallel_yadif_filter_line(parallel_yadif_context& ctx, uint8_t *dst, uint8
        }\r
 }\r
 \r
+namespace caspar {\r
+       \r
+tbb::concurrent_bounded_queue<decltype(org_yadif_filter_line)> parallel_line_func_pool;\r
+std::array<parallel_yadif_context, 18> ctxs;\r
+\r
 #define RENAME(a) f ## a\r
 \r
 #define ff(x) \\r
 void RENAME(x)(uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int prefs, int mrefs, int parity, int mode) \\r
 {\\r
-       static parallel_yadif_context ctx;\\r
-       parallel_yadif_filter_line(ctx, dst, prev, cur, next, w, prefs, mrefs, parity, mode);\\r
+       parallel_yadif_filter_line(ctxs[x], dst, prev, cur, next, w, prefs, mrefs, parity, mode);\\r
 }\r
 \r
 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
@@ -89,9 +94,6 @@ ff(0); ff(1); ff(2); ff(3); ff(4); ff(5); ff(6); ff(7); ff(8); ff(9); ff(10); ff
 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
 {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<decltype(org_yadif_filter_line)> parallel_line_func_pool;\r
 \r
 void init_pool()\r
 {\r
@@ -105,11 +107,8 @@ void return_parallel_yadif(void* func)
                parallel_line_func_pool.push(reinterpret_cast<decltype(fs[0])>(func));\r
 }\r
 \r
-std::shared_ptr<void> make_parallel_yadif(AVFilterContext* ctx, size_t height)\r
+std::shared_ptr<void> make_parallel_yadif(AVFilterContext* ctx)\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
@@ -120,8 +119,15 @@ std::shared_ptr<void> make_parallel_yadif(AVFilterContext* ctx, size_t height)
        if(!parallel_line_func_pool.try_pop(func))      \r
                CASPAR_LOG(warning) << "Not enough scalable-yadif context instances. Running non-scalable";\r
        else\r
+       {\r
+               int index = 0;\r
+               while(index < sizeof(fs)/sizeof(fs[0]) && fs[index] != func)\r
+                       ++index;\r
+\r
+               ctxs[index].last_index = ctx->inputs[0]->h;\r
                yadif->filter_line = func;\r
-       \r
+       }\r
+\r
        return std::shared_ptr<void>(func, return_parallel_yadif);\r
 }\r
 \r