[FFmpeg-cvslog] avfilter/vf_v360: implement diagonal field of view

Paul B Mahol git at videolan.org
Sat Sep 14 11:51:14 EEST 2019


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sat Sep 14 10:47:01 2019 +0200| [cb8d6a4e3ef39dff2522335021ecfde868c371f7] | committer: Paul B Mahol

avfilter/vf_v360: implement diagonal field of view

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

 doc/filters.texi      | 10 ++++++++--
 libavfilter/v360.h    |  2 +-
 libavfilter/vf_v360.c | 47 ++++++++++++++++++++++++++++++++++-------------
 3 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index f3bbbe0f32..b2a955113c 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -18006,7 +18006,10 @@ Format specific options:
 @table @option
 @item h_fov
 @item v_fov
-Set horizontal/vertical field of view. Values in degrees.
+ at item d_fov
+Set horizontal/vertical/diagonal field of view. Values in degrees.
+
+If diagonal field of view is set it overrides horizontal and vertical field of view.
 @end table
 
 @item dfisheye
@@ -18040,7 +18043,10 @@ Format specific options:
 @table @option
 @item h_fov
 @item v_fov
-Set horizontal/vertical field of view. Values in degrees.
+ at item d_fov
+Set horizontal/vertical/diagonal field of view. Values in degrees.
+
+If diagonal field of view is set it overrides horizontal and vertical field of view.
 @end table
 
 @end table
diff --git a/libavfilter/v360.h b/libavfilter/v360.h
index 85d87e7755..11c1e27e4b 100644
--- a/libavfilter/v360.h
+++ b/libavfilter/v360.h
@@ -103,7 +103,7 @@ typedef struct V360Context {
     int h_flip, v_flip, d_flip;
     int in_transpose, out_transpose;
 
-    float h_fov, v_fov;
+    float h_fov, v_fov, d_fov;
     float flat_range[3];
 
     float input_mirror_modifier[2];
diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c
index 7cd6aa9f6d..98cef5902e 100644
--- a/libavfilter/vf_v360.c
+++ b/libavfilter/vf_v360.c
@@ -102,6 +102,7 @@ static const AVOption v360_options[] = {
     {    "rorder", "rotation order",                OFFSET(rorder), AV_OPT_TYPE_STRING, {.str="ypr"},           0,                   0, FLAGS, "rorder"},
     {     "h_fov", "horizontal field of view",       OFFSET(h_fov), AV_OPT_TYPE_FLOAT,  {.dbl=90.f},     0.00001f,               360.f, FLAGS, "h_fov"},
     {     "v_fov", "vertical field of view",         OFFSET(v_fov), AV_OPT_TYPE_FLOAT,  {.dbl=45.f},     0.00001f,               360.f, FLAGS, "v_fov"},
+    {     "d_fov", "diagonal field of view",         OFFSET(d_fov), AV_OPT_TYPE_FLOAT,  {.dbl=0.f},           0.f,               360.f, FLAGS, "d_fov"},
     {    "h_flip", "flip out video horizontally",   OFFSET(h_flip), AV_OPT_TYPE_BOOL,   {.i64=0},               0,                   1, FLAGS, "h_flip"},
     {    "v_flip", "flip out video vertically",     OFFSET(v_flip), AV_OPT_TYPE_BOOL,   {.i64=0},               0,                   1, FLAGS, "v_flip"},
     {    "d_flip", "flip out video indepth",        OFFSET(d_flip), AV_OPT_TYPE_BOOL,   {.i64=0},               0,                   1, FLAGS, "d_flip"},
@@ -2139,6 +2140,20 @@ static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int p)
     return 0;
 }
 
+static void fov_from_dfov(V360Context *s, float w, float h)
+{
+    const float d_angle = 0.5 * FFMIN(s->d_fov, 359.f) * M_PI / 180.f;
+    const float d = hypotf(w, h);
+
+    s->h_fov = atan2f(tanf(d_angle) * w, d) * 360.f / M_PI;
+    s->v_fov = atan2f(tanf(d_angle) * h, d) * 360.f / M_PI;
+
+    if (s->h_fov < 0.f)
+        s->h_fov += 360.f;
+    if (s->v_fov < 0.f)
+        s->v_fov += 360.f;
+}
+
 static int config_output(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -2161,6 +2176,7 @@ static int config_output(AVFilterLink *outlink)
                           float *vec);
     void (*calculate_kernel)(float du, float dv, const XYRemap *r_tmp,
                              uint16_t *u, uint16_t *v, int16_t *ker);
+    int (*prepare_out)(AVFilterContext *ctx);
     float rot_mat[3][3];
 
     s->input_mirror_modifier[0] = s->ih_flip ? -1.f : 1.f;
@@ -2285,55 +2301,55 @@ static int config_output(AVFilterLink *outlink)
     switch (s->out) {
     case EQUIRECTANGULAR:
         out_transform = equirect_to_xyz;
-        err = 0;
+        prepare_out = NULL;
         w = roundf(wf);
         h = roundf(hf);
         break;
     case CUBEMAP_3_2:
         out_transform = cube3x2_to_xyz;
-        err = prepare_cube_out(ctx);
+        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;
-        err = prepare_cube_out(ctx);
+        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;
-        err = prepare_cube_out(ctx);
+        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;
-        err = prepare_eac_out(ctx);
+        prepare_out = prepare_eac_out;
         w = roundf(wf);
         h = roundf(hf / 8.f * 9.f);
         break;
     case FLAT:
         out_transform = flat_to_xyz;
-        err = prepare_flat_out(ctx);
+        prepare_out = prepare_flat_out;
         w = roundf(wf);
         h = roundf(hf);
         break;
     case DUAL_FISHEYE:
         out_transform = dfisheye_to_xyz;
-        err = 0;
+        prepare_out = NULL;
         w = roundf(wf);
         h = roundf(hf);
         break;
     case BARREL:
         out_transform = barrel_to_xyz;
-        err = 0;
+        prepare_out = NULL;
         w = roundf(wf / 4.f * 5.f);
         h = roundf(hf);
         break;
     case STEREOGRAPHIC:
         out_transform = stereographic_to_xyz;
-        err = prepare_stereographic_out(ctx);
+        prepare_out = prepare_stereographic_out;
         w = roundf(wf);
         h = roundf(hf * 2.f);
         break;
@@ -2342,10 +2358,6 @@ static int config_output(AVFilterLink *outlink)
         return AVERROR_BUG;
     }
 
-    if (err != 0) {
-        return err;
-    }
-
     // Override resolution with user values if specified
     if (s->width > 0 && s->height > 0) {
         w = s->width;
@@ -2361,6 +2373,15 @@ static int config_output(AVFilterLink *outlink)
             FFSWAP(int, w, h);
     }
 
+    if (s->d_fov > 0.f)
+        fov_from_dfov(s, w, h);
+
+    if (prepare_out) {
+        err = prepare_out(ctx);
+        if (err != 0)
+            return err;
+    }
+
     s->planeheight[1] = s->planeheight[2] = FF_CEIL_RSHIFT(h, desc->log2_chroma_h);
     s->planeheight[0] = s->planeheight[3] = h;
     s->planewidth[1]  = s->planewidth[2] = FF_CEIL_RSHIFT(w, desc->log2_chroma_w);



More information about the ffmpeg-cvslog mailing list