[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