diff options
author | Paul B Mahol <onemda@gmail.com> | 2019-09-16 18:16:57 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2019-09-16 18:43:11 +0200 |
commit | 05ffaa252ee89d1f21a140b995b162a6f68da0fa (patch) | |
tree | cae5d55646237de5ebab579c1af3406657205092 /libavfilter/vf_v360.c | |
parent | a09213da23e7f580bcc455db4e7b527816f5ddf5 (diff) | |
download | ffmpeg-05ffaa252ee89d1f21a140b995b162a6f68da0fa.tar.gz |
avfilter/vf_v360: refactor creation of remap data
Diffstat (limited to 'libavfilter/vf_v360.c')
-rw-r--r-- | libavfilter/vf_v360.c | 156 |
1 files changed, 74 insertions, 82 deletions
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; } |