matroska: fix handling of FlagInterlaced

This is an enum not a boolean, and a value of 2 signals
that the video is progressive, but we would mistakenly set
interlace-mode=mixed on the output caps.

https://bugzilla.gnome.org/show_bug.cgi?id=787206
This commit is contained in:
Tim-Philipp Müller 2018-08-23 22:57:35 +02:00
parent 00143ca554
commit fd0afe033b
4 changed files with 59 additions and 21 deletions

View file

@ -862,13 +862,18 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (num)
context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
if (num == 1)
videocontext->interlace_mode =
GST_MATROSKA_INTERLACE_MODE_INTERLACED;
else if (num == 2)
videocontext->interlace_mode =
GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
else
context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
(context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
0);
videocontext->interlace_mode =
GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
GST_DEBUG_OBJECT (demux, "video track interlacing mode: %d",
videocontext->interlace_mode);
break;
}
@ -5750,9 +5755,18 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
0, 1, NULL);
}
if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
"mixed", NULL);
switch (videocontext->interlace_mode) {
case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
gst_structure_set (structure,
"interlace-mode", G_TYPE_STRING, "progressive", NULL);
break;
case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
gst_structure_set (structure,
"interlace-mode", G_TYPE_STRING, "mixed", NULL);
break;
default:
break;
}
}
if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,

View file

@ -500,8 +500,10 @@ typedef enum {
} GstMatroskaTrackFlags;
typedef enum {
GST_MATROSKA_VIDEOTRACK_INTERLACED = (GST_MATROSKA_TRACK_SHIFT<<0)
} GstMatroskaVideoTrackFlags;
GST_MATROSKA_INTERLACE_MODE_UNKNOWN = 0,
GST_MATROSKA_INTERLACE_MODE_INTERLACED = 1,
GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE = 2,
} GstMatroskaInterlaceMode;
typedef enum {
GST_MATROSKA_STEREO_MODE_SBS_LR = 0x1,
@ -596,6 +598,8 @@ typedef struct _GstMatroskaTrackVideoContext {
GstMatroskaAspectRatioMode asr_mode;
guint32 fourcc;
GstMatroskaInterlaceMode interlace_mode;
GstVideoMultiviewMode multiview_mode;
GstVideoMultiviewFlags multiview_flags;

View file

@ -1005,8 +1005,14 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
mimetype = gst_structure_get_name (structure);
interlace_mode = gst_structure_get_string (structure, "interlace-mode");
if (interlace_mode != NULL && strcmp (interlace_mode, "progressive") != 0)
context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
if (interlace_mode != NULL) {
if (strcmp (interlace_mode, "progressive") == 0)
videocontext->interlace_mode = GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
else
videocontext->interlace_mode = GST_MATROSKA_INTERLACE_MODE_INTERLACED;
} else {
videocontext->interlace_mode = GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
}
if (!strcmp (mimetype, "video/x-theora")) {
/* we'll extract the details later from the theora identification header */
@ -2693,8 +2699,17 @@ gst_matroska_mux_track_header (GstMatroskaMux * mux,
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEODISPLAYHEIGHT,
videocontext->display_height);
}
if (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 1);
switch (videocontext->interlace_mode) {
case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 1);
break;
case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 2);
break;
default:
break;
}
if (videocontext->fourcc) {
guint32 fcc_le = GUINT32_TO_LE (videocontext->fourcc);

View file

@ -542,13 +542,18 @@ gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (num)
context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
if (num == 1)
videocontext->interlace_mode =
GST_MATROSKA_INTERLACE_MODE_INTERLACED;
else if (num == 2)
videocontext->interlace_mode =
GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
else
context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
(context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
0);
videocontext->interlace_mode =
GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
GST_DEBUG_OBJECT (parse, "video track interlacing mode: %d",
videocontext->interlace_mode);
break;
}