--- 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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel