[FFmpeg-cvslog] avfilter/vf_v360: add gaussian interpolation
Paul B Mahol
git at videolan.org
Sat Jan 18 14:47:45 EET 2020
ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sat Jan 18 13:43:33 2020 +0100| [62a0d226212d5e0857c62effb1cb41e5f4af6707] | committer: Paul B Mahol
avfilter/vf_v360: add gaussian interpolation
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=62a0d226212d5e0857c62effb1cb41e5f4af6707
---
doc/filters.texi | 3 +++
libavfilter/v360.h | 1 +
libavfilter/vf_v360.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+)
diff --git a/doc/filters.texi b/doc/filters.texi
index c8ac4311f5..252eb4b7ad 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -19027,6 +19027,9 @@ Lanczos interpolation.
@item sp16
@item spline16
Spline16 interpolation.
+ at item gauss
+ at item gaussian
+Gaussian interpolation.
@end table
Default value is @b{@samp{line}}.
diff --git a/libavfilter/v360.h b/libavfilter/v360.h
index 9f74272133..29bf27565c 100644
--- a/libavfilter/v360.h
+++ b/libavfilter/v360.h
@@ -55,6 +55,7 @@ enum InterpMethod {
BICUBIC,
LANCZOS,
SPLINE16,
+ GAUSSIAN,
NB_INTERP_METHODS,
};
diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c
index b56f6cc96b..452f52dce6 100644
--- a/libavfilter/vf_v360.c
+++ b/libavfilter/vf_v360.c
@@ -101,6 +101,8 @@ static const AVOption v360_options[] = {
{ "lanczos", "lanczos interpolation", 0, AV_OPT_TYPE_CONST, {.i64=LANCZOS}, 0, 0, FLAGS, "interp" },
{ "sp16", "spline16 interpolation", 0, AV_OPT_TYPE_CONST, {.i64=SPLINE16}, 0, 0, FLAGS, "interp" },
{ "spline16", "spline16 interpolation", 0, AV_OPT_TYPE_CONST, {.i64=SPLINE16}, 0, 0, FLAGS, "interp" },
+ { "gauss", "gaussian interpolation", 0, AV_OPT_TYPE_CONST, {.i64=GAUSSIAN}, 0, 0, FLAGS, "interp" },
+ { "gaussian", "gaussian interpolation", 0, AV_OPT_TYPE_CONST, {.i64=GAUSSIAN}, 0, 0, FLAGS, "interp" },
{ "w", "output width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, INT16_MAX, FLAGS, "w"},
{ "h", "output height", OFFSET(height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT16_MAX, FLAGS, "h"},
{ "in_stereo", "input stereo format", OFFSET(in_stereo), AV_OPT_TYPE_INT, {.i64=STEREO_2D}, 0, NB_STEREO_FMTS-1, FLAGS, "stereo" },
@@ -317,6 +319,7 @@ void ff_v360_init(V360Context *s, int depth)
case BICUBIC:
case LANCZOS:
case SPLINE16:
+ case GAUSSIAN:
s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
break;
}
@@ -511,6 +514,59 @@ static void spline16_kernel(float du, float dv, const XYRemap *rmap,
}
}
+/**
+ * Calculate 1-dimensional gaussian coefficients.
+ *
+ * @param t relative coordinate
+ * @param coeffs coefficients
+ */
+static void calculate_gaussian_coeffs(float t, float *coeffs)
+{
+ float sum = 0.f;
+
+ for (int i = 0; i < 4; i++) {
+ const float x = t - (i - 1);
+ if (x == 0.f) {
+ coeffs[i] = 1.f;
+ } else {
+ coeffs[i] = expf(-2.f * x * x) * expf(-x * x / 2.f);
+ }
+ sum += coeffs[i];
+ }
+
+ for (int i = 0; i < 4; i++) {
+ coeffs[i] /= sum;
+ }
+}
+
+/**
+ * Calculate kernel for gaussian interpolation.
+ *
+ * @param du horizontal relative coordinate
+ * @param dv vertical relative coordinate
+ * @param rmap calculated 4x4 window
+ * @param u u remap data
+ * @param v v remap data
+ * @param ker ker remap data
+ */
+static void gaussian_kernel(float du, float dv, const XYRemap *rmap,
+ uint16_t *u, uint16_t *v, int16_t *ker)
+{
+ float du_coeffs[4];
+ float dv_coeffs[4];
+
+ calculate_gaussian_coeffs(du, du_coeffs);
+ calculate_gaussian_coeffs(dv, dv_coeffs);
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ u[i * 4 + j] = rmap->u[i][j];
+ v[i * 4 + j] = rmap->v[i][j];
+ ker[i * 4 + j] = lrintf(du_coeffs[j] * dv_coeffs[i] * 16385.f);
+ }
+ }
+}
+
/**
* Modulo operation with only positive remainders.
*
@@ -2733,6 +2789,13 @@ static int config_output(AVFilterLink *outlink)
sizeof_uv = sizeof(uint16_t) * s->elements;
sizeof_ker = sizeof(uint16_t) * s->elements;
break;
+ case GAUSSIAN:
+ s->calculate_kernel = gaussian_kernel;
+ s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
+ s->elements = 4 * 4;
+ sizeof_uv = sizeof(uint16_t) * s->elements;
+ sizeof_ker = sizeof(uint16_t) * s->elements;
+ break;
default:
av_assert0(0);
}
More information about the ffmpeg-cvslog
mailing list