aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/matroskadec.c
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2016-12-06 14:48:45 -0300
committerJames Almer <jamrial@gmail.com>2016-12-07 22:40:59 -0300
commit445204cd5777e029a6674ed0739777817eda5646 (patch)
tree95f32d39e2859e1f1fab4a3395b0523c88332c09 /libavformat/matroskadec.c
parente3694478a98bc2cd702b3b3f0bfb19a100da737e (diff)
downloadffmpeg-445204cd5777e029a6674ed0739777817eda5646.tar.gz
avformat/matroskadec: add support for Spherical Video elements
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavformat/matroskadec.c')
-rw-r--r--libavformat/matroskadec.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 017a533269..f4a452ef0a 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -43,6 +43,7 @@
#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"
@@ -161,6 +162,14 @@ typedef struct MatroskaTrackVideoColor {
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;
@@ -174,6 +183,7 @@ typedef struct MatroskaTrackVideo {
uint64_t stereo_mode;
uint64_t alpha_mode;
MatroskaTrackVideoColor color;
+ MatroskaTrackVideoProjection projection;
} MatroskaTrackVideo;
typedef struct MatroskaTrackAudio {
@@ -424,6 +434,15 @@ static const EbmlSyntax matroska_track_video_color[] = {
{ 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 } },
@@ -433,6 +452,7 @@ static const EbmlSyntax matroska_track_video[] = {
{ 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 },
@@ -1879,6 +1899,44 @@ static int mkv_parse_video_color(AVStream *st, const MatroskaTrack *track) {
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;
@@ -2361,6 +2419,10 @@ static int matroska_parse_tracks(AVFormatContext *s)
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;