#define MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX 0x55D9
#define MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN 0x55DA
+#define MATROSKA_ID_VIDEOPROJECTION 0x7670
+#define MATROSKA_ID_VIDEOPROJECTIONTYPE 0x7671
+#define MATROSKA_ID_VIDEOPROJECTIONPRIVATE 0x7672
+#define MATROSKA_ID_VIDEOPROJECTIONPOSEYAW 0x7673
+#define MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH 0x7674
+#define MATROSKA_ID_VIDEOPROJECTIONPOSEROLL 0x7675
+
/* IDs in the trackaudio master */
#define MATROSKA_ID_AUDIOSAMPLINGFREQ 0xB5
#define MATROSKA_ID_AUDIOOUTSAMPLINGFREQ 0x78B5
MATROSKA_COLOUR_CHROMASITINGVERT_NB
} MatroskaColourChromaSitingVert;
+typedef enum {
+ MATROSKA_VIDEO_PROJECTION_TYPE_RECTANGULAR = 0,
+ MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR = 1,
+ MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP = 2,
+ MATROSKA_VIDEO_PROJECTION_TYPE_MESH = 3,
+} MatroskaVideoProjectionType;
+
/*
* Matroska Codec IDs, strings
*/
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/time_internal.h"
+#include "libavutil/spherical.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/flac.h"
MatroskaMasteringMeta mastering_meta;
} MatroskaTrackVideoColor;
+typedef struct MatroskaTrackVideoProjection {
+ uint64_t type;
+ EbmlBin private;
+ double yaw;
+ double pitch;
+ double roll;
+} MatroskaTrackVideoProjection;
+
typedef struct MatroskaTrackVideo {
double frame_rate;
uint64_t display_width;
uint64_t stereo_mode;
uint64_t alpha_mode;
MatroskaTrackVideoColor color;
+ MatroskaTrackVideoProjection projection;
} MatroskaTrackVideo;
typedef struct MatroskaTrackAudio {
{ 0 }
};
+static const EbmlSyntax matroska_track_video_projection[] = {
+ { MATROSKA_ID_VIDEOPROJECTIONTYPE, EBML_UINT, 0, offsetof(MatroskaTrackVideoProjection, type), { .u = MATROSKA_VIDEO_PROJECTION_TYPE_RECTANGULAR } },
+ { MATROSKA_ID_VIDEOPROJECTIONPRIVATE, EBML_BIN, 0, offsetof(MatroskaTrackVideoProjection, private) },
+ { MATROSKA_ID_VIDEOPROJECTIONPOSEYAW, EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, yaw), { .f=0.0 } },
+ { MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, pitch), { .f=0.0 } },
+ { MATROSKA_ID_VIDEOPROJECTIONPOSEROLL, EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, roll), { .f=0.0 } },
+ { 0 }
+};
+
static const EbmlSyntax matroska_track_video[] = {
{ MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT, 0, offsetof(MatroskaTrackVideo, frame_rate) },
{ MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo, display_width), { .u=-1 } },
{ MATROSKA_ID_VIDEOCOLORSPACE, EBML_BIN, 0, offsetof(MatroskaTrackVideo, color_space) },
{ MATROSKA_ID_VIDEOALPHAMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, alpha_mode) },
{ MATROSKA_ID_VIDEOCOLOR, EBML_NEST, 0, offsetof(MatroskaTrackVideo, color), { .n = matroska_track_video_color } },
+ { MATROSKA_ID_VIDEOPROJECTION, EBML_NEST, 0, offsetof(MatroskaTrackVideo, projection), { .n = matroska_track_video_projection } },
{ MATROSKA_ID_VIDEOPIXELCROPB, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE },
return 0;
}
+static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) {
+ AVSphericalMapping *spherical;
+ enum AVSphericalProjection projection;
+ size_t spherical_size;
+ int ret;
+
+ switch (track->video.projection.type) {
+ case MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR:
+ if (track->video.projection.private.size < 4)
+ return AVERROR_INVALIDDATA;
+ projection = AV_SPHERICAL_EQUIRECTANGULAR;
+ break;
+ case MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP:
+ if (track->video.projection.private.size < 4)
+ return AVERROR_INVALIDDATA;
+ projection = AV_SPHERICAL_CUBEMAP;
+ break;
+ default:
+ return 0;
+ }
+
+ spherical = av_spherical_alloc(&spherical_size);
+ if (!spherical)
+ return AVERROR(ENOMEM);
+ spherical->projection = projection;
+
+ spherical->yaw = (int32_t)(track->video.projection.yaw * (1 << 16));
+ spherical->pitch = (int32_t)(track->video.projection.pitch * (1 << 16));
+ spherical->roll = (int32_t)(track->video.projection.roll * (1 << 16));
+
+ ret = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL, (uint8_t *)spherical,
+ spherical_size);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int get_qt_codec(MatroskaTrack *track, uint32_t *fourcc, enum AVCodecID *codec_id)
{
const AVCodecTag *codec_tags;
if (ret < 0)
return ret;
}
+
+ ret = mkv_parse_video_projection(st, track);
+ if (ret < 0)
+ return ret;
} else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
st->codecpar->codec_tag = fourcc;