diff mbox

[FFmpeg-devel,2/3] mov: Export bounds and padding from spherical metadata

Message ID 20170210211145.54685-2-vittorio.giovara@gmail.com
State Superseded
Headers show

Commit Message

Vittorio Giovara Feb. 10, 2017, 9:11 p.m. UTC
Update the fate test as needed.
---
Please keep me in CC.
Vittorio

 libavformat/mov.c                 | 46 ++++++++++++++++++++++++++++++++++++++-
 tests/ref/fate/mov-spherical-mono |  8 +++++--
 2 files changed, 51 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index ca49786..a8900c1 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4625,6 +4625,8 @@  static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     MOVStreamContext *sc;
     int size;
     int32_t yaw, pitch, roll;
+    size_t l, t, r, b;
+    size_t padding = 0;
     uint32_t tag;
     enum AVSphericalProjection projection;
 
@@ -4686,9 +4688,17 @@  static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     switch (tag) {
     case MKTAG('c','b','m','p'):
         projection = AV_SPHERICAL_CUBEMAP;
+        padding = avio_rb32(pb);
         break;
     case MKTAG('e','q','u','i'):
-        projection = AV_SPHERICAL_EQUIRECTANGULAR;
+        t = avio_rb32(pb);
+        b = avio_rb32(pb);
+        l = avio_rb32(pb);
+        r = avio_rb32(pb);
+        if (l || t || r || b)
+            projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
+        else
+            projection = AV_SPHERICAL_EQUIRECTANGULAR;
         break;
     default:
         av_log(c->fc, AV_LOG_ERROR, "Unknown projection type\n");
@@ -4705,6 +4715,20 @@  static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     sc->spherical->pitch = pitch;
     sc->spherical->roll  = roll;
 
+    sc->spherical->padding = padding;
+
+    if (projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
+        /* conversion from 0.32 coordinates to pixels */
+        uint32_t max_coord = (uint32_t) -1;
+        size_t orig_width  = (size_t) sc->width  * max_coord / (max_coord - r - l);
+        size_t orig_height = (size_t) sc->height * max_coord / (max_coord - b - t);
+
+        /* add a (max_coord - 1) to round up integer division */
+        sc->spherical->left_bound   = (orig_width  * l + max_coord - 1) / max_coord;
+        sc->spherical->top_bound    = (orig_height * t + max_coord - 1) / max_coord;
+        sc->spherical->right_bound  = orig_width  - sc->width  - sc->spherical->left_bound;
+        sc->spherical->bottom_bound = orig_height - sc->height - sc->spherical->top_bound;
+    }
     return 0;
 }
 
@@ -4763,6 +4787,26 @@  static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_
         val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
         if (val)
             sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
+
+        /* tiling */
+        val = av_stristr(buffer, "<GSpherical:CroppedAreaLeftPixels>");
+        if (val)
+            sc->spherical->left_bound = strtol(val, NULL, 10);
+        val = av_stristr(buffer, "<GSpherical:CroppedAreaTopPixels>");
+        if (val)
+            sc->spherical->top_bound = strtol(val, NULL, 10);
+        val = av_stristr(buffer, "<GSpherical:CroppedAreaImageWidthPixels>");
+        if (val)
+            sc->spherical->right_bound =
+                sc->width - sc->spherical->left_bound - strtol(val, NULL, 10);
+        val = av_stristr(buffer, "<GSpherical:CroppedAreaImageHeightPixels>");
+        if (val)
+            sc->spherical->bottom_bound =
+                sc->height - sc->spherical->top_bound - strtol(val, NULL, 10);
+
+        if (sc->spherical->left_bound || sc->spherical->top_bound ||
+            sc->spherical->right_bound || sc->spherical->bottom_bound)
+            sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
     }
 
 out:
diff --git a/tests/ref/fate/mov-spherical-mono b/tests/ref/fate/mov-spherical-mono
index 9f4b4f8..a1365c4 100644
--- a/tests/ref/fate/mov-spherical-mono
+++ b/tests/ref/fate/mov-spherical-mono
@@ -7,8 +7,12 @@  inverted=0
 [/SIDE_DATA]
 [SIDE_DATA]
 side_data_type=Spherical Mapping
-side_data_size=16
-projection=equirectangular
+side_data_size=56
+projection=tiled equirectangular
+left_bound=148
+top_bound=73
+right_bound=147
+bottom_bound=72
 yaw=45
 pitch=30
 roll=15