matroskadec: parse stereo mode on decoding
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/757185
This commit is contained in:
parent
9301486408
commit
d4ae8ac92f
@ -32,6 +32,7 @@ version <next>:
|
|||||||
- request icecast metadata by default
|
- request icecast metadata by default
|
||||||
- support for using metadata in stream specifiers in avtools
|
- support for using metadata in stream specifiers in avtools
|
||||||
- Aliases and defaults for Ogg subtypes (opus, spx)
|
- Aliases and defaults for Ogg subtypes (opus, spx)
|
||||||
|
- matroska 3d support
|
||||||
|
|
||||||
|
|
||||||
version 10:
|
version 10:
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "libavutil/stereo3d.h"
|
||||||
|
|
||||||
#include "matroska.h"
|
#include "matroska.h"
|
||||||
|
|
||||||
const CodecTags ff_mkv_codec_tags[]={
|
const CodecTags ff_mkv_codec_tags[]={
|
||||||
@ -103,3 +105,65 @@ const AVMetadataConv ff_mkv_metadata_conv[] = {
|
|||||||
{ "PART_NUMBER" , "track" },
|
{ "PART_NUMBER" , "track" },
|
||||||
{ 0 }
|
{ 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_ANAGLYPH_GREEN_MAG = 12,
|
||||||
MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR = 13,
|
MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR = 13,
|
||||||
MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL = 14,
|
MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL = 14,
|
||||||
|
MATROSKA_VIDEO_STEREOMODE_TYPE_NB,
|
||||||
} MatroskaVideoStereoModeType;
|
} MatroskaVideoStereoModeType;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -255,4 +256,6 @@ extern const CodecTags ff_mkv_codec_tags[];
|
|||||||
extern const CodecMime ff_mkv_mime_tags[];
|
extern const CodecMime ff_mkv_mime_tags[];
|
||||||
extern const AVMetadataConv ff_mkv_metadata_conv[];
|
extern const AVMetadataConv ff_mkv_metadata_conv[];
|
||||||
|
|
||||||
|
int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode);
|
||||||
|
|
||||||
#endif /* AVFORMAT_MATROSKA_H */
|
#endif /* AVFORMAT_MATROSKA_H */
|
||||||
|
@ -123,6 +123,7 @@ typedef struct {
|
|||||||
uint64_t pixel_width;
|
uint64_t pixel_width;
|
||||||
uint64_t pixel_height;
|
uint64_t pixel_height;
|
||||||
uint64_t fourcc;
|
uint64_t fourcc;
|
||||||
|
uint64_t stereo_mode;
|
||||||
} MatroskaTrackVideo;
|
} MatroskaTrackVideo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -319,7 +320,7 @@ static EbmlSyntax matroska_track_video[] = {
|
|||||||
{ MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE },
|
{ MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE },
|
||||||
{ MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE },
|
{ MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE },
|
||||||
{ MATROSKA_ID_VIDEOFLAGINTERLACED, 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 },
|
{ MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
@ -1786,6 +1787,13 @@ static int matroska_parse_tracks(AVFormatContext *s)
|
|||||||
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
|
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
|
||||||
1000000000, track->default_duration, 30000);
|
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) {
|
} else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
|
||||||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||||
st->codec->sample_rate = track->audio.out_samplerate;
|
st->codec->sample_rate = track->audio.out_samplerate;
|
||||||
@ -1821,7 +1829,7 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
ebml.version > EBML_VERSION ||
|
ebml.version > EBML_VERSION ||
|
||||||
ebml.max_size > sizeof(uint64_t) ||
|
ebml.max_size > sizeof(uint64_t) ||
|
||||||
ebml.id_length > sizeof(uint32_t) ||
|
ebml.id_length > sizeof(uint32_t) ||
|
||||||
ebml.doctype_version > 2) {
|
ebml.doctype_version > 3) {
|
||||||
av_log(matroska->ctx, AV_LOG_ERROR,
|
av_log(matroska->ctx, AV_LOG_ERROR,
|
||||||
"EBML header using unsupported features\n"
|
"EBML header using unsupported features\n"
|
||||||
"(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
|
"(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user