|
|
|
@ -45,6 +45,7 @@ |
|
|
|
|
#include "libavutil/intreadwrite.h" |
|
|
|
|
#include "libavutil/lzo.h" |
|
|
|
|
#include "libavutil/mathematics.h" |
|
|
|
|
#include "libavutil/spherical.h" |
|
|
|
|
|
|
|
|
|
#include "libavcodec/bytestream.h" |
|
|
|
|
#include "libavcodec/flac.h" |
|
|
|
@ -116,6 +117,14 @@ typedef struct MatroskaTrackEncoding { |
|
|
|
|
MatroskaTrackCompression compression; |
|
|
|
|
} MatroskaTrackEncoding; |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
@ -126,6 +135,7 @@ typedef struct MatroskaTrackVideo { |
|
|
|
|
uint64_t interlaced; |
|
|
|
|
uint64_t field_order; |
|
|
|
|
uint64_t stereo_mode; |
|
|
|
|
MatroskaTrackVideoProjection projection; |
|
|
|
|
} MatroskaTrackVideo; |
|
|
|
|
|
|
|
|
|
typedef struct MatroskaTrackAudio { |
|
|
|
@ -309,6 +319,15 @@ static EbmlSyntax matroska_info[] = { |
|
|
|
|
{ 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 EbmlSyntax matroska_track_video[] = { |
|
|
|
|
{ MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT, 0, offsetof(MatroskaTrackVideo, frame_rate) }, |
|
|
|
|
{ MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo, display_width) }, |
|
|
|
@ -316,6 +335,7 @@ static EbmlSyntax matroska_track_video[] = { |
|
|
|
|
{ MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo, pixel_width) }, |
|
|
|
|
{ MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo, pixel_height) }, |
|
|
|
|
{ MATROSKA_ID_VIDEOCOLORSPACE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, fourcc) }, |
|
|
|
|
{ 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 }, |
|
|
|
@ -1576,6 +1596,51 @@ static void mkv_stereo_mode_display_mul(int stereo_mode, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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: |
|
|
|
|
projection = AV_SPHERICAL_EQUIRECTANGULAR; |
|
|
|
|
break; |
|
|
|
|
case MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP: |
|
|
|
|
if (track->video.projection.private.size < 4) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Missing projection private properties\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
projection = AV_SPHERICAL_CUBEMAP; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
av_log(NULL, AV_LOG_WARNING, |
|
|
|
|
"Unknown spherical metadata type %"PRIu64"\n", |
|
|
|
|
track->video.projection.type); |
|
|
|
|
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) { |
|
|
|
|
av_free(spherical); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int matroska_parse_tracks(AVFormatContext *s) |
|
|
|
|
{ |
|
|
|
|
MatroskaDemuxContext *matroska = s->priv_data; |
|
|
|
@ -1908,6 +1973,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->sample_rate = track->audio.out_samplerate; |
|
|
|
|