[FFmpeg-devel] [PATCH 3/3] mkv: Export bounds and padding from spherical metadata

Vittorio Giovara vittorio.giovara at gmail.com
Fri Feb 10 23:11:45 EET 2017


---
Although quite math-heavy, I saw little value in having a single parsing
function, and since it requires stream or demuxer specific information
I preferred to keep the two separate.

Please keep me in CC.
Vittorio

 libavformat/matroskadec.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 7223e94..dc1cd62 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1913,15 +1913,32 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track)
     AVSphericalMapping *spherical;
     enum AVSphericalProjection projection;
     size_t spherical_size;
+    size_t l, t, r, b;
+    size_t padding = 0;
     int ret;
+    GetByteContext gb;
+
+    bytestream2_init(&gb, track->video.projection.private.data,
+                     track->video.projection.private.size);
 
     switch (track->video.projection.type) {
     case MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR:
-        projection = AV_SPHERICAL_EQUIRECTANGULAR;
+        if (track->video.projection.private.size == 0)
+            projection = AV_SPHERICAL_EQUIRECTANGULAR;
+        else {
+            projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
+            bytestream2_skip(&gb, 4); // version + flags
+            t = bytestream2_get_be32(&gb);
+            b = bytestream2_get_be32(&gb);
+            l = bytestream2_get_be32(&gb);
+            r = bytestream2_get_be32(&gb);
+        }
         break;
     case MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP:
         if (track->video.projection.private.size < 4)
             return AVERROR_INVALIDDATA;
+        bytestream2_skip(&gb, 4); // layout
+        padding = bytestream2_get_be32(&gb);
         projection = AV_SPHERICAL_CUBEMAP;
         break;
     default:
@@ -1937,6 +1954,21 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track)
     spherical->pitch = (int32_t)(track->video.projection.pitch * (1 << 16));
     spherical->roll  = (int32_t)(track->video.projection.roll  * (1 << 16));
 
+    spherical->padding = padding;
+
+    if (spherical->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) track->video.pixel_width  * max_coord / (max_coord - r - l);
+        size_t orig_height = (size_t) track->video.pixel_height * max_coord / (max_coord - b - t);
+
+        /* add a (max_coord - 1) to round up integer division */
+        spherical->left_bound   = (orig_width  * l + max_coord - 1) / max_coord;
+        spherical->top_bound    = (orig_height * t + max_coord - 1) / max_coord;
+        spherical->right_bound  = orig_width  - track->video.pixel_width  - spherical->left_bound;
+        spherical->bottom_bound = orig_height - track->video.pixel_height - spherical->top_bound;
+    }
+
     ret = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL, (uint8_t *)spherical,
                                   spherical_size);
     if (ret < 0) {
-- 
2.10.0



More information about the ffmpeg-devel mailing list