aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2020-09-29 14:16:32 +0200
committerPaul B Mahol <onemda@gmail.com>2020-09-29 14:21:22 +0200
commit12585c87e63302c59f5a1f5c30181695ef9aea6e (patch)
tree5d140ea4dfd066c93fc3e320193edc9bdd8baba6
parent86b29c0cd0d0e82179f655c1385afd1013e00eca (diff)
downloadffmpeg-12585c87e63302c59f5a1f5c30181695ef9aea6e.tar.gz
avfilter/vf_v360: simplify input flipping
-rw-r--r--libavfilter/v360.h1
-rw-r--r--libavfilter/vf_v360.c163
2 files changed, 69 insertions, 95 deletions
diff --git a/libavfilter/v360.h b/libavfilter/v360.h
index c0f700b62b..9b52827bd1 100644
--- a/libavfilter/v360.h
+++ b/libavfilter/v360.h
@@ -151,7 +151,6 @@ typedef struct V360Context {
float rot_mat[3][3];
- float input_mirror_modifier[2];
float output_mirror_modifier[3];
int in_width, in_height;
diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c
index ffc23a27ce..ed84c05fcc 100644
--- a/libavfilter/vf_v360.c
+++ b/libavfilter/vf_v360.c
@@ -1111,9 +1111,6 @@ static void xyz_to_cube(const V360Context *s,
face = s->in_cubemap_face_order[*direction];
rotate_cube_face(uf, vf, s->in_cubemap_face_rotation[face]);
-
- (*uf) *= s->input_mirror_modifier[0];
- (*vf) *= s->input_mirror_modifier[1];
}
/**
@@ -1804,8 +1801,8 @@ static int xyz_to_stereographic(const V360Context *s,
const float theta = acosf(vec[2]);
const float r = tanf(theta * 0.5f);
const float c = r / hypotf(vec[0], vec[1]);
- const float x = vec[0] * c / s->iflat_range[0] * s->input_mirror_modifier[0];
- const float y = vec[1] * c / s->iflat_range[1] * s->input_mirror_modifier[1];
+ const float x = vec[0] * c / s->iflat_range[0];
+ const float y = vec[1] * c / s->iflat_range[1];
const float uf = (x + 1.f) * width / 2.f;
const float vf = (y + 1.f) * height / 2.f;
@@ -1910,8 +1907,8 @@ static int xyz_to_equisolid(const V360Context *s,
const float theta = acosf(vec[2]);
const float r = sinf(theta * 0.5f);
const float c = r / hypotf(vec[0], vec[1]);
- const float x = vec[0] * c / s->iflat_range[0] * s->input_mirror_modifier[0];
- const float y = vec[1] * c / s->iflat_range[1] * s->input_mirror_modifier[1];
+ const float x = vec[0] * c / s->iflat_range[0];
+ const float y = vec[1] * c / s->iflat_range[1];
const float uf = (x + 1.f) * width / 2.f;
const float vf = (y + 1.f) * height / 2.f;
@@ -2015,8 +2012,8 @@ static int xyz_to_orthographic(const V360Context *s,
const float theta = acosf(vec[2]);
const float r = sinf(theta);
const float c = r / hypotf(vec[0], vec[1]);
- const float x = vec[0] * c / s->iflat_range[0] * s->input_mirror_modifier[0];
- const float y = vec[1] * c / s->iflat_range[1] * s->input_mirror_modifier[1];
+ const float x = vec[0] * c / s->iflat_range[0];
+ const float y = vec[1] * c / s->iflat_range[1];
const float uf = (x + 1.f) * width / 2.f;
const float vf = (y + 1.f) * height / 2.f;
@@ -2055,8 +2052,8 @@ static int xyz_to_equirect(const V360Context *s,
const float *vec, int width, int height,
int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
{
- const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0];
- const float theta = asinf(vec[1]) * s->input_mirror_modifier[1];
+ const float phi = atan2f(vec[0], vec[2]);
+ const float theta = asinf(vec[1]);
const float uf = (phi / M_PI + 1.f) * width / 2.f;
const float vf = (theta / M_PI_2 + 1.f) * height / 2.f;
@@ -2093,8 +2090,8 @@ static int xyz_to_hequirect(const V360Context *s,
const float *vec, int width, int height,
int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
{
- const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0];
- const float theta = asinf(vec[1]) * s->input_mirror_modifier[1];
+ const float phi = atan2f(vec[0], vec[2]);
+ const float theta = asinf(vec[1]);
const float uf = (phi / M_PI_2 + 1.f) * width / 2.f;
const float vf = (theta / M_PI_2 + 1.f) * height / 2.f;
@@ -2156,8 +2153,8 @@ static int xyz_to_flat(const V360Context *s,
const float zf = vec[2];
const float h = hypotf(vec[0], vec[1]);
const float c = h <= 1e-6f ? 1.f : rr / h;
- float uf = vec[0] * c / s->iflat_range[0] * s->input_mirror_modifier[0];
- float vf = vec[1] * c / s->iflat_range[1] * s->input_mirror_modifier[1];
+ float uf = vec[0] * c / s->iflat_range[0];
+ float vf = vec[1] * c / s->iflat_range[1];
int visible, ui, vi;
uf = zf >= 0.f ? (uf + 1.f) * width / 2.f : 0.f;
@@ -2197,8 +2194,8 @@ static int xyz_to_mercator(const V360Context *s,
const float *vec, int width, int height,
int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
{
- const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0];
- const float theta = vec[1] * s->input_mirror_modifier[1];
+ const float phi = atan2f(vec[0], vec[2]);
+ const float theta = vec[1];
const float uf = (phi / M_PI + 1.f) * width / 2.f;
const float vf = (av_clipf(logf((1.f + theta) / (1.f - theta)) / (2.f * M_PI), -1.f, 1.f) + 1.f) * height / 2.f;
@@ -2268,8 +2265,8 @@ static int xyz_to_ball(const V360Context *s,
const float l = hypotf(vec[0], vec[1]);
const float r = sqrtf(1.f - vec[2]) / M_SQRT2;
- const float uf = (1.f + r * vec[0] * s->input_mirror_modifier[0] / (l > 0.f ? l : 1.f)) * width * 0.5f;
- const float vf = (1.f + r * vec[1] * s->input_mirror_modifier[1] / (l > 0.f ? l : 1.f)) * height * 0.5f;
+ const float uf = (1.f + r * vec[0] / (l > 0.f ? l : 1.f)) * width * 0.5f;
+ const float vf = (1.f + r * vec[1] / (l > 0.f ? l : 1.f)) * height * 0.5f;
const int ui = floorf(uf);
const int vi = floorf(vf);
@@ -2376,11 +2373,11 @@ static int xyz_to_hammer(const V360Context *s,
const float *vec, int width, int height,
int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
{
- const float theta = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0];
+ const float theta = atan2f(vec[0], vec[2]);
const float z = sqrtf(1.f + sqrtf(1.f - vec[1] * vec[1]) * cosf(theta * 0.5f));
const float x = sqrtf(1.f - vec[1] * vec[1]) * sinf(theta * 0.5f) / z;
- const float y = vec[1] / z * s->input_mirror_modifier[1];
+ const float y = vec[1] / z;
const float uf = (x + 1.f) * width / 2.f;
const float vf = (y + 1.f) * height / 2.f;
@@ -2448,8 +2445,8 @@ static int xyz_to_sinusoidal(const V360Context *s,
const float *vec, int width, int height,
int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
{
- const float theta = asinf(vec[1]) * s->input_mirror_modifier[1];
- const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0] * cosf(theta);
+ const float theta = asinf(vec[1]);
+ const float phi = atan2f(vec[0], vec[2]) * cosf(theta);
const float uf = (phi / M_PI + 1.f) * width / 2.f;
const float vf = (theta / M_PI_2 + 1.f) * height / 2.f;
@@ -2481,51 +2478,19 @@ static int prepare_eac_in(AVFilterContext *ctx)
{
V360Context *s = ctx->priv;
- if (s->ih_flip && s->iv_flip) {
- s->in_cubemap_face_order[RIGHT] = BOTTOM_LEFT;
- s->in_cubemap_face_order[LEFT] = BOTTOM_RIGHT;
- s->in_cubemap_face_order[UP] = TOP_LEFT;
- s->in_cubemap_face_order[DOWN] = TOP_RIGHT;
- s->in_cubemap_face_order[FRONT] = BOTTOM_MIDDLE;
- s->in_cubemap_face_order[BACK] = TOP_MIDDLE;
- } else if (s->ih_flip) {
- s->in_cubemap_face_order[RIGHT] = TOP_LEFT;
- s->in_cubemap_face_order[LEFT] = TOP_RIGHT;
- s->in_cubemap_face_order[UP] = BOTTOM_LEFT;
- s->in_cubemap_face_order[DOWN] = BOTTOM_RIGHT;
- s->in_cubemap_face_order[FRONT] = TOP_MIDDLE;
- s->in_cubemap_face_order[BACK] = BOTTOM_MIDDLE;
- } else if (s->iv_flip) {
- s->in_cubemap_face_order[RIGHT] = BOTTOM_RIGHT;
- s->in_cubemap_face_order[LEFT] = BOTTOM_LEFT;
- s->in_cubemap_face_order[UP] = TOP_RIGHT;
- s->in_cubemap_face_order[DOWN] = TOP_LEFT;
- s->in_cubemap_face_order[FRONT] = BOTTOM_MIDDLE;
- s->in_cubemap_face_order[BACK] = TOP_MIDDLE;
- } else {
- s->in_cubemap_face_order[RIGHT] = TOP_RIGHT;
- s->in_cubemap_face_order[LEFT] = TOP_LEFT;
- s->in_cubemap_face_order[UP] = BOTTOM_RIGHT;
- s->in_cubemap_face_order[DOWN] = BOTTOM_LEFT;
- s->in_cubemap_face_order[FRONT] = TOP_MIDDLE;
- s->in_cubemap_face_order[BACK] = BOTTOM_MIDDLE;
- }
+ s->in_cubemap_face_order[RIGHT] = TOP_RIGHT;
+ s->in_cubemap_face_order[LEFT] = TOP_LEFT;
+ s->in_cubemap_face_order[UP] = BOTTOM_RIGHT;
+ s->in_cubemap_face_order[DOWN] = BOTTOM_LEFT;
+ s->in_cubemap_face_order[FRONT] = TOP_MIDDLE;
+ s->in_cubemap_face_order[BACK] = BOTTOM_MIDDLE;
- if (s->iv_flip) {
- s->in_cubemap_face_rotation[TOP_LEFT] = ROT_270;
- s->in_cubemap_face_rotation[TOP_MIDDLE] = ROT_90;
- s->in_cubemap_face_rotation[TOP_RIGHT] = ROT_270;
- s->in_cubemap_face_rotation[BOTTOM_LEFT] = ROT_0;
- s->in_cubemap_face_rotation[BOTTOM_MIDDLE] = ROT_0;
- s->in_cubemap_face_rotation[BOTTOM_RIGHT] = ROT_0;
- } else {
- s->in_cubemap_face_rotation[TOP_LEFT] = ROT_0;
- s->in_cubemap_face_rotation[TOP_MIDDLE] = ROT_0;
- s->in_cubemap_face_rotation[TOP_RIGHT] = ROT_0;
- s->in_cubemap_face_rotation[BOTTOM_LEFT] = ROT_270;
- s->in_cubemap_face_rotation[BOTTOM_MIDDLE] = ROT_90;
- s->in_cubemap_face_rotation[BOTTOM_RIGHT] = ROT_270;
- }
+ s->in_cubemap_face_rotation[TOP_LEFT] = ROT_0;
+ s->in_cubemap_face_rotation[TOP_MIDDLE] = ROT_0;
+ s->in_cubemap_face_rotation[TOP_RIGHT] = ROT_0;
+ s->in_cubemap_face_rotation[BOTTOM_LEFT] = ROT_270;
+ s->in_cubemap_face_rotation[BOTTOM_MIDDLE] = ROT_90;
+ s->in_cubemap_face_rotation[BOTTOM_RIGHT] = ROT_270;
return 0;
}
@@ -2852,8 +2817,8 @@ static int xyz_to_fisheye(const V360Context *s,
const float lh = h > 0.f ? h : 1.f;
const float phi = atan2f(h, vec[2]) / M_PI;
- float uf = vec[0] / lh * phi * s->input_mirror_modifier[0] / s->iflat_range[0];
- float vf = vec[1] / lh * phi * s->input_mirror_modifier[1] / s->iflat_range[1];
+ float uf = vec[0] / lh * phi / s->iflat_range[0];
+ float vf = vec[1] / lh * phi / s->iflat_range[1];
const int visible = hypotf(uf, vf) <= 0.5f;
int ui, vi;
@@ -2927,8 +2892,8 @@ static int xyz_to_pannini(const V360Context *s,
const float *vec, int width, int height,
int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
{
- const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0];
- const float theta = asinf(vec[1]) * s->input_mirror_modifier[1];
+ const float phi = atan2f(vec[0], vec[2]);
+ const float theta = asinf(vec[1]);
const float d = s->ih_fov;
const float S = (d + 1.f) / (d + cosf(phi));
@@ -3041,8 +3006,8 @@ static int xyz_to_cylindrical(const V360Context *s,
const float *vec, int width, int height,
int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
{
- const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0] / s->iflat_range[0];
- const float theta = asinf(vec[1]) * s->input_mirror_modifier[1];
+ const float phi = atan2f(vec[0], vec[2]) / s->iflat_range[0];
+ const float theta = asinf(vec[1]);
const float uf = (phi + 1.f) * (width - 1) / 2.f;
const float vf = (tanf(theta) / s->iflat_range[1] + 1.f) * height / 2.f;
@@ -3169,13 +3134,13 @@ static int xyz_to_tetrahedron(const V360Context *s,
y = vec[1] / d;
z = -vec[2] / d;
- vf = 0.5f - y * 0.5f * s->input_mirror_modifier[1];
+ vf = 0.5f - y * 0.5f;
if ((x + y >= 0.f && y + z >= 0.f && -z - x <= 0.f) ||
(x + y <= 0.f && -y + z >= 0.f && z - x >= 0.f)) {
- uf = 0.25f * x * s->input_mirror_modifier[0] + 0.25f;
+ uf = 0.25f * x + 0.25f;
} else {
- uf = 0.75f - 0.25f * x * s->input_mirror_modifier[0];
+ uf = 0.75f - 0.25f * x;
}
uf *= width;
@@ -3259,8 +3224,8 @@ static int xyz_to_dfisheye(const V360Context *s,
const float lh = h > 0.f ? h : 1.f;
const float theta = acosf(fabsf(vec[2])) / M_PI;
- float uf = (theta * (vec[0] / lh) * s->input_mirror_modifier[0] / s->iflat_range[0] + 0.5f) * ew;
- float vf = (theta * (vec[1] / lh) * s->input_mirror_modifier[1] / s->iflat_range[1] + 0.5f) * eh;
+ float uf = (theta * (vec[0] / lh) / s->iflat_range[0] + 0.5f) * ew;
+ float vf = (theta * (vec[1] / lh) / s->iflat_range[1] + 0.5f) * eh;
int ui, vi;
int u_shift;
@@ -3378,8 +3343,8 @@ static int xyz_to_barrel(const V360Context *s,
{
const float scale = 0.99f;
- const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0];
- const float theta = asinf(vec[1]) * s->input_mirror_modifier[1];
+ const float phi = atan2f(vec[0], vec[2]);
+ const float theta = asinf(vec[1]);
const float theta_range = M_PI_4;
int ew, eh;
@@ -3391,7 +3356,7 @@ static int xyz_to_barrel(const V360Context *s,
ew = 4 * width / 5;
eh = height;
- u_shift = s->ih_flip ? width / 5 : 0;
+ u_shift = 0;
v_shift = 0;
uf = (phi / M_PI * scale + 1.f) * ew / 2.f;
@@ -3400,7 +3365,7 @@ static int xyz_to_barrel(const V360Context *s,
ew = width / 5;
eh = height / 2;
- u_shift = s->ih_flip ? 0 : 4 * ew;
+ u_shift = 4 * ew;
if (theta < 0.f) { // UP
uf = -vec[0] / vec[1];
@@ -3412,9 +3377,6 @@ static int xyz_to_barrel(const V360Context *s,
v_shift = eh;
}
- uf *= s->input_mirror_modifier[0] * s->input_mirror_modifier[1];
- vf *= s->input_mirror_modifier[1];
-
uf = 0.5f * ew * (uf * scale + 1.f);
vf = 0.5f * eh * (vf * scale + 1.f);
}
@@ -3451,8 +3413,8 @@ static int xyz_to_barrelsplit(const V360Context *s,
const float *vec, int width, int height,
int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
{
- const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0];
- const float theta = asinf(vec[1]) * s->input_mirror_modifier[1];
+ const float phi = atan2f(vec[0], vec[2]);
+ const float theta = asinf(vec[1]);
const float theta_range = M_PI_4;
@@ -3468,7 +3430,7 @@ static int xyz_to_barrelsplit(const V360Context *s,
ew = width / 3 * 2;
eh = height / 2;
- u_shift = s->ih_flip ? width / 3 : 0;
+ u_shift = 0;
v_shift = phi >= M_PI_2 || phi < -M_PI_2 ? eh : 0;
uf = fmodf(phi, M_PI_2) / M_PI_2;
@@ -3487,7 +3449,7 @@ static int xyz_to_barrelsplit(const V360Context *s,
ew = width / 3;
eh = height / 4;
- u_shift = s->ih_flip ? 0 : 2 * ew;
+ u_shift = 2 * ew;
if (theta <= 0.f && theta >= -M_PI_2 &&
phi <= M_PI_2 && phi >= -M_PI_2) {
@@ -3511,9 +3473,6 @@ static int xyz_to_barrelsplit(const V360Context *s,
v_shift = height * 0.75f;
}
- uf *= s->input_mirror_modifier[0] * s->input_mirror_modifier[1];
- vf *= s->input_mirror_modifier[1];
-
uf = 0.5f * width / 3.f * (uf * scalew + 1.f);
vf = height * 0.25f * (vf * scaleh + 1.f) + v_offset;
}
@@ -3921,6 +3880,23 @@ static inline void mirror(const float *modifier, float *vec)
vec[2] *= modifier[2];
}
+static inline void input_flip(int16_t u[4][4], int16_t v[4][4], int w, int h, int hflip, int vflip)
+{
+ if (hflip) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++)
+ u[i][j] = w - 1 - u[i][j];
+ }
+ }
+
+ if (vflip) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++)
+ v[i][j] = h - 1 - v[i][j];
+ }
+ }
+}
+
static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int sizeof_mask, int p)
{
const int pr_height = s->pr_height[p];
@@ -4074,6 +4050,7 @@ static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobn
in_mask = s->in_transform(s, vec, in_height, in_width, rmap.v, rmap.u, &du, &dv);
else
in_mask = s->in_transform(s, vec, in_width, in_height, rmap.u, rmap.v, &du, &dv);
+ input_flip(rmap.u, rmap.v, in_width, in_height, s->ih_flip, s->iv_flip);
av_assert1(!isnan(du) && !isnan(dv));
s->calculate_kernel(du, dv, &rmap, u, v, ker);
@@ -4110,8 +4087,6 @@ static int config_output(AVFilterLink *outlink)
int have_alpha;
s->max_value = (1 << depth) - 1;
- s->input_mirror_modifier[0] = s->ih_flip ? -1.f : 1.f;
- s->input_mirror_modifier[1] = s->iv_flip ? -1.f : 1.f;
switch (s->interp) {
case NEAREST: