Signed-off-by: Paul B Mahol <[email protected]>
---
doc/filters.texi | 8 ++++++++
libavfilter/vf_geq.c | 27 +++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/doc/filters.texi b/doc/filters.texi
index 55a8ebae56..6f9ebf6085 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -11019,6 +11019,14 @@ red/green/blue component. Return 0 if there is no such
component.
@item alpha(x, y)
Return the value of the pixel at location (@var{x},@var{y}) of the alpha
plane. Return 0 if there is no such plane.
+
+@item interpolation
+Set one of interpolation methods:
+@table @option
+@item nearest, n
+@item bilinear, b
+@end table
+Default is bilinear.
@end table
For functions, if @var{x} and @var{y} are outside the area, the value will be
diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
index 91eb9685f9..b7932f0b04 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_clipf(x, 0, w - 2);
yi = y = av_clipf(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_clipf(x, 0, w - 1);
+ yi = av_clipf(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
--
2.17.1
_______________________________________________
ffmpeg-devel mailing list
[email protected]
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
[email protected] with subject "unsubscribe".