Browse code

avfilter/vf_geq: >8 bps support

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

Michael Niedermayer authored on 2017/06/30 19:16:04
Showing 1 changed files
... ...
@@ -41,6 +41,7 @@ typedef struct GEQContext {
41 41
     int hsub, vsub;             ///< chroma subsampling
42 42
     int planes;                 ///< number of planes
43 43
     int is_rgb;
44
+    int bps;
44 45
 } GEQContext;
45 46
 
46 47
 enum { Y = 0, U, V, A, G, B, R };
... ...
@@ -74,7 +75,7 @@ static inline double getpix(void *priv, double x, double y, int plane)
74 74
     GEQContext *geq = priv;
75 75
     AVFrame *picref = geq->picref;
76 76
     const uint8_t *src = picref->data[plane];
77
-    const int linesize = picref->linesize[plane];
77
+    int linesize = picref->linesize[plane];
78 78
     const int w = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(picref->width,  geq->hsub) : picref->width;
79 79
     const int h = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(picref->height, geq->vsub) : picref->height;
80 80
 
... ...
@@ -87,8 +88,16 @@ static inline double getpix(void *priv, double x, double y, int plane)
87 87
     x -= xi;
88 88
     y -= yi;
89 89
 
90
-    return (1-y)*((1-x)*src[xi +  yi    * linesize] + x*src[xi + 1 +  yi    * linesize])
91
-          +   y *((1-x)*src[xi + (yi+1) * linesize] + x*src[xi + 1 + (yi+1) * linesize]);
90
+    if (geq->bps > 8) {
91
+        const uint16_t *src16 = (const uint16_t*)src;
92
+        linesize /= 2;
93
+
94
+        return (1-y)*((1-x)*src16[xi +  yi    * linesize] + x*src16[xi + 1 +  yi    * linesize])
95
+              +   y *((1-x)*src16[xi + (yi+1) * linesize] + x*src16[xi + 1 + (yi+1) * linesize]);
96
+    } else {
97
+        return (1-y)*((1-x)*src[xi +  yi    * linesize] + x*src[xi + 1 +  yi    * linesize])
98
+              +   y *((1-x)*src[xi + (yi+1) * linesize] + x*src[xi + 1 + (yi+1) * linesize]);
99
+    }
92 100
 }
93 101
 
94 102
 //TODO: cubic interpolate
... ...
@@ -129,8 +138,11 @@ static av_cold int geq_init(AVFilterContext *ctx)
129 129
         if (!geq->expr_str[V]) geq->expr_str[V] = av_strdup(geq->expr_str[U]);
130 130
     }
131 131
 
132
-    if (!geq->expr_str[A])
133
-        geq->expr_str[A] = av_strdup("255");
132
+    if (!geq->expr_str[A]) {
133
+        char bps_string[8];
134
+        snprintf(bps_string, sizeof(bps_string), "%d", (1<<geq->bps) - 1);
135
+        geq->expr_str[A] = av_strdup(bps_string);
136
+    }
134 137
     if (!geq->expr_str[G])
135 138
         geq->expr_str[G] = av_strdup("g(X,Y)");
136 139
     if (!geq->expr_str[B])
... ...
@@ -171,10 +183,27 @@ static int geq_query_formats(AVFilterContext *ctx)
171 171
         AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P,  AV_PIX_FMT_YUV440P,
172 172
         AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
173 173
         AV_PIX_FMT_GRAY8,
174
+        AV_PIX_FMT_YUV444P9,  AV_PIX_FMT_YUV422P9,  AV_PIX_FMT_YUV420P9,
175
+        AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9,
176
+        AV_PIX_FMT_YUV444P10,  AV_PIX_FMT_YUV422P10,  AV_PIX_FMT_YUV420P10,
177
+        AV_PIX_FMT_YUV440P10,
178
+        AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA420P10,
179
+        AV_PIX_FMT_GRAY10,
180
+        AV_PIX_FMT_YUV444P12,  AV_PIX_FMT_YUV422P12,  AV_PIX_FMT_YUV420P12,
181
+        AV_PIX_FMT_GRAY12,
182
+        AV_PIX_FMT_YUV444P14,  AV_PIX_FMT_YUV422P14,  AV_PIX_FMT_YUV420P14,
183
+        AV_PIX_FMT_YUV444P16,  AV_PIX_FMT_YUV422P16,  AV_PIX_FMT_YUV420P16,
184
+        AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA420P16,
185
+        AV_PIX_FMT_GRAY16,
174 186
         AV_PIX_FMT_NONE
175 187
     };
176 188
     static const enum AVPixelFormat rgb_pix_fmts[] = {
177 189
         AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
190
+        AV_PIX_FMT_GBRP9,
191
+        AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
192
+        AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
193
+        AV_PIX_FMT_GBRP14,
194
+        AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16,
178 195
         AV_PIX_FMT_NONE
179 196
     };
180 197
     AVFilterFormats *fmts_list;
... ...
@@ -198,6 +227,8 @@ static int geq_config_props(AVFilterLink *inlink)
198 198
     geq->hsub = desc->log2_chroma_w;
199 199
     geq->vsub = desc->log2_chroma_h;
200 200
     geq->planes = desc->nb_components;
201
+    geq->bps    = desc->comp[0].depth;
202
+
201 203
     return 0;
202 204
 }
203 205
 
... ...
@@ -223,6 +254,7 @@ static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in)
223 223
     for (plane = 0; plane < geq->planes && out->data[plane]; plane++) {
224 224
         int x, y;
225 225
         uint8_t *dst = out->data[plane];
226
+        uint16_t *dst16 = (uint16_t*)out->data[plane];
226 227
         const int linesize = out->linesize[plane];
227 228
         const int w = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(inlink->w, geq->hsub) : inlink->w;
228 229
         const int h = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(inlink->h, geq->vsub) : inlink->h;
... ...
@@ -234,11 +266,19 @@ static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in)
234 234
 
235 235
         for (y = 0; y < h; y++) {
236 236
             values[VAR_Y] = y;
237
-            for (x = 0; x < w; x++) {
238
-                values[VAR_X] = x;
239
-                dst[x] = av_expr_eval(geq->e[plane], values, geq);
237
+            if (geq->bps > 8) {
238
+                for (x = 0; x < w; x++) {
239
+                    values[VAR_X] = x;
240
+                    dst16[x] = av_expr_eval(geq->e[plane], values, geq);
241
+                }
242
+                dst16 += linesize / 2;
243
+            } else {
244
+                for (x = 0; x < w; x++) {
245
+                    values[VAR_X] = x;
246
+                    dst[x] = av_expr_eval(geq->e[plane], values, geq);
247
+                }
248
+                dst += linesize;
240 249
             }
241
-            dst += linesize;
242 250
         }
243 251
     }
244 252