Commit e57b9aa8 authored by Paul B Mahol's avatar Paul B Mahol

avfilter/vf_v360: add support for flat input format

parent 091695f8
...@@ -18910,14 +18910,21 @@ Equi-Angular Cubemap. ...@@ -18910,14 +18910,21 @@ Equi-Angular Cubemap.
@item flat @item flat
@item gnomonic @item gnomonic
@item rectilinear @item rectilinear
Regular video. @i{(output only)} Regular video.
Format specific options: Format specific options:
@table @option @table @option
@item h_fov @item h_fov
@item v_fov @item v_fov
@item d_fov @item d_fov
Set horizontal/vertical/diagonal field of view. Values in degrees. Set output horizontal/vertical/diagonal field of view. Values in degrees.
If diagonal field of view is set it overrides horizontal and vertical field of view.
@item ih_fov
@item iv_fov
@item id_fov
Set input horizontal/vertical/diagonal field of view. Values in degrees.
If diagonal field of view is set it overrides horizontal and vertical field of view. If diagonal field of view is set it overrides horizontal and vertical field of view.
@end table @end table
......
...@@ -130,7 +130,9 @@ typedef struct V360Context { ...@@ -130,7 +130,9 @@ typedef struct V360Context {
int in_transpose, out_transpose; int in_transpose, out_transpose;
float h_fov, v_fov, d_fov; float h_fov, v_fov, d_fov;
float ih_fov, iv_fov, id_fov;
float flat_range[2]; float flat_range[2];
float iflat_range[2];
float rot_mat[3][3]; float rot_mat[3][3];
......
...@@ -61,6 +61,9 @@ static const AVOption v360_options[] = { ...@@ -61,6 +61,9 @@ static const AVOption v360_options[] = {
{ "c6x1", "cubemap 6x1", 0, AV_OPT_TYPE_CONST, {.i64=CUBEMAP_6_1}, 0, 0, FLAGS, "in" }, { "c6x1", "cubemap 6x1", 0, AV_OPT_TYPE_CONST, {.i64=CUBEMAP_6_1}, 0, 0, FLAGS, "in" },
{ "eac", "equi-angular cubemap", 0, AV_OPT_TYPE_CONST, {.i64=EQUIANGULAR}, 0, 0, FLAGS, "in" }, { "eac", "equi-angular cubemap", 0, AV_OPT_TYPE_CONST, {.i64=EQUIANGULAR}, 0, 0, FLAGS, "in" },
{ "dfisheye", "dual fisheye", 0, AV_OPT_TYPE_CONST, {.i64=DUAL_FISHEYE}, 0, 0, FLAGS, "in" }, { "dfisheye", "dual fisheye", 0, AV_OPT_TYPE_CONST, {.i64=DUAL_FISHEYE}, 0, 0, FLAGS, "in" },
{ "flat", "regular video", 0, AV_OPT_TYPE_CONST, {.i64=FLAT}, 0, 0, FLAGS, "in" },
{"rectilinear", "regular video", 0, AV_OPT_TYPE_CONST, {.i64=FLAT}, 0, 0, FLAGS, "in" },
{ "gnomonic", "regular video", 0, AV_OPT_TYPE_CONST, {.i64=FLAT}, 0, 0, FLAGS, "in" },
{ "barrel", "barrel facebook's 360 format", 0, AV_OPT_TYPE_CONST, {.i64=BARREL}, 0, 0, FLAGS, "in" }, { "barrel", "barrel facebook's 360 format", 0, AV_OPT_TYPE_CONST, {.i64=BARREL}, 0, 0, FLAGS, "in" },
{ "fb", "barrel facebook's 360 format", 0, AV_OPT_TYPE_CONST, {.i64=BARREL}, 0, 0, FLAGS, "in" }, { "fb", "barrel facebook's 360 format", 0, AV_OPT_TYPE_CONST, {.i64=BARREL}, 0, 0, FLAGS, "in" },
{ "c1x6", "cubemap 1x6", 0, AV_OPT_TYPE_CONST, {.i64=CUBEMAP_1_6}, 0, 0, FLAGS, "in" }, { "c1x6", "cubemap 1x6", 0, AV_OPT_TYPE_CONST, {.i64=CUBEMAP_1_6}, 0, 0, FLAGS, "in" },
...@@ -133,6 +136,9 @@ static const AVOption v360_options[] = { ...@@ -133,6 +136,9 @@ static const AVOption v360_options[] = {
{ "iv_flip", "flip in video vertically", OFFSET(iv_flip), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS, "iv_flip"}, { "iv_flip", "flip in video vertically", OFFSET(iv_flip), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS, "iv_flip"},
{ "in_trans", "transpose video input", OFFSET(in_transpose), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS, "in_transpose"}, { "in_trans", "transpose video input", OFFSET(in_transpose), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS, "in_transpose"},
{ "out_trans", "transpose video output", OFFSET(out_transpose), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS, "out_transpose"}, { "out_trans", "transpose video output", OFFSET(out_transpose), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS, "out_transpose"},
{ "ih_fov", "input horizontal field of view",OFFSET(ih_fov), AV_OPT_TYPE_FLOAT, {.dbl=90.f}, 0.00001f, 360.f, FLAGS, "ih_fov"},
{ "iv_fov", "input vertical field of view", OFFSET(iv_fov), AV_OPT_TYPE_FLOAT, {.dbl=45.f}, 0.00001f, 360.f, FLAGS, "iv_fov"},
{ "id_fov", "input diagonal field of view", OFFSET(id_fov), AV_OPT_TYPE_FLOAT, {.dbl=0.f}, 0.f, 360.f, FLAGS, "id_fov"},
{ NULL } { NULL }
}; };
...@@ -1648,6 +1654,68 @@ static void xyz_to_equirect(const V360Context *s, ...@@ -1648,6 +1654,68 @@ static void xyz_to_equirect(const V360Context *s,
} }
} }
/**
* Prepare data for processing flat input format.
*
* @param ctx filter context
*
* @return error code
*/
static int prepare_flat_in(AVFilterContext *ctx)
{
V360Context *s = ctx->priv;
s->iflat_range[0] = tanf(0.5f * s->ih_fov * M_PI / 180.f);
s->iflat_range[1] = tanf(0.5f * s->iv_fov * M_PI / 180.f);
return 0;
}
/**
* Calculate frame position in flat format for corresponding 3D coordinates on sphere.
*
* @param s filter private context
* @param vec coordinates on sphere
* @param width frame width
* @param height frame height
* @param us horizontal coordinates for interpolation window
* @param vs vertical coordinates for interpolation window
* @param du horizontal relative coordinate
* @param dv vertical relative coordinate
*/
static void xyz_to_flat(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 = acosf(vec[2]);
const float r = tanf(theta);
const float rr = fabsf(r) < 1e+6f ? r : hypotf(width, height);
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];
int visible, ui, vi;
uf = zf >= 0.f ? (uf + 1.f) * width / 2.f : 0.f;
vf = zf >= 0.f ? (vf + 1.f) * height / 2.f : 0.f;
ui = floorf(uf);
vi = floorf(vf);
visible = vi >= 0 && vi < height && ui >= 0 && ui < width;
*du = uf - ui;
*dv = vf - vi;
for (int i = -1; i < 3; i++) {
for (int j = -1; j < 3; j++) {
us[i + 1][j + 1] = visible ? av_clip(ui + j, 0, width - 1) : 0;
vs[i + 1][j + 1] = visible ? av_clip(vi + i, 0, height - 1) : 0;
}
}
}
/** /**
* Calculate frame position in mercator format for corresponding 3D coordinates on sphere. * Calculate frame position in mercator format for corresponding 3D coordinates on sphere.
* *
...@@ -2899,6 +2967,9 @@ static int config_output(AVFilterLink *outlink) ...@@ -2899,6 +2967,9 @@ static int config_output(AVFilterLink *outlink)
s->in_width = s->inplanewidth[0]; s->in_width = s->inplanewidth[0];
s->in_height = s->inplaneheight[0]; s->in_height = s->inplaneheight[0];
if (s->id_fov > 0.f)
fov_from_dfov(s->id_fov, w, h, &s->ih_fov, &s->iv_fov);
if (s->in_transpose) if (s->in_transpose)
FFSWAP(int, s->in_width, s->in_height); FFSWAP(int, s->in_width, s->in_height);
...@@ -2933,11 +3004,16 @@ static int config_output(AVFilterLink *outlink) ...@@ -2933,11 +3004,16 @@ static int config_output(AVFilterLink *outlink)
wf = w; wf = w;
hf = h / 9.f * 8.f; hf = h / 9.f * 8.f;
break; break;
case FLAT:
s->in_transform = xyz_to_flat;
err = prepare_flat_in(ctx);
wf = w;
hf = h;
break;
case PERSPECTIVE: case PERSPECTIVE:
case CYLINDRICAL: case CYLINDRICAL:
case PANNINI: case PANNINI:
case FISHEYE: case FISHEYE:
case FLAT:
av_log(ctx, AV_LOG_ERROR, "Supplied format is not accepted as input.\n"); av_log(ctx, AV_LOG_ERROR, "Supplied format is not accepted as input.\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
case DUAL_FISHEYE: case DUAL_FISHEYE:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment