[FFmpeg-cvslog] avfilter/vf_v360: refactor creation of remap data

Paul B Mahol git at videolan.org
Mon Sep 16 20:25:22 EEST 2019


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Mon Sep 16 18:16:57 2019 +0200| [05ffaa252ee89d1f21a140b995b162a6f68da0fa] | committer: Paul B Mahol

avfilter/vf_v360: refactor creation of remap data

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

 libavfilter/v360.h    |  18 ++++++
 libavfilter/vf_v360.c | 156 ++++++++++++++++++++++++--------------------------
 2 files changed, 92 insertions(+), 82 deletions(-)

diff --git a/libavfilter/v360.h b/libavfilter/v360.h
index 24e4615c1c..a15ff7dbc4 100644
--- a/libavfilter/v360.h
+++ b/libavfilter/v360.h
@@ -85,6 +85,12 @@ enum RotationOrder {
     NB_RORDERS,
 };
 
+typedef struct XYRemap {
+    uint16_t u[4][4];
+    uint16_t v[4][4];
+    float ker[4][4];
+} XYRemap;
+
 typedef struct V360Context {
     const AVClass *class;
     int in, out;
@@ -130,11 +136,23 @@ typedef struct V360Context {
     int uv_linesize[4];
     int nb_planes;
     int nb_allocated;
+    int elements;
 
     uint16_t *u[4], *v[4];
     int16_t *ker[4];
     unsigned map[4];
 
+    void (*in_transform)(const struct V360Context *s,
+                         const float *vec, int width, int height,
+                         uint16_t us[4][4], uint16_t vs[4][4], float *du, float *dv);
+
+    void (*out_transform)(const struct V360Context *s,
+                          int i, int j, int width, int height,
+                          float *vec);
+
+    void (*calculate_kernel)(float du, float dv, const XYRemap *rmap,
+                             uint16_t *u, uint16_t *v, int16_t *ker);
+
     int (*remap_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
 
     void (*remap_line)(uint8_t *dst, int width, const uint8_t *src, ptrdiff_t in_linesize,
diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c
index 117002b22b..6cccb2570f 100644
--- a/libavfilter/vf_v360.c
+++ b/libavfilter/vf_v360.c
@@ -207,12 +207,6 @@ static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *sr
 DEFINE_REMAP1_LINE( 8, 1)
 DEFINE_REMAP1_LINE(16, 2)
 
-typedef struct XYRemap {
-    uint16_t u[4][4];
-    uint16_t v[4][4];
-    float ker[4][4];
-} XYRemap;
-
 /**
  * Generate remapping function with a given window size and pixel depth.
  *
@@ -2167,6 +2161,47 @@ static void set_dimensions(int *outw, int *outh, int w, int h, const AVPixFmtDes
     outh[0] = outh[3] = h;
 }
 
+// Calculate remap data
+static av_always_inline void v360_filter(AVFilterContext *ctx)
+{
+    V360Context *s = ctx->priv;
+
+    for (int p = 0; p < s->nb_allocated; p++) {
+        const int width = s->pr_width[p];
+        const int uv_linesize = s->uv_linesize[p];
+        const int height = s->pr_height[p];
+        const int in_width = s->inplanewidth[p];
+        const int in_height = s->inplaneheight[p];
+        float du, dv;
+        float vec[3];
+        XYRemap rmap;
+
+        for (int j = 0; j < height; j++) {
+            for (int i = 0; i < width; i++) {
+                uint16_t *u = s->u[p] + (j * uv_linesize + i) * s->elements;
+                uint16_t *v = s->v[p] + (j * uv_linesize + i) * s->elements;
+                int16_t *ker = s->ker[p] + (j * uv_linesize + i) * s->elements;
+
+                if (s->out_transpose)
+                    s->out_transform(s, j, i, height, width, vec);
+                else
+                    s->out_transform(s, i, j, width, height, vec);
+                av_assert1(!isnan(vec[0]) && !isnan(vec[1]) && !isnan(vec[2]));
+                rotate(s->rot_mat, vec);
+                av_assert1(!isnan(vec[0]) && !isnan(vec[1]) && !isnan(vec[2]));
+                normalize_vector(vec);
+                mirror(s->output_mirror_modifier, vec);
+                if (s->in_transpose)
+                    s->in_transform(s, vec, in_height, in_width, rmap.v, rmap.u, &du, &dv);
+                else
+                    s->in_transform(s, vec, in_width, in_height, rmap.u, rmap.v, &du, &dv);
+                av_assert1(!isnan(du) && !isnan(dv));
+                s->calculate_kernel(du, dv, &rmap, u, v, ker);
+            }
+        }
+    }
+}
+
 static int config_output(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -2176,20 +2211,11 @@ static int config_output(AVFilterLink *outlink)
     const int depth = desc->comp[0].depth;
     int sizeof_uv;
     int sizeof_ker;
-    int elements;
     int err;
     int h, w;
     int in_offset_h, in_offset_w;
     int out_offset_h, out_offset_w;
     float hf, wf;
-    void (*in_transform)(const V360Context *s,
-                         const float *vec, int width, int height,
-                         uint16_t us[4][4], uint16_t vs[4][4], float *du, float *dv);
-    void (*out_transform)(const V360Context *s,
-                          int i, int j, int width, int height,
-                          float *vec);
-    void (*calculate_kernel)(float du, float dv, const XYRemap *rmap,
-                             uint16_t *u, uint16_t *v, int16_t *ker);
     int (*prepare_out)(AVFilterContext *ctx);
 
     s->input_mirror_modifier[0] = s->ih_flip ? -1.f : 1.f;
@@ -2197,32 +2223,32 @@ static int config_output(AVFilterLink *outlink)
 
     switch (s->interp) {
     case NEAREST:
-        calculate_kernel = nearest_kernel;
+        s->calculate_kernel = nearest_kernel;
         s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
-        elements = 1;
-        sizeof_uv = sizeof(uint16_t) * elements;
+        s->elements = 1;
+        sizeof_uv = sizeof(uint16_t) * s->elements;
         sizeof_ker = 0;
         break;
     case BILINEAR:
-        calculate_kernel = bilinear_kernel;
+        s->calculate_kernel = bilinear_kernel;
         s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
-        elements = 2 * 2;
-        sizeof_uv = sizeof(uint16_t) * elements;
-        sizeof_ker = sizeof(uint16_t) * elements;
+        s->elements = 2 * 2;
+        sizeof_uv = sizeof(uint16_t) * s->elements;
+        sizeof_ker = sizeof(uint16_t) * s->elements;
         break;
     case BICUBIC:
-        calculate_kernel = bicubic_kernel;
+        s->calculate_kernel = bicubic_kernel;
         s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
-        elements = 4 * 4;
-        sizeof_uv = sizeof(uint16_t) * elements;
-        sizeof_ker = sizeof(uint16_t) * elements;
+        s->elements = 4 * 4;
+        sizeof_uv = sizeof(uint16_t) * s->elements;
+        sizeof_ker = sizeof(uint16_t) * s->elements;
         break;
     case LANCZOS:
-        calculate_kernel = lanczos_kernel;
+        s->calculate_kernel = lanczos_kernel;
         s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
-        elements = 4 * 4;
-        sizeof_uv = sizeof(uint16_t) * elements;
-        sizeof_ker = sizeof(uint16_t) * elements;
+        s->elements = 4 * 4;
+        sizeof_uv = sizeof(uint16_t) * s->elements;
+        sizeof_ker = sizeof(uint16_t) * s->elements;
         break;
     default:
         av_assert0(0);
@@ -2277,31 +2303,31 @@ static int config_output(AVFilterLink *outlink)
 
     switch (s->in) {
     case EQUIRECTANGULAR:
-        in_transform = xyz_to_equirect;
+        s->in_transform = xyz_to_equirect;
         err = 0;
         wf = w;
         hf = h;
         break;
     case CUBEMAP_3_2:
-        in_transform = xyz_to_cube3x2;
+        s->in_transform = xyz_to_cube3x2;
         err = prepare_cube_in(ctx);
         wf = w / 3.f * 4.f;
         hf = h;
         break;
     case CUBEMAP_1_6:
-        in_transform = xyz_to_cube1x6;
+        s->in_transform = xyz_to_cube1x6;
         err = prepare_cube_in(ctx);
         wf = w * 4.f;
         hf = h / 3.f;
         break;
     case CUBEMAP_6_1:
-        in_transform = xyz_to_cube6x1;
+        s->in_transform = xyz_to_cube6x1;
         err = prepare_cube_in(ctx);
         wf = w / 3.f * 2.f;
         hf = h * 2.f;
         break;
     case EQUIANGULAR:
-        in_transform = xyz_to_eac;
+        s->in_transform = xyz_to_eac;
         err = prepare_eac_in(ctx);
         wf = w;
         hf = h / 9.f * 8.f;
@@ -2310,19 +2336,19 @@ static int config_output(AVFilterLink *outlink)
         av_log(ctx, AV_LOG_ERROR, "Flat format is not accepted as input.\n");
         return AVERROR(EINVAL);
     case DUAL_FISHEYE:
-        in_transform = xyz_to_dfisheye;
+        s->in_transform = xyz_to_dfisheye;
         err = 0;
         wf = w;
         hf = h;
         break;
     case BARREL:
-        in_transform = xyz_to_barrel;
+        s->in_transform = xyz_to_barrel;
         err = 0;
         wf = w / 5.f * 4.f;
         hf = h;
         break;
     case STEREOGRAPHIC:
-        in_transform = xyz_to_stereographic;
+        s->in_transform = xyz_to_stereographic;
         err = 0;
         wf = w;
         hf = h / 2.f;
@@ -2338,55 +2364,55 @@ static int config_output(AVFilterLink *outlink)
 
     switch (s->out) {
     case EQUIRECTANGULAR:
-        out_transform = equirect_to_xyz;
+        s->out_transform = equirect_to_xyz;
         prepare_out = NULL;
         w = roundf(wf);
         h = roundf(hf);
         break;
     case CUBEMAP_3_2:
-        out_transform = cube3x2_to_xyz;
+        s->out_transform = cube3x2_to_xyz;
         prepare_out = prepare_cube_out;
         w = roundf(wf / 4.f * 3.f);
         h = roundf(hf);
         break;
     case CUBEMAP_1_6:
-        out_transform = cube1x6_to_xyz;
+        s->out_transform = cube1x6_to_xyz;
         prepare_out = prepare_cube_out;
         w = roundf(wf / 4.f);
         h = roundf(hf * 3.f);
         break;
     case CUBEMAP_6_1:
-        out_transform = cube6x1_to_xyz;
+        s->out_transform = cube6x1_to_xyz;
         prepare_out = prepare_cube_out;
         w = roundf(wf / 2.f * 3.f);
         h = roundf(hf / 2.f);
         break;
     case EQUIANGULAR:
-        out_transform = eac_to_xyz;
+        s->out_transform = eac_to_xyz;
         prepare_out = prepare_eac_out;
         w = roundf(wf);
         h = roundf(hf / 8.f * 9.f);
         break;
     case FLAT:
-        out_transform = flat_to_xyz;
+        s->out_transform = flat_to_xyz;
         prepare_out = prepare_flat_out;
         w = roundf(wf);
         h = roundf(hf);
         break;
     case DUAL_FISHEYE:
-        out_transform = dfisheye_to_xyz;
+        s->out_transform = dfisheye_to_xyz;
         prepare_out = NULL;
         w = roundf(wf);
         h = roundf(hf);
         break;
     case BARREL:
-        out_transform = barrel_to_xyz;
+        s->out_transform = barrel_to_xyz;
         prepare_out = NULL;
         w = roundf(wf / 4.f * 5.f);
         h = roundf(hf);
         break;
     case STEREOGRAPHIC:
-        out_transform = stereographic_to_xyz;
+        s->out_transform = stereographic_to_xyz;
         prepare_out = prepare_stereographic_out;
         w = roundf(wf);
         h = roundf(hf * 2.f);
@@ -2467,41 +2493,7 @@ static int config_output(AVFilterLink *outlink)
     calculate_rotation_matrix(s->yaw, s->pitch, s->roll, s->rot_mat, s->rotation_order);
     set_mirror_modifier(s->h_flip, s->v_flip, s->d_flip, s->output_mirror_modifier);
 
-    // Calculate remap data
-    for (int p = 0; p < s->nb_allocated; p++) {
-        const int width = s->pr_width[p];
-        const int uv_linesize = s->uv_linesize[p];
-        const int height = s->pr_height[p];
-        const int in_width = s->inplanewidth[p];
-        const int in_height = s->inplaneheight[p];
-        float du, dv;
-        float vec[3];
-        XYRemap rmap;
-
-        for (int j = 0; j < height; j++) {
-            for (int i = 0; i < width; i++) {
-                uint16_t *u = s->u[p] + (j * uv_linesize + i) * elements;
-                uint16_t *v = s->v[p] + (j * uv_linesize + i) * elements;
-                int16_t *ker = s->ker[p] + (j * uv_linesize + i) * elements;
-
-                if (s->out_transpose)
-                    out_transform(s, j, i, height, width, vec);
-                else
-                    out_transform(s, i, j, width, height, vec);
-                av_assert1(!isnan(vec[0]) && !isnan(vec[1]) && !isnan(vec[2]));
-                rotate(s->rot_mat, vec);
-                av_assert1(!isnan(vec[0]) && !isnan(vec[1]) && !isnan(vec[2]));
-                normalize_vector(vec);
-                mirror(s->output_mirror_modifier, vec);
-                if (s->in_transpose)
-                    in_transform(s, vec, in_height, in_width, rmap.v, rmap.u, &du, &dv);
-                else
-                    in_transform(s, vec, in_width, in_height, rmap.u, rmap.v, &du, &dv);
-                av_assert1(!isnan(du) && !isnan(dv));
-                calculate_kernel(du, dv, &rmap, u, v, ker);
-            }
-        }
-    }
+    v360_filter(ctx);
 
     return 0;
 }



More information about the ffmpeg-cvslog mailing list