Convert the Matroska stereo format to the Stereo3D format, and add a Stereo3D side data to the stream. Bump the doctype version supported. Bug-Id: 728 / https://bugs.debian.org/757185tags/n2.4
| @@ -32,6 +32,7 @@ version <next>: | |||
| - request icecast metadata by default | |||
| - support for using metadata in stream specifiers in avtools | |||
| - Aliases and defaults for Ogg subtypes (opus, spx) | |||
| - matroska 3d support | |||
| version 10: | |||
| @@ -19,6 +19,8 @@ | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include "libavutil/stereo3d.h" | |||
| #include "matroska.h" | |||
| const CodecTags ff_mkv_codec_tags[]={ | |||
| @@ -103,3 +105,65 @@ const AVMetadataConv ff_mkv_metadata_conv[] = { | |||
| { "PART_NUMBER" , "track" }, | |||
| { 0 } | |||
| }; | |||
| int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode) | |||
| { | |||
| AVPacketSideData *sd, *tmp; | |||
| AVStereo3D *stereo; | |||
| stereo = av_stereo3d_alloc(); | |||
| if (!stereo) | |||
| return AVERROR(ENOMEM); | |||
| tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp)); | |||
| if (!tmp) { | |||
| av_freep(&stereo); | |||
| return AVERROR(ENOMEM); | |||
| } | |||
| st->side_data = tmp; | |||
| st->nb_side_data++; | |||
| sd = &st->side_data[st->nb_side_data - 1]; | |||
| sd->type = AV_PKT_DATA_STEREO3D; | |||
| sd->data = (uint8_t *)stereo; | |||
| sd->size = sizeof(*stereo); | |||
| // note: the missing breaks are intentional | |||
| switch (stereo_mode) { | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_MONO: | |||
| stereo->type = AV_STEREO3D_2D; | |||
| break; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT: | |||
| stereo->flags |= AV_STEREO3D_FLAG_INVERT; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT: | |||
| stereo->type = AV_STEREO3D_SIDEBYSIDE; | |||
| break; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTTOM_TOP: | |||
| stereo->flags |= AV_STEREO3D_FLAG_INVERT; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM: | |||
| stereo->type = AV_STEREO3D_TOPBOTTOM; | |||
| break; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_RL: | |||
| stereo->flags |= AV_STEREO3D_FLAG_INVERT; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR: | |||
| stereo->type = AV_STEREO3D_CHECKERBOARD; | |||
| break; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_RL: | |||
| stereo->flags |= AV_STEREO3D_FLAG_INVERT; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR: | |||
| stereo->type = AV_STEREO3D_LINES; | |||
| break; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_RL: | |||
| stereo->flags |= AV_STEREO3D_FLAG_INVERT; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR: | |||
| stereo->type = AV_STEREO3D_COLUMNS; | |||
| break; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL: | |||
| stereo->flags |= AV_STEREO3D_FLAG_INVERT; | |||
| case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR: | |||
| stereo->type = AV_STEREO3D_FRAMESEQUENCE; | |||
| break; | |||
| } | |||
| return 0; | |||
| } | |||
| @@ -237,6 +237,7 @@ typedef enum { | |||
| MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_GREEN_MAG = 12, | |||
| MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR = 13, | |||
| MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL = 14, | |||
| MATROSKA_VIDEO_STEREOMODE_TYPE_NB, | |||
| } MatroskaVideoStereoModeType; | |||
| /* | |||
| @@ -255,4 +256,6 @@ extern const CodecTags ff_mkv_codec_tags[]; | |||
| extern const CodecMime ff_mkv_mime_tags[]; | |||
| extern const AVMetadataConv ff_mkv_metadata_conv[]; | |||
| int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); | |||
| #endif /* AVFORMAT_MATROSKA_H */ | |||
| @@ -123,6 +123,7 @@ typedef struct { | |||
| uint64_t pixel_width; | |||
| uint64_t pixel_height; | |||
| uint64_t fourcc; | |||
| uint64_t stereo_mode; | |||
| } MatroskaTrackVideo; | |||
| typedef struct { | |||
| @@ -319,7 +320,7 @@ static EbmlSyntax matroska_track_video[] = { | |||
| { MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE }, | |||
| { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE }, | |||
| { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_NONE }, | |||
| { MATROSKA_ID_VIDEOSTEREOMODE, EBML_NONE }, | |||
| { MATROSKA_ID_VIDEOSTEREOMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } }, | |||
| { MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE }, | |||
| { 0 } | |||
| }; | |||
| @@ -1786,6 +1787,13 @@ static int matroska_parse_tracks(AVFormatContext *s) | |||
| av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, | |||
| 1000000000, track->default_duration, 30000); | |||
| } | |||
| // add stream level stereo3d side data if it is a supported format | |||
| if (track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB && | |||
| track->video.stereo_mode != 10 && track->video.stereo_mode != 12) { | |||
| int ret = ff_mkv_stereo3d_conv(st, track->video.stereo_mode); | |||
| if (ret < 0) | |||
| return ret; | |||
| } | |||
| } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { | |||
| st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | |||
| st->codec->sample_rate = track->audio.out_samplerate; | |||
| @@ -1821,7 +1829,7 @@ static int matroska_read_header(AVFormatContext *s) | |||
| ebml.version > EBML_VERSION || | |||
| ebml.max_size > sizeof(uint64_t) || | |||
| ebml.id_length > sizeof(uint32_t) || | |||
| ebml.doctype_version > 2) { | |||
| ebml.doctype_version > 3) { | |||
| av_log(matroska->ctx, AV_LOG_ERROR, | |||
| "EBML header using unsupported features\n" | |||
| "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", | |||