From 028faacff56d7f90f6b119b0b0ac686fd614825f Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 21 Aug 2017 14:56:07 +0200 Subject: video: add metadata handling for spherical video This adds handling of spherical video metadata: retrieving it from demux_lavf and demux_mkv, passing it through filters, and adjusting it with vf_format. This does not include support for rendering this type of video. We don't expect we need/want to support the other projection types like cube maps, so we don't include that for now. They can be added later as needed. Also raise the maximum sizes of stringified image params, since they can get really long. --- demux/demux_lavf.c | 17 +++++++++++++++++ demux/demux_mkv.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ demux/stheader.h | 3 ++- 3 files changed, 66 insertions(+), 1 deletion(-) (limited to 'demux') diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index f890b5d693..e61529fb71 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -38,6 +38,10 @@ #include #include +#if HAVE_AVUTIL_SPHERICAL +#include +#endif + #include "common/msg.h" #include "common/tags.h" #include "common/av_common.h" @@ -641,6 +645,19 @@ static void handle_new_stream(demuxer_t *demuxer, int i) sh->codec->rotate = (((int)(-r) % 360) + 360) % 360; } +#if HAVE_AVUTIL_SPHERICAL + sd = av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL, NULL); + if (sd) { + AVSphericalMapping *sp = (void *)sd; + struct mp_spherical_params *mpsp = &sh->codec->spherical; + mpsp->type = sp->projection == AV_SPHERICAL_EQUIRECTANGULAR ? + MP_SPHERICAL_EQUIRECTANGULAR : MP_SPHERICAL_UNKNOWN; + mpsp->ref_angles[0] = sp->yaw / (float)(1 << 16); + mpsp->ref_angles[1] = sp->pitch / (float)(1 << 16); + mpsp->ref_angles[2] = sp->roll / (float)(1 << 16); + } +#endif + // This also applies to vfw-muxed mkv, but we can't detect these easily. sh->codec->avi_dts = matches_avinputformat_name(priv, "avi"); diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 9f670e2aa5..4b9551adae 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -109,6 +109,7 @@ typedef struct mkv_track { uint32_t colorspace; int stereo_mode; struct mp_colorspace color; + struct mp_spherical_params spherical; uint32_t a_channels, a_bps; float a_sfreq; @@ -584,6 +585,49 @@ static void parse_trackcolour(struct demuxer *demuxer, struct mkv_track *track, } } +static void parse_trackprojection(struct demuxer *demuxer, struct mkv_track *track, + struct ebml_projection *projection) +{ + if (projection->n_projection_type) { + const char *name; + switch (projection->projection_type) { + case 0: + name = "rectangular"; + track->spherical.type = MP_SPHERICAL_NONE; + break; + case 1: + name = "equirectangular"; + track->spherical.type = MP_SPHERICAL_EQUIRECTANGULAR; + break; + default: + name = "unknown"; + track->spherical.type = MP_SPHERICAL_UNKNOWN; + } + MP_VERBOSE(demuxer, "| + ProjectionType: %s (%"PRIu64")\n", name, + projection->projection_type); + } + if (projection->n_projection_private) { + MP_VERBOSE(demuxer, "| + ProjectionPrivate: %zd bytes\n", + projection->projection_private.len); + MP_WARN(demuxer, "Unknown ProjectionPrivate element.\n"); + } + if (projection->n_projection_pose_yaw) { + track->spherical.ref_angles[0] = projection->projection_pose_yaw; + MP_VERBOSE(demuxer, "| + ProjectionPoseYaw: %f\n", + projection->projection_pose_yaw); + } + if (projection->n_projection_pose_pitch) { + track->spherical.ref_angles[1] = projection->projection_pose_pitch; + MP_VERBOSE(demuxer, "| + ProjectionPosePitch: %f\n", + projection->projection_pose_pitch); + } + if (projection->n_projection_pose_roll) { + track->spherical.ref_angles[2] = projection->projection_pose_roll; + MP_VERBOSE(demuxer, "| + ProjectionPoseRoll: %f\n", + projection->projection_pose_roll); + } +} + static void parse_trackvideo(struct demuxer *demuxer, struct mkv_track *track, struct ebml_video *video) { @@ -628,6 +672,8 @@ static void parse_trackvideo(struct demuxer *demuxer, struct mkv_track *track, } if (video->n_colour) parse_trackcolour(demuxer, track, &video->colour); + if (video->n_projection) + parse_trackprojection(demuxer, track, &video->projection); } /** @@ -1454,6 +1500,7 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track) sh_v->stereo_mode = track->stereo_mode; sh_v->color = track->color; + sh_v->spherical = track->spherical; done: demux_add_sh_stream(demuxer, sh); diff --git a/demux/stheader.h b/demux/stheader.h index 04f8198df4..a0820f55b7 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -22,7 +22,7 @@ #include "common/common.h" #include "audio/chmap.h" -#include "video/csputils.h" +#include "video/mp_image.h" struct MPOpts; struct demuxer; @@ -93,6 +93,7 @@ struct mp_codec_params { int rotate; // intended display rotation, in degrees, [0, 359] int stereo_mode; // mp_stereo3d_mode (0 if none/unknown) struct mp_colorspace color; // colorspace info where available + struct mp_spherical_params spherical; // STREAM_VIDEO + STREAM_AUDIO int bits_per_coded_sample; -- cgit v1.2.3