You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	avformat/matroskadec: add support for Spherical Video elements
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
		| @@ -153,6 +153,13 @@ | ||||
| #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 | ||||
| @@ -331,6 +338,13 @@ typedef enum { | ||||
|   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 | ||||
|  */ | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user