summaryrefslogtreecommitdiff
path: root/libavfilter/vf_geq.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2019-10-11 18:26:22 +0200
committerPaul B Mahol <onemda@gmail.com>2019-10-14 10:55:51 +0200
commit8a0d45a92eb31b2e4ea2fe8a10fb9817a0b0e63f (patch)
treeed9289943c1b0e3a12d79af887070e5bc1771816 /libavfilter/vf_geq.c
parent996ff3fe86b0a7a0d2b8bc5a2570cb1271eb9474 (diff)
downloadffmpeg-8a0d45a92eb31b2e4ea2fe8a10fb9817a0b0e63f.tar.gz
avfilter/vf_geq: allow user to set interpolation method
Diffstat (limited to 'libavfilter/vf_geq.c')
-rw-r--r--libavfilter/vf_geq.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
index 8b1c7726dc..39083c149b 100644
--- a/libavfilter/vf_geq.c
+++ b/libavfilter/vf_geq.c
@@ -33,6 +33,12 @@
#include "libavutil/pixdesc.h"
#include "internal.h"
+enum InterpolationMethods {
+ INTERP_NEAREST,
+ INTERP_BILINEAR,
+ NB_INTERP
+};
+
static const char *const var_names[] = { "X", "Y", "W", "H", "N", "SW", "SH", "T", NULL };
enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_N, VAR_SW, VAR_SH, VAR_T, VAR_VARS_NB };
@@ -46,6 +52,7 @@ typedef struct GEQContext {
double values[VAR_VARS_NB]; ///< expression values
int hsub, vsub; ///< chroma subsampling
int planes; ///< number of planes
+ int interpolation;
int is_rgb;
int bps;
} GEQContext;
@@ -70,6 +77,12 @@ static const AVOption geq_options[] = {
{ "g", "set green expression", OFFSET(expr_str[G]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
{ "blue_expr", "set blue expression", OFFSET(expr_str[B]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
{ "b", "set blue expression", OFFSET(expr_str[B]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+ { "interpolation","set interpolation method", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERP_BILINEAR}, 0, NB_INTERP-1, FLAGS, "interp" },
+ { "i", "set interpolation method", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERP_BILINEAR}, 0, NB_INTERP-1, FLAGS, "interp" },
+ { "nearest", "nearest interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERP_NEAREST}, 0, 0, FLAGS, "interp" },
+ { "n", "nearest interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERP_NEAREST}, 0, 0, FLAGS, "interp" },
+ { "bilinear", "bilinear interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERP_BILINEAR}, 0, 0, FLAGS, "interp" },
+ { "b", "bilinear interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERP_BILINEAR}, 0, 0, FLAGS, "interp" },
{NULL},
};
@@ -88,6 +101,7 @@ static inline double getpix(void *priv, double x, double y, int plane)
if (!src)
return 0;
+ if (geq->interpolation == INTERP_BILINEAR) {
xi = x = av_clipd(x, 0, w - 2);
yi = y = av_clipd(y, 0, h - 2);
@@ -104,6 +118,19 @@ static inline double getpix(void *priv, double x, double y, int plane)
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]);
}
+ } else {
+ xi = av_clipd(x, 0, w - 1);
+ yi = av_clipd(y, 0, h - 1);
+
+ if (geq->bps > 8) {
+ const uint16_t *src16 = (const uint16_t*)src;
+ linesize /= 2;
+
+ return src16[xi + yi * linesize];
+ } else {
+ return src[xi + yi * linesize];
+ }
+ }
}
//TODO: cubic interpolate