[FFmpeg-cvslog] avfilter/vf_v360: add pannini input support

Paul B Mahol git at videolan.org
Sat Apr 4 15:16:51 EEST 2020


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sat Apr  4 14:12:43 2020 +0200| [ec7fb4524012e254d9f03cfe0253eb4f2c89dbeb] | committer: Paul B Mahol

avfilter/vf_v360: add pannini input support

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

 doc/filters.texi      |  7 +++++--
 libavfilter/vf_v360.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index a8d5fb1b4e..dce396e3fd 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -19044,12 +19044,15 @@ If diagonal field of view is set it overrides horizontal and vertical field of v
 @end table
 
 @item pannini
-Pannini projection. @i{(output only)}
+Pannini projection.
 
 Format specific options:
 @table @option
 @item h_fov
-Set pannini parameter.
+Set output pannini parameter.
+
+ at item ih_fov
+Set input pannini parameter.
 @end table
 
 @item cylindrical
diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c
index e33a857f87..ebc281dfca 100644
--- a/libavfilter/vf_v360.c
+++ b/libavfilter/vf_v360.c
@@ -74,6 +74,7 @@ static const AVOption v360_options[] = {
     {    "hammer", "hammer",                                     0, AV_OPT_TYPE_CONST,  {.i64=HAMMER},          0,                   0, FLAGS, "in" },
     {"sinusoidal", "sinusoidal",                                 0, AV_OPT_TYPE_CONST,  {.i64=SINUSOIDAL},      0,                   0, FLAGS, "in" },
     {   "fisheye", "fisheye",                                    0, AV_OPT_TYPE_CONST,  {.i64=FISHEYE},         0,                   0, FLAGS, "in" },
+    {   "pannini", "pannini",                                    0, AV_OPT_TYPE_CONST,  {.i64=PANNINI},         0,                   0, FLAGS, "in" },
     {"cylindrical", "cylindrical",                               0, AV_OPT_TYPE_CONST,  {.i64=CYLINDRICAL},     0,                   0, FLAGS, "in" },
     {"tetrahedron", "tetrahedron",                               0, AV_OPT_TYPE_CONST,  {.i64=TETRAHEDRON},     0,                   0, FLAGS, "in" },
     {"barrelsplit", "barrel split facebook's 360 format",        0, AV_OPT_TYPE_CONST,  {.i64=BARREL_SPLIT},    0,                   0, FLAGS, "in" },
@@ -2690,6 +2691,52 @@ static int pannini_to_xyz(const V360Context *s,
     return 1;
 }
 
+/**
+ * Calculate frame position in pannini 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 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 d = s->ih_fov;
+    const float S = (d + 1.f) / (d + cosf(phi));
+
+    const float x = S * sinf(phi);
+    const float y = S * tanf(theta);
+
+    const float uf = (x + 1.f) * width  / 2.f;
+    const float vf = (y + 1.f) * height / 2.f;
+
+    const int ui = floorf(uf);
+    const int vi = floorf(vf);
+
+    const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
+
+    *du = uf - ui;
+    *dv = vf - vi;
+
+    for (int i = 0; i < 4; i++) {
+        for (int j = 0; j < 4; j++) {
+            us[i][j] = visible ? av_clip(ui + j - 1, 0, width  - 1) : 0;
+            vs[i][j] = visible ? av_clip(vi + i - 1, 0, height - 1) : 0;
+        }
+    }
+
+    return visible;
+}
+
 /**
  * Prepare data for processing cylindrical output format.
  *
@@ -3877,7 +3924,6 @@ static int config_output(AVFilterLink *outlink)
         hf = h;
         break;
     case PERSPECTIVE:
-    case PANNINI:
         av_log(ctx, AV_LOG_ERROR, "Supplied format is not accepted as input.\n");
         return AVERROR(EINVAL);
     case DUAL_FISHEYE:
@@ -3928,6 +3974,12 @@ static int config_output(AVFilterLink *outlink)
         wf = w * 2;
         hf = h;
         break;
+    case PANNINI:
+        s->in_transform = xyz_to_pannini;
+        err = 0;
+        wf = w;
+        hf = h;
+        break;
     case CYLINDRICAL:
         s->in_transform = xyz_to_cylindrical;
         err = prepare_cylindrical_in(ctx);



More information about the ffmpeg-cvslog mailing list