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

Paul B Mahol git at videolan.org
Thu Mar 3 18:42:42 EET 2022


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Thu Mar  3 13:14:47 2022 +0100| [d607af50fde4f8f83ebdfe494650351e8f6d021c] | committer: Paul B Mahol

avfilter/vf_geq: add float formats support

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

 libavfilter/vf_geq.c | 57 +++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 48 insertions(+), 9 deletions(-)

diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
index eef1ac0958..fd9e0fd80b 100644
--- a/libavfilter/vf_geq.c
+++ b/libavfilter/vf_geq.c
@@ -52,6 +52,7 @@ typedef struct GEQContext {
     AVFrame *picref;            ///< current input buffer
     uint8_t *dst;               ///< reference pointer to the 8bits output
     uint16_t *dst16;            ///< reference pointer to the 16bits output
+    float *dst32;               ///< reference pointer to the 32bits output
     double values[VAR_VARS_NB]; ///< expression values
     int hsub, vsub;             ///< chroma subsampling
     int planes;                 ///< number of planes
@@ -114,13 +115,19 @@ static inline double getpix(void *priv, double x, double y, int plane)
         x -= xi;
         y -= yi;
 
-        if (geq->bps > 8) {
+        if (geq->bps > 8 && geq->bps <= 16) {
             const uint16_t *src16 = (const uint16_t*)src;
             linesize /= 2;
 
             return (1-y)*((1-x)*src16[xi +  yi    * linesize] + x*src16[xi + 1 +  yi    * linesize])
                   +   y *((1-x)*src16[xi + (yi+1) * linesize] + x*src16[xi + 1 + (yi+1) * linesize]);
-        } else {
+        } else if (geq->bps == 32) {
+            const float *src32 = (const float*)src;
+            linesize /= 4;
+
+            return (1-y)*((1-x)*src32[xi +  yi    * linesize] + x*src32[xi + 1 +  yi    * linesize])
+                  +   y *((1-x)*src32[xi + (yi+1) * linesize] + x*src32[xi + 1 + (yi+1) * linesize]);
+        } else if (geq->bps == 8) {
             return (1-y)*((1-x)*src[xi +  yi    * linesize] + x*src[xi + 1 +  yi    * linesize])
                   +   y *((1-x)*src[xi + (yi+1) * linesize] + x*src[xi + 1 + (yi+1) * linesize]);
         }
@@ -128,15 +135,22 @@ static inline double getpix(void *priv, double x, double y, int plane)
         xi = av_clipd(x, 0, w - 1);
         yi = av_clipd(y, 0, h - 1);
 
-        if (geq->bps > 8) {
+        if (geq->bps > 8 && geq->bps <= 16) {
             const uint16_t *src16 = (const uint16_t*)src;
             linesize /= 2;
 
             return src16[xi + yi * linesize];
-        } else {
+        } else if (geq->bps == 32) {
+            const float *src32 = (const float*)src;
+            linesize /= 4;
+
+            return src32[xi + yi * linesize];
+        } else if (geq->bps == 8) {
             return src[xi + yi * linesize];
         }
     }
+
+    return 0;
 }
 
 static int calculate_sums(GEQContext *geq, int plane, int w, int h)
@@ -150,10 +164,12 @@ static int calculate_sums(GEQContext *geq, int plane, int w, int h)
         geq->pixel_sums[plane] = av_malloc_array(w, h * sizeof (*geq->pixel_sums[plane]));
     if (!geq->pixel_sums[plane])
         return AVERROR(ENOMEM);
-    if (geq->bps > 8)
+    if (geq->bps == 32)
+        linesize /= 4;
+    else if (geq->bps > 8 && geq->bps <= 16)
         linesize /= 2;
     for (yi = 0; yi < h; yi ++) {
-        if (geq->bps > 8) {
+        if (geq->bps > 8 && geq->bps <= 16) {
             const uint16_t *src16 = (const uint16_t*)src;
             double linesum = 0;
 
@@ -161,13 +177,21 @@ static int calculate_sums(GEQContext *geq, int plane, int w, int h)
                 linesum += src16[xi + yi * linesize];
                 geq->pixel_sums[plane][xi + yi * w] = linesum;
             }
-        } else {
+        } else if (geq->bps == 8) {
             double linesum = 0;
 
             for (xi = 0; xi < w; xi ++) {
                 linesum += src[xi + yi * linesize];
                 geq->pixel_sums[plane][xi + yi * w] = linesum;
             }
+        } else if (geq->bps == 32) {
+            const float *src32 = (const float*)src;
+            double linesum = 0;
+
+            for (xi = 0; xi < w; xi ++) {
+                linesum += src32[xi + yi * linesize];
+                geq->pixel_sums[plane][xi + yi * w] = linesum;
+            }
         }
         if (yi)
             for (xi = 0; xi < w; xi ++) {
@@ -249,8 +273,10 @@ static av_cold int geq_init(AVFilterContext *ctx)
         if (!geq->expr_str[V]) geq->expr_str[V] = av_strdup(geq->expr_str[U]);
     }
 
-    if (!geq->expr_str[A]) {
+    if (!geq->expr_str[A] && geq->bps != 32) {
         geq->expr_str[A] = av_asprintf("%d", (1<<geq->bps) - 1);
+    } else {
+        geq->expr_str[A] = av_asprintf("%f", 1.f);
     }
     if (!geq->expr_str[G])
         geq->expr_str[G] = av_strdup("g(X,Y)");
@@ -322,6 +348,7 @@ static int geq_query_formats(AVFilterContext *ctx)
         AV_PIX_FMT_YUV444P16,  AV_PIX_FMT_YUV422P16,  AV_PIX_FMT_YUV420P16,
         AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA420P16,
         AV_PIX_FMT_GRAY16,
+        AV_PIX_FMT_GRAYF32,
         AV_PIX_FMT_NONE
     };
     static const enum AVPixelFormat rgb_pix_fmts[] = {
@@ -331,6 +358,7 @@ static int geq_query_formats(AVFilterContext *ctx)
         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
     };
     const enum AVPixelFormat *pix_fmts = geq->is_rgb ? rgb_pix_fmts : yuv_pix_fmts;
@@ -390,7 +418,7 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j
             }
             ptr += linesize;
         }
-    } else {
+    } else if (geq->bps <= 16) {
         uint16_t *ptr16 = geq->dst16 + (linesize/2) * slice_start;
         for (y = slice_start; y < slice_end; y++) {
             values[VAR_Y] = y;
@@ -400,6 +428,16 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j
             }
             ptr16 += linesize/2;
         }
+    } else {
+        float *ptr32 = geq->dst32 + (linesize/4) * slice_start;
+        for (y = slice_start; y < slice_end; y++) {
+            values[VAR_Y] = y;
+            for (x = 0; x < width; x++) {
+                values[VAR_X] = x;
+                ptr32[x] = av_expr_eval(geq->e[plane][jobnr], values, geq);
+            }
+            ptr32 += linesize/4;
+        }
     }
 
     return 0;
@@ -433,6 +471,7 @@ static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in)
 
         geq->dst = out->data[plane];
         geq->dst16 = (uint16_t*)out->data[plane];
+        geq->dst32 = (float*)out->data[plane];
 
         geq->values[VAR_W]  = width;
         geq->values[VAR_H]  = height;



More information about the ffmpeg-cvslog mailing list