From b0534c65d1797b871b5c796a1761011f5015acff Mon Sep 17 00:00:00 2001 From: Doug Nazar Date: Wed, 7 Aug 2019 10:01:34 -0400 Subject: [PATCH] matroska: Handle interlaced field order --- gst/matroska/matroska-demux.c | 45 ++++++++++++++++++++++++++++++++++- gst/matroska/matroska-ids.c | 1 + gst/matroska/matroska-ids.h | 2 ++ gst/matroska/matroska-parse.c | 38 +++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 5878f38449..e39965baf5 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -974,6 +974,44 @@ gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml, break; } + /* interlaced field order */ + case GST_MATROSKA_ID_VIDEOFIELDORDER:{ + guint64 num; + + if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) + break; + + if (videocontext->interlace_mode != + GST_MATROSKA_INTERLACE_MODE_INTERLACED) { + GST_WARNING_OBJECT (demux, + "FieldOrder element when not interlaced - ignoring"); + break; + } + + if (num == 0) + /* turns out we're actually progressive */ + videocontext->interlace_mode = + GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE; + else if (num == 2) + videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN; + else if (num == 9) + videocontext->field_order = + GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST; + else if (num == 14) + videocontext->field_order = + GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST; + else { + GST_FIXME_OBJECT (demux, + "Unknown or unsupported FieldOrder %" G_GUINT64_FORMAT, + num); + videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN; + } + + GST_DEBUG_OBJECT (demux, "video track field order: %d", + videocontext->field_order); + break; + } + /* aspect ratio behaviour */ case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{ guint64 num; @@ -6437,7 +6475,12 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext * break; case GST_MATROSKA_INTERLACE_MODE_INTERLACED: gst_structure_set (structure, - "interlace-mode", G_TYPE_STRING, "mixed", NULL); + "interlace-mode", G_TYPE_STRING, "interleaved", NULL); + + if (videocontext->field_order != GST_VIDEO_FIELD_ORDER_UNKNOWN) + gst_structure_set (structure, "field-order", G_TYPE_STRING, + gst_video_field_order_to_string (videocontext->field_order), + NULL); break; default: break; diff --git a/gst/matroska/matroska-ids.c b/gst/matroska/matroska-ids.c index b3c51309b6..3722822b19 100644 --- a/gst/matroska/matroska-ids.c +++ b/gst/matroska/matroska-ids.c @@ -59,6 +59,7 @@ gst_matroska_track_init_video_context (GstMatroskaTrackContext ** p_context) video_context->fourcc = 0; video_context->default_fps = 0.0; video_context->interlace_mode = GST_MATROSKA_INTERLACE_MODE_UNKNOWN; + video_context->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN; video_context->earliest_time = GST_CLOCK_TIME_NONE; video_context->dirac_unit = NULL; video_context->earliest_time = GST_CLOCK_TIME_NONE; diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h index ab74ed2897..429213f778 100644 --- a/gst/matroska/matroska-ids.h +++ b/gst/matroska/matroska-ids.h @@ -132,6 +132,7 @@ #define GST_MATROSKA_ID_VIDEOPIXELCROPLEFT 0x54CC #define GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT 0x54DD #define GST_MATROSKA_ID_VIDEOFLAGINTERLACED 0x9A +#define GST_MATROSKA_ID_VIDEOFIELDORDER 0x9D /* semi-draft */ #define GST_MATROSKA_ID_VIDEOSTEREOMODE 0x53B8 #define GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE 0x54B3 @@ -632,6 +633,7 @@ typedef struct _GstMatroskaTrackVideoContext { guint32 fourcc; GstMatroskaInterlaceMode interlace_mode; + GstVideoFieldOrder field_order; GstVideoMultiviewMode multiview_mode; GstVideoMultiviewFlags multiview_flags; diff --git a/gst/matroska/matroska-parse.c b/gst/matroska/matroska-parse.c index b34817ffb4..594cd9a137 100644 --- a/gst/matroska/matroska-parse.c +++ b/gst/matroska/matroska-parse.c @@ -557,6 +557,44 @@ gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml) break; } + /* interlaced field order */ + case GST_MATROSKA_ID_VIDEOFIELDORDER:{ + guint64 num; + + if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) + break; + + if (videocontext->interlace_mode != + GST_MATROSKA_INTERLACE_MODE_INTERLACED) { + GST_WARNING_OBJECT (parse, + "FieldOrder element when not interlaced - ignoring"); + break; + } + + if (num == 0) + /* turns out we're actually progressive */ + videocontext->interlace_mode = + GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE; + else if (num == 2) + videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN; + else if (num == 9) + videocontext->field_order = + GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST; + else if (num == 14) + videocontext->field_order = + GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST; + else { + GST_FIXME_OBJECT (parse, + "Unknown or unsupported FieldOrder %" G_GUINT64_FORMAT, + num); + videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN; + } + + GST_DEBUG_OBJECT (parse, "video track field order: %d", + videocontext->field_order); + break; + } + /* aspect ratio behaviour */ case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{ guint64 num;