From 5f0226668124aa7ae4db501ba7f4ace4c770f3d1 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Mar 2016 20:29:54 +0200 Subject: [PATCH] matroska: Support interlaced content correctly The matroska specification now has two elements for it. --- libavformat/matroska.h | 16 ++++++++++++++++ libavformat/matroskadec.c | 28 +++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/libavformat/matroska.h b/libavformat/matroska.h index a7a22a96af..40402bcdb8 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -113,6 +113,7 @@ #define MATROSKA_ID_VIDEOPIXELCROPR 0x54DD #define MATROSKA_ID_VIDEODISPLAYUNIT 0x54B2 #define MATROSKA_ID_VIDEOFLAGINTERLACED 0x9A +#define MATROSKA_ID_VIDEOFIELDORDER 0x9D #define MATROSKA_ID_VIDEOSTEREOMODE 0x53B8 #define MATROSKA_ID_VIDEOASPECTRATIO 0x54B3 #define MATROSKA_ID_VIDEOCOLORSPACE 0x2EB524 @@ -221,6 +222,21 @@ typedef enum { MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP = 3, } MatroskaTrackEncodingCompAlgo; +typedef enum { + MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED = 0, + MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED = 1, + MATROSKA_VIDEO_INTERLACE_FLAG_PROGRESSIVE = 2 +} MatroskaVideoInterlaceFlag; + +typedef enum { + MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE = 0, + MATROSKA_VIDEO_FIELDORDER_UNDETERMINED = 2, + MATROSKA_VIDEO_FIELDORDER_TT = 1, + MATROSKA_VIDEO_FIELDORDER_BB = 6, + MATROSKA_VIDEO_FIELDORDER_BT = 9, + MATROSKA_VIDEO_FIELDORDER_TB = 14, +} MatroskaVideoFieldOrder; + typedef enum { MATROSKA_VIDEO_STEREOMODE_TYPE_MONO = 0, MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT = 1, diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 75ac67c89b..978d56db16 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -123,6 +123,8 @@ typedef struct MatroskaTrackVideo { uint64_t pixel_width; uint64_t pixel_height; uint64_t fourcc; + uint64_t interlaced; + uint64_t field_order; uint64_t stereo_mode; } MatroskaTrackVideo; @@ -319,7 +321,8 @@ static EbmlSyntax matroska_track_video[] = { { MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE }, { MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE }, { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE }, - { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_NONE }, + { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_UINT, 0, offsetof(MatroskaTrackVideo, interlaced), { .u = MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED } }, + { MATROSKA_ID_VIDEOFIELDORDER, EBML_UINT, 0, offsetof(MatroskaTrackVideo, field_order), { .u = MATROSKA_VIDEO_FIELDORDER_UNDETERMINED } }, { MATROSKA_ID_VIDEOSTEREOMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } }, { MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE }, { 0 } @@ -1525,6 +1528,26 @@ static int matroska_parse_flac(AVFormatContext *s, return 0; } +static int mkv_field_order(int64_t field_order) +{ + switch (field_order) { + case MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE: + return AV_FIELD_PROGRESSIVE; + case MATROSKA_VIDEO_FIELDORDER_UNDETERMINED: + return AV_FIELD_UNKNOWN; + case MATROSKA_VIDEO_FIELDORDER_TT: + return AV_FIELD_TT; + case MATROSKA_VIDEO_FIELDORDER_BB: + return AV_FIELD_BB; + case MATROSKA_VIDEO_FIELDORDER_BT: + return AV_FIELD_BT; + case MATROSKA_VIDEO_FIELDORDER_TB: + return AV_FIELD_TB; + default: + return AV_FIELD_UNKNOWN; + } +} + static void mkv_stereo_mode_display_mul(int stereo_mode, int *h_width, int *h_height) { @@ -1850,6 +1873,9 @@ static int matroska_parse_tracks(AVFormatContext *s) st->codecpar->width = track->video.pixel_width; st->codecpar->height = track->video.pixel_height; + if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED) + st->codecpar->field_order = mkv_field_order(track->video.field_order); + if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB) mkv_stereo_mode_display_mul(track->video.stereo_mode, &display_width_mul, &display_height_mul);