[FFmpeg-cvslog] avfilter/vf_v360: simplify input flipping

Paul B Mahol git at videolan.org
Tue Sep 29 15:24:28 EEST 2020


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Tue Sep 29 14:16:32 2020 +0200| [12585c87e63302c59f5a1f5c30181695ef9aea6e] | committer: Paul B Mahol

avfilter/vf_v360: simplify input flipping

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=12585c87e63302c59f5a1f5c30181695ef9aea6e
---

 libavfilter/v360.h    |   1 -
 libavfilter/vf_v360.c | 163 +++++++++++++++++++++-----------------------------
 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:



More information about the ffmpeg-cvslog mailing list