[FFmpeg-cvslog] avfilter/vf_colorchannelmixer: add float formats support

Paul B Mahol git at videolan.org
Thu Mar 3 10:57:37 EET 2022


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed Mar  2 16:59:18 2022 +0100| [59520f068da89006d527f044a6560235260bcc6c] | committer: Paul B Mahol

avfilter/vf_colorchannelmixer: add float formats support

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

 libavfilter/colorchannelmixer_template.c | 68 +++++++++++++++++++++++++++-----
 libavfilter/vf_colorchannelmixer.c       | 33 ++++++++++++++++
 2 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/libavfilter/colorchannelmixer_template.c b/libavfilter/colorchannelmixer_template.c
index 0f15f8fd07..bef57476aa 100644
--- a/libavfilter/colorchannelmixer_template.c
+++ b/libavfilter/colorchannelmixer_template.c
@@ -21,10 +21,21 @@
 #include <float.h>
 
 #undef pixel
+#undef cpixel
+#undef ROUND
 #if DEPTH == 8
 #define pixel uint8_t
+#define cpixel int
+#define ROUND lrintf
 #elif DEPTH == 16
 #define pixel uint16_t
+#define cpixel int
+#define ROUND lrintf
+#else
+#define NOP(x) (x)
+#define pixel float
+#define cpixel float
+#define ROUND NOP
 #endif
 
 #undef fn
@@ -60,8 +71,22 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v
             const pixel gin = srcg[j];
             const pixel bin = srcb[j];
             const pixel ain = have_alpha ? srca[j] : 0;
-            int rout, gout, bout;
-
+            cpixel rout, gout, bout;
+
+#if DEPTH == 32
+            rout = s->rr * rin +
+                   s->rg * gin +
+                   s->rb * bin +
+                   (have_alpha == 1 ? s->ra * ain : 0);
+            gout = s->gr * rin +
+                   s->gg * gin +
+                   s->gb * bin +
+                   (have_alpha == 1 ? s->ga * ain : 0);
+            bout = s->br * rin +
+                   s->bg * gin +
+                   s->bb * bin +
+                   (have_alpha == 1 ? s->ba * ain : 0);
+#else
             rout = s->lut[R][R][rin] +
                    s->lut[R][G][gin] +
                    s->lut[R][B][bin] +
@@ -74,31 +99,52 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v
                    s->lut[B][G][gin] +
                    s->lut[B][B][bin] +
                    (have_alpha == 1 ? s->lut[B][A][ain] : 0);
+#endif
 
             if (pc) {
-                float frout = av_clipf(rout, 0.f, max);
-                float fgout = av_clipf(gout, 0.f, max);
-                float fbout = av_clipf(bout, 0.f, max);
-                float lin, lout;
+                float frout, fgout, fbout, lin, lout;
+
+#if DEPTH < 32
+                frout = av_clipf(rout, 0.f, max);
+                fgout = av_clipf(gout, 0.f, max);
+                fbout = av_clipf(bout, 0.f, max);
+#else
+                frout = rout;
+                fgout = gout;
+                fbout = bout;
+#endif
 
                 preserve_color(s->preserve_color, rin, gin, bin,
                                rout, gout, bout, max, &lin, &lout);
                 preservel(&frout, &fgout, &fbout, lin, lout, max);
 
-                rout = lrintf(lerpf(rout, frout, pa));
-                gout = lrintf(lerpf(gout, fgout, pa));
-                bout = lrintf(lerpf(bout, fbout, pa));
+                rout = ROUND(lerpf(rout, frout, pa));
+                gout = ROUND(lerpf(gout, fgout, pa));
+                bout = ROUND(lerpf(bout, fbout, pa));
             }
 
+#if DEPTH < 32
             dstr[j] = av_clip_uintp2(rout, depth);
             dstg[j] = av_clip_uintp2(gout, depth);
             dstb[j] = av_clip_uintp2(bout, depth);
+#else
+            dstr[j] = rout;
+            dstg[j] = gout;
+            dstb[j] = bout;
+#endif
 
             if (have_alpha == 1) {
+#if DEPTH < 32
                 dsta[j] = av_clip_uintp2(s->lut[A][R][rin] +
                                          s->lut[A][G][gin] +
                                          s->lut[A][B][bin] +
                                          s->lut[A][A][ain], depth);
+#else
+                dsta[j] = s->ar * rin +
+                          s->ag * gin +
+                          s->ab * bin +
+                          s->aa * ain;
+#endif
             }
         }
 
@@ -115,6 +161,8 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v
     return 0;
 }
 
+#if DEPTH < 32
+
 static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs,
                                                          int have_alpha, int step, int pc, int depth)
 {
@@ -191,3 +239,5 @@ static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, v
 
     return 0;
 }
+
+#endif
diff --git a/libavfilter/vf_colorchannelmixer.c b/libavfilter/vf_colorchannelmixer.c
index b32e0a9d0e..88dd7451dc 100644
--- a/libavfilter/vf_colorchannelmixer.c
+++ b/libavfilter/vf_colorchannelmixer.c
@@ -77,6 +77,10 @@ static void preservel(float *r, float *g, float *b, float lin, float lout, float
 #define DEPTH 16
 #include "colorchannelmixer_template.c"
 
+#undef DEPTH
+#define DEPTH 32
+#include "colorchannelmixer_template.c"
+
 #define OFFSET(x) offsetof(ColorChannelMixerContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
 
@@ -125,6 +129,7 @@ static const enum AVPixelFormat pix_fmts[] = {
     AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
     AV_PIX_FMT_GBRP14,
     AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16,
+    AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32,
     AV_PIX_FMT_NONE
 };
 
@@ -278,6 +283,26 @@ static int filter_slice_rgb0_pl(AVFilterContext *ctx, void *arg, int jobnr, int
     return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, -1, 4, 1, 8);
 }
 
+static int filter_slice_gbrp32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 0, 1, 0);
+}
+
+static int filter_slice_gbrap32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 1, 1, 0);
+}
+
+static int filter_slice_gbrp32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 0, 1, 1);
+}
+
+static int filter_slice_gbrap32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 1, 1, 1);
+}
+
 static int config_output(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -391,6 +416,14 @@ static int config_output(AVFilterLink *outlink)
         s->filter_slice[0] = filter_slice_gbrap16;
         s->filter_slice[1] = filter_slice_gbrap16_pl;
         break;
+    case AV_PIX_FMT_GBRPF32:
+        s->filter_slice[0] = filter_slice_gbrp32;
+        s->filter_slice[1] = filter_slice_gbrp32_pl;
+        break;
+    case AV_PIX_FMT_GBRAPF32:
+        s->filter_slice[0] = filter_slice_gbrap32;
+        s->filter_slice[1] = filter_slice_gbrap32_pl;
+        break;
     }
 
     return 0;



More information about the ffmpeg-cvslog mailing list