[FFmpeg-cvslog] avfilter/vf_mix: refactor mix function

Paul B Mahol git at videolan.org
Thu Feb 17 23:19:06 EET 2022


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Thu Feb 17 21:41:24 2022 +0100| [51b968c66e94c7ddc457a86a707db9302573ae2e] | committer: Paul B Mahol

avfilter/vf_mix: refactor mix function

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=51b968c66e94c7ddc457a86a707db9302573ae2e
---

 libavfilter/vf_mix.c | 130 ++++++++++++++++-----------------------------------
 1 file changed, 41 insertions(+), 89 deletions(-)

diff --git a/libavfilter/vf_mix.c b/libavfilter/vf_mix.c
index 693b0595d8..68f5f0598e 100644
--- a/libavfilter/vf_mix.c
+++ b/libavfilter/vf_mix.c
@@ -139,6 +139,44 @@ typedef struct ThreadData {
     AVFrame **in, *out;
 } ThreadData;
 
+#define MIX_SLICE(type, fun, clip)                                                              \
+    for (int p = 0; p < s->nb_planes; p++) {                                                    \
+        const int slice_start = (s->height[p] * jobnr) / nb_jobs;                               \
+        const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;                             \
+        const int width = s->linesize[p] / sizeof(type);                                        \
+        type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);                    \
+        ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type);                               \
+                                                                                                \
+        if (!((1 << p) & s->planes)) {                                                          \
+            av_image_copy_plane((uint8_t *)dst, out->linesize[p],                               \
+                                in[0]->data[p] + slice_start * in[0]->linesize[p],              \
+                                in[0]->linesize[p],                                             \
+                                s->linesize[p], slice_end - slice_start);                       \
+            continue;                                                                           \
+        }                                                                                       \
+                                                                                                \
+        for (int y = slice_start; y < slice_end; y++) {                                         \
+            for (int x = 0; x < width; x++) {                                                   \
+                float val = 0.f;                                                                \
+                                                                                                \
+                for (int i = 0; i < s->nb_inputs; i++) {                                        \
+                    float src = *(type *)(in[i]->data[p] + y * in[i]->linesize[p] + x * sizeof(type));\
+                                                                                                \
+                    val += src * weights[i];                                                    \
+                }                                                                               \
+                                                                                                \
+                dst[x] = clip(fun(val * s->wfactor), 0, s->max);                                \
+            }                                                                                   \
+                                                                                                \
+            dst += dst_linesize;                                                                \
+        }                                                                                       \
+    }
+
+#define CLIP8(x, min, max) av_clip_uint8(x)
+#define CLIP16(x, min, max) av_clip(x, min, max)
+#define CLIPF(x, min, max) (x)
+#define NOP(x) (x)
+
 static int mix_frames(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
 {
     MixContext *s = ctx->priv;
@@ -146,99 +184,13 @@ static int mix_frames(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
     AVFrame **in = td->in;
     AVFrame *out = td->out;
     const float *weights = s->weights;
-    int i, p, x, y;
 
     if (s->depth <= 8) {
-        for (p = 0; p < s->nb_planes; p++) {
-            const int slice_start = (s->height[p] * jobnr) / nb_jobs;
-            const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
-            uint8_t *dst = out->data[p] + slice_start * out->linesize[p];
-
-            if (!((1 << p) & s->planes)) {
-                av_image_copy_plane(dst, out->linesize[p],
-                                    in[0]->data[p] + slice_start * in[0]->linesize[p],
-                                    in[0]->linesize[p],
-                                    s->linesize[p], slice_end - slice_start);
-                continue;
-            }
-
-            for (y = slice_start; y < slice_end; y++) {
-                for (x = 0; x < s->linesize[p]; x++) {
-                    float val = 0.f;
-
-                    for (i = 0; i < s->nb_inputs; i++) {
-                        uint8_t src = in[i]->data[p][y * in[i]->linesize[p] + x];
-
-                        val += src * weights[i];
-                    }
-
-                    dst[x] = av_clip_uint8(lrintf(val * s->wfactor));
-                }
-
-                dst += out->linesize[p];
-            }
-        }
+        MIX_SLICE(uint8_t, lrintf, CLIP8)
     } else if (s->depth <= 16) {
-        for (p = 0; p < s->nb_planes; p++) {
-            const int slice_start = (s->height[p] * jobnr) / nb_jobs;
-            const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
-            uint16_t *dst = (uint16_t *)(out->data[p] + slice_start * out->linesize[p]);
-
-            if (!((1 << p) & s->planes)) {
-                av_image_copy_plane((uint8_t *)dst, out->linesize[p],
-                                    in[0]->data[p] + slice_start * in[0]->linesize[p],
-                                    in[0]->linesize[p],
-                                    s->linesize[p], slice_end - slice_start);
-                continue;
-            }
-
-            for (y = slice_start; y < slice_end; y++) {
-                for (x = 0; x < s->linesize[p] / 2; x++) {
-                    float val = 0.f;
-
-                    for (i = 0; i < s->nb_inputs; i++) {
-                        uint16_t src = AV_RN16(in[i]->data[p] + y * in[i]->linesize[p] + x * 2);
-
-                        val += src * weights[i];
-                    }
-
-                    dst[x] = av_clip(lrintf(val * s->wfactor), 0, s->max);
-                }
-
-                dst += out->linesize[p] / 2;
-            }
-        }
+        MIX_SLICE(uint16_t, lrintf, CLIP16)
     } else {
-        for (p = 0; p < s->nb_planes; p++) {
-            const int slice_start = (s->height[p] * jobnr) / nb_jobs;
-            const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
-            float *dst = (float *)(out->data[p] + slice_start * out->linesize[p]);
-            ptrdiff_t dst_linesize = out->linesize[p] / 4;
-
-            if (!((1 << p) & s->planes)) {
-                av_image_copy_plane((uint8_t *)dst, out->linesize[p],
-                                    in[0]->data[p] + slice_start * in[0]->linesize[p],
-                                    in[0]->linesize[p],
-                                    s->linesize[p], slice_end - slice_start);
-                continue;
-            }
-
-            for (y = slice_start; y < slice_end; y++) {
-                for (x = 0; x < s->linesize[p] / 2; x++) {
-                    float val = 0.f;
-
-                    for (i = 0; i < s->nb_inputs; i++) {
-                        float src = *(float *)(in[i]->data[p] + y * in[i]->linesize[p] + x * 4);
-
-                        val += src * weights[i];
-                    }
-
-                    dst[x] = val * s->wfactor;
-                }
-
-                dst += dst_linesize;
-            }
-        }
+        MIX_SLICE(float, NOP, CLIPF)
     }
 
     return 0;



More information about the ffmpeg-cvslog mailing list